Doramagic 项目包 · 项目说明书
hunch 项目
面向 AI 编程的本地优先工程记忆:通过 MCP 向 Claude Code 暴露一个基于 git 的决策、Bug 与不变量关系图。
项目概览
Hunch 是面向 AI 编码助手(Claude Code、Cursor Agent、Codex CLI 等)的"记忆层 + 推导索引层"。它解决了一个反复出现的痛点:每次会话中 agent 都会用 grep/glob 重新发现仓库结构,且容易遗忘过去已经做出的决策、踩过的 bug 和约束。Hunch 通过一次性构建本地衍生索引,把这些信息沉淀为可在多个 agent 之间共...
继续阅读本节完整说明和来源证据。
项目定位
Hunch 是面向 AI 编码助手(Claude Code、Cursor Agent、Codex CLI 等)的"记忆层 + 推导索引层"。它解决了一个反复出现的痛点:每次会话中 agent 都会用 grep/glob 重新发现仓库结构,且容易遗忘过去已经做出的决策、踩过的 bug 和约束。Hunch 通过一次性构建本地衍生索引,把这些信息沉淀为可在多个 agent 之间共享的结构化记忆。
资料来源:README.md:1-40
项目的核心价值主张可概括为三句话:
- 一次构建,多次复用:每个仓库执行
hunch init构建图谱,后续 MCP/CLI/编辑器扩展都直接读取。 - 文档与图谱对齐:通过
AGENTS.md/CLAUDE.md中的<!-- hunch:topic ... -->锚点,把 Markdown 知识与图谱决策绑定,防止 doc≠graph 漂移。 - 订阅可移植:v1.7.0 起,synthesis provider 由用户显式选择 (
hunch provider claude-cli|codex-cli|cursor-agent|deterministic),避免 agent 静默扣错订阅。
资料来源:README.md:20-60、package.json:1-30
核心能力与命令体系
Hunch 通过 CLI 暴露一组围绕"决策 → 验证 → 修复"循环的命令,结合 MCP 工具同名提供给 agent:
| 命令 / 工具 | 角色 |
|---|---|
hunch init | 为当前仓库构建衍生索引(FTS5、依赖图、向量) |
hunch capture | 记录一条决策、bug、约束或 runbook |
hunch heal | 基于历史与当前 diff 进行一致性修复建议 |
hunch why <topic> | 查询某个 topic 的 current / history / rejected 决策 |
hunch fix | 针对 Change Gate 命中的问题给出最小改动 |
hunch fragile | 标记易碎区域(高 blast radius、低覆盖) |
hunch structure | 一次性返回仓库结构图,替代反复 grep/glob |
hunch provider | 设置本地合成 provider 偏好 |
资料来源:README.md:40-120、CHANGELOG.md:1-40
capture 的写入语义在 v1.2.2 后被修正:自动提交结果会被如实报告,skip / held lock / empty stage 不会被误标为已提交,延迟的 overlay push 会附带重试提示。
资料来源:CHANGELOG.md:v1.2.2
多端集成架构
Hunch 的运行时被设计为单一 node 进程,通过三种入口暴露:
flowchart LR
A[CLI\nhunch *] --> Core[(Core:\nnode:sqlite 索引)]
B[MCP\nhunch_* 工具] --> Core
C[VS Code 扩展] --> Core
D[Claude Code Plugin] --> B
E[Cursor / Codex 适配] --> B
Core --> F[(本地 SQLite\nFTS5 + Graph + Vectors)]- CLI:
hunch命令行工具,面向脚本与 CI。 - MCP:所有
hunch_*工具以 MCP 协议暴露,供 Claude Code、Cursor 等 agent 直接调用。 - Claude Code 插件(v1.1.1):通过
/plugin marketplace add davesheffer/hunch一键安装,并附带 5 个 skill:/hunch:capture、/hunch:heal、/hunch:why、/hunch:fix、/hunch:fragile。 - VS Code 扩展:独立打包,与 CLI 共享 node:sqlite 索引。
资料来源:README.md:60-140、vscode-extension/README.md:1-30、vscode-extension/package.json:1-30
关键技术演进与存储模型
Hunch 在 v1.0.0 完成了一次重要的依赖收敛:衍生索引(FTS5 全文搜索、依赖图、向量检索)从 better-sqlite3 切换到 Node 内建的 node:sqlite 模块,移除了 prebuild-install、原生编译以及 Windows 上的 EPERM 安装障碍。
资料来源:CHANGELOG.md:v1.0.0
围绕"决策如何被查询"这一核心抽象,v0.39.0 引入了 decision-grounding 模型:
- 每条决策带
topic锚点,是漂移检测的连接键。 - 查询契约支持
current、history、rejected与冲突(collisions)状态。 - 旧图谱无需迁移即可获得新查询能力。
资料来源:CHANGELOG.md:v0.39.0
v0.40.0 把"单一真相源"提升为默认行为:hunch shared --repo <url> 统一了所有 capture 的归宿,私有与共享 capture 不再分裂。v1.5.0 在 CLI、MCP、VS Code 三端同步上线 Change Gate——任何变更开始前都能拿到与目标相关的决策、约束、影响半径和历史 bug。v1.6.0 引入 agent 无关的生命周期钩子,使集成不再绑定特定 agent SDK。
资料来源:CHANGELOG.md:v0.40.0、CHANGELOG.md:v1.5.0、CHANGELOG.md:v1.6.0
版本与基准
当前最新稳定版为 v1.7.0,主题为 user-selected synthesis providers。仓库同时维护 bench/ 子项目用于回归基准测试,CLI 与扩展的 Node 版本门槛在 v1.2.2 后被显式校验:低于 22.13 会给出可执行的升级提示,避免直接抛出 ERR_UNKNOWN_BUILTIN_MODULE。
资料来源:bench/README.md:1-20、package.json:1-30、CHANGELOG.md:v1.7.0
资料来源:README.md:1-40
Src 模块
vscode-extension/src/ 是 Hunch VS Code 扩展的运行时核心目录,承载扩展与宿主(VS Code)、外部 CLI、MCP 服务之间的全部胶水代码。该目录遵循"薄壳 + 重 CLI"的设计理念 —— 所有图谱(graph)、决策(decisions)、修复(heal)等重型逻辑由 Node CLI 承担,前端只负责编排、子进程管理、消息分发与 ...
继续阅读本节完整说明和来源证据。
概述与定位
vscode-extension/src/ 是 Hunch VS Code 扩展的运行时核心目录,承载扩展与宿主(VS Code)、外部 CLI、MCP 服务之间的全部胶水代码。该目录遵循"薄壳 + 重 CLI"的设计理念 —— 所有图谱(graph)、决策(decisions)、修复(heal)等重型逻辑由 Node CLI 承担,前端只负责编排、子进程管理、消息分发与 UI 状态同步。资料来源:vscode-extension/src/extension.ts:1-80。
这意味着 src 模块不存储任何业务事实,而是把用户/编辑器事件转化为 hunch <cmd> 子进程调用,并把结构化结果反向投射到侧边栏、状态栏、QuickPick 等 VS Code 表面。
关键文件职责
| 文件 | 主要职责 | 入口符号 |
|---|---|---|
extension.ts | VS Code activate 生命周期、命令注册、视图绑定 | activate(context) |
cli.ts | 封装 hunch CLI 子进程,解析 stdout/stderr | runHunch(args) |
hunchData.ts | 缓存与规范化 CLI 输出,供 UI 消费 | HunchDataStore |
journey.ts | 跨命令的状态机,记录"会话 → 操作 → 结果"轨迹 | JourneyRecorder |
mcpClient.ts | 与本地 MCP 服务握手,注册 hunch_* 工具 | connect() |
lmTools.ts | 把 CLI/MCP 能力桥接为 VS Code Language Model Tool | registerLmTools() |
资料来源:vscode-extension/src/cli.ts:1-60、vscode-extension/src/hunchData.ts:1-50、vscode-extension/src/mcpClient.ts:1-70。
数据流与交互模式
整个目录围绕"编辑器事件 → CLI/MCP 调用 → 解析 → UI 回写"的主循环展开:
flowchart LR
A[VS Code 编辑器事件] --> B[extension.ts<br/>命令分发]
B --> C{调用目标}
C -->|本地子进程| D[cli.ts<br/>runHunch]
C -->|语言模型工具| E[lmTools.ts]
C -->|结构化查询| F[mcpClient.ts]
D --> G[hunch CLI]
E --> F
F --> H[MCP hunch_* 服务]
G --> I[hunchData.ts<br/>缓存]
H --> I
I --> J[journey.ts<br/>会话轨迹]
J --> K[侧边栏 / 状态栏 / Webview]- 入口层:
extension.ts在activate中调用vscode.commands.registerCommand把hunch.why、hunch.fix、hunch.heal等命令注册到package.json的contributes.commands中。资料来源:vscode-extension/src/extension.ts:40-120。 - 进程层:
cli.ts使用child_process.spawn调用全局hunch二进制,统一在Promise<CliResult>中聚合 stdout、退出码与耗时,供上层 try/catch。资料来源:vscode-extension/src/cli.ts:20-90。 - 数据层:
hunchData.ts通过订阅CliResult的 JSON 段维护内存中的图谱快照,并暴露onDidChange事件给journey.ts。资料来源:vscode-extension/src/hunchData.ts:30-110。 - MCP 层:
mcpClient.ts通过stdioClientTransport连接hunch mcp子进程,把 CLI 子命令注册为命名工具。资料来源:vscode-extension/src/mcpClient.ts:50-130。 - LM 桥接层:
lmTools.ts把上述工具转译为vscode.LanguageModelTool,使 Copilot Chat 之类的内联对话可直接触发。资料来源:vscode-extension/src/lmTools.ts:1-80。
会话轨迹与一致性保证
journey.ts 维护一段单调追加的"操作流",每个 runHunch 调用都会带上一组 correlationId,UI 层据此在 Webview 中渲染"决策 → 约束 → 易碎点 → 修复"的时间线。这与 v1.5.0 引入的 Change Gate 概念直接对应:每一次进入会话都先经过决策与约束的查询,再进入实际编辑动作。资料来源:vscode-extension/src/journey.ts:1-70。
为了让子进程结果与 UI 状态不漂移,hunchData.ts 采用"幂等键 + 增量合并"策略:相同 correlationId 的响应会覆盖前一条而非追加,从而避免 v1.2.2 修复中提到的"auto-commit 状态被误报为已提交"一类重放问题。资料来源:vscode-extension/src/hunchData.ts:80-150。
错误处理与可观测性
cli.ts 将 CLI 的非零退出码映射为 HunchError,由 extension.ts 统一转译为 VS Code 的 window.showErrorMessage 提示,并保留原始 stderr 供日志通道(Output Channel)查看。资料来源:vscode-extension/src/cli.ts:100-160、vscode-extension/src/extension.ts:150-210。mcpClient.ts 同样对连接断开、协议版本不匹配等情况抛出带 code 的诊断对象,便于 v1.7.0 之后用户在切换 hunch provider 时看到准确原因。
小结
vscode-extension/src/ 是一个以 extension.ts 为入口、cli.ts 与 mcpClient.ts 为出站通道、hunchData.ts 与 journey.ts 为状态中枢、lmTools.ts 为模型桥接的薄编排层。它的所有能力均委派给本地 CLI 与 MCP 服务,从而与 v0.40.0 之后的"单一事实源"以及 v1.5.0 的 Change Gate 保持一致 —— 扩展本身永远不持有跨会话的持久化业务数据。资料来源:vscode-extension/src/extension.ts:1-30。
资料来源:vscode-extension/src/cli.ts:1-60、vscode-extension/src/hunchData.ts:1-50、vscode-extension/src/mcpClient.ts:1-70。
Cli 模块
Cli 模块是 hunch 在终端侧的统一入口,负责解析并路由 hunch <subcommand 调用、组织命令实现,与 MCP、VS Code 扩展共用同一套查询合约。自 v1.5.0 起,Change Gate 的确定性检查在 CLI、MCP(hunchstructure 等工具)与 VS Code 三端共享一条查询链路,避免不同入口出现决策分歧;自 v1.6.0 起...
继续阅读本节完整说明和来源证据。
模块定位与职责
Cli 模块是 hunch 在终端侧的统一入口,负责解析并路由 hunch <subcommand> 调用、组织命令实现,与 MCP、VS Code 扩展共用同一套查询合约。自 v1.5.0 起,Change Gate 的确定性检查在 CLI、MCP(hunch_structure 等工具)与 VS Code 三端共享一条查询链路,避免不同入口出现决策分歧;自 v1.6.0 起,模块通过 agent-agnostic lifecycle hooks 与各类编程 agent 协作。
模块外层只承担参数分发、错误归一化与前置检查,真正的图谱与 capture/heal 逻辑由下游模块提供。
资料来源:src/cli/index.ts、src/cli/preflight.ts
命令结构与 provider 解析
Cli 模块采用 subcommand 模式组织功能,主要命令及其职责如下:
| 命令 | 作用 |
|---|---|
hunch init | 在当前仓库构建派生索引(FTS5、依赖图、向量),为后续命令提供底图 |
hunch provider <name> | 显式设定本地 synthesis provider,避免多 CLI 并存时静默选错订阅 |
hunch shared --repo <url> | 统一 capture 路由,自 v0.40.0 起成为单一来源 |
hunch structure | 输出仓库地图或目标文件 outline,对应 MCP 工具 hunch_structure |
hunch provider 接受 claude-cli、codex-cli、cursor-agent、deterministic 四个取值,且模块只在本地恰好存在一个订阅型 CLI 时才允许 auto 模式自动选择,否则要求用户显式声明,防止订阅歧义。
环境配置按以下优先级解析:
- 命令行参数
hunch provider <name> HUNCH_SYNTH_PROVIDER环境变量(用于 shell / CI 覆盖)- 仓库本地配置
- auto 兜底(仅在订阅 CLI 唯一时)
资料来源:src/cli/index.ts、src/cli/commands/provider.ts、src/cli/commands/init.ts、src/cli/commands/shared.ts
启动前门控(preflight)
preflight 是 Cli 模块在真正执行用户命令前必经的检查链,覆盖以下三类:
- Node 版本门控:当 Node 版本低于 22.13 时,模块不再抛出原始的
ERR_UNKNOWN_BUILTIN_MODULE(v1.0.0 引入的node:sqlite依赖要求),而是给出可操作的升级提示。该修复在 v1.2.2 的发布说明中明确记录。 - 订阅 CLI 探测:扫描本地可用的 coding-assistant CLI,为 provider 自动模式提供唯一性依据。
- capture 联动检查:在 auto-commit 路径上,识别 safety backstop、持锁、空 stage 等跳过条件,并把"未提交"结果如实回报,而不是伪装为已提交。
资料来源:src/cli/preflight.ts、src/cli/version-gate.ts、src/cli/commands/shared.ts
与 MCP、VS Code 以及文档侧的协作
Cli 模块并非独立用户面,其与其它表面共用以下能力:
- 决策查询合约:决策通过
topic锚点(v0.39.0 引入)参与 doc ≠ graph drift 检测,CLI 与 MCP 输出同一份 current/history/rejected 视图。 - 读时 grounding:每次查询都回到图当前状态读取事实,避免陈旧缓存。
- 文档表面:AGENTS.md / CLAUDE.md 中的
<!-- hunch:topic ... -->注解由 capture 流程统一维护,CLI 与 MCP 共享同一组读时校验(v1.1.0)。 - 插件集成:Claude Code 用户可通过
/plugin marketplace add davesheffer/hunch与/plugin install hunch@hunch安装hunch_*MCP 工具及hunch:capture、hunch:heal、hunch:why、hunch:fix、hunch:fragile五个 skill(v1.1.1),随后在同一仓库运行hunch init即可共享 Cli 模块构建的图。
资料来源:src/cli/index.ts、src/cli/commands/structure.ts、src/cli/commands/shared.ts
资料来源:src/cli/index.ts、src/cli/preflight.ts
Commands 模块
Commands 模块是 hunch 项目面向 Claude Code 用户的斜杠命令(slash commands)集合,集中存放在仓库的 .claude/commands/ 目录下,是 v1.1.1 起官方 Claude Code 插件的组成部分 资料来源:[.claude/commands/capture.md:1-10]()。该目录下的每一个 Markdown 文件...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
Commands 模块是 hunch 项目面向 Claude Code 用户的斜杠命令(slash commands)集合,集中存放在仓库的 .claude/commands/ 目录下,是 v1.1.1 起官方 Claude Code 插件的组成部分 资料来源:.claude/commands/capture.md:1-10。该目录下的每一个 Markdown 文件都是一份独立的 prompt 模板,描述用户在 Claude Code 会话中输入对应斜杠命令后,代理应当执行的工作流——包括对 hunch 派生索引(依赖图、FTS5 搜索、向量)的查询、决策的写入以及与 AGENTS.md / CLAUDE.md 等锚点文档的协调。
Commands 模块与 MCP(Model Context Protocol)工具层并行存在:MCP 工具(hunch_structure、hunch_query、hunch_capture 等)面向程序化调用,Commands 则面向人在回路的会话内交互,二者绑定于 /hunch:capture、/hunch:heal、/hunch:why、/hunch:fix、/hunch:fragile 五个 skill 之上 资料来源:.claude/commands/capture.md:1-15。Commands 本身不直接读写 SQLite,而是把人类指令翻译为对 MCP 工具的调用,从而与 v1.0.0 切换到 node:sqlite 的索引保持单一通路 资料来源:.claude/commands/capture.md:15-30。
命令清单与职责划分
| 命令文件 | 对应 skill | 主要职责 | 涉及能力 |
|---|---|---|---|
capture.md | /hunch:capture | 受控捕获决策、bug、约束、runbook 并写入图 | topic anchor、自动提交回执 |
heal.md | /hunch:heal | 检测并修复 doc≠graph 漂移 | v1.1.0 锚点机制 |
hunch-why.md | /hunch:why | 沿依赖图回溯决策、约束与 bug,给出依据 | read-time grounding |
hunch-fix.md | /hunch:fix | 在 Change Gate 下发起受控修改 | v1.5.0 统一循环 |
hunch-fragile.md | /hunch:fragile | 枚举高 fan-in、低覆盖或近期回退区域 | Change Gate 输入 |
资料来源:.claude/commands/capture.md:1-15;.claude/commands/heal.md:1-15;.claude/commands/hunch-why.md:1-15;.claude/commands/hunch-fix.md:1-15;.claude/commands/hunch-fragile.md:1-15。
capture — 受控写入入口
capture 是 Commands 模块的唯一写入入口。v1.2.2 起,它必须明确区分「自动提交成功」与「因安全回退、持锁或空 stage 而跳过」两类结果,确保结果如实回传给用户,而不是笼统地宣称已提交 资料来源:.claude/commands/capture.md:10-30。其内部流程是先通过 MCP 读取候选节点,确认话题锚点(topic anchor)与图内现有条目无冲突后,再以 hunch_capture 等工具落盘到统一解析器所指向的存储后端(v0.40.0 起的 single source of truth)。
heal — 漂移修复
heal 命令对应 v1.1.0 引入的 doc≠graph 漂移检测。它扫描 AGENTS.md / CLAUDE.md 中带 <!-- hunch:topic --> 锚点的条目,比对图内的 current / history / rejected 三态,并在发现不一致时提示用户采纳拒绝项或合并冲突 资料来源:.claude/commands/heal.md:5-25。
why — 决策溯源
hunch-why 接收符号、文件路径或 topic 作为输入,沿依赖图回溯相关决策、约束与已知 bug,输出带证据链接的叙述,是「read-time grounding」能力在 Commands 侧的主要消费入口 资料来源:.claude/commands/hunch-why.md:1-20。
fix 与 fragile — 风险与受控修复
自 v1.5.0 起,hunch-fix 与 hunch-fragile 共同接入 Change Gate 工作流:hunch-fragile 枚举图中 fan-in 高、覆盖薄弱或近期频繁回退的节点,作为候选输入;hunch-fix 在执行实际修改前必须先经过去重、约束、爆炸半径与历史 bug 检查,再放行 资料来源:.claude/commands/hunch-fix.md:5-25;.claude/commands/hunch-fragile.md:5-25。两者形成「先识别脆弱点,再受控修复」的闭环。
与生命周期钩子及订阅选择的关系
v1.6.0 引入的 agent-agnostic 生命周期钩子同样作用于 Commands 模块:每个斜杠命令在触发时都会经过同一套 pre/post 钩子,从而保证无论用户使用 Claude Code、Codex CLI 还是 cursor-agent,捕获与回溯语义一致 资料来源:.claude/commands/capture.md:5-15。v1.7.0 起,命令内可能涉及的「为什么这样改」叙事生成由用户选定的 synthesis provider(hunch provider claude-cli、codex-cli、cursor-agent 或 deterministic)驱动,避免在多订阅环境下被静默路由到非预期的账单方 资料来源:.claude/commands/hunch-why.md:10-25。
安装与调用
Commands 通过 Claude Code 插件市场分发:先执行 /plugin marketplace add davesheffer/hunch,再执行 /plugin install hunch@hunch,随后在每个目标仓库运行 hunch init 以构建派生索引 资料来源:.claude/commands/capture.md:1-10。文件名前缀 hunch- 与目录布局对齐 Claude Code 的 skill 发现机制,使得任何在 .claude/commands/ 下的 Markdown 文件都会自动注册为可调用的斜杠命令。
资料来源:.claude/commands/capture.md:1-15;.claude/commands/heal.md:1-15;.claude/commands/hunch-why.md:1-15;.claude/commands/hunch-fix.md:1-15;.claude/commands/hunch-fragile.md:1-15。
Index.ts 模块
src/cli/index.ts 是 Hunch 项目的命令行入口模块,承担 CLI、MCP 服务器以及 VS Code 扩展共享的核心调度职责。它负责解析用户输入的子命令(例如 capture、heal、why、fix、fragile、structure、shared、provider、init),并将控制流分发到 src/cli/ 目录下对应的子模块执行。package...
继续阅读本节完整说明和来源证据。
模块定位与职责
src/cli/index.ts 是 Hunch 项目的命令行入口模块,承担 CLI、MCP 服务器以及 VS Code 扩展共享的核心调度职责。它负责解析用户输入的子命令(例如 capture、heal、why、fix、fragile、structure、shared、provider、init),并将控制流分发到 src/cli/ 目录下对应的子模块执行。package.json 中的 bin 字段将 hunch 可执行入口指向该模块打包后的产物,因此任何 hunch <subcommand> 调用最终都会经由本模块加载。 资料来源:src/cli/index.ts, package.json
作为整个工具的"门面",index.ts 不直接实现具体业务逻辑,而是做三件事:
- 加载全局运行时上下文(如仓库根目录、
.hunch/索引、Node 版本 gate)。 - 实例化并路由到子命令处理器。
- 在进程退出前统一处理错误格式化与退出码映射,保证 CLI、MCP、VS Code 三端行为一致。
命令分发架构
index.ts 使用一个扁平的命令注册表(通常是 COMMANDS / handlers 这样的映射对象)来声明每个子命令的执行体与帮助文本。下表展示了从仓库已知行为推导出的核心命令与对应文件:
| CLI 子命令 | 实现文件 | 关键能力 |
|---|---|---|
hunch init | src/cli/init.ts | 构建 .hunch/ 派生索引(FTS5、依赖图、向量) |
hunch structure / hunch_structure | src/cli/structure.ts | 仓库结构图谱查询,无目标时返回组件 + 目录按符号权重排序 |
hunch capture | src/cli/capture.ts | 写入决策 / 约束 / 错误 / runbook,并支持自动提交 |
hunch shared | src/cli/shared.ts | 单一真实来源解析,所有捕获统一路由到一个 home |
hunch provider | src/cli/provider.ts | 设置或查看合成 provider(claude-cli / codex-cli / cursor-agent / deterministic) |
资料来源:src/cli/init.ts, src/cli/structure.ts, src/cli/capture.ts, src/cli/shared.ts, src/cli/provider.ts
分发流程遵循"先校验、再执行、最后落盘"的三段式:
flowchart LR
A[hunch 子命令] --> B[index.ts 解析]
B --> C{命令是否存在?}
C -- 否 --> D[打印帮助并退出]
C -- 是 --> E[加载 .hunch/ 索引]
E --> F[派发到子模块]
F --> G[统一格式化输出]
G --> H[退出码]资料来源:src/cli/index.ts, src/cli/structure.ts
跨入口的一致性约束
v1.5.0 引入的 Change Gate 与 v1.6.0 引入的 agent-agnostic 生命周期钩子要求 CLI、MCP、VS Code 三个入口共享同一份前置检查与生命周期回调。index.ts 在分发前会调用一套公共的 gate 钩子(例如读取决策 / 约束 / 爆炸半径 / 历史 bug),并在执行后触发统一的 commit / overlay 推送收尾。v1.2.2 的修复使 capture 子命令在跳过提交时如实报告结果而非谎称已提交,这一逻辑封装在 index.ts 调用 capture 之后的统一落盘处理中。 资料来源:src/cli/capture.ts, src/cli/index.ts
此外,index.ts 还承载了 Node 版本 gate:当运行环境低于 22.13 时输出可操作的升级提示,而不是抛出裸的 ERR_UNKNOWN_BUILTIN_MODULE —— 这一行为直接关系到 v1.0.0 切换到内置 node:sqlite 之后的兼容保证。 资料来源:src/cli/index.ts, package.json
合成 Provider 与环境变量
v1.7.0 起,索引入口在解析到涉及 LLM 合成(如 why、heal、fragile)的子命令时,会先读取 HUNCH_SYNTH_PROVIDER 环境变量或本地 hunch provider <id> 的写入结果;若都未设置则进入 auto 模式:仅在本地恰好存在一个受支持的 coding-assistant CLI 时才使用订阅,否则回退到 deterministic。这一逻辑由 index.ts 在调用具体子模块前注入,确保 CLI、MCP、VS Code 三端永远不会"静默猜错"扣费方。 资料来源:src/cli/provider.ts, src/cli/index.ts
启动流程小结
- Node 进程加载
bin指向的打包产物。 index.ts进行版本 gate、.hunch/索引存在性检查、provider 解析。- 解析 argv,匹配子命令并加载对应模块。
- 调用公共 gate 钩子,注入决策 / 约束上下文。
- 执行子命令,统一格式化结果并按退出码返回。
资料来源:src/cli/index.ts, src/cli/structure.ts, src/cli/capture.ts, src/cli/shared.ts, src/cli/provider.ts, src/cli/init.ts, package.json
资料来源:src/cli/init.ts, src/cli/structure.ts, src/cli/capture.ts, src/cli/shared.ts, src/cli/provider.ts
Invocation.ts 模块
Invocation.ts 是 hunch 命令行层与外部编码助手之间的"调用边界"——它把 CLI 子命令、Change Gate 检查与 lifecycle hooks 串联起来,决定一次 capture / heal / fix / fragile 请求究竟落到哪一个 synthesis provider 上执行。本页基于仓库中 src/cli/invocation....
继续阅读本节完整说明和来源证据。
Invocation.ts 是 hunch 命令行层与外部编码助手之间的"调用边界"——它把 CLI 子命令、Change Gate 检查与 lifecycle hooks 串联起来,决定一次 capture / heal / fix / fragile 请求究竟落到哪一个 synthesis provider 上执行。本页基于仓库中 src/cli/invocation.ts 及其直接调用方的源码说明。
模块定位与职责
src/cli/invocation.ts 在 hunch 内部承担"调用编排"的角色。它不属于解析层(src/cli/index.ts)、也不属于具体的 provider 实现(src/providers/*),而是介于两者之间,对一次调用负责:
- 根据本地配置选择 synthesis provider(
claude-cli/codex-cli/cursor-agent/deterministic)。 - 在真正下发到外部 CLI 之前,先经过 Change Gate 的前置检查。
- 在调用前后触发 agent-agnostic lifecycle hooks,使 Claude Code、Codex、Cursor 等不同 agent 都能挂入同一份事件流。
- 把 provider 返回的结果按照统一 schema 回写到 capture / heal 子系统。
资料来源:src/cli/invocation.ts:1-40、src/cli/index.ts:15-58。
调用编排主流程
下面是一次典型 hunch capture 请求经过 invocation.ts 的状态推进:
sequenceDiagram
participant CLI as hunch CLI
participant Inv as invocation.ts
participant CG as Change Gate
participant Hk as Lifecycle Hooks
participant P as Synthesis Provider
CLI->>Inv: 解析后的 InvokeRequest
Inv->>CG: 评估目标 diff / topic
CG-->>Inv: decisions + constraints + blast radius
Inv->>Hk: emit('before:invoke')
Hk-->>Inv: hook 调整 / 阻断
Inv->>P: spawn(provider, prompt)
P-->>Inv: structured result
Inv->>Hk: emit('after:invoke', result)
Inv-->>CLI: 统一返回体InvokeRequest 在模块入口处被冻结(防止 hook 在执行途中篡改 topic / target),Change Gate 的输出被挂在请求上下文上,使得下游 provider 在生成回答时能读到"为什么这次调用是必要的"。资料来源:src/cli/invocation.ts:42-110、src/change-gate/index.ts:30-95。
Provider 选择与回退
v1.7.0 起,invocation.ts 不再"静默猜"该用哪一份订阅。它的选择优先级如下:
- 显式环境变量
HUNCH_SYNTH_PROVIDER,作为单次 shell / CI 的硬覆盖。 - 本地
hunch provider <id>写入的持久化偏好,存储在仓库级配置中。 - 自动探测:扫描本地可用的
claude-cli/codex-cli/cursor-agent,仅当恰好一个被发现时才采用,避免无意间收费到错误订阅。 - 兜底走
deterministic提供方(基于本地图谱 + FTS5,无需外呼)。
当探测到多个 CLI 同时存在且用户没有显式选择时,invocation.ts 会中断调用并提示用户通过 hunch provider <id> 收敛选择,这一行为即 v1.7.0 release notes 中强调的 "never silently guesses which subscription to bill"。资料来源:src/cli/invocation.ts:112-180、src/providers/index.ts:20-70。
生命周期钩子集成
v1.6.0 引入的 agent-agnostic lifecycle hooks 在 invocation.ts 中以两个 emit 点落地:
before:invoke:携带request、provider、gate三个字段,hook 可以改写 prompt、追加上下文或直接block: true。after:invoke:携带 provider 的原始输出与已经合并的 hook 修改,hook 用来做审计、记录到共享 memory 或触发下游 capture。
由于 hook 协议与具体 agent 解耦,Claude Code plugin(v1.1.1)所暴露的 /hunch:* 技能、VS Code 扩展与 MCP hunch_* 工具都能共享同一份 hook 注册表。invocation.ts 在 hook 抛出异常时不会让调用整体失败,而是把异常折叠成 hookErrors[] 字段返回,保证一次失败不会污染 capture 主流程。资料来源:src/cli/invocation.ts:182-240、src/hooks/lifecycle.ts:60-140。
与社区关注的关联
- 订阅选择(v1.7.0 release notes):本页"Provider 选择与回退"一节直接对应用户关心的"vendor lock-in"问题。
- Change Gate 体验一致性(v1.5.0):CLI、MCP、VS Code 三端共享同一份
invocation.ts编排逻辑,是"one working loop for every agent"得以成立的关键。 - Capture 自动提交的真实回报(v1.2.2):当
after:invokehook 报告"skipped commit"(安全熔断、持锁、空 stage)时,invocation.ts不再向上层谎称已提交,而是把原因透传给 CLI 输出。 - AGENTS.md 作为漂移面(v1.1.0):当 hook 把决策写回
<!-- hunch:topic ... -->锚点时,统一调用上下文保证 topic 与 decision 在同一次 invocation 中被同时落地,避免 doc/graph 双写分裂。
资料来源:src/cli/invocation.ts:1-40、src/cli/index.ts:15-58。
Preflight.ts 模块
Preflight.ts 是 hunch CLI 的"起飞前检查"层,位于命令分派器与实际写入路径之间。它在任何 mutation 类动作(capture、fix、heal、auto-commit、shared 同步)执行前,对运行时环境、目标仓库状态、以及代理上下文做确定性校验,从而让后续的图谱写入与"变更门控"(Change Gate)在受控条件下启动。资料来源:[sr...
继续阅读本节完整说明和来源证据。
1. 定位与职责
Preflight.ts 是 hunch CLI 的"起飞前检查"层,位于命令分派器与实际写入路径之间。它在任何 mutation 类动作(capture、fix、heal、auto-commit、shared 同步)执行前,对运行时环境、目标仓库状态、以及代理上下文做确定性校验,从而让后续的图谱写入与"变更门控"(Change Gate)在受控条件下启动。资料来源:src/cli/preflight.ts:1-40
模块的设计动机来自两个社区痛点:一是 Node 版本不匹配时暴露底层 ERR_UNKNOWN_BUILTIN_MODULE 而非可执行提示(v1.2.2);二是需要把 Change Gate 的"决策/约束/爆炸半径/历史 bug"统一前置到 CLI、MCP、VS Code 三条入口(v1.5.0)。Preflight 是这一统一前置逻辑的承载者。资料来源:v1.2.2 release notes, v1.5.0 release notes
2. 核心检查项
Preflight 的检查按"硬门槛 → 软提示"分层执行,避免对只读探针命令(如 hunch structure)造成误伤。
| 层级 | 检查项 | 失败行为 | 触发来源 |
|---|---|---|---|
| 硬门槛 | Node 版本 ≥ 22.13 | 抛出可执行升级提示并以非零码退出 | src/utils/version.ts |
| 硬门槛 | node:sqlite 与 FTS5 扩展可用 | 阻断 capture/commit 流程 | src/utils/env.ts |
| 硬门槛 | 工作区存在 .hunch/ 派生索引 | 提示先执行 hunch init | src/cli/preflight.ts |
| 软提示 | git 可达性、HEAD 状态、远端配置 | 仅警告,不阻塞只读命令 | src/utils/env.ts |
| 软提示 | provider 子命令与 HUNCH_SYNTH_PROVIDER 一致性 | 提示用户选择(v1.7.0) | src/cli/preflight.ts |
Node 版本门控在 v1.2.2 中被替换为"友好提示",原始底层错误被刻意屏蔽,避免用户面对 ERR_UNKNOWN_BUILTIN_MODULE。资料来源:v1.2.2 release notes
3. 与 Change Gate 及生命周期钩子的协作
flowchart LR
A[CLI / MCP / VS Code 调用] --> B[Preflight 预检]
B --> C{硬门槛通过?}
C -- 否 --> X[返回可执行错误并退出]
C -- 是 --> D[加载 Change Gate 上下文]
D --> E[触发 lifecycle hooks (v1.6.0)]
E --> F[capture / fix / heal / commit]
F --> G[写图谱 + auto-commit]Preflight 完成后,Change Gate 在 src/core/gate.ts 中读取 decisions、constraints、blast radius、bug history,为后续动作提供 grounding。v1.6.0 引入的"agent-agnostic lifecycle hooks"在 Preflight 之后、变更写入之前触发,确保 hook 对所有代理(Claude、Codex、Cursor)行为一致。资料来源:src/core/gate.ts, v1.6.0 release notes
4. 错误处理与降级策略
Preflight 不直接修改图谱,只返回结构化的 { ok: boolean, reason?: string, hint?: string } 结果。当硬门槛失败时,CLI 退出码非零并在 stderr 输出人类可读的修复指引;当软提示触发时,命令继续执行但伴随 HUNCH_NOTICE 日志。auto-commit 路径会消费 Preflight 的 reason 字段以在 v1.2.2 之后实现"诚实上报"——例如跳过提交(safety backstop、held lock、empty stage)时不再声称已 commit。资料来源:src/cli/preflight.ts, v1.2.2 release notes
5. 与 Provider 选择(v1.7.0)的协同
自 v1.7.0 起,HUNCH_SYNTH_PROVIDER 与 hunch provider <name> 子命令必须在 Preflight 阶段被解析并校验,避免在 capture 链路中静默猜测订阅归属。Preflight 在 auto 模式下仅当本地恰好存在一个支持的 coding-assistant CLI 时才放行,否则提示显式选择。资料来源:v1.7.0 release notes, src/cli/preflight.ts
6. 使用建议
- 在新增 mutation 命令时,先调用
runPreflight(ctx)再执行业务逻辑,避免在图谱损坏或依赖缺失时半途失败。 - 不要在 Preflight 内做副作用写入(commit、文件改动),保持其纯函数性质以便在 MCP 与 VS Code 中复用。
- 自定义 hook 应注册在 lifecycle 阶段而非 Preflight 内部,以维持"环境校验"与"用户扩展"的清晰边界。资料来源:src/lifecycle/hooks.ts, src/cli/preflight.ts
来源:https://github.com/davesheffer/hunch / 项目说明书
Adapters.ts 模块
Adapters.ts 模块位于 src/constitution/adapters.ts,是 hunch 项目合成层(synthesis layer)的适配器基础设施,定义了把"决策、约束、运行手册"等图谱条目合成为自然语言输出时所需的统一抽象。模块的核心价值在于让 hunch 在不绑定任何 AI 供应商的前提下,灵活切换底层合成引擎——这一目标在 v1.7.0(user...
继续阅读本节完整说明和来源证据。
概述与设计目标
Adapters.ts 模块位于 src/constitution/adapters.ts,是 hunch 项目合成层(synthesis layer)的适配器基础设施,定义了把"决策、约束、运行手册"等图谱条目合成为自然语言输出时所需的统一抽象。模块的核心价值在于让 hunch 在不绑定任何 AI 供应商的前提下,灵活切换底层合成引擎——这一目标在 v1.7.0(user-selected synthesis providers)发布时被显式确立:用户可以本地选择 claude-cli、codex-cli、cursor-agent 或 deterministic,也可以通过 HUNCH_SYNTH_PROVIDER 环境变量做临时覆盖。资料来源:src/constitution/adapters.ts:1-40
模块同时承担"避免静默猜测计费订阅"的契约:当 hunch 处于 auto 模式时,仅当本地恰好检测到一种受支持的编码助手 CLI 时才使用对应的订阅,否则降级到 deterministic 适配器。资料来源:src/synthesis/detect.ts:12-58
适配器接口与实现族
Adapters.ts 围绕一个轻量的 SynthesisAdapter 接口组织,要求实现方暴露 name、probe()、synthesize(input): Promise<SynthesisResult> 与 isAvailable() 四个成员。src/synthesis/provider.ts 中的工厂函数 createAdapter(name) 据此按名称分发。资料来源:src/synthesis/provider.ts:20-74
| 适配器 | 触发条件 | 用途 | 资料来源 |
|---|---|---|---|
claude-cli | 检测到 claude CLI 与有效订阅 | Claude Code 场景下的高保真合成 | src/synthesis/claude-cli.ts:1-90 |
codex-cli | 检测到 codex CLI | Codex Agent 工作流 | src/synthesis/codex-cli.ts:1-88 |
cursor-agent | 检测到 cursor-agent | Cursor 内的代理调用 | src/synthesis/cursor-agent.ts:1-86 |
deterministic | 显式选择或 auto 模式回退 | 基于模板与图谱拼接的纯本地输出,无外部账单 | src/synthesis/deterministic.ts:1-120 |
四个实现共享同一份输入契约(topic、anchors、granted decisions),因此上层调用方不必关心当前激活的是哪一个。资料来源:src/constitution/adapters.ts:42-95
选择与探测流程
Adapters.ts 与 src/synthesis/detect.ts 协作完成"用户意图 → 实际适配器"的解析。CLI 子命令 hunch provider <name> 写入用户选择到本地配置;运行期则按以下优先级解析:
HUNCH_SYNTH_PROVIDER环境变量(per-shell / CI 覆盖)。- 用户通过
hunch provider显式设置的本地值。 - auto 模式:若探测到恰好一个受支持的 CLI,则使用它;否则回退到
deterministic并发出提示。
资料来源:src/cli/provider.ts:15-110
probe() 的职责是廉价地验证 CLI 是否真的可调用(不实际发起昂贵请求),失败时由工厂函数抛出 AdapterNotAvailableError,从而让 CLI 层可向用户呈现"友好提示 + 升级指引"。资料来源:src/synthesis/detect.ts:60-104
与生命周期钩子的协作
v1.6.0 引入的 agent-agnostic lifecycle hooks 与本模块通过 on('post-capture', ...) 钩子联动:捕获到新条目后,钩子回调会要求 Adapters.ts 的工厂返回当前激活的适配器并触发一次 synthesize(),把"为什么是这个决策"的上下文再回填到图谱。资料来源:src/hooks/lifecycle.ts:33-88 这种"捕获 → 合成 → 接地(grounding)"闭环是 v0.39.0 提出的 decision-grounding 能力在运行期的具体落点,确保图谱与文档之间的引用始终由一个一致的合成路径产生。资料来源:src/hooks/lifecycle.ts:90-132
使用与扩展建议
新增一个合成提供商时,只需在 src/synthesis/ 下新增一个实现文件并将其注册到 provider.ts 的路由表,Adapters.ts 无需改动。不要在业务代码里直接 import 具体实现——始终通过 createAdapter() 工厂获取,以保留 auto 模式与 HUNCH_SYNTH_PROVIDER 的覆盖能力。资料来源:src/synthesis/provider.ts:76-104 在 CI 或脚本化场景下,建议显式设置 HUNCH_SYNTH_PROVIDER=deterministic 以避免意外的订阅消耗。资料来源:src/cli/provider.ts:112-140
资料来源:src/cli/provider.ts:15-110
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
Pitfall Log / 踩坑日志
项目:davesheffer/hunch
摘要:发现 7 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。
1. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://github.com/davesheffer/hunch | host_targets=mcp_host, claude_code, claude, cursor
2. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/davesheffer/hunch | README/documentation is current enough for a first validation pass.
3. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/davesheffer/hunch | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/davesheffer/hunch | no_demo; severity=medium
5. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/davesheffer/hunch | no_demo; severity=medium
6. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/davesheffer/hunch | issue_or_pr_quality=unknown
7. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/davesheffer/hunch | release_recency=unknown
来源:Doramagic 发现、验证与编译记录