@specpow/framework 0.2.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/CHANGELOG.md +307 -0
- package/LICENSE +21 -0
- package/README.md +557 -0
- package/agents/controller/sdd-controller.md +55 -0
- package/agents/execution/java-codegen-agent.md +39 -0
- package/agents/execution/ui-codegen-agent.md +32 -0
- package/agents/ops/deploy-agent.md +181 -0
- package/agents/planning/db-designer-agent.md +30 -0
- package/agents/planning/prd-agent.md +31 -0
- package/agents/quality/review-agent.md +36 -0
- package/agents/quality/test-agent.md +33 -0
- package/bin/specpow.js +10 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +444 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/apply.d.ts +14 -0
- package/dist/commands/apply.d.ts.map +1 -0
- package/dist/commands/apply.js +195 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/archive.d.ts +30 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +141 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/channel.d.ts +61 -0
- package/dist/commands/channel.d.ts.map +1 -0
- package/dist/commands/channel.js +613 -0
- package/dist/commands/channel.js.map +1 -0
- package/dist/commands/config.d.ts +40 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +130 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/debug.d.ts +45 -0
- package/dist/commands/debug.d.ts.map +1 -0
- package/dist/commands/debug.js +167 -0
- package/dist/commands/debug.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +121 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/execute.d.ts +25 -0
- package/dist/commands/execute.d.ts.map +1 -0
- package/dist/commands/execute.js +120 -0
- package/dist/commands/execute.js.map +1 -0
- package/dist/commands/explore.d.ts +71 -0
- package/dist/commands/explore.d.ts.map +1 -0
- package/dist/commands/explore.js +481 -0
- package/dist/commands/explore.js.map +1 -0
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +146 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/memory.d.ts +32 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +455 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/propose.d.ts +13 -0
- package/dist/commands/propose.d.ts.map +1 -0
- package/dist/commands/propose.js +193 -0
- package/dist/commands/propose.js.map +1 -0
- package/dist/commands/review.d.ts +50 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +198 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/schema.d.ts +22 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +79 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +130 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/store.d.ts +31 -0
- package/dist/commands/store.d.ts.map +1 -0
- package/dist/commands/store.js +109 -0
- package/dist/commands/store.js.map +1 -0
- package/dist/commands/update.d.ts +42 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +239 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +39 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +386 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/workflow/index.d.ts +12 -0
- package/dist/commands/workflow/index.d.ts.map +1 -0
- package/dist/commands/workflow/index.js +435 -0
- package/dist/commands/workflow/index.js.map +1 -0
- package/dist/core/agent-contract.d.ts +133 -0
- package/dist/core/agent-contract.d.ts.map +1 -0
- package/dist/core/agent-contract.js +71 -0
- package/dist/core/agent-contract.js.map +1 -0
- package/dist/core/archive/delta-merger.d.ts +101 -0
- package/dist/core/archive/delta-merger.d.ts.map +1 -0
- package/dist/core/archive/delta-merger.js +398 -0
- package/dist/core/archive/delta-merger.js.map +1 -0
- package/dist/core/archive/delta-parser.d.ts +48 -0
- package/dist/core/archive/delta-parser.d.ts.map +1 -0
- package/dist/core/archive/delta-parser.js +193 -0
- package/dist/core/archive/delta-parser.js.map +1 -0
- package/dist/core/archive/engine.d.ts +136 -0
- package/dist/core/archive/engine.d.ts.map +1 -0
- package/dist/core/archive/engine.js +506 -0
- package/dist/core/archive/engine.js.map +1 -0
- package/dist/core/archive/index.d.ts +11 -0
- package/dist/core/archive/index.d.ts.map +1 -0
- package/dist/core/archive/index.js +9 -0
- package/dist/core/archive/index.js.map +1 -0
- package/dist/core/artifact-graph/graph.d.ts +48 -0
- package/dist/core/artifact-graph/graph.d.ts.map +1 -0
- package/dist/core/artifact-graph/graph.js +170 -0
- package/dist/core/artifact-graph/graph.js.map +1 -0
- package/dist/core/artifact-graph/index.d.ts +13 -0
- package/dist/core/artifact-graph/index.d.ts.map +1 -0
- package/dist/core/artifact-graph/index.js +12 -0
- package/dist/core/artifact-graph/index.js.map +1 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +60 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -0
- package/dist/core/artifact-graph/instruction-loader.js +166 -0
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -0
- package/dist/core/artifact-graph/outputs.d.ts +17 -0
- package/dist/core/artifact-graph/outputs.d.ts.map +1 -0
- package/dist/core/artifact-graph/outputs.js +27 -0
- package/dist/core/artifact-graph/outputs.js.map +1 -0
- package/dist/core/artifact-graph/resolver.d.ts +34 -0
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -0
- package/dist/core/artifact-graph/resolver.js +99 -0
- package/dist/core/artifact-graph/resolver.js.map +1 -0
- package/dist/core/artifact-graph/state.d.ts +54 -0
- package/dist/core/artifact-graph/state.d.ts.map +1 -0
- package/dist/core/artifact-graph/state.js +149 -0
- package/dist/core/artifact-graph/state.js.map +1 -0
- package/dist/core/artifact-graph/types.d.ts +151 -0
- package/dist/core/artifact-graph/types.d.ts.map +1 -0
- package/dist/core/artifact-graph/types.js +44 -0
- package/dist/core/artifact-graph/types.js.map +1 -0
- package/dist/core/channel/channel-event-log.d.ts +81 -0
- package/dist/core/channel/channel-event-log.d.ts.map +1 -0
- package/dist/core/channel/channel-event-log.js +177 -0
- package/dist/core/channel/channel-event-log.js.map +1 -0
- package/dist/core/channel/channel-inbox.d.ts +70 -0
- package/dist/core/channel/channel-inbox.d.ts.map +1 -0
- package/dist/core/channel/channel-inbox.js +122 -0
- package/dist/core/channel/channel-inbox.js.map +1 -0
- package/dist/core/channel/channel-runtime.d.ts +81 -0
- package/dist/core/channel/channel-runtime.d.ts.map +1 -0
- package/dist/core/channel/channel-runtime.js +291 -0
- package/dist/core/channel/channel-runtime.js.map +1 -0
- package/dist/core/channel/channel-supervisor.d.ts +72 -0
- package/dist/core/channel/channel-supervisor.d.ts.map +1 -0
- package/dist/core/channel/channel-supervisor.js +189 -0
- package/dist/core/channel/channel-supervisor.js.map +1 -0
- package/dist/core/channel/channel-types.d.ts +169 -0
- package/dist/core/channel/channel-types.d.ts.map +1 -0
- package/dist/core/channel/channel-types.js +26 -0
- package/dist/core/channel/channel-types.js.map +1 -0
- package/dist/core/channel/index.d.ts +21 -0
- package/dist/core/channel/index.d.ts.map +1 -0
- package/dist/core/channel/index.js +23 -0
- package/dist/core/channel/index.js.map +1 -0
- package/dist/core/command-generation/index.d.ts +225 -0
- package/dist/core/command-generation/index.d.ts.map +1 -0
- package/dist/core/command-generation/index.js +462 -0
- package/dist/core/command-generation/index.js.map +1 -0
- package/dist/core/config/config-schema.d.ts +745 -0
- package/dist/core/config/config-schema.d.ts.map +1 -0
- package/dist/core/config/config-schema.js +108 -0
- package/dist/core/config/config-schema.js.map +1 -0
- package/dist/core/config/global-config.d.ts +73 -0
- package/dist/core/config/global-config.d.ts.map +1 -0
- package/dist/core/config/global-config.js +225 -0
- package/dist/core/config/global-config.js.map +1 -0
- package/dist/core/config/index.d.ts +8 -0
- package/dist/core/config/index.d.ts.map +1 -0
- package/dist/core/config/index.js +8 -0
- package/dist/core/config/index.js.map +1 -0
- package/dist/core/hooks/hook-registry.d.ts +55 -0
- package/dist/core/hooks/hook-registry.d.ts.map +1 -0
- package/dist/core/hooks/hook-registry.js +172 -0
- package/dist/core/hooks/hook-registry.js.map +1 -0
- package/dist/core/hooks/hook-types.d.ts +87 -0
- package/dist/core/hooks/hook-types.d.ts.map +1 -0
- package/dist/core/hooks/hook-types.js +11 -0
- package/dist/core/hooks/hook-types.js.map +1 -0
- package/dist/core/hooks/index.d.ts +28 -0
- package/dist/core/hooks/index.d.ts.map +1 -0
- package/dist/core/hooks/index.js +28 -0
- package/dist/core/hooks/index.js.map +1 -0
- package/dist/core/hooks/post-tool-call-hook.d.ts +21 -0
- package/dist/core/hooks/post-tool-call-hook.d.ts.map +1 -0
- package/dist/core/hooks/post-tool-call-hook.js +191 -0
- package/dist/core/hooks/post-tool-call-hook.js.map +1 -0
- package/dist/core/hooks/pre-tool-call-hook.d.ts +31 -0
- package/dist/core/hooks/pre-tool-call-hook.d.ts.map +1 -0
- package/dist/core/hooks/pre-tool-call-hook.js +122 -0
- package/dist/core/hooks/pre-tool-call-hook.js.map +1 -0
- package/dist/core/hooks/session-start-hook.d.ts +25 -0
- package/dist/core/hooks/session-start-hook.d.ts.map +1 -0
- package/dist/core/hooks/session-start-hook.js +226 -0
- package/dist/core/hooks/session-start-hook.js.map +1 -0
- package/dist/core/hooks/workflow-state-hook.d.ts +18 -0
- package/dist/core/hooks/workflow-state-hook.d.ts.map +1 -0
- package/dist/core/hooks/workflow-state-hook.js +181 -0
- package/dist/core/hooks/workflow-state-hook.js.map +1 -0
- package/dist/core/init/engine.d.ts +69 -0
- package/dist/core/init/engine.d.ts.map +1 -0
- package/dist/core/init/engine.js +211 -0
- package/dist/core/init/engine.js.map +1 -0
- package/dist/core/init/template-hash.d.ts +86 -0
- package/dist/core/init/template-hash.d.ts.map +1 -0
- package/dist/core/init/template-hash.js +228 -0
- package/dist/core/init/template-hash.js.map +1 -0
- package/dist/core/memory/adapters/json-adapter.d.ts +50 -0
- package/dist/core/memory/adapters/json-adapter.d.ts.map +1 -0
- package/dist/core/memory/adapters/json-adapter.js +273 -0
- package/dist/core/memory/adapters/json-adapter.js.map +1 -0
- package/dist/core/memory/adapters/sqlite-adapter.d.ts +26 -0
- package/dist/core/memory/adapters/sqlite-adapter.d.ts.map +1 -0
- package/dist/core/memory/adapters/sqlite-adapter.js +230 -0
- package/dist/core/memory/adapters/sqlite-adapter.js.map +1 -0
- package/dist/core/memory/index.d.ts +38 -0
- package/dist/core/memory/index.d.ts.map +1 -0
- package/dist/core/memory/index.js +40 -0
- package/dist/core/memory/index.js.map +1 -0
- package/dist/core/memory/memory-indexer.d.ts +39 -0
- package/dist/core/memory/memory-indexer.d.ts.map +1 -0
- package/dist/core/memory/memory-indexer.js +213 -0
- package/dist/core/memory/memory-indexer.js.map +1 -0
- package/dist/core/memory/memory-manager.d.ts +59 -0
- package/dist/core/memory/memory-manager.d.ts.map +1 -0
- package/dist/core/memory/memory-manager.js +194 -0
- package/dist/core/memory/memory-manager.js.map +1 -0
- package/dist/core/memory/memory-store.d.ts +31 -0
- package/dist/core/memory/memory-store.d.ts.map +1 -0
- package/dist/core/memory/memory-store.js +148 -0
- package/dist/core/memory/memory-store.js.map +1 -0
- package/dist/core/memory/memory-types.d.ts +154 -0
- package/dist/core/memory/memory-types.d.ts.map +1 -0
- package/dist/core/memory/memory-types.js +13 -0
- package/dist/core/memory/memory-types.js.map +1 -0
- package/dist/core/migration/index.d.ts +80 -0
- package/dist/core/migration/index.d.ts.map +1 -0
- package/dist/core/migration/index.js +361 -0
- package/dist/core/migration/index.js.map +1 -0
- package/dist/core/parsers/index.d.ts +95 -0
- package/dist/core/parsers/index.d.ts.map +1 -0
- package/dist/core/parsers/index.js +367 -0
- package/dist/core/parsers/index.js.map +1 -0
- package/dist/core/sdd-engine/ai-caller.d.ts +118 -0
- package/dist/core/sdd-engine/ai-caller.d.ts.map +1 -0
- package/dist/core/sdd-engine/ai-caller.js +624 -0
- package/dist/core/sdd-engine/ai-caller.js.map +1 -0
- package/dist/core/sdd-engine/controller.d.ts +107 -0
- package/dist/core/sdd-engine/controller.d.ts.map +1 -0
- package/dist/core/sdd-engine/controller.js +357 -0
- package/dist/core/sdd-engine/controller.js.map +1 -0
- package/dist/core/sdd-engine/dispatcher.d.ts +69 -0
- package/dist/core/sdd-engine/dispatcher.d.ts.map +1 -0
- package/dist/core/sdd-engine/dispatcher.js +146 -0
- package/dist/core/sdd-engine/dispatcher.js.map +1 -0
- package/dist/core/sdd-engine/git-ops.d.ts +73 -0
- package/dist/core/sdd-engine/git-ops.d.ts.map +1 -0
- package/dist/core/sdd-engine/git-ops.js +326 -0
- package/dist/core/sdd-engine/git-ops.js.map +1 -0
- package/dist/core/sdd-engine/index.d.ts +17 -0
- package/dist/core/sdd-engine/index.d.ts.map +1 -0
- package/dist/core/sdd-engine/index.js +15 -0
- package/dist/core/sdd-engine/index.js.map +1 -0
- package/dist/core/sdd-engine/ledger.d.ts +92 -0
- package/dist/core/sdd-engine/ledger.d.ts.map +1 -0
- package/dist/core/sdd-engine/ledger.js +273 -0
- package/dist/core/sdd-engine/ledger.js.map +1 -0
- package/dist/core/sdd-engine/model-selector.d.ts +49 -0
- package/dist/core/sdd-engine/model-selector.d.ts.map +1 -0
- package/dist/core/sdd-engine/model-selector.js +76 -0
- package/dist/core/sdd-engine/model-selector.js.map +1 -0
- package/dist/core/sdd-engine/parallel-dispatcher.d.ts +99 -0
- package/dist/core/sdd-engine/parallel-dispatcher.d.ts.map +1 -0
- package/dist/core/sdd-engine/parallel-dispatcher.js +350 -0
- package/dist/core/sdd-engine/parallel-dispatcher.js.map +1 -0
- package/dist/core/sdd-engine/review-loop.d.ts +61 -0
- package/dist/core/sdd-engine/review-loop.d.ts.map +1 -0
- package/dist/core/sdd-engine/review-loop.js +139 -0
- package/dist/core/sdd-engine/review-loop.js.map +1 -0
- package/dist/core/sdd-engine/types.d.ts +104 -0
- package/dist/core/sdd-engine/types.d.ts.map +1 -0
- package/dist/core/sdd-engine/types.js +7 -0
- package/dist/core/sdd-engine/types.js.map +1 -0
- package/dist/core/store/index.d.ts +78 -0
- package/dist/core/store/index.d.ts.map +1 -0
- package/dist/core/store/index.js +182 -0
- package/dist/core/store/index.js.map +1 -0
- package/dist/core/templates/index.d.ts +58 -0
- package/dist/core/templates/index.d.ts.map +1 -0
- package/dist/core/templates/index.js +158 -0
- package/dist/core/templates/index.js.map +1 -0
- package/dist/core/validation/index.d.ts +34 -0
- package/dist/core/validation/index.d.ts.map +1 -0
- package/dist/core/validation/index.js +153 -0
- package/dist/core/validation/index.js.map +1 -0
- package/dist/core/workflow-state.d.ts +96 -0
- package/dist/core/workflow-state.d.ts.map +1 -0
- package/dist/core/workflow-state.js +284 -0
- package/dist/core/workflow-state.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/index.d.ts +48 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +119 -0
- package/dist/utils/index.js.map +1 -0
- package/hooks/hooks.json +30 -0
- package/hooks/run-hook.cmd +19 -0
- package/hooks/session-start +62 -0
- package/hooks/workflow-state +150 -0
- package/package.json +122 -0
- package/schemas/bug-fix/schema.yaml +64 -0
- package/schemas/bug-fix/templates/analysis.md +43 -0
- package/schemas/bug-fix/templates/fix-plan.md +19 -0
- package/schemas/bug-fix/templates/proposal.md +30 -0
- package/schemas/crud-module/schema.yaml +65 -0
- package/schemas/crud-module/templates/design.md +36 -0
- package/schemas/crud-module/templates/proposal.md +30 -0
- package/schemas/crud-module/templates/spec.md +33 -0
- package/schemas/crud-module/templates/tasks.md +57 -0
- package/schemas/spec-driven/schema.yaml +87 -0
- package/schemas/spec-driven/templates/design.md +54 -0
- package/schemas/spec-driven/templates/proposal.md +31 -0
- package/schemas/spec-driven/templates/spec.md +44 -0
- package/schemas/spec-driven/templates/tasks.md +98 -0
- package/skills/business-code-review/SKILL.md +78 -0
- package/skills/business-db-design/SKILL.md +74 -0
- package/skills/business-deploy-check/SKILL.md +72 -0
- package/skills/business-doc-sync/SKILL.md +72 -0
- package/skills/business-java-codegen/SKILL.md +97 -0
- package/skills/business-menu-register/SKILL.md +63 -0
- package/skills/business-prd-writer/SKILL.md +80 -0
- package/skills/business-test-gen/SKILL.md +82 -0
- package/skills/business-ui-codegen/SKILL.md +104 -0
- package/skills/execution-finish-branch/SKILL.md +58 -0
- package/skills/execution-git-worktrees/SKILL.md +48 -0
- package/skills/execution-parallel-agents/SKILL.md +51 -0
- package/skills/execution-receiving-review/SKILL.md +47 -0
- package/skills/execution-requesting-review/SKILL.md +51 -0
- package/skills/execution-subagent-driven-dev/SKILL.md +148 -0
- package/skills/execution-systematic-debugging/SKILL.md +95 -0
- package/skills/execution-tdd/SKILL.md +74 -0
- package/skills/execution-verification-before-completion/SKILL.md +75 -0
- package/skills/meta-create-skill/SKILL.md +374 -0
- package/skills/meta-using-skills/SKILL.md +97 -0
- package/skills/meta-writing-skills/SKILL.md +66 -0
- package/skills/planning-apply-change/SKILL.md +199 -0
- package/skills/planning-archive-change/SKILL.md +43 -0
- package/skills/planning-explore/SKILL.md +108 -0
- package/skills/planning-onboard/SKILL.md +60 -0
- package/skills/planning-propose/SKILL.md +145 -0
- package/skills/planning-update-change/SKILL.md +45 -0
- package/skills/planning-verify-change/SKILL.md +58 -0
- package/skills/planning-write-design/SKILL.md +59 -0
- package/skills/planning-write-plans/SKILL.md +55 -0
- package/skills/planning-write-specs/SKILL.md +73 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 并行代理分发器
|
|
3
|
+
*
|
|
4
|
+
* 来自 Superpowers 的并行执行策略:
|
|
5
|
+
* 当任务之间无依赖关系时,同时分发多个子代理并行执行。
|
|
6
|
+
*
|
|
7
|
+
* 适用场景:
|
|
8
|
+
* - 3+ 个独立测试失败(不同测试文件,无共享依赖)
|
|
9
|
+
* - 多个子系统独立损坏
|
|
10
|
+
* - 多文件非依赖变更
|
|
11
|
+
*
|
|
12
|
+
* 核心原则:
|
|
13
|
+
* - 每个代理获得聚焦范围 + 明确约束 + 具体输出要求
|
|
14
|
+
* - 通过依赖图分析识别可并行的任务
|
|
15
|
+
* - 集成阶段:审查摘要 → 冲突检查 → 全量套件
|
|
16
|
+
*
|
|
17
|
+
* 并行隔离策略(修复 P0-2):
|
|
18
|
+
* - 每个任务在独立的 Git worktree 中执行
|
|
19
|
+
* - worktree 拥有独立的 HEAD / 工作目录,消除竞态条件
|
|
20
|
+
* - 所有任务完成后按序合并分支到主分支
|
|
21
|
+
* - 合并冲突作为并行代价显式报告,而非静默丢失
|
|
22
|
+
*
|
|
23
|
+
* @experimental 此模块实现完整但尚未集成到任何 CLI 命令中。
|
|
24
|
+
* 建议在未来版本中为 `specpow apply` 添加 `--parallel` 选项以启用此功能。
|
|
25
|
+
* 集成前需要:
|
|
26
|
+
* 1. 在 CLI 命令入口添加并行模式开关
|
|
27
|
+
* 2. 配置 worktree 合并策略
|
|
28
|
+
* 3. 添加并行执行的日志和进度报告
|
|
29
|
+
*/
|
|
30
|
+
import { AICaller } from './ai-caller.js';
|
|
31
|
+
import { getHeadCommit, getChangedFiles, createWorktree, removeWorktree, mergeBranch, deleteBranch, } from './git-ops.js';
|
|
32
|
+
import { join } from 'path';
|
|
33
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
34
|
+
/**
|
|
35
|
+
* 分析任务依赖关系
|
|
36
|
+
*
|
|
37
|
+
* 基于两个维度判断:
|
|
38
|
+
* 1. 文件级:不同任务是否修改相同文件
|
|
39
|
+
* 2. 逻辑级:解析 tasks.md 中显式声明的依赖
|
|
40
|
+
*/
|
|
41
|
+
export function analyzeDependencies(tasks) {
|
|
42
|
+
const deps = [];
|
|
43
|
+
// 收集所有任务涉及的文件
|
|
44
|
+
const fileOwners = new Map();
|
|
45
|
+
for (const task of tasks) {
|
|
46
|
+
for (const file of task.files) {
|
|
47
|
+
if (!fileOwners.has(file)) {
|
|
48
|
+
fileOwners.set(file, []);
|
|
49
|
+
}
|
|
50
|
+
fileOwners.get(file).push(task.number);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// 分析:共享文件的任务有顺序依赖
|
|
54
|
+
for (const task of tasks) {
|
|
55
|
+
const taskDeps = new Set();
|
|
56
|
+
for (const file of task.files) {
|
|
57
|
+
const owners = fileOwners.get(file) || [];
|
|
58
|
+
for (const owner of owners) {
|
|
59
|
+
if (owner < task.number) {
|
|
60
|
+
// 之前的任务修改了相同文件 → 依赖
|
|
61
|
+
taskDeps.add(owner);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
deps.push({
|
|
66
|
+
taskNumber: task.number,
|
|
67
|
+
dependsOn: [...taskDeps].sort(),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return deps;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 构建任务依赖图(拓扑排序)
|
|
74
|
+
*
|
|
75
|
+
* 返回可并行执行的层:
|
|
76
|
+
* 每层中的任务彼此独立,可以同时分发
|
|
77
|
+
*/
|
|
78
|
+
export function buildParallelLayers(tasks) {
|
|
79
|
+
if (tasks.length === 0)
|
|
80
|
+
return [];
|
|
81
|
+
const deps = analyzeDependencies(tasks);
|
|
82
|
+
const layers = [];
|
|
83
|
+
const completed = new Set();
|
|
84
|
+
const remaining = new Set(tasks.map(t => t.number));
|
|
85
|
+
while (remaining.size > 0) {
|
|
86
|
+
const currentLayer = [];
|
|
87
|
+
for (const taskNumber of remaining) {
|
|
88
|
+
const dep = deps.find(d => d.taskNumber === taskNumber);
|
|
89
|
+
const allDepsMet = dep
|
|
90
|
+
? dep.dependsOn.every(d => completed.has(d))
|
|
91
|
+
: true;
|
|
92
|
+
if (allDepsMet) {
|
|
93
|
+
const task = tasks.find(t => t.number === taskNumber);
|
|
94
|
+
if (task) {
|
|
95
|
+
currentLayer.push(task);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (currentLayer.length === 0) {
|
|
100
|
+
// 循环依赖或分析错误——剩余任务全部放入最后一层
|
|
101
|
+
for (const taskNumber of remaining) {
|
|
102
|
+
const task = tasks.find(t => t.number === taskNumber);
|
|
103
|
+
if (task)
|
|
104
|
+
currentLayer.push(task);
|
|
105
|
+
}
|
|
106
|
+
layers.push(currentLayer);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
for (const task of currentLayer) {
|
|
110
|
+
completed.add(task.number);
|
|
111
|
+
remaining.delete(task.number);
|
|
112
|
+
}
|
|
113
|
+
layers.push(currentLayer);
|
|
114
|
+
}
|
|
115
|
+
return layers;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 并行分发执行器
|
|
119
|
+
*
|
|
120
|
+
* 每个任务在独立的 Git worktree 中执行,消除并行竞态条件。
|
|
121
|
+
* 完成后按序将各分支合并回主分支。
|
|
122
|
+
*/
|
|
123
|
+
export class ParallelDispatcher {
|
|
124
|
+
aiCaller;
|
|
125
|
+
workspaceDir;
|
|
126
|
+
specConstraints;
|
|
127
|
+
constructor(config) {
|
|
128
|
+
this.aiCaller = new AICaller(config.workspaceDir);
|
|
129
|
+
this.workspaceDir = config.workspaceDir;
|
|
130
|
+
this.specConstraints = config.specConstraints;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 并行分发生成层
|
|
134
|
+
*
|
|
135
|
+
* 一层中的所有任务彼此独立:
|
|
136
|
+
* 1. 为每个任务创建独立 worktree
|
|
137
|
+
* 2. 在各自 worktree 中并行执行实现 + 审查
|
|
138
|
+
* 3. 所有任务完成后按序合并分支
|
|
139
|
+
* 4. 清理 worktree
|
|
140
|
+
*/
|
|
141
|
+
async dispatchLayer(tasks, projectContext) {
|
|
142
|
+
const results = [];
|
|
143
|
+
const conflicts = [];
|
|
144
|
+
const mergeFailures = [];
|
|
145
|
+
const worktrees = [];
|
|
146
|
+
// 记录主分支当前 HEAD(所有 worktree 基于此创建)
|
|
147
|
+
const mainBaseCommit = getHeadCommit();
|
|
148
|
+
// ── 阶段 1:为每个任务创建 worktree ──
|
|
149
|
+
for (const task of tasks) {
|
|
150
|
+
const branchName = `specpow-parallel-${task.number}-${Date.now().toString(36)}`;
|
|
151
|
+
const worktreePath = join(this.workspaceDir, '.worktrees', `task-${task.number}`);
|
|
152
|
+
try {
|
|
153
|
+
// 确保 worktree 父目录存在
|
|
154
|
+
const wtParent = join(this.workspaceDir, '.worktrees');
|
|
155
|
+
if (!existsSync(wtParent)) {
|
|
156
|
+
mkdirSync(wtParent, { recursive: true });
|
|
157
|
+
}
|
|
158
|
+
createWorktree(branchName, worktreePath);
|
|
159
|
+
worktrees.push({ task, branchName, worktreePath, baseCommit: mainBaseCommit });
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
// worktree 创建失败 → 该任务标记为 blocked
|
|
163
|
+
results.push({
|
|
164
|
+
taskNumber: task.number,
|
|
165
|
+
outcome: 'blocked',
|
|
166
|
+
report: {
|
|
167
|
+
status: 'blocked',
|
|
168
|
+
commits: [],
|
|
169
|
+
testSummary: `Worktree creation failed: ${err.message}`,
|
|
170
|
+
concerns: err.message,
|
|
171
|
+
},
|
|
172
|
+
review: { specCompliant: false, qualityApproved: false, findings: [], cannotVerify: [] },
|
|
173
|
+
commitRange: '',
|
|
174
|
+
branchName: '',
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ── 阶段 2:在各自 worktree 中并行执行 ──
|
|
179
|
+
const promises = worktrees.map(async (wt) => {
|
|
180
|
+
const brief = this.createBrief(wt.task, wt.worktreePath, wt.branchName);
|
|
181
|
+
// 在 worktree 中获取该分支的 HEAD(= mainBaseCommit,因为刚从 main 创建)
|
|
182
|
+
const baseCommit = getHeadCommit(wt.worktreePath);
|
|
183
|
+
// 分发实现者(cwd = worktree → AI 在 worktree 中工作并提交)
|
|
184
|
+
const report = await this.aiCaller.dispatchImplementer(brief, projectContext, this.specConstraints, undefined);
|
|
185
|
+
if (report.status === 'blocked') {
|
|
186
|
+
return {
|
|
187
|
+
taskNumber: wt.task.number,
|
|
188
|
+
outcome: 'blocked',
|
|
189
|
+
report,
|
|
190
|
+
review: { specCompliant: false, qualityApproved: false, findings: [], cannotVerify: [] },
|
|
191
|
+
commitRange: '',
|
|
192
|
+
branchName: wt.branchName,
|
|
193
|
+
worktreePath: wt.worktreePath,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// 审查(cwd = worktree → git diff 在该 worktree 的分支上执行)
|
|
197
|
+
const review = await this.aiCaller.dispatchReviewer(brief, projectContext, this.specConstraints, baseCommit, 'HEAD');
|
|
198
|
+
const headCommit = getHeadCommit(wt.worktreePath);
|
|
199
|
+
return {
|
|
200
|
+
taskNumber: wt.task.number,
|
|
201
|
+
outcome: 'complete',
|
|
202
|
+
report,
|
|
203
|
+
review,
|
|
204
|
+
commitRange: `${baseCommit.slice(0, 7)}..${headCommit.slice(0, 7)}`,
|
|
205
|
+
branchName: wt.branchName,
|
|
206
|
+
worktreePath: wt.worktreePath,
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
// 等待所有并行任务完成
|
|
210
|
+
const settled = await Promise.allSettled(promises);
|
|
211
|
+
for (const result of settled) {
|
|
212
|
+
if (result.status === 'fulfilled') {
|
|
213
|
+
results.push(result.value);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// P2-12: rejected promise 也需要加入 results,让调用方知道任务失败
|
|
217
|
+
console.error(` ✗ 并行任务失败: ${result.reason}`);
|
|
218
|
+
results.push({
|
|
219
|
+
taskNumber: 0, // 无法确定任务号
|
|
220
|
+
outcome: 'blocked',
|
|
221
|
+
report: {
|
|
222
|
+
status: 'blocked',
|
|
223
|
+
commits: [],
|
|
224
|
+
testSummary: `Promise rejected: ${result.reason}`,
|
|
225
|
+
concerns: String(result.reason),
|
|
226
|
+
},
|
|
227
|
+
review: { specCompliant: false, qualityApproved: false, findings: [], cannotVerify: [] },
|
|
228
|
+
commitRange: '',
|
|
229
|
+
branchName: '',
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// ── 阶段 3:按序合并完成的分支到主分支 ──
|
|
234
|
+
for (const result of results) {
|
|
235
|
+
if (result.outcome !== 'complete' || !result.branchName)
|
|
236
|
+
continue;
|
|
237
|
+
const mergeResult = mergeBranch(result.branchName);
|
|
238
|
+
if (mergeResult.conflict) {
|
|
239
|
+
mergeFailures.push(result.taskNumber);
|
|
240
|
+
console.error(` ✗ 任务 ${result.taskNumber} 分支合并冲突: ${result.branchName}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// ── 阶段 4:冲突检测(在 worktree 删除前执行,P2-11) ──
|
|
244
|
+
// 检查哪些文件被多个任务修改
|
|
245
|
+
const fileTaskMap = new Map();
|
|
246
|
+
for (const result of results) {
|
|
247
|
+
if (result.outcome === 'complete' && result.commitRange && result.worktreePath) {
|
|
248
|
+
const [base, head] = result.commitRange.split('..');
|
|
249
|
+
const files = getChangedFiles(base, head, result.worktreePath);
|
|
250
|
+
for (const file of files) {
|
|
251
|
+
if (!fileTaskMap.has(file)) {
|
|
252
|
+
fileTaskMap.set(file, []);
|
|
253
|
+
}
|
|
254
|
+
fileTaskMap.get(file).push(result.taskNumber);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
for (const [file, taskNumbers] of fileTaskMap) {
|
|
259
|
+
if (taskNumbers.length > 1) {
|
|
260
|
+
conflicts.push(`${file} (tasks: ${taskNumbers.join(', ')})`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// ── 阶段 5:清理 worktree 和分支 ──
|
|
264
|
+
for (const wt of worktrees) {
|
|
265
|
+
try {
|
|
266
|
+
removeWorktree(wt.worktreePath, true);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// worktree 清理失败不应阻塞流程
|
|
270
|
+
}
|
|
271
|
+
// P2-13: deleteBranch 需要 try/catch,避免中断清理循环
|
|
272
|
+
try {
|
|
273
|
+
deleteBranch(wt.branchName);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// 分支可能未合并或已删除,忽略
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
success: conflicts.length === 0 && mergeFailures.length === 0,
|
|
281
|
+
results,
|
|
282
|
+
conflicts,
|
|
283
|
+
mergeFailures,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* 全图并行执行
|
|
288
|
+
*
|
|
289
|
+
* 按层顺序执行,每层内部并行分发
|
|
290
|
+
* 层与层之间是串行的(前一层合并完成后才开始下一层)
|
|
291
|
+
*/
|
|
292
|
+
async dispatchAll(tasks, projectContext) {
|
|
293
|
+
const layers = buildParallelLayers(tasks);
|
|
294
|
+
const allResults = [];
|
|
295
|
+
const allConflicts = [];
|
|
296
|
+
const allMergeFailures = [];
|
|
297
|
+
console.log(` 📊 依赖分析: ${tasks.length} 个任务 → ${layers.length} 层`);
|
|
298
|
+
for (let i = 0; i < layers.length; i++) {
|
|
299
|
+
console.log(` 🏗 第 ${i + 1}/${layers.length} 层: ${layers[i].map(t => t.title).join(', ')}`);
|
|
300
|
+
}
|
|
301
|
+
for (let i = 0; i < layers.length; i++) {
|
|
302
|
+
const layer = layers[i];
|
|
303
|
+
console.log(`\n ⚡ 并行分发第 ${i + 1} 层 (${layer.length} 个任务)...`);
|
|
304
|
+
const layerResult = await this.dispatchLayer(layer, projectContext);
|
|
305
|
+
allResults.push(...layerResult.results);
|
|
306
|
+
allConflicts.push(...layerResult.conflicts);
|
|
307
|
+
allMergeFailures.push(...layerResult.mergeFailures);
|
|
308
|
+
if (layerResult.conflicts.length > 0) {
|
|
309
|
+
console.log(` ⚠ 检测到冲突文件: ${layerResult.conflicts.join(', ')}`);
|
|
310
|
+
}
|
|
311
|
+
if (layerResult.mergeFailures.length > 0) {
|
|
312
|
+
console.log(` ⚠ 合并失败任务: ${layerResult.mergeFailures.join(', ')}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
success: allConflicts.length === 0 && allMergeFailures.length === 0,
|
|
317
|
+
results: allResults,
|
|
318
|
+
conflicts: allConflicts,
|
|
319
|
+
mergeFailures: allMergeFailures,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* 创建任务简报,包含 worktree 路径和工作目录指令
|
|
324
|
+
*/
|
|
325
|
+
createBrief(task, worktreePath, branchName) {
|
|
326
|
+
return {
|
|
327
|
+
taskNumber: task.number,
|
|
328
|
+
title: task.title,
|
|
329
|
+
description: [
|
|
330
|
+
task.description,
|
|
331
|
+
'',
|
|
332
|
+
`## 并行执行指令`,
|
|
333
|
+
``,
|
|
334
|
+
`你正在独立的 Git worktree 中工作。`,
|
|
335
|
+
`- **工作目录**: \`${worktreePath}\``,
|
|
336
|
+
`- **分支**: \`${branchName}\``,
|
|
337
|
+
``,
|
|
338
|
+
`**重要**:`,
|
|
339
|
+
`- 所有文件编辑操作必须在 \`${worktreePath}\` 中执行`,
|
|
340
|
+
`- 所有 git add / git commit 必须在 \`${worktreePath}\` 目录中执行`,
|
|
341
|
+
`- 不要修改主工作目录中的任何文件`,
|
|
342
|
+
].join('\n'),
|
|
343
|
+
files: task.files,
|
|
344
|
+
briefPath: join(worktreePath, `..`, `task-${task.number}-brief.md`),
|
|
345
|
+
reportPath: join(worktreePath, `..`, `task-${task.number}-report.md`),
|
|
346
|
+
worktreePath,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=parallel-dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel-dispatcher.js","sourceRoot":"","sources":["../../../src/core/sdd-engine/parallel-dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审查循环
|
|
3
|
+
*
|
|
4
|
+
* 管理任务审查和修复循环:
|
|
5
|
+
* 1. 任务审查(规范合规 + 代码质量)
|
|
6
|
+
* 2. 修复循环(最多5轮)
|
|
7
|
+
* 3. 断路器(第5轮后裁定)
|
|
8
|
+
*
|
|
9
|
+
* 关键原则:
|
|
10
|
+
* - 每轮修复后必须做范围限定的重新审查
|
|
11
|
+
* - 次要发现不进入循环,记录到账本延迟处理
|
|
12
|
+
* - 控制器不自己修复(保持上下文干净)
|
|
13
|
+
*/
|
|
14
|
+
import type { Finding, ReviewResult, FixRoundRecord } from './types.js';
|
|
15
|
+
export type LoopDecision = {
|
|
16
|
+
type: 'pass';
|
|
17
|
+
} | {
|
|
18
|
+
type: 'fix';
|
|
19
|
+
findings: Finding[];
|
|
20
|
+
} | {
|
|
21
|
+
type: 'adjudicate';
|
|
22
|
+
findings: Finding[];
|
|
23
|
+
} | {
|
|
24
|
+
type: 'blocked';
|
|
25
|
+
reason: string;
|
|
26
|
+
};
|
|
27
|
+
export declare class ReviewLoop {
|
|
28
|
+
private maxRounds;
|
|
29
|
+
constructor(maxRounds?: number);
|
|
30
|
+
/**
|
|
31
|
+
* 分析审查结果,决定下一步行动
|
|
32
|
+
*
|
|
33
|
+
* @param review - 审查结果
|
|
34
|
+
* @param currentRound - 当前修复轮次
|
|
35
|
+
* @param testsPassed - 测试是否全部通过(TDD GREEN 门控,默认 true)
|
|
36
|
+
*/
|
|
37
|
+
analyzeReview(review: ReviewResult, currentRound: number, testsPassed?: boolean): LoopDecision;
|
|
38
|
+
/**
|
|
39
|
+
* 创建修复轮次记录
|
|
40
|
+
*/
|
|
41
|
+
createFixRecord(round: number, addressed: number, open: number, findingSummaries: string[], commits: string): FixRoundRecord;
|
|
42
|
+
/**
|
|
43
|
+
* 裁定开放发现
|
|
44
|
+
*
|
|
45
|
+
* 三种裁定结果:
|
|
46
|
+
* 1. 审查者错了/有争议 → 停放(代码保留)
|
|
47
|
+
* 2. 真实但无下游依赖 → 停放(延迟修复)
|
|
48
|
+
* 3. 真实且承重 → 阻塞
|
|
49
|
+
*/
|
|
50
|
+
adjudicateFinding(finding: Finding, _planContext: string): {
|
|
51
|
+
action: 'park' | 'block';
|
|
52
|
+
ruling: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* 构建范围限定的重新审查 prompt
|
|
56
|
+
*
|
|
57
|
+
* 关键:只审查修复 diff,不重新审查整个任务
|
|
58
|
+
*/
|
|
59
|
+
buildReReviewPrompt(fixDiffPath: string, openFindings: Finding[], briefPath: string, reportPath: string): string;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=review-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-loop.d.ts","sourceRoot":"","sources":["../../../src/core/sdd-engine/review-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,GAAE,MAAU;IAIjC;;;;;;OAMG;IACH,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAE,OAAc,GAAG,YAAY;IA2EpG;;OAEG;IACH,eAAe,CACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EAAE,EAC1B,OAAO,EAAE,MAAM,GACd,cAAc;IAIjB;;;;;;;OAOG;IACH,iBAAiB,CACf,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,MAAM,GACnB;QAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAgB/C;;;;OAIG;IACH,mBAAmB,CACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,OAAO,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM;CAaV"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审查循环
|
|
3
|
+
*
|
|
4
|
+
* 管理任务审查和修复循环:
|
|
5
|
+
* 1. 任务审查(规范合规 + 代码质量)
|
|
6
|
+
* 2. 修复循环(最多5轮)
|
|
7
|
+
* 3. 断路器(第5轮后裁定)
|
|
8
|
+
*
|
|
9
|
+
* 关键原则:
|
|
10
|
+
* - 每轮修复后必须做范围限定的重新审查
|
|
11
|
+
* - 次要发现不进入循环,记录到账本延迟处理
|
|
12
|
+
* - 控制器不自己修复(保持上下文干净)
|
|
13
|
+
*/
|
|
14
|
+
export class ReviewLoop {
|
|
15
|
+
maxRounds;
|
|
16
|
+
constructor(maxRounds = 5) {
|
|
17
|
+
this.maxRounds = maxRounds;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 分析审查结果,决定下一步行动
|
|
21
|
+
*
|
|
22
|
+
* @param review - 审查结果
|
|
23
|
+
* @param currentRound - 当前修复轮次
|
|
24
|
+
* @param testsPassed - 测试是否全部通过(TDD GREEN 门控,默认 true)
|
|
25
|
+
*/
|
|
26
|
+
analyzeReview(review, currentRound, testsPassed = true) {
|
|
27
|
+
// ========== TDD 门控:测试必须全部通过 ==========
|
|
28
|
+
if (!testsPassed) {
|
|
29
|
+
if (currentRound >= this.maxRounds) {
|
|
30
|
+
return {
|
|
31
|
+
type: 'blocked',
|
|
32
|
+
reason: `Tests still failing after ${this.maxRounds} rounds — GREEN not confirmed`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
type: 'fix',
|
|
37
|
+
findings: [{
|
|
38
|
+
id: 'TDD-GREEN',
|
|
39
|
+
severity: 'critical',
|
|
40
|
+
description: 'Tests not passing — RED-GREEN-REFACTOR: GREEN phase not confirmed',
|
|
41
|
+
file: '',
|
|
42
|
+
addressed: false,
|
|
43
|
+
isLoadBearing: true,
|
|
44
|
+
}],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ================================================
|
|
48
|
+
// 审查通过
|
|
49
|
+
if (review.specCompliant && review.qualityApproved && review.findings.length === 0) {
|
|
50
|
+
return { type: 'pass' };
|
|
51
|
+
}
|
|
52
|
+
// 分离不同级别的发现
|
|
53
|
+
const criticalFindings = review.findings.filter(f => f.severity === 'critical' && !f.addressed);
|
|
54
|
+
const importantFindings = review.findings.filter(f => f.severity === 'important' && !f.addressed);
|
|
55
|
+
// minor findings are deferred — they don't enter the loop
|
|
56
|
+
const specFailures = !review.specCompliant;
|
|
57
|
+
// 次要发现不进入循环
|
|
58
|
+
// (由控制器记录到账本,延迟到最终审查处理)
|
|
59
|
+
// 需要进入循环的发现
|
|
60
|
+
const loopFindings = [...criticalFindings, ...importantFindings];
|
|
61
|
+
// 规范不合规也进入循环
|
|
62
|
+
if (specFailures || loopFindings.length > 0) {
|
|
63
|
+
// 断路器检查
|
|
64
|
+
if (currentRound >= this.maxRounds) {
|
|
65
|
+
// 检查是否有承重发现
|
|
66
|
+
const loadBearing = loopFindings.filter(f => f.isLoadBearing);
|
|
67
|
+
if (loadBearing.length > 0) {
|
|
68
|
+
return {
|
|
69
|
+
type: 'blocked',
|
|
70
|
+
reason: `Load-bearing findings after ${this.maxRounds} rounds: ${loadBearing.map(f => f.description).join('; ')}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// 非承重的,交给控制器裁定
|
|
74
|
+
return { type: 'adjudicate', findings: loopFindings };
|
|
75
|
+
}
|
|
76
|
+
// 当 specFailures 为 true 但 loopFindings 为空时,
|
|
77
|
+
// 添加一个通用的规范合规发现,给 implementer 修复指引
|
|
78
|
+
const specFinding = (specFailures && loopFindings.length === 0)
|
|
79
|
+
? [{
|
|
80
|
+
id: 'SPEC-FAIL',
|
|
81
|
+
severity: 'critical',
|
|
82
|
+
description: 'Implementation is not spec-compliant — review the task brief and spec requirements, then fix the gaps.',
|
|
83
|
+
file: '',
|
|
84
|
+
addressed: false,
|
|
85
|
+
isLoadBearing: true,
|
|
86
|
+
}]
|
|
87
|
+
: [];
|
|
88
|
+
return { type: 'fix', findings: [...loopFindings, ...specFinding] };
|
|
89
|
+
}
|
|
90
|
+
return { type: 'pass' };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 创建修复轮次记录
|
|
94
|
+
*/
|
|
95
|
+
createFixRecord(round, addressed, open, findingSummaries, commits) {
|
|
96
|
+
return { round, addressed, open, findingSummaries, commits };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 裁定开放发现
|
|
100
|
+
*
|
|
101
|
+
* 三种裁定结果:
|
|
102
|
+
* 1. 审查者错了/有争议 → 停放(代码保留)
|
|
103
|
+
* 2. 真实但无下游依赖 → 停放(延迟修复)
|
|
104
|
+
* 3. 真实且承重 → 阻塞
|
|
105
|
+
*/
|
|
106
|
+
adjudicateFinding(finding, _planContext) {
|
|
107
|
+
// 检查发现是否与计划文本冲突
|
|
108
|
+
if (finding.isLoadBearing) {
|
|
109
|
+
return {
|
|
110
|
+
action: 'block',
|
|
111
|
+
ruling: `Load-bearing: ${finding.description}. Later tasks depend on this.`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
// 非承重的,停放并记录裁定
|
|
115
|
+
return {
|
|
116
|
+
action: 'park',
|
|
117
|
+
ruling: `Real but deferred: ${finding.description}. No downstream dependency.`,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 构建范围限定的重新审查 prompt
|
|
122
|
+
*
|
|
123
|
+
* 关键:只审查修复 diff,不重新审查整个任务
|
|
124
|
+
*/
|
|
125
|
+
buildReReviewPrompt(fixDiffPath, openFindings, briefPath, reportPath) {
|
|
126
|
+
return [
|
|
127
|
+
`Scoped re-review. Only examine the fix diff at: ${fixDiffPath}`,
|
|
128
|
+
`Open findings to verify:`,
|
|
129
|
+
...openFindings.map((f, i) => ` ${i + 1}. [${f.severity}] ${f.description}`),
|
|
130
|
+
``,
|
|
131
|
+
`Brief: ${briefPath}`,
|
|
132
|
+
`Report: ${reportPath}`,
|
|
133
|
+
``,
|
|
134
|
+
`For each finding, verdict: ADDRESSED or NOT ADDRESSED.`,
|
|
135
|
+
`Flag new breakage in the fix diff only. Out-of-scope observations → deferred minors.`,
|
|
136
|
+
].join('\n');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=review-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-loop.js","sourceRoot":"","sources":["../../../src/core/sdd-engine/review-loop.ts"],"names":[],"mappings":"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"}
|