claude-coder 1.9.2 → 1.10.1

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 (40) hide show
  1. package/README.md +166 -141
  2. package/bin/cli.js +19 -4
  3. package/package.json +2 -2
  4. package/src/common/assets.js +66 -52
  5. package/src/common/config.js +22 -0
  6. package/src/common/sdk.js +1 -3
  7. package/src/common/utils.js +3 -1
  8. package/src/core/coding.js +3 -1
  9. package/src/core/design.js +268 -0
  10. package/src/core/go.js +3 -3
  11. package/src/core/hooks.js +30 -16
  12. package/src/core/init.js +9 -0
  13. package/src/core/plan.js +21 -15
  14. package/src/core/prompts.js +47 -2
  15. package/src/core/repair.js +1 -1
  16. package/src/core/runner.js +84 -117
  17. package/src/core/scan.js +4 -3
  18. package/src/core/session.js +30 -16
  19. package/src/core/simplify.js +4 -2
  20. package/src/core/state.js +23 -8
  21. package/src/index.js +4 -0
  22. package/templates/{codingUser.md → coding/user.md} +1 -0
  23. package/templates/design/base.md +103 -0
  24. package/templates/design/fixSystem.md +71 -0
  25. package/templates/design/fixUser.md +3 -0
  26. package/templates/design/init.md +304 -0
  27. package/templates/design/system.md +108 -0
  28. package/templates/design/user.md +11 -0
  29. package/templates/{coreProtocol.md → other/coreProtocol.md} +1 -0
  30. package/templates/{test_rule.md → other/test_rule.md} +0 -2
  31. package/templates/{planUser.md → plan/user.md} +2 -1
  32. /package/templates/{codingSystem.md → coding/system.md} +0 -0
  33. /package/templates/{goSystem.md → go/system.md} +0 -0
  34. /package/templates/{bash-process.md → other/bash-process.md} +0 -0
  35. /package/templates/{guidance.json → other/guidance.json} +0 -0
  36. /package/templates/{requirements.example.md → other/requirements.example.md} +0 -0
  37. /package/templates/{web-testing.md → other/web-testing.md} +0 -0
  38. /package/templates/{planSystem.md → plan/system.md} +0 -0
  39. /package/templates/{scanSystem.md → scan/system.md} +0 -0
  40. /package/templates/{scanUser.md → scan/user.md} +0 -0
package/README.md CHANGED
@@ -1,214 +1,239 @@
1
1
  # Claude Coder
2
2
 
