@andyqiu/codeforge 0.3.13 → 0.4.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.
@@ -0,0 +1,67 @@
1
+ # Review Profile: plan_only(方案文档审阅)
2
+
3
+ <!-- ADR:reviewer-multi-profile -->
4
+
5
+ > 适用:`review_target=plan_only`,审 planner 输出的方案 markdown(`plans/*.md`)。
6
+ > 本 profile **替代**通用 code.md 清单(方案审阅与代码审阅维度不同)。
7
+
8
+ ## 适用场景
9
+
10
+ - codeforge 派 planner 出方案后,自动派 reviewer 审方案(ADR:full-chain-auto-review-gating)
11
+ - 用户手动 `/review plan_only`
12
+ - workflow `feature-dev.yaml` 第 2 步「审方案」
13
+
14
+ **不审什么**:不审代码 diff,只审 `plans/*.md`。pending 列表里若混杂代码 diff,**仅审 plan 文件**并在 Review Summary 标注「跳过 N 个非方案文件」。
15
+
16
+ ## 审阅维度(7 维度,按优先级,逐项过)
17
+
18
+ | # | 维度 | 权重 | 检查清单 | 反例(必拒) |
19
+ |---|---|---|---|---|
20
+ | 1 | 需求覆盖完整性 | P0 | 每个 PRD/需求点是否有对应实现步骤?有无遗漏的 edge case(边界值 / 异常路径 / 失败回滚)?走 spec 路径时每个 `AC-x` / `PRE-x` 是否在 ADR-Draft Decision 段被引用? | 需求说「失败要 retry 3 次」方案没提;spec `AC-2` 在 Decision 段没出现 |
21
+ | 2 | 架构合理性 | P0 | 模块边界是否清晰(职责单一)?依赖方向是否合理(无下层依赖上层)?有无引入循环依赖?跨模块的接口契约是否明确? | 方案让 `lib/` 反向 import `agents/`;新模块同时职责「写存储+发 webhook+解析配置」 |
22
+ | 3 | ADR 覆盖 | P0 | 是否为**关键决策点**创建/引用了 ADR(新增 plugin / workflow / command / tool / agent)?现有 ADR 是否有冲突(如 ADR-A 说禁止 X,方案又用了 X)?ADR-Draft 三段(Context / Options / Decision)是否齐全? | 新建 plugin 没 ADR;方案与 ADR:apply-hard-gate 冲突未说明 |
23
+ | 4 | Phase 拆分合理性 | P1 | Phase 之间有无强依赖未声明(B Phase 依赖 A 但未注明)?单 Phase 是否过大(涉及 > 50 行改动建议再拆)?Phase 顺序是否反映依赖关系? | 一个 Phase 改 200 行;Phase 2 实际依赖 Phase 3 结果 |
24
+ | 5 | 接口稳定性 | P1 | 对外接口是否有破坏性变更(公开 API / CLI flag / 配置 schema)?是否需要迁移策略(旧调用方如何过渡)?是否需要 deprecation warning? | 改 cli flag 名字没迁移路径;改 KH schema 没数据迁移脚本 |
25
+ | 6 | 风险评估完整性 | P1 | 方案是否列了 ≥ 2 条风险?技术风险 / 时间风险 / 依赖风险各一句话标注?每条风险是否有 mitigation? | 风险表只写「无明显风险」;列了风险没 mitigation |
26
+ | 7 | 可回滚性 | P1 | 改动失败时能否快速回滚?有无 schema 变更 / 数据迁移这种不可逆操作?是否需要 feature flag? | 改 KH schema 没 rollback 脚本;删旧字段没保留窗口期 |
27
+
28
+ ## 强制章节检查(机审清单 — 等价章节可接受)
29
+
30
+ 按 `docs/agent-templates/planner.md` 模板核对,**允许等价章节命名**:
31
+
32
+ - [ ] **需求理解**(标题包含「需求」/「理解」/「目标」之一即可,≤ 5 行)
33
+ - [ ] **项目上下文**(标题含「上下文」/「背景」/「现状」之一)
34
+ - [ ] **需求溯源**(仅走 spec 路径强制;标题含「溯源」/「needs」/「acceptance」/「AC」之一)
35
+ - [ ] **实现方案**(标题含「方案」/「实现」/「设计」之一;必须包含 ≥ 3 个子节,分别覆盖:涉及文件、步骤、测试)
36
+ - [ ] **风险与缓解**(标题含「风险」;表格 ≥ 2 行;列名含「缓解」/「mitigation」/「应对」之一)
37
+ - [ ] **ADR-Draft**(标题字面量 `ADR-Draft`,**这一项不放宽**——Context / Options Considered / Decision 三段齐全)
38
+
39
+ **判定原则**:
40
+ - 章节**内容覆盖**才是关键,**不死磕标题字面量**
41
+ - 仅 `ADR-Draft` 标题保持字面量约束(让 `adr-check` 工具能机械 grep)
42
+ - 任一**内容覆盖**缺失 → REQUEST_CHANGES,反馈格式:「方案缺 X 内容(等价章节也接受,但当前章节内未覆盖)」
43
+
44
+ ## 输出格式调整
45
+
46
+ `## File-by-File` 改为「方案章节-by-章节」:
47
+
48
+ ```
49
+ ## 章节-by-章节
50
+
51
+ ### `## 需求理解`
52
+ - ✓ 复述准确
53
+
54
+ ### `## 实现方案 > ### 步骤`
55
+ - ⚠ Step 3 未声明依赖 Step 2 的输出
56
+ - ✗ Step 5 改了 lib/x.ts 但 `### 涉及文件` 未列出
57
+
58
+ ### `## ADR-Draft`
59
+ - ✗ Decision 段没有引用 `AC-2`(走 spec 路径必须引用)
60
+ ```
61
+
62
+ REQUEST_CHANGES 时必须给「方案哪段」具体修改意见(不是「整体觉得不够」笼统话)。
63
+
64
+ ## 失败回退
65
+
66
+ - pending 不含 `plans/*.md` → 报「未找到方案文件」,不要硬出审阅
67
+ - 方案 < 20 行(trivial 改动)→ 给 APPROVE 但备注「方案过短,可考虑省略本次 review」
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scripts/postinstall.mjs — npm postinstall 自动全局安装入口
4
+ *
5
+ * 设计意图(ADR: npm-postinstall-auto-global):
6
+ * - npm install -g @andyqiu/codeforge 完成后自动等效 `codeforge install --global`
7
+ * - 本地 install / devDep install / pnpm·yarn·bun 全局安装 → fail-closed 不触发
8
+ * - 任何失败均 exit 0,绝不阻断包管理器主流程
9
+ *
10
+ * 包管理器矩阵(详见 ADR Decision 段):
11
+ * npm -g ✅ 唯一保证注入 npm_config_global=true 的包管理器 → 触发安装
12
+ * pnpm ❌ v11+ 官方声明不传递 npm_config_*;fail-closed + stderr 提示
13
+ * yarn ❌ classic/berry 均不传递 npm_config_*;fail-closed + stderr 提示
14
+ * bun ❌ 行为未文档化;fail-closed + stderr 提示
15
+ * unknown ❌ 无 user_agent 信号;静默 exit 0
16
+ *
17
+ * 短路条件(任一命中即静默 exit 0):
18
+ * - CODEFORGE_SKIP_POSTINSTALL=1 用户/CI 显式禁用
19
+ * - CI=true 且未设 CODEFORGE_POSTINSTALL_IN_CI=1 避免污染 CI ~/.config
20
+ * - 未支持的 process.platform(仅 linux/darwin/win32 通过)
21
+ */
22
+
23
+ import { spawnSync } from "node:child_process"
24
+ import * as path from "node:path"
25
+ import * as url from "node:url"
26
+
27
+ const __filename = url.fileURLToPath(import.meta.url)
28
+ const __dirname = path.dirname(__filename)
29
+ const REPO_ROOT = path.resolve(__dirname, "..")
30
+
31
+ // ────────────────────────────────────────────────────────────────────
32
+ // 工具函数
33
+ // ────────────────────────────────────────────────────────────────────
34
+
35
+ /**
36
+ * 解析 npm_config_user_agent,识别包管理器。
37
+ * 所有主流包管理器都设此变量,格式形如:
38
+ * "npm/10.0.0 node/v20.0.0 linux x64 workspaces/false"
39
+ * "pnpm/9.0.0 npm/? node/v20.0.0 linux x64"
40
+ * "yarn/1.22.0 npm/? node/v18.0.0 linux x64"
41
+ * "bun/1.0.0 npm/? node/v20.0.0 linux x64"
42
+ */
43
+ function detectPackageManager() {
44
+ const ua = process.env.npm_config_user_agent || ""
45
+ if (ua.startsWith("npm/")) return "npm"
46
+ if (ua.startsWith("pnpm/")) return "pnpm"
47
+ if (ua.startsWith("yarn/")) return "yarn"
48
+ if (ua.startsWith("bun/")) return "bun"
49
+ return "unknown"
50
+ }
51
+
52
+ function warn(msg) {
53
+ // 写 stderr 避免污染期望干净 stdout 的脚本
54
+ process.stderr.write(`[codeforge postinstall] ${msg}\n`)
55
+ }
56
+
57
+ function exitOk(reason) {
58
+ // 调试/测试可读:CODEFORGE_POSTINSTALL_DEBUG=1 时打印短路原因到 stderr
59
+ if (process.env.CODEFORGE_POSTINSTALL_DEBUG === "1") {
60
+ process.stderr.write(`[codeforge postinstall] skip: ${reason}\n`)
61
+ }
62
+ process.exit(0)
63
+ }
64
+
65
+ // ────────────────────────────────────────────────────────────────────
66
+ // 主流程(全局 try/catch 兜底,任何异常 → exit 0)
67
+ // ────────────────────────────────────────────────────────────────────
68
+
69
+ try {
70
+ // ── 短路 S1: 用户/CI 显式禁用 ──
71
+ if (process.env.CODEFORGE_SKIP_POSTINSTALL === "1") {
72
+ exitOk("CODEFORGE_SKIP_POSTINSTALL=1")
73
+ }
74
+
75
+ // ── 短路 S2: CI 环境默认跳过 ──
76
+ if (process.env.CI === "true" && process.env.CODEFORGE_POSTINSTALL_IN_CI !== "1") {
77
+ exitOk("CI=true (set CODEFORGE_POSTINSTALL_IN_CI=1 to opt in)")
78
+ }
79
+
80
+ // ── 短路 S3: 未支持平台 ──
81
+ const supportedPlatforms = ["linux", "darwin", "win32"]
82
+ if (!supportedPlatforms.includes(process.platform)) {
83
+ exitOk(`unsupported platform: ${process.platform}`)
84
+ }
85
+
86
+ // ── 主决策 ──
87
+ const pm = detectPackageManager()
88
+ const isGlobal = process.env.npm_config_global === "true"
89
+
90
+ // D1: npm + global → 触发安装
91
+ if (pm === "npm" && isGlobal) {
92
+ const cli = path.join(REPO_ROOT, "bin", "codeforge.mjs")
93
+ const args = [cli, "install", "--global", "--skip-build"]
94
+ const env = { ...process.env, CODEFORGE_FROM_POSTINSTALL: "1" }
95
+ const r = spawnSync(process.execPath, args, {
96
+ stdio: "inherit",
97
+ env,
98
+ })
99
+ if (r.status !== 0) {
100
+ warn(
101
+ `自动全局安装失败(exit code ${r.status ?? "unknown"})。` +
102
+ `请手动执行:codeforge install --global`,
103
+ )
104
+ }
105
+ // 无论成功失败,都 exit 0,不阻断 npm
106
+ process.exit(0)
107
+ }
108
+
109
+ // D2: 识别为 pnpm/yarn/bun → fail-closed + 用户可见提示
110
+ if (pm === "pnpm" || pm === "yarn" || pm === "bun") {
111
+ warn(
112
+ `检测到使用 ${pm},无法自动确定是否为全局安装;` +
113
+ `如果你刚才跑的是 \`${pm} global add\` / \`add -g\`,` +
114
+ `请手动执行:codeforge install --global`,
115
+ )
116
+ process.exit(0)
117
+ }
118
+
119
+ // D3: 其它(npm 但非 global / unknown pm / 无 user_agent)→ 静默 exit 0
120
+ exitOk(`no-op (pm=${pm}, global=${isGlobal})`)
121
+ } catch (e) {
122
+ // 任何未捕获异常都不向 npm 抛错
123
+ warn(`unexpected error: ${e && e.message ? e.message : String(e)}`)
124
+ process.exit(0)
125
+ }
@@ -100,9 +100,16 @@ weighted_score = 0.8×0.30 + 0.5×0.25 + 0.3×0.20 + 0.6×0.15 + 0.2×0.10
100
100
 
