@zyaiting/keelson 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +48 -30
  2. package/README_CN.md +48 -30
  3. package/hooks/codebuddy-session.mjs +13 -28
  4. package/hooks/codex-session.mjs +16 -0
  5. package/hooks/prompt-state.mjs +5 -29
  6. package/hooks/session-start.mjs +7 -0
  7. package/hooks/workflow-guard.mjs +95 -0
  8. package/package.json +1 -1
  9. package/registry/platforms.json +4 -4
  10. package/registry/runtime-hashes.json +41 -0
  11. package/skills/keelson/SKILL.md +6 -3
  12. package/skills/keelson/references/build.md +12 -0
  13. package/skills/keelson/references/discover.md +5 -3
  14. package/skills/keelson/references/frontend.md +1 -1
  15. package/skills/keelson/references/interview.md +26 -7
  16. package/skills/keelson/references/land.md +2 -0
  17. package/skills/keelson/references/shape.md +3 -3
  18. package/skills/keelson/references/verify.md +1 -1
  19. package/skills/keelson/templates/resident-block.md +1 -1
  20. package/skills/keelson/templates/workflow.md +3 -3
  21. package/skills/zh/keelson/SKILL.md +6 -3
  22. package/skills/zh/keelson/references/build.md +12 -0
  23. package/skills/zh/keelson/references/discover.md +5 -3
  24. package/skills/zh/keelson/references/frontend.md +1 -1
  25. package/skills/zh/keelson/references/interview.md +26 -7
  26. package/skills/zh/keelson/references/land.md +2 -0
  27. package/skills/zh/keelson/references/shape.md +3 -3
  28. package/skills/zh/keelson/references/verify.md +2 -0
  29. package/skills/zh/keelson/templates/resident-block.md +1 -1
  30. package/skills/zh/keelson/templates/workflow.md +3 -3
  31. package/src/cli.js +4 -3
  32. package/src/commands/ablate.js +2 -1
  33. package/src/commands/ask.js +4 -1
  34. package/src/commands/context.js +7 -0
  35. package/src/commands/doctor.js +3 -1
  36. package/src/commands/hook.js +6 -1
  37. package/src/commands/init.js +12 -7
  38. package/src/commands/new.js +1 -1
  39. package/src/commands/platforms.js +1 -1
  40. package/src/commands/start.js +33 -0
  41. package/src/commands/uninstall.js +1 -1
  42. package/src/lib/decisions.js +3 -1
  43. package/src/lib/hook-context.js +30 -0
  44. package/src/lib/markdown.js +1 -1
  45. package/src/lib/rules.js +10 -2
  46. package/src/lib/workflow.js +102 -0
  47. package/src/platforms/integration.js +75 -93
  48. package/src/platforms/runtime.js +68 -17
package/README.md CHANGED
@@ -1,33 +1,40 @@
1
1
  <p align="center"><img src="https://raw.githubusercontent.com/Atingaii/keelson/main/docs/assets/keelson-banner.png" alt="Keelson" width="620"></p>
2
2
 
3
- <p align="center"><strong>Start with a conversation. Leave work the next session can build on.</strong></p>
3
+ <p align="center"><strong>Clarify the goal. Build to the contract. Keep what you learn.</strong></p>
4
4
  <p align="center">Project memory, engineering guidance, and acceptance checks for your coding agent. Describe the outcome; keep decisions and verification alongside the code.</p>
5
5
 
6
6
  <p align="center">
7
- <a href="README_CN.md">简体中文</a> ·
7
+ <a href="https://github.com/Atingaii/keelson/blob/main/README_CN.md">简体中文</a> ·
8
8
  <a href="#quick-start">Quick start</a> ·
9
- <a href="docs/README.md">Documentation</a> ·
10
- <a href="docs/platforms.md">Agent support</a>
9
+ <a href="https://github.com/Atingaii/keelson/blob/main/docs/README.md">Documentation</a> ·
10
+ <a href="https://github.com/Atingaii/keelson/blob/main/docs/platforms.md">Agent support</a>
11
11
  </p>
12
12
 
13
13
  <p align="center">
14
+ <a href="https://www.npmjs.com/package/@zyaiting/keelson"><img src="https://img.shields.io/npm/v/%40zyaiting%2Fkeelson" alt="npm version"></a>
14
15
  <a href="https://github.com/Atingaii/keelson/actions/workflows/ci.yml"><img src="https://github.com/Atingaii/keelson/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
15
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT license"></a>
16
+ <a href="https://github.com/Atingaii/keelson/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT license"></a>
16
17
  </p>
17
18
 
18
- <p align="center"><img src="https://raw.githubusercontent.com/Atingaii/keelson/main/docs/assets/keelson-demo.gif" alt="Real agent conversation replay: a task-filter request followed by implementation, verification, and archiving" width="100%"></p>
19
- <p align="center"><sub>Initialized example repository · Translated excerpts from a real session, with waits shortened · Just describe the task</sub></p>
20
-
21
19
  ## Why Keelson?
22
20
 
23
- Coding agents can write code. Ongoing development also needs shared context, clear boundaries, and a reliable way to establish that work is done.
21
+ Keelson brings software engineering practices into everyday agent conversations: agree on the outcome, preserve the reasoning, and check the result. It addresses four recurring problems.
24
22
 
