add-coder 0.2.10 → 1.0.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.
package/README.md CHANGED
@@ -8,6 +8,8 @@ Make 0.75 into one.
8
8
 
9
9
 
10
10
  > 🧭 **从零上手实操?** 请参见 [GUIDE.md](https://github.com/xiaomingming92/add-coder/blob/main/GUIDE.md) — 包含触发词速查、需求转 Plan、完整链路演练。
11
+ >
12
+ > 🔄 **add-coder 升级后更新模板?** `npx add-coder sync --adapter=qoder --patch` — 实操看 [GUIDE.md §版本升级](#) | 原理看 [DEVELOPMENT.md](https://github.com/xiaomingming92/add-coder/blob/main/DEVELOPMENT.md)
11
13
 
12
14
  ```bash
13
15
  npx add-coder init
@@ -29,7 +31,22 @@ npx add-coder init
29
31
  | 审计靠开发者自觉记录 | **MCP 审计工具链** 自动记录每次操作,系统闸门强制检查 |
30
32
  | 无关联性 | 审计事件天然关联 Plan → Spec → Task → Step → Tool Call,形成完整证据链 |
31
33
 
32
- ### ② Prompt Cache 原生友好 — 月费 ¥218,节省 98%
34
+ ### ② Caijuehub 规则引擎:业务规则直驱代码
35
+
36
+ Caijuehub 是 add-coder 历史上第一个实现 **TOML 规则声明 → 自动生成策略 → 业务代码消费** 的裁决引擎。以 sync --patch 为例:
37
+
38
+ ```toml
39
+ # sync-rules.toml — 改这里,不改代码
40
+ [patch]
41
+ on_conflict = "interactive" # 内容冲突时:交互勾选
42
+ on_missing = "write" # 文件缺失时:静默写入
43
+ [version]
44
+ on_upgrade = "baseline" # 版本升级时:自动覆盖
45
+ ```
46
+
47
+ `npm run generate` 后,策略直驱 sync.ts 行为。**人类从"追踪散落的 if"升级为"读一张决策表"**——认知负担从 O(N×M) 降为 O(1)。产品经理、市场人员改 TOML 即可把控软件能力,决策权集中、单一入口绕不过去。更进一步:当业务规则以声明式集中管理,**AI Agent 可大规模索引、检索、修改规则**——人机协作不再局限于对话生成代码,而是共同操作同一张决策表。这是 [codein2027 集中裁决层理论](https://github.com/xiaomingming92/codein2027) 的第一个工程落地。详见 [docs/caijuehub.md](./docs/caijuehub.md)。
48
+
49
+ ### ③ Prompt Cache 原生友好 — 月费 ¥218,节省 98%
33
50
 
34
51
  ADD 范式不仅是方法论——它的结构化 Step 流程天然适配 DeepSeek Prompt Cache 的前缀匹配机制,带来极致的 Token 成本效率。**实测数据验证**:
35
52
 
@@ -48,7 +65,7 @@ ADD 范式 + Qoder: cache 命中率 99.31%, 每次请求 MISS 仅 2,426 toke
48
65
 
49
66
  > 📊 [完整分析报告](./docs/ADD范式缓存命中分析报告.md) — 含 4 张 Mermaid 图表、17 天逐日数据、跨 IDE 对比与成本建模。
50
67
 
51
- ### 门禁驱动,而非自由对话
68
+ ### 门禁驱动,而非自由对话
52
69
 
53
70
  传统 AI coding 是「你说我做」,质量完全依赖 LLM 当天状态。add-coder 在架构中嵌入了 **双质量闸门**:
54
71
 
@@ -59,7 +76,7 @@ RAHS (Runtime Architecture Health Score) — 运行时架构健康度,< 90% BL
59
76
 
60
77
  这不是「建议」,是**架构阻断** — 不通过闸门的 Step 无法推进到下一步。
61
78
 
62
- ### 跨轮记忆,而非每轮失忆
79
+ ### 跨轮记忆,而非每轮失忆
63
80
 
64
81
  AI 对话的致命缺陷:上次讨论的架构决策、已修复的 Bug、达成的约定,下轮对话全部遗忘。add-coder 在架构层面解决:
65
82
 
@@ -67,7 +84,7 @@ AI 对话的致命缺陷:上次讨论的架构决策、已修复的 Bug、达
67
84
  - **Plan 索引** — 所有 Plan 通过 `index.md` 集中索引,支持模糊匹配快速定位
68
85
  - **DevLog 时序记录** — 每一步操作写入 `{YYYY-MM}/{DD}/` 时间轴,可回溯任意历史状态
69
86
 
70
- ### Policy-Update-Loop:治理自我进化(脚手架不包含此架构能力,接下来会给到DEMO仓库让大家更好理解Policy-Update-Loop和Report体系)
87
+ ### Policy-Update-Loop:治理自我进化(脚手架不包含此架构能力,接下来会给到DEMO仓库让大家更好理解Policy-Update-Loop和Report体系)
71
88
 
72
89
  不是静态模板,而是**闭环自适应系统**:
73
90
 
@@ -77,7 +94,7 @@ AI 对话的致命缺陷:上次讨论的架构决策、已修复的 Bug、达
77
94
 
78
95
  运行时产生的 Report 会反过来更新 governance rules,实现治理策略的持续进化。
79
96
 
80
- ### 多 IDE 的 Hook 即治理层
97
+ ### 多 IDE 的 Hook 即治理层
81
98
 
82
99
  hook 不是「通知推送」,而是 **ADD 范式在 IDE agent 生命周期中的 17 个确定性治理卡位**。每个 IDE(Claude Code / Qoder CN / VS Code Copilot / Trae / Codex)有各自的 hook 机制,但治理逻辑统一——架构一致,适配层不同。
83
100
 
@@ -91,6 +108,8 @@ hook 不是「通知推送」,而是 **ADD 范式在 IDE agent 生命周期中
91
108
 
92
109
  > 实施 Plan: [add-coder-hook-full-alignment-plan-v1](./.qoder/plans/2026-07/17/add-coder-hook-full-alignment-plan-v1.md) | 触发源: [GitHub Issue #6](https://github.com/xiaomingming92/add-coder/issues/6)
93
110
 
111
+
112
+
94
113
  ---
95
114
 
96
115
  ## 快速开始
@@ -286,7 +305,22 @@ Traditional AI development: Chat → Generate code → Dig through chat history
286
305
  | Auditing relies on developer discipline | The **MCP audit toolchain** automatically records every operation; system gateways enforce checks |
287
306
  | No traceability | Audit events are naturally linked: Plan → Spec → Task → Step → Tool Call, forming a complete evidence chain |
288
307
 
289
- ### ② Prompt Cache Native ¥218/mo, 98% Savings
308
+ ### ② Caijuehub Rule Engine: Business Rules Drive Code
309
+
310
+ Caijuehub is add-coder's first implementation of **TOML declaration → auto-generated strategy → business code consumption**. Using sync --patch as an example:
311
+
312
+ ```toml
313
+ # sync-rules.toml — edit here, not code
314
+ [patch]
315
+ on_conflict = "interactive" # content conflict → interactive checkbox
316
+ on_missing = "write" # file missing → silent write
317
+ [version]
318
+ on_upgrade = "baseline" # version upgrade → auto overwrite
319
+ ```
320
+
321
+ After `npm run generate`, the strategy directly drives sync.ts behavior. **Humans upgrade from "hunting scattered if-statements" to "reading a decision table"** — cognitive load drops from O(N×M) to O(1). Product managers and marketers edit TOML to control software capabilities, with decisions centralized at a single entry point that cannot be bypassed. Furthermore: when business rules are declaratively centralized, **AI Agents can index, search, and modify rules at scale** — human-AI collaboration extends beyond conversation-driven code generation to jointly operating the same decision table. This is the first engineering implementation of [codein2027's Centralized Decision Layer theory](https://github.com/xiaomingming92/codein2027). Details: [docs/caijuehub.md](./docs/caijuehub.md).
322
+
323
+ ### ③ Prompt Cache Native — ¥218/mo, 98% Savings
290
324
 
291
325
  The ADD paradigm isn't just methodology — its structured Step workflow naturally aligns with DeepSeek's Prompt Cache prefix-matching mechanism, delivering extreme token cost efficiency. **Real-world billing validation**:
292
326
 
@@ -305,7 +339,7 @@ ADD paradigm + Qoder: cache hit rate 99.31%, only 2,426 MISS tokens/req
305
339
 
306
340
  > 📊 [Full analysis report](./docs/ADD范式缓存命中分析报告.md) — 4 Mermaid diagrams, 17-day daily data, cross-IDE comparison, and cost modeling.
307
341
 
308
- ### Gateway-Driven, Not Free-Form Conversation
342
+ ### Gateway-Driven, Not Free-Form Conversation
309
343
 
310
344
  Traditional AI coding is "you say, I do" — quality depends entirely on the LLM's state that day. add-coder embeds **dual quality gateways** into the architecture:
311
345
 
@@ -316,7 +350,7 @@ RAHS (Runtime Architecture Health Score) — Runtime architecture health, < 90%
316
350
 
317
351
  These are not "suggestions" — they are **architectural blocks**. A Step cannot advance without passing its gateway.
318
352
 
319
- ### Cross-Session Memory, Not Per-Session Amnesia
353
+ ### Cross-Session Memory, Not Per-Session Amnesia
320
354
 
321
355
  The fatal flaw of AI conversations: architectural decisions from last session, bugs fixed, agreements reached — all forgotten in the next conversation. add-coder solves this at the architecture level:
322
356
 
@@ -324,7 +358,7 @@ The fatal flaw of AI conversations: architectural decisions from last session, b
324
358
  - **Plan Index** — All Plans are centrally indexed via `index.md`, supporting fuzzy-match quick lookup
325
359
  - **DevLog Timeline** — Every operation is written to the `{YYYY-MM}/{DD}/` timeline, enabling full historical state traceability
326
360
 
327
- ### Policy-Update-Loop: Self-Evolving Governance (the scaffold itself does not include this architectural capability; a DEMO repo will be provided next to better illustrate the Policy-Update-Loop and Report system)
361
+ ### Policy-Update-Loop: Self-Evolving Governance (the scaffold itself does not include this architectural capability; a DEMO repo will be provided next to better illustrate the Policy-Update-Loop and Report system)
328
362
 
329
363
  Not a static template, but a **closed-loop adaptive system**:
330
364
 
@@ -334,7 +368,7 @@ Execute → Audit → Boundary Report → Rule Adjustment → Next Execution
334
368
 
335
369
  Runtime-generated Reports feed back into governance rules, enabling continuous evolution of governance strategies.
336
370
 
337
- ### Multi-IDE Hooks as the Governance Layer
371
+ ### Multi-IDE Hooks as the Governance Layer
338
372
 
339
373
  Hooks are not "notification push" — they are the **IDE runtime interception layer**:
340
374
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/index.ts
4
- import { readFileSync as readFileSync6 } from "fs";
4
+ import { readFileSync as readFileSync7 } from "fs";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/caijuehub/strategies/detect.strategy.ts
@@ -155,7 +155,7 @@ function renderList(items, selected, startIdx, height) {
155
155
  `;
156
156
  }
157
157
  out += `
158
- \u547D\u4EE4: [a]\u5168\u9009 [n]\u53D6\u6D88\u5168\u9009 [1-${items.length}]\u5207\u6362 [\u2191\u2193]\u6EDA\u52A8 [Enter]\u786E\u8BA4 [q]\u9000\u51FA
158
+ \u547D\u4EE4: [a]\u5168\u90E8\u8DF3\u8FC7 [A]\u5168\u90E8\u8986\u76D6 [1-${items.length}]\u5207\u6362 [Enter]\u786E\u8BA4 [q]\u9000\u51FA
159
159
  `;
160
160
  return out;
161
161
  }
