
这是什么
OpenWolf 把一个编码项目的工作记忆放在代码旁边的 .wolf 文件夹里,再把它接到开发者本来就在用的 agent 上:为 Claude Code 与 Codex CLI 装生命周期钩子,为 OpenCode 装原生插件——会话开始时先给一份很短的项目索引和仍然相关的已存任务证据,读取索引过的文件之前先给说明与行号范围,一次编辑之后被改到的那条索引记录就地刷新。文件夹里放着任务检查点、文件索引、项目笔记、候选约定、bug 记录、agent 之间的交接包、带还原指针的旧会话笔记归档与一本 token 台账。文档写明记忆、索引与用量处理都在本地完成、不额外调用模型,唯一的网络流量是一个可选的工作进程去 npm 查有没有兼容的新运行时。用量数字来自 agent 自己写下的计数器,按 agent 与模型分组,缺的计数器就标为不可得。
谁做的持有这个仓库的账号占 123 次提交里的 78 次,其中 72 次来自同一个邮箱,作者名写作 Farhan Palathinkal Afsal(55 次)与 Farhan(17 次)。另有 11 次来自 cytostack@192.168.1.11,这个地址在提交历史里没有关联任何 GitHub 账号;第二个账号 doctorfarhan 占 21 次。贡献者名单有十四个人,除这两个账号与提交了 2 次的 meketreve 之外,其余十一个名字各占一次。
它是怎么搭起来的
组成 · 6一个放着本地文件的文件夹,加一层生命周期钩子,再加一个可选的守护进程负责 dashboard 与维护工作。组织性约束写在文档第一行:不另跑一个模型来维护记忆或生成摘要,所以这个工具知道的一切,要么是编码 agent 自己写下来的,要么是从那个 agent 自己的记录里读出来的。这一个决定解释了仓库的形状——一层大到足以住进别人事件系统里的钩子,以及一层带锁、带迁移、带归档与还原指针的文件格式,好让并发的会话不会互相弄丢写入。计量这边是读者而不是表:用量取自 Claude 会话记录、Codex rollout 与 OpenCode 插件记录里的 provider 计数器,而没有计数器的地方,文档说它就是不可得,而不是被重建出来。
- src/hooks/
- 集成面,也是仓库里最大的目录:37 个文件、271 KB,光
shared.ts就有 48,050 字节;其后是post-write.ts25,670、session-start.ts17,439、anatomy-store.ts16,796、ledger-math.ts14,695、pre-read.ts13,059、post-bash.ts11,596、pre-write.ts7,407、stop.ts7,275——受支持的宿主每暴露一个事件,就对应一个文件。 - src/templates/
- 安装时要写出去的全部东西,45 个文件、232 KB:
OPENWOLF.md3,014 字节、config.json2,501、cron-manifest.json1,604、STATUS.md1,471、cerebrum.md763、memory.md219、identity.md341,以及给AGENTS.md、GEMINI.md与 OpenCode 的三份规则片段;五个 skill;一份 31,141 字节的框架文档;以及给 OpenCode 的第二份运行时,25 个文件,其中shared.ts同样是 48,050 字节。 - src/tracker/
- 做读取与算术的九个文件、48 KB:
usage.ts14,966 字节、pricing.ts11,420(同一个文件以同样大小被复制进 dashboard)、cache-attribution.ts6,200、transcript-usage.ts6,077、waste-detector.ts3,958、usage-report.ts2,743、token-ledger.ts2,736、token-estimator.ts776、usage-worker.ts267。 - src/cli/
- 22 个文件、170 KB 的命令层:
update.ts35,607 与init.ts30,407 是仓库里除共享钩子运行时之外最大的两个文件,其后是bench.ts10,828、index.ts10,335、memory-migrate.ts9,219、daemon-cmd.ts8,651、cron-cmd.ts8,367、report.ts7,071、map.ts6,221、status.ts5,565、find.ts4,599、registry.ts4,299、handoff.ts3,048、scan.ts2,327。 - src/daemon/ 与 src/dashboard/
- 可选的那一半。守护进程六个文件、43 KB——
wolf-daemon.ts19,212 字节、cron-engine.ts14,291、context-audit.ts5,082、file-watcher.ts2,977、source-watcher.ts1,829、health.ts1,099——管着 cron 清单、钩子健康度、源码与 Git 监视器,以及src/utils/dashboard-auth.ts(2,952 字节)里的令牌校验。它服务的 dashboard 是 31 个文件、149 KB 的 React 应用,最大的是 25,640 字节的TokenUsage.tsx。 - docs/、docs/audit/ 与 tests/
docs/下十八份文档、378 KB,包括claude-codex-handoff-plan.md14,903 字节、session-visibility-plan.md13,548、repair-operations.md11,608,底下是一套 VitePress 主题(落地页组件 43,135 字节);docs/public/CNAME带着自定义域名,.github/workflows/docs.yml负责发布。docs/audit/另有六个 JSON、346 KB,光discussion-items.json就 268,270 字节。tests/三十个文件、199 KB,包括handoff.test.ts12,900、anatomy-store.test.ts12,155、concurrency.test.ts11,286、usage-integrity.test.ts10,544。
取舍,以及它替代了什么
维护记忆完全不调用模型 替代 另跑一个模型来总结会话、写笔记
文档开门就排除这条路:这个工具「does not run a second model to maintain memory or generate summaries」;cron 引擎遇到已退役的任务类型会直接抛错——「ai_task is no longer supported: OpenWolf makes no model calls. Remove this task from .wolf/cron-manifest.json.」换来的限制也被写明:agent「still needs to save useful semantic summaries; OpenWolf cannot infer every decision from a file edit.」
报 agent 自己的计数器,而不是自建一块计量表 替代 从工具自己能看到的东西反推用量
本地那套按输出大小的算术被明确与 provider 计数器分开——「Local output-size calculations remain estimates, separate from provider token counters」——汇出来的数字被标成「an API list-price estimate with stated assumptions, not a subscription invoice or a measurement of remaining quota.」;覆盖率按 agent 分别报告,好让缺失的计数器被看出是缺失。
上一个会话存下的东西,在校验器放行前一律当作不可信 替代 下次运行时把旧笔记当指令加载
文档用两句话写明:「Saved evidence is marked as untrusted context. Durable instructions are loaded automatically only when the independent protected-memory verifier approves them.」
src/hooks/trusted-memory.ts(3,516 字节)就是那道校验,同一个文件也被复制进 OpenCode 那份运行时副本。每个边界上只发变化过的上下文 替代 每次提示词都把存下的笔记重新加载一遍
交接方案文档写下意图——「before the next task turn, load only changed facts」——而 issue #126 报的正是实现没守住:
recent被算进了变化检测,于是在从没写过检查点的项目里,钩子每个提示词都注入一段「~400–700 tokens each」的证据块。读到的材料里还没有修法。为 OpenCode 多带一份钩子运行时,让它以插件形式跑起来 替代 只支持会调用外部钩子的宿主
两份副本在树里看得见——
src/templates/opencode-plugin/下 25 个文件,shared.ts两边都是 48,050 字节,靠scripts/sync-plugin-runtime.mjs(622 字节)保持一致——账单也看得见:issue #129 记下 OpenCode V2 换了插件 API 之后,安装器写出的形状不再能被加载。项目笔记进版本控制,运行期数据被忽略 替代 把整个文件夹挡在仓库之外
分界被写成规则,而不是交给生成的 ignore 文件:「Project notes can be shared through version control after review. Local usage, runtime and session data follow the generated ignore rules.」README 还对读者重申了复核这一步——「Review notes, bug records and indexed content before sharing them」。
依据docs/how-it-works.md(5,257 字符,全文打印)、README.md(16,080 字符,其中报告打印了前 6,000 字符)、issue #126 里引用的 docs/claude-codex-handoff-plan.md、完整的 274 个文件树及其体积、两级的目录汇总,以及上文引用过的 issue 与 pull request 正文。
制作过程
6 个阶段- 01
十二个 release,前四个月一个都没有
仓库建于 2026-03-15,123 次提交几乎全堆在后半段:三月 21 次、四月 4 次、五月 5 次、六月 2 次,然后七月 40 次、八月 39 次、九月 12 次,最后一次是 2026-09-15T16:00:52Z 的文档提交,把 2.5.2 标为已发布。十二个 release 从另一头讲同一个故事:最早的是 2026-07-14T22:54:31Z 的 v2.0.0,二十五分钟后是 v2.0.1;仓库里根本没有 1.x 的 release,却有三份 issue 是用户在 1.0.4 上写的,写完后升级到了 2.5.2。十二个里有八个落在 2026 年 8 月:08-19 两个相隔四十四分钟,08-20 三个小时里发了四个,08-29 又是两个;最后这一对的先后值得记下来——v2.5.1 发于 20:45:43Z,七分钟后才是 v2.5.0。每一个 release 都有对应的 tag,没有一个是 prerelease 或 draft。版本线周围是 2,369 个星、215 个 fork、11 个 watcher、60 个 open issue,仓库体积 11,086 KB,默认分支是 main,主题标签里同时有 agent-memory、context-engineering 与 token-optimization;贡献者名单十四人,123 次提交里 112 次能关联到 GitHub 账号。45 条共同作者尾注里有 37 条写的是 Claude Fable 5,另有五条分别写着 Opus 5、Opus 4.7 与 Opus 4.8;报告里最新的 issue 是 2026-09-29 开的。
- 02
记忆是一个装着纯文本文件的文件夹,每个写入者身上都有一把锁
装进去的是一个目录,不是一个服务。
docs/how-it-works.md列清了.wolf/里有什么——项目索引与可读的anatomy.md、memory.md、STATUS.md、cerebrum.md、buglog.json、放检查点与交接包的handoff/、带还原指针的archive/、token-ledger.json与hooks/——并把它一分为二:「Project notes can be shared through version control after review. Local usage, runtime and session data follow the generated ignore rules.」同一个文档还划下另一条线:「A checkpoint records task state separately from the full conversation」——所以那不是对话记录,agent 还被明确告知「still needs to save useful semantic summaries」,因为「OpenWolf cannot infer every decision from a file edit」。加载是增量而非累加:「OpenWolf can return changed context without repeatedly loading every old note」;回来的内容默认不被信任:「Saved evidence is marked as untrusted context. Durable instructions are loaded automatically only when the independent protected-memory verifier approves them」——src/hooks/trusted-memory.ts(3,516 字节)就是那道校验,OpenCode 插件里也有一份。并发写入靠锁与可恢复的事件记录,边界也写明:「These controls reduce lost updates; they do not replace a backup.」 - 03
token 台账读的是 agent 自己的计数器,并且把这一点写明
计量这一半是刻意的只读方,而不是一台计量表。
docs/how-it-works.md说它「reads available provider counters from Claude transcripts, Codex rollouts and OpenCode plugin records」,会「reconciles repeated records and reports coverage by agent」,而且「Missing counters remain unavailable」——缺的地方不外推补上。记账口径写在同一处:「Input totals include cached input. Output includes reasoning where reported. Pricing separates the relevant input categories and uses each recorded provider and model.」最后那个数字是什么,也没留给读者猜:「The result is an API list-price estimate with stated assumptions, not a subscription invoice or a measurement of remaining quota.」另有两类数字被有意分开:README 把token-ledger.json描述为「Operational records and separate content-size estimates」,而 Bash 输出治理器自己的算术被标为本地计算,因为「Local output-size calculations remain estimates, separate from provider token counters」。代码也照这条分界走:src/tracker/九个文件 48 KB,其中usage.ts14,966 字节、pricing.ts11,420(同一个文件以同样大小被复制进 dashboard)、cache-attribution.ts6,200、transcript-usage.ts6,077 与 776 字节的token-estimator.ts。覆盖率按 agent 分别报告,因为一份缺失或被截断的记录本身就是一条限制。 - 04
台账里真正记下的数字,以及每个数字的依据
材料里的每个用量数字都来自用户自己的台账,而且都说明了依据。issue #118 量到的是一次重新注入三条规则提醒的开销:
token-ledger.json里两个会话分别记到 4,392 与 3,030 token,而配置里的会话摘要预算是 1,500——这次提醒花掉的是它所处预算的好几倍,数字是直接从工具自己的台账里引的。issue #126 把每个提示词都会注入的证据块估为「~400–700 tokens each」,再据此乘出 60 轮会话的「~30k tokens」;前者是他的测量,后者是他的乘法,两个都不是项目自己给出的数字。issue #131 在一个用了大约五个月的项目里数出 1,221 条 session 记录、对应 110 个不同的 session id,同一个会话最多被记了 65 遍,并追到每轮都会触发、却把每次触发都当成会话结束的 Stop 钩子上。issue #114 报的是一个项目上 anatomy 命中/未命中为 5/32(14%),其中 113 次未命中里有 43 次读的是根本进不了索引的文件。读到的材料里没有任何节省百分比:README 摘录在任何结果之前就断了,本该产出这些数字的 A/B 工具链只以文件形式出现在树里、没带数字——scripts/benchmark/run-ab.mjs(5,926 字节)驱动六个任务文件。最接近前后对比的东西在 pull request #115 里:60 个并发的 post-read 钩子,加锁之前只留下 60 次读取里的 6 次,之后是 60 次,按作者的说法是在「on real multi-process runs」上量的。 - 05
一套钩子运行时,外加为「没有钩子的宿主」准备的第二份副本
README 里那张集成清单本身就是设计:「Hooks: Claude Code, Codex CLI · Plugin: OpenCode · Compatible hooks: Grok Build · Context only: Cursor, Gemini CLI, Antigravity」——两个会调用外部钩子的宿主、一个加载插件的宿主、一个靠 Claude 兼容发现机制够到的宿主,以及三个只能往规则文件里塞一段文本的宿主。
src/agents/就是为这种分布写的十个小适配器,从 6,838 字节的codex.ts到 490 字节的grok.ts。OpenCode 调不了外部钩子,于是拿到的是以插件形式交付的运行时,而这份运行时在仓库里存了两遍:src/templates/opencode-plugin/下 25 个文件,其中shared.ts是 48,050 字节——与src/hooks/shared.ts一样大——靠scripts/sync-plugin-runtime.mjs(622 字节)保持一致。pull request #113 把 OpenCode 的状态文件按有效 session id 拆开,并回收超过七天的会话文件,维护者直接采纳了那个回收逻辑,写道:「Splitting state per session without it would have grown the directory without bound.」第二种交付形状的代价写在 issue 里:#129 说 OpenCode V2 换掉了插件 API,安装器写下的插件还是 V1 形状,而 V2 每次启动会把它发现两次;#130 说在 Windows 上 SessionStart 钩子可能超过安装器给 Claude Code 与 Codex 一并配置的五秒超时。两个还开着的 pull request 走的是同一条路:#122 把 Antigravity 的生命周期事件桥接进已有钩子,#127 靠复用.wolf/hooks/加上 Pi 与 Oh My Pi,报告 327 个测试通过。 - 06
十六份报告、一个 pull request,以及被留在记录里的分歧
最热闹的一段来自一位贡献者的报告。pull request #115「2.5.1: multi-writer safety, project boundaries, and honest results」一次关掉 #78 到 #93 的十六个缺陷——「Fifteen were found and reported by @davdittrich, one by @krsfer, each with a reproduction」——而这位报告者自己也为每个缺陷各开了一个修复(#94、#98 到 #103、#105 到 #113),当时全都还开着。维护者写明先后:「Those PRs came first and should be weighed against this branch before merging either.」其中两个被整体采纳并点名——#103 里读取失败时的描述符泄漏、#113 里的会话文件回收——#103 还得到一句很少写进更新日志的话:「The version that shipped had the same leak until I read yours.」验证方面的说法是 271 个测试通过,每个新测试都先在未修复的代码上跑过并确认会失败。分歧被写下来而不是抹平:#106 把守护进程控制收窄到 PM2 进程名,回复说明 2.5.1 改用
.wolf/daemon.pid这份归属记录,好让由openwolf dashboard启动的守护进程也能被停掉。其余几轮更短:#118 的规则上限「was adapted in the 2.5.2 branch and is covered by tests」,#104 关于共享同一个.wolf的工作除了extra_roots之外都进了 2.5.2,而 #121 修正过的那条 dashboard 警告「has not been applied yet.」
相关档案
全部档案 →第 070 号
delegate-skills
一个技能包,给每一种编码 agent CLI 各配一份委派技能:编排方写好自足的任务书,另一条 CLI 去改真实工作树,而审查与提交留给人。
第 108 号
agy-staff
它把 Google 的 Antigravity CLI 雇成一名员工。宿主 agent——Claude Code、Codex 或 Pi——留住决策权,把调研、评审和范围明确的改动交给一个跑在后台的 Gemini 3.8 Flash 员工,用一个 job id 来回传话。
第 109 号
Whiteboard
一个桌面应用,让 agent 和人共用同一块画布。agent 把审查画出来——时序图、实体关系图、钉在某次提交上的代码引用——而画布上的每个形状都能跳回它被画出来时所指的那段代码。