cc-devflow 4.5.11 → 4.5.12
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/.claude/skills/cc-act/CHANGELOG.md +18 -0
- package/.claude/skills/cc-act/PLAYBOOK.md +17 -269
- package/.claude/skills/cc-act/SKILL.md +38 -425
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_INDEX_TEMPLATE.md +2 -13
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_TEMPLATE.md +1 -9
- package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +21 -177
- package/.claude/skills/cc-act/references/closure-contract.md +12 -63
- package/.claude/skills/cc-act/references/git-commit-guidelines.md +5 -5
- package/.claude/skills/cc-act/scripts/cc-act-common.sh +5 -322
- package/.claude/skills/cc-act/scripts/detect-ship-target.sh +11 -2
- package/.claude/skills/cc-act/scripts/inspect-git-index.sh +58 -0
- package/.claude/skills/cc-act/scripts/render-pr-brief.sh +40 -440
- package/.claude/skills/cc-act/scripts/verify-act-gate.sh +10 -50
- package/.claude/skills/cc-check/CHANGELOG.md +18 -0
- package/.claude/skills/cc-check/PLAYBOOK.md +19 -273
- package/.claude/skills/cc-check/SKILL.md +33 -456
- package/.claude/skills/cc-check/references/review-contract.md +12 -147
- package/.claude/skills/cc-dev/CHANGELOG.md +15 -0
- package/.claude/skills/cc-dev/PLAYBOOK.md +1 -1
- package/.claude/skills/cc-dev/SKILL.md +52 -137
- package/.claude/skills/cc-dev/scripts/resolve-cc-devflow.sh +181 -0
- package/.claude/skills/cc-do/CHANGELOG.md +11 -0
- package/.claude/skills/cc-do/PLAYBOOK.md +19 -113
- package/.claude/skills/cc-do/SKILL.md +39 -245
- package/.claude/skills/cc-do/references/execution-recovery.md +15 -109
- package/.claude/skills/cc-do/scripts/cc-do-common.sh +5 -57
- package/.claude/skills/cc-do/scripts/check-task-status.sh +35 -65
- package/.claude/skills/cc-do/scripts/mark-task-complete.sh +9 -46
- package/.claude/skills/cc-do/scripts/select-ready-tasks.sh +29 -97
- package/.claude/skills/cc-investigate/CHANGELOG.md +16 -0
- package/.claude/skills/cc-investigate/PLAYBOOK.md +20 -180
- package/.claude/skills/cc-investigate/SKILL.md +64 -246
- package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +48 -98
- package/.claude/skills/cc-investigate/references/investigation-contract.md +14 -218
- package/.claude/skills/cc-next/CHANGELOG.md +6 -0
- package/.claude/skills/cc-next/PLAYBOOK.md +12 -8
- package/.claude/skills/cc-next/SKILL.md +34 -140
- package/.claude/skills/cc-plan/CHANGELOG.md +16 -0
- package/.claude/skills/cc-plan/PLAYBOOK.md +22 -161
- package/.claude/skills/cc-plan/SKILL.md +45 -295
- package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +30 -228
- package/.claude/skills/cc-plan/references/planning-contract.md +24 -161
- package/.claude/skills/cc-plan/scripts/next-change-key.sh +8 -44
- package/.claude/skills/cc-plan/scripts/parse-task-dependencies.js +2 -2
- package/.claude/skills/cc-plan/scripts/validate-scope.sh +1 -1
- package/.claude/skills/cc-pr-land/SKILL.md +14 -114
- package/.claude/skills/cc-pr-review/CHANGELOG.md +4 -0
- package/.claude/skills/cc-pr-review/SKILL.md +20 -103
- package/.claude/skills/cc-review/CHANGELOG.md +17 -0
- package/.claude/skills/cc-review/PLAYBOOK.md +13 -86
- package/.claude/skills/cc-review/SKILL.md +53 -241
- package/.claude/skills/cc-review/references/e2e-and-plugin-verification.md +2 -2
- package/.claude/skills/cc-review/references/implementation-review-branch.md +7 -147
- package/.claude/skills/cc-review/references/plan-review-branch.md +5 -147
- package/.claude/skills/cc-review/references/review-methods.md +10 -218
- package/.claude/skills/cc-review/scripts/collect-review-context.sh +4 -63
- package/.claude/skills/cc-roadmap/PLAYBOOK.md +1 -1
- package/.claude/skills/cc-roadmap/SKILL.md +3 -3
- package/.claude/skills/cc-simplify/CHANGELOG.md +7 -0
- package/.claude/skills/cc-simplify/SKILL.md +26 -21
- package/.claude/skills/cc-spec-init/PLAYBOOK.md +12 -48
- package/.claude/skills/cc-spec-init/SKILL.md +29 -132
- package/.claude/skills/cc-spec-init/references/spec-contract.md +8 -17
- package/CHANGELOG.md +13 -0
- package/bin/cc-devflow-cli.js +20 -260
- package/bin/cc-devflow.js +44 -7
- package/docs/commands/README.md +1 -1
- package/docs/commands/README.zh-CN.md +1 -1
- package/docs/examples/README.md +1 -1
- package/docs/examples/START-HERE.md +14 -15
- package/docs/examples/example-bindings.json +11 -11
- package/docs/examples/full-design-blocked/README.md +4 -6
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/{planning/tasks.md → task.md} +20 -15
- package/docs/examples/local-handoff/README.md +8 -11
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/pr-brief.md +31 -0
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/{planning/tasks.md → task.md} +18 -13
- package/docs/examples/pdca-loop/README.md +6 -9
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +9 -11
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/{planning/tasks.md → task.md} +18 -13
- package/docs/examples/scripts/check-example-bindings.sh +11 -62
- package/docs/guides/artifact-contract.md +10 -40
- package/docs/guides/getting-started.md +8 -8
- package/docs/guides/getting-started.zh-CN.md +8 -8
- package/docs/guides/minimize-artifacts.md +16 -130
- package/docs/guides/project-postmortem.md +14 -71
- package/lib/compiler/__tests__/skills-registry.test.js +9 -8
- package/lib/compiler/resource-copier.js +29 -0
- package/lib/skill-runtime/__tests__/archive-change.test.js +2 -2
- package/lib/skill-runtime/__tests__/benchmark-skills.test.js +3 -3
- package/lib/skill-runtime/__tests__/cli-bootstrap.integration.test.js +14 -4
- package/lib/skill-runtime/errors.js +3 -3
- package/lib/skill-runtime/index.js +5 -23
- package/lib/skill-runtime/paths.js +5 -52
- package/lib/skill-runtime/query-registry.js +4 -4
- package/lib/skill-runtime/query.js +89 -201
- package/lib/skill-runtime/store.js +4 -40
- package/lib/skill-runtime/trace.js +2 -2
- package/package.json +2 -5
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_PRINCIPLES_TEMPLATE.md +0 -29
- package/.claude/skills/cc-act/assets/RELEASE_NOTE_TEMPLATE.md +0 -54
- package/.claude/skills/cc-act/scripts/generate-status-report.sh +0 -92
- package/.claude/skills/cc-act/scripts/sync-act-docs.sh +0 -355
- package/.claude/skills/cc-check/assets/REPORT_CARD_TEMPLATE.json +0 -234
- package/.claude/skills/cc-check/scripts/render-report-card.js +0 -438
- package/.claude/skills/cc-check/scripts/verify-gate.sh +0 -85
- package/.claude/skills/cc-do/scripts/build-task-context.sh +0 -175
- package/.claude/skills/cc-do/scripts/record-review-decision.sh +0 -88
- package/.claude/skills/cc-do/scripts/recover-workflow.sh +0 -82
- package/.claude/skills/cc-do/scripts/run-problem-analysis.sh +0 -70
- package/.claude/skills/cc-do/scripts/verify-task-gates.sh +0 -109
- package/.claude/skills/cc-do/scripts/write-task-checkpoint.sh +0 -92
- package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +0 -224
- package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +0 -178
- package/.claude/skills/cc-spec-init/assets/CHANGE_META_TEMPLATE.json +0 -28
- package/.claude/skills/cc-spec-init/scripts/validate-spec-links.sh +0 -45
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +0 -234
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/task-manifest.json +0 -488
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/review/report-card.json +0 -189
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/resume-index.md +0 -39
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/status.md +0 -29
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +0 -123
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/task-manifest.json +0 -292
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/review/report-card.json +0 -136
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/status.md +0 -29
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +0 -124
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +0 -292
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/review/report-card.json +0 -136
- package/docs/get-shit-done-strategy-audit.md +0 -518
- package/docs/skill-runtime-migration.md +0 -46
- package/lib/skill-runtime/__tests__/approve.test.js +0 -92
- package/lib/skill-runtime/__tests__/autopilot.test.js +0 -253
- package/lib/skill-runtime/__tests__/benchmark-artifacts.test.js +0 -165
- package/lib/skill-runtime/__tests__/delegation.test.js +0 -97
- package/lib/skill-runtime/__tests__/dispatch.test.js +0 -237
- package/lib/skill-runtime/__tests__/intent.test.js +0 -203
- package/lib/skill-runtime/__tests__/lifecycle.test.js +0 -169
- package/lib/skill-runtime/__tests__/planner.tdd.test.js +0 -331
- package/lib/skill-runtime/__tests__/prepare-pr.test.js +0 -126
- package/lib/skill-runtime/__tests__/query.test.js +0 -860
- package/lib/skill-runtime/__tests__/readiness.test.js +0 -53
- package/lib/skill-runtime/__tests__/release.test.js +0 -85
- package/lib/skill-runtime/__tests__/review-check-integration.test.js +0 -148
- package/lib/skill-runtime/__tests__/review-records.test.js +0 -619
- package/lib/skill-runtime/__tests__/runtime.integration.test.js +0 -351
- package/lib/skill-runtime/__tests__/schemas.test.js +0 -337
- package/lib/skill-runtime/__tests__/task-contract-migrate.test.js +0 -137
- package/lib/skill-runtime/__tests__/task-contract.test.js +0 -874
- package/lib/skill-runtime/__tests__/team-state.test.js +0 -51
- package/lib/skill-runtime/__tests__/verify-artifacts.test.js +0 -203
- package/lib/skill-runtime/__tests__/worker-run.test.js +0 -275
- package/lib/skill-runtime/__tests__/worker.test.js +0 -56
- package/lib/skill-runtime/__tests__/workflow-context-legacy-fallback.test.js +0 -31
- package/lib/skill-runtime/__tests__/workflow-context.test.js +0 -98
- package/lib/skill-runtime/artifacts.js +0 -88
- package/lib/skill-runtime/context-index.js +0 -545
- package/lib/skill-runtime/delegation.js +0 -533
- package/lib/skill-runtime/intent.js +0 -309
- package/lib/skill-runtime/lifecycle.js +0 -294
- package/lib/skill-runtime/operations/CLAUDE.md +0 -19
- package/lib/skill-runtime/operations/approve.js +0 -81
- package/lib/skill-runtime/operations/autopilot-core.js +0 -337
- package/lib/skill-runtime/operations/autopilot-execution.js +0 -307
- package/lib/skill-runtime/operations/autopilot-shared.js +0 -48
- package/lib/skill-runtime/operations/autopilot.js +0 -163
- package/lib/skill-runtime/operations/dispatch.js +0 -416
- package/lib/skill-runtime/operations/init.js +0 -60
- package/lib/skill-runtime/operations/janitor.js +0 -61
- package/lib/skill-runtime/operations/plan.js +0 -59
- package/lib/skill-runtime/operations/prepare-pr.js +0 -25
- package/lib/skill-runtime/operations/release.js +0 -99
- package/lib/skill-runtime/operations/resume.js +0 -126
- package/lib/skill-runtime/operations/review-records.js +0 -265
- package/lib/skill-runtime/operations/snapshot.js +0 -45
- package/lib/skill-runtime/operations/task-contract.js +0 -593
- package/lib/skill-runtime/operations/verify.js +0 -170
- package/lib/skill-runtime/operations/worker-run.js +0 -531
- package/lib/skill-runtime/operations/worker.js +0 -33
- package/lib/skill-runtime/planner.js +0 -539
- package/lib/skill-runtime/readiness.js +0 -84
- package/lib/skill-runtime/review-records.js +0 -123
- package/lib/skill-runtime/review.js +0 -855
- package/lib/skill-runtime/schemas.js +0 -746
- package/lib/skill-runtime/task-contract.js +0 -188
- package/lib/skill-runtime/team-state.js +0 -122
- package/lib/skill-runtime/workflow-context.js +0 -748
|
@@ -1,55 +1,19 @@
|
|
|
1
1
|
# CC-Spec-Init Playbook
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Role
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
2. `spec` 记录现状,`roadmap` 记录未来,`change-meta` 记录桥接。
|
|
7
|
-
3. 同一个 change 可以多挂 capability,但只能有一个 primary capability。
|
|
8
|
-
4. 正常演化优先 `deprecated` / `merged` / `split`,不要直接物理删除。
|
|
9
|
-
5. 每次变更结束都跑链接校验,别把断链留到下轮执行。
|
|
5
|
+
Specs record current capability truth. Roadmap records future work. Git records process history.
|
|
10
6
|
|
|
11
|
-
##
|
|
7
|
+
## Flow
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
1. Read existing `devflow/specs/INDEX.md`.
|
|
10
|
+
2. Read related capability specs.
|
|
11
|
+
3. Decide whether the work is bootstrap, create, split, merge, deprecate, or language cleanup.
|
|
12
|
+
4. Update spec Markdown only.
|
|
13
|
+
5. Commit the spec change.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
- 建 `devflow/specs/capabilities/`
|
|
17
|
-
- 为当前最重要的 capability 建最小 truth source
|
|
15
|
+
## Do Not
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
- 回写 `INDEX.md`
|
|
23
|
-
- 为当前 change 生成 `change-meta.json`
|
|
24
|
-
|
|
25
|
-
### Update Links
|
|
26
|
-
|
|
27
|
-
- 修 roadmap / backlog / change / spec 的 capability 引用
|
|
28
|
-
- 重建 `INDEX.md`
|
|
29
|
-
|
|
30
|
-
### Split / Merge / Deprecate
|
|
31
|
-
|
|
32
|
-
- 在原 capability spec 标明状态变化
|
|
33
|
-
- 补 `splitInto` / `mergedInto` / `supersededBy`
|
|
34
|
-
- 确认历史 change 仍然可追踪
|
|
35
|
-
|
|
36
|
-
## Command Kit
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
# 初始化 specs 目录
|
|
40
|
-
bash .claude/skills/cc-spec-init/scripts/bootstrap-specs.sh
|
|
41
|
-
|
|
42
|
-
# 校验 spec 链路
|
|
43
|
-
bash .claude/skills/cc-spec-init/scripts/validate-spec-links.sh
|
|
44
|
-
|
|
45
|
-
# 看哪些 change 已缺 change-meta
|
|
46
|
-
find devflow/changes -maxdepth 2 -name change-meta.json | sort
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Review Questions
|
|
50
|
-
|
|
51
|
-
1. capability 的边界是否清楚到 AI 不会把别的系统能力写进来?
|
|
52
|
-
2. `Current Truth` 是否只写当前成立的承诺?
|
|
53
|
-
3. `Missing` 和 `Intentional Gaps` 是否被保留下来?
|
|
54
|
-
4. roadmap item 和 change 是否都能指向 capability?
|
|
55
|
-
5. 这次是该 `update`,还是其实应该 `split` / `merge`?
|
|
17
|
+
- Do not create change-scoped JSON.
|
|
18
|
+
- Do not store workflow state in specs.
|
|
19
|
+
- Do not turn one requirement's implementation detail into capability truth.
|
|
@@ -1,148 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cc-spec-init
|
|
3
|
-
version: 1.
|
|
4
|
-
description: Use when you need to initialize capability specs under `devflow/specs
|
|
3
|
+
version: 1.2.0
|
|
4
|
+
description: Use when you need to initialize or evolve capability specs under `devflow/specs/`.
|
|
5
|
+
reads:
|
|
6
|
+
- PLAYBOOK.md
|
|
7
|
+
- references/spec-contract.md
|
|
8
|
+
- assets/INDEX_TEMPLATE.md
|
|
9
|
+
- assets/CAPABILITY_TEMPLATE.md
|
|
10
|
+
writes:
|
|
11
|
+
- path: devflow/specs/INDEX.md
|
|
12
|
+
durability: durable
|
|
13
|
+
required: false
|
|
14
|
+
- path: devflow/specs/capabilities/<capability>.md
|
|
15
|
+
durability: durable
|
|
16
|
+
required: false
|
|
17
|
+
effects:
|
|
18
|
+
- capability truth source initialization or update
|
|
19
|
+
- Git commit after spec work completes
|
|
5
20
|
---
|
|
6
21
|
|
|
7
22
|
# CC-Spec-Init
|
|
8
23
|
|
|
9
|
-
|
|
24
|
+
`cc-spec-init` maintains long-lived capability specs. It is not a process-state generator.
|
|
10
25
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`cc-spec-init` 是 capability-centered spec 的收口器。
|
|
14
|
-
|
|
15
|
-
它只做一件事:把系统“当前承诺什么”收成稳定 truth source,并把 `roadmap -> change -> spec` 的链接补齐。
|
|
16
|
-
|
|
17
|
-
它不是主 workflow 的一环。
|
|
18
|
-
|
|
19
|
-
主 workflow 仍然是:
|
|
20
|
-
|
|
21
|
-
- `cc-roadmap`
|
|
22
|
-
- `cc-plan` 或 `cc-investigate`
|
|
23
|
-
- `cc-do`
|
|
24
|
-
- `cc-check`
|
|
25
|
-
- `cc-act`
|
|
26
|
-
|
|
27
|
-
`cc-spec-init` 负责这些动作:
|
|
28
|
-
|
|
29
|
-
- 初始化 `devflow/specs/`
|
|
30
|
-
- 新建 capability spec
|
|
31
|
-
- 对 capability 做 `split` / `merge` / `deprecate`
|
|
32
|
-
- 生成或修复 `devflow/changes/<change-key>/change-meta.json`
|
|
33
|
-
- 重建 `devflow/specs/INDEX.md`
|
|
34
|
-
- 校验 capability、roadmap item、change 之间的链接完整性
|
|
35
|
-
|
|
36
|
-
## Runtime Output Policy
|
|
37
|
-
|
|
38
|
-
写入任何 durable Markdown 或 JSON metadata 前,先运行 `cc-devflow config resolve --format policy`。
|
|
39
|
-
|
|
40
|
-
- `Output language` 是机器约束,capability spec、`devflow/specs/INDEX.md` 和 `change-meta.json` 必须记录并遵守它。
|
|
41
|
-
- `agent_preferences` 是用户偏好建议,只影响表达方式和结构选择,不覆盖本 Skill 的工作流边界。
|
|
42
|
-
- 如果配置解析失败,先修配置或向用户说明阻塞,不要用默认语言继续生成正式文档。
|
|
43
|
-
|
|
44
|
-
## Read First
|
|
45
|
-
|
|
46
|
-
1. `PLAYBOOK.md`
|
|
47
|
-
2. `CHANGELOG.md`
|
|
48
|
-
3. `references/spec-contract.md`
|
|
49
|
-
4. `assets/INDEX_TEMPLATE.md`
|
|
50
|
-
5. `assets/CAPABILITY_TEMPLATE.md`
|
|
51
|
-
6. `assets/CHANGE_META_TEMPLATE.json`
|
|
52
|
-
|
|
53
|
-
## Use This Skill When
|
|
54
|
-
|
|
55
|
-
- 你第一次把仓库升级到 capability-centered spec 模型
|
|
56
|
-
- 需要创建新 capability spec
|
|
57
|
-
- 需要把 change 绑定到 primary / secondary capability
|
|
58
|
-
- 需要做 capability 的 `split` / `merge` / `deprecate`
|
|
59
|
-
- `cc-roadmap`、`cc-plan`、`cc-act` 发现 spec 链路断了
|
|
60
|
-
- 需要在 closeout 前确认 spec/roadmap/change 仍然同构
|
|
61
|
-
|
|
62
|
-
如果当前工作只是执行一个已冻结任务,不要停在这里,回主 workflow。
|
|
63
|
-
|
|
64
|
-
## Entry Gate
|
|
65
|
-
|
|
66
|
-
1. 先读现有 `devflow/specs/INDEX.md`、相关 capability spec、相关 `devflow/ROADMAP.md` / `devflow/BACKLOG.md`、相关 `change-meta.json`。
|
|
67
|
-
2. 先判断你是在做 `bootstrap`、`create`、`update-links`、`split`、`merge` 还是 `deprecate`。
|
|
68
|
-
3. 先锁定 capability 边界,再写模板;不要先写 prose 再猜结构。
|
|
69
|
-
4. 先明确 primary capability,再允许 secondary capabilities 存在。
|
|
70
|
-
5. 先检查命名是否已经有 canonical term;同义词、歧义词和关系约束没收口前,不要新建第二套 capability 名称。
|
|
71
|
-
|
|
72
|
-
## Session Protocol
|
|
73
|
-
|
|
74
|
-
1. 先判断现状:
|
|
75
|
-
- `devflow/specs/` 是否已存在
|
|
76
|
-
- capability 是否已存在
|
|
77
|
-
- 相关 change 是否已有 `change-meta.json`
|
|
78
|
-
2. 如果是首次初始化:
|
|
79
|
-
- 创建 `devflow/specs/INDEX.md`
|
|
80
|
-
- 创建 `devflow/specs/capabilities/`
|
|
81
|
-
- 为当前已知 capability 写最小 spec
|
|
82
|
-
3. 如果是新 capability:
|
|
83
|
-
- 先写 capability 边界、约束、当前 truth、gaps
|
|
84
|
-
- 再写最小 language block:canonical term、definition、aliases to avoid、relationships、flagged ambiguities
|
|
85
|
-
- 再登记到 `INDEX.md`
|
|
86
|
-
4. 如果是 change 绑定:
|
|
87
|
-
- 生成或更新 `change-meta.json`
|
|
88
|
-
- 填入 `primaryCapability`、`secondaryCapabilities`、`expectedDelta`、`affectedInvariants`、`gapsClosed`、`newGaps`
|
|
89
|
-
5. 如果是 capability 结构调整:
|
|
90
|
-
- 优先 `deprecated` / `mergedInto` / `splitInto`
|
|
91
|
-
- 不要直接物理删除,除非确认没有 roadmap/change 仍在引用
|
|
92
|
-
6. 结束前运行链接校验,确认:
|
|
93
|
-
- `INDEX.md` 引到的 capability 文件都存在
|
|
94
|
-
- `change-meta.json` 里的 capability 都能落到 spec
|
|
95
|
-
- roadmap / backlog 里的 capability 引用仍可追踪
|
|
96
|
-
- 新 capability 的名称、aliases、relationships 没有和已有 spec 冲突
|
|
97
|
-
|
|
98
|
-
## Language Boundary Gate
|
|
99
|
-
|
|
100
|
-
capability spec 是长期 truth source,命名必须比一次需求更稳定:
|
|
101
|
-
|
|
102
|
-
- canonical term:只选一个主名,优先沿用 roadmap、历史 design/analysis、代码公共接口和用户领域语言里已经稳定的词。
|
|
103
|
-
- aliases to avoid:记录容易混用的别名,说明为什么不能继续用。
|
|
104
|
-
- flagged ambiguity:同一个词指向两个概念时,必须写清拆分边界,必要时拆 capability。
|
|
105
|
-
- relationships:用一句话写清 capability 之间的拥有、依赖、生命周期、输入输出或互斥关系。
|
|
106
|
-
- implementation names:类名、文件名、函数名只有在它们已经是公共领域语言时才进入 spec;否则留在 change 设计里。
|
|
107
|
-
|
|
108
|
-
## Output
|
|
26
|
+
Allowed outputs:
|
|
109
27
|
|
|
110
28
|
- `devflow/specs/INDEX.md`
|
|
111
29
|
- `devflow/specs/capabilities/<capability>.md`
|
|
112
|
-
- `devflow/changes/<change-key>/change-meta.json`
|
|
113
|
-
- 链接校验结果
|
|
114
|
-
|
|
115
|
-
## Working Rules
|
|
116
30
|
|
|
117
|
-
|
|
118
|
-
2. `roadmap` 写未来推进,不写当前 truth。
|
|
119
|
-
3. `change-meta.json` 是机器真相源;capability markdown 是人机共读的长期约束源。
|
|
120
|
-
4. 一个 change 可以挂多个 capability,但必须有一个 `primaryCapability`。
|
|
121
|
-
5. capability 不直接硬删除;优先用状态表达历史连续性。
|
|
122
|
-
6. `INDEX.md` 只做目录和状态总览,不复制各 spec 正文。
|
|
31
|
+
Do not create change-scoped JSON. Changes link to specs through `task.md`, roadmap text, PR text, and Git commits.
|
|
123
32
|
|
|
124
|
-
##
|
|
33
|
+
## Use This Skill When
|
|
125
34
|
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
- 模板:`assets/CAPABILITY_TEMPLATE.md`
|
|
131
|
-
- 模板:`assets/CHANGE_META_TEMPLATE.json`
|
|
132
|
-
- 初始化:`scripts/bootstrap-specs.sh`
|
|
133
|
-
- 校验:`scripts/validate-spec-links.sh`
|
|
35
|
+
- initializing `devflow/specs/`
|
|
36
|
+
- creating a capability spec
|
|
37
|
+
- splitting, merging, or deprecating a capability
|
|
38
|
+
- clarifying canonical project language
|
|
134
39
|
|
|
135
40
|
## Exit Criteria
|
|
136
41
|
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
- 下一步可以安心回到 `cc-roadmap`、`cc-plan` 或 `cc-act`
|
|
142
|
-
|
|
143
|
-
## Do Not
|
|
144
|
-
|
|
145
|
-
- 不把 roadmap 写回 spec
|
|
146
|
-
- 不把执行细节写成 capability truth
|
|
147
|
-
- 不允许没有 primary capability 的多 capability change
|
|
148
|
-
- 不直接删 capability 文件导致链路断裂
|
|
42
|
+
- capability boundary is clear
|
|
43
|
+
- current truth and gaps are written
|
|
44
|
+
- `INDEX.md` links to existing capability files
|
|
45
|
+
- spec changes are committed to Git
|
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
# Spec Contract
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Files
|
|
4
4
|
|
|
5
|
-
- `devflow/
|
|
6
|
-
- `devflow/specs/
|
|
7
|
-
- `devflow/specs/capabilities/*.md`: 某个 capability 当前承诺什么
|
|
8
|
-
- `devflow/changes/<change>/change-meta.json`: 某次 change 如何影响 capability
|
|
5
|
+
- `devflow/specs/INDEX.md`
|
|
6
|
+
- `devflow/specs/capabilities/<capability>.md`
|
|
9
7
|
|
|
10
|
-
##
|
|
8
|
+
## Rules
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Change Meta Rules
|
|
18
|
-
|
|
19
|
-
1. `primaryCapability` 必填。
|
|
20
|
-
2. `secondaryCapabilities` 可空,但必须有明确原因。
|
|
21
|
-
3. `changeType` 只使用:`create`、`update`、`split`、`merge`、`deprecate`。
|
|
22
|
-
4. `syncStatus` 生命周期:`planned -> verified -> synced`。
|
|
10
|
+
- Specs describe stable capability truth.
|
|
11
|
+
- Specs do not track per-change state.
|
|
12
|
+
- Per-change decisions live in `task.md`, PR text, commits, or postmortems.
|
|
13
|
+
- Capability names must follow project language and avoid duplicate terms.
|
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [4.5.12] - 2026-05-13
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Changed `cc-devflow task-contract` so task document budgets are advisory warnings instead of blocking validation failures.
|
|
17
|
+
- Changed `npm run benchmark:skills` so skill entrypoint budgets report advisory failures without failing `npm run verify`.
|
|
18
|
+
- Updated `cc-plan` and `cc-investigate` to preserve required task-template fields instead of trimming contract truth to fit token estimates.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Fixed `task-contract compile` so shorthand task checklists fail before `task-manifest.json` or `change-meta.json` can be generated.
|
|
23
|
+
- Added task-template validation to reject incomplete task blocks with `C11` instead of letting default manifest enrichment hide missing contract fields.
|
|
24
|
+
|
|
12
25
|
## [4.5.11] - 2026-05-13
|
|
13
26
|
|
|
14
27
|
### Added
|
package/bin/cc-devflow-cli.js
CHANGED
|
@@ -60,8 +60,6 @@ Commands:
|
|
|
60
60
|
config doctor Validate config and local ignore safety
|
|
61
61
|
query list List typed runtime query ids
|
|
62
62
|
query <id> Run a typed runtime query as JSON
|
|
63
|
-
task-contract Compile task contract artifacts
|
|
64
|
-
review Record durable review ledger events
|
|
65
63
|
next-change-key Compute the next REQ/FIX change key
|
|
66
64
|
archive-change Archive a completed change to devflow/changes/archive/YYYY-MM/
|
|
67
65
|
restore-change Restore an archived change back to devflow/changes/
|
|
@@ -115,11 +113,7 @@ Examples:
|
|
|
115
113
|
cc-devflow config set output.document_language zh-CN --user
|
|
116
114
|
cc-devflow config resolve --cwd /path/to/project --format policy
|
|
117
115
|
cc-devflow query list
|
|
118
|
-
cc-devflow query ship-readiness --cwd /path/to/project --change REQ-123
|
|
119
116
|
cc-devflow query workflow-context --cwd /path/to/project --change REQ-123 --change-key REQ-123-my-feature --data-only --no-trace --compact
|
|
120
|
-
cc-devflow query progress --change REQ-123 --change-key REQ-123-my-feature
|
|
121
|
-
cc-devflow task-contract compile --cwd /path/to/project --change REQ-123 --change-key REQ-123-my-feature
|
|
122
|
-
cc-devflow review start --cwd /path/to/project --change REQ-123 --change-key REQ-123-my-feature --base-sha abc --head-sha def
|
|
123
117
|
`);
|
|
124
118
|
}
|
|
125
119
|
|
|
@@ -183,6 +177,9 @@ function copyManagedDirectory(src, dest, options = {}) {
|
|
|
183
177
|
const stats = fs.statSync(src);
|
|
184
178
|
if (stats.isDirectory()) {
|
|
185
179
|
fs.mkdirSync(dest, { recursive: true });
|
|
180
|
+
if (force) {
|
|
181
|
+
pruneManagedDirectory(src, dest);
|
|
182
|
+
}
|
|
186
183
|
const entries = fs.readdirSync(src);
|
|
187
184
|
for (const entry of entries) {
|
|
188
185
|
copyManagedDirectory(path.join(src, entry), path.join(dest, entry), options);
|
|
@@ -212,6 +209,23 @@ function copyManagedDirectory(src, dest, options = {}) {
|
|
|
212
209
|
}
|
|
213
210
|
}
|
|
214
211
|
|
|
212
|
+
function pruneManagedDirectory(src, dest) {
|
|
213
|
+
if (!fs.existsSync(dest) || !fs.statSync(dest).isDirectory()) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const sourceEntries = new Set(fs.readdirSync(src));
|
|
218
|
+
for (const entry of fs.readdirSync(dest)) {
|
|
219
|
+
if (sourceEntries.has(entry)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const targetPath = path.join(dest, entry);
|
|
224
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
225
|
+
console.log(`[DELETE] ${path.relative(process.cwd(), targetPath)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
215
229
|
function syncDistributedSkills(targetRoot, options = {}) {
|
|
216
230
|
const { force = false } = options;
|
|
217
231
|
const targetClaudeDir = path.join(targetRoot, '.claude');
|
|
@@ -540,252 +554,6 @@ async function runQueryCommand(args) {
|
|
|
540
554
|
return result.ok ? 0 : 2;
|
|
541
555
|
}
|
|
542
556
|
|
|
543
|
-
async function runTaskContractCommand(args) {
|
|
544
|
-
const [subcommand, ...rest] = args;
|
|
545
|
-
|
|
546
|
-
if (!subcommand || subcommand === '--help' || subcommand === '-h') {
|
|
547
|
-
console.error('Use: cc-devflow task-contract <compile|validate|migrate> --change <changeId> [--change-key <key>] [--cwd <path>] [--fold-design] [--fold-analysis]');
|
|
548
|
-
return 3;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
const options = parseChangeScopedArgs(rest);
|
|
552
|
-
if (!options.changeId) {
|
|
553
|
-
console.error('task-contract --change is required.');
|
|
554
|
-
return 3;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
if (subcommand === 'compile' || subcommand === 'validate' || subcommand === 'migrate') {
|
|
558
|
-
const {
|
|
559
|
-
runCompile,
|
|
560
|
-
runValidate,
|
|
561
|
-
runMigrate
|
|
562
|
-
} = require(path.join(PACKAGE_ROOT, 'lib/skill-runtime/operations/task-contract.js'));
|
|
563
|
-
const runners = {
|
|
564
|
-
compile: runCompile,
|
|
565
|
-
validate: runValidate,
|
|
566
|
-
migrate: runMigrate
|
|
567
|
-
};
|
|
568
|
-
const runner = runners[subcommand];
|
|
569
|
-
const result = await runner({
|
|
570
|
-
repoRoot: path.resolve(options.cwd || process.cwd()),
|
|
571
|
-
changeId: options.changeId,
|
|
572
|
-
changeKey: options.changeKey,
|
|
573
|
-
foldDesign: options.rest.includes('--fold-design'),
|
|
574
|
-
foldAnalysis: options.rest.includes('--fold-analysis')
|
|
575
|
-
});
|
|
576
|
-
if (result.code !== 0) {
|
|
577
|
-
console.error(result.stderr || result.error || `task-contract ${subcommand} failed`);
|
|
578
|
-
return result.code;
|
|
579
|
-
}
|
|
580
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
581
|
-
return result.code;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
console.error(`Unknown task-contract command: ${subcommand}`);
|
|
585
|
-
return 3;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
function parseReviewStartArgs(args) {
|
|
589
|
-
const scoped = parseChangeScopedArgs(args);
|
|
590
|
-
const parsed = {
|
|
591
|
-
...scoped,
|
|
592
|
-
mode: 'implementation',
|
|
593
|
-
scope: 'current-diff',
|
|
594
|
-
baseSha: 'unknown',
|
|
595
|
-
headSha: 'unknown',
|
|
596
|
-
selectedNodes: [],
|
|
597
|
-
skippedNodes: [],
|
|
598
|
-
riskLanes: []
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
for (let i = 0; i < scoped.rest.length; i++) {
|
|
602
|
-
const arg = scoped.rest[i];
|
|
603
|
-
if (arg === '--mode') { parsed.mode = scoped.rest[++i]; continue; }
|
|
604
|
-
if (arg.startsWith('--mode=')) { parsed.mode = arg.slice('--mode='.length); continue; }
|
|
605
|
-
if (arg === '--scope') { parsed.scope = scoped.rest[++i]; continue; }
|
|
606
|
-
if (arg.startsWith('--scope=')) { parsed.scope = arg.slice('--scope='.length); continue; }
|
|
607
|
-
if (arg === '--base-sha') { parsed.baseSha = scoped.rest[++i]; continue; }
|
|
608
|
-
if (arg.startsWith('--base-sha=')) { parsed.baseSha = arg.slice('--base-sha='.length); continue; }
|
|
609
|
-
if (arg === '--head-sha') { parsed.headSha = scoped.rest[++i]; continue; }
|
|
610
|
-
if (arg.startsWith('--head-sha=')) { parsed.headSha = arg.slice('--head-sha='.length); continue; }
|
|
611
|
-
if (arg === '--selected-node') { parsed.selectedNodes.push(scoped.rest[++i]); continue; }
|
|
612
|
-
if (arg.startsWith('--selected-node=')) { parsed.selectedNodes.push(arg.slice('--selected-node='.length)); continue; }
|
|
613
|
-
if (arg === '--skipped-node') { parsed.skippedNodes.push(scoped.rest[++i]); continue; }
|
|
614
|
-
if (arg.startsWith('--skipped-node=')) { parsed.skippedNodes.push(arg.slice('--skipped-node='.length)); continue; }
|
|
615
|
-
if (arg === '--risk-lane') { parsed.riskLanes.push(scoped.rest[++i]); continue; }
|
|
616
|
-
if (arg.startsWith('--risk-lane=')) { parsed.riskLanes.push(arg.slice('--risk-lane='.length)); continue; }
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
return parsed;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
function parseReviewEventArgs(args) {
|
|
623
|
-
const scoped = parseChangeScopedArgs(args);
|
|
624
|
-
const parsed = {
|
|
625
|
-
...scoped,
|
|
626
|
-
reviewId: null,
|
|
627
|
-
nodeId: null,
|
|
628
|
-
mode: 'implementation',
|
|
629
|
-
target: null,
|
|
630
|
-
status: null,
|
|
631
|
-
coverage: [],
|
|
632
|
-
evidenceRefs: [],
|
|
633
|
-
findings: [],
|
|
634
|
-
next: null,
|
|
635
|
-
findingId: null,
|
|
636
|
-
severity: null,
|
|
637
|
-
confidence: null,
|
|
638
|
-
displayTier: null,
|
|
639
|
-
fingerprint: null,
|
|
640
|
-
scope: null,
|
|
641
|
-
path: null,
|
|
642
|
-
evidence: null,
|
|
643
|
-
recommendation: null,
|
|
644
|
-
route: null,
|
|
645
|
-
blockingCount: null,
|
|
646
|
-
warningCount: null,
|
|
647
|
-
output: null
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
for (let i = 0; i < scoped.rest.length; i++) {
|
|
651
|
-
const arg = scoped.rest[i];
|
|
652
|
-
if (arg === '--review-id') { parsed.reviewId = scoped.rest[++i]; continue; }
|
|
653
|
-
if (arg.startsWith('--review-id=')) { parsed.reviewId = arg.slice('--review-id='.length); continue; }
|
|
654
|
-
if (arg === '--node-id') { parsed.nodeId = scoped.rest[++i]; continue; }
|
|
655
|
-
if (arg.startsWith('--node-id=')) { parsed.nodeId = arg.slice('--node-id='.length); continue; }
|
|
656
|
-
if (arg === '--mode') { parsed.mode = scoped.rest[++i]; continue; }
|
|
657
|
-
if (arg.startsWith('--mode=')) { parsed.mode = arg.slice('--mode='.length); continue; }
|
|
658
|
-
if (arg === '--target') { parsed.target = scoped.rest[++i]; continue; }
|
|
659
|
-
if (arg.startsWith('--target=')) { parsed.target = arg.slice('--target='.length); continue; }
|
|
660
|
-
if (arg === '--status') { parsed.status = scoped.rest[++i]; continue; }
|
|
661
|
-
if (arg.startsWith('--status=')) { parsed.status = arg.slice('--status='.length); continue; }
|
|
662
|
-
if (arg === '--coverage') { parsed.coverage.push(scoped.rest[++i]); continue; }
|
|
663
|
-
if (arg.startsWith('--coverage=')) { parsed.coverage.push(arg.slice('--coverage='.length)); continue; }
|
|
664
|
-
if (arg === '--evidence-ref') { parsed.evidenceRefs.push(scoped.rest[++i]); continue; }
|
|
665
|
-
if (arg.startsWith('--evidence-ref=')) { parsed.evidenceRefs.push(arg.slice('--evidence-ref='.length)); continue; }
|
|
666
|
-
if (arg === '--finding') { parsed.findings.push(scoped.rest[++i]); continue; }
|
|
667
|
-
if (arg.startsWith('--finding=')) { parsed.findings.push(arg.slice('--finding='.length)); continue; }
|
|
668
|
-
if (arg === '--next') { parsed.next = scoped.rest[++i]; continue; }
|
|
669
|
-
if (arg.startsWith('--next=')) { parsed.next = arg.slice('--next='.length); continue; }
|
|
670
|
-
if (arg === '--finding-id') { parsed.findingId = scoped.rest[++i]; continue; }
|
|
671
|
-
if (arg.startsWith('--finding-id=')) { parsed.findingId = arg.slice('--finding-id='.length); continue; }
|
|
672
|
-
if (arg === '--severity') { parsed.severity = scoped.rest[++i]; continue; }
|
|
673
|
-
if (arg.startsWith('--severity=')) { parsed.severity = arg.slice('--severity='.length); continue; }
|
|
674
|
-
if (arg === '--confidence') { parsed.confidence = scoped.rest[++i]; continue; }
|
|
675
|
-
if (arg.startsWith('--confidence=')) { parsed.confidence = arg.slice('--confidence='.length); continue; }
|
|
676
|
-
if (arg === '--display-tier') { parsed.displayTier = scoped.rest[++i]; continue; }
|
|
677
|
-
if (arg.startsWith('--display-tier=')) { parsed.displayTier = arg.slice('--display-tier='.length); continue; }
|
|
678
|
-
if (arg === '--fingerprint') { parsed.fingerprint = scoped.rest[++i]; continue; }
|
|
679
|
-
if (arg.startsWith('--fingerprint=')) { parsed.fingerprint = arg.slice('--fingerprint='.length); continue; }
|
|
680
|
-
if (arg === '--scope') { parsed.scope = scoped.rest[++i]; continue; }
|
|
681
|
-
if (arg.startsWith('--scope=')) { parsed.scope = arg.slice('--scope='.length); continue; }
|
|
682
|
-
if (arg === '--path') { parsed.path = scoped.rest[++i]; continue; }
|
|
683
|
-
if (arg.startsWith('--path=')) { parsed.path = arg.slice('--path='.length); continue; }
|
|
684
|
-
if (arg === '--evidence') { parsed.evidence = scoped.rest[++i]; continue; }
|
|
685
|
-
if (arg.startsWith('--evidence=')) { parsed.evidence = arg.slice('--evidence='.length); continue; }
|
|
686
|
-
if (arg === '--recommendation') { parsed.recommendation = scoped.rest[++i]; continue; }
|
|
687
|
-
if (arg.startsWith('--recommendation=')) { parsed.recommendation = arg.slice('--recommendation='.length); continue; }
|
|
688
|
-
if (arg === '--route') { parsed.route = scoped.rest[++i]; continue; }
|
|
689
|
-
if (arg.startsWith('--route=')) { parsed.route = arg.slice('--route='.length); continue; }
|
|
690
|
-
if (arg === '--blocking-count') { parsed.blockingCount = scoped.rest[++i]; continue; }
|
|
691
|
-
if (arg.startsWith('--blocking-count=')) { parsed.blockingCount = arg.slice('--blocking-count='.length); continue; }
|
|
692
|
-
if (arg === '--warning-count') { parsed.warningCount = scoped.rest[++i]; continue; }
|
|
693
|
-
if (arg.startsWith('--warning-count=')) { parsed.warningCount = arg.slice('--warning-count='.length); continue; }
|
|
694
|
-
if (arg === '--output') { parsed.output = scoped.rest[++i]; continue; }
|
|
695
|
-
if (arg.startsWith('--output=')) { parsed.output = arg.slice('--output='.length); continue; }
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
return parsed;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
async function runReviewCommand(args) {
|
|
702
|
-
const [subcommand, ...rest] = args;
|
|
703
|
-
|
|
704
|
-
if (!subcommand || subcommand === '--help' || subcommand === '-h') {
|
|
705
|
-
console.error('Use: cc-devflow review start --change <changeId> [--change-key <key>] [--cwd <path>]');
|
|
706
|
-
return 3;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
const reviewRunners = {
|
|
710
|
-
start: null,
|
|
711
|
-
'record-node': 'runReviewRecordNode',
|
|
712
|
-
'add-finding': 'runReviewAddFinding',
|
|
713
|
-
close: 'runReviewClose',
|
|
714
|
-
render: 'runReviewRender'
|
|
715
|
-
};
|
|
716
|
-
|
|
717
|
-
if (subcommand === 'start') {
|
|
718
|
-
const options = parseReviewStartArgs(rest);
|
|
719
|
-
if (!options.changeId) {
|
|
720
|
-
console.error('review start --change is required.');
|
|
721
|
-
return 3;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
const { runReviewStart } = require(path.join(PACKAGE_ROOT, 'lib/skill-runtime/operations/review-records.js'));
|
|
725
|
-
const result = await runReviewStart({
|
|
726
|
-
repoRoot: path.resolve(options.cwd || process.cwd()),
|
|
727
|
-
changeId: options.changeId,
|
|
728
|
-
changeKey: options.changeKey,
|
|
729
|
-
mode: options.mode,
|
|
730
|
-
scope: options.scope,
|
|
731
|
-
baseSha: options.baseSha,
|
|
732
|
-
headSha: options.headSha,
|
|
733
|
-
selectedNodes: options.selectedNodes,
|
|
734
|
-
skippedNodes: options.skippedNodes,
|
|
735
|
-
riskLanes: options.riskLanes
|
|
736
|
-
});
|
|
737
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
738
|
-
return result.code;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
if (reviewRunners[subcommand]) {
|
|
742
|
-
const options = parseReviewEventArgs(rest);
|
|
743
|
-
if (!options.changeId) {
|
|
744
|
-
console.error(`review ${subcommand} --change is required.`);
|
|
745
|
-
return 3;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
const runnerName = reviewRunners[subcommand];
|
|
749
|
-
const runners = require(path.join(PACKAGE_ROOT, 'lib/skill-runtime/operations/review-records.js'));
|
|
750
|
-
const result = await runners[runnerName]({
|
|
751
|
-
repoRoot: path.resolve(options.cwd || process.cwd()),
|
|
752
|
-
changeId: options.changeId,
|
|
753
|
-
changeKey: options.changeKey,
|
|
754
|
-
reviewId: options.reviewId,
|
|
755
|
-
nodeId: options.nodeId,
|
|
756
|
-
mode: options.mode,
|
|
757
|
-
target: options.target,
|
|
758
|
-
status: options.status,
|
|
759
|
-
coverage: options.coverage,
|
|
760
|
-
evidenceRefs: options.evidenceRefs,
|
|
761
|
-
findings: options.findings,
|
|
762
|
-
next: options.next,
|
|
763
|
-
findingId: options.findingId,
|
|
764
|
-
severity: options.severity,
|
|
765
|
-
confidence: options.confidence,
|
|
766
|
-
displayTier: options.displayTier,
|
|
767
|
-
fingerprint: options.fingerprint,
|
|
768
|
-
scope: options.scope,
|
|
769
|
-
path: options.path,
|
|
770
|
-
evidence: options.evidence,
|
|
771
|
-
recommendation: options.recommendation,
|
|
772
|
-
route: options.route,
|
|
773
|
-
blockingCount: options.blockingCount,
|
|
774
|
-
warningCount: options.warningCount,
|
|
775
|
-
output: options.output
|
|
776
|
-
});
|
|
777
|
-
if (result.code !== 0) {
|
|
778
|
-
console.error(result.stderr || result.error || `review ${subcommand} failed`);
|
|
779
|
-
return result.code;
|
|
780
|
-
}
|
|
781
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
782
|
-
return result.code;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
console.error(`Unknown review command: ${subcommand}`);
|
|
786
|
-
return 3;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
557
|
function runNextChangeKey(args) {
|
|
790
558
|
const parsed = { prefix: null, description: null, cwd: null };
|
|
791
559
|
|
|
@@ -948,14 +716,6 @@ async function main() {
|
|
|
948
716
|
return runQueryCommand(rest);
|
|
949
717
|
}
|
|
950
718
|
|
|
951
|
-
if (command === 'task-contract') {
|
|
952
|
-
return runTaskContractCommand(rest);
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
if (command === 'review') {
|
|
956
|
-
return runReviewCommand(rest);
|
|
957
|
-
}
|
|
958
|
-
|
|
959
719
|
if (command === 'next-change-key') {
|
|
960
720
|
return runNextChangeKey(rest);
|
|
961
721
|
}
|
package/bin/cc-devflow.js
CHANGED
|
@@ -1,16 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const ClaudeAdapter = require('../lib/adapters/claude-adapter');
|
|
5
|
-
const CodexAdapter = require('../lib/adapters/codex-adapter');
|
|
6
|
-
const { validateConfig, getDefaultConfig } = require('../lib/adapters/config-validator');
|
|
7
|
-
const logger = require('../lib/adapters/logger');
|
|
8
|
-
const fs = require('fs');
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
9
4
|
const path = require('path');
|
|
10
|
-
|
|
5
|
+
|
|
6
|
+
const CLI_BIN = path.resolve(__dirname, 'cc-devflow-cli.js');
|
|
7
|
+
const CLI_COMMANDS = new Set([
|
|
8
|
+
'help',
|
|
9
|
+
'--help',
|
|
10
|
+
'-h',
|
|
11
|
+
'init',
|
|
12
|
+
'adapt',
|
|
13
|
+
'config',
|
|
14
|
+
'query',
|
|
15
|
+
'next-change-key',
|
|
16
|
+
'archive-change',
|
|
17
|
+
'restore-change',
|
|
18
|
+
'list-archived'
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
function runCli(args) {
|
|
22
|
+
const result = spawnSync(process.execPath, [CLI_BIN, ...args], {
|
|
23
|
+
stdio: 'inherit'
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (result.error) {
|
|
27
|
+
console.error(`Failed to run cc-devflow CLI: ${result.error.message}`);
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return typeof result.status === 'number' ? result.status : 1;
|
|
32
|
+
}
|
|
11
33
|
|
|
12
34
|
async function main() {
|
|
13
35
|
try {
|
|
36
|
+
const cliArgs = process.argv.slice(2);
|
|
37
|
+
const cliCommand = cliArgs[0];
|
|
38
|
+
|
|
39
|
+
if (!cliCommand || CLI_COMMANDS.has(cliCommand)) {
|
|
40
|
+
process.exit(runCli(cliArgs));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const AdapterRegistry = require('../lib/adapters/registry');
|
|
44
|
+
const ClaudeAdapter = require('../lib/adapters/claude-adapter');
|
|
45
|
+
const CodexAdapter = require('../lib/adapters/codex-adapter');
|
|
46
|
+
const { validateConfig, getDefaultConfig } = require('../lib/adapters/config-validator');
|
|
47
|
+
const logger = require('../lib/adapters/logger');
|
|
48
|
+
const fs = require('fs');
|
|
49
|
+
const yaml = require('js-yaml');
|
|
50
|
+
|
|
14
51
|
// 1. Initialize Registry
|
|
15
52
|
const registry = AdapterRegistry.getInstance();
|
|
16
53
|
|