@@ -197,12 +197,12 @@ async function selectFiles(projectRoot, files) {
197
197
  draw();
198
198
  });
199
199
  rl.on("line", (input2) => {
200
- const trimmed = input2.trim().toLowerCase();
201
- if (trimmed === "q" || trimmed === "quit") {
200
+ const trimmed = input2.trim();
201
+ if (trimmed === "q" || trimmed.toLowerCase() === "quit") {
202
202
  rl.close();
203
- } else if (trimmed === "a") {
203
+ } else if (trimmed === "A") {
204
204
  items.forEach((_, i) => selected.add(i));
205
- } else if (trimmed === "n") {
205
+ } else if (trimmed === "a") {
206
206
  selected.clear();
207
207
  } else {
208
208
  const num = parseInt(trimmed, 10);
@@ -444,7 +444,7 @@ var PRISMA_CONFIG = {
444
444
  autoGenerate: true,
445
445
  migrationName: "add_workflow_init",
446
446
  schemaArg: "--schema=prisma/",
447
- requiresUserModel: false
447
+ requiresUserModel: true
448
448
  };
449
449
  function ensurePrismaConfig(projectRoot) {
450
450
  const configPath = resolve3(projectRoot, "prisma.config.ts");
@@ -629,6 +629,7 @@ async function injectPrisma2(projectRoot, options = {}) {
629
629
 
630
630
  // src/cli/commands/init.ts
631
631
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync3, copyFileSync as copyFileSync2, readdirSync as readdirSync2 } from "fs";
632
+ import { createHash } from "crypto";
632
633
  import { resolve as resolve5 } from "path";
633
634
  import { spawnSync as spawnSync2 } from "child_process";
634
635
  import { createConnection } from "net";
@@ -903,6 +904,23 @@ async function renderAndWrite(ctx) {
903
904
  }
904
905
  }
905
906
  }
907
+ if (!dry) {
908
+ const hashMap = {};
909
+ let npmVer = "";
910
+ try {
911
+ npmVer = JSON.parse(readFileSync5(resolve5(projectRoot, "node_modules", "add-coder", "templates", ".add-coder-src-hash.json"), "utf-8"))._version ?? "";
912
+ } catch {
913
+ }
914
+ for (const [rp, c] of allFiles) {
915
+ hashMap[rp] = createHash("sha256").update(c).digest("hex").slice(0, 8);
916
+ }
917
+ const hashOut = resolve5(projectRoot, magicDir, ".add-coder-hash.json");
918
+ writeFileSync3(hashOut, JSON.stringify(hashMap, null, 2) + "\n", "utf-8");
919
+ if (npmVer) {
920
+ writeFileSync3(resolve5(projectRoot, magicDir, ".add-coder-version"), npmVer + "\n", "utf-8");
921
+ }
922
+ console.log(`hash: ${Object.keys(hashMap).length} entries \u2192 ${magicDir}/.add-coder-hash.json`);
923
+ }
906
924
  return await writeFiles2(projectRoot, allFiles, { force: options.force, dryRun: options.dryRun });
907
925
  }
908
926
  async function deployDatabase(ctx) {
@@ -996,8 +1014,30 @@ function finalize(ctx, result) {
996
1014
  }
997
1015
 
998
1016
  // src/cli/commands/sync.ts
999
- import { existsSync as existsSync7 } from "fs";
1017
+ import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
1000
1018
  import { resolve as resolve6 } from "path";
1019
+ import { createHash as createHash2 } from "crypto";
1020
+
1021
+ // src/caijuehub/strategies/sync.strategy.ts
1022
+ var SYNC_CONFIG = {
1023
+ PATCH_GUARD: [/[/]plans[/]/, /[/]specs[/]/, /[/]reviews[/]/],
1024
+ HASH_OUTPUT_FILE: ".add-coder-hash.json",
1025
+ HASH_SRC_FILE: "templates/.add-coder-src-hash.json",
1026
+ HASH_HEX_LENGTH: 8,
1027
+ PATCH_ON_MISSING: "write",
1028
+ PATCH_ON_CONFLICT: "interactive",
1029
+ PATCH_ON_SAME: "skip",
1030
+ VERSION_ON_FIRST: "baseline",
1031
+ VERSION_ON_UPGRADE: "baseline",
1032
+ VERSION_ON_HASH_LOST: "conflict",
1033
+ VERSION_SENTINEL: ".add-coder-version",
1034
+ DEFAULT_ON_MISSING: "write",
1035
+ DEFAULT_ON_EXISTING: "skip",
1036
+ PROMPT_FULL: "\u6240\u6709 ADD \u6A21\u677F\u6587\u4EF6\u5DF2\u5C31\u4F4D\u3002\u4F7F\u7528 --patch \u66F4\u65B0\u5DF2\u6709\u6587\u4EF6\u3002",
1037
+ PROMPT_PATCH_DONE: "\u6240\u6709 ADD \u6A21\u677F\u6587\u4EF6\u5DF2\u662F\u6700\u65B0\u3002"
1038
+ };
1039
+
1040
+ // src/cli/commands/sync.ts
1001
1041
  var ADAPTER_RENDERERS2 = {
1002
1042
  claude: renderAdapter,
1003
1043
  qoder: renderAdapter2,
@@ -1020,6 +1060,34 @@ function resolveAdapter2(projectRoot, specified) {
1020
1060
  console.log("\u672A\u68C0\u6D4B\u5230 IDE \u73AF\u5883\uFF0C\u9ED8\u8BA4 qoder");
1021
1061
  return "qoder";
1022
1062
  }
1063
+ function isUserData(p) {
1064
+ return SYNC_CONFIG.PATCH_GUARD.some((r) => r.test(p));
1065
+ }
1066
+ function hash8(c) {
1067
+ return createHash2("sha256").update(c).digest("hex").slice(0, SYNC_CONFIG.HASH_HEX_LENGTH);
1068
+ }
1069
+ function loadHashFile(root, magic) {
1070
+ try {
1071
+ return JSON.parse(readFileSync6(resolve6(root, magic, SYNC_CONFIG.HASH_OUTPUT_FILE), "utf-8"));
1072
+ } catch {
1073
+ return {};
1074
+ }
1075
+ }
1076
+ function loadVersionFile(root, magic) {
1077
+ try {
1078
+ return readFileSync6(resolve6(root, magic, SYNC_CONFIG.VERSION_SENTINEL), "utf-8").trim();
1079
+ } catch {
1080
+ return "";
1081
+ }
1082
+ }
1083
+ function saveVersionFile(root, magic, version2) {
1084
+ writeFileSync4(resolve6(root, magic, SYNC_CONFIG.VERSION_SENTINEL), version2 + "\n", "utf-8");
1085
+ }
1086
+ function saveHashFile(root, magic, files) {
1087
+ const m = {};
1088
+ for (const [p, c] of files) m[p] = hash8(c);
1089
+ writeFileSync4(resolve6(root, magic, SYNC_CONFIG.HASH_OUTPUT_FILE), JSON.stringify(m, null, 2) + "\n", "utf-8");
1090
+ }
1023
1091
  async function syncCommand(options = {}) {
1024
1092
  const projectRoot = process.cwd();
1025
1093
  const target = resolveAdapter2(projectRoot, options.adapter);
@@ -1050,6 +1118,75 @@ async function syncCommand(options = {}) {
1050
1118
  for (const [p, c] of claudeFiles) allFiles.set(p, c);
1051
1119
  console.log(`claude adapter (via Agent Host): ${claudeFiles.size} \u6587\u4EF6`);
1052
1120
  }
1121
+ if (options.patch) {
1122
+ const candidates = /* @__PURE__ */ new Map();
1123
+ let skipped = 0;
1124
+ for (const [p, c] of allFiles) {
1125
+ if (isUserData(p)) {
1126
+ skipped++;
1127
+ continue;
1128
+ }
1129
+ candidates.set(p, c);
1130
+ }
1131
+ const outHash = loadHashFile(projectRoot, magicDir);
1132
+ const srcHashPath = resolve6(projectRoot, "node_modules", "add-coder", "templates", ".add-coder-src-hash.json");
1133
+ let npmVersion = "";
1134
+ try {
1135
+ npmVersion = JSON.parse(readFileSync6(srcHashPath, "utf-8"))._version ?? "";
1136
+ } catch {
1137
+ }
1138
+ const installedVersion = loadVersionFile(projectRoot, magicDir);
1139
+ const isFirstPatch = !installedVersion;
1140
+ const isUpgrade = installedVersion && npmVersion && installedVersion !== npmVersion;
1141
+ const hashLost = installedVersion && !isUpgrade && Object.keys(outHash).length === 0;
1142
+ const establishBaseline = isFirstPatch || isUpgrade;
1143
+ if (isFirstPatch) {
1144
+ console.log(`\u{1F3AF} \u9996\u6B21 patch\uFF0C\u5EFA\u7ACB\u57FA\u7EBF v${npmVersion}`);
1145
+ } else if (isUpgrade) {
1146
+ console.log(`\u{1F3AF} \u7248\u672C\u5347\u7EA7: ${installedVersion} \u2192 ${npmVersion}\uFF0C\u5EFA\u7ACB\u65B0\u57FA\u7EBF`);
1147
+ } else if (hashLost) {
1148
+ console.log(`\u26A0\uFE0F hash \u4E22\u5931\uFF08\u7248\u672C ${installedVersion} \u672A\u53D8\uFF09\uFF0C\u5168\u90E8\u8FDB\u4EA4\u4E92\u786E\u8BA4`);
1149
+ }
1150
+ const missingFiles = /* @__PURE__ */ new Map();
1151
+ const conflictFiles = /* @__PURE__ */ new Map();
1152
+ let sameCount = 0;
1153
+ for (const [relPath, content] of candidates) {
1154
+ const absPath = resolve6(projectRoot, relPath);
1155
+ if (!existsSync7(absPath)) {
1156
+ missingFiles.set(relPath, content);
1157
+ } else if (establishBaseline) {
1158
+ missingFiles.set(relPath, content);
1159
+ } else {
1160
+ const curH = hash8(readFileSync6(absPath, "utf-8"));
1161
+ const storedH = outHash[relPath];
1162
+ if (storedH && curH === storedH) {
1163
+ sameCount++;
1164
+ } else {
1165
+ conflictFiles.set(relPath, content);
1166
+ }
1167
+ }
1168
+ }
1169
+ console.log(`patch: ${allFiles.size} \u2192 skip user ${skipped} | missing ${missingFiles.size} | conflict ${conflictFiles.size} | same ${sameCount}`);
1170
+ if (missingFiles.size > 0) {
1171
+ const r = await writeFiles2(projectRoot, missingFiles, { force: true, yes: true });
1172
+ console.log(` missing: \u65B0\u5EFA ${r.created}`);
1173
+ }
1174
+ if (conflictFiles.size > 0) {
1175
+ const sel = await selectFiles(projectRoot, conflictFiles);
1176
+ if (sel.size > 0) {
1177
+ const r = await writeFiles2(projectRoot, sel, { force: true, yes: true });
1178
+ console.log(` conflict: \u8986\u76D6 ${r.overwritten}, \u8DF3\u8FC7 ${conflictFiles.size - sel.size}`);
1179
+ } else {
1180
+ console.log(` conflict: \u7528\u6237\u53D6\u6D88\uFF0C${conflictFiles.size} \u4E2A\u6587\u4EF6\u672A\u5199\u5165`);
1181
+ }
1182
+ }
1183
+ if (missingFiles.size === 0 && conflictFiles.size === 0) {
1184
+ console.log(SYNC_CONFIG.PROMPT_PATCH_DONE);
1185
+ }
1186
+ saveHashFile(projectRoot, magicDir, new Map([...missingFiles, ...conflictFiles]));
1187
+ saveVersionFile(projectRoot, magicDir, npmVersion);
1188
+ return;
1189
+ }
1053
1190
  const missing = /* @__PURE__ */ new Map();
1054
1191
  for (const [relPath, content] of allFiles) {
1055
1192
  if (!existsSync7(resolve6(projectRoot, relPath))) {
@@ -1057,7 +1194,7 @@ async function syncCommand(options = {}) {
1057
1194
  }
1058
1195
  }
1059
1196
  if (missing.size === 0) {
1060
- console.log("\u6240\u6709 ADD \u6A21\u677F\u6587\u4EF6\u5DF2\u5C31\u4F4D\u3002");
1197
+ console.log(SYNC_CONFIG.PROMPT_FULL);
1061
1198
  return;
1062
1199
  }
1063
1200
  let filesToWrite = missing;
@@ -1101,11 +1238,11 @@ async function statusCommand() {
1101
1238
 
1102
1239
  // src/cli/index.ts
1103
1240
  var { version } = JSON.parse(
1104
- readFileSync6(new URL("../package.json", import.meta.url), "utf-8")
1241
+ readFileSync7(new URL("../package.json", import.meta.url), "utf-8")
1105
1242
  );
1106
1243
  var program = new Command();
1107
1244
  program.name("add-coder").description("\u521D\u59CB\u5316 ADD \u8303\u5F0F\u5DE5\u4F5C\u6D41\u6A21\u677F").version(version);
1108
1245
  program.command("init").description("\u521D\u59CB\u5316 ADD \u6A21\u677F\u5230\u5F53\u524D\u9879\u76EE").option("--adapter <type>", "\u76EE\u6807 IDE: claude | qoder | vscode").option("--config <path>", "\u6307\u5B9A\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84").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);
1109
- program.command("sync").description("\u589E\u91CF\u540C\u6B65\u7F3A\u5931\u6587\u4EF6").option("--adapter <type>", "\u76EE\u6807 IDE: claude | qoder | vscode").option("-i, --interactive", "\u4EA4\u4E92\u5F0F\u9009\u62E9\u8981\u540C\u6B65\u7684\u6587\u4EF6").action(syncCommand);
1246
+ program.command("sync").description("\u589E\u91CF\u540C\u6B65\u7F3A\u5931\u6587\u4EF6\uFF08--patch \u8986\u76D6\u5DF2\u6709\u6A21\u677F\uFF09").option("--adapter <type>", "\u76EE\u6807 IDE: claude | qoder | vscode").option("--patch", "\u8986\u76D6\u5DF2\u6709\u6A21\u677F\u6587\u4EF6\uFF08\u4E0D\u78B0 plans/specs/reviews\uFF09").option("-i, --interactive", "\u4EA4\u4E92\u5F0F\u9009\u62E9\u8981\u540C\u6B65\u7684\u6587\u4EF6").action(syncCommand);
1110
1247
  program.command("status").description("\u68C0\u67E5 ADD \u6A21\u677F\u5B8C\u6574\u6027").action(statusCommand);
1111
1248
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-coder",
3
- "version": "0.2.10",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "description": "[codein2027](https://github.com/xiaomingming92/codein2027) - A complete scaffolding for building the ADD programming paradigm, the implementation layer for AI code governance. Core principle: Audit as Infrastructure. Breaks the black-box programming process and cross-session amnesia, evolving programming paradigms into an auditable, traceable, and convergent new era. npx-ready.\n\n[codein2027](https://github.com/xiaomingming92/codein2027) 快速构建 ADD 编程范式的完整脚手架——AI 代码治理的落地方案。以「审计即基础设施」为核心,彻底打破编程过程黑盒与跨轮失忆,让编程范式进化为可审计、可追溯、可收敛的新时代。npx 即用,人人可体验。",
6
6
  "repository": {
@@ -32,7 +32,9 @@
32
32
  "vscode",
33
33
  "mcp",
34
34
  "workflow",
35
- "codein2027"
35
+ "codein2027",
36
+ "裁决层",
37
+ "caijuehub"
36
38
  ],
37
39
  "author": "xiaomingming",
38
40
  "email": "wujixmm@gmail.com",
@@ -89,6 +91,8 @@
89
91
  "lint": "eslint src/",
90
92
  "lint:fix": "eslint src/ --fix",
91
93
  "generate": "tsx src/caijuehub/transcribe.ts",
94
+ "podman-add-coder-up": "podman-compose --env-file .env.development -f podman-compose.add.yml up -d",
95
+ "podman-add-coder-down": "podman-compose --env-file .env.development -f podman-compose.add.yml down",
92
96
  "test": "vitest run"
93
97
  }
94
98
  }
@@ -0,0 +1,256 @@
1
+ {
2
+ "_version": "1.0.0",
3
+ "adapters/claude/hooks/doc-format-guard.sh": "ec59ad3f",
4
+ "adapters/claude/hooks/lib/common.sh": "db321ef6",
5
+ "adapters/claude/hooks/lib/context-inject.sh": "4132f203",
6
+ "adapters/claude/hooks/lib/notify.sh": "e0033e53",
7
+ "adapters/claude/hooks/lib/preload-templates.sh": "96dd67fe",
8
+ "adapters/claude/hooks/lib/session-end.sh": "29813cbc",
9
+ "adapters/claude/hooks/lib/state-detect.sh": "b87dd85a",
10
+ "adapters/claude/hooks/lib/subagent-stop.sh": "4cc1d446",
11
+ "adapters/claude/hooks/lib/vocabulary.sh": "d5a92ac3",
12
+ "adapters/claude/hooks/notification.sh": "60bf9b01",
13
+ "adapters/claude/hooks/permission-denied.sh": "0a0605df",
14
+ "adapters/claude/hooks/permission-gate.sh": "bcca7732",
15
+ "adapters/claude/hooks/post-tool-failure.sh": "669b1b65",
16
+ "adapters/claude/hooks/post-tool-use.sh": "f54dd009",
17
+ "adapters/claude/hooks/pre-compact.sh": "4248f84f",
18
+ "adapters/claude/hooks/pre-tool-use.sh": "34e7e4de",
19
+ "adapters/claude/hooks/prompt-submit.sh": "680b41f4",
20
+ "adapters/claude/hooks/review-checklist.sh": "b383a983",
21
+ "adapters/claude/hooks/session-end.sh": "777ae808",
22
+ "adapters/claude/hooks/session-start.sh": "fd1d5e4f",
23
+ "adapters/claude/hooks/stop-check.sh": "41bc519a",
24
+ "adapters/claude/hooks/stop-failure.sh": "e3d6c335",
25
+ "adapters/claude/hooks/subagent-guard.sh": "5922efba",
26
+ "adapters/claude/hooks/subagent-stop.sh": "0f89e28c",
27
+ "adapters/claude/mcp.json": "e8c54cbd",
28
+ "adapters/claude/settings.json": "067ccc45",
29
+ "adapters/codex/hooks/doc-format-guard.sh": "94ebd860",
30
+ "adapters/codex/hooks/lib/common.sh": "db321ef6",
31
+ "adapters/codex/hooks/lib/context-inject.sh": "4132f203",
32
+ "adapters/codex/hooks/lib/notify.sh": "e0033e53",
33
+ "adapters/codex/hooks/lib/preload-templates.sh": "96dd67fe",
34
+ "adapters/codex/hooks/lib/session-end.sh": "29813cbc",
35
+ "adapters/codex/hooks/lib/state-detect.sh": "64c23045",
36
+ "adapters/codex/hooks/lib/subagent-stop.sh": "4cc1d446",
37
+ "adapters/codex/hooks/lib/vocabulary.sh": "d5a92ac3",
38
+ "adapters/codex/hooks/notification.sh": "f7aed25d",
39
+ "adapters/codex/hooks/permission-gate.sh": "bcca7732",
40
+ "adapters/codex/hooks/post-tool-failure.sh": "669b1b65",
41
+ "adapters/codex/hooks/post-tool-use.sh": "f54dd009",
42
+ "adapters/codex/hooks/pre-compact.sh": "6164c007",
43
+ "adapters/codex/hooks/pre-tool-use.sh": "a7072670",
44
+ "adapters/codex/hooks/prompt-submit.sh": "bea6f381",
45
+ "adapters/codex/hooks/review-checklist.sh": "b383a983",
46
+ "adapters/codex/hooks/session-end.sh": "3cc8c346",
47
+ "adapters/codex/hooks/session-start.sh": "8a5a2c62",
48
+ "adapters/codex/hooks/stop-check.sh": "dc4829be",
49
+ "adapters/codex/hooks/subagent-guard.sh": "47d04662",
50
+ "adapters/codex/hooks/subagent-stop.sh": "0a34648b",
51
+ "adapters/codex/hooks.json": "d9c99f6b",
52
+ "adapters/codex/settings.json": "44136fa3",
53
+ "adapters/qoder/hooks/doc-format-guard.sh": "bd4ffffb",
54
+ "adapters/qoder/hooks/lib/common.sh": "db321ef6",
55
+ "adapters/qoder/hooks/lib/context-inject.sh": "4132f203",
56
+ "adapters/qoder/hooks/lib/notify.sh": "e0033e53",
57
+ "adapters/qoder/hooks/lib/preload-templates.sh": "96dd67fe",
58
+ "adapters/qoder/hooks/lib/session-end.sh": "29813cbc",
59
+ "adapters/qoder/hooks/lib/state-detect.sh": "b87dd85a",
60
+ "adapters/qoder/hooks/lib/subagent-stop.sh": "4cc1d446",
61
+ "adapters/qoder/hooks/lib/vocabulary.sh": "d5a92ac3",
62
+ "adapters/qoder/hooks/notification.sh": "7d4efea6",
63
+ "adapters/qoder/hooks/permission-gate.sh": "3bf27b1a",
64
+ "adapters/qoder/hooks/post-tool-failure.sh": "8bc7a0e4",
65
+ "adapters/qoder/hooks/post-tool-use.sh": "47dd691c",
66
+ "adapters/qoder/hooks/pre-compact.sh": "092fa6cf",
67
+ "adapters/qoder/hooks/pre-tool-use.sh": "51d31986",
68
+ "adapters/qoder/hooks/prompt-submit.sh": "ac37b64c",
69
+ "adapters/qoder/hooks/review-checklist.sh": "666831c8",
70
+ "adapters/qoder/hooks/session-end.sh": "c50339df",
71
+ "adapters/qoder/hooks/session-start.sh": "7cf070d6",
72
+ "adapters/qoder/hooks/stop-check.sh": "974db988",
73
+ "adapters/qoder/hooks/subagent-guard.sh": "ce60eaac",
74
+ "adapters/qoder/hooks/subagent-stop.sh": "5a2c78c6",
75
+ "adapters/qoder/mcp.json": "209444d5",
76
+ "adapters/qoder/settings.json": "4bae3c9a",
77
+ "adapters/qoder/sync-policy.json": "a4bcbbaf",
78
+ "adapters/trae/hooks/doc-format-guard.sh": "a563db0f",
79
+ "adapters/trae/hooks/lib/common.sh": "db321ef6",
80
+ "adapters/trae/hooks/lib/context-inject.sh": "4132f203",
81
+ "adapters/trae/hooks/lib/notify.sh": "e0033e53",
82
+ "adapters/trae/hooks/lib/preload-templates.sh": "96dd67fe",
83
+ "adapters/trae/hooks/lib/session-end.sh": "29813cbc",
84
+ "adapters/trae/hooks/lib/state-detect.sh": "64c23045",
85
+ "adapters/trae/hooks/lib/subagent-stop.sh": "4cc1d446",
86
+ "adapters/trae/hooks/lib/vocabulary.sh": "d5a92ac3",
87
+ "adapters/trae/hooks/notification.sh": "f7aed25d",
88
+ "adapters/trae/hooks/permission-gate.sh": "bcca7732",
89
+ "adapters/trae/hooks/post-tool-failure.sh": "669b1b65",
90
+ "adapters/trae/hooks/post-tool-use.sh": "f54dd009",
91
+ "adapters/trae/hooks/pre-compact.sh": "6164c007",
92
+ "adapters/trae/hooks/pre-tool-use.sh": "a7072670",
93
+ "adapters/trae/hooks/prompt-submit.sh": "bea6f381",
94
+ "adapters/trae/hooks/review-checklist.sh": "b383a983",
95
+ "adapters/trae/hooks/session-end.sh": "3cc8c346",
96
+ "adapters/trae/hooks/session-start.sh": "8a5a2c62",
97
+ "adapters/trae/hooks/stop-check.sh": "dc4829be",
98
+ "adapters/trae/hooks/subagent-guard.sh": "47d04662",
99
+ "adapters/trae/hooks/subagent-stop.sh": "0a34648b",
100
+ "adapters/trae/hooks.json": "e5045c2c",
101
+ "adapters/trae/settings.json": "ca3d163b",
102
+ "adapters/vscode/.github/hooks/error-occurred.json": "9caa13dc",
103
+ "adapters/vscode/.github/hooks/post-tool-use.json": "bff9d4d8",
104
+ "adapters/vscode/.github/hooks/pre-compact.json": "fade404e",
105
+ "adapters/vscode/.github/hooks/pre-tool-use.json": "19c59396",
106
+ "adapters/vscode/.github/hooks/session-end.json": "3089c017",
107
+ "adapters/vscode/.github/hooks/session-start.json": "fa0b3d63",
108
+ "adapters/vscode/.github/hooks/stop-check.json": "e5a16e33",
109
+ "adapters/vscode/.github/hooks/subagent-start.json": "169857ad",
110
+ "adapters/vscode/.github/hooks/subagent-stop.json": "47dbdd8d",
111
+ "adapters/vscode/.github/hooks/user-prompt-submit.json": "3a608d62",
112
+ "adapters/vscode/extensions.json": "0f4024c1",
113
+ "adapters/vscode/hooks/doc-format-guard.sh": "0db27261",
114
+ "adapters/vscode/hooks/lib/common.sh": "db321ef6",
115
+ "adapters/vscode/hooks/lib/context-inject.sh": "4132f203",
116
+ "adapters/vscode/hooks/lib/notify.sh": "e0033e53",
117
+ "adapters/vscode/hooks/lib/preload-templates.sh": "96dd67fe",
118
+ "adapters/vscode/hooks/lib/session-end.sh": "29813cbc",
119
+ "adapters/vscode/hooks/lib/state-detect.sh": "b87dd85a",
120
+ "adapters/vscode/hooks/lib/subagent-stop.sh": "4cc1d446",
121
+ "adapters/vscode/hooks/lib/vocabulary.sh": "d5a92ac3",
122
+ "adapters/vscode/hooks/notification.sh": "f7aed25d",
123
+ "adapters/vscode/hooks/permission-gate.sh": "bcca7732",
124
+ "adapters/vscode/hooks/post-tool-failure.sh": "355cfab1",
125
+ "adapters/vscode/hooks/post-tool-use.sh": "5f188718",
126
+ "adapters/vscode/hooks/pre-compact.sh": "a0908f0e",
127
+ "adapters/vscode/hooks/pre-tool-use.sh": "0da68eed",
128
+ "adapters/vscode/hooks/prompt-submit.sh": "4529a394",
129
+ "adapters/vscode/hooks/review-checklist.sh": "b383a983",
130
+ "adapters/vscode/hooks/session-end.sh": "7b407b9f",
131
+ "adapters/vscode/hooks/session-start.sh": "ad724a3e",
132
+ "adapters/vscode/hooks/stop-check.sh": "df1ad9dd",
133
+ "adapters/vscode/hooks/subagent-guard.sh": "5d0ea685",
134
+ "adapters/vscode/hooks/subagent-stop.sh": "dd19f712",
135
+ "adapters/vscode/launch.json": "f2b79855",
136
+ "adapters/vscode/settings.json": "f2a30bf7",
137
+ "adapters/vscode/tasks.json": "654d7fbd",
138
+ "core/agents/add-flow-guardian.md": "697d422f",
139
+ "core/agents/add-orchestrator.md": "0d555e99",
140
+ "core/docs/ADD-governance-claude-code.md": "0f582a7e",
141
+ "core/docs/ADD-governance-codex.md": "289e8b71",
142
+ "core/docs/ADD-governance-qoder-cn.md": "332a7253",
143
+ "core/docs/ADD-governance-trae.md": "ffb29a0e",
144
+ "core/docs/ADD-governance-vscode-copilot.md": "74062e88",
145
+ "core/hooks/doc-format-guard.sh": "6f14934b",
146
+ "core/hooks/lib/common.sh": "db321ef6",
147
+ "core/hooks/lib/context-inject.sh": "4132f203",
148
+ "core/hooks/lib/notify.sh": "e0033e53",
149
+ "core/hooks/lib/preload-templates.sh": "96dd67fe",
150
+ "core/hooks/lib/session-end.sh": "29813cbc",
151
+ "core/hooks/lib/state-detect.sh": "135bde23",
152
+ "core/hooks/lib/subagent-stop.sh": "4cc1d446",
153
+ "core/hooks/lib/vocabulary.sh": "d5a92ac3",
154
+ "core/hooks/notification.sh": "f7aed25d",
155
+ "core/hooks/permission-gate.sh": "bcca7732",
156
+ "core/hooks/post-tool-failure.sh": "669b1b65",
157
+ "core/hooks/post-tool-use.sh": "f54dd009",
158
+ "core/hooks/pre-compact.sh": "6164c007",
159
+ "core/hooks/pre-tool-use.sh": "a7072670",
160
+ "core/hooks/prompt-submit.sh": "bea6f381",
161
+ "core/hooks/review-checklist.sh": "b383a983",
162
+ "core/hooks/session-end.sh": "3cc8c346",
163
+ "core/hooks/session-start.sh": "8a5a2c62",
164
+ "core/hooks/stop-check.sh": "dc4829be",
165
+ "core/hooks/subagent-guard.sh": "47d04662",
166
+ "core/hooks/subagent-stop.sh": "0a34648b",
167
+ "core/plans/2026-07/08/add-coder-npm-package-add-route-v1.md": "b05fce99",
168
+ "core/plans/2026-07/08/add-coder-npm-package-handoff-v1.md": "1bd40a4a",
169
+ "core/plans/2026-07/08/add-coder-npm-package-plan-v1.md": "323cbc7c",
170
+ "core/prisma/add.prisma": "83700ec2",
171
+ "core/reports/REPORT-WORKFLOW.md": "03d39b21",
172
+ "core/reports/boundary-runtime-report.md": "6fd8053f",
173
+ "core/reports/code-review-combined-report.md": "195d52aa",
174
+ "core/reports/code-review-fix-verification-report.md": "478e38e2",
175
+ "core/reports/code-review-suggestions.md": "1b8f6a16",
176
+ "core/reports/index.md": "6348c374",
177
+ "core/reports/runtime-report/gateway.md": "a5751665",
178
+ "core/reviews/.gitkeep": "e3b0c442",
179
+ "core/rules/project_rules.md": "5bf3dc94",
180
+ "core/rules/theory-practice-map.toml": "876192f5",
181
+ "core/scripts/db-ensure.sh": "fb81c10a",
182
+ "core/scripts/gen-plan-index.sh": "bfc6ad3e",
183
+ "core/scripts/mcp-server/elicitation/confirm.ts": "924857b8",
184
+ "core/scripts/mcp-server/elicitation/index.ts": "44c5dc3f",
185
+ "core/scripts/mcp-server/index.ts": "3483ec45",
186
+ "core/scripts/mcp-server/notifications/hitl.ts": "96eb7c5d",
187
+ "core/scripts/mcp-server/notifications/hook.ts": "a6cb861f",
188
+ "core/scripts/mcp-server/notifications/index.ts": "b6615afa",
189
+ "core/scripts/mcp-server/resources/add-coder-version.ts": "299fa071",
190
+ "core/scripts/mcp-server/resources/add-state.ts": "1c1cc3a2",
191
+ "core/scripts/mcp-server/resources/hook-events-report.ts": "1d4b5996",
192
+ "core/scripts/mcp-server/resources/index.ts": "50e19629",
193
+ "core/scripts/mcp-server/resources/round-task.ts": "104a0d74",
194
+ "core/scripts/mcp-server/sampling/index.ts": "7ee26d92",
195
+ "core/scripts/mcp-server/sampling/review.ts": "5db7a8df",
196
+ "core/scripts/mcp-server/shared/env.ts": "4b295e42",
197
+ "core/scripts/mcp-server/shared/fs.ts": "97257db9",
198
+ "core/scripts/mcp-server/shared/prisma.ts": "5133f329",
199
+ "core/scripts/mcp-server/shared/response.ts": "f7806b67",
200
+ "core/scripts/mcp-server/tasks/index.ts": "c040eb75",
201
+ "core/scripts/mcp-server/tasks/runner.ts": "d84bd35d",
202
+ "core/scripts/mcp-server/tasks/store.ts": "2fce1a92",
203
+ "core/scripts/mcp-server/tools/audit.ts": "47ea912f",
204
+ "core/scripts/mcp-server/tools/context.ts": "463df4f4",
205
+ "core/scripts/mcp-server/tools/docs.ts": "a3937aec",
206
+ "core/scripts/mcp-server/tools/gateway.ts": "388ff183",
207
+ "core/scripts/mcp-server/tools/hook-event-report.ts": "3926005b",
208
+ "core/scripts/mcp-server/tools/index.ts": "d5b3bc68",
209
+ "core/scripts/mcp-server/tools/quality.ts": "26ddf75d",
210
+ "core/scripts/mcp-server/types.ts": "6c5e60bc",
211
+ "core/scripts/mcp-server.ts": "99cc6833",
212
+ "core/skills/add-paradigm/SKILL.md": "082b1fb2",
213
+ "core/skills/session-init/SKILL.md": "0fbdc5cd",
214
+ "core/specs/add-coder-npm-package/checklist.md": "ed92032c",
215
+ "core/specs/add-coder-npm-package/spec.md": "c7d0f235",
216
+ "core/specs/add-coder-npm-package/tasks.md": "c34301e5",
217
+ "core/templates/01-架构/《ADD开发工作路径与文档协同规范》.md": "811716d8",
218
+ "core/templates/TERMINOLOGY.md": "e9f4f781",
219
+ "core/templates/add-route-template-heavyweight.md": "8b1eb7c2",
220
+ "core/templates/add-route-template.md": "670f9ebe",
221
+ "core/templates/add-route-template.schema.json": "c29a8f65",
222
+ "core/templates/checklist-template.md": "f904e049",
223
+ "core/templates/checklist-template.schema.json": "fb3a73e8",
224
+ "core/templates/fix-verification-template.md": "9c9ed175",
225
+ "core/templates/fix-verification-template.schema.json": "a18bc6a5",
226
+ "core/templates/handoff-multi-round-template.md": "d3a2375d",
227
+ "core/templates/handoff-multi-round.schema.json": "abed4220",
228
+ "core/templates/handoff-single-round-template.md": "dceb7c86",
229
+ "core/templates/handoff-single-round.schema.json": "0627cda2",
230
+ "core/templates/index.md": "7ffab71a",
231
+ "core/templates/prd-incremental-template.md": "bf8a4a1a",
232
+ "core/templates/prd-incremental-template.schema.json": "7d0d6a39",
233
+ "core/templates/prd-standard-template.md": "f9c53727",
234
+ "core/templates/prd-standard-template.schema.json": "79e7fae0",
235
+ "core/templates/report-template.md": "bc4602ac",
236
+ "core/templates/report-template.schema.json": "44dd2bd0",
237
+ "core/templates/review-implementation-template.md": "a8f8c748",
238
+ "core/templates/review-implementation-template.schema.json": "d97b9eb6",
239
+ "core/templates/review-runtime-template.md": "c5960af1",
240
+ "core/templates/review-runtime-template.schema.json": "c346ea7d",
241
+ "core/templates/review-template.md": "d5fd3323",
242
+ "core/templates/review-template.schema.json": "abc2ece6",
243
+ "core/templates/runtime-report-template.md": "7b35208a",
244
+ "core/templates/runtime-report-template.schema.json": "6c1143e6",
245
+ "core/templates/simple-plan-template.md": "0bb1ebbe",
246
+ "core/templates/simple-plan-template.schema.json": "99d53cc1",
247
+ "core/templates/spec-template.md": "3fe8f818",
248
+ "core/templates/spec-template.schema.json": "b13b3de8",
249
+ "core/templates/standard-plan-template.md": "44d30a4e",
250
+ "core/templates/standard-plan-template.schema.json": "2b767928",
251
+ "core/templates/tasks-template.md": "3a0f318d",
252
+ "core/templates/tasks-template.schema.json": "c046de41",
253
+ "core/tools/README.md": "26a63460",
254
+ "core/vocabulary/add-governance-vocabulary.md": "e2227fae",
255
+ "shared/hooks-lib/common.sh": "441eee52"
256
+ }