3
- **中文** | [English](docs/README.en.md)
3
+ **中文** | [English](docs/README.en.md) | [在线文档](https://lk19940215.github.io/claude-coder/#/quick-start)
4
4
 
5
- 一个**长时间自运行的自主编码 Agent Harness**:基于 Claude Agent SDK,通过 Hook 提示注入引导模型行为,倒计时活跃度监控保障稳定运行,多 session 编排实现一句话需求到完整项目的全自动交付。
5
+ > 🚀 **一句话需求 完整项目。AI 编码数小时,你只需一行命令。**
6
6
 
7
- ### 亮点
7
+ **觉得好用?回来点个 ⭐ 吧!** 你的 Star 是我持续维护的最大动力。
8
8
 
9
- - **Session 生命周期管理**:Session 类封装 SDK 管理、query 执行、hooks、indicator 全生命周期,runner 编排循环含 AI 驱动的 JSON 自愈修复
10
- - **Hook 提示注入**:通过 JSON 配置在工具调用时向模型注入上下文引导,零代码修改即可扩展规则([机制详解](design/hook-mechanism.md))
11
- - **长时间自循环编码**:多 session 编排 + 倒计时活跃度监控 + git 回滚重试,Agent 可持续编码数小时不中断([守护机制](design/session-guard.md))
12
- - **配置驱动**:支持 Claude 官方、Coding Plan 多模型路由、DeepSeek 等任意 Anthropic 兼容 API
9
+ ```bash
10
+ claude-coder run "用 React + Express 做一个带登录的 Todo 应用"
11
+ ```
12
+
13
+ ```
14
+ ✓ 项目扫描完成
15
+ ✓ 分解为 8 个任务
16
+ ▸ Session 1/8: 搭建项目脚手架 .......... done ✅
17
+ ▸ Session 2/8: 实现用户注册/登录 ........ done ✅
18
+ ▸ Session 3/8: Todo CRUD ................ done ✅
19
+ ...
20
+ ✓ 全部任务完成,8 次提交已推送 🎉
21
+ ```
22
+
23
+ 你下一行命令,Claude Coder 拆需求、写代码、跑测试、提交 Git,**循环执行直到交付**。中间卡住了?自动回滚重试。JSON 损坏了?AI 自修复。你只需要等通知。
13
24
 
14
25
  ---
15
26
 
16
- ## 快速上手
27
+ ## 💡 你是不是也遇到过这些问题?
28
+
29
+ ### 🎨 "我不会设计 UI,做出来的页面又丑又乱"
30
+
31
+ > 你是后端出身,或者独立开发者,没有设计师搭档。每次做前端页面都在找模板、抄样式,结果还是不满意。
32
+
33
+ > ⚠️ **Windows 已知限制**:`.pen` 文件的跨文件组件引用(`ref: "sys:header"`)在 Windows 的 Pencil 插件中不受支持(Pencil应用也不支持)。Mac 桌面应用、插件均正常预览。建议在 Mac 上使用 design 命令生成和预览设计稿。跨文件变量引用(`$sys:color.bg`)和同文件内组件引用在所有平台均可用。
34
+
35
+ **✨ Claude Coder 的解法:**
17
36
 
18
37
  ```bash
19
- # 前置:安装 Claude Agent SDK
20
- npm install -g @anthropic-ai/claude-agent-sdk
38
+ claude-coder design "后台管理系统:用户管理、数据看板、系统设置"
39
+ ```
21
40
 
22
- # 安装
23
- npm install -g claude-coder
41
+ AI 自动生成专业的 `.pen` UI 设计稿 → 完整的配色、字体、组件规范 → 编码阶段 AI **自动参考设计稿还原 UI** 🎯
24
42
 
25
- # 配置模型
26
- claude-coder setup
27
43
 
28
- # 进入项目目录
29
- cd your-project
44
+ ### 😤 "AI 写的代码和设计稿差了十万八千里"
30
45
 
31
- # 初始化项目(扫描技术栈、生成 profile)
32
- claude-coder init
46
+ > 用了 AI 编码工具,代码能跑,但 UI 还原度惨不忍睹。颜色、间距、布局全凭 AI 想象。
33
47
 
34
- # 开始自动编码
35
- claude-coder run "实现用户注册和登录功能"
36
- ```
48
+ **✨ Claude Coder 的解法:**
37
49
 
38
- ## 命令列表
50
+ 设计文件通过 `design_map.json` 索引 → 编码时 AI 自动读取对应 `.pen` 设计文件 → 提取颜色、间距、组件结构 → **像素级还原设计意图** 🎯
39
51
 
40
- | 命令 | 说明 |
41
- |------|------|
42
- | `claude-coder setup` | 交互式配置(模型、MCP、安全限制、自动审查) |
43
- | `claude-coder init` | 初始化项目环境(扫描技术栈、生成 profile) |
44
- | `claude-coder init --deploy-templates` | 部署模板和食谱到项目目录(可自定义) |
45
- | `claude-coder plan "需求"` | 生成计划方案 |
46
- | `claude-coder plan -r [file]` | 从需求文件生成计划 |
47
- | `claude-coder plan --planOnly` | 仅生成计划文档,不分解任务 |
48
- | `claude-coder plan -i "需求"` | 交互模式,允许模型提问 |
49
- | `claude-coder go` | AI 对话式需求收集与方案组装 |
50
- | `claude-coder go "需求"` | AI 自动分析需求并组装方案 |
51
- | `claude-coder go -r file` | 从文件读取需求并自动组装 |
52
- | `claude-coder run [需求]` | 自动编码循环 |
53
- | `claude-coder run --max 1` | 单次执行 |
54
- | `claude-coder run --dry-run` | 预览模式(查看任务队列) |
55
- | `claude-coder simplify [focus]` | 代码审查和简化 |
56
- | `claude-coder auth [url]` | 配置浏览器测试工具 / 导出登录状态 |
57
- | `claude-coder status` | 查看进度和成本 |
58
-
59
- **选项**:`--max N` 限制 session 数(默认 50),`--pause N` 每 N 个 session 暂停确认,`--model M` 指定模型。
60
-
61
- ## 工作原理
62
-
63
- ```
64
- 需求输入 ─→ 项目扫描 ─→ 任务分解 ─→ 编码循环
65
-
66
- ┌──────┴──────┐
67
- │ Session N │
68
- │ Claude SDK │
69
- │ 3 步流程 │
70
- └──────┬──────┘
71
-
72
- runner 校验
73
- (含 AI 自愈)
74
-
75
- 通过 → simplify? → push → 下一个任务
76
- 失败 → git 回滚 + 重试
77
- ```
78
-
79
- 每个 session 内,Agent 自主执行 3 步:**实现**(任务上下文由 prompt 注入,编码实现) → **验证**(按 category 选最轻量测试) → **收尾**(git commit + 写 session_result.json)。
80
-
81
- Runner 在 session 结束后自动校验 `session_result.json` + git 进度。校验失败时 AI 自动尝试修复损坏的 JSON 文件(`repair.js`),仍失败则回滚代码并重试。
82
-
83
- ## 机制文档
52
+ ### 💥 "AI 编码工具总是中途崩、半途而废"
84
53
 
85
- | 文档 | 说明 |
86
- |------|------|
87
- | [技术架构](design/ARCHITECTURE.md) | 核心设计规则、Session 类职责、模块关系、Prompt 注入架构 |
88
- | [Hook 注入机制](design/hook-mechanism.md) | SDK Hook 调研、GuidanceInjector 三级匹配、配置格式、副作用评估 |
89
- | [Session 守护机制](design/session-guard.md) | 中断策略、倒计时活跃度检测、工具运行状态追踪、防刷屏 |
90
- | [Go 指令流程](design/go-flow.md) | AI 驱动的需求组装、食谱系统、与 plan 衔接 |
91
- | [浏览器测试工具](docs/PLAYWRIGHT_CREDENTIALS.md) | Playwright MCP / Chrome DevTools MCP 对比、安装、凭证管理 |
92
- | [SDK 使用指南](docs/CLAUDE_AGENT_SDK_GUIDE.md) | Claude Agent SDK 接口参考 |
54
+ > 用过其他 AI 编码工具,写了几个文件就卡住了、报错了、或者把之前的代码覆盖了。每次都要手动介入。
93
55
 
94
- ## 使用场景
56
+ **✨ Claude Coder 的解法:**
95
57
 
96
- **新项目**:`claude-coder run "用 Express + React 做 Todo 应用"` — 自动搭建脚手架、分解任务、逐个实现。
58
+ ```
59
+ 失败 → 🔄 自动回滚到上一个好的提交
60
+ 再试 → 🛠️ AI 自修复损坏的 JSON
61
+ 又失败 → ⏭️ 自动跳过,继续下一个任务
62
+ ```
97
63
 
98
- **已有项目**:`claude-coder run "新增头像上传功能"` 先扫描现有代码和技术栈,再增量开发。
64
+ Session 编排 + 活跃度监控,**Agent 连续编码数小时不中断** ⚡
99
65
 
100
- **需求文档驱动**:在项目根目录创建 `requirements.md`,运行 `claude-coder plan -r requirements.md` 分解任务后 `claude-coder run` 执行。
66
+ ### 🧹 "AI 写的代码越堆越乱,没人 Review"
101
67
 
102
- **AI 驱动需求组装**:`claude-coder go "用户管理页面"` — AI 扫描内置食谱库,自动组装完整需求方案,一键进入 plan 分解任务。支持对话模式 (`go`) 逐步引导非技术人员。
68
+ > AI 编码工具产出大量代码,但没有人审查质量。冗余逻辑、重复代码越积越多,最后不敢改。
103
69
 
104
- **自动测试 + 凭证持久化**:`claude-coder auth http://localhost:3000` — 导出浏览器登录态,Agent 测试时自动使用。详见 [浏览器测试工具指南](docs/PLAYWRIGHT_CREDENTIALS.md)。
70
+ **✨ Claude Coder 的解法:**
105
71
 
106
- ## 浏览器测试工具
72
+ ```
73
+ Session 3 完成 ✅ → 🧹 自动审查最近代码变更
74
+ 发现冗余 → 重构优化 → 自动提交 style: auto simplify
75
+ Session 4 继续 ▸
76
+ ```
107
77
 
108
- 支持两种 MCP 浏览器测试工具,通过 `WEB_TEST_TOOL` 环境变量切换:
78
+ 每隔 N session 自动触发 AI 代码审查(`simplify`),审查累积变更、消除冗余、优化结构,**编码和审查一体化** 🎯
109
79
 
110
- | 维度 | Playwright MCP | Chrome DevTools MCP |
111
- |------|---------------|---------------------|
112
- | **维护方** | 微软 | Google |
113
- | **核心优势** | 25+ 自动化工具,多实例并行 | 连接已打开 Chrome,调试能力强 |
114
- | **多实例** | 支持 | 不支持(单实例,多开请用 Playwright) |
115
- | **安装依赖** | `npx playwright install chromium` | Node.js v20.19+ / Chrome 144+ |
116
- | **凭证方案** | persistent 模式复用登录态 | 直接复用已打开 Chrome 的登录态 |
117
- | **适合场景** | CI/CD、多并行测试、需要 Chromium 隔离 | 本地开发、调试、利用已有 Chrome 环境 |
80
+ ### 🤹 "一个人要干前端、后端、测试、部署"
118
81
 
119
- ### 安装步骤
82
+ > 独立开发者或者小团队,一个人要搞定所有环节。
120
83
 
121
- ```bash
122
- # Playwright MCP(推荐)
123
- claude-coder setup # → 选择「Playwright MCP」→ 选择模式
124
- npx playwright install chromium
125
- claude-coder auth http://your-app.com # 导出登录态
84
+ **✨ Claude Coder 的解法:**
126
85
 
127
- # Chrome DevTools MCP(需 Node.js v20.19+)
128
- claude-coder setup #选择「Chrome DevTools MCP」
129
- # 打开 Chrome → chrome://inspect/#remote-debugging → 启用远程调试
130
- claude-coder auth # 配置 .mcp.json
86
+ ```
87
+ 📝 需求描述 → 🎨 UI 设计 📋 任务分解 → 💻 编码实现 → ✅ 测试验证 → 📦 Git 提交
131
88
  ```
132
89
 
133
- ### 常见问题
90
+ **全流程自动化**,你只需要描述你想要什么。
134
91
 
135
- **Q: Playwright 和 Chrome DevTools 该选哪个?**
136
- A: 如果你需要多实例并行测试或 CI/CD 集成,选 Playwright MCP。如果你只需要本地调试、想复用已打开 Chrome 的登录态和扩展,选 Chrome DevTools MCP。
92
+ ---
137
93
 
138
- **Q: Chrome DevTools MCP 报 `chrome-devtools-mcp` 安装失败?**
139
- A: 确保 Node.js ≥ v20.19。nvm 用户执行 `nvm alias default 22 && nvm use 22`,然后重新安装 `npm install -g @anthropic-ai/claude-code`。
94
+ ## 🔗 完整工作流
140
95
 
141
- **Q: Playwright 浏览器启动后白屏或超时?**
142
- A: 运行 `npx playwright install chromium` 确保浏览器已安装。persistent 模式下检查 `.claude-coder/.runtime/browser-profile/` 目录是否存在。
96
+ ```
97
+ 📝 需求输入 🎉 最终交付
98
+ │ ▲
99
+ ▼ │
100
+ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────────┐
101
+ │ 🎨 │ │ 📋 │ │ 🔍 │ │ 🔄 run (循环) │
102
+ │ design │ → │ plan │ → │ init │ → │ ┌──────────────┐ │
103
+ │ UI 设计 │ │ 分解任务 │ │ 扫描项目 │ │ │ Session N │ │
104
+ │ .pen │ │ tasks │ │ profile │ │ │ 💻 编码 │ │
105
+ └─────────┘ └─────────┘ └─────────┘ │ │ ✅ 验证 │ │
106
+ │ │ │ 📦 提交 │ │
107
+ └──── 📄 design_map.json ─────────────→ │ └──────┬───────┘ │
108
+ │ │ │
109
+ │ 每 N 次 → 🧹 审查 │
110
+ │ 失败 → 🔄 回滚 │
111
+ └─────────────────────┘
112
+ ```
143
113
 
144
- **Q: 切换工具后需要重新认证吗?**
145
- A: 不需要。`claude-coder setup` 切换时自动更新 `.env` 和 `.mcp.json`。之前的认证数据(如 browser-profile)保留,切回时直接可用。
114
+ **关键链路:design → plan → run → simplify 全程贯通。** 设计稿通过 `design_map.json` 索引,编码阶段 AI 自动参考。每隔 N 个成功 session 自动触发代码审查,编码和质量保障一体化。
146
115
 
147
- **Q: 两个工具可以同时启用吗?**
148
- A: 不可以。`.mcp.json` 中同时只保留一个工具的配置,切换时自动替换。
116
+ ---
149
117
 
150
- 详见 [浏览器测试工具完整文档](docs/PLAYWRIGHT_CREDENTIALS.md)。
118
+ ## ⚡ 30 秒上手
151
119
 
152
- ## 模型支持
120
+ ```bash
121
+ # 1️⃣ 安装
122
+ npm install -g @anthropic-ai/claude-agent-sdk
123
+ npm install -g claude-coder
124
+
125
+ # 2️⃣ 配置(交互式,选模型 + API)
126
+ claude-coder setup
127
+
128
+ # 3️⃣ 跑起来
129
+ cd your-project
130
+ claude-coder init
131
+ claude-coder run "实现用户注册和登录功能"
132
+ ```
133
+
134
+ 就这么简单。
135
+
136
+ ---
137
+
138
+ ## 🏆 核心能力
139
+
140
+ | | 能力 | 说明 |
141
+ |---|------|------|
142
+ | 📝 | **需求 → 代码** | 一句话或需求文档输入,自动分解任务、逐个编码实现 |
143
+ | 🎨 | **AI 生成 UI 设计** | `design` 命令生成 `.pen` 设计稿,编码时 AI 自动参考 |
144
+ | 🔄 | **长时间自运行** | 多 Session 编排 + 活跃度监控,连续编码数小时不中断 |
145
+ | 🛡️ | **自愈与容错** | 校验失败自动回滚,损坏文件 AI 修复,连续失败自动跳过 |
146
+ | 🧹 | **自动代码审查** | 每 N 个 session 自动审查累积变更,消除冗余、优化结构 |
147
+ | 🔌 | **任意模型** | Claude、DeepSeek、GLM、Qwen 或任何兼容 API |
148
+ | ⚙️ | **Hook 提示注入** | JSON 配置注入行为引导,零代码扩展 AI 规则 |
149
+
150
+ ---
153
151
 
154
- | 提供商 | 说明 |
155
- |--------|------|
156
- | 默认 | Claude 官方模型,使用系统登录态 |
157
- | Coding Plan | 自建 API,推荐的多模型路由配置 |
158
- | API | DeepSeek 或其他 Anthropic 兼容 API |
152
+ ## 📖 命令速查
159
153
 
160
- ## 建议配置
154
+ | 命令 | 说明 |
155
+ |------|------|
156
+ | `setup` | 🔧 交互式配置(模型、MCP、安全限制) |
157
+ | `init` | 🔍 初始化项目(扫描技术栈、生成 profile) |
158
+ | `go [需求]` | 💬 AI 驱动的需求收集与方案组装 |
159
+ | `plan "需求"` | 📋 生成计划并分解任务 |
160
+ | `design [需求]` | 🎨 AI 生成 UI 设计(`.pen` 文件) |
161
+ | `design --type fix` | 🛠️ 修复不合规的设计文件 |
162
+ | `run [需求]` | 🚀 自动编码循环 |
163
+ | `simplify [focus]` | 🧹 代码审查和简化 |
164
+ | `auth [url]` | 🔐 配置浏览器测试工具 |
165
+ | `status` | 📊 查看进度和成本 |
166
+
167
+ **常用选项**:`--max N` 限制 session 数 / `--pause N` 每 N 个暂停确认 / `--dry-run` 预览 / `--model M` 指定模型
168
+
169
+ ---
161
170
 
162
- ### 长时间自运行 Agent(最稳)
171
+ ## 🤖 模型推荐
163
172
 
173
+ **长时间自运行(最稳定)**
164
174
  ```bash
165
175
  ANTHROPIC_DEFAULT_OPUS_MODEL=glm-5
166
176
  ANTHROPIC_DEFAULT_SONNET_MODEL=qwen3-coder-next
167
- ANTHROPIC_DEFAULT_HAIKU_MODEL=qwen3-coder-plus
168
177
  ANTHROPIC_MODEL=kimi-k2.5
169
178
  ```
170
179
 
171
- ### 自用 Claude Code(最强)
172
-
180
+ **自用(最强)**
173
181
  ```bash
174
182
  ANTHROPIC_DEFAULT_OPUS_MODEL=qwen3-max-2026-01-23
175
183
  ANTHROPIC_DEFAULT_SONNET_MODEL=qwen3-coder-next
176
- ANTHROPIC_DEFAULT_HAIKU_MODEL=qwen3-coder-plus
177
184
  ANTHROPIC_MODEL=glm-5
178
185
  ```
179
186
 
180
- ## 项目结构
187
+ ---
188
+
189
+ ## 📚 深入了解
190
+
191
+ | 文档 | 说明 |
192
+ |------|------|
193
+ | [🏗️ 技术架构](design/ARCHITECTURE.md) | Session 类、模块关系、Prompt 注入 |
194
+ | [🪝 Hook 机制](design/hook-mechanism.md) | 三级匹配、配置格式 |
195
+ | [🛡️ Session 守护](design/session-guard.md) | 倒计时检测、状态追踪 |
196
+ | [💬 Go 指令](design/go-flow.md) | 需求组装、食谱系统 |
197
+ | [🎨 UI 设计流程](design/ui-design-flow.md) | design 命令、与编码联动 |
198
+ | [🌐 浏览器测试](docs/PLAYWRIGHT_CREDENTIALS.md) | Playwright / Chrome DevTools |
199
+ | [📖 SDK 参考](docs/CLAUDE_AGENT_SDK_GUIDE.md) | Claude Agent SDK 接口 |
200
+
201
+ ---
202
+
203
+ <details>
204
+ <summary>📁 项目结构</summary>
181
205
 
182
206
  ```
183
207
  your-project/
184
- .claude-coder/ # 运行时数据(gitignored)
208
+ .claude-coder/
185
209
  .env # 模型配置
186
210
  project_profile.json # 项目扫描结果
187
211
  tasks.json # 任务列表 + 状态
188
- session_result.json # 上次 session 结果
189
- progress.json # 会话历史 + 成本
190
- test.env # 测试凭证(可选)
191
- go/ # go 指令输出的方案文件
192
- recipes/ # 食谱库(--deploy-templates 时从内置模板部署,可选)
212
+ design/ # UI 设计文件
213
+ design_map.json # 设计映射表
214
+ pages/ # 页面设计(.pen)
215
+ go/ # go 指令输出方案
216
+ recipes/ # 食谱库(可选)
193
217
  .runtime/
194
- harness_state.json # 运行状态(session 计数等)
195
- logs/ # session 独立日志
218
+ harness_state.json # 运行状态
219
+ logs/ # session 日志
196
220
  ```
197
221
 
198
- ## 常见问题
222
+ </details>
199
223
 
200
- **"Credit balance is too low"**:运行 `claude-coder setup` 重新配置 API Key。
224
+ ## FAQ
201
225
 
202
226
  **中断恢复**:直接重新运行 `claude-coder run`,从上次中断处继续。
203
227
 
204
- **长时间无响应**:模型处理复杂任务时可能出现长思考间隔(indicator 显示黄色"工具执行中"或红色"无响应"),这是正常行为。超过阈值后自动中断并重试。通过 `claude-coder setup` 的安全限制配置或 `.env` `SESSION_STALL_TIMEOUT=秒数` 调整。
228
+ **跳过任务**:将 `tasks.json` 中该任务的 `status` 改为 `done`。
229
+
230
+ **长时间无响应**:超过阈值后自动中断并重试。通过 `claude-coder setup` 调整超时。
205
231
 
206
- **跳过任务**:将 `.claude-coder/tasks.json` 中该任务的 `status` 改为 `done`。
232
+ ---
207
233
 
208
- ## 参考文章
234
+ ---
209
235
 
210
- [Anthropic: Effective harnesses for long-running agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents)
211
236
 
212
- ## License
237
+ 📖 [Anthropic: Effective harnesses for long-running agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents)
213
238
 
214
- MIT
239
+ MIT License
package/bin/cli.js CHANGED
@@ -12,6 +12,7 @@ const COMMANDS = {
12
12
  auth: { desc: '导出 Playwright 登录状态', usage: 'claude-coder auth [url]' },
13
13
  status: { desc: '查看任务进度和成本', usage: 'claude-coder status' },
14
14
  go: { desc: 'AI 驱动的需求组装', usage: 'claude-coder go ["需求"] [-r file] [--reset]' },
15
+ design: { desc: 'AI 生成/修改 UI 设计', usage: 'claude-coder design ["需求"] [--type init|new|fix] [--reset]' },
15
16
  };
16
17
 
17
18
  function showHelp() {
@@ -38,6 +39,13 @@ function showHelp() {
38
39
  console.log(' claude-coder go "用户管理页面" AI 自动分析需求并组装方案');
39
40
  console.log(' claude-coder go -r requirements.md 从文件读取需求并自动组装');
40
41
  console.log(' claude-coder go --reset 重置 Go 记忆');
42
+ console.log(' claude-coder design 对话式 UI 设计');
43
+ console.log(' claude-coder design "用户管理后台" AI 自动生成 UI 设计');
44
+ console.log(' claude-coder design "改成暗色主题" 迭代修改已有设计');
45
+ console.log(' claude-coder design "还原首页" --model glm-5 推荐模型');
46
+ console.log(' claude-coder design --type fix 修复 .pen 文件格式问题');
47
+ console.log(' claude-coder design --type init 强制初始化设计库');
48
+ console.log(' claude-coder design --reset 重置设计状态');
41
49
  console.log(' claude-coder auth 导出 Playwright 登录状态');
42
50
  console.log(' claude-coder auth http://localhost:8080 指定登录 URL');
43
51
  console.log(' claude-coder status 查看进度和成本');
@@ -57,9 +65,11 @@ function parseArgs(argv) {
57
65
  args.splice(i, 1, args[i].slice(0, eq), args[i].slice(eq + 1));
58
66
  }
59
67
  switch (args[i]) {
60
- case '--max':
61
- opts.max = parseInt(args[++i], 10) || 50;
68
+ case '--max': {
69
+ const v = parseInt(args[++i], 10);
70
+ opts.max = isNaN(v) ? 50 : v;
62
71
  break;
72
+ }
63
73
  case '--pause':
64
74
  { const v = parseInt(args[++i], 10); opts.pause = (v >= 0 && !isNaN(v)) ? v : 5; }
65
75
  break;
@@ -70,9 +80,11 @@ function parseArgs(argv) {
70
80
  opts.model = args[++i] || null;
71
81
  break;
72
82
  case '-n':
73
- case '--n':
74
- opts.n = parseInt(args[++i], 10) || 3;
83
+ case '--n': {
84
+ const nv = parseInt(args[++i], 10);
85
+ opts.n = isNaN(nv) ? 3 : nv;
75
86
  break;
87
+ }
76
88
  case '-r': {
77
89
  const next = args[i + 1];
78
90
  if (next && !next.startsWith('-')) {
@@ -89,6 +101,9 @@ function parseArgs(argv) {
89
101
  case '--reset':
90
102
  opts.reset = true;
91
103
  break;
104
+ case '--type':
105
+ opts.type = args[++i] || null;
106
+ break;
92
107
  case '-i':
93
108
  case '--interactive':
94
109
  opts.interactive = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-coder",
3
- "version": "1.9.2",
3
+ "version": "1.10.1",
4
4
  "description": "Claude Coder — Autonomous coding agent harness powered by Claude Code SDK. Scan, plan, code, validate, git-commit in a loop.",
5
5
  "bin": {
6
6
  "claude-coder": "bin/cli.js"
@@ -14,7 +14,7 @@
14
14
  "templates/"
15
15
  ],
16
16
  "scripts": {
17
- "test": "node test/complete.test.js && node test/integration.test.js && node test/flow.test.js"
17
+ "test": "node test/complete.test.js && node test/integration.test.js && node test/flow.test.js && node test/interaction.test.js"
18
18
  },
19
19
  "keywords": [
20
20
  "claude-coder",
@@ -11,24 +11,36 @@ const BUNDLED_RECIPES_DIR = path.join(__dirname, '..', '..', 'recipes');
11
11
  // kind: 'runtime' — .claude-coder/.runtime/ 目录,无缓存
12
12
  // kind: 'root' — 项目根目录,无缓存
13
13
  const REGISTRY = new Map([
14
- // System Prompt Templates (per session type)
15
- ['coreProtocol', { file: 'coreProtocol.md', kind: 'template' }],
16
- ['codingSystem', { file: 'codingSystem.md', kind: 'template' }],
17
- ['planSystem', { file: 'planSystem.md', kind: 'template' }],
18
- ['scanSystem', { file: 'scanSystem.md', kind: 'template' }],
19
- ['goSystem', { file: 'goSystem.md', kind: 'template' }],
20
-
21
- // User Prompt Templates
22
- ['codingUser', { file: 'codingUser.md', kind: 'template' }],
23
- ['scanUser', { file: 'scanUser.md', kind: 'template' }],
24
- ['planUser', { file: 'planUser.md', kind: 'template' }],
25
-
26
- // Other Templates
27
- ['testRule', { file: 'test_rule.md', kind: 'template' }],
28
- ['guidance', { file: 'guidance.json', kind: 'template' }],
29
- ['webTesting', { file: 'web-testing.md', kind: 'template' }],
30
- ['bashProcess', { file: 'bash-process.md', kind: 'template' }],
31
- ['requirements', { file: 'requirements.example.md', kind: 'template' }],
14
+ // Go templates
15
+ ['goSystem', { file: ['go', 'system.md'], kind: 'template' }],
16
+
17
+ // Plan templates
18
+ ['planSystem', { file: ['plan', 'system.md'], kind: 'template' }],
19
+ ['planUser', { file: ['plan', 'user.md'], kind: 'template' }],
20
+
21
+ // Coding templates
22
+ ['codingSystem', { file: ['coding', 'system.md'], kind: 'template' }],
23
+ ['codingUser', { file: ['coding', 'user.md'], kind: 'template' }],
24
+
25
+ // Scan templates
26
+ ['scanSystem', { file: ['scan', 'system.md'], kind: 'template' }],
27
+ ['scanUser', { file: ['scan', 'user.md'], kind: 'template' }],
28
+
29
+ // Design templates
30
+ ['designBase', { file: ['design', 'base.md'], kind: 'template' }],
31
+ ['designSystem', { file: ['design', 'system.md'], kind: 'template' }],
32
+ ['designFixSystem',{ file: ['design', 'fixSystem.md'], kind: 'template' }],
33
+ ['designInit', { file: ['design', 'init.md'], kind: 'template' }],
34
+ ['designUser', { file: ['design', 'user.md'], kind: 'template' }],
35
+ ['designFixUser', { file: ['design', 'fixUser.md'], kind: 'template' }],
36
+
37
+ // Shared / other templates
38
+ ['coreProtocol', { file: ['other', 'coreProtocol.md'], kind: 'template' }],
39
+ ['testRule', { file: ['other', 'test_rule.md'], kind: 'template' }],
40
+ ['guidance', { file: ['other', 'guidance.json'], kind: 'template' }],
41
+ ['webTesting', { file: ['other', 'web-testing.md'], kind: 'template' }],
42
+ ['bashProcess', { file: ['other', 'bash-process.md'], kind: 'template' }],
43
+ ['requirements', { file: ['other', 'requirements.example.md'], kind: 'template' }],
32
44
 
33
45
  // Data files (.claude-coder/)
34
46
  ['env', { file: '.env', kind: 'data' }],
@@ -38,9 +50,10 @@ const REGISTRY = new Map([
38
50
  ['profile', { file: 'project_profile.json', kind: 'data' }],
39
51
  ['testEnv', { file: 'test.env', kind: 'data' }],
40
52
  ['playwrightAuth', { file: 'playwright-auth.json', kind: 'data' }],
53
+ ['designMap', { file: ['design', 'design_map.json'], kind: 'data' }],
41
54
 
42
55
  // Runtime files (.claude-coder/.runtime/)
43
- ['harnessState', { file: 'harness_state.json', kind: 'runtime' }],
56
+ ['harnessState', { file: 'harness_state.json', kind: 'data' }],
44
57
  ['browserProfile', { file: 'browser-profile', kind: 'runtime' }],
45
58
 
46
59
  // Root files (project root)
@@ -52,6 +65,8 @@ const DIRS = new Map([
52
65
  ['assets', 'assets'],
53
66
  ['runtime', '.runtime'],
54
67
  ['logs', '.runtime/logs'],
68
+ ['design', 'design'],
69
+ ['designPages', 'design/pages'],
55
70
  ]);
56
71
 
57
72
  function renderTemplate(template, vars = {}) {
@@ -71,39 +86,43 @@ class AssetManager {
71
86
  this.assetsDir = null;
72
87
  this.bundledDir = BUNDLED_DIR;
73
88
  this.registry = new Map(REGISTRY);
74
- this.cache = new Map();
75
89
  }
76
90
 
77
91
  init(projectRoot) {
78
92
  this.projectRoot = projectRoot || process.cwd();
79
93
  this.loopDir = path.join(this.projectRoot, '.claude-coder');
80
94
  this.assetsDir = path.join(this.loopDir, 'assets');
81
- this.cache.clear();
82
95
  }
83
96
 
84
97
  _ensureInit() {
85
98
  if (!this.loopDir) this.init();
86
99
  }
87
100
 
101
+ _fileSegments(file) {
102
+ return Array.isArray(file) ? file : [file];
103
+ }
104
+
105
+
88
106
  path(name) {
89
107
  this._ensureInit();
90
108
  const entry = this.registry.get(name);
91
109
  if (!entry) return null;
110
+ const segs = this._fileSegments(entry.file);
92
111
  switch (entry.kind) {
93
- case 'template': return this._resolveTemplate(entry.file);
94
- case 'data': return path.join(this.loopDir, entry.file);
95
- case 'runtime': return path.join(this.loopDir, '.runtime', entry.file);
96
- case 'root': return path.join(this.projectRoot, entry.file);
112
+ case 'template': return this._resolveTemplate(segs);
113
+ case 'data': return path.join(this.loopDir, ...segs);
114
+ case 'runtime': return path.join(this.loopDir, '.runtime', ...segs);
115
+ case 'root': return path.join(this.projectRoot, ...segs);
97
116
  default: return null;
98
117
  }
99
118
  }
100
119
 
101
- _resolveTemplate(filename) {
120
+ _resolveTemplate(segments) {
102
121
  if (this.assetsDir) {
103
- const userPath = path.join(this.assetsDir, filename);
122
+ const userPath = path.join(this.assetsDir, ...segments);
104
123
  if (fs.existsSync(userPath)) return userPath;
105
124
  }
106
- const bundled = path.join(this.bundledDir, filename);
125
+ const bundled = path.join(this.bundledDir, ...segments);
107
126
  if (fs.existsSync(bundled)) return bundled;
108
127
  return null;
109
128
  }
@@ -125,18 +144,8 @@ class AssetManager {
125
144
  const entry = this.registry.get(name);
126
145
  if (!entry) return null;
127
146
 
128
- if (entry.kind === 'template') {
129
- const key = entry.file;
130
- if (this.cache.has(key)) return this.cache.get(key);
131
- const filePath = this._resolveTemplate(entry.file);
132
- if (!filePath) return '';
133
- const content = fs.readFileSync(filePath, 'utf8');
134
- this.cache.set(key, content);
135
- return content;
136
- }
137
-
138
147
  const filePath = this.path(name);
139
- if (!filePath || !fs.existsSync(filePath)) return null;
148
+ if (!filePath || !fs.existsSync(filePath)) return entry.kind === 'template' ? '' : null;
140
149
  return fs.readFileSync(filePath, 'utf8');
141
150
  }
142
151
 
@@ -184,17 +193,25 @@ class AssetManager {
184
193
  if (!fs.existsSync(this.assetsDir)) {
185
194
  fs.mkdirSync(this.assetsDir, { recursive: true });
186
195
  }
187
- const files = fs.readdirSync(this.bundledDir);
188
196
  const deployed = [];
189
- for (const file of files) {
190
- const dest = path.join(this.assetsDir, file);
191
- if (fs.existsSync(dest)) continue;
192
- const src = path.join(this.bundledDir, file);
193
- try {
194
- fs.copyFileSync(src, dest);
195
- deployed.push(file);
196
- } catch { /* skip */ }
197
- }
197
+ const walk = (srcBase, destBase) => {
198
+ const entries = fs.readdirSync(srcBase, { withFileTypes: true });
199
+ for (const entry of entries) {
200
+ const srcPath = path.join(srcBase, entry.name);
201
+ const destPath = path.join(destBase, entry.name);
202
+ if (entry.isDirectory()) {
203
+ if (!fs.existsSync(destPath)) fs.mkdirSync(destPath, { recursive: true });
204
+ walk(srcPath, destPath);
205
+ } else {
206
+ if (fs.existsSync(destPath)) continue;
207
+ try {
208
+ fs.copyFileSync(srcPath, destPath);
209
+ deployed.push(path.relative(this.assetsDir, destPath));
210
+ } catch { /* skip */ }
211
+ }
212
+ }
213
+ };
214
+ walk(this.bundledDir, this.assetsDir);
198
215
  return deployed;
199
216
  }
200
217
 
@@ -235,9 +252,6 @@ class AssetManager {
235
252
  return BUNDLED_RECIPES_DIR;
236
253
  }
237
254
 
238
- clearCache() {
239
- this.cache.clear();
240
- }
241
255
  }
242
256
 
243
257
  const assets = new AssetManager();