Show HN:Wallfacer——面向 Claude Code 等工具的终端会话管理器
英文标题:🔶 Show HN: Wallfacer – A terminal session manager for Claude Code, and more
Wallfacer 是一款面向 Claude Code、Cursor CLI、Kiro CLI 和 Codex 的本地终端会话管理器,可统一索引、命名、标记、分组、搜索、恢复或删除 AI 编程会话。它以只读方式扫描各 Agent 的会话文件,并将标题、标签和项目等附加元数据保存在本地 SQLite 数据库中,不会修改 Agent 原始文件。该工具同时提供全屏 TUI 与可脚本化的 CLI,支持 `--json` 输出、按 Agent 筛选以及安全回收站删除。对于同时使用多个 AI 编程 Agent 的开发者而言,Wallfacer 解决了会话文件分散、难以辨识和难以找回历史上下文的问题。
716.3 KB
56.1 KB
81.5 KB
中文
██╗ ██╗█████╗ ██╗ ██╗ ███████╗█████╗ ██████╗███████╗██████╗ ██║ ██║██╔══██╗██║ ██║ ██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗ ██║ █╗ ██║███████║██║ ██║ █████╗ ███████║██║ █████╗ ██████╔╝ ██║███╗██║██╔══██║██║ ██║ ██╔══╝ ██╔══██║██║ ██╔══╝ ██╔══██╗ ╚███╔███╔╝██║ ██║███████╗███████╗██║ ██║ ██║╚██████╗███████╗██║ ██║ ╚══╝╚══╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝ ╚═╝
面向 Claude Code、Cursor CLI、Kiro CLI 和 Codex 的终端会话管理器——查看你曾启动过的每一个 AI 编程会话,然后在全屏浏览器中或直接通过命令行对它们进行命名、打标签、分组、搜索、恢复或删除。
Claude Code 会将每段对话存储为 ~/.claude/projects/ 下一个没有标题的 JSONL 文件,并按你当时所在的目录归类。Kiro CLI 也采用类似方式,不过它将文件放在统一扁平的 ~/.kiro/sessions/cli/ 文件夹中;Cursor CLI 则将每段聊天隐藏在 ~/.cursor/chats/ 下以哈希值命名的目录中;Codex 则按日期将其 rollout 归档至 ~/.codex/sessions/。几周之后,你会拥有来自四个 Agent 的数十份转录记录,彼此难以区分,也无从找到真正需要的那一份。
wallfacer 会为它们全部建立索引——只读,绝不触碰 Agent 的文件——并将你的标题、标签和项目保存在它自己的本地 SQLite 数据库中。
- 统一查看全部内容——来自每个目录、每个 Agent 的所有会话,按最近使用时间排序
- 整理——重命名会话、添加标签、归入项目
- 搜索——可搜索标题、首条提示词、目录、项目和标签
- 启动与恢复——可从任意位置启动新会话,或跳回旧会话
- 多 Agent 支持——Claude Code、Cursor CLI、Kiro CLI 与 Codex 并列显示;启动会话时选择 Agent,之后可按 Agent 筛选
- 安全删除——
rm会移入回收站;只有--purge才会永久删除 - TUI 和 CLI——为用户提供全屏浏览器,为脚本提供子命令和
--json - 可扩展——Agent 采用可插拔适配器;opencode 已列入路线图
在 macOS 或 Linux 上通过 Homebrew 安装:
brew tap pradipta/wallfacer https://github.com/pradipta/wallfacer
brew install pradipta/wallfacer/wallfacer
该 formula 位于此仓库内,而不是单独的 homebrew-wallfacer tap 中;这也是为什么 tap 命令需要明确写出其 URL。此后,brew upgrade wallfacer 可像往常一样工作。
或者通过 Go 安装:
go install github.com/pradipta/wallfacer@latest
要求 Go 1.22 及以上版本。预构建二进制文件位于 releases 页面;从源码构建的说明见开发指南。
wallfacer 是一个二进制程序,具有两个前端;具体进入哪个前端取决于你是否传入子命令:
| 你输入的命令 | 你得到的界面 |
|---|---|
wallfacer |
TUI——全屏、交互式会话浏览器。建议从这里开始。 |
wallfacer <command> |
CLI——适合脚本和命令行熟练操作的一次性子命令。 |
它们不是两个独立工具,也无需在二者之间切换:两者读写同一个 SQLite 索引,因此你在浏览器中为会话添加的标签,会立刻可由 wallfacer list --tag 查找到,反之亦然。TUI 能完成的所有操作,子命令同样可以完成。
(如果 stdout 不是终端——例如 wallfacer | less 或在脚本中运行——不带子命令的命令会打印帮助信息,而不是打开浏览器。)
打开浏览器后即可在其中操作:
或者通过 shell 操作:
wallfacer new ~/work/api --title "Fix flaky auth tests"
wallfacer resume "fix flaky auth tests" # 按标题或 ID 前缀恢复
wallfacer search auth
wallfacer list --project api --json # 供脚本使用
直接运行 wallfacer 会打开全屏会话浏览器:左侧为列表,右侧为详情面板,展示当前高亮会话的 wallfacer show 全部输出。
每一行都会显示项目、标签、目录、存在时长和 Agent——与 wallfacer list 输出的元数据相同。当终端宽度低于约 100 列时,详情面板会隐藏,列表将占据全宽。
| 按键 | 操作 |
|---|---|
↑/↓ j/k |
移动 |
/ |
对标题、项目、目录、标签和 Agent 名称进行模糊筛选 |
P / T / A |
循环切换项目/标签/Agent 筛选条件(循环回到未筛选状态) |
x |
清除项目、标签和 Agent 筛选条件 |
tab |
显示或隐藏详情面板 |
enter |
恢复会话——终端控制权会交给 Agent;退出后返回浏览器 |
n |
新建会话(依次询问 Agent、目录、标题、项目和标签) |
r / t / p |
重命名/编辑标签/设置项目 |
d |
删除至回收站,需确认 |
? / q |
帮助/退出 |
选择 Agent 是第一步,并通过单行选择器完成:使用 ←/→ 或数字选择,按 enter 继续,按 esc 退出。Claude Code 默认被选中;如果只注册了一个适配器,这一步会被完全跳过。
CLI——wallfacer <command>
每个子命令均为一次性操作:运行、打印输出并退出。它们与浏览器使用同一份索引。
| 命令 | 功能 |
|---|---|
wallfacer |
(无子命令) 打开交互式浏览器 |
wallfacer new [dir] [--agent A] [--title T] [--project P] [--tag t] |
在目录中启动一个新会话 |
wallfacer resume <ref> |
在会话原始目录中重新打开会话 |
wallfacer list [--project P] [--tag T] [--agent A] [--json] |
按最新优先列出会话;--agent 接受不区分大小写的子字符串 |
wallfacer search <query> |
搜索标题、提示词、目录、项目和标签 |
wallfacer show <ref> |
显示一个会话的完整详情 |
wallfacer rename <ref> <title> |
重命名会话 |
| `wallfacer tag add | rm …` |
| `wallfacer project set | clear ` |
wallfacer rm <ref> [--purge] [-f] |
将会话移入回收站(--purge 会永久删除) |
wallfacer sync |
重新扫描磁盘(每条命令前会自动运行) |
<ref> 可以是 ID 前缀(resume 5f2),也可以是精确标题(resume "smoke test")——对于存在歧义的引用,程序会列出候选项而非猜测。通过 wallfacer 之外启动的会话也会被自动发现;无需导入步骤。
wallfacer 会扫描 ~/.claude/projects/、~/.cursor/chats/、~/.kiro/sessions/cli/ 和 ~/.codex/sessions/,仅读取每个会话文件的开头部分,以获取其工作目录、时间戳和首条提示词(即自动标题)。每个 Agent 的记录都带有 Agent 类型,因此 wallfacer list 会显示 AGENT 列,--agent 可将结果缩小至不区分大小写的子字符串,例如 kiro 或 cursor。你的元数据保存在 ~/.local/share/wallfacer/ 中的 SQLite 数据库内——删除它只会丢失这层附加元数据,绝不会丢失对话。同步采用增量方式,因此即使有数百个会话也能保持快速。
rm 会将会话移入 wallfacer 的回收站。对于将一个会话分散到多个文件中的 Agent——Kiro CLI 会写入转录文件、元数据辅助文件、提示词历史和临时目录,而 Cursor CLI 则将聊天拆分在自身目录与按项目存放的转录文件之间——整套文件都会一同移动,因此删除的会话不会残留在 Agent 自身的会话选择器中。
浏览器每天会向 GitHub 查询一次是否存在更新版本;如果有,则会在底部状态栏提示一次。子命令会将该缓存结果重复输出到 stderr,因此更新提示永远不会进入 --json 输出或管道。没有任何操作会等待检查完成:查询属于浏览器,因为浏览器前端的生命周期足以跨越一次网络往返;子命令只读取缓存结果——即一次文件读取,不涉及网络——因此若更新检查较晚完成,只会在你下次运行 wallfacer 时显示。缓存位于数据目录中,WALLFACER_NO_UPDATE_CHECK=1 可关闭整个功能。
其他 Agent 可通过一个小型适配器接口接入——参见 docs/adding-an-agent.md。
有关构建、测试和发布,请参见开发指南。欢迎贡献,尤其欢迎新增 Agent 适配器。
该名称借自刘慈欣《黑暗森林》中的“面壁者”——他们被托付执行过于庞杂、他人无法追随的计划。
English / 原文
██╗ ██╗█████╗ ██╗ ██╗ ███████╗█████╗ ██████╗███████╗██████╗ ██║ ██║██╔══██╗██║ ██║ ██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗ ██║ █╗ ██║███████║██║ ██║ █████╗ ███████║██║ █████╗ ██████╔╝ ██║███╗██║██╔══██║██║ ██║ ██╔══╝ ██╔══██║██║ ██╔══╝ ██╔══██╗ ╚███╔███╔╝██║ ██║███████╗███████╗██║ ██║ ██║╚██████╗███████╗██║ ██║ ╚══╝╚══╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝ ╚═╝
A terminal session manager for Claude Code, Cursor CLI, Kiro CLI and Codex — see every AI coding session you've ever started, then name, tag, group, search, resume, or delete them, from a full-screen browser or straight from the command line.
Claude Code stores every conversation as an untitled JSONL file under ~/.claude/projects/, keyed by whatever directory you were in. Kiro CLI does much the same in a single flat ~/.kiro/sessions/cli/ folder, Cursor CLI buries each chat in a hash-named directory under ~/.cursor/chats/, and Codex files its rollouts by date under ~/.codex/sessions/. After a few weeks you have dozens of transcripts, across four agents, that you can't tell apart and no way to find the one you need.
wallfacer indexes them all — read-only, it never touches the agents' files — and keeps your titles, tags, and projects in its own local SQLite database.
- One view of everything — every session, from every directory and every agent, sorted by recency
- Organize — rename sessions, tag them, group them into projects
- Search — across titles, first prompts, directories, projects, and tags
- Launch & resume — start new sessions or jump back into old ones, from anywhere
- Multi-agent — Claude Code, Cursor CLI, Kiro CLI and Codex side by side; pick the agent when you start a session, filter by it afterwards
- Safe deletes —
rmmoves to trash; only--purgeis permanent - TUI and CLI — a full-screen browser for humans, subcommands +
--jsonfor scripts - Extensible — agents are pluggable adapters; opencode is on the roadmap
With Homebrew, on macOS or Linux:
brew tap pradipta/wallfacer https://github.com/pradipta/wallfacer
brew install pradipta/wallfacer/wallfacer
The formula lives in this repository instead of a separate homebrew-wallfacer tap, which is the only reason the tap needs its URL spelled out. After that, brew upgrade wallfacer works as usual.
Or with Go:
go install github.com/pradipta/wallfacer@latest
Requires Go 1.22+. Pre-built binaries are on the releases page; building from source is covered in the development guide.
wallfacer is one binary with two front ends, and which one you get depends on whether you pass a subcommand:
| You type | You get |
|---|---|
wallfacer |
The TUI — a full-screen, interactive session browser. Start here. |
wallfacer <command> |
The CLI — one-shot subcommands for scripts and muscle memory. |
They are not separate tools and there is nothing to switch between: both read and write the same SQLite index, so a session you tag in the browser is immediately findable by wallfacer list --tag, and vice versa. Anything the TUI can do, a subcommand can do too.
(If stdout isn't a terminal — wallfacer | less, or inside a script — the bare command prints help instead of opening the browser.)
Open the browser and work from there:
Or drive it from the shell:
wallfacer new ~/work/api --title "Fix flaky auth tests"
wallfacer resume "fix flaky auth tests" # by title or ID prefix
wallfacer search auth
wallfacer list --project api --json # for scripts
Bare wallfacer opens a full-screen session browser: a list on the left, and a detail pane on the right showing everything wallfacer show prints for whatever is highlighted.
Every row shows its project, tags, directory, age and agent — the same metadata wallfacer list prints. Below ~100 columns the detail pane steps aside and the list takes the full width.
| Key | Action |
|---|---|
↑/↓ j/k |
move |
/ |
fuzzy filter across titles, projects, dirs, tags and agent names |
P / T / A |
cycle the project / tag / agent filter (wraps back to unfiltered) |
x |
clear the project, tag and agent filters |
tab |
show or hide the detail pane |
enter |
resume — the terminal is handed to the agent; the browser returns when you exit |
n |
new session (asks for the agent, then directory, title, project, tags) |
r / t / p |
rename / edit tags / set project |
d |
delete → trash, with confirmation |
? / q |
help / quit |
The agent step comes first and is a one-line picker: ←/→ or a digit to choose, enter to go on, esc to back out. Claude Code is preselected, and the step is skipped entirely if only one adapter is registered.
The CLI — wallfacer <command>
Every subcommand is one-shot: it runs, prints, and exits. Same index as the browser.
| Command | What it does |
|---|---|
wallfacer |
(no subcommand) Open the interactive browser |
wallfacer new [dir] [--agent A] [--title T] [--project P] [--tag t] |
Start a new session in a directory |
wallfacer resume <ref> |
Reopen a session in its original directory |
wallfacer list [--project P] [--tag T] [--agent A] [--json] |
List sessions, newest first; --agent accepts a case-insensitive substring |
wallfacer search <query> |
Search titles, prompts, dirs, projects, tags |
wallfacer show <ref> |
Full details of one session |
wallfacer rename <ref> <title> |
Rename a session |
| `wallfacer tag add | rm …` |
| `wallfacer project set | clear ` |
wallfacer rm <ref> [--purge] [-f] |
Trash a session (--purge deletes permanently) |
wallfacer sync |
Rescan disk (runs automatically before every command) |
<ref> is an ID prefix (resume 5f2) or an exact title (resume "smoke test") — ambiguous references list the candidates instead of guessing. Sessions started outside wallfacer are picked up automatically; there's no import step.
wallfacer scans ~/.claude/projects/, ~/.cursor/chats/, ~/.kiro/sessions/cli/ and ~/.codex/sessions/, reading just the head of each session file for its working directory, timestamps, and first prompt (the automatic title). Every agent's listing carries the agent type, so wallfacer list shows an AGENT column and --agent narrows to a case-insensitive substring such as kiro or cursor. Your metadata lives in SQLite at ~/.local/share/wallfacer/ — delete it and you lose only the overlay, never a conversation. Sync is incremental, so it stays fast with hundreds of sessions.
rm moves a session to wallfacer's trash. For agents that spread one session over several files — Kiro CLI writes a transcript plus a metadata sidecar, prompt history and a scratch directory, and Cursor CLI splits a chat between its own directory and a transcript filed under the project — the whole set travels together, so a deleted session doesn't linger in the agent's own session picker.
Once a day the browser asks GitHub whether a newer release exists and, if so, mentions it once on its footer; subcommands repeat that cached answer on stderr, so it never lands in --json output or a pipe. Nothing ever waits for it: the lookup belongs to the browser because it is the front end that outlives a network round trip, and a subcommand only reads the cached answer — a file read, no network — so an update that lands late simply shows up the next time you run wallfacer. The cache lives in the data dir, and WALLFACER_NO_UPDATE_CHECK=1 turns the whole thing off.
Other agents plug in through a small adapter interface — see docs/adding-an-agent.md.
See the development guide for building, testing, and releasing. Contributions welcome — especially new agent adapters.
The name is borrowed from the Wallfacers of Liu Cixin's The Dark Forest — people entrusted with plans too sprawling for anyone else to follow.

