Wallfacer
架在多个编程 agent 之外、管理它们落盘会话的外部终端工具
§ 01定位
它不在任何 agent 的一次请求生命周期里,所以下面不打 Harness 层标签。它是一个架在多个编程 agent 之外的终端工具,把 Claude Code、Cursor CLI、Kiro CLI、Codex 散落在本地的会话统一索引起来,方便你搜索、恢复和整理[2]。
§ 02它实现了什么 · 怎么运作
- 它怎么拿到会话(同步):运行时扫描四个 agent 各自的会话目录——
~/.claude/projects/、~/.cursor/chats/、~/.kiro/sessions/cli/、~/.codex/sessions/。对每个会话文件,它只读文件头,取出四样东西:工作目录、时间戳、首条 prompt(拿来当自动标题)、以及文件来自哪个目录(据此判定属于哪个 agent)。同步是增量的,几百个会话也快;在 Wallfacer 之外新开的会话会被自动收进来,没有"导入"这一步[2]。 - 它把东西存在哪:你自己加的信息(改过的标题、标签、项目分组)存在一个独立的本地 SQLite 里(
~/.local/share/wallfacer/),各 agent 的原始会话文件一字不动[2]。 - 你能对它做什么:在 TUI 界面里浏览、或用命令行列出全部会话;按标题、首条 prompt、工作目录、项目、标签搜索;按 agent 过滤;选中一个会话直接恢复/拉起;重命名、打标签、归到某个项目;把不要的丢回收站或永久删(删掉的只是这层覆盖数据)[2]。
- 它目前还没做的:按会话正文内容搜索(FTS5 在路线图)、语义聚类、跨会话问答/摘要、导出、统计、桌面版——这些要么在路线图上、要么还没有[3]。
一个类比帮理解:它像给几个各写各的日记本做了一张统一的目录卡片——卡片记着每本日记的位置、时间、开头第一句,你靠卡片快速翻到某一篇;卡片本身不誊抄日记内容,日记也不因为卡片而改动。下面三条决策,都能对回这张"目录卡片"的做法。
§ 03我的初判 vs 实际
初判(Vivian):跨编程 agent 的会话管理器(不止 Claude Code),花样在"索引构建 + 管理可用性";给了三阶梯——① 按 agent 索引 ② 读项目历史、语义聚类同类对话 ③ memory 沉淀,能就大问题定位项目、衍生想法。不确定它做到哪一阶。
对照下来: - 押准的:它确实跨 agent(上面列了四个 + opencode 路线图[2]);而单 agent 的会话管理各家插件已做得很足,跨 agent 的统一才是它站得住的地方。"花样在索引与管理"也说对了。 - 一处要修:我第一版给它贴了"Memory 机制"这个 Harness 层标签,属于硬套。Harness 描述的是 agent 内部的工程,它站在所有 agent 外面,准确说法是上面的"定位"。 - 对你三阶梯的回答:它只做到第 ① 阶(那张目录卡片),而且从架构上看上不去 ②③(理由见决策三)。这个阶梯是好的思考工具,拆完后用法要变:与其当成"它会一路走到第三阶的路线图",不如当成"一个在①和②之间要做取舍的岔路口"。
§ 04关键设计决策
决策一:只读会话文件的"头部"——让它便宜安全的同一个选择,也定住了它的能力上限
- 对回机制
上一节说它同步时"只读文件头、取工作目录和首条 prompt"。这一步的选择,是不解析正文、且原始文件只读不写。
- 证据
[1][2]
- 增量(README 不会直说的)
这个选择有两面。正面是换来便宜、快、安全——删掉 Wallfacer 只丢那张目录卡片,一句对话都不少[2]。背面是它同时把能力封在了"元数据检索"这一层:因为不读正文,按内容搜索就做不了,所以全文搜索(FTS5)只能挂在路线图上、成了要补的洞[3]。让它轻的那个决定,和限制它的那个决定,是同一个。
- 一个能看清这层限制的具体例子——它怎么起标题
Claude Code 的一个 session 是没有标题字段的 JSONL(只按目录命名),标题得由 Wallfacer 自己定。它的办法是把文件头里的第一条 prompt 原样抽出来当标题[1][2],而不是读完整段会话、用模型概括一个更贴切的题目。连"给会话起个名"这种小事,它能做的也只有抽取、做不了合成——因为合成要读正文、要调模型,正是这套只读文件头的架构主动避开的。反过来说,一个愿意读正文、调模型的工具,就能给出"这次会话在解决什么"式的概括标题,而这正是 Wallfacer 用简洁换掉的东西。
- 代价
能廉价拿到的信息止于文件头;越过这条线的一切(内容搜索、摘要)都要另起一套。
- 可迁移判断
评估一个"极简又安全"的设计时,先去找这份简洁的代价——简洁常常靠预先放弃某种能力换来。看清它放弃了什么,就看清了它未来要补的洞在哪。
决策二:靠逆向各 agent 未公开的落盘约定来接入,而不是等它们提供接口
- 对回机制
上一节那四个写死的目录路径(
~/.claude/projects/等)和"每个 agent 一个适配器",就是这条决策的落点。 - 证据
[2]
- 增量
这些落盘格式是各 agent 的内部实现,没有公开承诺稳定。Wallfacer 读的是逆向出来的结构,某个 agent 一次版本更新就可能改动目录或字段,让一个适配器读不出东西——而且它不会报错,只表现为那个 agent 的会话忽然不见了。还有一层更隐蔽的耦合:它唯一真正拥有的数据(你打的标签、建的项目)以文件路径为键挂在它不拥有的会话文件上;某个 agent 若轮转或搬走旧会话,这些标签就会指向空处(推断——README 只说了删除 Wallfacer 自身数据的后果,没提反向情形)。
- 代价
换来"不用等任何 agent 配合、装上就能用",代价是绑在一批会变、无稳定承诺的格式上,长期得靠人盯着格式变化、维护适配器。
- 可迁移判断
靠逆向对方的存储格式做集成,和对着公开接口做集成,是可靠性完全不同的两类活。前者好在即刻可用、不求人;要让它可靠,得把"对方格式会变"当常态来设计,留监测、留容错。(我们自己接微信公众号那条路踩的就是这个:we-mp-rss 借道微信读书,格式一变就取不到,属于同一类问题。)
决策三:停在"索引"这一阶,更像是架构把后两阶挡在了外面,而非只是没排期
- 对回机制
上一节的"能搜索/过滤/恢复/打标,但没有正文搜索、没有聚类和综合",就是这条决策的现状。
- 证据
[3]
- 增量
你三阶梯的 ②③ 它上不去,原因在地基。它只读文件头、且跨的是四种异构格式的 agent,手里从来没有一份统一的、带语义的会话内容——而语义聚类、就历史问大问题,恰恰要先有这样一份统一表示。要做到 ②③,得先把各 agent 的全量正文解析成一套统一结构,那是换地基,不是在现有架构上加个功能。(它为何停在这里,创始人没明说;从痛点看是够用即止——他要的是找回某次会话,不是一个知识系统。推断。)
- 代价
天花板是"找回",到不了"洞见";它答不了"我过去这些项目里有什么共性"这类问题。
- 可迁移判断
把能力想成"索引→聚类→综合"的阶梯时,留个心眼——它们未必在一条路上。只读元数据的架构能把索引做得很好,却给不出综合所需的统一语义底座;想上综合那一阶,往往要换数据处理的地基。所以这种阶梯更像岔路口:先走轻的索引,就把重的综合推到了一次重构之后。
§ 05市场与需求
- 痛点有创始人的一手印证:在巨型 monorepo 里到处开会话,几天后想找回"上次我是怎么解决的"却无从检索[1]。一个人同时用多个编程 agent 越普遍,这个痛点越明显,跨 agent 也就是它相对单 agent 插件的立足点。
- 它的边界也清楚(推断):只读加本地 SQLite 的选择,决定了它是一个个人本地效率工具——不碰云、不做团队协作、不做知识综合。想象空间更大的 ②③ 阶属于另一个产品,顺着现在这套架构长不出来。
§ 06证据清单
- 创始人 pradiptasarma 的 Show HN 回复(已由管线抓取):只读覆盖层、读本地文件抽取工作目录+首条 prompt、元数据存本地 SQLite;痛点=monorepo 里找回过去会话 — https://news.ycombinator.com/item?id=49192219
- README:多 agent(Claude Code/Cursor CLI/Kiro CLI/Codex,opencode 路线图)、扫 4 个 agent 目录只读文件头、自有 SQLite、TUI+CLI、搜索/按 agent 过滤/恢复/重命名/打标/项目分组/回收站、增量同步、无导入步骤 — https://github.com/pradipta/wallfacer
- README 功能范围与路线图:无正文搜索/语义聚类/跨会话问答/摘要;路线图=FTS5 全文搜索、restore、导出 Markdown、统计、桌面版(Wails+xterm.js) — https://github.com/pradipta/wallfacer