sillyspec 3.27.11 → 3.28.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/.claude/skills/sillyspec-execute/SKILL.md +1 -1
- package/README.md +3 -2
- package/package.json +1 -1
- package/src/agent-session-log.js +77 -10
- package/src/change-delete.js +181 -0
- package/src/config-schema.js +2 -2
- package/src/contract-matrix.js +15 -2
- package/src/docs-check.js +126 -0
- package/src/doctor-diagnostics.js +64 -1
- package/src/endpoint-extractor.js +107 -28
- package/src/index.js +208 -13
- package/src/init.js +104 -27
- package/src/machine-interface.js +63 -0
- package/src/module-changelog.js +116 -0
- package/src/progress/change-registry.js +28 -0
- package/src/progress/shared.js +6 -0
- package/src/progress/stage-machine.js +191 -9
- package/src/progress.js +6 -0
- package/src/run/command.js +26 -1
- package/src/run/complete-handlers.js +42 -4
- package/src/run/complete.js +12 -4
- package/src/run/prompt.js +12 -1
- package/src/run/quick-audit.js +98 -0
- package/src/run/shared.js +86 -0
- package/src/run/stage.js +18 -11
- package/src/spec-sync.js +191 -14
- package/src/stages/archive.js +5 -0
- package/src/stages/execute.js +7 -2
- package/src/sync.js +575 -21
- package/src/task-review.js +51 -4
- package/src/verify-postcheck.js +60 -8
- package/src/verify-probes.js +3 -0
- package/src/workflow.js +4 -0
- package/src/worktree-apply.js +4 -4
- package/src/worktree.js +6 -4
- package/{.worktrees/542c4415/templates/claude-instruction.md → templates/agents-instruction.md} +2 -2
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.claude/worktrees/sillyspec-data-model-research/.gitattributes +0 -2
- package/.claude/worktrees/sillyspec-data-model-research/.husky/pre-push +0 -20
- package/.claude/worktrees/sillyspec-data-model-research/README.md +0 -203
- package/.claude/worktrees/sillyspec-data-model-research/SKILL.md +0 -91
- package/.claude/worktrees/sillyspec-data-model-research/bin/sillyspec.js +0 -2
- package/.claude/worktrees/sillyspec-data-model-research/logo.jpg +0 -0
- package/.claude/worktrees/sillyspec-data-model-research/package-lock.json +0 -977
- package/.claude/worktrees/sillyspec-data-model-research/package.json +0 -39
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/favicon.jpg +0 -0
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/index.html +0 -16
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/logo.jpg +0 -0
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/package.json +0 -25
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/executor.js +0 -95
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/index.js +0 -679
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/parser.js +0 -526
- package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/watcher.js +0 -357
- package/.claude/worktrees/sillyspec-data-model-research/src/agent-session-log.js +0 -803
- package/.claude/worktrees/sillyspec-data-model-research/src/change-list.js +0 -290
- package/.claude/worktrees/sillyspec-data-model-research/src/change-risk-profile.js +0 -270
- package/.claude/worktrees/sillyspec-data-model-research/src/check-primitives.js +0 -65
- package/.claude/worktrees/sillyspec-data-model-research/src/classify-change.js +0 -109
- package/.claude/worktrees/sillyspec-data-model-research/src/commit-suggest.js +0 -202
- package/.claude/worktrees/sillyspec-data-model-research/src/config-cat.js +0 -88
- package/.claude/worktrees/sillyspec-data-model-research/src/config-schema.js +0 -328
- package/.claude/worktrees/sillyspec-data-model-research/src/constants.js +0 -97
- package/.claude/worktrees/sillyspec-data-model-research/src/contract-matrix.js +0 -480
- package/.claude/worktrees/sillyspec-data-model-research/src/datetime.js +0 -20
- package/.claude/worktrees/sillyspec-data-model-research/src/db-engine.js +0 -55
- package/.claude/worktrees/sillyspec-data-model-research/src/db.js +0 -381
- package/.claude/worktrees/sillyspec-data-model-research/src/decision-distill.js +0 -517
- package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/backends/local-agent.js +0 -155
- package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/probe.js +0 -246
- package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/strategy.js +0 -121
- package/.claude/worktrees/sillyspec-data-model-research/src/docs-check.js +0 -825
- package/.claude/worktrees/sillyspec-data-model-research/src/docs-debt.js +0 -393
- package/.claude/worktrees/sillyspec-data-model-research/src/docs-gate.js +0 -107
- package/.claude/worktrees/sillyspec-data-model-research/src/doctor-diagnostics.js +0 -1099
- package/.claude/worktrees/sillyspec-data-model-research/src/endpoint-extractor.js +0 -420
- package/.claude/worktrees/sillyspec-data-model-research/src/foreign-declared.js +0 -78
- package/.claude/worktrees/sillyspec-data-model-research/src/fs-atomic.js +0 -73
- package/.claude/worktrees/sillyspec-data-model-research/src/git-helper.js +0 -150
- package/.claude/worktrees/sillyspec-data-model-research/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.claude/worktrees/sillyspec-data-model-research/src/hooks/worktree-guard.js +0 -892
- package/.claude/worktrees/sillyspec-data-model-research/src/index.js +0 -2798
- package/.claude/worktrees/sillyspec-data-model-research/src/init.js +0 -626
- package/.claude/worktrees/sillyspec-data-model-research/src/knowledge-match.js +0 -231
- package/.claude/worktrees/sillyspec-data-model-research/src/local-detect.js +0 -128
- package/.claude/worktrees/sillyspec-data-model-research/src/local-register.js +0 -104
- package/.claude/worktrees/sillyspec-data-model-research/src/machine-interface.js +0 -543
- package/.claude/worktrees/sillyspec-data-model-research/src/migrate.js +0 -127
- package/.claude/worktrees/sillyspec-data-model-research/src/module-impact.js +0 -166
- package/.claude/worktrees/sillyspec-data-model-research/src/module-resolve.js +0 -222
- package/.claude/worktrees/sillyspec-data-model-research/src/modules.js +0 -580
- package/.claude/worktrees/sillyspec-data-model-research/src/progress/change-registry.js +0 -336
- package/.claude/worktrees/sillyspec-data-model-research/src/progress/consistency-doctor.js +0 -355
- package/.claude/worktrees/sillyspec-data-model-research/src/progress/shared.js +0 -36
- package/.claude/worktrees/sillyspec-data-model-research/src/progress/stage-machine.js +0 -594
- package/.claude/worktrees/sillyspec-data-model-research/src/progress/step-store.js +0 -265
- package/.claude/worktrees/sillyspec-data-model-research/src/progress.js +0 -1304
- package/.claude/worktrees/sillyspec-data-model-research/src/quick-recommend.js +0 -115
- package/.claude/worktrees/sillyspec-data-model-research/src/quicklog.js +0 -852
- package/.claude/worktrees/sillyspec-data-model-research/src/review-tier.js +0 -77
- package/.claude/worktrees/sillyspec-data-model-research/src/run/command.js +0 -1595
- package/.claude/worktrees/sillyspec-data-model-research/src/run/complete-handlers.js +0 -1552
- package/.claude/worktrees/sillyspec-data-model-research/src/run/complete.js +0 -1259
- package/.claude/worktrees/sillyspec-data-model-research/src/run/concurrent-detect.js +0 -156
- package/.claude/worktrees/sillyspec-data-model-research/src/run/gates.js +0 -1084
- package/.claude/worktrees/sillyspec-data-model-research/src/run/multi-repo-context.js +0 -208
- package/.claude/worktrees/sillyspec-data-model-research/src/run/next.js +0 -128
- package/.claude/worktrees/sillyspec-data-model-research/src/run/prompt.js +0 -843
- package/.claude/worktrees/sillyspec-data-model-research/src/run/quick-audit.js +0 -186
- package/.claude/worktrees/sillyspec-data-model-research/src/run/scan-profile.js +0 -269
- package/.claude/worktrees/sillyspec-data-model-research/src/run/shared.js +0 -1562
- package/.claude/worktrees/sillyspec-data-model-research/src/run/stage.js +0 -584
- package/.claude/worktrees/sillyspec-data-model-research/src/run.js +0 -23
- package/.claude/worktrees/sillyspec-data-model-research/src/scan-diff.js +0 -388
- package/.claude/worktrees/sillyspec-data-model-research/src/scan-postcheck.js +0 -512
- package/.claude/worktrees/sillyspec-data-model-research/src/scan-staleness.js +0 -95
- package/.claude/worktrees/sillyspec-data-model-research/src/setup.js +0 -414
- package/.claude/worktrees/sillyspec-data-model-research/src/sillyhub-mcp/client.js +0 -597
- package/.claude/worktrees/sillyspec-data-model-research/src/sillyhub-mcp/config.js +0 -62
- package/.claude/worktrees/sillyspec-data-model-research/src/spec-dir-typo.js +0 -50
- package/.claude/worktrees/sillyspec-data-model-research/src/spec-sync.js +0 -358
- package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract-engine.js +0 -171
- package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract-spec.js +0 -550
- package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract.js +0 -889
- package/.claude/worktrees/sillyspec-data-model-research/src/stage-review.js +0 -597
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/archive.js +0 -199
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/brainstorm-auto.js +0 -236
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/brainstorm.js +0 -617
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/cmd-existence.js +0 -145
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/doctor.js +0 -540
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/execute.js +0 -1275
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/explore.js +0 -43
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/index.js +0 -29
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/knowledge.js +0 -514
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/plan-postcheck.js +0 -1344
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/plan.js +0 -650
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/quick.js +0 -167
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/scan.js +0 -608
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/status.js +0 -64
- package/.claude/worktrees/sillyspec-data-model-research/src/stages/verify.js +0 -246
- package/.claude/worktrees/sillyspec-data-model-research/src/sync.js +0 -1470
- package/.claude/worktrees/sillyspec-data-model-research/src/task-review.js +0 -1498
- package/.claude/worktrees/sillyspec-data-model-research/src/taskcard.js +0 -210
- package/.claude/worktrees/sillyspec-data-model-research/src/verify-postcheck.js +0 -1718
- package/.claude/worktrees/sillyspec-data-model-research/src/verify-probes.js +0 -277
- package/.claude/worktrees/sillyspec-data-model-research/src/version.js +0 -19
- package/.claude/worktrees/sillyspec-data-model-research/src/workflow.js +0 -600
- package/.claude/worktrees/sillyspec-data-model-research/src/workspace.js +0 -125
- package/.claude/worktrees/sillyspec-data-model-research/src/worktree-apply.js +0 -1446
- package/.claude/worktrees/sillyspec-data-model-research/src/worktree-deps.js +0 -576
- package/.claude/worktrees/sillyspec-data-model-research/src/worktree.js +0 -1715
- package/.claude/worktrees/sillyspec-data-model-research/templates/claude-instruction.md +0 -23
- package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/taskcard-rules.md +0 -28
- package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/testcase-design.md +0 -12
- package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/verify-probes.md +0 -32
- package/.claude/worktrees/sillyspec-data-model-research/templates/workflows/archive-impact.yaml +0 -79
- package/.claude/worktrees/sillyspec-data-model-research/templates/workflows/scan-docs.yaml +0 -132
- package/.npmrc-temp +0 -1
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-propose/SKILL.md +0 -87
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.worktrees/2c37b1d7/.claude/skills/verify-per-user/SKILL.md +0 -6
- package/.worktrees/2c37b1d7/.gitattributes +0 -2
- package/.worktrees/2c37b1d7/.husky/pre-push +0 -20
- package/.worktrees/2c37b1d7/README.md +0 -203
- package/.worktrees/2c37b1d7/SKILL.md +0 -91
- package/.worktrees/2c37b1d7/architecture-analysis.md +0 -448
- package/.worktrees/2c37b1d7/bin/sillyspec.js +0 -2
- package/.worktrees/2c37b1d7/eval/README.md +0 -86
- package/.worktrees/2c37b1d7/eval/eval.config.json +0 -28
- package/.worktrees/2c37b1d7/eval/lib/adapters/cli.mjs +0 -63
- package/.worktrees/2c37b1d7/eval/lib/adapters/dryrun.mjs +0 -27
- package/.worktrees/2c37b1d7/eval/lib/config.mjs +0 -82
- package/.worktrees/2c37b1d7/eval/lib/db.mjs +0 -76
- package/.worktrees/2c37b1d7/eval/lib/report.mjs +0 -120
- package/.worktrees/2c37b1d7/eval/lib/runner.mjs +0 -157
- package/.worktrees/2c37b1d7/eval/lib/tasks.mjs +0 -73
- package/.worktrees/2c37b1d7/eval/lib/util.mjs +0 -107
- package/.worktrees/2c37b1d7/eval/lib/workdir.mjs +0 -30
- package/.worktrees/2c37b1d7/eval/run.mjs +0 -83
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/files/package.json +0 -6
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/task.json +0 -6
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/verify.mjs +0 -28
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/package.json +0 -6
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/task.json +0 -6
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/verify.mjs +0 -31
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/data/notes.txt +0 -5
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/package.json +0 -6
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/task.json +0 -6
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/verify.mjs +0 -38
- package/.worktrees/2c37b1d7/logo.jpg +0 -0
- package/.worktrees/2c37b1d7/package-lock.json +0 -977
- package/.worktrees/2c37b1d7/package.json +0 -41
- package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.worktrees/2c37b1d7/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/index.html +0 -16
- package/.worktrees/2c37b1d7/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.worktrees/2c37b1d7/packages/dashboard/package.json +0 -25
- package/.worktrees/2c37b1d7/packages/dashboard/server/executor.js +0 -95
- package/.worktrees/2c37b1d7/packages/dashboard/server/index.js +0 -679
- package/.worktrees/2c37b1d7/packages/dashboard/server/parser.js +0 -526
- package/.worktrees/2c37b1d7/packages/dashboard/server/watcher.js +0 -357
- package/.worktrees/2c37b1d7/src/agent-session-log.js +0 -803
- package/.worktrees/2c37b1d7/src/change-list.js +0 -290
- package/.worktrees/2c37b1d7/src/change-risk-profile.js +0 -339
- package/.worktrees/2c37b1d7/src/check-primitives.js +0 -65
- package/.worktrees/2c37b1d7/src/classify-change.js +0 -109
- package/.worktrees/2c37b1d7/src/commit-suggest.js +0 -202
- package/.worktrees/2c37b1d7/src/config-cat.js +0 -88
- package/.worktrees/2c37b1d7/src/config-schema.js +0 -328
- package/.worktrees/2c37b1d7/src/constants.js +0 -97
- package/.worktrees/2c37b1d7/src/contract-matrix.js +0 -533
- package/.worktrees/2c37b1d7/src/datetime.js +0 -20
- package/.worktrees/2c37b1d7/src/db-engine.js +0 -55
- package/.worktrees/2c37b1d7/src/db.js +0 -381
- package/.worktrees/2c37b1d7/src/decision-distill.js +0 -517
- package/.worktrees/2c37b1d7/src/dispatch/backends/local-agent.js +0 -155
- package/.worktrees/2c37b1d7/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.worktrees/2c37b1d7/src/dispatch/probe.js +0 -246
- package/.worktrees/2c37b1d7/src/dispatch/strategy.js +0 -121
- package/.worktrees/2c37b1d7/src/docs-check.js +0 -825
- package/.worktrees/2c37b1d7/src/docs-debt.js +0 -393
- package/.worktrees/2c37b1d7/src/docs-gate.js +0 -107
- package/.worktrees/2c37b1d7/src/doctor-diagnostics.js +0 -1099
- package/.worktrees/2c37b1d7/src/endpoint-extractor.js +0 -409
- package/.worktrees/2c37b1d7/src/foreign-declared.js +0 -155
- package/.worktrees/2c37b1d7/src/fs-atomic.js +0 -73
- package/.worktrees/2c37b1d7/src/git-helper.js +0 -150
- package/.worktrees/2c37b1d7/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.worktrees/2c37b1d7/src/hooks/worktree-guard.js +0 -892
- package/.worktrees/2c37b1d7/src/index.js +0 -2854
- package/.worktrees/2c37b1d7/src/init.js +0 -626
- package/.worktrees/2c37b1d7/src/knowledge-match.js +0 -231
- package/.worktrees/2c37b1d7/src/local-detect.js +0 -128
- package/.worktrees/2c37b1d7/src/local-register.js +0 -104
- package/.worktrees/2c37b1d7/src/machine-interface.js +0 -543
- package/.worktrees/2c37b1d7/src/migrate.js +0 -127
- package/.worktrees/2c37b1d7/src/module-impact.js +0 -166
- package/.worktrees/2c37b1d7/src/module-resolve.js +0 -222
- package/.worktrees/2c37b1d7/src/modules.js +0 -580
- package/.worktrees/2c37b1d7/src/plan-adopt-waves.js +0 -126
- package/.worktrees/2c37b1d7/src/progress/change-registry.js +0 -336
- package/.worktrees/2c37b1d7/src/progress/consistency-doctor.js +0 -355
- package/.worktrees/2c37b1d7/src/progress/shared.js +0 -36
- package/.worktrees/2c37b1d7/src/progress/stage-machine.js +0 -594
- package/.worktrees/2c37b1d7/src/progress/step-store.js +0 -265
- package/.worktrees/2c37b1d7/src/progress.js +0 -1304
- package/.worktrees/2c37b1d7/src/quick-recommend.js +0 -115
- package/.worktrees/2c37b1d7/src/quicklog.js +0 -883
- package/.worktrees/2c37b1d7/src/review-tier.js +0 -77
- package/.worktrees/2c37b1d7/src/run/command.js +0 -1641
- package/.worktrees/2c37b1d7/src/run/complete-handlers.js +0 -1552
- package/.worktrees/2c37b1d7/src/run/complete.js +0 -1259
- package/.worktrees/2c37b1d7/src/run/concurrent-detect.js +0 -156
- package/.worktrees/2c37b1d7/src/run/gates.js +0 -1111
- package/.worktrees/2c37b1d7/src/run/multi-repo-context.js +0 -208
- package/.worktrees/2c37b1d7/src/run/next.js +0 -128
- package/.worktrees/2c37b1d7/src/run/prompt.js +0 -843
- package/.worktrees/2c37b1d7/src/run/quick-audit.js +0 -186
- package/.worktrees/2c37b1d7/src/run/scan-profile.js +0 -269
- package/.worktrees/2c37b1d7/src/run/shared.js +0 -1562
- package/.worktrees/2c37b1d7/src/run/stage.js +0 -587
- package/.worktrees/2c37b1d7/src/run.js +0 -23
- package/.worktrees/2c37b1d7/src/scan-diff.js +0 -388
- package/.worktrees/2c37b1d7/src/scan-postcheck.js +0 -524
- package/.worktrees/2c37b1d7/src/scan-staleness.js +0 -95
- package/.worktrees/2c37b1d7/src/setup.js +0 -414
- package/.worktrees/2c37b1d7/src/sillyhub-mcp/client.js +0 -597
- package/.worktrees/2c37b1d7/src/sillyhub-mcp/config.js +0 -62
- package/.worktrees/2c37b1d7/src/spec-dir-typo.js +0 -50
- package/.worktrees/2c37b1d7/src/spec-sync.js +0 -358
- package/.worktrees/2c37b1d7/src/stage-contract-engine.js +0 -171
- package/.worktrees/2c37b1d7/src/stage-contract-spec.js +0 -551
- package/.worktrees/2c37b1d7/src/stage-contract.js +0 -948
- package/.worktrees/2c37b1d7/src/stage-review.js +0 -597
- package/.worktrees/2c37b1d7/src/stages/archive.js +0 -199
- package/.worktrees/2c37b1d7/src/stages/brainstorm-auto.js +0 -285
- package/.worktrees/2c37b1d7/src/stages/brainstorm.js +0 -624
- package/.worktrees/2c37b1d7/src/stages/cmd-existence.js +0 -145
- package/.worktrees/2c37b1d7/src/stages/doctor.js +0 -540
- package/.worktrees/2c37b1d7/src/stages/execute.js +0 -1277
- package/.worktrees/2c37b1d7/src/stages/explore.js +0 -43
- package/.worktrees/2c37b1d7/src/stages/index.js +0 -29
- package/.worktrees/2c37b1d7/src/stages/knowledge.js +0 -514
- package/.worktrees/2c37b1d7/src/stages/plan-postcheck.js +0 -1398
- package/.worktrees/2c37b1d7/src/stages/plan.js +0 -655
- package/.worktrees/2c37b1d7/src/stages/quick.js +0 -167
- package/.worktrees/2c37b1d7/src/stages/scan.js +0 -608
- package/.worktrees/2c37b1d7/src/stages/status.js +0 -64
- package/.worktrees/2c37b1d7/src/stages/verify.js +0 -246
- package/.worktrees/2c37b1d7/src/sync.js +0 -1470
- package/.worktrees/2c37b1d7/src/task-review.js +0 -1498
- package/.worktrees/2c37b1d7/src/taskcard-placeholders.js +0 -21
- package/.worktrees/2c37b1d7/src/taskcard.js +0 -250
- package/.worktrees/2c37b1d7/src/verify-postcheck.js +0 -1718
- package/.worktrees/2c37b1d7/src/verify-probes.js +0 -327
- package/.worktrees/2c37b1d7/src/version.js +0 -19
- package/.worktrees/2c37b1d7/src/workflow.js +0 -600
- package/.worktrees/2c37b1d7/src/workspace.js +0 -125
- package/.worktrees/2c37b1d7/src/worktree-apply.js +0 -1611
- package/.worktrees/2c37b1d7/src/worktree-deps.js +0 -668
- package/.worktrees/2c37b1d7/src/worktree.js +0 -1849
- package/.worktrees/2c37b1d7/templates/claude-instruction.md +0 -23
- package/.worktrees/2c37b1d7/templates/prompts/taskcard-rules.md +0 -29
- package/.worktrees/2c37b1d7/templates/prompts/testcase-design.md +0 -12
- package/.worktrees/2c37b1d7/templates/prompts/verify-probes.md +0 -32
- package/.worktrees/2c37b1d7/templates/workflows/archive-impact.yaml +0 -79
- package/.worktrees/2c37b1d7/templates/workflows/scan-docs.yaml +0 -132
- package/.worktrees/542c4415/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.worktrees/542c4415/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.worktrees/542c4415/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.worktrees/542c4415/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.worktrees/542c4415/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.worktrees/542c4415/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.worktrees/542c4415/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.worktrees/542c4415/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.worktrees/542c4415/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.worktrees/542c4415/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.worktrees/542c4415/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.worktrees/542c4415/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.worktrees/542c4415/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.worktrees/542c4415/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.worktrees/542c4415/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.worktrees/542c4415/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.worktrees/542c4415/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.worktrees/542c4415/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.worktrees/542c4415/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.worktrees/542c4415/.gitattributes +0 -2
- package/.worktrees/542c4415/.husky/pre-push +0 -20
- package/.worktrees/542c4415/README.md +0 -203
- package/.worktrees/542c4415/SKILL.md +0 -91
- package/.worktrees/542c4415/architecture-analysis.md +0 -448
- package/.worktrees/542c4415/bin/sillyspec.js +0 -2
- package/.worktrees/542c4415/eval/README.md +0 -86
- package/.worktrees/542c4415/eval/eval.config.json +0 -28
- package/.worktrees/542c4415/eval/lib/adapters/cli.mjs +0 -63
- package/.worktrees/542c4415/eval/lib/adapters/dryrun.mjs +0 -27
- package/.worktrees/542c4415/eval/lib/config.mjs +0 -82
- package/.worktrees/542c4415/eval/lib/db.mjs +0 -76
- package/.worktrees/542c4415/eval/lib/report.mjs +0 -120
- package/.worktrees/542c4415/eval/lib/runner.mjs +0 -157
- package/.worktrees/542c4415/eval/lib/tasks.mjs +0 -73
- package/.worktrees/542c4415/eval/lib/util.mjs +0 -107
- package/.worktrees/542c4415/eval/lib/workdir.mjs +0 -30
- package/.worktrees/542c4415/eval/run.mjs +0 -83
- package/.worktrees/542c4415/eval/tasks/001-slugify/files/package.json +0 -6
- package/.worktrees/542c4415/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
- package/.worktrees/542c4415/eval/tasks/001-slugify/task.json +0 -6
- package/.worktrees/542c4415/eval/tasks/001-slugify/verify.mjs +0 -28
- package/.worktrees/542c4415/eval/tasks/002-each-day/files/package.json +0 -6
- package/.worktrees/542c4415/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
- package/.worktrees/542c4415/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
- package/.worktrees/542c4415/eval/tasks/002-each-day/task.json +0 -6
- package/.worktrees/542c4415/eval/tasks/002-each-day/verify.mjs +0 -31
- package/.worktrees/542c4415/eval/tasks/003-word-report/files/data/notes.txt +0 -5
- package/.worktrees/542c4415/eval/tasks/003-word-report/files/package.json +0 -6
- package/.worktrees/542c4415/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
- package/.worktrees/542c4415/eval/tasks/003-word-report/task.json +0 -6
- package/.worktrees/542c4415/eval/tasks/003-word-report/verify.mjs +0 -38
- package/.worktrees/542c4415/logo.jpg +0 -0
- package/.worktrees/542c4415/package-lock.json +0 -977
- package/.worktrees/542c4415/package.json +0 -41
- package/.worktrees/542c4415/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.worktrees/542c4415/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.worktrees/542c4415/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/542c4415/packages/dashboard/dist/index.html +0 -16
- package/.worktrees/542c4415/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/542c4415/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.worktrees/542c4415/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.worktrees/542c4415/packages/dashboard/package.json +0 -25
- package/.worktrees/542c4415/packages/dashboard/server/executor.js +0 -95
- package/.worktrees/542c4415/packages/dashboard/server/index.js +0 -679
- package/.worktrees/542c4415/packages/dashboard/server/parser.js +0 -526
- package/.worktrees/542c4415/packages/dashboard/server/watcher.js +0 -357
- package/.worktrees/542c4415/src/agent-session-log.js +0 -803
- package/.worktrees/542c4415/src/change-list.js +0 -290
- package/.worktrees/542c4415/src/change-risk-profile.js +0 -339
- package/.worktrees/542c4415/src/check-primitives.js +0 -65
- package/.worktrees/542c4415/src/classify-change.js +0 -109
- package/.worktrees/542c4415/src/commit-suggest.js +0 -202
- package/.worktrees/542c4415/src/config-cat.js +0 -88
- package/.worktrees/542c4415/src/config-schema.js +0 -328
- package/.worktrees/542c4415/src/constants.js +0 -97
- package/.worktrees/542c4415/src/contract-matrix.js +0 -533
- package/.worktrees/542c4415/src/datetime.js +0 -20
- package/.worktrees/542c4415/src/db-engine.js +0 -55
- package/.worktrees/542c4415/src/db.js +0 -381
- package/.worktrees/542c4415/src/decision-distill.js +0 -517
- package/.worktrees/542c4415/src/dispatch/backends/local-agent.js +0 -155
- package/.worktrees/542c4415/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.worktrees/542c4415/src/dispatch/probe.js +0 -246
- package/.worktrees/542c4415/src/dispatch/strategy.js +0 -121
- package/.worktrees/542c4415/src/docs-check.js +0 -825
- package/.worktrees/542c4415/src/docs-debt.js +0 -393
- package/.worktrees/542c4415/src/docs-gate.js +0 -107
- package/.worktrees/542c4415/src/doctor-diagnostics.js +0 -1099
- package/.worktrees/542c4415/src/endpoint-extractor.js +0 -409
- package/.worktrees/542c4415/src/foreign-declared.js +0 -155
- package/.worktrees/542c4415/src/fs-atomic.js +0 -73
- package/.worktrees/542c4415/src/git-helper.js +0 -150
- package/.worktrees/542c4415/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.worktrees/542c4415/src/hooks/worktree-guard.js +0 -892
- package/.worktrees/542c4415/src/index.js +0 -2854
- package/.worktrees/542c4415/src/init.js +0 -626
- package/.worktrees/542c4415/src/knowledge-match.js +0 -231
- package/.worktrees/542c4415/src/local-detect.js +0 -128
- package/.worktrees/542c4415/src/local-register.js +0 -104
- package/.worktrees/542c4415/src/machine-interface.js +0 -543
- package/.worktrees/542c4415/src/migrate.js +0 -127
- package/.worktrees/542c4415/src/module-impact.js +0 -166
- package/.worktrees/542c4415/src/module-resolve.js +0 -222
- package/.worktrees/542c4415/src/modules.js +0 -580
- package/.worktrees/542c4415/src/plan-adopt-waves.js +0 -126
- package/.worktrees/542c4415/src/progress/change-registry.js +0 -336
- package/.worktrees/542c4415/src/progress/consistency-doctor.js +0 -355
- package/.worktrees/542c4415/src/progress/shared.js +0 -36
- package/.worktrees/542c4415/src/progress/stage-machine.js +0 -594
- package/.worktrees/542c4415/src/progress/step-store.js +0 -265
- package/.worktrees/542c4415/src/progress.js +0 -1304
- package/.worktrees/542c4415/src/quick-recommend.js +0 -115
- package/.worktrees/542c4415/src/quicklog.js +0 -883
- package/.worktrees/542c4415/src/review-tier.js +0 -77
- package/.worktrees/542c4415/src/run/command.js +0 -1641
- package/.worktrees/542c4415/src/run/complete-handlers.js +0 -1552
- package/.worktrees/542c4415/src/run/complete.js +0 -1259
- package/.worktrees/542c4415/src/run/concurrent-detect.js +0 -156
- package/.worktrees/542c4415/src/run/gates.js +0 -1111
- package/.worktrees/542c4415/src/run/multi-repo-context.js +0 -208
- package/.worktrees/542c4415/src/run/next.js +0 -128
- package/.worktrees/542c4415/src/run/prompt.js +0 -843
- package/.worktrees/542c4415/src/run/quick-audit.js +0 -186
- package/.worktrees/542c4415/src/run/scan-profile.js +0 -269
- package/.worktrees/542c4415/src/run/shared.js +0 -1562
- package/.worktrees/542c4415/src/run/stage.js +0 -587
- package/.worktrees/542c4415/src/run.js +0 -23
- package/.worktrees/542c4415/src/scan-diff.js +0 -388
- package/.worktrees/542c4415/src/scan-postcheck.js +0 -524
- package/.worktrees/542c4415/src/scan-staleness.js +0 -95
- package/.worktrees/542c4415/src/setup.js +0 -414
- package/.worktrees/542c4415/src/sillyhub-mcp/client.js +0 -597
- package/.worktrees/542c4415/src/sillyhub-mcp/config.js +0 -62
- package/.worktrees/542c4415/src/spec-dir-typo.js +0 -50
- package/.worktrees/542c4415/src/spec-sync.js +0 -358
- package/.worktrees/542c4415/src/stage-contract-engine.js +0 -171
- package/.worktrees/542c4415/src/stage-contract-spec.js +0 -551
- package/.worktrees/542c4415/src/stage-contract.js +0 -948
- package/.worktrees/542c4415/src/stage-review.js +0 -597
- package/.worktrees/542c4415/src/stages/archive.js +0 -199
- package/.worktrees/542c4415/src/stages/brainstorm-auto.js +0 -285
- package/.worktrees/542c4415/src/stages/brainstorm.js +0 -624
- package/.worktrees/542c4415/src/stages/cmd-existence.js +0 -145
- package/.worktrees/542c4415/src/stages/doctor.js +0 -540
- package/.worktrees/542c4415/src/stages/execute.js +0 -1277
- package/.worktrees/542c4415/src/stages/explore.js +0 -43
- package/.worktrees/542c4415/src/stages/index.js +0 -29
- package/.worktrees/542c4415/src/stages/knowledge.js +0 -514
- package/.worktrees/542c4415/src/stages/plan-postcheck.js +0 -1398
- package/.worktrees/542c4415/src/stages/plan.js +0 -655
- package/.worktrees/542c4415/src/stages/quick.js +0 -167
- package/.worktrees/542c4415/src/stages/scan.js +0 -608
- package/.worktrees/542c4415/src/stages/status.js +0 -64
- package/.worktrees/542c4415/src/stages/verify.js +0 -246
- package/.worktrees/542c4415/src/sync.js +0 -1470
- package/.worktrees/542c4415/src/task-review.js +0 -1498
- package/.worktrees/542c4415/src/taskcard-placeholders.js +0 -21
- package/.worktrees/542c4415/src/taskcard.js +0 -250
- package/.worktrees/542c4415/src/verify-postcheck.js +0 -1718
- package/.worktrees/542c4415/src/verify-probes.js +0 -327
- package/.worktrees/542c4415/src/version.js +0 -19
- package/.worktrees/542c4415/src/workflow.js +0 -600
- package/.worktrees/542c4415/src/workspace.js +0 -125
- package/.worktrees/542c4415/src/worktree-apply.js +0 -1611
- package/.worktrees/542c4415/src/worktree-deps.js +0 -668
- package/.worktrees/542c4415/src/worktree.js +0 -1849
- package/.worktrees/542c4415/templates/prompts/taskcard-rules.md +0 -29
- package/.worktrees/542c4415/templates/prompts/testcase-design.md +0 -12
- package/.worktrees/542c4415/templates/prompts/verify-probes.md +0 -32
- package/.worktrees/542c4415/templates/workflows/archive-impact.yaml +0 -79
- package/.worktrees/542c4415/templates/workflows/scan-docs.yaml +0 -132
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-propose/SKILL.md +0 -87
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.worktrees/8d2d0392/.claude/skills/verify-per-user/SKILL.md +0 -6
- package/.worktrees/8d2d0392/.gitattributes +0 -2
- package/.worktrees/8d2d0392/.husky/pre-push +0 -20
- package/.worktrees/8d2d0392/README.md +0 -203
- package/.worktrees/8d2d0392/SKILL.md +0 -91
- package/.worktrees/8d2d0392/architecture-analysis.md +0 -448
- package/.worktrees/8d2d0392/bin/sillyspec.js +0 -2
- package/.worktrees/8d2d0392/eval/README.md +0 -86
- package/.worktrees/8d2d0392/eval/eval.config.json +0 -28
- package/.worktrees/8d2d0392/eval/lib/adapters/cli.mjs +0 -63
- package/.worktrees/8d2d0392/eval/lib/adapters/dryrun.mjs +0 -27
- package/.worktrees/8d2d0392/eval/lib/config.mjs +0 -82
- package/.worktrees/8d2d0392/eval/lib/db.mjs +0 -76
- package/.worktrees/8d2d0392/eval/lib/report.mjs +0 -120
- package/.worktrees/8d2d0392/eval/lib/runner.mjs +0 -157
- package/.worktrees/8d2d0392/eval/lib/tasks.mjs +0 -73
- package/.worktrees/8d2d0392/eval/lib/util.mjs +0 -107
- package/.worktrees/8d2d0392/eval/lib/workdir.mjs +0 -30
- package/.worktrees/8d2d0392/eval/run.mjs +0 -83
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/files/package.json +0 -6
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/task.json +0 -6
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/verify.mjs +0 -28
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/package.json +0 -6
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/task.json +0 -6
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/verify.mjs +0 -31
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/data/notes.txt +0 -5
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/package.json +0 -6
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/task.json +0 -6
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/verify.mjs +0 -38
- package/.worktrees/8d2d0392/logo.jpg +0 -0
- package/.worktrees/8d2d0392/package-lock.json +0 -977
- package/.worktrees/8d2d0392/package.json +0 -41
- package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.worktrees/8d2d0392/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/index.html +0 -16
- package/.worktrees/8d2d0392/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.worktrees/8d2d0392/packages/dashboard/package.json +0 -25
- package/.worktrees/8d2d0392/packages/dashboard/server/executor.js +0 -95
- package/.worktrees/8d2d0392/packages/dashboard/server/index.js +0 -679
- package/.worktrees/8d2d0392/packages/dashboard/server/parser.js +0 -526
- package/.worktrees/8d2d0392/packages/dashboard/server/watcher.js +0 -357
- package/.worktrees/8d2d0392/src/agent-session-log.js +0 -803
- package/.worktrees/8d2d0392/src/change-list.js +0 -290
- package/.worktrees/8d2d0392/src/change-risk-profile.js +0 -339
- package/.worktrees/8d2d0392/src/check-primitives.js +0 -65
- package/.worktrees/8d2d0392/src/classify-change.js +0 -109
- package/.worktrees/8d2d0392/src/commit-suggest.js +0 -202
- package/.worktrees/8d2d0392/src/config-cat.js +0 -88
- package/.worktrees/8d2d0392/src/config-schema.js +0 -328
- package/.worktrees/8d2d0392/src/constants.js +0 -97
- package/.worktrees/8d2d0392/src/contract-matrix.js +0 -533
- package/.worktrees/8d2d0392/src/datetime.js +0 -20
- package/.worktrees/8d2d0392/src/db-engine.js +0 -55
- package/.worktrees/8d2d0392/src/db.js +0 -381
- package/.worktrees/8d2d0392/src/decision-distill.js +0 -517
- package/.worktrees/8d2d0392/src/dispatch/backends/local-agent.js +0 -155
- package/.worktrees/8d2d0392/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.worktrees/8d2d0392/src/dispatch/probe.js +0 -246
- package/.worktrees/8d2d0392/src/dispatch/strategy.js +0 -121
- package/.worktrees/8d2d0392/src/docs-check.js +0 -825
- package/.worktrees/8d2d0392/src/docs-debt.js +0 -393
- package/.worktrees/8d2d0392/src/docs-gate.js +0 -107
- package/.worktrees/8d2d0392/src/doctor-diagnostics.js +0 -1099
- package/.worktrees/8d2d0392/src/endpoint-extractor.js +0 -409
- package/.worktrees/8d2d0392/src/foreign-declared.js +0 -78
- package/.worktrees/8d2d0392/src/fs-atomic.js +0 -73
- package/.worktrees/8d2d0392/src/git-helper.js +0 -150
- package/.worktrees/8d2d0392/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.worktrees/8d2d0392/src/hooks/worktree-guard.js +0 -892
- package/.worktrees/8d2d0392/src/index.js +0 -2854
- package/.worktrees/8d2d0392/src/init.js +0 -626
- package/.worktrees/8d2d0392/src/knowledge-match.js +0 -231
- package/.worktrees/8d2d0392/src/local-detect.js +0 -128
- package/.worktrees/8d2d0392/src/local-register.js +0 -104
- package/.worktrees/8d2d0392/src/machine-interface.js +0 -543
- package/.worktrees/8d2d0392/src/migrate.js +0 -127
- package/.worktrees/8d2d0392/src/module-impact.js +0 -166
- package/.worktrees/8d2d0392/src/module-resolve.js +0 -222
- package/.worktrees/8d2d0392/src/modules.js +0 -580
- package/.worktrees/8d2d0392/src/plan-adopt-waves.js +0 -126
- package/.worktrees/8d2d0392/src/progress/change-registry.js +0 -336
- package/.worktrees/8d2d0392/src/progress/consistency-doctor.js +0 -355
- package/.worktrees/8d2d0392/src/progress/shared.js +0 -36
- package/.worktrees/8d2d0392/src/progress/stage-machine.js +0 -594
- package/.worktrees/8d2d0392/src/progress/step-store.js +0 -265
- package/.worktrees/8d2d0392/src/progress.js +0 -1304
- package/.worktrees/8d2d0392/src/quick-recommend.js +0 -115
- package/.worktrees/8d2d0392/src/quicklog.js +0 -883
- package/.worktrees/8d2d0392/src/review-tier.js +0 -77
- package/.worktrees/8d2d0392/src/run/command.js +0 -1641
- package/.worktrees/8d2d0392/src/run/complete-handlers.js +0 -1552
- package/.worktrees/8d2d0392/src/run/complete.js +0 -1259
- package/.worktrees/8d2d0392/src/run/concurrent-detect.js +0 -156
- package/.worktrees/8d2d0392/src/run/gates.js +0 -1094
- package/.worktrees/8d2d0392/src/run/multi-repo-context.js +0 -208
- package/.worktrees/8d2d0392/src/run/next.js +0 -128
- package/.worktrees/8d2d0392/src/run/prompt.js +0 -843
- package/.worktrees/8d2d0392/src/run/quick-audit.js +0 -186
- package/.worktrees/8d2d0392/src/run/scan-profile.js +0 -269
- package/.worktrees/8d2d0392/src/run/shared.js +0 -1562
- package/.worktrees/8d2d0392/src/run/stage.js +0 -587
- package/.worktrees/8d2d0392/src/run.js +0 -23
- package/.worktrees/8d2d0392/src/scan-diff.js +0 -388
- package/.worktrees/8d2d0392/src/scan-postcheck.js +0 -524
- package/.worktrees/8d2d0392/src/scan-staleness.js +0 -95
- package/.worktrees/8d2d0392/src/setup.js +0 -414
- package/.worktrees/8d2d0392/src/sillyhub-mcp/client.js +0 -597
- package/.worktrees/8d2d0392/src/sillyhub-mcp/config.js +0 -62
- package/.worktrees/8d2d0392/src/spec-dir-typo.js +0 -50
- package/.worktrees/8d2d0392/src/spec-sync.js +0 -358
- package/.worktrees/8d2d0392/src/stage-contract-engine.js +0 -171
- package/.worktrees/8d2d0392/src/stage-contract-spec.js +0 -551
- package/.worktrees/8d2d0392/src/stage-contract.js +0 -948
- package/.worktrees/8d2d0392/src/stage-review.js +0 -597
- package/.worktrees/8d2d0392/src/stages/archive.js +0 -199
- package/.worktrees/8d2d0392/src/stages/brainstorm-auto.js +0 -285
- package/.worktrees/8d2d0392/src/stages/brainstorm.js +0 -624
- package/.worktrees/8d2d0392/src/stages/cmd-existence.js +0 -145
- package/.worktrees/8d2d0392/src/stages/doctor.js +0 -540
- package/.worktrees/8d2d0392/src/stages/execute.js +0 -1277
- package/.worktrees/8d2d0392/src/stages/explore.js +0 -43
- package/.worktrees/8d2d0392/src/stages/index.js +0 -29
- package/.worktrees/8d2d0392/src/stages/knowledge.js +0 -514
- package/.worktrees/8d2d0392/src/stages/plan-postcheck.js +0 -1398
- package/.worktrees/8d2d0392/src/stages/plan.js +0 -651
- package/.worktrees/8d2d0392/src/stages/quick.js +0 -167
- package/.worktrees/8d2d0392/src/stages/scan.js +0 -608
- package/.worktrees/8d2d0392/src/stages/status.js +0 -64
- package/.worktrees/8d2d0392/src/stages/verify.js +0 -246
- package/.worktrees/8d2d0392/src/sync.js +0 -1470
- package/.worktrees/8d2d0392/src/task-review.js +0 -1498
- package/.worktrees/8d2d0392/src/taskcard-placeholders.js +0 -21
- package/.worktrees/8d2d0392/src/taskcard.js +0 -217
- package/.worktrees/8d2d0392/src/verify-postcheck.js +0 -1718
- package/.worktrees/8d2d0392/src/verify-probes.js +0 -327
- package/.worktrees/8d2d0392/src/version.js +0 -19
- package/.worktrees/8d2d0392/src/workflow.js +0 -600
- package/.worktrees/8d2d0392/src/workspace.js +0 -125
- package/.worktrees/8d2d0392/src/worktree-apply.js +0 -1611
- package/.worktrees/8d2d0392/src/worktree-deps.js +0 -576
- package/.worktrees/8d2d0392/src/worktree.js +0 -1838
- package/.worktrees/8d2d0392/templates/claude-instruction.md +0 -23
- package/.worktrees/8d2d0392/templates/prompts/taskcard-rules.md +0 -29
- package/.worktrees/8d2d0392/templates/prompts/testcase-design.md +0 -12
- package/.worktrees/8d2d0392/templates/prompts/verify-probes.md +0 -32
- package/.worktrees/8d2d0392/templates/workflows/archive-impact.yaml +0 -79
- package/.worktrees/8d2d0392/templates/workflows/scan-docs.yaml +0 -132
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.worktrees/c1eae35e/.gitattributes +0 -2
- package/.worktrees/c1eae35e/.husky/pre-push +0 -20
- package/.worktrees/c1eae35e/README.md +0 -203
- package/.worktrees/c1eae35e/SKILL.md +0 -91
- package/.worktrees/c1eae35e/architecture-analysis.md +0 -448
- package/.worktrees/c1eae35e/bin/sillyspec.js +0 -2
- package/.worktrees/c1eae35e/eval/README.md +0 -86
- package/.worktrees/c1eae35e/eval/eval.config.json +0 -28
- package/.worktrees/c1eae35e/eval/lib/adapters/cli.mjs +0 -63
- package/.worktrees/c1eae35e/eval/lib/adapters/dryrun.mjs +0 -27
- package/.worktrees/c1eae35e/eval/lib/config.mjs +0 -82
- package/.worktrees/c1eae35e/eval/lib/db.mjs +0 -76
- package/.worktrees/c1eae35e/eval/lib/report.mjs +0 -120
- package/.worktrees/c1eae35e/eval/lib/runner.mjs +0 -157
- package/.worktrees/c1eae35e/eval/lib/tasks.mjs +0 -73
- package/.worktrees/c1eae35e/eval/lib/util.mjs +0 -107
- package/.worktrees/c1eae35e/eval/lib/workdir.mjs +0 -30
- package/.worktrees/c1eae35e/eval/run.mjs +0 -83
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/files/package.json +0 -6
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/task.json +0 -6
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/verify.mjs +0 -28
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/package.json +0 -6
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/task.json +0 -6
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/verify.mjs +0 -31
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/data/notes.txt +0 -5
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/package.json +0 -6
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/task.json +0 -6
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/verify.mjs +0 -38
- package/.worktrees/c1eae35e/logo.jpg +0 -0
- package/.worktrees/c1eae35e/package-lock.json +0 -977
- package/.worktrees/c1eae35e/package.json +0 -41
- package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.worktrees/c1eae35e/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/index.html +0 -16
- package/.worktrees/c1eae35e/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.worktrees/c1eae35e/packages/dashboard/package.json +0 -25
- package/.worktrees/c1eae35e/packages/dashboard/server/executor.js +0 -95
- package/.worktrees/c1eae35e/packages/dashboard/server/index.js +0 -679
- package/.worktrees/c1eae35e/packages/dashboard/server/parser.js +0 -526
- package/.worktrees/c1eae35e/packages/dashboard/server/watcher.js +0 -357
- package/.worktrees/c1eae35e/src/agent-session-log.js +0 -803
- package/.worktrees/c1eae35e/src/change-list.js +0 -290
- package/.worktrees/c1eae35e/src/change-risk-profile.js +0 -339
- package/.worktrees/c1eae35e/src/check-primitives.js +0 -65
- package/.worktrees/c1eae35e/src/classify-change.js +0 -109
- package/.worktrees/c1eae35e/src/commit-suggest.js +0 -202
- package/.worktrees/c1eae35e/src/config-cat.js +0 -88
- package/.worktrees/c1eae35e/src/config-schema.js +0 -328
- package/.worktrees/c1eae35e/src/constants.js +0 -97
- package/.worktrees/c1eae35e/src/contract-matrix.js +0 -533
- package/.worktrees/c1eae35e/src/datetime.js +0 -20
- package/.worktrees/c1eae35e/src/db-engine.js +0 -55
- package/.worktrees/c1eae35e/src/db.js +0 -381
- package/.worktrees/c1eae35e/src/decision-distill.js +0 -517
- package/.worktrees/c1eae35e/src/dispatch/backends/local-agent.js +0 -155
- package/.worktrees/c1eae35e/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.worktrees/c1eae35e/src/dispatch/probe.js +0 -246
- package/.worktrees/c1eae35e/src/dispatch/strategy.js +0 -121
- package/.worktrees/c1eae35e/src/docs-check.js +0 -825
- package/.worktrees/c1eae35e/src/docs-debt.js +0 -393
- package/.worktrees/c1eae35e/src/docs-gate.js +0 -107
- package/.worktrees/c1eae35e/src/doctor-diagnostics.js +0 -1099
- package/.worktrees/c1eae35e/src/endpoint-extractor.js +0 -409
- package/.worktrees/c1eae35e/src/foreign-declared.js +0 -155
- package/.worktrees/c1eae35e/src/fs-atomic.js +0 -73
- package/.worktrees/c1eae35e/src/git-helper.js +0 -150
- package/.worktrees/c1eae35e/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.worktrees/c1eae35e/src/hooks/worktree-guard.js +0 -892
- package/.worktrees/c1eae35e/src/index.js +0 -2854
- package/.worktrees/c1eae35e/src/init.js +0 -626
- package/.worktrees/c1eae35e/src/knowledge-match.js +0 -231
- package/.worktrees/c1eae35e/src/local-detect.js +0 -128
- package/.worktrees/c1eae35e/src/local-register.js +0 -104
- package/.worktrees/c1eae35e/src/machine-interface.js +0 -543
- package/.worktrees/c1eae35e/src/migrate.js +0 -127
- package/.worktrees/c1eae35e/src/module-impact.js +0 -166
- package/.worktrees/c1eae35e/src/module-resolve.js +0 -222
- package/.worktrees/c1eae35e/src/modules.js +0 -580
- package/.worktrees/c1eae35e/src/plan-adopt-waves.js +0 -126
- package/.worktrees/c1eae35e/src/progress/change-registry.js +0 -336
- package/.worktrees/c1eae35e/src/progress/consistency-doctor.js +0 -355
- package/.worktrees/c1eae35e/src/progress/shared.js +0 -36
- package/.worktrees/c1eae35e/src/progress/stage-machine.js +0 -594
- package/.worktrees/c1eae35e/src/progress/step-store.js +0 -265
- package/.worktrees/c1eae35e/src/progress.js +0 -1304
- package/.worktrees/c1eae35e/src/quick-recommend.js +0 -115
- package/.worktrees/c1eae35e/src/quicklog.js +0 -883
- package/.worktrees/c1eae35e/src/review-tier.js +0 -77
- package/.worktrees/c1eae35e/src/run/command.js +0 -1641
- package/.worktrees/c1eae35e/src/run/complete-handlers.js +0 -1552
- package/.worktrees/c1eae35e/src/run/complete.js +0 -1259
- package/.worktrees/c1eae35e/src/run/concurrent-detect.js +0 -156
- package/.worktrees/c1eae35e/src/run/gates.js +0 -1111
- package/.worktrees/c1eae35e/src/run/multi-repo-context.js +0 -208
- package/.worktrees/c1eae35e/src/run/next.js +0 -128
- package/.worktrees/c1eae35e/src/run/prompt.js +0 -843
- package/.worktrees/c1eae35e/src/run/quick-audit.js +0 -186
- package/.worktrees/c1eae35e/src/run/scan-profile.js +0 -269
- package/.worktrees/c1eae35e/src/run/shared.js +0 -1562
- package/.worktrees/c1eae35e/src/run/stage.js +0 -587
- package/.worktrees/c1eae35e/src/run.js +0 -23
- package/.worktrees/c1eae35e/src/scan-diff.js +0 -388
- package/.worktrees/c1eae35e/src/scan-postcheck.js +0 -524
- package/.worktrees/c1eae35e/src/scan-staleness.js +0 -95
- package/.worktrees/c1eae35e/src/setup.js +0 -414
- package/.worktrees/c1eae35e/src/sillyhub-mcp/client.js +0 -597
- package/.worktrees/c1eae35e/src/sillyhub-mcp/config.js +0 -62
- package/.worktrees/c1eae35e/src/spec-dir-typo.js +0 -50
- package/.worktrees/c1eae35e/src/spec-sync.js +0 -358
- package/.worktrees/c1eae35e/src/stage-contract-engine.js +0 -171
- package/.worktrees/c1eae35e/src/stage-contract-spec.js +0 -551
- package/.worktrees/c1eae35e/src/stage-contract.js +0 -948
- package/.worktrees/c1eae35e/src/stage-review.js +0 -597
- package/.worktrees/c1eae35e/src/stages/archive.js +0 -199
- package/.worktrees/c1eae35e/src/stages/brainstorm-auto.js +0 -285
- package/.worktrees/c1eae35e/src/stages/brainstorm.js +0 -624
- package/.worktrees/c1eae35e/src/stages/cmd-existence.js +0 -145
- package/.worktrees/c1eae35e/src/stages/doctor.js +0 -540
- package/.worktrees/c1eae35e/src/stages/execute.js +0 -1277
- package/.worktrees/c1eae35e/src/stages/explore.js +0 -43
- package/.worktrees/c1eae35e/src/stages/index.js +0 -29
- package/.worktrees/c1eae35e/src/stages/knowledge.js +0 -514
- package/.worktrees/c1eae35e/src/stages/plan-postcheck.js +0 -1398
- package/.worktrees/c1eae35e/src/stages/plan.js +0 -655
- package/.worktrees/c1eae35e/src/stages/quick.js +0 -167
- package/.worktrees/c1eae35e/src/stages/scan.js +0 -608
- package/.worktrees/c1eae35e/src/stages/status.js +0 -64
- package/.worktrees/c1eae35e/src/stages/verify.js +0 -246
- package/.worktrees/c1eae35e/src/sync.js +0 -1470
- package/.worktrees/c1eae35e/src/task-review.js +0 -1498
- package/.worktrees/c1eae35e/src/taskcard-placeholders.js +0 -21
- package/.worktrees/c1eae35e/src/taskcard.js +0 -250
- package/.worktrees/c1eae35e/src/verify-postcheck.js +0 -1718
- package/.worktrees/c1eae35e/src/verify-probes.js +0 -327
- package/.worktrees/c1eae35e/src/version.js +0 -19
- package/.worktrees/c1eae35e/src/workflow.js +0 -600
- package/.worktrees/c1eae35e/src/workspace.js +0 -125
- package/.worktrees/c1eae35e/src/worktree-apply.js +0 -1611
- package/.worktrees/c1eae35e/src/worktree-deps.js +0 -668
- package/.worktrees/c1eae35e/src/worktree.js +0 -1849
- package/.worktrees/c1eae35e/templates/claude-instruction.md +0 -23
- package/.worktrees/c1eae35e/templates/prompts/taskcard-rules.md +0 -29
- package/.worktrees/c1eae35e/templates/prompts/testcase-design.md +0 -12
- package/.worktrees/c1eae35e/templates/prompts/verify-probes.md +0 -32
- package/.worktrees/c1eae35e/templates/workflows/archive-impact.yaml +0 -79
- package/.worktrees/c1eae35e/templates/workflows/scan-docs.yaml +0 -132
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-propose/SKILL.md +0 -87
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.worktrees/dafc71ad/.gitattributes +0 -2
- package/.worktrees/dafc71ad/.husky/pre-push +0 -20
- package/.worktrees/dafc71ad/README.md +0 -203
- package/.worktrees/dafc71ad/SKILL.md +0 -91
- package/.worktrees/dafc71ad/analysis.md +0 -366
- package/.worktrees/dafc71ad/architecture-analysis.md +0 -448
- package/.worktrees/dafc71ad/bin/sillyspec.js +0 -2
- package/.worktrees/dafc71ad/eval/README.md +0 -86
- package/.worktrees/dafc71ad/eval/eval.config.json +0 -28
- package/.worktrees/dafc71ad/eval/lib/adapters/cli.mjs +0 -63
- package/.worktrees/dafc71ad/eval/lib/adapters/dryrun.mjs +0 -27
- package/.worktrees/dafc71ad/eval/lib/config.mjs +0 -82
- package/.worktrees/dafc71ad/eval/lib/db.mjs +0 -76
- package/.worktrees/dafc71ad/eval/lib/report.mjs +0 -120
- package/.worktrees/dafc71ad/eval/lib/runner.mjs +0 -157
- package/.worktrees/dafc71ad/eval/lib/tasks.mjs +0 -73
- package/.worktrees/dafc71ad/eval/lib/util.mjs +0 -107
- package/.worktrees/dafc71ad/eval/lib/workdir.mjs +0 -30
- package/.worktrees/dafc71ad/eval/run.mjs +0 -83
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/files/package.json +0 -6
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/task.json +0 -6
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/verify.mjs +0 -28
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/package.json +0 -6
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/task.json +0 -6
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/verify.mjs +0 -31
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/data/notes.txt +0 -5
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/package.json +0 -6
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/task.json +0 -6
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/verify.mjs +0 -38
- package/.worktrees/dafc71ad/logo.jpg +0 -0
- package/.worktrees/dafc71ad/package-lock.json +0 -977
- package/.worktrees/dafc71ad/package.json +0 -41
- package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.worktrees/dafc71ad/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/index.html +0 -16
- package/.worktrees/dafc71ad/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.worktrees/dafc71ad/packages/dashboard/package.json +0 -25
- package/.worktrees/dafc71ad/packages/dashboard/server/executor.js +0 -95
- package/.worktrees/dafc71ad/packages/dashboard/server/index.js +0 -679
- package/.worktrees/dafc71ad/packages/dashboard/server/parser.js +0 -526
- package/.worktrees/dafc71ad/packages/dashboard/server/watcher.js +0 -357
- package/.worktrees/dafc71ad/src/agent-session-log.js +0 -803
- package/.worktrees/dafc71ad/src/change-list.js +0 -290
- package/.worktrees/dafc71ad/src/change-risk-profile.js +0 -339
- package/.worktrees/dafc71ad/src/check-primitives.js +0 -65
- package/.worktrees/dafc71ad/src/classify-change.js +0 -109
- package/.worktrees/dafc71ad/src/commit-suggest.js +0 -202
- package/.worktrees/dafc71ad/src/config-cat.js +0 -88
- package/.worktrees/dafc71ad/src/config-schema.js +0 -328
- package/.worktrees/dafc71ad/src/constants.js +0 -97
- package/.worktrees/dafc71ad/src/contract-matrix.js +0 -533
- package/.worktrees/dafc71ad/src/datetime.js +0 -20
- package/.worktrees/dafc71ad/src/db-engine.js +0 -55
- package/.worktrees/dafc71ad/src/db.js +0 -381
- package/.worktrees/dafc71ad/src/decision-distill.js +0 -517
- package/.worktrees/dafc71ad/src/dispatch/backends/local-agent.js +0 -155
- package/.worktrees/dafc71ad/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.worktrees/dafc71ad/src/dispatch/probe.js +0 -246
- package/.worktrees/dafc71ad/src/dispatch/strategy.js +0 -121
- package/.worktrees/dafc71ad/src/docs-check.js +0 -825
- package/.worktrees/dafc71ad/src/docs-debt.js +0 -393
- package/.worktrees/dafc71ad/src/docs-gate.js +0 -107
- package/.worktrees/dafc71ad/src/doctor-diagnostics.js +0 -1099
- package/.worktrees/dafc71ad/src/endpoint-extractor.js +0 -409
- package/.worktrees/dafc71ad/src/foreign-declared.js +0 -155
- package/.worktrees/dafc71ad/src/fs-atomic.js +0 -73
- package/.worktrees/dafc71ad/src/git-helper.js +0 -150
- package/.worktrees/dafc71ad/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.worktrees/dafc71ad/src/hooks/worktree-guard.js +0 -892
- package/.worktrees/dafc71ad/src/index.js +0 -2854
- package/.worktrees/dafc71ad/src/init.js +0 -626
- package/.worktrees/dafc71ad/src/knowledge-match.js +0 -231
- package/.worktrees/dafc71ad/src/local-detect.js +0 -128
- package/.worktrees/dafc71ad/src/local-register.js +0 -104
- package/.worktrees/dafc71ad/src/machine-interface.js +0 -543
- package/.worktrees/dafc71ad/src/migrate.js +0 -127
- package/.worktrees/dafc71ad/src/module-impact.js +0 -166
- package/.worktrees/dafc71ad/src/module-resolve.js +0 -222
- package/.worktrees/dafc71ad/src/modules.js +0 -580
- package/.worktrees/dafc71ad/src/plan-adopt-waves.js +0 -126
- package/.worktrees/dafc71ad/src/progress/change-registry.js +0 -336
- package/.worktrees/dafc71ad/src/progress/consistency-doctor.js +0 -355
- package/.worktrees/dafc71ad/src/progress/shared.js +0 -36
- package/.worktrees/dafc71ad/src/progress/stage-machine.js +0 -594
- package/.worktrees/dafc71ad/src/progress/step-store.js +0 -265
- package/.worktrees/dafc71ad/src/progress.js +0 -1304
- package/.worktrees/dafc71ad/src/quick-recommend.js +0 -115
- package/.worktrees/dafc71ad/src/quicklog.js +0 -883
- package/.worktrees/dafc71ad/src/review-tier.js +0 -77
- package/.worktrees/dafc71ad/src/run/command.js +0 -1641
- package/.worktrees/dafc71ad/src/run/complete-handlers.js +0 -1552
- package/.worktrees/dafc71ad/src/run/complete.js +0 -1259
- package/.worktrees/dafc71ad/src/run/concurrent-detect.js +0 -156
- package/.worktrees/dafc71ad/src/run/gates.js +0 -1111
- package/.worktrees/dafc71ad/src/run/multi-repo-context.js +0 -208
- package/.worktrees/dafc71ad/src/run/next.js +0 -128
- package/.worktrees/dafc71ad/src/run/prompt.js +0 -843
- package/.worktrees/dafc71ad/src/run/quick-audit.js +0 -186
- package/.worktrees/dafc71ad/src/run/scan-profile.js +0 -269
- package/.worktrees/dafc71ad/src/run/shared.js +0 -1562
- package/.worktrees/dafc71ad/src/run/stage.js +0 -587
- package/.worktrees/dafc71ad/src/run.js +0 -23
- package/.worktrees/dafc71ad/src/scan-diff.js +0 -388
- package/.worktrees/dafc71ad/src/scan-postcheck.js +0 -524
- package/.worktrees/dafc71ad/src/scan-staleness.js +0 -95
- package/.worktrees/dafc71ad/src/setup.js +0 -414
- package/.worktrees/dafc71ad/src/sillyhub-mcp/client.js +0 -597
- package/.worktrees/dafc71ad/src/sillyhub-mcp/config.js +0 -62
- package/.worktrees/dafc71ad/src/spec-dir-typo.js +0 -50
- package/.worktrees/dafc71ad/src/spec-sync.js +0 -358
- package/.worktrees/dafc71ad/src/stage-contract-engine.js +0 -171
- package/.worktrees/dafc71ad/src/stage-contract-spec.js +0 -551
- package/.worktrees/dafc71ad/src/stage-contract.js +0 -948
- package/.worktrees/dafc71ad/src/stage-review.js +0 -597
- package/.worktrees/dafc71ad/src/stages/archive.js +0 -199
- package/.worktrees/dafc71ad/src/stages/brainstorm-auto.js +0 -285
- package/.worktrees/dafc71ad/src/stages/brainstorm.js +0 -624
- package/.worktrees/dafc71ad/src/stages/cmd-existence.js +0 -145
- package/.worktrees/dafc71ad/src/stages/doctor.js +0 -540
- package/.worktrees/dafc71ad/src/stages/execute.js +0 -1277
- package/.worktrees/dafc71ad/src/stages/explore.js +0 -43
- package/.worktrees/dafc71ad/src/stages/index.js +0 -29
- package/.worktrees/dafc71ad/src/stages/knowledge.js +0 -514
- package/.worktrees/dafc71ad/src/stages/plan-postcheck.js +0 -1398
- package/.worktrees/dafc71ad/src/stages/plan.js +0 -655
- package/.worktrees/dafc71ad/src/stages/quick.js +0 -167
- package/.worktrees/dafc71ad/src/stages/scan.js +0 -608
- package/.worktrees/dafc71ad/src/stages/status.js +0 -64
- package/.worktrees/dafc71ad/src/stages/verify.js +0 -246
- package/.worktrees/dafc71ad/src/sync.js +0 -1470
- package/.worktrees/dafc71ad/src/task-review.js +0 -1498
- package/.worktrees/dafc71ad/src/taskcard-placeholders.js +0 -21
- package/.worktrees/dafc71ad/src/taskcard.js +0 -250
- package/.worktrees/dafc71ad/src/verify-postcheck.js +0 -1718
- package/.worktrees/dafc71ad/src/verify-probes.js +0 -327
- package/.worktrees/dafc71ad/src/version.js +0 -19
- package/.worktrees/dafc71ad/src/workflow.js +0 -600
- package/.worktrees/dafc71ad/src/workspace.js +0 -125
- package/.worktrees/dafc71ad/src/worktree-apply.js +0 -1611
- package/.worktrees/dafc71ad/src/worktree-deps.js +0 -668
- package/.worktrees/dafc71ad/src/worktree.js +0 -1849
- package/.worktrees/dafc71ad/templates/claude-instruction.md +0 -23
- package/.worktrees/dafc71ad/templates/prompts/taskcard-rules.md +0 -29
- package/.worktrees/dafc71ad/templates/prompts/testcase-design.md +0 -12
- package/.worktrees/dafc71ad/templates/prompts/verify-probes.md +0 -32
- package/.worktrees/dafc71ad/templates/workflows/archive-impact.yaml +0 -79
- package/.worktrees/dafc71ad/templates/workflows/scan-docs.yaml +0 -132
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-archive/SKILL.md +0 -87
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-auto/SKILL.md +0 -93
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-commit/SKILL.md +0 -67
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-continue/SKILL.md +0 -47
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-execute/SKILL.md +0 -214
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-explore/SKILL.md +0 -102
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-export/SKILL.md +0 -57
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-init/SKILL.md +0 -177
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-plan/SKILL.md +0 -156
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-propose/SKILL.md +0 -87
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-quick/SKILL.md +0 -116
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-resume/SKILL.md +0 -70
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-scan/SKILL.md +0 -79
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-state/SKILL.md +0 -64
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-status/SKILL.md +0 -54
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-verify/SKILL.md +0 -87
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
- package/.worktrees/e58fcc4c/.gitattributes +0 -2
- package/.worktrees/e58fcc4c/.husky/pre-push +0 -20
- package/.worktrees/e58fcc4c/README.md +0 -203
- package/.worktrees/e58fcc4c/SKILL.md +0 -91
- package/.worktrees/e58fcc4c/architecture-analysis.md +0 -503
- package/.worktrees/e58fcc4c/bin/sillyspec.js +0 -2
- package/.worktrees/e58fcc4c/eval/README.md +0 -86
- package/.worktrees/e58fcc4c/eval/eval.config.json +0 -28
- package/.worktrees/e58fcc4c/eval/lib/adapters/cli.mjs +0 -63
- package/.worktrees/e58fcc4c/eval/lib/adapters/dryrun.mjs +0 -27
- package/.worktrees/e58fcc4c/eval/lib/config.mjs +0 -82
- package/.worktrees/e58fcc4c/eval/lib/db.mjs +0 -76
- package/.worktrees/e58fcc4c/eval/lib/report.mjs +0 -120
- package/.worktrees/e58fcc4c/eval/lib/runner.mjs +0 -157
- package/.worktrees/e58fcc4c/eval/lib/tasks.mjs +0 -73
- package/.worktrees/e58fcc4c/eval/lib/util.mjs +0 -107
- package/.worktrees/e58fcc4c/eval/lib/workdir.mjs +0 -30
- package/.worktrees/e58fcc4c/eval/run.mjs +0 -83
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/files/package.json +0 -6
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/task.json +0 -6
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/verify.mjs +0 -28
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/package.json +0 -6
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/task.json +0 -6
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/verify.mjs +0 -31
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/data/notes.txt +0 -5
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/package.json +0 -6
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/task.json +0 -6
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/verify.mjs +0 -38
- package/.worktrees/e58fcc4c/logo.jpg +0 -0
- package/.worktrees/e58fcc4c/package-lock.json +0 -977
- package/.worktrees/e58fcc4c/package.json +0 -41
- package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
- package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/.worktrees/e58fcc4c/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/index.html +0 -16
- package/.worktrees/e58fcc4c/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-overview.html +0 -256
- package/.worktrees/e58fcc4c/packages/dashboard/package.json +0 -25
- package/.worktrees/e58fcc4c/packages/dashboard/server/executor.js +0 -95
- package/.worktrees/e58fcc4c/packages/dashboard/server/index.js +0 -679
- package/.worktrees/e58fcc4c/packages/dashboard/server/parser.js +0 -526
- package/.worktrees/e58fcc4c/packages/dashboard/server/watcher.js +0 -357
- package/.worktrees/e58fcc4c/src/agent-session-log.js +0 -803
- package/.worktrees/e58fcc4c/src/change-list.js +0 -290
- package/.worktrees/e58fcc4c/src/change-risk-profile.js +0 -339
- package/.worktrees/e58fcc4c/src/check-primitives.js +0 -65
- package/.worktrees/e58fcc4c/src/classify-change.js +0 -109
- package/.worktrees/e58fcc4c/src/commit-suggest.js +0 -202
- package/.worktrees/e58fcc4c/src/config-cat.js +0 -88
- package/.worktrees/e58fcc4c/src/config-schema.js +0 -328
- package/.worktrees/e58fcc4c/src/constants.js +0 -97
- package/.worktrees/e58fcc4c/src/contract-matrix.js +0 -533
- package/.worktrees/e58fcc4c/src/datetime.js +0 -20
- package/.worktrees/e58fcc4c/src/db-engine.js +0 -55
- package/.worktrees/e58fcc4c/src/db.js +0 -381
- package/.worktrees/e58fcc4c/src/decision-distill.js +0 -517
- package/.worktrees/e58fcc4c/src/dispatch/backends/local-agent.js +0 -155
- package/.worktrees/e58fcc4c/src/dispatch/backends/sillyhub-mcp.js +0 -245
- package/.worktrees/e58fcc4c/src/dispatch/probe.js +0 -246
- package/.worktrees/e58fcc4c/src/dispatch/strategy.js +0 -121
- package/.worktrees/e58fcc4c/src/docs-check.js +0 -825
- package/.worktrees/e58fcc4c/src/docs-debt.js +0 -393
- package/.worktrees/e58fcc4c/src/docs-gate.js +0 -107
- package/.worktrees/e58fcc4c/src/doctor-diagnostics.js +0 -1099
- package/.worktrees/e58fcc4c/src/endpoint-extractor.js +0 -409
- package/.worktrees/e58fcc4c/src/foreign-declared.js +0 -155
- package/.worktrees/e58fcc4c/src/fs-atomic.js +0 -73
- package/.worktrees/e58fcc4c/src/git-helper.js +0 -150
- package/.worktrees/e58fcc4c/src/hooks/claude-pre-tool-use.cjs +0 -130
- package/.worktrees/e58fcc4c/src/hooks/worktree-guard.js +0 -892
- package/.worktrees/e58fcc4c/src/index.js +0 -2854
- package/.worktrees/e58fcc4c/src/init.js +0 -626
- package/.worktrees/e58fcc4c/src/knowledge-match.js +0 -231
- package/.worktrees/e58fcc4c/src/local-detect.js +0 -128
- package/.worktrees/e58fcc4c/src/local-register.js +0 -104
- package/.worktrees/e58fcc4c/src/machine-interface.js +0 -543
- package/.worktrees/e58fcc4c/src/migrate.js +0 -127
- package/.worktrees/e58fcc4c/src/module-impact.js +0 -166
- package/.worktrees/e58fcc4c/src/module-resolve.js +0 -222
- package/.worktrees/e58fcc4c/src/modules.js +0 -580
- package/.worktrees/e58fcc4c/src/plan-adopt-waves.js +0 -126
- package/.worktrees/e58fcc4c/src/progress/change-registry.js +0 -336
- package/.worktrees/e58fcc4c/src/progress/consistency-doctor.js +0 -355
- package/.worktrees/e58fcc4c/src/progress/shared.js +0 -36
- package/.worktrees/e58fcc4c/src/progress/stage-machine.js +0 -594
- package/.worktrees/e58fcc4c/src/progress/step-store.js +0 -265
- package/.worktrees/e58fcc4c/src/progress.js +0 -1304
- package/.worktrees/e58fcc4c/src/quick-recommend.js +0 -115
- package/.worktrees/e58fcc4c/src/quicklog.js +0 -883
- package/.worktrees/e58fcc4c/src/review-tier.js +0 -77
- package/.worktrees/e58fcc4c/src/run/command.js +0 -1641
- package/.worktrees/e58fcc4c/src/run/complete-handlers.js +0 -1552
- package/.worktrees/e58fcc4c/src/run/complete.js +0 -1259
- package/.worktrees/e58fcc4c/src/run/concurrent-detect.js +0 -156
- package/.worktrees/e58fcc4c/src/run/gates.js +0 -1111
- package/.worktrees/e58fcc4c/src/run/multi-repo-context.js +0 -208
- package/.worktrees/e58fcc4c/src/run/next.js +0 -128
- package/.worktrees/e58fcc4c/src/run/prompt.js +0 -843
- package/.worktrees/e58fcc4c/src/run/quick-audit.js +0 -186
- package/.worktrees/e58fcc4c/src/run/scan-profile.js +0 -269
- package/.worktrees/e58fcc4c/src/run/shared.js +0 -1562
- package/.worktrees/e58fcc4c/src/run/stage.js +0 -587
- package/.worktrees/e58fcc4c/src/run.js +0 -23
- package/.worktrees/e58fcc4c/src/scan-diff.js +0 -388
- package/.worktrees/e58fcc4c/src/scan-postcheck.js +0 -524
- package/.worktrees/e58fcc4c/src/scan-staleness.js +0 -95
- package/.worktrees/e58fcc4c/src/setup.js +0 -414
- package/.worktrees/e58fcc4c/src/sillyhub-mcp/client.js +0 -597
- package/.worktrees/e58fcc4c/src/sillyhub-mcp/config.js +0 -62
- package/.worktrees/e58fcc4c/src/spec-dir-typo.js +0 -50
- package/.worktrees/e58fcc4c/src/spec-sync.js +0 -358
- package/.worktrees/e58fcc4c/src/stage-contract-engine.js +0 -171
- package/.worktrees/e58fcc4c/src/stage-contract-spec.js +0 -551
- package/.worktrees/e58fcc4c/src/stage-contract.js +0 -948
- package/.worktrees/e58fcc4c/src/stage-review.js +0 -597
- package/.worktrees/e58fcc4c/src/stages/archive.js +0 -199
- package/.worktrees/e58fcc4c/src/stages/brainstorm-auto.js +0 -285
- package/.worktrees/e58fcc4c/src/stages/brainstorm.js +0 -624
- package/.worktrees/e58fcc4c/src/stages/cmd-existence.js +0 -145
- package/.worktrees/e58fcc4c/src/stages/doctor.js +0 -540
- package/.worktrees/e58fcc4c/src/stages/execute.js +0 -1277
- package/.worktrees/e58fcc4c/src/stages/explore.js +0 -43
- package/.worktrees/e58fcc4c/src/stages/index.js +0 -29
- package/.worktrees/e58fcc4c/src/stages/knowledge.js +0 -514
- package/.worktrees/e58fcc4c/src/stages/plan-postcheck.js +0 -1398
- package/.worktrees/e58fcc4c/src/stages/plan.js +0 -655
- package/.worktrees/e58fcc4c/src/stages/quick.js +0 -167
- package/.worktrees/e58fcc4c/src/stages/scan.js +0 -608
- package/.worktrees/e58fcc4c/src/stages/status.js +0 -64
- package/.worktrees/e58fcc4c/src/stages/verify.js +0 -246
- package/.worktrees/e58fcc4c/src/sync.js +0 -1470
- package/.worktrees/e58fcc4c/src/task-review.js +0 -1498
- package/.worktrees/e58fcc4c/src/taskcard-placeholders.js +0 -21
- package/.worktrees/e58fcc4c/src/taskcard.js +0 -250
- package/.worktrees/e58fcc4c/src/verify-postcheck.js +0 -1718
- package/.worktrees/e58fcc4c/src/verify-probes.js +0 -327
- package/.worktrees/e58fcc4c/src/version.js +0 -19
- package/.worktrees/e58fcc4c/src/workflow.js +0 -600
- package/.worktrees/e58fcc4c/src/workspace.js +0 -125
- package/.worktrees/e58fcc4c/src/worktree-apply.js +0 -1611
- package/.worktrees/e58fcc4c/src/worktree-deps.js +0 -668
- package/.worktrees/e58fcc4c/src/worktree.js +0 -1849
- package/.worktrees/e58fcc4c/templates/claude-instruction.md +0 -23
- package/.worktrees/e58fcc4c/templates/prompts/taskcard-rules.md +0 -29
- package/.worktrees/e58fcc4c/templates/prompts/testcase-design.md +0 -12
- package/.worktrees/e58fcc4c/templates/prompts/verify-probes.md +0 -32
- package/.worktrees/e58fcc4c/templates/workflows/archive-impact.yaml +0 -79
- package/.worktrees/e58fcc4c/templates/workflows/scan-docs.yaml +0 -132
- package/templates/claude-instruction.md +0 -23
|
@@ -1,1641 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* run/command.js(W6 Step8c 从 run.js 抽出)。
|
|
3
|
-
*
|
|
4
|
-
* 命令分发层:runCommand(主入口,被 src/index.js + 6 个 test import)+ auto 模式 +
|
|
5
|
-
* ensureStageSteps(被 step-migration test import)+ 4 个 runCommand 私有 helper
|
|
6
|
-
* (resolveChangeName / resolveChangeNameAuto / showStatus / resetStage)。
|
|
7
|
-
*
|
|
8
|
-
* 调用图(单向,无环):runCommand → { runStage(stage.js), runAutoMode, resetStage, showStatus,
|
|
9
|
-
* ensureStageSteps, completeStep/skip/wait/continue(complete.js) };runAutoMode → { outputStep,
|
|
10
|
-
* completeStep, ensureStageSteps, checkApproval(shared) },不调 runStage(内联 outputStep)。
|
|
11
|
-
*
|
|
12
|
-
* 安全锚:run.js 始终 barrel。runCommand + ensureStageSteps 被 test 直接 import → run.js barrel
|
|
13
|
-
* re-export(契约保留);其余 5 函数 runCommand 私有,无 test 直接 import。
|
|
14
|
-
*
|
|
15
|
-
* 路径修正(相对 src/run/):
|
|
16
|
-
* - 动态 import './init.js' / './worktree.js' / './classify-change.js' → '../'(src/ 下退一层)
|
|
17
|
-
* - 'fs'(runCommand 内 await import('fs'))裸模块名不变
|
|
18
|
-
* - 静态 import './progress.js' / './stage-contract.js' / './stages/*' / './fs-atomic.js' → '../'
|
|
19
|
-
* './run/shared.js' / './run/quick-audit.js' / './run/prompt.js' / './run/complete.js' /
|
|
20
|
-
* './run/stage.js' → './shared.js' 等同级
|
|
21
|
-
*/
|
|
22
|
-
import { basename, join, resolve, dirname } from 'node:path'
|
|
23
|
-
import { existsSync, readdirSync, mkdirSync, writeFileSync, readFileSync, rmSync } from 'node:fs'
|
|
24
|
-
import { randomBytes, randomUUID } from 'node:crypto'
|
|
25
|
-
import { writeAtomicSync } from '../fs-atomic.js'
|
|
26
|
-
import { resolveSpecDir, countAncestorSpecDirs, resolveChangeDir, triggerSync, getStageSteps, formatWaitOptions, checkApproval, warnApprovalUnknown, didYouMean, assertSafeChangeName, detectQuickSessionDrift, detectWorktreeSpecDrift, resolveRuntimeRoot, writePlatformPointer, checkPlatformManaged, isSelfReferentialSpecRoot, PLATFORM_MANAGED_FILENAME } from './shared.js'
|
|
27
|
-
import { resolveQuickLinkedChanges } from './quick-audit.js'
|
|
28
|
-
import { outputStep } from './prompt.js'
|
|
29
|
-
import { completeStep, skipStep, waitStep, continueStep } from './complete.js'
|
|
30
|
-
import { runStage } from './stage.js'
|
|
31
|
-
import { sanitizeDesc } from '../quicklog.js'
|
|
32
|
-
import { ProgressManager } from '../progress.js'
|
|
33
|
-
import { validateChangeExists, checkTransition } from '../stage-contract.js'
|
|
34
|
-
import { READONLY_AUXILIARY_STAGES } from '../constants.js'
|
|
35
|
-
import { stageRegistry, auxiliaryStages } from '../stages/index.js'
|
|
36
|
-
import { definition as brainstormAutoDef } from '../stages/brainstorm-auto.js'
|
|
37
|
-
import { setQuickFileNotes } from '../quicklog.js'
|
|
38
|
-
|
|
39
|
-
// F2/F4: 哪些 flag 吃下一个 token 作「值」(其余 --flag 都是布尔,不吞值)。
|
|
40
|
-
// 校验循环只对 VALUE_FLAGS 跳下一个 token(否则 --done 后跟 typo 会被当 --done 的值吞掉)。
|
|
41
|
-
// getFlagValue 也据此拒收「下一个 token 是另一个 flag 名」当值。
|
|
42
|
-
const VALUE_FLAGS = new Set([
|
|
43
|
-
'--reason', '--options', '--answer', '--confirm-mode',
|
|
44
|
-
'--output', '--input', '--change', '--linked-changes',
|
|
45
|
-
'--spec-dir', '--spec-root', '--runtime-root', '--workspace-id', '--scan-run-id',
|
|
46
|
-
'--files', '--file-notes', '--from-step', '--mode', '--dir', '--confirm-mode',
|
|
47
|
-
'--req', '--cause', '--solution', '--result', // quick 末步四字段参数(合成 --output,见 outputText 解析段)
|
|
48
|
-
'--ql', // quick --cancel 显式指定 qlId(缺省读会话 guard.json)
|
|
49
|
-
'--base', // scan diff 基线 commit(吃值;只在 run scan --diff 转发路径消费)
|
|
50
|
-
])
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* 检测 `--files` 是否被空格分隔误用(坑 quick-files-space-separated-silently-drops)。
|
|
54
|
-
*
|
|
55
|
-
* --files 是单值 flag(VALUE_FLAGS:校验循环只跳一个 token、--k=v 只展开一个值),空格分隔的
|
|
56
|
-
* 多文件只有首个被当值,其余沦为位置参数被 `:482` 的 `startsWith('--')` 校验静默忽略 →
|
|
57
|
-
* guard.allowedFiles 只剩首个 → --done 边界审计误拦,边界保护形同虚设。
|
|
58
|
-
*
|
|
59
|
-
* 返回 --files 值及其后所有连续非 flag token(疑似被丢的多文件);length > 1 即误用,调用方
|
|
60
|
-
* fail-loud(process.exit 2,同 run --json :109 显式拒绝静默吞风格)。贪婪收集多值会破坏
|
|
61
|
-
* VALUE_FLAGS 单值框架(校验循环/等号展开/getFlagValue 都假设单值),故仅检测不改语义。
|
|
62
|
-
*
|
|
63
|
-
* 纯函数:无副作用、不读 process、不 mutate 入参,供 command.js 解析 + 单测复用。
|
|
64
|
-
* @param {string[]} flags runCommand 规范化后的 flags 数组(--k=v 已展开)
|
|
65
|
-
* @returns {string[]} --files 值 + 其后连续非 flag token;无 --files / 值是 flag 名 / 含逗号 → []
|
|
66
|
-
*/
|
|
67
|
-
export function detectSpaceSeparatedFiles(flags) {
|
|
68
|
-
const idx = flags.indexOf('--files')
|
|
69
|
-
if (idx === -1) return []
|
|
70
|
-
const val = flags[idx + 1]
|
|
71
|
-
// 值缺失 / 值本身是 flag 名(--files --done 漏值)/ 逗号分隔(正确用法)→ 不检测
|
|
72
|
-
if (!val || val.startsWith('--') || val.includes(',')) return []
|
|
73
|
-
const suspects = [val]
|
|
74
|
-
for (let j = idx + 2; j < flags.length && !flags[j].startsWith('--'); j++) suspects.push(flags[j])
|
|
75
|
-
return suspects
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* 从 progress 或变更目录推导变更名
|
|
80
|
-
*/
|
|
81
|
-
function resolveChangeName(cwd, progress, specDir = null) {
|
|
82
|
-
if (progress.currentChange) return progress.currentChange
|
|
83
|
-
const changesDir = join(specDir || resolveSpecDir(cwd), 'changes')
|
|
84
|
-
if (!existsSync(changesDir)) return null
|
|
85
|
-
const entries = readdirSync(changesDir, { withFileTypes: true })
|
|
86
|
-
.filter(e => e.isDirectory() && e.name !== 'archive')
|
|
87
|
-
if (entries.length === 1) return entries[0].name
|
|
88
|
-
return null
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 确保阶段的 steps 已初始化到 progress
|
|
93
|
-
*/
|
|
94
|
-
export async function ensureStageSteps(progress, stageName, cwd, specDir = null) {
|
|
95
|
-
if (!progress.stages) progress.stages = {}
|
|
96
|
-
|
|
97
|
-
const steps = await getStageSteps(stageName, cwd, progress, specDir)
|
|
98
|
-
if (!steps) return false
|
|
99
|
-
|
|
100
|
-
if (!progress.stages[stageName] || !progress.stages[stageName].steps || progress.stages[stageName].steps.length === 0) {
|
|
101
|
-
progress.stages[stageName] = {
|
|
102
|
-
status: 'in-progress',
|
|
103
|
-
startedAt: new Date().toLocaleString('zh-CN',{hour12:false}),
|
|
104
|
-
completedAt: null,
|
|
105
|
-
steps: steps.map(s => ({ name: s.name, status: 'pending' }))
|
|
106
|
-
}
|
|
107
|
-
return true // 需要写入
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// 检查步骤数量是否匹配(execute 动态步骤可能变化)
|
|
111
|
-
if (progress.stages[stageName].steps.length !== steps.length) {
|
|
112
|
-
const oldSteps = progress.stages[stageName].steps
|
|
113
|
-
// 漂移显式化(坑 execute-step-table-drift,2026-08-20 实证):plan.md Wave 数在 execute
|
|
114
|
-
// 中途被改后 DB 步骤表与重算定义错位(17/12 交替),重播种本身按名保留完成态是对的,
|
|
115
|
-
// 但此前完全静默——agent 只见各处计数打架的报错,不知道发生了什么、该不该继续
|
|
116
|
-
console.warn(`⚠️ ${stageName} 步骤表与当前定义漂移(DB ${oldSteps.length} 步 → 定义 ${steps.length} 步,常见原因:execute 中途修改了 plan.md 的 Wave 结构)`)
|
|
117
|
-
console.warn(` 已按步骤名保留完成态重播种(新增步骤置 pending;Wave 重编号时同名步骤继承旧状态,勾选真相以 tasks.md/review.json 为准)`)
|
|
118
|
-
progress.stages[stageName].steps = steps.map(s => {
|
|
119
|
-
const old = oldSteps.find(step => step.name === s.name)
|
|
120
|
-
if (old) return old // 精确名命中 → 保留旧状态
|
|
121
|
-
// migratedFrom:新步骤是合并/重命名来的(如 brainstorm 13→8 折叠)。
|
|
122
|
-
// 吸收的旧步骤全部 completed → 新步骤标 completed,避免 completed 丢失导致 currentIdx 回跳。
|
|
123
|
-
if (Array.isArray(s.migratedFrom) && s.migratedFrom.length > 0) {
|
|
124
|
-
const migrated = oldSteps.filter(step => s.migratedFrom.includes(step.name))
|
|
125
|
-
if (migrated.length > 0 && migrated.every(step => step.status === 'completed')) {
|
|
126
|
-
return { name: s.name, status: 'completed', migratedFrom: true }
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return { name: s.name, status: 'pending' }
|
|
130
|
-
})
|
|
131
|
-
return true
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return false
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* run <stage> --help/-h 的用法帮助(runCommand 内 --help 短路调用)。
|
|
139
|
-
* 只打印不落盘:帮助查询不该有副作用(建会话/写 QUICKLOG)。
|
|
140
|
-
*/
|
|
141
|
-
function printStageUsage(stageName) {
|
|
142
|
-
const stage = stageRegistry[stageName]
|
|
143
|
-
console.log(`
|
|
144
|
-
sillyspec run ${stageName}${stage && stage.title ? ` — ${stage.title}` : ''}${stage && stage.description ? `\n ${stage.description}` : ''}
|
|
145
|
-
|
|
146
|
-
用法:
|
|
147
|
-
sillyspec run ${stageName} 开始/继续该阶段(输出下一步 prompt)
|
|
148
|
-
sillyspec run ${stageName} --status 查看阶段进度
|
|
149
|
-
sillyspec run ${stageName} --done --output "摘要" [--input "用户原话"] 完成当前步骤
|
|
150
|
-
sillyspec run ${stageName} --change <名> 指定变更(多活跃变更必填)
|
|
151
|
-
|
|
152
|
-
通用参数: --done --output --input --status --skip --reset --reopen --from-step
|
|
153
|
-
--wait --continue --answer --change --spec-dir --non-interactive
|
|
154
|
-
--interactive --skip-approval --json(不支持)
|
|
155
|
-
quick 专属: --linked-changes none|a,b --files a.js,b.js --allow-new
|
|
156
|
-
--allow-delete --force-baseline --confirm --file-notes
|
|
157
|
-
scan 专属: --quick --standard --deep --force-rescan --diff [--base <commit>] [--full] [--report]
|
|
158
|
-
archive专属: --confirm
|
|
159
|
-
`)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* sillyspec run <stage> 主命令
|
|
164
|
-
*/
|
|
165
|
-
export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
166
|
-
// 原始 cwd 快照(下方 cwd 纠正前):agent 在子目录启动时,其会话 transcript 挂在子目录
|
|
167
|
-
// 对应的 harness 项目目录下,agent-log 探测须用原始 cwd(纠正后的是项目根,探测会扑空)
|
|
168
|
-
const invokedCwd = cwd
|
|
169
|
-
// W1-B: run <stage> 暂不支持 --json。之前 --json 进 knownFlags 白名单却从不读取(静默吞),
|
|
170
|
-
// agent 按 gate/derive 契约期望 envelope 实则拿到混合人类文本。显式 fail-fast 杜绝歧义;
|
|
171
|
-
// 完整 run envelope 待 outputStep 重构(W6)后支持(prompt + nextAction 结构化)。
|
|
172
|
-
if (opts.json) {
|
|
173
|
-
console.error('❌ run <stage> 暂不支持 --json(静默吞是 bug,故显式拒绝)。')
|
|
174
|
-
console.error(' 查事实用 gate/derive(支持 --json envelope);run 输出人类可读 prompt 供 agent 直接执行。')
|
|
175
|
-
process.exit(2) // 用法错 → exit 2
|
|
176
|
-
}
|
|
177
|
-
// 解析参数
|
|
178
|
-
const stageName = args[0]
|
|
179
|
-
let flags = args.slice(1) // let:下方规范化 --k=v 会改写
|
|
180
|
-
|
|
181
|
-
// F7: 规范化 --key=value → ['--key', 'value']。许多 CLI 通用等号语法此前被整 token 当未知参数拒绝。
|
|
182
|
-
// 只对值类 flag 展开(见 VALUE_FLAGS);布尔 flag 不吃值,--skip-approval=x 这种无意义,原样进校验报错。
|
|
183
|
-
flags = flags.flatMap(tok => {
|
|
184
|
-
if (typeof tok === 'string' && tok.startsWith('--') && tok.includes('=')) {
|
|
185
|
-
const eq = tok.indexOf('=')
|
|
186
|
-
const key = tok.slice(0, eq)
|
|
187
|
-
const val = tok.slice(eq + 1)
|
|
188
|
-
if (VALUE_FLAGS.has(key)) return [key, val]
|
|
189
|
-
}
|
|
190
|
-
return [tok]
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
if (!stageName) {
|
|
194
|
-
console.error('❌ 请指定阶段,例如: sillyspec run brainstorm')
|
|
195
|
-
console.error(`可选: ${Object.keys(stageRegistry).join(', ')}, auto`)
|
|
196
|
-
process.exit(2) // 用法错 → exit 2
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (!stageRegistry[stageName] && stageName !== 'auto') {
|
|
200
|
-
console.error(`❌ 未知阶段: ${stageName}`)
|
|
201
|
-
console.error(`可选: ${Object.keys(stageRegistry).join(', ')}, auto`)
|
|
202
|
-
process.exit(2) // 用法错 → exit 2
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// ── cwd 纠正:向上查找真实项目根 ──
|
|
206
|
-
// 防止多 project 工作区中 cwd 停在子目录(如 backend/)时
|
|
207
|
-
// 状态写入子目录下误建的 .sillyspec,导致状态分裂
|
|
208
|
-
// HUB-12c:守卫须同时查平台接管声明——指针被 cleanup、声明还在、祖先有别的 .sillyspec
|
|
209
|
-
//(monorepo 嵌套)时,cwd 被上移后 checkPlatformManaged 在新 cwd 扑空 → 静默落本地库,
|
|
210
|
-
// 双入口 fail-closed 被绕过(状态分裂正是它要防的)
|
|
211
|
-
if (!specDir && !existsSync(join(cwd, '.sillyspec-platform.json')) && !checkPlatformManaged(cwd)) {
|
|
212
|
-
// 平台模式(cwd 有 .sillyspec-platform.json 指针或接管声明)不做 cwd 纠正:指针已明确
|
|
213
|
-
// specDir,向上找 .sillyspec 反而会撞到无关项目(如用户 home 的 .sillyspec),导致
|
|
214
|
-
// --done 恢复读写 ~/.sillyspec-platform.json 出错的 specRoot。
|
|
215
|
-
const resolvedRoot = resolveSpecDir(cwd)
|
|
216
|
-
if (resolvedRoot && resolvedRoot !== join(cwd, '.sillyspec')) {
|
|
217
|
-
const realRoot = dirname(resolvedRoot)
|
|
218
|
-
if (realRoot !== cwd) {
|
|
219
|
-
cwd = realRoot
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// 平台模式参数(供 SillyHub 等平台调用)
|
|
225
|
-
// --spec-dir 是统一参数名,--spec-root 保留为向后兼容别名
|
|
226
|
-
const getFlagValue = (name) => {
|
|
227
|
-
const idx = flags.indexOf(name)
|
|
228
|
-
if (idx === -1) return null
|
|
229
|
-
const next = flags[idx + 1]
|
|
230
|
-
// F4: 下一个 token 若是另一个 flag 名(--xxx),说明本 flag 漏值,
|
|
231
|
-
// 不能把 flag 名当值返回(否则 --change --done → changeName="--done" 一路污染)。
|
|
232
|
-
if (!next || (typeof next === 'string' && next.startsWith('--'))) return null
|
|
233
|
-
return next
|
|
234
|
-
}
|
|
235
|
-
const isDone = flags.includes('--done')
|
|
236
|
-
const isSkip = flags.includes('--skip')
|
|
237
|
-
const isStatus = flags.includes('--status')
|
|
238
|
-
const isReset = flags.includes('--reset')
|
|
239
|
-
const isReopen = flags.includes('--reopen')
|
|
240
|
-
// --cancel(2026-08-21 审计第四批 C-2):quick 误启动会话的官方取消口。取消 = QUICKLOG 条目
|
|
241
|
-
// 翻「已取消」+ tasks.md 挂载行移除 + 会话 guard 目录清理 + db 行注销(取消 quick 会话行,
|
|
242
|
-
// 非真实变更)。fail-closed:已完成/已勾选的拒绝(真实工作记录)。
|
|
243
|
-
const isCancel = flags.includes('--cancel')
|
|
244
|
-
if (isCancel && stageName !== 'quick') {
|
|
245
|
-
console.error('❌ --cancel 仅支持 quick 阶段(sillyspec run quick --cancel --change <quick-会话ID>)')
|
|
246
|
-
process.exit(2)
|
|
247
|
-
}
|
|
248
|
-
if (isCancel && (isDone || isSkip || isReset || isReopen || isStatus)) {
|
|
249
|
-
console.error('❌ --cancel 与 --done/--skip/--reset/--reopen/--status 互斥')
|
|
250
|
-
process.exit(2)
|
|
251
|
-
}
|
|
252
|
-
const fromStepValue = getFlagValue('--from-step')
|
|
253
|
-
const isConfirm = flags.includes('--confirm')
|
|
254
|
-
const isSkipApproval = flags.includes('--skip-approval')
|
|
255
|
-
const isWait = flags.includes('--wait')
|
|
256
|
-
const isContinue = flags.includes('--continue')
|
|
257
|
-
const isNonInteractive = flags.includes('--non-interactive')
|
|
258
|
-
const isInteractive = flags.includes('--interactive')
|
|
259
|
-
// F3 冲突 flag 检测:步骤/阶段动作 flag 互斥——各自定义「对当前步骤做什么」,同时给 2+ 个
|
|
260
|
-
// 语义矛盾。旧实现按代码里 if 顺序静默取先命中的、其余被忽略,agent 以为生效的其实没生效
|
|
261
|
-
// (如 --done --reset 只 reset 不 done,agent 却以为完成了步骤)。显式报冲突让 agent 选一个。
|
|
262
|
-
const STEP_ACTIONS = [
|
|
263
|
-
['--done', isDone, '完成当前步骤'],
|
|
264
|
-
['--skip', isSkip, '跳过当前步骤'],
|
|
265
|
-
['--reset', isReset, '重置整个阶段(从头开始)'],
|
|
266
|
-
['--reopen', isReopen, '重新打开已完成阶段进入修订(配 --from-step)'],
|
|
267
|
-
['--wait', isWait, '暂停等用户决策'],
|
|
268
|
-
['--continue', isContinue, '恢复等待中的步骤'],
|
|
269
|
-
['--status', isStatus, '查看进度(只读)'],
|
|
270
|
-
]
|
|
271
|
-
const activeActions = STEP_ACTIONS.filter(([, v]) => v)
|
|
272
|
-
if (activeActions.length >= 2) {
|
|
273
|
-
console.error('❌ 步骤动作参数冲突(同时只能指定一个):')
|
|
274
|
-
for (const [name, , desc] of activeActions) console.error(` ${name} — ${desc}`)
|
|
275
|
-
console.error(' 这些动作互斥,请只保留其中一个再重试。')
|
|
276
|
-
process.exit(2)
|
|
277
|
-
}
|
|
278
|
-
// scan profile flag 互斥:--quick/--standard/--deep 同时给≥2 个语义矛盾(computeScanProfile
|
|
279
|
-
// 只取首个命中、其余静默忽略 → agent 以为生效的其实没生效,与 STEP_ACTIONS 同类风险)。
|
|
280
|
-
const PROFILE_FLAGS = [
|
|
281
|
-
['--quick', flags.includes('--quick'), 'quick profile(快速接入,4 份核心文档)'],
|
|
282
|
-
['--standard', flags.includes('--standard'), 'standard profile(压缩步骤)'],
|
|
283
|
-
['--deep', flags.includes('--deep'), 'deep profile(完整扫描)'],
|
|
284
|
-
]
|
|
285
|
-
const activeProfiles = PROFILE_FLAGS.filter(([, v]) => v)
|
|
286
|
-
if (activeProfiles.length >= 2) {
|
|
287
|
-
console.error('❌ scan profile 参数冲突(同时只能指定一个):')
|
|
288
|
-
for (const [name, , desc] of activeProfiles) console.error(` ${name} — ${desc}`)
|
|
289
|
-
console.error(' 这三档互斥,请只保留其中一个再重试。')
|
|
290
|
-
process.exit(2)
|
|
291
|
-
}
|
|
292
|
-
// 注:--non-interactive 与 --interactive 的冲突在 index.js 检测(--interactive 被 index.js
|
|
293
|
-
// 作为全局 flag 吞掉、不透传到此处,故 isInteractive 在此恒为 false)。
|
|
294
|
-
const waitReason = getFlagValue('--reason')
|
|
295
|
-
const waitOptions = getFlagValue('--options')
|
|
296
|
-
const continueAnswer = getFlagValue('--answer')
|
|
297
|
-
const resolvedSpecDir = specDir || getFlagValue('--spec-dir') || getFlagValue('--spec-root')
|
|
298
|
-
const platformOpts = {
|
|
299
|
-
specRoot: resolvedSpecDir ? resolve(resolvedSpecDir) : null,
|
|
300
|
-
runtimeRoot: getFlagValue('--runtime-root') ? resolve(getFlagValue('--runtime-root')) : null,
|
|
301
|
-
workspaceId: getFlagValue('--workspace-id'),
|
|
302
|
-
scanRunId: getFlagValue('--scan-run-id'),
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// 跨 --done 生命周期:从 metadata 文件恢复 platformOpts
|
|
306
|
-
// 首次 scan 时写入,所有后续调用(包括 run、--done、--skip)都读取
|
|
307
|
-
// 优先在 specDir 下查找,否则回退到 cwd/.sillyspec/.runtime/
|
|
308
|
-
let specRoot = platformOpts.specRoot || resolveSpecDir(cwd)
|
|
309
|
-
// 平台参数恢复策略:
|
|
310
|
-
// 1. 优先检查 cwd/.sillyspec-platform.json(轻量指针文件,不污染 .sillyspec 结构)
|
|
311
|
-
// 2. 然后检查 specRoot/.runtime/platform-scan.json(首次 scan 写入)
|
|
312
|
-
const platformPointer = join(cwd, '.sillyspec-platform.json')
|
|
313
|
-
const platformScanFile = join(specRoot, '.runtime', 'platform-scan.json')
|
|
314
|
-
let platformOptsFile = existsSync(platformPointer) ? platformPointer : platformScanFile
|
|
315
|
-
let platformFileExists = existsSync(platformOptsFile)
|
|
316
|
-
// 如果命令行没传 spec-root,尝试从持久化文件恢复
|
|
317
|
-
if (!platformOpts.specRoot && !platformOpts.runtimeRoot) {
|
|
318
|
-
if (platformFileExists) {
|
|
319
|
-
try {
|
|
320
|
-
const { readFileSync } = await import('fs')
|
|
321
|
-
const saved = JSON.parse(readFileSync(platformOptsFile, 'utf8'))
|
|
322
|
-
// 自指指针免疫(FR-4,变更 2026-08-23-repo-native-spec-backfill):saved.specRoot 经
|
|
323
|
-
// realpath 解析回本地 .sillyspec(repo-native junction 回环,旧模板投毒残留)→ 整体
|
|
324
|
-
// 忽略恢复(specRoot/runtimeRoot/workspaceId/scanRunId 全不回填,platformOpts 保持
|
|
325
|
-
// 无平台参数状态),按本地模式运行——内置 sync 走本地链路,specRoot 保持本地取值链。
|
|
326
|
-
if (isSelfReferentialSpecRoot(cwd, saved.specRoot)) {
|
|
327
|
-
console.warn(`⚠️ 检测到自指平台指针(repo-native junction 回环,specRoot 指回本地 .sillyspec),已忽略并按本地模式运行: ${platformOptsFile}`)
|
|
328
|
-
} else {
|
|
329
|
-
if (saved.specRoot) platformOpts.specRoot = saved.specRoot
|
|
330
|
-
if (saved.runtimeRoot) platformOpts.runtimeRoot = saved.runtimeRoot
|
|
331
|
-
if (saved.workspaceId) platformOpts.workspaceId = saved.workspaceId
|
|
332
|
-
if (saved.scanRunId) platformOpts.scanRunId = saved.scanRunId
|
|
333
|
-
// 平台模式 fail-fast:文件存在但缺少 specRoot
|
|
334
|
-
if (!platformOpts.specRoot && !platformOpts.runtimeRoot) {
|
|
335
|
-
console.error(`❌ 平台模式参数文件存在但缺少 specRoot/runtimeRoot: ${platformOptsFile}`)
|
|
336
|
-
console.error(' 可能原因:platform-scan.json 损坏或写入不完整')
|
|
337
|
-
console.error(' 解决:重新运行首次 scan 并传入 --spec-root')
|
|
338
|
-
process.exit(2) // 环境错(平台文件损坏)→ exit 2
|
|
339
|
-
}
|
|
340
|
-
// 恢复成功:更新 specRoot(初始值可能是 cwd/.sillyspec,恢复后应为真实 specDir)
|
|
341
|
-
specRoot = platformOpts.specRoot || specRoot
|
|
342
|
-
}
|
|
343
|
-
} catch (e) {
|
|
344
|
-
console.error(`❌ 平台模式参数文件读取失败: ${platformOptsFile}`)
|
|
345
|
-
console.error(` 错误: ${e.message}`)
|
|
346
|
-
console.error(' 可能原因:文件损坏')
|
|
347
|
-
console.error(' 解决:删除该文件并重新运行首次 scan 传入 --spec-root')
|
|
348
|
-
process.exit(2) // 环境错(文件损坏)→ exit 2
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
// ── 平台接管声明 fail-closed(入口二,D-B@v2)──
|
|
353
|
-
// runCommand 有独立指针恢复链(不经 resolvePlatformSpecDir),指针缺失时若不在此
|
|
354
|
-
// 封堵,run/quick/scan 等全部 stage 命令会静默落本地库(与入口一行为分裂)。
|
|
355
|
-
// 触发条件:命令行没传平台参数 + 指针与 platform-scan.json 皆未命中 + 接管声明存在。
|
|
356
|
-
// 显式 --spec-dir/--spec-root 传参时 platformOpts.specRoot 已赋值,天然不进此分支(逃生口)。
|
|
357
|
-
if (!platformOpts.specRoot && !platformOpts.runtimeRoot && !platformFileExists) {
|
|
358
|
-
const decl = checkPlatformManaged(cwd)
|
|
359
|
-
if (decl) {
|
|
360
|
-
// 陈旧自指声明降级(FR-4,变更 2026-08-23-repo-native-spec-backfill):decl.specRoot 经
|
|
361
|
-
// realpath 解析回本地 .sillyspec(repo-native junction 投毒残留、指针已被清理)→ 视为
|
|
362
|
-
// 陈旧声明,warn 后按本地模式继续(不 exit 1)——声明描述的"平台接管"物理上指向本地
|
|
363
|
-
// .sillyspec,无跨库状态分裂风险;非自指声明维持 fail-closed 原样(状态保护阻断)。
|
|
364
|
-
if (isSelfReferentialSpecRoot(cwd, decl.specRoot)) {
|
|
365
|
-
console.warn(`⚠️ 检测到陈旧的自指平台接管声明(repo-native junction 回环,原 specRoot 指回本地 .sillyspec),已降级并按本地模式运行;可 sillyspec platform disconnect 清理残留声明: ${join(cwd, PLATFORM_MANAGED_FILENAME)}`)
|
|
366
|
-
} else {
|
|
367
|
-
console.error(`❌ 平台接管声明生效:本项目已由平台托管(原 specRoot: ${decl.specRoot || '(未记录)'}),但恢复指针缺失,拒绝静默回退本地模式。`)
|
|
368
|
-
console.error(` 声明文件: ${join(cwd, PLATFORM_MANAGED_FILENAME)}`)
|
|
369
|
-
console.error(' 恢复:① 重跑平台 scan/init(带 --spec-root)重建指针;② 确认不再使用平台:sillyspec platform disconnect(删除接管声明);③ 显式 --spec-dir <路径> 临时指定目录。')
|
|
370
|
-
// exit(1) 而非邻近环境错的 exit(2):这是"状态保护阻断"(对齐 PointerUnreachableError
|
|
371
|
-
// 顶层 catch 语义),非"用法/环境错"——见 design.md §5.3 v2 复审观察 (a)
|
|
372
|
-
process.exit(1)
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
// 持久化 platformOpts
|
|
377
|
-
// 在 specRoot/.runtime/ 写主文件,同时在 cwd 下写恢复指针
|
|
378
|
-
// (writePlatformPointer 收敛双写逻辑,cmdInit 平台模式共用,防两处字段漂移)
|
|
379
|
-
if (platformOpts.specRoot || platformOpts.runtimeRoot) {
|
|
380
|
-
writePlatformPointer(cwd, platformOpts)
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// 统一规范基路径:平台模式用 specRoot,本地模式用 cwd/.sillyspec
|
|
384
|
-
// runCommand 后续所有 .sillyspec/ 操作必须用 specBase
|
|
385
|
-
// let:下方 worktree 副本漂移守卫命中时锚回 wt.mainSpecBase(task-05/D-03)
|
|
386
|
-
let specBase = platformOpts.specRoot || join(cwd, '.sillyspec')
|
|
387
|
-
|
|
388
|
-
// 漂移提醒:cwd 祖先链 ≥2 个 .sillyspec = monorepo 多实例,当前命中的「最近」实例
|
|
389
|
-
// 可能不是用户意图的项目(如 cd 进被独立 scan 的子项目跑测试后忘回根)。
|
|
390
|
-
// 平台模式 / 显式 --spec-dir 跳过(已明确指定,无歧义)。仅提醒不阻断。
|
|
391
|
-
if (!platformOpts.specRoot && !specDir) {
|
|
392
|
-
const ancestorCount = countAncestorSpecDirs(cwd)
|
|
393
|
-
if (ancestorCount >= 2) {
|
|
394
|
-
console.warn(`⚠️ 检测到祖先链有 ${ancestorCount} 个 .sillyspec 实例(monorepo 多实例),当前使用: ${specBase}`)
|
|
395
|
-
console.warn(` 若意图是另一个项目:cd 回该项目根,或用 --spec-dir <根>/.sillyspec 显式指定。`)
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// scan diff 转发(D-001@v1:command.js 只认 --diff flag,等价 `sillyspec scan diff` 子命令;
|
|
400
|
-
// 裸 token `run scan diff` 不在此解析——那是 index.js 子命令拦截的职责,防 command.js 静默吞)。
|
|
401
|
-
// 纯只读比较:零会话/QUICKLOG 副作用,仅解析 --base/--full/--report 后转发 scan-diff 退出码。
|
|
402
|
-
if (stageName === 'scan' && flags.includes('--diff')) {
|
|
403
|
-
const { runScanDiff } = await import('../scan-diff.js')
|
|
404
|
-
const diffBase = getFlagValue('--base')
|
|
405
|
-
process.exitCode = runScanDiff({
|
|
406
|
-
projectRoot: cwd,
|
|
407
|
-
specBase,
|
|
408
|
-
projectName: basename(cwd),
|
|
409
|
-
base: diffBase,
|
|
410
|
-
full: flags.includes('--full'),
|
|
411
|
-
report: flags.includes('--report'),
|
|
412
|
-
})
|
|
413
|
-
return
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// 平台模式:首次接入时清理旧版本残留的 cwd/.sillyspec/(防止源码污染)。
|
|
417
|
-
// ⚠️ 同 init.js:必须保护真实资产(changes/、projects/、sillyspec.db)。
|
|
418
|
-
// 只在「首次」执行一次——用 cwd 下的 .sillyspec-platform-cleaned 标记文件记录已处理,
|
|
419
|
-
// 后续每次 run 直接跳过,避免重复检查 + 红叉噪声(此清理不阻塞流程、不动真实资产)。
|
|
420
|
-
// 自指守卫(FR-4,变更 2026-08-23-repo-native-spec-backfill):显式自指 --spec-root
|
|
421
|
-
// (repo-native junction 回环)下 cwd/.sillyspec 与 specRoot 同物理目录——它就是平台
|
|
422
|
-
// 规范目录本体,绝非"旧版本残留";跳过整个清理决策(含 marker 写入,防后续真平台
|
|
423
|
-
// 接入被误标记已清理)。否则 rmSync 会删掉 repo-native 唯一真理源并留下悬空链接。
|
|
424
|
-
if (platformOpts.specRoot && !isSelfReferentialSpecRoot(cwd, platformOpts.specRoot)) {
|
|
425
|
-
const legacyDir = join(cwd, '.sillyspec')
|
|
426
|
-
const cleanedMarker = join(cwd, '.sillyspec-platform-cleaned')
|
|
427
|
-
if (!existsSync(cleanedMarker)) {
|
|
428
|
-
if (existsSync(legacyDir)) {
|
|
429
|
-
let hasChanges = false;
|
|
430
|
-
try {
|
|
431
|
-
const cd = join(legacyDir, 'changes');
|
|
432
|
-
if (existsSync(cd)) hasChanges = readdirSync(cd).length > 0;
|
|
433
|
-
} catch {}
|
|
434
|
-
let hasProjects = false;
|
|
435
|
-
try {
|
|
436
|
-
const pd = join(legacyDir, 'projects');
|
|
437
|
-
if (existsSync(pd)) hasProjects = readdirSync(pd).length > 0;
|
|
438
|
-
} catch {}
|
|
439
|
-
const hasDb = existsSync(join(legacyDir, 'sillyspec.db'));
|
|
440
|
-
|
|
441
|
-
if (hasChanges || hasProjects || hasDb) {
|
|
442
|
-
// 真实资产存在:只清运行时残留(白名单保留 worktrees/进度),不整删
|
|
443
|
-
const { cleanupRuntimeResidue } = await import('../init.js')
|
|
444
|
-
cleanupRuntimeResidue(legacyDir);
|
|
445
|
-
console.log('ℹ️ [sillyspec] 源码目录 .sillyspec/ 含真实资产,已跳过整删,仅清理运行时残留(仅本次首次,后续不再提示)。');
|
|
446
|
-
} else {
|
|
447
|
-
try { rmSync(legacyDir, { recursive: true, force: true }) } catch {}
|
|
448
|
-
if (!existsSync(legacyDir)) console.log('🧹 已清理旧版本残留的源码 .sillyspec/ 目录');
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
// 标记本 cwd 已做平台残留清理决策,后续 run 跳过(即使之后 .sillyspec/ 被重建也不误清)
|
|
452
|
-
try { writeFileSync(cleanedMarker, new Date().toISOString() + '\n') } catch {}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// 解析 --output
|
|
457
|
-
// F4 守卫统一走 getFlagValue(坑 raw-flag-value-bypass):裸 flags[idx+1] 会把漏值后紧跟的
|
|
458
|
-
// flag 名当值(--output --input x → output="--input"),--change --done 甚至会建出名为
|
|
459
|
-
// --done 的变更目录(assertSafeChangeName 的 [\w.-] 恰好放行)。getFlagValue 的 F4 注释
|
|
460
|
-
// 点名过本坑,此前只有 from-step 等少数 flag 用了它。
|
|
461
|
-
let outputText = null
|
|
462
|
-
const outputValue = getFlagValue('--output')
|
|
463
|
-
if (outputValue !== null) outputText = outputValue
|
|
464
|
-
|
|
465
|
-
// 解析 quick 末步四字段参数(2026-08-21 agent-手工产出审计第二批 F6):--req/--cause/
|
|
466
|
-
// --solution/--result 各传一项,CLI 合成单行四字段 outputText(quicklog 落盘侧
|
|
467
|
-
// splitSingleLineFields 会归一为多行字段块)。消灭 agent 手拼「需求:… 根因:…」模板的
|
|
468
|
-
// 格式事故面(嵌套全角冒号拆分误判 / 缺字段被 --done 拒 / 标题截断规则踩坑)。
|
|
469
|
-
// 任一四参数出现即要求全四;与 --output 互斥(两路同时给说明意图不明,fail-fast)。
|
|
470
|
-
{
|
|
471
|
-
const FOUR = [['--req', '需求:'], ['--cause', '根因:'], ['--solution', '方案:'], ['--result', '结果:']]
|
|
472
|
-
const fourVals = FOUR.map(([f]) => [f, getFlagValue(f)])
|
|
473
|
-
if (fourVals.some(([, v]) => v !== null)) {
|
|
474
|
-
if (outputText !== null) {
|
|
475
|
-
console.error('❌ --req/--cause/--solution/--result 与 --output 互斥——四参数由 CLI 合成结构化 output,勿混用');
|
|
476
|
-
process.exit(2)
|
|
477
|
-
}
|
|
478
|
-
const missing = fourVals.filter(([, v]) => v === null).map(([f]) => f)
|
|
479
|
-
if (missing.length > 0) {
|
|
480
|
-
console.error(`❌ quick 末步四字段参数缺项:${missing.join(' ')}(--req/--cause/--solution/--result 必须全给,或缺字段 --done 会被拒)`);
|
|
481
|
-
process.exit(2)
|
|
482
|
-
}
|
|
483
|
-
outputText = FOUR.map(([f, label]) => `${label}${getFlagValue(f)}`).join(' ')
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// 解析 --input
|
|
488
|
-
let inputText = null
|
|
489
|
-
const inputValue = getFlagValue('--input')
|
|
490
|
-
if (inputValue !== null) inputText = inputValue
|
|
491
|
-
|
|
492
|
-
// quick 位置参数 → 任务描述(与 auto 模式建议的 `sillyspec run quick "需求"` 用法一致)。
|
|
493
|
-
// 旧行为静默忽略裸 token(QUICKLOG 标题回退占位);现显式消费——跳过值类 flag 的值
|
|
494
|
-
// (--files src/a.js 的 src/a.js 不是位置参数),取第一个真位置 token。配合下方
|
|
495
|
-
// 「新会话必须带描述」启动门(坑 quick-no-input-placeholder-title)。
|
|
496
|
-
if (stageName === 'quick' && inputText === null) {
|
|
497
|
-
for (let i = 0; i < flags.length; i++) {
|
|
498
|
-
const t = flags[i]
|
|
499
|
-
if (typeof t !== 'string') continue
|
|
500
|
-
if (t.startsWith('--')) { if (VALUE_FLAGS.has(t)) i++; continue }
|
|
501
|
-
inputText = t
|
|
502
|
-
break
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// 解析 --linked-changes <a,b|none>(quick 专用:显式声明关联变更,CI/脚本友好)
|
|
507
|
-
// 与 --change 解耦:--linked-changes 语义清晰(关联变更),不与「指定变更名」混淆。
|
|
508
|
-
// null = 未指定(走持久化/交互/兼容回退);[] = 显式 none(不关联);[...] = 显式列表
|
|
509
|
-
let explicitLinked = null
|
|
510
|
-
const linkedValue = getFlagValue('--linked-changes')
|
|
511
|
-
if (linkedValue !== null) {
|
|
512
|
-
const v = linkedValue.trim()
|
|
513
|
-
explicitLinked = v.toLowerCase() === 'none' ? [] : v.split(',').map(s => s.trim()).filter(Boolean)
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// 解析 --change <name>(quick 阶段向后兼容:逗号分隔作为「关联变更」;
|
|
517
|
-
// 历史写法,语义与「指定变更名」冲突,新用法建议改用 --linked-changes)
|
|
518
|
-
let changeName = null
|
|
519
|
-
let linkedChanges = []
|
|
520
|
-
const changeValue = getFlagValue('--change')
|
|
521
|
-
if (changeValue !== null) {
|
|
522
|
-
changeName = changeValue
|
|
523
|
-
if (stageName === 'quick') {
|
|
524
|
-
linkedChanges = changeName.split(',').map(s => s.trim()).filter(Boolean)
|
|
525
|
-
changeName = null
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
// --linked-changes 优先于 --change(显式 > 隐式兼容)
|
|
529
|
-
if (explicitLinked !== null) {
|
|
530
|
-
linkedChanges = explicitLinked
|
|
531
|
-
}
|
|
532
|
-
// F6 路径穿越消毒:change 名会被 join 进 .sillyspec/changes/<name>/ 当目录名,
|
|
533
|
-
// 含 ../ 或路径分隔符会逃出 changes/ 写到任意位置。quick 的 --change 复用为 sessionId
|
|
534
|
-
// (quick-<8hex>,正则已约束) 或 linkedChanges,故 quick 的 changeName 不在此校验。
|
|
535
|
-
try {
|
|
536
|
-
if (stageName !== 'quick' && changeName) assertSafeChangeName(changeName)
|
|
537
|
-
for (const lc of linkedChanges) {
|
|
538
|
-
if (lc && lc !== 'none') assertSafeChangeName(lc, '关联变更名(--linked-changes)')
|
|
539
|
-
}
|
|
540
|
-
} catch (e) {
|
|
541
|
-
console.error(`❌ ${e.message}`)
|
|
542
|
-
console.error(` 合法变更名示例:2026-07-27-add-login(仅字母/数字/._-,不含 / \\ ..)`)
|
|
543
|
-
process.exit(2)
|
|
544
|
-
}
|
|
545
|
-
// quick 会话隔离(D-001@v1 + D-003@v1 + §4.4 跨进程传递):每会话用 sessionId 作 changeName,
|
|
546
|
-
// DB 分行 progress.quick-<uuid8>,避免并行 quick 会话共享单行 progress.default.quick 互相覆盖。
|
|
547
|
-
// sessionId = crypto.randomUUID 前 8 hex(摒弃旧 quick-YYYYMMDD-HHMMSS 时间戳,同秒并发撞)。
|
|
548
|
-
// crypto.randomUUID 从 node:crypto import(兼容 engines node>=18,不依赖 Node 19+ 全局)。
|
|
549
|
-
//
|
|
550
|
-
// --done 跨进程恢复 sessionId 的优先级(§4.4):
|
|
551
|
-
// 1. --change quick-<uuid8>(单值且匹配 sessionId 形态)→ 精确指定本会话 sessionId
|
|
552
|
-
// (quick 的 --change 历史被复用为 linkedChanges 见上 1370-1377;此处对「恰好一个 quick-<8hex>」
|
|
553
|
-
// 特例识别为 sessionId,多值/不匹配仍走 linkedChanges 语义,向后兼容)
|
|
554
|
-
// 2. 未识别出 sessionId 且为 --done → fallback 读 .runtime/current-quick-run-id(单会话兼容;
|
|
555
|
-
// 多会话时可能拿到他者,文档声明建议带 --change)
|
|
556
|
-
// 3. 仍读不到 → 生成新 UUID(兼容旧行为;进度可能命中空行,由后续 pm.read 兜底)
|
|
557
|
-
const QUICK_SID_RE = /^quick-[0-9a-f]{8}$/
|
|
558
|
-
let quickSessionId = null
|
|
559
|
-
let quickFallbackUsed = false // Q7: --done 未带 --change 时 fallback 读 current-quick-run-id 命中(区别于显式 --change quick-<hex>)
|
|
560
|
-
let quickSidFresh = false // 本轮刚生成全新 sessionId(非 --change 精确恢复 / 非 fallback)——供下方「新会话必须带 --input」门判定
|
|
561
|
-
if (stageName === 'quick') {
|
|
562
|
-
// 1373-1376 已把 quick 的 --change 值清进 linkedChanges、changeName 置 null。
|
|
563
|
-
// 此处回看 --change 原始值:若恰好是单个 quick-<8hex> → 识别为本会话 sessionId(精确恢复),
|
|
564
|
-
// 并撤销把它当 linkedChanges 的误判。多值或不匹配 → 维持 linkedChanges 语义(旧兼容)。
|
|
565
|
-
// F4 守卫同款(changeIdx 变量已随裸读清理移除,此处改 getFlagValue 复读原始值)
|
|
566
|
-
const rawChangeValue = getFlagValue('--change')
|
|
567
|
-
const rawChange = rawChangeValue !== null ? rawChangeValue.trim() : null
|
|
568
|
-
const rawIsSingleSid = rawChange && rawChange.indexOf(',') === -1 && QUICK_SID_RE.test(rawChange)
|
|
569
|
-
if (rawIsSingleSid) {
|
|
570
|
-
// --done --change quick-<uuid8>:精确恢复(撤销 1373-1376 把它误当 linkedChanges)
|
|
571
|
-
quickSessionId = rawChange
|
|
572
|
-
changeName = rawChange
|
|
573
|
-
linkedChanges = []
|
|
574
|
-
} else if (!changeName) {
|
|
575
|
-
// 未精确指定:非 --done 必生成新 sessionId;--done 先 fallback current-quick-run-id,读不到再生成
|
|
576
|
-
const isDoneLike = isDone || isStatus || isSkip || isReset || isReopen
|
|
577
|
-
if (isDoneLike) {
|
|
578
|
-
try {
|
|
579
|
-
const runtimeRoot = resolveRuntimeRoot(platformOpts, specRoot)
|
|
580
|
-
const idFile = join(runtimeRoot, 'current-quick-run-id')
|
|
581
|
-
if (existsSync(idFile)) {
|
|
582
|
-
const v = readFileSync(idFile, 'utf8').trim()
|
|
583
|
-
if (QUICK_SID_RE.test(v)) { quickSessionId = v; quickFallbackUsed = true }
|
|
584
|
-
}
|
|
585
|
-
} catch {}
|
|
586
|
-
}
|
|
587
|
-
if (!quickSessionId) {
|
|
588
|
-
quickSessionId = 'quick-' + randomUUID().slice(0, 8)
|
|
589
|
-
quickSidFresh = true
|
|
590
|
-
}
|
|
591
|
-
changeName = quickSessionId
|
|
592
|
-
} else {
|
|
593
|
-
// 用户显式传了非 sessionId 形态的变更名 → 尊重,不生成 UUID(旧兼容路径)
|
|
594
|
-
quickSessionId = changeName
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// ── 本地 agent 会话日志登记 + 上报(平台会话展示用,best-effort)──
|
|
599
|
-
// 平台/daemon 模式下 SillyHub 只能看到 CLI 阶段信息,看不到本地 agent 的实际执行日志。
|
|
600
|
-
// 在此探测当前 agent 环境(Claude Code / Codex / ZCode transcript / SILLYSPEC_AGENT_LOG
|
|
601
|
-
// 覆盖),把日志本地路径登记进 <runtimeRoot>/agent-session-log.json(留底)并立即
|
|
602
|
-
// REST 上报平台(POST /api/agent-logs,与进度上报同风格;协议见
|
|
603
|
-
// docs/platform-agent-log-protocol.md)。探测不到不发不写;任何失败只 warn 一行,
|
|
604
|
-
// 绝不阻断 run 主流程。
|
|
605
|
-
// 位置(2026-08-23-agent-activity-sessions task-01):必须在上方 changeName/quickSessionId
|
|
606
|
-
// 解析完成之后——上报携带会话化上下文 context:entry 级 changeKey/quickId(平台按
|
|
607
|
-
// (workspace, harness, entry.ctx) 聚合建会话;quick 会话 quickId 优先且与 changeKey 互斥)
|
|
608
|
-
// + body 级 hubSessionId(daemon 派发平台会话时注入 env SILLYHUB_SESSION_ID,非空才带)。
|
|
609
|
-
// 两段解析均在顶层作用域,此处统一算一次 context 两值皆可达。
|
|
610
|
-
try {
|
|
611
|
-
const isQuickSession = stageName === 'quick' && Boolean(quickSessionId)
|
|
612
|
-
const hubSessionIdEnv = typeof process.env.SILLYHUB_SESSION_ID === 'string' ? process.env.SILLYHUB_SESSION_ID.trim() : ''
|
|
613
|
-
const agentLogContext = {
|
|
614
|
-
hubSessionId: hubSessionIdEnv || null,
|
|
615
|
-
// quick 会话 → quickId(quick-<8hex> 完整原样,不剥前缀);普通场景 → changeKey(--change 值,无则 null)
|
|
616
|
-
changeKey: isQuickSession ? null : (changeName || null),
|
|
617
|
-
quickId: isQuickSession ? quickSessionId : null,
|
|
618
|
-
}
|
|
619
|
-
const { recordAgentLogInvocation } = await import('../agent-session-log.js')
|
|
620
|
-
const r = await recordAgentLogInvocation({
|
|
621
|
-
cwd,
|
|
622
|
-
invokedCwd,
|
|
623
|
-
platformOpts,
|
|
624
|
-
specBase,
|
|
625
|
-
context: agentLogContext,
|
|
626
|
-
// 只记 flag 名不记值(--output 等 flag 值是 agent 工作文本,不进产物)
|
|
627
|
-
command: [stageName, ...flags.filter(t => typeof t === 'string' && t.startsWith('--'))].join(' '),
|
|
628
|
-
})
|
|
629
|
-
if (r && r.isNew && r.latestLogPath) {
|
|
630
|
-
const pushNote = r.pushed === true ? '已上报平台' : r.pushed === false ? '上报失败(本地已留底)' : '本地留底'
|
|
631
|
-
console.log(`📄 本地 agent 日志已登记(${pushNote}): ${r.latestLogPath}`)
|
|
632
|
-
}
|
|
633
|
-
} catch { /* best-effort:登记失败不影响 run 主流程 */ }
|
|
634
|
-
|
|
635
|
-
// quick 关联变更存在性守卫(坑 quick-change-phantom-linked):quick 的 --change/--linked-changes
|
|
636
|
-
// 被解析为关联变更后静默接受不存在的名字(quick 不建变更,链接幻影名必是笔误/语义误用——想给
|
|
637
|
-
// 会话起名却传了 --change),后果是 QUICKLOG 挂悬空关联污染 change 关联图谱 + --done 时 sessionId
|
|
638
|
-
// 走 fallback 可能命中他者会话。f70c9c3 只修了「建幻影目录」后果(appendTaskCheckbox 加
|
|
639
|
-
// existsSync 守卫),本守卫把误用拦在 flag 装载层。只校验 CLI 显式装载的 linkedChanges;
|
|
640
|
-
// 持久化 guard.json 复用(下方 run↔--done 之间变更可能被归档)与交互式选择(列表只列存在项)不检。
|
|
641
|
-
if (stageName === 'quick' && linkedChanges.length > 0) {
|
|
642
|
-
const missing = linkedChanges.filter(lc => lc !== 'none' && !existsSync(join(specRoot, 'changes', lc)))
|
|
643
|
-
if (missing.length > 0) {
|
|
644
|
-
console.error(`❌ quick 的 --change/--linked-changes 被当作「关联变更」处理,但以下变更不存在:${missing.join('、')}`)
|
|
645
|
-
console.error(' (quick 不创建变更,关联的变更必须预先存在)')
|
|
646
|
-
console.error(' - 想给会话起名:不要传 --change,sessionId 由 CLI 自动生成(后续 --done 用它)')
|
|
647
|
-
console.error(' - 想关联变更:修正拼写(.sillyspec/changes/ 下已存在的目录名),显式写法 --linked-changes <名>')
|
|
648
|
-
console.error(' - 想新建变更:quick 不建变更,走 brainstorm 完整流程')
|
|
649
|
-
process.exit(2)
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// 解析 --files a.js,b.js(quick 专用:显式声明 allowedFiles)
|
|
654
|
-
// --files 是单值 flag,空格分隔的多文件只取首个致其余静默丢失(坑 quick-files-space-separated-silently-drops)。
|
|
655
|
-
// detectSpaceSeparatedFiles 检测误用 → fail-loud 报错指明逗号用法(同 run --json :109 风格)。
|
|
656
|
-
const spaceSuspects = detectSpaceSeparatedFiles(flags)
|
|
657
|
-
if (spaceSuspects.length > 1) {
|
|
658
|
-
console.error('❌ --files 检测到空格分隔的多文件:CLI 只识别首个,其余会被静默丢弃(边界保护失效)。')
|
|
659
|
-
console.error(` 疑似多文件:${spaceSuspects.join(' ')}`)
|
|
660
|
-
console.error(' --files 是单值参数,多文件请用逗号分隔(无空格):')
|
|
661
|
-
console.error(` --files ${spaceSuspects.join(',')}`)
|
|
662
|
-
process.exit(2) // 用法错 → exit 2
|
|
663
|
-
}
|
|
664
|
-
let quickFiles = []
|
|
665
|
-
const filesValue = getFlagValue('--files')
|
|
666
|
-
if (filesValue !== null) {
|
|
667
|
-
quickFiles = filesValue.split(',').map(f => f.trim()).filter(Boolean)
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// 解析 --file-notes "path::括注 || path::括注"(quick 专用:QUICKLOG「文件:」行落盘多行括注)。
|
|
671
|
-
// 旁路注入 quicklog.js(per-process setter),不经 complete 收尾路径透传(避碰多 agent 并发改的收尾热点)。
|
|
672
|
-
// completeQuicklogEntry 读后即清;不传 → '' → 回填审计到的实际文件单行(向后兼容)。
|
|
673
|
-
// 格式 fail-fast(坑 quick-file-notes-format-silent,2026-08-24):分隔符写错(`|`/`,` 等)时
|
|
674
|
-
// 整段会被静默挤进第一个文件的括注、QUICKLOG 落盘后只能手工修——解析处直接拦。
|
|
675
|
-
let quickFileNotes = ''
|
|
676
|
-
const fileNotesValue = getFlagValue('--file-notes')
|
|
677
|
-
if (fileNotesValue !== null) {
|
|
678
|
-
quickFileNotes = fileNotesValue
|
|
679
|
-
const { validateFileNotesFormat } = await import('../quicklog.js')
|
|
680
|
-
const fv = validateFileNotesFormat(quickFileNotes)
|
|
681
|
-
if (!fv.ok) {
|
|
682
|
-
console.error(`❌ --file-notes 格式不对(${fv.problems.length} 处),已拒绝执行(旧行为会静默挤错进 QUICKLOG,只能手工修):`)
|
|
683
|
-
for (const p of fv.problems.slice(0, 5)) {
|
|
684
|
-
console.error(` 「${p.seg.slice(0, 80)}」${p.reason}——${p.hint}`)
|
|
685
|
-
}
|
|
686
|
-
if (fv.problems.length > 5) console.error(` …等共 ${fv.problems.length} 处`)
|
|
687
|
-
console.error(' 正确格式: --file-notes "path1::括注1 || path2::括注2"(`||` 双竖线分隔多文件,`::` 分隔路径与括注)')
|
|
688
|
-
process.exit(2) // 用法错(--file-notes 格式非法)→ exit 2
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
setQuickFileNotes(quickFileNotes)
|
|
692
|
-
|
|
693
|
-
const isAllowNew = flags.includes('--allow-new')
|
|
694
|
-
const isAllowDelete = flags.includes('--allow-delete')
|
|
695
|
-
const isForceBaseline = flags.includes('--force-baseline')
|
|
696
|
-
const isForceRescan = flags.includes('--force-rescan')
|
|
697
|
-
|
|
698
|
-
// F10b(ql-20260818-010):语义别名定向提示。did-you-mean 按编辑距离猜形近 flag,猜中的常是
|
|
699
|
-
// 形近但语义错的(--title → --files,ql-20260818-003 负面③实证)。常见「语义别名」在此登记
|
|
700
|
-
// 定向指引:命中时替代 did-you-mean 打印,引导到真正承载该语义的 flag/机制。
|
|
701
|
-
const FLAG_SEMANTIC_HINTS = {
|
|
702
|
-
'--title': 'QUICKLOG 条目标题无独立参数——从 --output 的「需求:」字段自动提取(写成一句语义化短标题即可)',
|
|
703
|
-
'--message': '结果摘要用 --output(quick 末步须含 需求:/根因:/方案:/结果: 四字段)',
|
|
704
|
-
'--summary': '结果摘要用 --output(quick 末步须含 需求:/根因:/方案:/结果: 四字段)',
|
|
705
|
-
'--result': '结果摘要用 --output(quick 末步须含 需求:/根因:/方案:/结果: 四字段)',
|
|
706
|
-
'--name': 'quick 会话名由 CLI 自动分配(quick-<hash>),恢复会话用 --change <quick-session-id>;关联变更用 --linked-changes',
|
|
707
|
-
'--session': 'quick 会话名由 CLI 自动分配(quick-<hash>),恢复会话用 --change <quick-session-id>',
|
|
708
|
-
'--note': '文件括注用 --file-notes "path::注 || path::注";启动时任务描述用 --input',
|
|
709
|
-
'--notes': '文件括注用 --file-notes "path::注 || path::注"',
|
|
710
|
-
'--desc': '启动时任务描述用 --input;QUICKLOG 标题从 --output「需求:」自动提取',
|
|
711
|
-
'--description': '启动时任务描述用 --input;QUICKLOG 标题从 --output「需求:」自动提取',
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
// 未知参数 fail-fast
|
|
715
|
-
const knownFlags = new Set([
|
|
716
|
-
'--done', '--skip', '--status', '--reset', '--confirm', '--skip-approval', '--cancel', '--ql',
|
|
717
|
-
'--wait', '--continue', '--non-interactive', '--interactive',
|
|
718
|
-
'--reason', '--options', '--answer', '--confirm-mode',
|
|
719
|
-
'--output', '--input', '--change', '--linked-changes',
|
|
720
|
-
'--req', '--cause', '--solution', '--result',
|
|
721
|
-
'--spec-dir', '--spec-root', '--runtime-root', '--workspace-id', '--scan-run-id',
|
|
722
|
-
'--files', '--file-notes', '--allow-new', '--allow-delete', '--force-baseline', '--force-rescan',
|
|
723
|
-
'--json', '--dir', '--help',
|
|
724
|
-
'--reopen', '--from-step', '--mode',
|
|
725
|
-
'--deep', '--quick', '--standard', // scan profile 三档显式选择(scan-profile.js 从 argv 读;互斥见下方 PROFILE_FLAGS 检测)
|
|
726
|
-
'--adopt-branch', // execute 显式收编既有 sillyspec/<change> 分支为 worktree 工作分支(坑 worktree-user-branch-conflict)
|
|
727
|
-
'--diff', '--base', '--full', '--report', // scan diff(D-001:command.js 只补 flag,裸 token 解析归 index.js 子命令拦截)
|
|
728
|
-
'-h',
|
|
729
|
-
])
|
|
730
|
-
for (let i = 0; i < flags.length; i++) {
|
|
731
|
-
const f = flags[i]
|
|
732
|
-
if (f.startsWith('--')) {
|
|
733
|
-
if (!knownFlags.has(f)) {
|
|
734
|
-
// F10: flag 级 did-you-mean(此前只命令级有);F10b:语义别名定向提示优先于形近猜测
|
|
735
|
-
const semanticHint = FLAG_SEMANTIC_HINTS[f]
|
|
736
|
-
console.error(`❌ 未知参数: ${f}`)
|
|
737
|
-
if (semanticHint) {
|
|
738
|
-
console.error(` ${semanticHint}`)
|
|
739
|
-
} else {
|
|
740
|
-
const suggestion = didYouMean(f, [...knownFlags])
|
|
741
|
-
if (suggestion) console.error(` 你是想输入「${suggestion}」吗?`)
|
|
742
|
-
else console.error(`已知参数: ${[...knownFlags].sort().join(', ')}`)
|
|
743
|
-
}
|
|
744
|
-
process.exit(2) // 用法错 → exit 2
|
|
745
|
-
}
|
|
746
|
-
// F2: 只有吃值的 flag 才跳下一个 token。布尔 flag(--done 等)不能 i++——
|
|
747
|
-
// 否则会把紧跟的 typo flag 当成 --done 的「值」吞掉,既不校验也不生效(静默忽略)。
|
|
748
|
-
if (VALUE_FLAGS.has(f)) i++
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
// ── --help/-h 短路:flag 校验通过后、任何副作用(cwd 纠正/会话创建/QUICKLOG 落盘)之前 ──
|
|
753
|
-
// --help 此前在 knownFlags 白名单里被静默吞掉,run quick --help 会误开 quick 会话+写骨架
|
|
754
|
-
// 条目(查询意图不该有副作用);-h 更是被当未知参数 exit 2。帮助查询 = 用法展示 = 退出 0。
|
|
755
|
-
if (flags.includes('--help') || flags.includes('-h')) {
|
|
756
|
-
printStageUsage(stageName)
|
|
757
|
-
process.exit(0)
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
// 坑 quick-no-input-placeholder-title(2026-08-24 用户反馈二期①):全新 quick 会话(上方
|
|
761
|
-
// 刚生成新 sessionId)不带 --input 且无 --linked-changes 可取标题 → 拒绝启动(exit 2)。
|
|
762
|
-
// 旧行为只 warn 提示「建议放弃重启」,占位标题「(quick 任务)」已落盘、只能 reset 重来——
|
|
763
|
-
// 语义标题要拖到最终 --done 才回填,平台「快速修复」列表全程隐藏。此刻零沉没成本(progress
|
|
764
|
-
// 行/QUICKLOG/guard 均未创建),直接拒掉最便宜。放在 --help 短路之后(help 查询不该被拦)、
|
|
765
|
-
// 任何会话副作用之前。精确恢复(--change quick-<hex>)与 done-like(--done/--reset/--cancel/
|
|
766
|
-
// --status/--skip/--reopen)不受限;--linked-changes 启动可从关联变更 proposal/design 提取标题。
|
|
767
|
-
if (stageName === 'quick' && quickSidFresh
|
|
768
|
-
&& !(isDone || isStatus || isSkip || isReset || isReopen || isCancel)
|
|
769
|
-
&& !inputText && !(Array.isArray(linkedChanges) && linkedChanges.length > 0)) {
|
|
770
|
-
console.error('❌ 新 quick 会话必须带 --input "<一句话任务描述>"(或 --linked-changes <a,b> 从关联变更取标题)。')
|
|
771
|
-
console.error(' 不带描述启动会落「(quick 任务)」占位标题:平台「快速修复」列表隐藏占位条目、语义标题要拖到最终 --done 才回填,长任务全程不可见。')
|
|
772
|
-
console.error(' 用法: sillyspec run quick --input "<一句话任务描述>" [--linked-changes <a,b>] [--files <...>]')
|
|
773
|
-
process.exit(2) // 用法错(新会话无任务描述)→ exit 2
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
const isAuxiliary = auxiliaryStages.includes(stageName)
|
|
777
|
-
// scan 元数据追踪(存储在 stageData.scanMeta 中,completeStep 通过 progress 访问)
|
|
778
|
-
|
|
779
|
-
// let:下方 worktree 副本漂移守卫命中时用主仓 specRoot 重建 pm(task-05/D-03)
|
|
780
|
-
let pm = new ProgressManager({ specDir: specRoot })
|
|
781
|
-
|
|
782
|
-
// quick 阶段:确定关联变更
|
|
783
|
-
// 优先级:--linked-changes / --change 显式 > 已持久化 quick-guard.json(--done 复用)> 交互式 > 非交互 fallback
|
|
784
|
-
// 关键:--done 收尾时复用首次 run 持久化的 linkedChanges,不在管道/CI 下重复弹交互 prompt。
|
|
785
|
-
// explicitLinked === null 且未传 --change 时才进入此分支(显式 --linked-changes none 不应触发交互)。
|
|
786
|
-
if (stageName === 'quick' && explicitLinked === null && linkedChanges.length === 0) {
|
|
787
|
-
// D-002:guard 按 session 存(.runtime/quick-sessions/<sessionId>/guard.json)。
|
|
788
|
-
// sessionId == changeName == quick-<uuid8>(上面参数解析已确定)。回退读旧单文件 quick-guard.json(task-03 前兼容)。
|
|
789
|
-
let persistedLinked = null
|
|
790
|
-
try {
|
|
791
|
-
const sessionGuardFile = join(specRoot, '.runtime', 'quick-sessions', changeName, 'guard.json')
|
|
792
|
-
const legacyGuardFile = join(specRoot, '.runtime', 'quick-guard.json')
|
|
793
|
-
const g = existsSync(sessionGuardFile)
|
|
794
|
-
? JSON.parse(readFileSync(sessionGuardFile, 'utf8'))
|
|
795
|
-
: (existsSync(legacyGuardFile) ? JSON.parse(readFileSync(legacyGuardFile, 'utf8')) : null)
|
|
796
|
-
if (g && Array.isArray(g.linkedChanges)) persistedLinked = g.linkedChanges
|
|
797
|
-
} catch {}
|
|
798
|
-
if (persistedLinked) {
|
|
799
|
-
linkedChanges = persistedLinked
|
|
800
|
-
} else {
|
|
801
|
-
linkedChanges = await resolveQuickLinkedChanges({
|
|
802
|
-
pm, cwd, specDir: specRoot, quickFiles,
|
|
803
|
-
taskDescription: inputText || '',
|
|
804
|
-
nonInteractive: isNonInteractive,
|
|
805
|
-
})
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
// execute 阶段必须带 --change:不允许自动检测或默认值,变更名必须由 agent 显式传入
|
|
810
|
-
// --status 豁免(纯查看不需要指定变更)
|
|
811
|
-
if (stageName === 'execute' && !changeName && !isStatus) {
|
|
812
|
-
console.error('❌ execute 阶段必须用 --change <变更名> 指定要操作的变更。')
|
|
813
|
-
console.error(' agent 必须传参,不设默认值、不做自动检测。')
|
|
814
|
-
console.error(' 请加 --change <变更名> 重新执行。')
|
|
815
|
-
process.exit(2) // 用法错(execute 必须显式 --change)→ exit 2
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
// worktree 副本漂移自动锚定守卫(坑 worktree-execute-spec-drift,D-03@v1):specBase 命中 worktree 内
|
|
819
|
-
// .sillyspec checkout 副本 = agent 误 cd 进 worktree 跑 plan/execute/verify/archive(100% 误操作场景)。
|
|
820
|
-
// 不 exit:自动把 specBase 锚回主仓 wt.mainSpecBase 后继续——进度/产出落主仓,不再写分裂副本(副本随
|
|
821
|
-
// 工作树清理丢失)。必须在 validateChangeExists 之前:副本里 change 目录真实存在,存在性校验会被骗
|
|
822
|
-
// 放行;锚定后用主仓 specBase 复查。覆盖 plan/execute/verify/archive(validateChangeExists 同 Set)。
|
|
823
|
-
// 关键坑:连带重写 specBase/specRoot/specDir + 重建 pm——四者同源派生(pm._customSpecDir 持旧 specRoot),
|
|
824
|
-
// 只改 specBase 会让下游 validateChangeExists(specBase) 与 pm.read(走 pm._customSpecDir) 仍指副本。
|
|
825
|
-
// 平台模式/显式 --spec-dir 跳过(已明确指定,与 line~285 warn / quick 守卫条件对齐)。
|
|
826
|
-
// 其他漂移(下方 changeMissing 守卫 / quick session drift 守卫)非副本场景,仍 exit(2) 不自动纠正。
|
|
827
|
-
if (!platformOpts.specRoot && !specDir
|
|
828
|
-
&& ['plan', 'execute', 'verify', 'archive'].includes(stageName)) {
|
|
829
|
-
const wt = detectWorktreeSpecDrift(specBase)
|
|
830
|
-
if (wt) {
|
|
831
|
-
specBase = wt.mainSpecBase
|
|
832
|
-
specRoot = wt.mainSpecBase
|
|
833
|
-
specDir = wt.mainSpecBase
|
|
834
|
-
pm = new ProgressManager({ specDir: specRoot })
|
|
835
|
-
// 【坑 execute-runs-isolation】下游 runtimeRoot 解析(execute-runs/stage-reviews 落点)经
|
|
836
|
-
// platformOpts 透传读此锚点,落主仓 .runtime,不随 worktree cleanup 整目录删消失。
|
|
837
|
-
// D-02:只参与 runtimeRoot 解析(resolveRuntimeRoot),绝不设 specRoot/runtimeRoot——
|
|
838
|
-
// 否则触发平台 sentinel 副作用(triggerSync/checkApproval 跳过 + prompt 误进平台渲染分支)。
|
|
839
|
-
platformOpts.specDriftAnchor = wt.mainSpecBase
|
|
840
|
-
console.warn(`⚠️ 已自动锚定主仓 spec:${wt.mainSpecBase}(原 cwd 命中 worktree 副本 ${wt.changeName},已纠正,流程继续)`)
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
// --change 变更名存在性校验(治 cwd 漂移误匹配,缺陷 execute-in-place-windows-pitfalls 坑5):
|
|
845
|
-
// 必须在 pm.read/initChange 之前——initChange 会为 --change 指定的新名字创建 changes/ 目录,
|
|
846
|
-
// 校验若在其后则目录已存在、永远通过。用原始 changeName(--change 参数),覆盖 plan/execute/
|
|
847
|
-
// verify/archive;quick-<8hex> sessionId 与 brainstorm 新建豁免(见 validateChangeExists)。
|
|
848
|
-
const changeMissing = validateChangeExists(specBase, stageName, changeName)
|
|
849
|
-
if (changeMissing) {
|
|
850
|
-
console.error(`❌ ${changeMissing.message}`)
|
|
851
|
-
console.error(` 可能 cwd 漂移——当前 cwd=${cwd},命中的 spec=${specBase}。`)
|
|
852
|
-
console.error(` 若意图操作别的项目,请 cd 到对应项目根,或用 --spec-dir 指定正确的 spec 目录。`)
|
|
853
|
-
process.exit(2) // 环境错(cwd/spec 漂移)→ exit 2
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
// quick 专用 cwd 漂移 fail-fast 守卫(坑 quick-cwd-drift-splits-specdir):
|
|
857
|
-
// quick 被 validateChangeExists 的 sessionId 豁免(quick-<8hex> 不在 changes/ 下),漂移时除上方
|
|
858
|
-
// countAncestorSpecDirs 的 warn 外无硬守卫 → 无声分裂(progress/artifact/QUICKLOG 落子项目、根
|
|
859
|
-
// 会话停滞)。这里补:当前 specBase 无本 session guard、但祖先链别处有 = 跨 specDir 漂移 → fail-fast。
|
|
860
|
-
// 平台模式/显式 --spec-dir 跳过(specBase 已明确,与 line~285 warn 条件对齐)。
|
|
861
|
-
if (stageName === 'quick' && changeName && /^quick-[0-9a-f]{8}$/.test(changeName)
|
|
862
|
-
&& !platformOpts.specRoot && !specDir) {
|
|
863
|
-
const drift = detectQuickSessionDrift(cwd, specBase, changeName)
|
|
864
|
-
if (drift) {
|
|
865
|
-
console.error(`❌ ${drift.message}`)
|
|
866
|
-
console.error(` 当前 cwd=${cwd},命中的 spec=${specBase}。`)
|
|
867
|
-
process.exit(2) // 环境错(cwd/spec 漂移)→ exit 2
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
let progress = pm.read(cwd, changeName)
|
|
872
|
-
|
|
873
|
-
// task-03 (D-005@v2 / FR-04): READONLY_AUXILIARY_STAGES(status/doctor)查询只读短路。
|
|
874
|
-
// 无显式写 flag 时在 registerChange / ensureStageSteps 之前拦截,零副作用:
|
|
875
|
-
// - 目标 progress 不存在 → 提示「只读查询不建变更」exit 0(不 initChange、不建 default 行,治 8b)
|
|
876
|
-
// - 目标 progress 存在 → 只读展示,不 seed steps、不刷新 lastActive、不 registerChange
|
|
877
|
-
// (治 B7 多 agent 并发 lastActive 互相覆盖)
|
|
878
|
-
// 显式写意图不短路:doctor 写操作 flag(--cleanup-remnant / --align-execute-progress)与
|
|
879
|
-
// 步骤动作 flag(--done/--skip/--reset/--reopen/--wait/--continue)走原写路径;--status 本身
|
|
880
|
-
// 是只读查询,纳入短路。--fix 是 worktree doctor 的 flag 不在此列(design.md Phase 4)。
|
|
881
|
-
const READONLY_WRITE_ACTIONS = ['--cleanup-remnant', '--align-execute-progress', '--done', '--skip', '--reset', '--reopen', '--wait', '--continue']
|
|
882
|
-
if (READONLY_AUXILIARY_STAGES.includes(stageName) && !flags.some(f => READONLY_WRITE_ACTIONS.includes(f))) {
|
|
883
|
-
if (!progress) {
|
|
884
|
-
console.log('ℹ️ 未找到进度数据(只读查询不建变更)')
|
|
885
|
-
process.exit(0)
|
|
886
|
-
}
|
|
887
|
-
// 只读展示路径:复用阶段定义渲染当前步骤 prompt(outputStep 对 status/doctor 纯只读),
|
|
888
|
-
// 不落盘任何 progress 改动。--status 走现有 showStatus 展示。
|
|
889
|
-
const readOnlyChange = changeName || progress.currentChange || resolveChangeName(cwd, progress, specRoot)
|
|
890
|
-
if (isStatus) {
|
|
891
|
-
let nextSuggestion = null
|
|
892
|
-
try { nextSuggestion = pm._getNextSuggestion(progress) } catch { /* 读建议失败不阻断展示 */ }
|
|
893
|
-
return showStatus(progress, stageName, nextSuggestion)
|
|
894
|
-
}
|
|
895
|
-
const readonlySteps = await getStageSteps(stageName, cwd, progress, specRoot)
|
|
896
|
-
if (readonlySteps && readonlySteps.length > 0) {
|
|
897
|
-
// 已有进度(历史 seed 过)则渲染当前待办步;无进度从首步开始
|
|
898
|
-
const existingSteps = progress.stages?.[stageName]?.steps
|
|
899
|
-
const pendingIdx = existingSteps ? existingSteps.findIndex(s => s.status === 'pending' || s.status === 'in-progress') : -1
|
|
900
|
-
const stepIdx = pendingIdx !== -1 ? pendingIdx : 0
|
|
901
|
-
await outputStep(stageName, stepIdx, readonlySteps, cwd, readOnlyChange, progress.project || null, platformOpts)
|
|
902
|
-
}
|
|
903
|
-
return
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
if (!progress) {
|
|
907
|
-
// 如果指定了变更名或有变更目录,自动初始化变更的 progress
|
|
908
|
-
const autoChange = changeName || resolveChangeNameAuto(cwd, specRoot)
|
|
909
|
-
if (autoChange) {
|
|
910
|
-
// 创建时即写 title(与 name/KEY 同时落 db):--input 需求描述 sanitizeDesc 优先,无则用 name 兜底。
|
|
911
|
-
// proposal 还没写、无权威标题来源,这是临时值;brainstorm/plan 完成 proposal/design 落盘后由
|
|
912
|
-
// complete.js 通用完成路径 deriveTitleFromLinkedChange 刷新为真实 # 标题(与 quick 启动 title 同源)。
|
|
913
|
-
progress = pm.initChange(cwd, autoChange, { title: inputText ? sanitizeDesc(inputText) : autoChange })
|
|
914
|
-
} else if (isAuxiliary) {
|
|
915
|
-
let autoName = changeName || resolveChangeNameAuto(cwd, specRoot) || 'default'
|
|
916
|
-
// archive 特例:归档后变更从活跃列表排除(listChanges WHERE status='active'),
|
|
917
|
-
// 不带 --change 回退 default 会读错变更。无活跃变更时取最新归档变更,读其现有 progress。
|
|
918
|
-
// 归档目录名 = 原变更名恒等迁移(archiveDestDirName 不改名),直接原名对读——此前按
|
|
919
|
-
// 「日期前缀过滤 + 剥日期」找,剥出的短名与 DB 行名(含日期)恒不符 → pm.read 返回
|
|
920
|
-
// null → initChange 凭空建幻影变更再跑 archive(坑 archive-fallback-phantom-change)。
|
|
921
|
-
if (stageName === 'archive' && autoName === 'default') {
|
|
922
|
-
try {
|
|
923
|
-
const archiveDir = join(specBase, 'changes', 'archive')
|
|
924
|
-
if (existsSync(archiveDir)) {
|
|
925
|
-
const latest = readdirSync(archiveDir, { withFileTypes: true })
|
|
926
|
-
.filter(d => d.isDirectory())
|
|
927
|
-
.map(d => d.name)
|
|
928
|
-
.sort()
|
|
929
|
-
.pop()
|
|
930
|
-
if (latest) {
|
|
931
|
-
autoName = latest
|
|
932
|
-
progress = pm.read(cwd, autoName)
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
} catch {}
|
|
936
|
-
}
|
|
937
|
-
changeName = autoName
|
|
938
|
-
if (!progress) {
|
|
939
|
-
// auxiliary 创建也写 title(--input 优先 / name 兜底),同上完整流程语义。
|
|
940
|
-
progress = pm.initChange(cwd, autoName, { title: inputText ? sanitizeDesc(inputText) : autoName })
|
|
941
|
-
// initChange 可能因 project 表为空返回 null
|
|
942
|
-
if (!progress) {
|
|
943
|
-
progress = { currentStage: stageName, stages: {}, lastActive: new Date().toLocaleString('zh-CN', { hour12: false }), project: '' }
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
} else {
|
|
947
|
-
// brainstorm 作为流程入口,自动生成变更名并初始化
|
|
948
|
-
if (stageName === 'brainstorm') {
|
|
949
|
-
if (isDone) {
|
|
950
|
-
console.error('❌ --done 找不到变更进度数据。')
|
|
951
|
-
console.error(' 请用 --change <变更名> 指定要完成的变更,')
|
|
952
|
-
console.error(' 或先运行 sillyspec run brainstorm --change <变更名> 初始化。')
|
|
953
|
-
process.exit(2) // 用法错(--done 找不到变更,未传 --change)→ exit 2
|
|
954
|
-
}
|
|
955
|
-
// task-03 (D-006@v1 / FR-05): 无 --change 仅当无已存在活跃变更时 auto-create;
|
|
956
|
-
// 多活跃变更仓强制 --change(exit 2 引导),防 B8 幽灵变更。活跃变更数用 pm.listChanges
|
|
957
|
-
// (与 progress show 同源,DB changes 表 status='active')。
|
|
958
|
-
const activeChanges = pm.listChanges(cwd)
|
|
959
|
-
if (activeChanges.length > 0) {
|
|
960
|
-
console.error(`❌ 已存在 ${activeChanges.length} 个活跃变更,run brainstorm 无 --change 不会自动创建新变更。`)
|
|
961
|
-
console.error(` 活跃变更:${activeChanges.join('、')}`)
|
|
962
|
-
console.error(' 请用 --change <变更名> 指定要操作的变更,')
|
|
963
|
-
console.error(' 或先归档/收尾现有活跃变更后重试。')
|
|
964
|
-
process.exit(2) // 用法错(多活跃变更未指定 --change)→ exit 2
|
|
965
|
-
}
|
|
966
|
-
const date = new Date().toISOString().slice(0, 10)
|
|
967
|
-
const autoName = `${date}-new-change-${randomBytes(4).toString('hex')}`
|
|
968
|
-
console.log(`🔄 自动创建变更:${autoName}`)
|
|
969
|
-
console.log(` 提示:可以用 --change <名称> 指定自定义变更名`)
|
|
970
|
-
console.log(` 或事后重命名:sillyspec change-rename ${autoName} <新名称>`)
|
|
971
|
-
// brainstorm 自动创建变更也写 title(--input 需求描述优先 / 自动名兜底),proposal 落盘后刷新。
|
|
972
|
-
progress = pm.initChange(cwd, autoName, { title: inputText ? sanitizeDesc(inputText) : autoName })
|
|
973
|
-
changeName = autoName
|
|
974
|
-
} else {
|
|
975
|
-
console.error('❌ 未找到进度数据,请先运行 sillyspec init 或指定 --change <变更名>')
|
|
976
|
-
// 自愈引导(坑 suggestion-command-missing-change 同族):多活跃变更仓不带 --change 时
|
|
977
|
-
// pm.read 无法自动定位(单活跃可自动),列出候选让 agent 一步补对,而非盲猜变更名
|
|
978
|
-
try {
|
|
979
|
-
const activeChanges = pm.listChanges(cwd)
|
|
980
|
-
if (activeChanges.length > 1) {
|
|
981
|
-
console.error(` 当前有 ${activeChanges.length} 个活跃变更(无法自动定位),请显式指定:`)
|
|
982
|
-
for (const c of activeChanges) console.error(` - --change ${c}`)
|
|
983
|
-
}
|
|
984
|
-
} catch { /* 列举失败不掩盖原报错 */ }
|
|
985
|
-
process.exit(2) // 环境错(未 init / 未传 --change)→ exit 2
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
// 确保 progress 有 currentChange
|
|
991
|
-
const effectiveChange = changeName || progress.currentChange || resolveChangeName(cwd, progress, specRoot)
|
|
992
|
-
|
|
993
|
-
// ── Q7:quick --done 不带 --change 时 fallback 读 current-quick-run-id 可能命中他者会话 ──
|
|
994
|
-
// 并发两 quick 会话:B 后启动覆盖 A 的 id(last-writer-wins),A 的 --done 不带 --change → 读到 B 的 sessionId
|
|
995
|
-
// → 误操作 B 的 progress/QUICKLOG。fallback 命中的会话若已完成或无可推进步骤(id stale / 他者已收尾),
|
|
996
|
-
// 拒绝推进并要求显式 --change。(live A/B race 需 per-session 锚 commit,见 review Q2/D2,本守卫只兜 stale/completed。)
|
|
997
|
-
if (stageName === 'quick' && isDone && quickFallbackUsed) {
|
|
998
|
-
const qs = progress.stages.quick
|
|
999
|
-
const hasActionable = qs?.steps && qs.steps.some(s => s.status === 'pending' || s.status === 'waiting' || s.status === 'in-progress')
|
|
1000
|
-
if (!qs || qs.status === 'completed' || !hasActionable) {
|
|
1001
|
-
console.error(`\n❌ --done 未带 --change,回退读到的 quick 会话 ${changeName} 已不可推进(已完成或无待办步骤)。`)
|
|
1002
|
-
console.error(` 并发多 quick 会话时 .runtime/current-quick-run-id 可能指向他者会话(last-writer-wins)。`)
|
|
1003
|
-
console.error(` 请显式带 --change <quick-session-id> 指定要完成的会话(sillyspec run quick --status 查各会话进度)。`)
|
|
1004
|
-
process.exit(2) // 用法错(fallback 命中 stale/他者会话)→ exit 2
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
// -- auto 模式:自动推进所有流程阶段
|
|
1009
|
-
if (stageName === 'auto') {
|
|
1010
|
-
return await runAutoMode(pm, progress, cwd, flags, effectiveChange, platformOpts)
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
// --change 只作为变更名标识,不再拦截流程
|
|
1014
|
-
// 注册变更到全局活跃列表(如果尚未注册)
|
|
1015
|
-
if (effectiveChange) {
|
|
1016
|
-
pm.registerChange(cwd, effectiveChange)
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
// --reset
|
|
1020
|
-
if (isReset) {
|
|
1021
|
-
return await resetStage(pm, progress, stageName, cwd, effectiveChange, platformOpts)
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
// ── 规则 1:completed 阶段直接 run,拒绝(但 --status 放行)──
|
|
1025
|
-
const stageStatus = progress.stages[stageName]?.status
|
|
1026
|
-
if (stageStatus === 'completed' && !isReopen && !isStatus) {
|
|
1027
|
-
console.error(`\n❌ ${stageName} 阶段已完成。`)
|
|
1028
|
-
console.error(` 使用 --reopen 进行修订,或 --reset 从头开始。`)
|
|
1029
|
-
console.error(` 修订示例: sillyspec run ${stageName} --reopen --from-step <步骤序号或名称>`)
|
|
1030
|
-
process.exit(1)
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
// ── 规则 5:stale 阶段直接 run,拒绝(但 --status / --reset 放行)──
|
|
1034
|
-
if (stageStatus === 'stale' && !isReopen && !isStatus && !isReset) {
|
|
1035
|
-
const staleReason = progress.stages[stageName]?.staleReason || '上游阶段已修订'
|
|
1036
|
-
console.error(`\n⚠️ ${stageName} 阶段已失效(stale)。`)
|
|
1037
|
-
console.error(` 原因:${staleReason}`)
|
|
1038
|
-
console.error(` 使用 --reopen --from-step <步骤> 进行修订,或 --reset 从头开始。`)
|
|
1039
|
-
process.exit(1)
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
// ── --reopen 处理 ──
|
|
1043
|
-
if (isReopen) {
|
|
1044
|
-
// stale/revising 阶段可能 steps 为空,或者 execute 阶段的 steps 需要从最新 plan.md 刷新
|
|
1045
|
-
const stageDataPre = progress.stages[stageName]
|
|
1046
|
-
const needsInit = !stageDataPre || !stageDataPre.steps || stageDataPre.steps.length === 0
|
|
1047
|
-
// execute 阶段在 reopen 时需要从最新 plan.md 重新解析 steps(plan 可能已变更)。
|
|
1048
|
-
// 按名保留旧状态(坑 execute-reopen-wipes-prior-completion):reopenStage 的语义是
|
|
1049
|
-
// 「i < fromStep 保持原状(completed)」,此前预置全 pending 会把 fromStep 之前已完成的
|
|
1050
|
-
// 步骤一并清空——CLI 打印「从步骤 N 开始修订」、prompt 注入「之前已完成不需要重做」,
|
|
1051
|
-
// 实际 currentIdx 却回到 0,agent 被迫从头重做,修订语义完全失效。
|
|
1052
|
-
if (needsInit || stageName === 'execute') {
|
|
1053
|
-
const freshSteps = await getStageSteps(stageName, cwd, progress, specRoot)
|
|
1054
|
-
if (freshSteps && freshSteps.length > 0) {
|
|
1055
|
-
if (!progress.stages[stageName]) progress.stages[stageName] = { status: 'stale', steps: [] }
|
|
1056
|
-
const oldSteps = progress.stages[stageName].steps || []
|
|
1057
|
-
progress.stages[stageName].steps = freshSteps.map(s => {
|
|
1058
|
-
const old = oldSteps.find(step => step.name === s.name)
|
|
1059
|
-
return old ? { ...old } : { name: s.name, status: 'pending' }
|
|
1060
|
-
})
|
|
1061
|
-
pm._write(cwd, progress, effectiveChange)
|
|
1062
|
-
progress = pm.read(cwd, effectiveChange) || progress
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
const result = pm.reopenStage(cwd, stageName, {
|
|
1067
|
-
fromStep: fromStepValue,
|
|
1068
|
-
changeName: effectiveChange,
|
|
1069
|
-
})
|
|
1070
|
-
if (!result.ok) {
|
|
1071
|
-
console.error(`\n❌ ${result.error}`)
|
|
1072
|
-
if (stageStatus === 'completed') {
|
|
1073
|
-
console.error(`\n 提示:sillyspec run ${stageName} --reopen --from-step <步骤序号或名称>`)
|
|
1074
|
-
}
|
|
1075
|
-
process.exit(1)
|
|
1076
|
-
}
|
|
1077
|
-
console.log(`\n🔧 ${stageName} 阶段已重新打开(revision ${result.revision})`)
|
|
1078
|
-
console.log(` 从步骤「${result.fromStep}」开始修订`)
|
|
1079
|
-
console.log(` 该步骤及之后的产出需要重新生成。`)
|
|
1080
|
-
if (stageName === 'execute') console.log(` ⚡ execute 步骤已从最新 plan.md 重新解析。`)
|
|
1081
|
-
console.log('')
|
|
1082
|
-
|
|
1083
|
-
// 重新读取 progress
|
|
1084
|
-
progress = pm.read(cwd, effectiveChange) || progress
|
|
1085
|
-
|
|
1086
|
-
// 注入 revision context 到 platformOpts,供 outputStep 使用
|
|
1087
|
-
const stageData = progress.stages[stageName]
|
|
1088
|
-
if (stageData && stageData.revision > 0) {
|
|
1089
|
-
platformOpts._revision = {
|
|
1090
|
-
revision: stageData.revision,
|
|
1091
|
-
fromStep: stageData.reopenedFromStep,
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
} else {
|
|
1095
|
-
// 非 reopen 的正常执行:如果阶段处于 revising 状态,也注入 revision context
|
|
1096
|
-
const revStageData = progress.stages[stageName]
|
|
1097
|
-
if (revStageData && revStageData.status === 'revising' && revStageData.revision > 0 && !platformOpts._revision) {
|
|
1098
|
-
platformOpts._revision = {
|
|
1099
|
-
revision: revStageData.revision,
|
|
1100
|
-
fromStep: revStageData.reopenedFromStep,
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
// ── quick --cancel:误启动会话的取消口(数据源 quicklog.js cancelQuickSession)──
|
|
1106
|
-
// --change 取 quick-<uuid8> 会话 ID(quick 启动时 CLI echo 的 sessionId);qlId 从会话 guard
|
|
1107
|
-
// 或 --ql 显式参数解析。取消后 db 行注销(quick 会话行非真实变更,直接 unregister 安全)。
|
|
1108
|
-
if (stageName === 'quick' && isCancel) {
|
|
1109
|
-
const cancelSessionRaw = quickSessionId || changeName
|
|
1110
|
-
const qlFlag = getFlagValue('--ql')
|
|
1111
|
-
if (!cancelSessionRaw || cancelSessionRaw === 'quick-unknown') {
|
|
1112
|
-
console.error('用法: sillyspec run quick --cancel --change <quick-会话ID> [--ql <ql-xxx>]\n 取消误启动的 quick 会话:QUICKLOG 条目翻「已取消」+ tasks.md 挂载行移除 + 会话目录清理 + db 行注销。\n 已完成/已勾选的会话拒绝取消(真实工作记录)')
|
|
1113
|
-
process.exit(2)
|
|
1114
|
-
}
|
|
1115
|
-
const specBase = resolveSpecDir(cwd, { specDir })
|
|
1116
|
-
// qlId 优先 --ql 显式;否则读会话 guard.json(allocate 时 CLI 写入);再退 current marker 旁的会话
|
|
1117
|
-
let qlId = qlFlag
|
|
1118
|
-
if (!qlId) {
|
|
1119
|
-
const guardPath = join(specBase, '.runtime', 'quick-sessions', cancelSessionRaw, 'guard.json')
|
|
1120
|
-
try {
|
|
1121
|
-
if (existsSync(guardPath)) qlId = JSON.parse(readFileSync(guardPath, 'utf8')).qlId
|
|
1122
|
-
} catch { /* guard 损坏 → 下面按找不到报错 */ }
|
|
1123
|
-
}
|
|
1124
|
-
if (!qlId) {
|
|
1125
|
-
console.error(`❌ 无法定位会话 ${cancelSessionRaw} 的 qlId(guard.json 缺失/损坏)——显式传 --ql <ql-xxx>(QUICKLOG 条目头)`)
|
|
1126
|
-
process.exit(1)
|
|
1127
|
-
}
|
|
1128
|
-
let gitUser = 'unknown'
|
|
1129
|
-
try { gitUser = (await import('../git-helper.js')).git(cwd, ['config', 'user.name']) || 'unknown' } catch {}
|
|
1130
|
-
const { cancelQuickSession } = await import('../quicklog.js')
|
|
1131
|
-
let result
|
|
1132
|
-
try {
|
|
1133
|
-
result = await cancelQuickSession({ specBase, gitUser, qlId, sessionId: cancelSessionRaw })
|
|
1134
|
-
} catch (e) {
|
|
1135
|
-
console.error(`❌ 取消失败: ${e.message}`)
|
|
1136
|
-
process.exit(1)
|
|
1137
|
-
}
|
|
1138
|
-
if (!result.ok) {
|
|
1139
|
-
console.error(`❌ 取消失败: ${result.reason}`)
|
|
1140
|
-
process.exit(1)
|
|
1141
|
-
}
|
|
1142
|
-
// db 侧:quick 会话行注销(quick-<uuid8> 是进度库里的会话行,非真实变更目录)
|
|
1143
|
-
try {
|
|
1144
|
-
pm.unregisterChange(cwd, cancelSessionRaw)
|
|
1145
|
-
} catch { /* 行不存在/平台模式 → 会话目录清理已完成,db 无行可注销不算失败 */ }
|
|
1146
|
-
console.log(`🗑️ 已取消 quick 会话 ${cancelSessionRaw}(qlId ${qlId})`)
|
|
1147
|
-
console.log(` QUICKLOG 条目翻「已取消」: ${result.quicklogFile}`)
|
|
1148
|
-
if (result.removedTaskRows.length > 0) console.log(` tasks.md 挂载行已移除: ${result.removedTaskRows.join('、')}`)
|
|
1149
|
-
console.log(' 会话 guard 目录与 current marker 已清理(已完成条目不会被取消)')
|
|
1150
|
-
return
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
// quick 启动(非 --done):reset steps + 写 current-quick-run-id(本会话 sessionId,作 --done fallback)。
|
|
1154
|
-
// sessionId 已在参数解析阶段生成(quickSessionId == changeName == quick-<uuid8>),
|
|
1155
|
-
// 这里复用同一值写 current-quick-run-id,保证两处一致。
|
|
1156
|
-
// 旧 quick-YYYYMMDD-HHMMSS 时间戳已摒弃(D-003@v1:同秒并发撞)。
|
|
1157
|
-
if (stageName === 'quick' && !isDone && !isStatus && !isSkip && !isReset && !isReopen) {
|
|
1158
|
-
// 不再无条件 reset steps:原逻辑把任何 quick 非 --done 启动都重置为 pending,致 in-progress
|
|
1159
|
-
// 的 quick 中途查 prompt(sillyspec run quick)丢已 done 的 step 进度(报告
|
|
1160
|
-
// quick-state-reset-platform-mode)。现保留进度——completed 重跑由 runStage 内
|
|
1161
|
-
// currentIdx === -1 自动重置(~1944 行);in-progress 输出当前 step;全新由
|
|
1162
|
-
// ensureStageSteps 初始化;显式从头用 --reset(已由 !isReset 排除出本分支)。
|
|
1163
|
-
try {
|
|
1164
|
-
const runtimeRoot = resolveRuntimeRoot(platformOpts, specRoot)
|
|
1165
|
-
mkdirSync(runtimeRoot, { recursive: true })
|
|
1166
|
-
writeAtomicSync(join(runtimeRoot, 'current-quick-run-id'), quickSessionId + '\n')
|
|
1167
|
-
} catch (e) {
|
|
1168
|
-
// 写失败不能静默:--done 不带 --change 时靠这个文件做跨进程 fallback,写不成就必须显式带 --change
|
|
1169
|
-
console.warn(`⚠️ current-quick-run-id 写入失败(${e.message}),--done 必须显式带 --change ${quickSessionId}`)
|
|
1170
|
-
}
|
|
1171
|
-
// 显式告知 agent 本会话 sessionId + --done 需带 --change(CLI 短进程,run/done 独立进程,
|
|
1172
|
-
// sessionId 靠 --change 跨进程传递;不带 --change 时 fallback 读 current-quick-run-id,多会话不可靠)
|
|
1173
|
-
console.log(`📌 本 quick 会话 sessionId: ${quickSessionId}`)
|
|
1174
|
-
console.log(` 完成时用: sillyspec run quick --done --change ${quickSessionId} --output "..."`)
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
// 确保步骤已初始化
|
|
1178
|
-
const changed = await ensureStageSteps(progress, stageName, cwd, specRoot)
|
|
1179
|
-
if (changed && effectiveChange) {
|
|
1180
|
-
pm._write(cwd, progress, effectiveChange)
|
|
1181
|
-
triggerSync(cwd, effectiveChange, platformOpts)
|
|
1182
|
-
progress = pm.read(cwd, effectiveChange) || progress
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
// --file-notes 非末步静默忽略前置 warn(坑 quick-file-notes-nonfinal-ignored,2026-08-22 实证:
|
|
1186
|
-
// step2 --done 传 --file-notes 被静默丢——CLI 短进程,注入随进程结束即丢,白传一轮)。
|
|
1187
|
-
// 放此处:ensureStageSteps 之后 progress 已就绪可判步骤状态;仅 quick + 带了 --file-notes +
|
|
1188
|
-
// 非「唯一 pending 的末步 --done」时提示。末步 --done 是消费点,不提示。
|
|
1189
|
-
if (quickFileNotes !== '' && stageName === 'quick' && !isStatus) {
|
|
1190
|
-
try {
|
|
1191
|
-
const qSteps = progress?.stages?.quick?.steps
|
|
1192
|
-
const pendingCount = Array.isArray(qSteps) ? qSteps.filter(st => ['pending', 'in-progress'].includes(st?.status)).length : 0
|
|
1193
|
-
if (!isDone || pendingCount > 1) {
|
|
1194
|
-
console.warn(`⚠️ --file-notes 本次不会生效:它只在 quick 末步(暂存和更新记录)--done 时随收尾消费——CLI 是短进程,本次注入随进程结束即丢。请在末步 --done 时连同 --output 一起传。`)
|
|
1195
|
-
}
|
|
1196
|
-
} catch { /* 判定失败不提示(fail-open) */ }
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
// --status
|
|
1200
|
-
if (isStatus) {
|
|
1201
|
-
// D9:状态展示末尾附「下一步该跑什么」。pm 持有状态机,按 progress 实际进度算出精确命令;
|
|
1202
|
-
// 不传则 agent 只看到一堆 step 进度条,却不知道完成后/卡住时下一条命令是什么。
|
|
1203
|
-
let nextSuggestion = null
|
|
1204
|
-
try { nextSuggestion = pm._getNextSuggestion(progress) } catch { /* 读建议失败不阻断状态展示 */ }
|
|
1205
|
-
return showStatus(progress, stageName, nextSuggestion)
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
// --skip
|
|
1209
|
-
if (isSkip) {
|
|
1210
|
-
return await skipStep(pm, progress, stageName, cwd, effectiveChange, platformOpts)
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
// --wait: 将 step 设为 waiting(独立于 --done)
|
|
1214
|
-
if (isWait) {
|
|
1215
|
-
return await waitStep(pm, progress, stageName, cwd, outputText, waitReason, waitOptions, { changeName: effectiveChange, nonInteractive: isNonInteractive && !isInteractive, platformOpts })
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
// --continue: 从 waiting 恢复
|
|
1219
|
-
if (isContinue) {
|
|
1220
|
-
return await continueStep(pm, progress, stageName, cwd, continueAnswer, { changeName: effectiveChange, nonInteractive: isNonInteractive && !isInteractive, platformOpts, fromStep: fromStepValue })
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
// --done
|
|
1224
|
-
if (isDone) {
|
|
1225
|
-
// task-03 (D-004@v1 / FR-02): --done 与 runStage(stage.js:35-45)同源状态转换守卫,
|
|
1226
|
-
// 含 fromStageData 透传(让 scan failed_post_check 门控对 --done 同样生效)。
|
|
1227
|
-
// auxiliary 的 --done 不受影响(checkTransition 对 auxiliary toStage 放行,见 stage-contract.js)。
|
|
1228
|
-
// --skip-approval 绕过语义对齐 runStage(打错但放行)。
|
|
1229
|
-
const prevStage = progress.currentStage || ''
|
|
1230
|
-
const fromStageData = (progress.stages && prevStage && progress.stages[prevStage]) || undefined
|
|
1231
|
-
const transition = checkTransition(prevStage, stageName, fromStageData ? { fromStageData } : {})
|
|
1232
|
-
if (!transition.allowed) {
|
|
1233
|
-
console.error(`❌ 阶段转换不允许: ${prevStage || '(起始)'} → ${stageName}`)
|
|
1234
|
-
console.error(` 原因: ${transition.reason}`)
|
|
1235
|
-
console.error(` 提示: 使用 --skip-approval 绕过(需明确意图)`)
|
|
1236
|
-
if (!isSkipApproval) {
|
|
1237
|
-
process.exit(1)
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
const doneAnswer = getFlagValue('--answer')
|
|
1241
|
-
return await completeStep(pm, progress, stageName, cwd, outputText, inputText, { confirm: isConfirm, changeName: effectiveChange, nonInteractive: isNonInteractive && !isInteractive, platformOpts, doneAnswer, isForceBaseline, isAllowNew, isAllowDelete })
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
// 默认:输出当前步骤
|
|
1245
|
-
return await runStage(pm, progress, stageName, cwd, effectiveChange, isSkipApproval, platformOpts, { quickFiles, isAllowNew, isAllowDelete, isForceBaseline, isForceRescan, linkedChanges, taskDescription: inputText, adoptBranch: stageName === 'execute' && flags.includes('--adopt-branch') })
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
/**
|
|
1249
|
-
* 自动推导变更名(不依赖 progress)
|
|
1250
|
-
*/
|
|
1251
|
-
function resolveChangeNameAuto(cwd, specDir = null) {
|
|
1252
|
-
const changesDir = join(specDir || resolveSpecDir(cwd), 'changes')
|
|
1253
|
-
if (!existsSync(changesDir)) return null
|
|
1254
|
-
const entries = readdirSync(changesDir, { withFileTypes: true })
|
|
1255
|
-
.filter(e => e.isDirectory() && e.name !== 'archive')
|
|
1256
|
-
if (entries.length === 1) return entries[0].name
|
|
1257
|
-
return null
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
function showStatus(progress, stageName, nextSuggestion = null) {
|
|
1261
|
-
const stageData = progress.stages[stageName]
|
|
1262
|
-
const stageDef = stageRegistry[stageName]
|
|
1263
|
-
|
|
1264
|
-
if (!stageData || !stageData.steps || stageData.steps.length === 0) {
|
|
1265
|
-
console.log(`阶段:${stageName}(${stageDef?.title || stageName})`)
|
|
1266
|
-
console.log(`进度:未初始化`)
|
|
1267
|
-
if (stageData?.status) {
|
|
1268
|
-
console.log(`状态:${stageData.status}`)
|
|
1269
|
-
if (stageData.staleReason) console.log(`⚠️ 失效原因:${stageData.staleReason}`)
|
|
1270
|
-
}
|
|
1271
|
-
return
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
const steps = stageData.steps
|
|
1275
|
-
const completed = steps.filter(s => s.status === 'completed' || s.status === 'skipped').length
|
|
1276
|
-
const bar = '█'.repeat(completed) + '░'.repeat(steps.length - completed)
|
|
1277
|
-
|
|
1278
|
-
console.log(`阶段:${stageName}(${stageDef?.title || stageName})`)
|
|
1279
|
-
console.log(`进度:[${bar}] ${completed}/${steps.length}`)
|
|
1280
|
-
|
|
1281
|
-
// ── Revision v1 信息 ──
|
|
1282
|
-
if (stageData.status === 'revising') {
|
|
1283
|
-
console.log(`\n🔧 修订中 (revision ${stageData.revision || 1})`)
|
|
1284
|
-
if (stageData.reopenedFromStep) console.log(` 从步骤:${stageData.reopenedFromStep}`)
|
|
1285
|
-
if (stageData.reopenedAt) console.log(` 重开时间:${stageData.reopenedAt}`)
|
|
1286
|
-
}
|
|
1287
|
-
if (stageData.status === 'stale') {
|
|
1288
|
-
console.log(`\n⚠️ 已失效`)
|
|
1289
|
-
if (stageData.staleReason) console.log(` 原因:${stageData.staleReason}`)
|
|
1290
|
-
console.log(` 建议:sillyspec run ${stageName} --reopen --from-step 1`)
|
|
1291
|
-
}
|
|
1292
|
-
if (stageData.status === 'completed') {
|
|
1293
|
-
console.log(`\n✅ 已完成`)
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
console.log('')
|
|
1297
|
-
|
|
1298
|
-
const firstPending = steps.findIndex(s => s.status === 'pending' || s.status === 'in-progress')
|
|
1299
|
-
|
|
1300
|
-
if (progress.batchProgress) {
|
|
1301
|
-
const bp = progress.batchProgress
|
|
1302
|
-
const bpTotal = bp.total || 0
|
|
1303
|
-
const bpCompleted = bp.completed || 0
|
|
1304
|
-
const bpFailed = bp.failed || 0
|
|
1305
|
-
const bpSkipped = bp.skipped || 0
|
|
1306
|
-
const bpBarLen = 20
|
|
1307
|
-
const bpFilled = Math.round((bpCompleted / Math.max(bpTotal, 1)) * bpBarLen)
|
|
1308
|
-
const bpBar = '█'.repeat(bpFilled) + '░'.repeat(bpBarLen - bpFilled)
|
|
1309
|
-
const bpParts = []
|
|
1310
|
-
if (bpFailed > 0) bpParts.push(`${bpFailed} 失败`)
|
|
1311
|
-
if (bpSkipped > 0) bpParts.push(`${bpSkipped} 跳过`)
|
|
1312
|
-
const bpSuffix = bpParts.length ? ` (${bpParts.join(', ')})` : ''
|
|
1313
|
-
console.log(`\n📊 批量进度: ${bpBar} ${bpCompleted}/${bpTotal}${bpSuffix}\n`)
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
steps.forEach((step, i) => {
|
|
1317
|
-
const icon = step.status === 'completed' ? '✅' : step.status === 'skipped' ? '⏭️' : step.status === 'waiting' ? '⏸️' : '⬜'
|
|
1318
|
-
const isCurrent = (step.status === 'pending' || step.status === 'in-progress') && i === firstPending
|
|
1319
|
-
const isWaiting = step.status === 'waiting'
|
|
1320
|
-
console.log(`${icon} Step ${i + 1}: ${step.name}${isCurrent ? ' ← 当前' : ''}${isWaiting ? ' [WAITING]' : ''}`)
|
|
1321
|
-
if (isWaiting) {
|
|
1322
|
-
if (step.waitReason) console.log(` 原因:${step.waitReason}`)
|
|
1323
|
-
if (step.waitOptions) console.log(` 选项:${formatWaitOptions(step.waitOptions)}`)
|
|
1324
|
-
if (step.waitedAt) console.log(` 等待时间:${step.waitedAt}`)
|
|
1325
|
-
}
|
|
1326
|
-
})
|
|
1327
|
-
|
|
1328
|
-
// D9:本阶段进度之后,给出全局「下一步该跑什么」——
|
|
1329
|
-
// 否则 agent 看完进度条仍要自己推状态机(尤其阶段已完成 / 失效 / 修订中这类非线性状态)。
|
|
1330
|
-
if (nextSuggestion && nextSuggestion.command) {
|
|
1331
|
-
console.log(`\n👉 ${nextSuggestion.text}`)
|
|
1332
|
-
console.log(` 下一步命令:${nextSuggestion.command}`)
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
async function resetStage(pm, progress, stageName, cwd, changeName, platformOpts = {}) {
|
|
1337
|
-
// execute 阶段 reset 时清理自建 worktree,否则下次 run execute 会因 existingMeta 存在
|
|
1338
|
-
// 直接复用带脏状态的旧 worktree(启动逻辑:meta 存在即复用,不查健康状态)
|
|
1339
|
-
if (stageName === 'execute' && changeName) {
|
|
1340
|
-
try {
|
|
1341
|
-
const { WorktreeManager } = await import('../worktree.js')
|
|
1342
|
-
const wm = new WorktreeManager({ cwd })
|
|
1343
|
-
const meta = wm.getMeta(changeName)
|
|
1344
|
-
if (meta) {
|
|
1345
|
-
const cleanResult = wm.cleanup(changeName, { force: true })
|
|
1346
|
-
if (cleanResult.residual?.length > 0) {
|
|
1347
|
-
console.warn(`⚠️ reset 清理 worktree 残留: ${cleanResult.residual.join('; ')}`)
|
|
1348
|
-
console.warn(` 手动处理: sillyspec worktree cleanup ${changeName} --force`)
|
|
1349
|
-
} else if (cleanResult.result === 'kept') {
|
|
1350
|
-
console.log(`🔗 旧 worktree 保留 (${cleanResult.mode}: 外部隔离环境)`)
|
|
1351
|
-
} else if (cleanResult.result !== 'skipped') {
|
|
1352
|
-
console.log(`🧹 已清理旧 worktree (${cleanResult.result}, mode: ${cleanResult.mode}),下次 execute 将重建干净环境`)
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
} catch (e) {
|
|
1356
|
-
console.warn(`⚠️ reset 清理 worktree 失败(不阻断 reset): ${e.message}`)
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
const defSteps = await getStageSteps(stageName, cwd, progress, platformOpts?.specRoot || null)
|
|
1360
|
-
progress.stages[stageName] = {
|
|
1361
|
-
status: 'in-progress',
|
|
1362
|
-
startedAt: new Date().toLocaleString('zh-CN',{hour12:false}),
|
|
1363
|
-
completedAt: null,
|
|
1364
|
-
steps: defSteps ? defSteps.map(s => ({ name: s.name, status: 'pending' })) : []
|
|
1365
|
-
}
|
|
1366
|
-
progress.lastActive = new Date().toLocaleString('zh-CN',{hour12:false})
|
|
1367
|
-
pm._write(cwd, progress, changeName)
|
|
1368
|
-
triggerSync(cwd, changeName, platformOpts)
|
|
1369
|
-
console.log(`🔄 ${stageName} 阶段已重置`)
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
/**
|
|
1373
|
-
* auto 模式:自动推进 brainstorm → plan → execute → verify
|
|
1374
|
-
*/
|
|
1375
|
-
async function runAutoMode(pm, progress, cwd, flags, changeName, platformOpts = {}) {
|
|
1376
|
-
const flowStages = ['brainstorm', 'plan', 'execute', 'verify', 'archive']
|
|
1377
|
-
const isDone = flags.includes('--done')
|
|
1378
|
-
// F4 守卫(坑 raw-flag-value-bypass,与 runCommand getFlagValue 同款):裸 flags[idx+1] 会把
|
|
1379
|
-
// 漏值后紧跟的 flag 名当值(--output --done → outputText="--done" 污染落盘 output)。
|
|
1380
|
-
const autoFlagValue = (name) => {
|
|
1381
|
-
const i = flags.indexOf(name)
|
|
1382
|
-
const next = i !== -1 ? flags[i + 1] : undefined
|
|
1383
|
-
return next && !String(next).startsWith('--') ? next : null
|
|
1384
|
-
}
|
|
1385
|
-
const outputText = autoFlagValue('--output')
|
|
1386
|
-
const inputText = autoFlagValue('--input')
|
|
1387
|
-
const skipApproval = flags.includes('--skip-approval')
|
|
1388
|
-
const explicitMode = autoFlagValue('--mode')
|
|
1389
|
-
const specBase = platformOpts?.specRoot || join(cwd, '.sillyspec')
|
|
1390
|
-
|
|
1391
|
-
// Helper: 在 auto 模式下获取步骤定义
|
|
1392
|
-
const getAutoSteps = async (stage) => {
|
|
1393
|
-
if (stage === 'brainstorm') {
|
|
1394
|
-
return brainstormAutoDef.steps
|
|
1395
|
-
}
|
|
1396
|
-
return getStageSteps(stage, cwd, progress, platformOpts?.specRoot || null)
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
const nextInFlow = (stage) => {
|
|
1400
|
-
const i = flowStages.indexOf(stage)
|
|
1401
|
-
return i >= 0 && i < flowStages.length - 1 ? flowStages[i + 1] : null
|
|
1402
|
-
}
|
|
1403
|
-
const firstOpenStage = () => flowStages.find(s => progress.stages?.[s]?.status !== 'completed')
|
|
1404
|
-
const ensureAutoStage = async (stage) => {
|
|
1405
|
-
const stageChanged = progress.currentStage !== stage
|
|
1406
|
-
progress.currentStage = stage
|
|
1407
|
-
// Auto 模式下 brainstorm 使用 artifact-first 步骤
|
|
1408
|
-
if (stage === 'brainstorm') {
|
|
1409
|
-
const existingSteps = progress.stages?.brainstorm?.steps
|
|
1410
|
-
const isAutoModeSteps = existingSteps?.length === 4 && existingSteps?.[0]?.name === '进度确认与上下文加载'
|
|
1411
|
-
if (!isAutoModeSteps) {
|
|
1412
|
-
if (!progress.stages) progress.stages = {}
|
|
1413
|
-
progress.stages.brainstorm = {
|
|
1414
|
-
status: 'in-progress',
|
|
1415
|
-
startedAt: new Date().toLocaleString('zh-CN', { hour12: false }),
|
|
1416
|
-
completedAt: null,
|
|
1417
|
-
steps: brainstormAutoDef.steps.map(s => ({ name: s.name, status: 'pending' }))
|
|
1418
|
-
}
|
|
1419
|
-
pm._write(cwd, progress, changeName)
|
|
1420
|
-
triggerSync(cwd, changeName, platformOpts)
|
|
1421
|
-
progress = pm.read(cwd, changeName)
|
|
1422
|
-
return progress
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
// specRoot 必传(坑 auto-mode-specroot-miss):平台模式 specRoot 是外部目录,漏传时
|
|
1426
|
-
// getStageSteps 从 cwd 推导 miss 掉 plan/execute 动态步骤(buildPlanSteps(null) 只剩
|
|
1427
|
-
// 2 步 fixedPrefix),种出的步骤表两次 --done 即判阶段完成,与 getAutoSteps 渲染双轨失配
|
|
1428
|
-
const changed = await ensureStageSteps(progress, stage, cwd, platformOpts?.specRoot || null)
|
|
1429
|
-
if (stageChanged || changed) {
|
|
1430
|
-
pm._write(cwd, progress, changeName)
|
|
1431
|
-
triggerSync(cwd, changeName, platformOpts)
|
|
1432
|
-
}
|
|
1433
|
-
progress = pm.read(cwd, changeName)
|
|
1434
|
-
return progress
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
// ── Classify change on first entry ──
|
|
1438
|
-
if (!progress.stages?.brainstorm?.status && !progress.stages?.plan?.status) {
|
|
1439
|
-
const { classifyChange, readAutoModeFromLocalYaml } = await import('../classify-change.js')
|
|
1440
|
-
// auto_mode 接线(2026-08-11):从 local.yaml 读 auto_mode 段传 localConfig,让 force_*_patterns 真生效。
|
|
1441
|
-
const localConfig = readAutoModeFromLocalYaml(cwd)
|
|
1442
|
-
const classification = classifyChange({ description: inputText || '', explicitMode, localConfig })
|
|
1443
|
-
if (classification.mode === 'quick') {
|
|
1444
|
-
console.log(`📊 auto 模式分类:${classification.mode}(${classification.reason})`)
|
|
1445
|
-
console.log(` 此变更建议使用 quick 模式,运行:sillyspec run quick "${inputText || '需求'}"`)
|
|
1446
|
-
return
|
|
1447
|
-
}
|
|
1448
|
-
console.log(`📊 auto 模式分类:${classification.mode}(${classification.reason})`)
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
let currentStage = progress.currentStage
|
|
1452
|
-
if (!currentStage || progress.stages?.[currentStage]?.status === 'completed') {
|
|
1453
|
-
currentStage = firstOpenStage()
|
|
1454
|
-
}
|
|
1455
|
-
if (!currentStage) {
|
|
1456
|
-
console.log('All auto flow stages are complete.')
|
|
1457
|
-
return
|
|
1458
|
-
}
|
|
1459
|
-
if (!flowStages.includes(currentStage)) {
|
|
1460
|
-
const openStage = firstOpenStage()
|
|
1461
|
-
if (!openStage) {
|
|
1462
|
-
console.log('All auto flow stages are complete.')
|
|
1463
|
-
return
|
|
1464
|
-
}
|
|
1465
|
-
console.log(`⚠️ 当前阶段 ${currentStage} 不在 auto 流程中,自动跳转到 ${openStage}`)
|
|
1466
|
-
currentStage = openStage
|
|
1467
|
-
}
|
|
1468
|
-
await ensureAutoStage(currentStage)
|
|
1469
|
-
|
|
1470
|
-
if (!isDone) {
|
|
1471
|
-
console.log('════════════════════════════════════════')
|
|
1472
|
-
console.log(' SillySpec Auto Mode')
|
|
1473
|
-
if (changeName) console.log(` Change: ${changeName}`)
|
|
1474
|
-
console.log('════════════════════════════════════════')
|
|
1475
|
-
console.log(` Flow: ${flowStages.join(' -> ')}`)
|
|
1476
|
-
console.log(` Current: ${currentStage}`)
|
|
1477
|
-
for (const stage of flowStages) {
|
|
1478
|
-
const stageData = progress.stages?.[stage]
|
|
1479
|
-
const total = stageData?.steps?.length || '?'
|
|
1480
|
-
const completed = stageData?.steps?.filter(step => step.status === 'completed' || step.status === 'skipped').length || 0
|
|
1481
|
-
const marker = stageData?.status === 'completed' ? 'done' : stage === currentStage ? 'active' : 'pending'
|
|
1482
|
-
console.log(` ${marker} ${stage} (${completed}/${total})`)
|
|
1483
|
-
}
|
|
1484
|
-
console.log('')
|
|
1485
|
-
|
|
1486
|
-
const defSteps = await getAutoSteps(currentStage)
|
|
1487
|
-
const pendingIdx = progress.stages[currentStage]?.steps?.findIndex(step => step.status === 'pending' || step.status === 'in-progress') ?? -1
|
|
1488
|
-
if (pendingIdx === -1) {
|
|
1489
|
-
const wsIdx = progress.stages[currentStage]?.steps?.findIndex(step => step.status === 'waiting') ?? -1
|
|
1490
|
-
if (wsIdx !== -1) {
|
|
1491
|
-
const ws = progress.stages[currentStage].steps[wsIdx]
|
|
1492
|
-
console.log(`⏸️ Step ${wsIdx + 1} 等待用户输入:${ws.name}`)
|
|
1493
|
-
if (ws.waitReason) console.log(` 原因:${ws.waitReason}`)
|
|
1494
|
-
console.log(` 继续:sillyspec run auto --continue --answer "..."`)
|
|
1495
|
-
return
|
|
1496
|
-
}
|
|
1497
|
-
const next = nextInFlow(currentStage)
|
|
1498
|
-
if (next) console.log(`${currentStage} is complete. Run: sillyspec run auto --done --output "${currentStage} complete"`)
|
|
1499
|
-
else console.log('All auto flow stages are complete.')
|
|
1500
|
-
return
|
|
1501
|
-
}
|
|
1502
|
-
// execute 阶段启动前检查审批
|
|
1503
|
-
if (currentStage === 'execute' && !skipApproval) {
|
|
1504
|
-
const approval = await checkApproval(cwd, changeName, platformOpts)
|
|
1505
|
-
if (approval) {
|
|
1506
|
-
if (approval.status === 'rejected') {
|
|
1507
|
-
console.error(`❌ 变更 ${changeName} 的执行已被拒绝:${approval.reason || '无原因'}`)
|
|
1508
|
-
process.exit(1)
|
|
1509
|
-
}
|
|
1510
|
-
if (approval.status === 'pending') {
|
|
1511
|
-
console.log(`⏳ 变更 ${changeName} 的执行审批待处理中...`)
|
|
1512
|
-
console.log(' 提示:使用 --skip-approval 跳过审批检查')
|
|
1513
|
-
}
|
|
1514
|
-
// HUB-07:unknown 醒目警告 + 留痕(原单行 warn 不显眼且无记录)
|
|
1515
|
-
if (approval.status === 'unknown') {
|
|
1516
|
-
warnApprovalUnknown(cwd, changeName, approval.reason)
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
await outputStep(currentStage, pendingIdx, defSteps, cwd, changeName, progress.project || null, platformOpts)
|
|
1521
|
-
return
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
if (!outputText) {
|
|
1525
|
-
console.error('auto --done requires --output')
|
|
1526
|
-
process.exit(2) // 用法错 → exit 2
|
|
1527
|
-
}
|
|
1528
|
-
|
|
1529
|
-
const result = await completeStep(pm, progress, currentStage, cwd, outputText, inputText, { printNext: false, changeName, platformOpts })
|
|
1530
|
-
if (!result) return
|
|
1531
|
-
progress = pm.read(cwd, changeName)
|
|
1532
|
-
// change 行被并发归档/删除时 read 返回 null(体检 BUG-05):引导排查而非 TypeError 崩溃
|
|
1533
|
-
if (!progress) {
|
|
1534
|
-
console.error(`❌ 完成步骤后进度数据消失(变更 ${changeName} 可能被并发归档/删除),请用 sillyspec progress show 核对当前状态`)
|
|
1535
|
-
process.exitCode = 1
|
|
1536
|
-
return
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
|
-
const nextPendingIdx = progress.stages[currentStage]?.steps?.findIndex(step => step.status === 'pending' || step.status === 'in-progress') ?? -1
|
|
1540
|
-
if (nextPendingIdx !== -1) {
|
|
1541
|
-
const defSteps = await getAutoSteps(currentStage)
|
|
1542
|
-
// execute 阶段启动前检查审批
|
|
1543
|
-
if (currentStage === 'execute' && !skipApproval) {
|
|
1544
|
-
const approval = await checkApproval(cwd, changeName, platformOpts)
|
|
1545
|
-
if (approval) {
|
|
1546
|
-
if (approval.status === 'rejected') {
|
|
1547
|
-
console.error(`❌ 变更 ${changeName} 的执行已被拒绝:${approval.reason || '无原因'}`)
|
|
1548
|
-
process.exit(1)
|
|
1549
|
-
}
|
|
1550
|
-
if (approval.status === 'pending') {
|
|
1551
|
-
console.log(`⏳ 变更 ${changeName} 的执行审批待处理中...`)
|
|
1552
|
-
console.log(' 提示:使用 --skip-approval 跳过审批检查')
|
|
1553
|
-
}
|
|
1554
|
-
// HUB-07:unknown 醒目警告 + 留痕(原单行 warn 不显眼且无记录)
|
|
1555
|
-
if (approval.status === 'unknown') {
|
|
1556
|
-
warnApprovalUnknown(cwd, changeName, approval.reason)
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
await outputStep(currentStage, nextPendingIdx, defSteps, cwd, changeName, progress.project || null, platformOpts)
|
|
1561
|
-
return
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
|
-
const next = nextInFlow(currentStage)
|
|
1565
|
-
if (!next) {
|
|
1566
|
-
console.log('\nAll auto flow stages are complete.')
|
|
1567
|
-
return
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
// ── next-action.json 驱动:brainstorm → plan 推进判断 ──
|
|
1571
|
-
if (currentStage === 'brainstorm' && next === 'plan') {
|
|
1572
|
-
const changeDir = resolveChangeDir(cwd, progress, platformOpts?.specRoot || null)
|
|
1573
|
-
if (changeDir) {
|
|
1574
|
-
const nextActionFile = join(changeDir, 'next-action.json')
|
|
1575
|
-
try {
|
|
1576
|
-
const nextAction = JSON.parse(readFileSync(nextActionFile, 'utf8'))
|
|
1577
|
-
if (nextAction.has_blocking_questions === true) {
|
|
1578
|
-
console.log(`\n⏸️ brainstorm 有阻塞问题,无法自动进入 plan:`)
|
|
1579
|
-
for (const q of (nextAction.questions || [])) {
|
|
1580
|
-
console.log(` Q-${q.id}: ${q.question}`)
|
|
1581
|
-
if (q.options) console.log(` 选项:${q.options.join(' / ')}`)
|
|
1582
|
-
if (q.recommended) console.log(` 推荐:${q.recommended}`)
|
|
1583
|
-
}
|
|
1584
|
-
console.log(`\n 请回答阻塞问题后继续:sillyspec run auto --done --output "已回答"`)
|
|
1585
|
-
return
|
|
1586
|
-
}
|
|
1587
|
-
console.log(`\n✅ next-action.json: ${nextAction.status},自动进入 plan`)
|
|
1588
|
-
} catch (e) {
|
|
1589
|
-
// next-action.json 不存在或格式错误,继续推进(向后兼容)
|
|
1590
|
-
console.log(`\n⚠️ next-action.json 未找到,继续进入 plan`)
|
|
1591
|
-
}
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
progress.currentStage = next
|
|
1596
|
-
if (!progress.stages[next]) {
|
|
1597
|
-
progress.stages[next] = { status: 'pending', steps: [], startedAt: null, completedAt: null }
|
|
1598
|
-
}
|
|
1599
|
-
if (progress.stages[next].status === 'pending' || !progress.stages[next].status) {
|
|
1600
|
-
progress.stages[next].status = 'in-progress'
|
|
1601
|
-
progress.stages[next].startedAt = new Date().toLocaleString('zh-CN',{hour12:false})
|
|
1602
|
-
}
|
|
1603
|
-
progress.lastActive = new Date().toLocaleString('zh-CN',{hour12:false})
|
|
1604
|
-
// specRoot 同上(坑 auto-mode-specroot-miss):平台模式动态步骤表必须从外部 specRoot 构建
|
|
1605
|
-
await ensureStageSteps(progress, next, cwd, platformOpts?.specRoot || null)
|
|
1606
|
-
pm._write(cwd, progress, changeName)
|
|
1607
|
-
triggerSync(cwd, changeName, platformOpts)
|
|
1608
|
-
progress = pm.read(cwd, changeName)
|
|
1609
|
-
// 同 BUG-05:写入后被并发删除的窗口,null 直接解引用会 TypeError
|
|
1610
|
-
if (!progress) {
|
|
1611
|
-
console.error(`❌ 阶段推进后进度数据消失(变更 ${changeName} 可能被并发归档/删除),请用 sillyspec progress show 核对当前状态`)
|
|
1612
|
-
process.exitCode = 1
|
|
1613
|
-
return
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
console.log(`\n${currentStage} complete. Auto advanced to ${next}.`)
|
|
1617
|
-
const nextSteps = await getAutoSteps(next)
|
|
1618
|
-
const firstPending = progress.stages[next]?.steps?.findIndex(step => step.status === 'pending' || step.status === 'in-progress') ?? -1
|
|
1619
|
-
if (firstPending !== -1) {
|
|
1620
|
-
// execute 阶段启动前检查审批
|
|
1621
|
-
if (next === 'execute' && !skipApproval) {
|
|
1622
|
-
const approval = await checkApproval(cwd, changeName, platformOpts)
|
|
1623
|
-
if (approval) {
|
|
1624
|
-
if (approval.status === 'rejected') {
|
|
1625
|
-
console.error(`❌ 变更 ${changeName} 的执行已被拒绝:${approval.reason || '无原因'}`)
|
|
1626
|
-
process.exit(1)
|
|
1627
|
-
}
|
|
1628
|
-
if (approval.status === 'pending') {
|
|
1629
|
-
console.log(`⏳ 变更 ${changeName} 的执行审批待处理中...`)
|
|
1630
|
-
console.log(' 提示:使用 --skip-approval 跳过审批检查')
|
|
1631
|
-
}
|
|
1632
|
-
// HUB-07:unknown 醒目警告 + 留痕(原单行 warn 不显眼且无记录)
|
|
1633
|
-
if (approval.status === 'unknown') {
|
|
1634
|
-
warnApprovalUnknown(cwd, changeName, approval.reason)
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
await outputStep(next, firstPending, nextSteps, cwd, changeName, progress.project || null, platformOpts)
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
|