101
101
  **Functional 常见打分依据**:
102
102
  - 0.0:只说了"做个东西",完全不知道做什么
103
+ - 0.2:有隐约方向但目标群体/核心输出不明(如"做个管理工具")
104
+ - 0.4:目标群体 + 核心使用场景已清晰,但核心功能边界还未明确(如"给老板看指标的看板",知道谁用/做什么,但不知道哪些指标/什么展示形式)
103
105
  - 0.5:知道大方向("做个导出"),但不知道输出形式、流程
104
106
  - 1.0:输入输出明确,核心流程可描述,用户能说出 Job
105
107
 
108
+ > **初轮信息密度校准**(方案 A 补充):Phase A 初轮评分反映的是**信息密度**,不是需求质量高低。
109
+ > 用户首轮说出「目标群体 + 核心 Job」即可给 0.4,不要因为细节不足降到 0.2。
110
+ > 0.2 应保留给真正「只有一个动词、连做什么都不清楚」的极端情形。
111
+ > 典型校准案例:「做看板让老板看指标」= 目标群体(老板)+ 核心输出(看板/指标)已给出 → Functional ≥ 0.4。
112
+
106
113
  **Edge Cases 常见打分依据**:
107
114
  - 0.0:完全没讨论过边界
108
115
  - 0.5:讨论了 1-2 个正常 happy path,无异常路径