25
- | A familiar problem | How Keelson helps |
26
- | --- | --- |
27
- | Every new session starts with another project explanation | Goals, decisions, and unfinished work stay in the repository for the next session. |
28
- | Implementation starts before the request is understood | The agent reads existing code, defines acceptance, and asks about decisions that change the direction. |
29
- | The code is written, but completion is unclear | Check records track the inputs they verified, keeping implementation, verification, and completion distinct. |
30
- | The page works, but its design and interactions feel unfinished | Design guidance covers typography, color, feedback, responsive behavior, and accessibility, with browser acceptance. |
23
+ **1. The agent builds the wrong thing.**
24
+
25
+ “Add a filter” leaves room for different defaults, edge cases, and compatibility choices. Keelson guides the agent to inspect the code, automatically investigate unclear goals and connected decisions, then turn the request into concrete acceptance examples before implementation. This applies **behaviour-driven development**: use examples to expose disagreement early, asking only about choices that affect the direction.
26
+
27
+ **2. Every session needs the same explanation.**
28
+
29
+ The next agent sees the code but may miss what “member” means or why an alternative was rejected. Keelson keeps domain terms, decisions, and unfinished work alongside the code. **Ubiquitous language** and **decision records** give later sessions shared vocabulary and reasons to work from, reducing repeated explanations.
30
+
31
+ **3. “Done” does not say what was checked.**
32
+
33
+ A passing test can miss the requested behaviour; an old result can describe old code. Keelson guides small implementation steps and acceptance review, and ties check records to the inputs they verified. **Short feedback loops** become a concrete completion gate: missing or stale verification blocks normal archiving.
34
+
35
+ **4. The page works, but using it feels rough.**
36
+
37
+ Unclear feedback, lost form input, and awkward mobile controls are usability problems. Keelson turns **usability heuristics** into guidance for hierarchy, interaction, responsive behaviour, and accessibility. The agent reviews the actual interface in a browser and checks real interactions, alongside code checks.
31
38
 
32
39
  Keelson combines an **Agent Skill + local CLI**. The skill guides the agent's work; the CLI manages project state and verification records. Use it for features, bug fixes, refactoring, and frontend improvements.
33
40
 
@@ -37,7 +44,7 @@ Keelson combines an **Agent Skill + local CLI**. The skill guides the agent's wo
37
44
  - A coding agent that can read project files, make changes, and run commands.
38
45
  - A local project directory; Git is recommended for tracking code and project knowledge.
39
46
 
