add-coder 0.1.4 → 0.1.7

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.
package/README.md CHANGED
@@ -1,10 +1,70 @@
1
1
  # add-coder
2
2
 
3
- [codein2027](https://github.com/xiaomingming92/codein2027) 项目配套工具包——将 ADD 范式从"公司内部方法论"落地为"任何人 `npx` 即可体验的开源工具"。
3
+ **AI 代码治理的落地方案** — [codein2027](https://github.com/xiaomingming92/codein2027) 快速构建 ADD 编程范式的完整脚手架。以「审计即基础设施」为核心,彻底打破编程过程黑盒与跨轮失忆,让编程范式进化为可审计、可追溯、可收敛的新时代。
4
4
 
5
- 一键初始化 ADD(Audit-Driven Development)范式工作流模板,支持 Claude Code、Qoder、VS Code 三端。
5
+ ```bash
6
+ npx add-coder init
7
+ ```
8
+
9
+ ---
10
+
11
+ ## 这不是模板工具,这是架构差异
12
+
13
+ 市面上已有大量 AI 编程模板、hook 适配器、MCP 脚手架。add-coder 与它们的根本区别不在「生成什么文件」,而在 **架构层面的范式转换**:
14
+
15
+ ### ① 审计是基础设施,而非事后日志
16
+
17
+ 传统 AI 开发:对话 → 生成代码 → 事后翻聊天记录找「谁改了什么」
18
+
19
+ | 传统模式 | add-coder |
20
+ |---------|----------|
21
+ | 日志是 append-only 文本文件 | 审计是 **结构化数据表**(DevOperation + AuditLog),支持按 plan/step/agent/tool 多维查询 |
22
+ | 审计靠开发者自觉记录 | **MCP 审计工具链** 自动记录每次操作,系统闸门强制检查 |
23
+ | 无关联性 | 审计事件天然关联 Plan → Spec → Task → Step → Tool Call,形成完整证据链 |
24
+
25
+ ### ② 门禁驱动,而非自由对话
26
+
27
+ 传统 AI coding 是「你说我做」,质量完全依赖 LLM 当天状态。add-coder 在架构中嵌入了 **双质量闸门**:
28
+
29
+ ```
30
+ DPS (Design-Process Symmetry) — 设计/实现/文档/审计 四维各 25%,< 85% BLOCKED
31
+ RAHS (Runtime Architecture Health Score) — 运行时架构健康度,< 90% BLOCKED
32
+ ```
33
+
34
+ 这不是「建议」,是**架构阻断** — 不通过闸门的 Step 无法推进到下一步。
35
+
36
+ ### ③ 跨轮记忆,而非每轮失忆
37
+
38
+ AI 对话的致命缺陷:上次讨论的架构决策、已修复的 Bug、达成的约定,下轮对话全部遗忘。add-coder 在架构层面解决:
39
+
40
+ - **Handoff 文档** — 每轮 Session 结束时自动生成结构化交接文档,下轮会话自动加载
41
+ - **Plan 索引** — 所有 Plan 通过 `index.md` 集中索引,支持模糊匹配快速定位
42
+ - **DevLog 时序记录** — 每一步操作写入 `{YYYY-MM}/{DD}/` 时间轴,可回溯任意历史状态
6
43
 
7
- ADD 范式将 AI 开发从"口述代码"升级为"可审计工程"——DPS/RAHS 双质量闸门 + ADD-7 审计追踪 + policy-update-loop 运行时自适应。详见 [codein2027/README.md §"ADD 范式与商业化路径"](https://github.com/xiaomingming92/codein2027#add-paradigm)。
44
+ ### Policy-Update-Loop:治理自我进化
45
+
46
+ 不是静态模板,而是**闭环自适应系统**:
47
+
48
+ ```
49
+ 执行 → 审计 → 边界报告 → 规则调整 → 下一轮执行
50
+ ```
51
+
52
+ 运行时产生的 Report 会反过来更新 governance rules,实现治理策略的持续进化。
53
+
54
+ ### ⑤ 多 IDE 的 Hook 即治理层
55
+
56
+ hook 不是「通知推送」,而是 **IDE 运行时拦截层**:
57
+
58
+ | Hook 类型 | 作用 |
59
+ |----------|------|
60
+ | PreToolUse | 工具调用前校验白名单、注入上下文、DPS 条件检查 |
61
+ | PostToolUse | 自动审计记录、Plan 同步检测、格式守卫 |
62
+ | PreCompact | 跨轮上下文压缩时强制保留关键文档路径 |
63
+ | PromptSubmit | 注入 ADD 词汇表触发词,确保 LLM 对「验收」「门禁」等命令零延迟响应 |
64
+
65
+ 每个 IDE(Claude/Qoder/VS Code)有各自的 hook 实现,但**治理逻辑统一** — 架构一致,适配层不同。
66
+
67
+ ---
8
68
 
9
69
  ## 快速开始
10
70
 
@@ -47,8 +107,6 @@ npx add-coder init --yes
47
107
 
48
108
  ### init 内部流程
49
109
 
50
- `npx add-coder init` 按以下步骤执行:
51
-
52
110
  | 步骤 | 动作 | 说明 |
53
111
  |------|------|------|
54
112
  | ① | 检测 IDE | 扫描 `.qoder/` `.claude/` `.vscode/` 存在性,或通过 `--adapter` 指定 |
@@ -59,8 +117,6 @@ npx add-coder init --yes
59
117
  | ⑥ | 写入文件 | 交互/yes/force/dry-run 四种模式,`.sh` 脚本自动 `chmod` |
60
118
  | ⑦ | 输出摘要 | 新建/跳过/覆盖统计 + 下一步提示 |
61
119
 
62
- > **Prisma 注入说明**:ADD-7 审计需要 `DevOperation` + `AuditLog` 两张表。首次 `init` 自动引导 `prisma init` 并注入 `User` 模型,第二次 `init` 执行 `prisma migrate dev` 完成建表。
63
-
64
120
  ### init 选项
65
121
 
66
122
  | 选项 | 说明 |
@@ -80,11 +136,61 @@ npx add-coder init --yes
80
136
  | `.qoder/` | Qoder 适配(hooks、settings.json、mcp.json) |
81
137
  | `.vscode/` | VS Code 适配(settings.json、tasks.json) |
82
138
 
83
- ## 边界说明
139
+ ## MCP 审计工具链
140
+
141
+ `init` 自动部署 MCP 服务器 (`mcp-server.ts`) 到项目中,IDE 通过 `mcp.json` 加载。提供以下审计与治理工具:
84
142
 
85
- npm 包提供模板和 MCP 工具链骨架。Report 体系(gateway.md 边界监测)和 policy-update-loop 运行时自适应由宿主项目实现,不在 npm 包覆盖范围内。
143
+ | 工具 | 用途 | 触发场景 |
144
+ |------|------|---------|
145
+ | `record_dev_operation` | 记录开发操作审计(before/after/reason) | 每次文件变更、配置修改 |
146
+ | `query_audit_logs` | 按 planKeyword / targetId 查询审计记录 | 跨会话恢复上下文、验证迭代证据 |
147
+ | `get_project_context` | 获取 ADD 工作流状态快照 | 空白对话开局 |
148
+ | `get_db_schema` | 获取 Prisma schema 信息 | 数据库相关操作 |
149
+ | `check_dps` | DPS 闸门(设计/实现/文档/审计 四维各 25%) | Step 0 末尾 |
150
+ | `check_rahs` | RAHS 闸门(运行时架构健康度) | Step 4/8 |
151
+ | `check_add_route_status` | add-route 文件存在性校验 | Step 3 前 |
152
+ | `check_spec_sync` | Spec 文档勾选状态与代码一致性 | Spec 执行后 |
153
+ | `find_related_docs` | 检索相关架构/规范文档 | 语境理解 |
86
154
 
87
- > 🚧 **即将上线**:ADD 范式项目案例仓库——沉淀真实 ADD 项目案例讲解Report 体系(gateway.md 边界监测)和 policy-update-loop 运行时自适应
155
+ > 完整工具列表见 [MCP 工具链规范](https://github.com/xiaomingming92/codein2027/blob/main/docs/大田精准耕播智能决策系统/knowledge/02-规范/%E3%80%8A%E5%BC%80%E5%8F%91%E6%93%8D%E4%BD%9C%E5%AE%A1%E8%AE%A1%E5%AD%98%E6%A1%A3%E8%A7%84%E8%8C%83%E3%80%8B.md)。
156
+
157
+ ## 架构全景
158
+
159
+ ```
160
+ ┌─────────────┐
161
+ │ ADD 范式 │
162
+ │ Step 0-9 │
163
+ └──────┬──────┘
164
+ │ 门禁驱动
165
+ ┌────────────┼────────────┐
166
+ ▼ ▼ ▼
167
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
168
+ │ DPS 闸门 │ │ RAHS 闸门│ │合规检查 │
169
+ └────┬─────┘ └────┬─────┘ └────┬─────┘
170
+ │ │ │
171
+ ▼ ▼ ▼
172
+ ┌─────────────────────────────────────┐
173
+ │ 审计基础设施层 │
174
+ │ DevOperation / AuditLog 表 │
175
+ │ MCP 审计工具链 │
176
+ │ Handoff / DevLog 时序文档 │
177
+ └─────────────────────────────────────┘
178
+
179
+ ┌────────────┼────────────┐
180
+ ▼ ▼ ▼
181
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
182
+ │ Claude │ │ Qoder │ │ VS Code │
183
+ │ Hooks │ │ Hooks │ │ Config │
184
+ └──────────┘ └──────────┘ └──────────┘
185
+
186
+ ┌────────────┘
187
+
188
+ ┌─────────────────────────────────────┐
189
+ │ Caijuehub 规则引擎 │
190
+ │ TOML 驱动的策略体系 │
191
+ │ 检测/适配/Prisma/写入 全可配置 │
192
+ └─────────────────────────────────────┘
193
+ ```
88
194
 
89
195
  ## 前置条件
90
196
 
@@ -102,4 +208,4 @@ npm 包提供模板和 MCP 工具链骨架。Report 体系(gateway.md 边界
102
208
  > POSTGRES_USER: admin
103
209
  > POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
104
210
  > ```
105
- > 数据卷建议挂载到 `~/data/your_project/postgres/`,避免容器销毁丢失数据。
211
+ > 数据卷建议挂载到 `~/data/your_project/postgres/`,避免容器销毁丢失数据。
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/index.ts
4
+ import { readFileSync as readFileSync7 } from "fs";
4
5
  import { Command } from "commander";
5
6
 
6
7
  // src/caijuehub/strategies/detect.strategy.ts
@@ -83,7 +84,7 @@ var defaults = {
83
84
  };
84
85
 
85
86
  // src/cli/config-loader.ts
86
- async function loadConfig(projectRoot, configPath, options) {
87
+ async function loadConfig(projectRoot, configPath, _options) {
87
88
  let config = { ...defaults };
88
89
  const pkgPath = join2(projectRoot, "package.json");
89
90
  if (existsSync2(pkgPath)) {
@@ -114,12 +115,9 @@ ${errors}`);
114
115
  // src/caijuehub/strategies/writer.strategy.ts
115
116
  import { existsSync as existsSync3, mkdirSync, writeFileSync, chmodSync } from "fs";
116
117
  import { join as join3, dirname } from "path";
118
+
119
+ // src/lib/utils.ts
117
120
  import { createInterface } from "readline";
118
- var WRITER_CONFIG = {
119
- onExisting: "ask",
120
- jsonMerge: "deep",
121
- shellChmod: true
122
- };
123
121
  function ask(q) {
124
122
  const rl = createInterface({ input: process.stdin, output: process.stdout });
125
123
  return new Promise((r) => {
@@ -129,6 +127,13 @@ function ask(q) {
129
127
  });
130
128
  });
131
129
  }
130
+
131
+ // src/caijuehub/strategies/writer.strategy.ts
132
+ var WRITER_CONFIG = {
133
+ onExisting: "ask",
134
+ jsonMerge: "deep",
135
+ shellChmod: true
136
+ };
132
137
  async function writeFiles(projectRoot, files, options = {}) {
133
138
  const C = WRITER_CONFIG;
134
139
  let created = 0, skipped = 0, overwritten = 0;
@@ -320,10 +325,9 @@ import { resolve as resolve2, dirname as dirname6 } from "path";
320
325
  import { fileURLToPath as fileURLToPath5 } from "url";
321
326
 
322
327
  // src/caijuehub/strategies/prisma.strategy.ts
323
- import { execSync } from "child_process";
328
+ import { spawnSync } from "child_process";
324
329
  import { copyFileSync, existsSync as existsSync4, readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
325
330
  import { resolve } from "path";
326
- import { createInterface as createInterface2 } from "readline";
327
331
  var PRISMA_CONFIG = {
328
332
  onMissing: "ask",
329
333
  onExistingAddPrisma: "ask",
@@ -333,15 +337,6 @@ var PRISMA_CONFIG = {
333
337
  schemaArg: "--schema=prisma/",
334
338
  requiresUserModel: true
335
339
  };
336
- function ask2(q) {
337
- const rl = createInterface2({ input: process.stdin, output: process.stdout });
338
- return new Promise((r) => {
339
- rl.question(q, (a) => {
340
- rl.close();
341
- r(a.trim().toLowerCase());
342
- });
343
- });
344
- }
345
340
  async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
346
341
  const C = PRISMA_CONFIG;
347
342
  const prismaDir = resolve(projectRoot, "prisma");
@@ -353,10 +348,10 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
353
348
  return true;
354
349
  }
355
350
  if (C.onMissing === "ask" && !options.force && !options.yes) {
356
- const a = await ask2("\u9879\u76EE\u7F3A\u5C11 Prisma\uFF0C\u662F\u5426\u6267\u884C prisma init\uFF1F[Y/n] ");
351
+ const a = await ask("\u9879\u76EE\u7F3A\u5C11 Prisma\uFF0C\u662F\u5426\u6267\u884C prisma init\uFF1F[Y/n] ");
357
352
  if (a !== "n" && a !== "no") {
358
353
  console.log("\u6267\u884C npx prisma init ...");
359
- execSync("npx prisma init --datasource-provider postgresql", { cwd: projectRoot, stdio: "inherit" });
354
+ spawnSync("npx", ["prisma", "init", "--datasource-provider", "postgresql"], { cwd: projectRoot, stdio: "inherit", shell: false });
360
355
  const envPath = resolve(projectRoot, ".env");
361
356
  const devEnvPath = resolve(projectRoot, ".env.development");
362
357
  if (existsSync4(envPath)) {
@@ -368,7 +363,7 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
368
363
  writeFileSync2(devEnvPath, `${existing}${existing ? "\n" : ""}${dbUrl[0]}
369
364
  `, "utf-8");
370
365
  }
371
- execSync("rm -f .env", { cwd: projectRoot });
366
+ if (existsSync4(envPath)) unlinkSync(envPath);
372
367
  console.log("\u5DF2\u5C06 DATABASE_URL \u8FC1\u79FB\u5230 .env.development");
373
368
  }
374
369
  }
@@ -393,7 +388,7 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
393
388
  writeFileSync2(schemaPath, userModel + "\n" + schema, "utf-8");
394
389
  console.log("\u5DF2\u6CE8\u5165 User \u6A21\u578B\u5230 schema.prisma");
395
390
  } else {
396
- const a = await ask2("schema.prisma \u7F3A\u5C11 User \u6A21\u578B\uFF0C\u662F\u5426\u81EA\u52A8\u6CE8\u5165\uFF1F[Y/n] ");
391
+ const a = await ask("schema.prisma \u7F3A\u5C11 User \u6A21\u578B\uFF0C\u662F\u5426\u81EA\u52A8\u6CE8\u5165\uFF1F[Y/n] ");
397
392
  if (a !== "n" && a !== "no") {
398
393
  const schema = readFileSync6(schemaPath, "utf-8");
399
394
  writeFileSync2(schemaPath, userModel + "\n" + schema, "utf-8");
@@ -415,14 +410,14 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
415
410
  console.log("\u8DF3\u8FC7");
416
411
  return true;
417
412
  } else {
418
- const choice = await ask2("\u5DF2\u6709 prisma/add.prisma\uFF1A[s]\u8DF3\u8FC7 / [o]\u8986\u76D6 / [d]diff\uFF08\u9ED8\u8BA4 s\uFF09: ");
413
+ const choice = await ask("\u5DF2\u6709 prisma/add.prisma\uFF1A[s]\u8DF3\u8FC7 / [o]\u8986\u76D6 / [d]diff\uFF08\u9ED8\u8BA4 s\uFF09: ");
419
414
  if (choice === "o") {
420
415
  console.log("\u8986\u76D6");
421
416
  } else if (choice === "d") {
422
417
  copyFileSync(destPath, destPath + ".bak");
423
418
  console.log("=== \u5F53\u524D\uFF08\u5DF2\u5907\u4EFD\uFF09===\n" + readFileSync6(destPath, "utf-8"));
424
419
  console.log("=== \u6A21\u677F ===\n" + readFileSync6(addPrismaTemplate, "utf-8"));
425
- if (await ask2("\u786E\u8BA4\u8986\u76D6\uFF1F[y/N] ") !== "y") {
420
+ if (await ask("\u786E\u8BA4\u8986\u76D6\uFF1F[y/N] ") !== "y") {
426
421
  console.log("\u5DF2\u8DF3\u8FC7");
427
422
  return true;
428
423
  }
@@ -439,21 +434,26 @@ async function injectPrisma(projectRoot, addPrismaTemplate, options = {}) {
439
434
  copyFileSync(addPrismaTemplate, destPath);
440
435
  console.log("\u5DF2\u590D\u5236 add.prisma");
441
436
  try {
442
- const cmd = `npx prisma migrate dev --name ${C.migrationName} ${C.schemaArg}`;
443
- console.log(`\u6267\u884C ${cmd} ...`);
444
- execSync(cmd, { cwd: projectRoot, stdio: "inherit" });
437
+ const args = ["prisma", "migrate", "dev", "--name", C.migrationName];
438
+ if (C.schemaArg) args.push(C.schemaArg);
439
+ console.log(`\u6267\u884C npx ${args.join(" ")} ...`);
440
+ const r = spawnSync("npx", args, { cwd: projectRoot, stdio: "inherit", shell: false });
441
+ if (r.status !== 0) throw new Error(`prisma migrate dev \u9000\u51FA\u7801: ${r.status}`);
445
442
  } catch (err) {
446
443
  if (C.onMigrateFail === "keep") {
447
444
  console.log("\u8FC1\u79FB\u5931\u8D25\uFF0C\u4FDD\u7559\u6587\u4EF6");
448
445
  return true;
449
446
  }
450
- unlinkSync(destPath);
447
+ try {
448
+ unlinkSync(destPath);
449
+ } catch {
450
+ }
451
451
  console.log("\u5DF2\u56DE\u6EDA");
452
452
  throw new Error(`\u8FC1\u79FB\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
453
453
  }
454
454
  if (C.autoGenerate) {
455
455
  console.log("\u6267\u884C prisma generate ...");
456
- execSync("npx prisma generate", { cwd: projectRoot, stdio: "inherit" });
456
+ spawnSync("npx", ["prisma", "generate"], { cwd: projectRoot, stdio: "inherit", shell: false });
457
457
  }
458
458
  console.log("ADD \u6CBB\u7406\u6A21\u578B\u5DF2\u5C31\u7EEA");
459
459
  return true;
@@ -568,8 +568,11 @@ async function statusCommand() {
568
568
  }
569
569
 
570
570
  // src/cli/index.ts
571
+ var { version } = JSON.parse(
572
+ readFileSync7(new URL("../package.json", import.meta.url), "utf-8")
573
+ );
571
574
  var program = new Command();
572
- program.name("add-coder").description("\u521D\u59CB\u5316 ADD \u8303\u5F0F\u5DE5\u4F5C\u6D41\u6A21\u677F").version("0.1.0");
575
+ program.name("add-coder").description("\u521D\u59CB\u5316 ADD \u8303\u5F0F\u5DE5\u4F5C\u6D41\u6A21\u677F").version(version);
573
576
  program.command("init").description("\u521D\u59CB\u5316 ADD \u6A21\u677F\u5230\u5F53\u524D\u9879\u76EE").option("--adapter <type>", "\u76EE\u6807 IDE: claude | qoder | vscode | auto", "auto").option("--config <path>", "\u6307\u5B9A\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84").option("--yes", "\u8DF3\u8FC7\u4EA4\u4E92\uFF0C\u53EA\u521B\u5EFA\u65B0\u6587\u4EF6").option("--force", "\u8986\u76D6\u5DF2\u6709\u6587\u4EF6\uFF0C\u4E0D\u4EA4\u4E92").option("--dry-run", "\u9884\u89C8\u6A21\u5F0F\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").action(initCommand);
574
577
  program.command("sync").description("\u589E\u91CF\u540C\u6B65\u7F3A\u5931\u6587\u4EF6").action(syncCommand);
575
578
  program.command("status").description("\u68C0\u67E5 ADD \u6A21\u677F\u5B8C\u6574\u6027").action(statusCommand);
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "add-coder",
3
- "version": "0.1.4",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
- "description": "Initialize ADD paradigm workflow templates for Claude Code, Qoder, and VS Code.",
5
+ "description": "[codein2027](https://github.com/xiaomingming92/codein2027) 快速构建 ADD 编程范式的完整脚手架——AI 代码治理的落地方案。以「审计即基础设施」为核心,彻底打破编程过程黑盒与跨轮失忆,让编程范式进化为可审计、可追溯、可收敛的新时代。npx 即用,人人可体验。",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "add-coder": "bin/add-coder.js"
@@ -15,19 +15,11 @@
15
15
  "engines": {
16
16
  "node": ">=20"
17
17
  },
18
- "packageManager": "pnpm@11.9.0",
19
18
  "files": [
20
19
  "bin",
21
20
  "dist",
22
21
  "templates"
23
22
  ],
24
- "scripts": {
25
- "build": "tsup",
26
- "prepare": "tsup",
27
- "dev": "tsup --watch",
28
- "generate": "tsx src/caijuehub/transcribe.ts",
29
- "test": "node bin/add-coder.js --help"
30
- },
31
23
  "keywords": [
32
24
  "add",
33
25
  "add-paradigm",
@@ -35,11 +27,12 @@
35
27
  "qoder",
36
28
  "vscode",
37
29
  "mcp",
38
- "workflow"
30
+ "workflow",
31
+ "codein2027"
39
32
  ],
40
33
  "author": "xiaomingming",
41
34
  "email": "wujixmm@gmail.com",
42
- "license": "MIT",
35
+ "license": "AGPL-3.0-only",
43
36
  "dependencies": {
44
37
  "commander": "^13.1.0",
45
38
  "smol-toml": "^1.7.0",
@@ -58,7 +51,19 @@
58
51
  }
59
52
  },
60
53
  "devDependencies": {
54
+ "@eslint/js": "^9.39.4",
55
+ "@types/node": "^22.20.1",
56
+ "eslint": "^9.39.4",
61
57
  "tsup": "^8.4.0",
62
- "typescript": "^5.7.0"
58
+ "typescript": "^6.0.3",
59
+ "typescript-eslint": "^8.62.1"
60
+ },
61
+ "scripts": {
62
+ "build": "tsup",
63
+ "dev": "tsup --watch",
64
+ "lint": "eslint src/",
65
+ "lint:fix": "eslint src/ --fix",
66
+ "generate": "tsx src/caijuehub/transcribe.ts",
67
+ "test": "node bin/add-coder.js --help"
63
68
  }
64
- }
69
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -14,6 +14,7 @@
14
14
 
15
15
  **输入**:
16
16
  - 上游 Review:`.qoder/reviews/farm-agent-add-coder-npm-package-review-v1.md` ✅
17
+ - 上游 Review v2:`.qoder/reviews/farm-agent-add-coder-npm-package-review-v2.md` ✅ — 代码实现评审
17
18
  - Plan 文档:`.qoder/plans/2026-07/08/farm-agent-add-coder-npm-package-plan-v1.md` ✅
18
19
 
19
20
  **动作**:
@@ -107,11 +108,12 @@
107
108
  | 4 | 3 | Claude 适配器实现 | `templates/adapters/claude/`、`src/adapters/claude/renderer.ts` | `record_dev_operation` (CREATE) | — | 第2轮 Task 0 | ⬜ |
108
109
  | 5 | 3 | Qoder 适配器实现 | `templates/adapters/qoder/`、`src/adapters/qoder/renderer.ts` | `record_dev_operation` (CREATE/MODIFY) | — | 第3轮 Task 0 | ⬜ |
109
110
  | 6 | 3 | VS Code 适配器实现 | `templates/adapters/vscode/`、`src/adapters/vscode/renderer.ts` | `record_dev_operation` (CREATE/MODIFY) | — | 第3轮 Task 1 | ⬜ |
111
+ | 6b | 3 | 三目录部署(core→.add/.qoder/.claude) | `src/core/renderer.ts`、`src/cli/commands/init.ts`、adapter renderers | `record_dev_operation` (MODIFY) | — | 第3轮 Task 2 | ⬜ |
110
112
  | 7 | 4 | 配置系统(Zod schema) | `src/config/schema.ts`、`src/config/defaults.ts` | `record_dev_operation` (CREATE) | — | 无 | ⬜ |
111
113
  | 8 | 4 | CLI 重写 | `src/cli/`、`bin/add-coder.js`、`tsup.config.ts` | `record_dev_operation` (CREATE/MODIFY) | — | 第1轮 Task 0 + 第4轮 Task 0 | ⬜ |
112
114
  | 9 | 5 | 集成测试 + 文档 + devlog | 测试文件、`README.md`、`package.json` | `record_dev_operation` (CREATE/MODIFY) | — | 全部前序 Task | ⬜ |
113
- | 10 | 6 | CaijueHub 核心 | `src/caijuehub/caijue.toml`、`src/caijuehub/caijue.ts` | `record_dev_operation` (CREATE) | — | 第4轮 Task 1 | ⬜ |
114
- | 11 | 6 | 重构模块读 caijue | `src/cli/detect.ts`、`src/cli/commands/init.ts` | `record_dev_operation` (MODIFY) | — | 第6轮 Task 0 | ⬜ |
115
+ | 10 | 6 | CaijueHub 核心 | `src/caijuehub/caijue.toml`、`src/caijuehub/caijue.ts`、`src/caijuehub/transcribe.ts`、`src/caijuehub/*-rules.toml` (4) | `record_dev_operation` (CREATE) | — | 第4轮 Task 1 | ⬜ |
116
+ | 11 | 6 | 策略文件 + cli 重构 | `src/caijuehub/strategies/*.strategy.ts` (4)、`src/cli/detect.ts`、`src/cli/prisma-injector.ts`、`src/cli/writer.ts` | `record_dev_operation` (CREATE/MODIFY) | — | 第6轮 Task 0 | ⬜ |
115
117
 
116
118
  ### 依赖拓扑
117
119
 
@@ -127,6 +129,9 @@
127
129
 
128
130
  第3轮: 适配器实现
129
131
  Task 0: Claude → Task 1: Qoder → Task 2: VS Code(串行)
132
+
133
+ ▼ 增量:core 内容三目录部署
134
+ Task 3.3: renderCore() 改造 → adapter renderers 不再重复部署 core
130
135
 
131
136
 
132
137
  第4轮: 配置 + CLI
@@ -320,4 +325,7 @@
320
325
  | `packages/add-coder/templates/docs/` (grounding 文档) | CREATE | 1/1 | DOC | ⬜ |
321
326
  | `packages/add-coder/src/caijuehub/caijue.toml` | CREATE | 6/0 | CAIJUE_CONFIG | ⬜ |
322
327
  | `packages/add-coder/src/caijuehub/caijue.ts` | CREATE | 6/0 | CAIJUE_CONFIG | ⬜ |
328
+ | `packages/add-coder/src/caijuehub/transcribe.ts` | CREATE | 6/0 | CAIJUE_CONFIG | ⬜ |
329
+ | `packages/add-coder/src/caijuehub/*-rules.toml` (4) | CREATE | 6/0 | CAIJUE_CONFIG | ⬜ |
330
+ | `packages/add-coder/src/caijuehub/strategies/*.strategy.ts` (4) | CREATE | 6/1 | STRATEGY | ⬜ |
323
331
  | `packages/add-coder/README.md` | MODIFY | 5/0 | DOC | ⬜ |
@@ -610,6 +610,11 @@ npm run generate → transcribe.ts → GENERATED 区块 │ injectPrisma
610
610
  | caijue.toml | 无 | 索引注册 4 个策略 | 新增 |
611
611
  | transcribe.ts | 无 | GENERATED 区块产出引擎 | 新增 |
612
612
  | 策略文件 | 无 | GENERATED+USER CODE 双区块模式 | 新增 |
613
+ | 模板部署策略 | 仅 `.add/` | `.qoder/` `.claude/` 同时部署 core 内容 | IDE 只认自身 magic path,需三者各自完整 |
614
+ | `templates/core/prisma/` | add.prisma 模板 | 删除,由 injectPrisma 直接处理 | Prisma 文件不应在 `.add/` 下 |
615
+ | plans/specs 示例 | 无 | `templates/core/plans/` `specs/` 含 add-coder 示例 | 用户首次 init 即可看到完整 ADD 文档样例 |
616
+ | 三目录部署 | 仅 `.add/` | Plan 已设计,`renderCore()` 改造待执行 | 见 Plan §3.2 改造待执行清单 |
617
+ | Review v2 回流 | 无 | `.qoder/reviews/farm-agent-add-coder-npm-package-review-v2.md` | 代码实现评审:2 条 P0(spawnSync catch 失能、ask 重复定义)在 Plan §4.8 回流,P0-1 已补充至 Task 1.0 验收项 |
613
618
 
614
619
  ## §8 验证结果
615
620
 
@@ -630,6 +635,9 @@ npm run generate → transcribe.ts → GENERATED 区块 │ injectPrisma
630
635
  - [x] `grep -r "farm.agent\|大田\|/home/xmm" templates/` 返回空
631
636
  - [ ] `npm pack` → `npm install` 端到端(待运行时验证)
632
637
  - [x] ADD-7 `query_audit_logs` 回查确认 — 共 20 条记录,覆盖 6 轮全部关键文件
638
+ - [x] Review v2 P0-1(spawnSync catch 失能)已记录至 Plan 并补充验收项
639
+ - [ ] Review v2 P0-2(ask 重复定义)待第6轮 CaijueHub 重构时提取到 utils
640
+ - [ ] Review v2 P1-1(unlinkSync 缺口)、P1-2/3(gitignore)待 CI 基建清单补充
633
641
 
634
642
  ---
635
643