@@ -2,20 +2,25 @@
2
2
  # feature-dev.yaml — CodeForge 第一个真实工作流
3
3
  #
4
4
  # 触发:用户输入 /ship
5
- # 流程:planner → coder → reviewer → apply
5
+ # 流程:planner → 审方案 → coder → reviewer → apply
6
6
  # 关键步骤(write/apply)默认要求人工审批(除非 autonomy=full)
7
7
  # ──────────────────────────────────────────────────────────────
8
8
 
9
9
  name: feature-dev
10
- # ADR:workflow-on-decision-branching 跨 step 反馈循环上限(reviewer→coder REQUEST_CHANGES 反复 goto 兜底)
11
- max_loops: 3
10
+ # ADR:workflow-on-decision-branching + ADR:full-chain-auto-review-gating
11
+ # — 跨 step 反馈循环上限。
12
+ # 原 3 是「reviewer→coder REQUEST_CHANGES」单层循环;
13
+ # 新增「reviewer→planner」方案 review 循环后,整体循环层数增加,
14
+ # max_loops 提升到 5 给两类回退路径足够预算。
15
+ max_loops: 5
12
16
  version: 1.0.0
13
17
  description: |
14
18
  完整的"从需求到落地"流程。串联三个核心 agent:
15
19
  1. planner 出方案(自动 smart_search + repo-map)