40
- Keelson generates integrations for Codex, Claude Code, OpenCode, Gemini CLI, and other hosts. See [Agent support](docs/platforms.md) for capabilities and validation coverage.
47
+ Claude Code, Codex CLI and CodeBuddy CLI are the primary supported hosts. Keelson also generates integrations for other coding agents. See [Agent support](https://github.com/Atingaii/keelson/blob/main/docs/platforms.md) for capabilities and validation coverage.
41
48
 
42
49
  ## Quick start
43
50
 
@@ -47,24 +54,30 @@ Keelson generates integrations for Codex, Claude Code, OpenCode, Gemini CLI, and
47
54
  npm install -g @zyaiting/keelson
48
55
  ```
49
56
 
50
- **2. Initialize your project**, using Codex here:
57
+ **2. Initialize your project**, selecting your CLI:
51
58
 
52
59
  ```bash
53
60
  cd /path/to/your/project
54
- keelson init --codex
61
+ keelson init --claude # Claude Code
62
+ # or: keelson init --codex
63
+ # or: keelson init --codebuddy
55
64
  ```
56
65
 
57
66
  **3. Open your agent in that directory and describe the task.** Initialize once, then keep working through conversation.
58
67
 
59
- > Add a priority filter to the task list: show everything by default, with an option for high-priority tasks only. Keep existing calls compatible, add tests, and verify the result.
68
+ > Add a priority filter to the task list.
60
69
 
61
- To upgrade, run `npm install -g @zyaiting/keelson@latest`, then `keelson update` in your project. See the [setup guide](docs/getting-started.md) and [supported agents](docs/platforms.md).
70
+ To upgrade, run `npm install -g @zyaiting/keelson@latest`, then `keelson update` in your project. See the [setup guide](https://github.com/Atingaii/keelson/blob/main/docs/getting-started.md) and [supported agents](https://github.com/Atingaii/keelson/blob/main/docs/platforms.md).
62
71
 
63
72
  ## From request to completion
64
73
 
65
- **UnderstandScope → Implement and verifyArchive and resume**
74
+ **InvestigateDecide → Implement Independently review Verify Preserve knowledge**
75
+
76
+ After initialization, ordinary requests trigger the relevant workflow automatically: investigate requirements, clarify material choices with recommendations, apply engineering and UI/UX guidance, implement, verify, and preserve the result for later sessions. You do not need to name a skill or manage workflow commands. Clear edits use a minimal change record. A simple gap gets one question; connected uncertainties get the whole ready decision frontier, with recommendations and reasons for each choice. The agent resumes authorized work once those choices are settled.
66
77
 
67
- The agent loads relevant guidance, maintains acceptance criteria, and runs project checks. It wraps up when the gates pass, asking for your input when a choice changes the plan. Small edits stay lightweight.
78
+ Before implementation, the agent starts the settled change and loads its declared specs and rules. Review gets a separate context pack built from the request and contracts. Verified changes promote durable decisions into project specs, so later work starts with what the project has learned.
79
+
80
+ Claude Code, Codex and CodeBuddy integrations restore workflow context and gate supported file edits. Codex requires the generated hooks to be trusted in `/hooks` when prompted; other host permissions remain in effect. Disabled hooks fall back to installed guidance and the shared CLI. See [automation and its boundaries](https://github.com/Atingaii/keelson/blob/main/docs/automation.md).
68
81
 
69
82
  You can also ask:
70
83
 
@@ -72,7 +85,7 @@ You can also ask:
72
85
  - **Improve an interface:** “Polish the settings page, keep our brand, preserve input when saving fails, and check the mobile flow.”
73
86
  - **Resume:** “Continue the previous change. First check what's left.”
74
87
 
75
- Frontend work has 22 composable [design actions](docs/frontend.md), discoverable with `keelson design`, including critique, simplification, polish, and adaptation. Checking the actual interface requires the agent to use a browser.
88
+ The agent automatically selects from 22 composable [design actions](https://github.com/Atingaii/keelson/blob/main/docs/frontend.md), discoverable with `keelson design`, including critique, simplification, polish, and adaptation when the work affects an interface. Checking the actual interface requires the agent to use a browser.
76
89
 
77
90
  ## What stays in your project?
78
91
 
@@ -85,17 +98,22 @@ Initialization creates a small foundation. Further documents appear as the work
85
98
  | `.keelson/changes/`, `.keelson/specs/`, `.keelson/rules/` | Changes, behavior contracts, and project rules created as needed. |
86
99
  | Host entry points such as `AGENTS.md` | Direct the agent to Keelson. |
87
100
 
88
- Guidance comes from the installed package by default. Use `--vendor` when you want to commit a copy alongside your project. See [configuration](docs/configuration.md) for paths and options.
101
+ Guidance comes from the installed package by default. Use `--vendor` when you want to commit a copy alongside your project. See [configuration](https://github.com/Atingaii/keelson/blob/main/docs/configuration.md) for paths and options.
89
102
 
90
103
  ## Engineering principles
91
104
 
92
- - **Start with the problem.** Establish outcomes, constraints, and invariants before choosing mechanisms. Additional complexity must earn its place.
93
- - **Load and retain what matters.** Small edits move directly; larger work adds contracts and plans. Preserve knowledge the next change will need.
94
- - **Build through feedback.** Use small steps, independent review, and focused checks. Record test results separately from browser observations.
95
- - **Ground completion in evidence.** Check records are tied to verified inputs; changed code needs fresh verification. Ending a conversation does not finish a task.
105
+ The ideas above come from established engineering and interaction design practices. Keelson adapts them to repository work:
106
+
107
+ | Principle | How it appears in Keelson |
108
+ | --- | --- |
109
+ | [Behaviour-driven development](https://cucumber.io/docs/bdd/) | Describe observable behaviour with acceptance examples; use them to guide implementation and review. |
110
+ | [Ubiquitous language](https://martinfowler.com/bliki/UbiquitousLanguage.html), from domain-driven design | Keep project terms and code-name mappings in a glossary as needed, so conversation and code use the same meanings. |
111
+ | [Architecture decision records](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) | Keep concise decisions and trade-offs in the repository, with their context available to the next session. |
112
+ | [Small iterations and feedback](https://agilemanifesto.org/principles.html) | Build a working slice, check it, and adjust; keep small changes lightweight and add planning when complexity warrants it. |
113
+ | [Usability heuristics](https://www.nngroup.com/articles/ten-usability-heuristics/) | Review visible status, consistent language, error recovery, and user control through actual interface interactions. |
96
114
 
97
- Review commands in `.keelson/config.yaml` before their first execution. The agent runs and records checks with `keelson check --trust --record`; passing exit codes still need an acceptance review. See [verification and trust](docs/verification.md).
115
+ Review commands in `.keelson/config.yaml` before their first execution. The agent runs and records checks with `keelson check --trust --record`; passing exit codes still need an acceptance review. See [verification and trust](https://github.com/Atingaii/keelson/blob/main/docs/verification.md).
98
116
 
99
117
  ## Documentation and contributing
100
118
 
101
- [Documentation](docs/README.md) · [CLI reference](docs/cli.md) · [Frontend design](docs/frontend.md) · [Contributing](CONTRIBUTING.md) · [Report an issue](https://github.com/Atingaii/keelson/issues) · [MIT](LICENSE)
119
+ [Documentation](https://github.com/Atingaii/keelson/blob/main/docs/README.md) · [CLI reference](https://github.com/Atingaii/keelson/blob/main/docs/cli.md) · [Frontend design](https://github.com/Atingaii/keelson/blob/main/docs/frontend.md) · [Contributing](https://github.com/Atingaii/keelson/blob/main/CONTRIBUTING.md) · [Report an issue](https://github.com/Atingaii/keelson/issues) · [MIT](https://github.com/Atingaii/keelson/blob/main/LICENSE)
package/README_CN.md CHANGED
@@ -1,33 +1,40 @@
1
1
  <p align="center"><img src="https://raw.githubusercontent.com/Atingaii/keelson/main/docs/assets/keelson-banner.png" alt="Keelson" width="620"></p>
2
2
 
3
- <p align="center"><strong>在仓库里对话,让每次开发都有据可循、有处接续。</strong></p>
3
+ <p align="center"><strong>让 Agent 先想清楚,再按规范做完,把经验留在仓库。</strong></p>
4
4
  <p align="center">为编码 Agent 提供项目记忆、工程方法和验收流程。你描述目标,Agent 推进实现,把决策与验证留在代码旁。</p>
5
5
 
6
6
  <p align="center">
7
- <a href="README.md">English</a> ·
7
+ <a href="https://github.com/Atingaii/keelson/blob/main/README.md">English</a> ·
8
8
  <a href="#快速开始">快速开始</a> ·
9
- <a href="docs/zh/README.md">文档</a> ·
10
- <a href="docs/platforms.md">Agent 支持</a>
9
+ <a href="https://github.com/Atingaii/keelson/blob/main/docs/zh/README.md">文档</a> ·
10
+ <a href="https://github.com/Atingaii/keelson/blob/main/docs/platforms.md">Agent 支持</a>
11
11
  </p>
12
12
 
13
13
  <p align="center">
14
+ <a href="https://www.npmjs.com/package/@zyaiting/keelson"><img src="https://img.shields.io/npm/v/%40zyaiting%2Fkeelson" alt="npm 版本"></a>
14
15
  <a href="https://github.com/Atingaii/keelson/actions/workflows/ci.yml"><img src="https://github.com/Atingaii/keelson/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
15
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT license"></a>
16
+ <a href="https://github.com/Atingaii/keelson/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT license"></a>
16
17
  </p>
17
18
 
18
- <p align="center"><img src="https://raw.githubusercontent.com/Atingaii/keelson/main/docs/assets/keelson-demo-zh.gif" alt="真实 Agent 对话回放:用户提出任务筛选需求,Agent 完成实现、验证与归档" width="100%"></p>
19
- <p align="center"><sub>已初始化的示例仓库 · 真实会话节选,等待已压缩 · 用户只需提出需求</sub></p>
20
-
21
19
  ## 为什么选择 Keelson?
22
20
 
23
- 编码 Agent 能写代码,但长期开发还需要持续的上下文、明确的边界和可信的验收。
21
+ Keelson 将软件工程中的成熟做法带进日常 Agent 对话:先对齐结果,留下决策依据,再检查实际产出。它围绕四个常见问题展开。
24
22
 
25
- | 开发中遇到的问题 | Keelson 如何处理 |
26
- | --- | --- |
27
- | 换个会话,又要解释整个项目 | 将目标、决策和未完成工作保存在仓库,下次继续读取。 |
28
- | 需求说完就开写,结果偏离预期 | 先读现有实现,明确验收;只对影响方向的关键选择提问。 |
29
- | 代码写完了,却不知道是否真的完成 | 保存与当前代码对应的检查记录,区分实现、验证和完成。 |
30
- | 页面能用,却缺少设计与交互细节 | 提供设计指导,覆盖排版、配色、状态反馈、响应式和无障碍,并要求浏览器验收。 |
23
+ **1. Agent 做出来的,并不是你想要的。**
24
+
25
+ “加个筛选”背后,还有默认行为、边界情况和兼容性。Keelson 引导 Agent 先读代码,自动调查模糊目标和相互关联的选择,把需求变成具体的验收示例,再开始实现。这借鉴了**行为驱动开发(BDD)**:通过例子尽早发现理解偏差,只对影响方向的选择提问。
26
+
27
+ **2. 换个会话,又得解释同一个项目。**
28
+
29
+ 新 Agent 看得到代码,却未必知道“成员”的业务含义,也不知道某个方案为什么被否决。Keelson 将领域术语、决策和未完成工作留在仓库。**统一语言**与**决策记录**让后续会话沿用已有词汇和理由,减少重复解释。
30
+
31
+ **3. 说“完成了”,却不知道验证了什么。**
32
+
33
+ 测试通过可能没有覆盖原始需求,旧结果也可能对应旧代码。Keelson 引导小步实现、逐项验收,并将检查记录绑定到受检输入。**短反馈循环**由此落实到完成条件:验证缺失或过期时,正常归档会被阻止。
34
+
35
+ **4. 页面能用,但用起来不顺手。**
36
+
37
+ 反馈不清楚、保存失败丢输入、手机上操作别扭,都是可用性问题。Keelson 将**可用性启发式原则**转成层级、交互、响应式和无障碍指导,由 Agent 在浏览器中观察界面、实际操作,并结合代码检查验收。
31
38
 
32
39
  Keelson 由 **Agent Skill + 本地 CLI** 组成:Skill 指导 Agent 如何工作,CLI 管理项目状态与验证记录。适用于新功能、问题修复、重构和前端体验优化。
33
40
 
@@ -37,7 +44,7 @@ Keelson 由 **Agent Skill + 本地 CLI** 组成:Skill 指导 Agent 如何工
37
44
  - 一个能读取项目、修改文件并执行命令的编码 Agent。
38
45
  - 一个本地项目目录;建议使用 Git 管理代码和项目知识。
39
46
 
40
- 支持生成 Codex、Claude Code、OpenCode、Gemini CLI 等宿主的集成入口;各宿主的能力与验证范围见 [Agent 支持](docs/platforms.md)。
47
+ 重点适配 **Claude Code、Codex CLI CodeBuddy CLI**,也支持其他编码 Agent 的集成入口;各宿主的能力与验证范围见 [Agent 支持](https://github.com/Atingaii/keelson/blob/main/docs/platforms.md)。
41
48
 
42
49
  ## 快速开始
43
50
 
@@ -47,24 +54,30 @@ Keelson 由 **Agent Skill + 本地 CLI** 组成:Skill 指导 Agent 如何工
47
54
  npm install -g @zyaiting/keelson
48
55
  ```
49
56
 
50
- **2. 在你的项目中初始化**,以 Codex 为例:
57
+ **2. 在你的项目中初始化**,选择使用的 CLI:
51
58
 
52
59
  ```bash
53
60
  cd /path/to/your/project
54
- keelson init --codex --lang zh
61
+ keelson init --claude --lang zh # Claude Code
62
+ # 或:keelson init --codex --lang zh
63
+ # 或:keelson init --codebuddy --lang zh
55
64
  ```
56
65
 
57
66
  **3. 在这个目录启动 Agent,直接提出需求。** 初始化只需一次;后续正常对话即可。
58
67
 
59
- > 给任务列表加一个优先级筛选:默认显示全部,也能只看高优先级。保持现有调用兼容,补齐测试并完成验证。
68
+ > 给任务列表加一个优先级筛选。
60
69
 
61
- 升级 CLI:`npm install -g @zyaiting/keelson@latest`,然后在项目中运行 `keelson update`。更多设置见[上手教程](docs/zh/getting-started.md);其他宿主见 [Agent 支持](docs/platforms.md)。
70
+ 升级 CLI:`npm install -g @zyaiting/keelson@latest`,然后在项目中运行 `keelson update`。更多设置见[上手教程](https://github.com/Atingaii/keelson/blob/main/docs/zh/getting-started.md);其他宿主见 [Agent 支持](https://github.com/Atingaii/keelson/blob/main/docs/platforms.md)。
62
71
 
63
72
  ## 从一句需求到一次完成
64
73
 
65
- **理解目标明确范围实现与验证归档与接续**
74
+ **调查决策实现独立复核 → 验证 → 知识回写**
75
+
76
+ 初始化后,普通需求自动触发相应流程:调查需求、带着推荐澄清关键选择、应用工程与 UI/UX 指导、实现、验证,并保留结果供后续会话接续。你无需点名 Skill 或管理工作流命令。明确的小修改使用最小变更记录;简单缺口一次问一个,复杂问题一轮问完前提已明确的整组决定,每题给推荐与理由。决定明确后继续已授权的工作。
66
77
 
67
- Agent 按任务读取需要的指导,维护验收标准并执行项目检查;条件满足后自动收尾。遇到影响方案的选择时再与你确认,普通小修改保持轻量。
78
+ 实现前,Agent 自动启动已澄清的变更,加载声明的规范与规则;复核使用从原始需求和契约生成的独立上下文包。验收后,持久决策回写到项目规范,下次开发继续使用这些知识。
79
+
80
+ Claude Code、Codex 和 CodeBuddy 集成均支持恢复流程上下文,并对受支持的文件修改执行启动门禁。Codex 首次提示时需在 `/hooks` 中信任生成的 hooks;各宿主原有权限确认继续生效。禁用 hooks 时,由已安装指导驱动相同 CLI。详见[自动化机制与边界](https://github.com/Atingaii/keelson/blob/main/docs/zh/automation.md)。
68
81
 
69
82
  你也可以这样说:
70
83
 
@@ -72,7 +85,7 @@ Agent 按任务读取需要的指导,维护验收标准并执行项目检查
72
85
  - **改善界面:**“优化设置页,保留品牌风格,保存失败时不要丢输入,并检查手机端体验。”
73
86
  - **接着开发:**“继续上次的改动,先确认还剩什么。”
74
87
 
75
- 前端任务有 22 个可组合的[设计动作](docs/zh/frontend.md),可通过 `keelson design` 查看,包括审视、简化、打磨和适配。实际界面效果需要 Agent 使用浏览器检查。
88
+ 涉及界面的任务中,Agent 会从 22 个可组合的[设计动作](https://github.com/Atingaii/keelson/blob/main/docs/zh/frontend.md)中按需选择,包括审视、简化、打磨和适配;可通过 `keelson design` 查看。实际界面效果需要 Agent 使用浏览器检查。
76
89
 
77
90
  ## 项目里会留下什么?
78
91
 
@@ -85,17 +98,22 @@ Agent 按任务读取需要的指导,维护验收标准并执行项目检查
85
98
  | `.keelson/changes/`、`.keelson/specs/`、`.keelson/rules/` | 按需建立的变更、行为契约和项目规则。 |
86
99
  | 宿主入口,如 `AGENTS.md` | 引导 Agent 加载 Keelson。 |
87
100
 
88
- 默认从已安装的包读取指导。需要把指导副本一并提交时,才使用 `--vendor`。目录与选项详见[配置文档](docs/zh/configuration.md)。
101
+ 默认从已安装的包读取指导。需要把指导副本一并提交时,才使用 `--vendor`。目录与选项详见[配置文档](https://github.com/Atingaii/keelson/blob/main/docs/zh/configuration.md)。
89
102
 
90
103
  ## 工程学原理
91
104
 
92
- - **从问题出发。** 先确认结果、约束和不变量,再选择技术方案;额外机制必须证明有用。
93
- - **按需加载,逐步沉淀。** 小改动直接推进,复杂任务补充契约与计划;只保留下一次开发需要的知识。
94
- - **用反馈推动实现。** 小步实现、独立审阅、针对性验证;测试结果与界面观察分别记录。
95
- - **让完成有证据。** 检查记录绑定受检输入,代码变化后需要重新验证;结束对话不等于完成任务。
105
+ 前面的做法来自已有的软件工程与交互设计知识。Keelson 将它们用于仓库中的具体工作:
106
+
107
+ | 原理 | 在 Keelson 中如何落地 |
108
+ | --- | --- |
109
+ | [行为驱动开发(BDD)](https://cucumber.io/docs/bdd/) | 用验收示例描述可观察的行为,指导实现和需求核对。 |
110
+ | 领域驱动设计中的[统一语言](https://martinfowler.com/bliki/UbiquitousLanguage.html) | 按需记录业务术语及代码名称映射,让对话和代码中的词含义一致。 |
111
+ | [架构决策记录(ADR)](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) | 在仓库保留简短决策与取舍,让后续会话理解当时的背景。 |
112
+ | [小步迭代与反馈](https://agilemanifesto.org/principles.html) | 先做出可工作的切片,检查后调整;小改动保持轻量,复杂时再补充计划。 |
113
+ | [可用性启发式原则](https://www.nngroup.com/articles/ten-usability-heuristics/) | 通过实际界面操作,检查状态是否可见、用词是否一致、错误能否恢复、用户能否掌控操作。 |
96
114
 
97
- 首次执行前应审阅 `.keelson/config.yaml` 中的检查命令。Agent 使用 `keelson check --trust --record` 运行并记录检查;退出码通过仍需对照验收标准。详见[验证与信任](docs/zh/verification.md)。
115
+ 首次执行前应审阅 `.keelson/config.yaml` 中的检查命令。Agent 使用 `keelson check --trust --record` 运行并记录检查;退出码通过仍需对照验收标准。详见[验证与信任](https://github.com/Atingaii/keelson/blob/main/docs/zh/verification.md)。
98
116
 
99
117
  ## 文档与参与
100
118
 
101
- [完整文档](docs/zh/README.md) · [命令参考](docs/zh/cli.md) · [前端设计](docs/zh/frontend.md) · [贡献指南](CONTRIBUTING.md) · [反馈问题](https://github.com/Atingaii/keelson/issues) · [MIT](LICENSE)
119
+ [完整文档](https://github.com/Atingaii/keelson/blob/main/docs/zh/README.md) · [命令参考](https://github.com/Atingaii/keelson/blob/main/docs/zh/cli.md) · [前端设计](https://github.com/Atingaii/keelson/blob/main/docs/zh/frontend.md) · [贡献指南](https://github.com/Atingaii/keelson/blob/main/CONTRIBUTING.md) · [反馈问题](https://github.com/Atingaii/keelson/issues) · [MIT](https://github.com/Atingaii/keelson/blob/main/LICENSE)
@@ -1,16 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  // CodeBuddy session bridge for Keelson.
3
- // SessionStart/UserPromptSubmit: touch local session runtime and inject a tiny focus hint.
3
+ // SessionStart/UserPromptSubmit: restore workflow and declared project contracts.
4
4
  // PreToolUse(Bash|PowerShell): deterministically prepend KEELSON_SESSION_ID to the command.
5
5
  // Raw CodeBuddy session ids are never written to disk.
6
- import crypto from 'node:crypto';
7
6
  import fs from 'node:fs';
8
- import path from 'node:path';
9
- import { runtimeDir } from '../src/lib/runtime-path.js';
7
+ import { findProjectRoot } from '../src/lib/paths.js';
8
+ import { hookEnvironment, sessionContext } from '../src/lib/hook-context.js';
9
+ import { writeSession } from '../src/lib/session.js';
10
10
 
11
- const hash = (value, n) => crypto.createHash('sha256').update(String(value)).digest('hex').slice(0, n);
12
- const readJson = (p) => { try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return null; } };
13
- const writeJson = (p, v) => { fs.mkdirSync(path.dirname(p), { recursive: true }); fs.writeFileSync(p, JSON.stringify(v, null, 2) + '\n'); };
14
11
  const shellQuote = (v) => `'${String(v).replace(/'/g, "'\\''")}'`;
15
12
 
16
13
  let input = {};
@@ -19,17 +16,13 @@ try {
19
16
  if (raw.trim()) input = JSON.parse(raw);
20
17
  } catch {}
21
18
 
22
- const root = input.cwd || process.env.CODEBUDDY_PROJECT_DIR || process.cwd();
19
+ const root = findProjectRoot(process.env.CODEBUDDY_PROJECT_DIR || input.cwd || process.cwd());
23
20
  const sessionId = typeof input.session_id === 'string' ? input.session_id.trim() : '';
24
- if (!sessionId || !fs.existsSync(path.join(root, '.keelson'))) process.exit(0);
21
+ if (!sessionId || !root) process.exit(0);
25
22
 
26
- const opaque = hash(`codebuddy:${sessionId}`, 32);
27
- const key = hash(opaque, 24);
28
- const sessionFile = path.join(runtimeDir(root), 'sessions', `${key}.json`);
29
- const session = readJson(sessionFile) || { schema: 1, change: null, createdAt: new Date().toISOString() };
30
- session.updatedAt = new Date().toISOString();
31
- session.source = 'codebuddy';
32
- writeJson(sessionFile, session);
23
+ const env = hookEnvironment('codebuddy', input);
24
+ const opaque = env.KEELSON_SESSION_ID;
25
+ writeSession(root, { source: 'codebuddy' }, env);
33
26
 
34
27
  const event = input.hook_event_name || '';
35
28
  if (event === 'PreToolUse' && ['bash', 'powershell'].includes(String(input.tool_name || '').toLowerCase())) {
@@ -44,8 +37,6 @@ if (event === 'PreToolUse' && ['bash', 'powershell'].includes(String(input.tool_
44
37
  continue: true,
45
38
  hookSpecificOutput: {
46
39
  hookEventName: 'PreToolUse',
47
- permissionDecision: 'allow',
48
- permissionDecisionReason: 'Keelson attached the opaque session identity used only for local work-focus routing.',
49
40
  modifiedInput: {
50
41
  ...input.tool_input,
51
42
  command: injected,
@@ -55,13 +46,7 @@ if (event === 'PreToolUse' && ['bash', 'powershell'].includes(String(input.tool_
55
46
  process.exit(0);
56
47
  }
57
48
 
58
- const changesDir = path.join(root, '.keelson', 'changes');
59
- const active = fs.existsSync(changesDir)
60
- ? fs.readdirSync(changesDir, { withFileTypes: true })
61
- .filter((d) => d.isDirectory() && d.name !== 'archive' && fs.existsSync(path.join(changesDir, d.name, 'change.md')))
62
- .map((d) => d.name)
63
- : [];
64
- const focused = session.change && active.includes(session.change) ? session.change : null;
65
- if (focused) process.stdout.write(`[keelson] session focus: ${focused}; use the existing change unless the user requests an independent outcome.\n`);
66
- else if (active.length === 1) process.stdout.write(`[keelson] resume candidate: ${active[0]}; bind only if this prompt continues that work.\n`);
67
- else if (active.length > 1) process.stdout.write(`[keelson] active changes: ${active.join(', ')}; no session focus, so do not guess.\n`);
49
+ if (['SessionStart', 'UserPromptSubmit'].includes(event)) {
50
+ try { process.stdout.write(sessionContext(root, env, event, 'codebuddy') + '\n'); }
51
+ catch (error) { process.stdout.write(`[keelson] Context restoration needs attention: ${error.message}\n`); }
52
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import { findProjectRoot } from '../src/lib/paths.js';
4
+ import { hookEnvironment, sessionContext } from '../src/lib/hook-context.js';
5
+
6
+ let input = {};
7
+ try { input = JSON.parse(fs.readFileSync(0, 'utf8')); } catch { process.exit(0); }
8
+ const root = findProjectRoot(input.cwd || process.cwd());
9
+ if (!root) process.exit(0);
10
+ const event = input.hook_event_name || 'SessionStart';
11
+ try {
12
+ const context = sessionContext(root, hookEnvironment('codex', input), event, 'codex');
13
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: event, additionalContext: context } }) + '\n');
14
+ } catch (error) {
15
+ process.stdout.write(`[keelson] Context restoration needs attention: ${error.message}\n`);
16
+ }
@@ -5,10 +5,10 @@ import crypto from 'node:crypto';
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { runtimeDir } from '../src/lib/runtime-path.js';
8
+ import { workflowHint } from '../src/lib/workflow.js';
8
9
 
9
10
  const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
10
11
  const k = path.join(root, '.keelson');
11
- const changesDir = path.join(k, 'changes');
12
12
  if (!fs.existsSync(k)) process.exit(0);
13
13
 
14
14
  const read = (p) => (fs.existsSync(p) ? fs.readFileSync(p, 'utf8').replace(/\r\n?/g, '\n') : '');
@@ -35,32 +35,8 @@ if (sessionPath) {
35
35
  session.source = 'claude-prompt';
36
36
  writeJson(sessionPath, session);
37
37
  }
38
- if (!fs.existsSync(changesDir)) process.exit(0);
39
-
40
- const summarize = (name) => {
41
- const dir = path.join(changesDir, name);
42
- const change = read(path.join(dir, 'change.md'));
43
- if (!change) return null;
44
- const tasks = read(path.join(dir, 'tasks.md'));
45
- const total = (tasks.match(/^\s*[-*]\s+\[[ xX]\]/gm) || []).length;
46
- const done = (tasks.match(/^\s*[-*]\s+\[[xX]\]/gm) || []).length;
47
- const ledger = read(path.join(dir, 'ledger.md'));
48
- const verifies = [...ledger.matchAll(/^###\s+Verify:[\s\S]*?exit\s*(?:code)?\s*[:=]?\s*(\d+)/gim)];
49
- const lastExit = verifies.length ? Number(verifies.at(-1)[1]) : null;
50
- const explicit = (change.match(/^status:\s*([\w-]+)/m) || [])[1];
51
- const verify = verifies.length ? (lastExit === 0 ? 'passed' : 'failed') : 'not-run';
52
- const open = (change.match(/^##\s+Open questions?\s*\n([\s\S]*?)(?=^##\s|(?![\s\S]))/im) || [])[1] || '';
53
- const openCount = (open.match(/^\s*[-*]\s+(?!…|none)/gim) || []).length;
54
- return `${name} · ${explicit || (total ? (done < total ? 'in-progress' : 'awaiting verification') : 'in-progress')} · verify ${verify}${total ? ` · ${done}/${total} tasks` : ''}${openCount ? ` · ${openCount} open` : ''}`;
55
- };
56
-
57
- if (session?.change) {
58
- const line = summarize(session.change);
59
- if (line) process.stdout.write(`[keelson] focus: ${line}\n`);
60
- process.exit(0);
38
+ try {
39
+ process.stdout.write(workflowHint(root, { ...process.env, ...(envIdentity ? { KEELSON_SESSION_ID: envIdentity } : {}) }) + '\n');
40
+ } catch (error) {
41
+ process.stdout.write(`[keelson] Cannot restore workflow: ${error.message}. Run keelson doctor before implementation.\n`);
61
42
  }
62
-
63
- const names = fs.readdirSync(changesDir, { withFileTypes: true })
64
- .filter((d) => d.isDirectory() && d.name !== 'archive' && fs.existsSync(path.join(changesDir, d.name, 'change.md')))
65
- .map((d) => d.name);
66
- if (names.length === 1) process.stdout.write(`[keelson] resume candidate: ${summarize(names[0])}; bind only if this prompt continues that work\n`);
@@ -5,6 +5,7 @@ import crypto from 'node:crypto';
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { runtimeDir } from '../src/lib/runtime-path.js';
8
+ import { activeWorkflow, phaseContext, renderPhaseContext, workflowHint } from '../src/lib/workflow.js';
8
9
 
9
10
  const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
10
11
  const k = path.join(root, '.keelson');
@@ -57,6 +58,7 @@ if (sessionPath) {
57
58
  session = readJson(sessionPath) || { schema: 1, change: null, createdAt: new Date().toISOString() };
58
59
  session.updatedAt = new Date().toISOString();
59
60
  session.source = 'claude-session-start';
61
+ session.injectedContexts = []; // compact/resume must restore previously injected constraints.
60
62
  writeJson(sessionPath, session);
61
63
  }
62
64
 
@@ -91,4 +93,9 @@ if (ordered.length) {
91
93
  lines.push('', '--- Active work ---');
92
94
  for (const c of ordered.slice(0, 6)) lines.push(`${c.name}${c.name === focused ? ' [focus]' : ''}: ${c.tier}${c.status ? `, ${c.status}` : ''}${c.total ? `, ${c.done}/${c.total} tasks` : ''}${c.owner ? `, ${c.owner}` : ''}`);
93
95
  }
96
+ try {
97
+ const env = { ...process.env, ...(envIdentity ? { KEELSON_SESSION_ID: envIdentity } : {}) };
98
+ lines.push('', workflowHint(root, env));
99
+ if (focused) lines.push(renderPhaseContext(phaseContext(root, activeWorkflow(root, focused, env))));
100
+ } catch (error) { lines.push(`[keelson] Context restoration needs attention: ${error.message}`); }
94
101
  process.stdout.write(lines.join('\n') + '\n');
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ // Host-specific file-tool gates and phase context injection. Shell/MCP writers
3
+ // remain host-policy territory; this is a workflow guard, not a sandbox.
4
+ import crypto from 'node:crypto';
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { findProjectRoot } from '../src/lib/paths.js';
8
+ import { hookEnvironment } from '../src/lib/hook-context.js';
9
+ import { readSession, writeSession } from '../src/lib/session.js';
10
+ import { activeWorkflow, implementationBlockers, phaseContext, renderPhaseContext } from '../src/lib/workflow.js';
11
+
12
+ let input = {};
13
+ try { input = JSON.parse(fs.readFileSync(0, 'utf8')); } catch { process.exit(2); }
14
+ const host = process.argv[2] || 'claude';
15
+ const projectDir = host === 'claude' ? process.env.CLAUDE_PROJECT_DIR : host === 'codebuddy' ? process.env.CODEBUDDY_PROJECT_DIR : null;
16
+ const root = findProjectRoot(projectDir || input.cwd || process.cwd());
17
+ if (!root) process.exit(0);
18
+ const env = hookEnvironment(host, input);
19
+ const event = input.hook_event_name || 'PreToolUse';
20
+ const tool = input.tool_name;
21
+ const output = (fields) => process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: event, ...fields } }) + '\n');
22
+
23
+ try {
24
+ const session = readSession(root, env);
25
+ const name = session.state?.change;
26
+ if (host === 'codex' && event === 'SubagentStart' && !name) {
27
+ // session_id is the root, not necessarily the spawning parent. Let the
28
+ // assigned task name its change rather than inheriting an unrelated focus.
29
+ output({ additionalContext: '[keelson] Preserve your assigned scope, including read-only work. If your task includes KEELSON_CHANGE=<name>, run `keelson focus <name>`, then `keelson context --phase check` for review or `--phase implement` for implementation before doing that work. Do not infer a task from the root session or sole repository candidate. Without a marker, keep discovery read-only; create or select a change only when the task explicitly requires implementation. These commands do not grant permission to edit.' });
30
+ process.exit(0);
31
+ }
32
+ const workflow = activeWorkflow(root, name, env);
33
+ // Never infer an unrelated session's change from the sole repository candidate.
34
+ if (!name) workflow.change = null;
35
+ const args = input.tool_input ?? {};
36
+ const file = args.file_path ?? args.notebook_path;
37
+ const patch = host === 'codex' && tool === 'apply_patch';
38
+ const editing = patch || ['Edit', 'Write', 'MultiEdit', 'NotebookEdit', 'NotebookWrite'].includes(tool);
39
+ const files = patch
40
+ ? [...String(args.command ?? '').matchAll(/^\*\*\* (?:Add File|Update File|Delete File|Move to): (.+)\r?$/gm)].map((m) => m[1].trim())
41
+ : typeof file === 'string' ? [file] : [];
42
+ const relative = files.map((f) => path.relative(root, path.resolve(input.cwd || root, f)).replace(/\\/g, '/'));
43
+ const planningOnly = relative.length > 0 && relative.every((f) => f.startsWith('.keelson/') && !f.split('/').includes('..'));
44
+ if (editing && !planningOnly) {
45
+ const blockers = implementationBlockers(workflow.change, workflow.changes);
46
+ if (blockers.length) {
47
+ output({ permissionDecision: 'deny', permissionDecisionReason: blockers.join(' ') + ' The agent should resolve this within existing authorization; do not ask the user to run workflow commands.' });
48
+ process.exit(0);
49
+ }
50
+ }
51
+ if (editing && planningOnly) process.exit(0);
52
+ if (!workflow.change) process.exit(0);
53
+ if (host === 'codex' && ['spawn_agent', 'Agent', 'Task'].includes(tool)) {
54
+ const markers = [...String(args.message ?? args.prompt ?? '').matchAll(/^\s*KEELSON_CHANGE=([^\s]+)[ \t]*$/gm)];
55
+ if (markers.length !== 1 || markers[0][1] !== name) {
56
+ output({ permissionDecision: 'deny', permissionDecisionReason: `Add the single line KEELSON_CHANGE=${name} to this child task so its own CLI session can bind the assigned change. Keep its phase, original instructions and any read-only scope. The agent should correct the task prompt; do not ask the user to run workflow commands.` });
57
+ process.exit(0);
58
+ }
59
+ }
60
+ const descriptor = `${input.agent_type ?? ''} ${args.subagent_type ?? args.agent_type ?? ''} ${args.description ?? ''} ${args.prompt ?? args.message ?? ''}`;
61
+ const reviewing = /KEELSON_PHASE=check|keelson-check|\breview\b|\breviewer\b|复核|审查/i.test(descriptor);
62
+ if (event === 'SubagentStart' && !reviewing && !/KEELSON_PHASE=implement|keelson-implement/i.test(descriptor)) {
63
+ // Generic agent_type carries no parent's prompt or reliable phase. The
64
+ // Agent/Task hook already injected the appropriate pack into that prompt.
65
+ const hint = '[keelson] Follow the phase and contracts in your task prompt. If they are missing, load `keelson context --phase check` for review or `--phase implement` for implementation. Preserve your assigned scope; context is not permission to edit.';
66
+ // A bound Codex child can safely receive its own packs. An unbound child
67
+ // received explicit binding instructions above, never a guessed root task.
68
+ const packs = host === 'codex' ? ['implement', 'check'].map((phase) => renderPhaseContext(phaseContext(root, workflow, phase))) : [];
69
+ output({ additionalContext: [hint, ...packs].join('\n\n') });
70
+ process.exit(0);
71
+ }
72
+ const phase = reviewing ? 'check' : 'implement';
73
+ const pack = phaseContext(root, workflow, phase, relative);
74
+ const context = renderPhaseContext(pack);
75
+ if (['Agent', 'Task'].includes(tool) && typeof args.prompt === 'string') {
76
+ // Preserve every original argument and normal host permission checks.
77
+ if (host === 'codex') output({ additionalContext: context });
78
+ else output({ [host === 'codebuddy' ? 'modifiedInput' : 'updatedInput']: { ...args, prompt: `${args.prompt}\n\n${context}` } });
79
+ } else if (event === 'SubagentStart') {
80
+ output({ additionalContext: context });
81
+ } else if (host === 'codex' && input.agent_id) {
82
+ // Codex does not emit SessionStart when a child compacts or resumes. Do
83
+ // not suppress the next contract pack on the basis of a pre-compact cache.
84
+ output({ additionalContext: context });
85
+ } else if (host !== 'codebuddy') {
86
+ const digest = crypto.createHash('sha256').update(`${input.agent_id ?? 'main'}\n${context}`).digest('hex');
87
+ if (!(session.state?.injectedContexts ?? []).includes(digest)) {
88
+ output({ additionalContext: context });
89
+ writeSession(root, { injectedContexts: [...(session.state?.injectedContexts ?? []).slice(-15), digest] }, env);
90
+ }
91
+ }
92
+ } catch (error) {
93
+ if (event === 'PreToolUse') output({ permissionDecision: 'deny', permissionDecisionReason: `Keelson context could not be loaded: ${error.message}. Repair the declared context before retrying.` });
94
+ else output({ additionalContext: `Keelson context could not be loaded: ${error.message}. Investigate before implementation.` });
95
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zyaiting/keelson",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Local, verifiable check records and durable decisions for AI-assisted code changes.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 2,
3
- "updated": "2026-09-20",
4
- "note": "Adapters describe generated discovery paths, not a promise of live end-to-end host parity. Codex session identity has been exercised locally. Other hosts have adapter contract tests; hooks are supported only where listed. Native session identity sources include CODEX_THREAD_ID, Claude hooks, Pi environment and explicit KEELSON_SESSION_ID. No source means an honest degraded state. Default installation is lightweight; --vendor explicitly copies package guidance.",
3
+ "updated": "2026-09-21",
4
+ "note": "Adapters describe generated discovery paths, not a promise of live end-to-end host parity. Codex session identity has been exercised locally. Other hosts have adapter contract tests; Claude Code, Codex and CodeBuddy have workflow hook adapters; hook execution depends on the host version, trust and settings. Native session identity sources include CODEX_THREAD_ID, Claude hooks, Pi environment and explicit KEELSON_SESSION_ID. No source means an honest degraded state. Default installation is lightweight; --vendor explicitly copies package guidance.",
5
5
  "platforms": {
6
6
  "claude": {
7
7
  "label": "Claude Code",
@@ -19,7 +19,7 @@
19
19
  "bin": "codex",
20
20
  "instructions": "AGENTS.md",
21
21
  "skillsDir": ".agents/skills",
22
- "hooks": false,
22
+ "hooks": true,
23
23
  "confidence": "verified",
24
24
  "support": "first-class",
25
25
  "sessionFocus": "native",
@@ -71,7 +71,7 @@
71
71
  "bin": "codebuddy",
72
72
  "instructions": "CODEBUDDY.md",
73
73
  "skillsDir": ".codebuddy/skills",
74
- "hooks": false,
74
+ "hooks": true,
75
75
  "confidence": "documented",
76
76
  "support": "first-class",
77
77
  "sessionFocus": "native",