16
- 2. coder 按方案 stage 改动到 .codeforge/pending/
17
- 3. reviewer 审阅 + 跑测试
18
- 4. 用户审批 apply 落地工作区 → 自动沉淀经验回 KH
20
+ 2. reviewer 审方案(plan_only,REQUEST_CHANGES planner 重写)
21
+ 3. coder 按方案 stage 改动到 .codeforge/pending/
22
+ 4. reviewer 审代码 + 跑测试
23
+ 5. 用户审批 → apply 落地工作区 → 自动沉淀经验回 KH
19
24
 
20
25
  trigger: /ship
21
26
 
@@ -36,6 +41,31 @@ steps:
36
41
  on_error: skip # KH 不可用不阻塞主流程(C18 同精神)
37
42
  on_error: abort
38
43
 
44
+ # ADR:full-chain-auto-review-gating — 软层 Phase 1,方案 review 门控
45
+ - name: 审方案
46
+ agent: reviewer
47
+ description: 审 planner 输出的方案(plans/*.md)合理性,通过后才派 coder 执行
48
+ inject_context:
49
+ review_target: plan_only
50
+ focus:
51
+ - 需求覆盖
52
+ - 设计合理性
53
+ - 风险评估
54
+ - 涉及文件清单
55
+ actions:
56
+ - tool: pending-changes
57
+ args:
58
+ action: list
59
+ status: pending
60
+ on_error: skip
61
+ on_decision:
62
+ APPROVE: continue
63
+ REQUEST_CHANGES:
64
+ action: goto
65
+ target: 规划 # 回 planner 改方案,max_loops=5 兜底
66
+ BLOCK: abort # 严重设计问题终止 workflow
67
+ on_error: abort
68
+
39
69
  - name: 执行
40
70
  agent: coder
41
71
  description: 严格按方案 stage 改动;测试失败立刻停下汇报
@@ -65,7 +95,7 @@ steps:
65
95
  APPROVE: continue # 进入"落地" step
66
96
  REQUEST_CHANGES:
67
97
  action: goto
68
- target: 执行 # 回到 coder 实现 step(max_loops=3 兜底)
98
+ target: 执行 # 回到 coder 实现 step(max_loops=5 兜底)
69
99
  BLOCK: abort # 严重问题终止 workflow
70
100
  on_error: abort
71
101