sillyspec 3.27.5 → 3.27.7
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-archive/SKILL.md +87 -87
- package/.claude/skills/sillyspec-auto/SKILL.md +93 -93
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -114
- package/.claude/skills/sillyspec-commit/SKILL.md +67 -67
- package/.claude/skills/sillyspec-continue/SKILL.md +47 -47
- package/.claude/skills/sillyspec-doctor/SKILL.md +76 -76
- package/.claude/skills/sillyspec-execute/SKILL.md +214 -214
- package/.claude/skills/sillyspec-explore/SKILL.md +102 -102
- package/.claude/skills/sillyspec-export/SKILL.md +57 -57
- package/.claude/skills/sillyspec-init/SKILL.md +177 -177
- package/.claude/skills/sillyspec-knowledge/SKILL.md +269 -269
- package/.claude/skills/sillyspec-plan/SKILL.md +156 -156
- package/.claude/skills/sillyspec-propose/SKILL.md +87 -0
- package/.claude/skills/sillyspec-quick/SKILL.md +116 -116
- package/.claude/skills/sillyspec-resume/SKILL.md +70 -70
- package/.claude/skills/sillyspec-scan/SKILL.md +79 -79
- package/.claude/skills/sillyspec-state/SKILL.md +64 -64
- package/.claude/skills/sillyspec-status/SKILL.md +54 -54
- package/.claude/skills/sillyspec-verify/SKILL.md +87 -87
- package/.claude/skills/sillyspec-workspace/SKILL.md +175 -175
- package/.claude/skills/verify-per-user/SKILL.md +6 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-archive/SKILL.md +87 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-auto/SKILL.md +93 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-commit/SKILL.md +67 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-continue/SKILL.md +47 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-doctor/SKILL.md +76 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-execute/SKILL.md +214 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-explore/SKILL.md +102 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-export/SKILL.md +57 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-init/SKILL.md +177 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-knowledge/SKILL.md +270 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-plan/SKILL.md +156 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-propose/SKILL.md +87 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-quick/SKILL.md +116 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-resume/SKILL.md +70 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-scan/SKILL.md +79 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-state/SKILL.md +64 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-status/SKILL.md +54 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-verify/SKILL.md +87 -0
- package/.worktrees/2c37b1d7/.claude/skills/sillyspec-workspace/SKILL.md +175 -0
- package/.worktrees/2c37b1d7/.claude/skills/verify-per-user/SKILL.md +6 -0
- package/.worktrees/2c37b1d7/.gitattributes +2 -0
- package/.worktrees/2c37b1d7/.husky/pre-push +20 -0
- package/.worktrees/2c37b1d7/README.md +203 -0
- package/.worktrees/2c37b1d7/SKILL.md +91 -0
- package/.worktrees/2c37b1d7/architecture-analysis.md +448 -0
- package/.worktrees/2c37b1d7/bin/sillyspec.js +2 -0
- package/.worktrees/2c37b1d7/eval/README.md +86 -0
- package/.worktrees/2c37b1d7/eval/eval.config.json +28 -0
- package/.worktrees/2c37b1d7/eval/lib/adapters/cli.mjs +63 -0
- package/.worktrees/2c37b1d7/eval/lib/adapters/dryrun.mjs +27 -0
- package/.worktrees/2c37b1d7/eval/lib/config.mjs +82 -0
- package/.worktrees/2c37b1d7/eval/lib/db.mjs +76 -0
- package/.worktrees/2c37b1d7/eval/lib/report.mjs +120 -0
- package/.worktrees/2c37b1d7/eval/lib/runner.mjs +157 -0
- package/.worktrees/2c37b1d7/eval/lib/tasks.mjs +73 -0
- package/.worktrees/2c37b1d7/eval/lib/util.mjs +107 -0
- package/.worktrees/2c37b1d7/eval/lib/workdir.mjs +30 -0
- package/.worktrees/2c37b1d7/eval/run.mjs +83 -0
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/files/package.json +6 -0
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/solution/src/slugify.mjs +26 -0
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/task.json +6 -0
- package/.worktrees/2c37b1d7/eval/tasks/001-slugify/verify.mjs +28 -0
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/package.json +6 -0
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/src/dates.mjs +4 -0
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/solution/src/dates.mjs +30 -0
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/task.json +6 -0
- package/.worktrees/2c37b1d7/eval/tasks/002-each-day/verify.mjs +31 -0
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/data/notes.txt +5 -0
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/package.json +6 -0
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/solution/bin/report.mjs +36 -0
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/task.json +6 -0
- package/.worktrees/2c37b1d7/eval/tasks/003-word-report/verify.mjs +38 -0
- package/.worktrees/2c37b1d7/logo.jpg +0 -0
- package/.worktrees/2c37b1d7/package-lock.json +977 -0
- package/.worktrees/2c37b1d7/package.json +41 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/index.html +16 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-overview.html +256 -0
- package/.worktrees/2c37b1d7/packages/dashboard/package.json +25 -0
- package/.worktrees/2c37b1d7/packages/dashboard/server/executor.js +95 -0
- package/.worktrees/2c37b1d7/packages/dashboard/server/index.js +679 -0
- package/.worktrees/2c37b1d7/packages/dashboard/server/parser.js +526 -0
- package/.worktrees/2c37b1d7/packages/dashboard/server/watcher.js +357 -0
- package/.worktrees/2c37b1d7/src/agent-session-log.js +803 -0
- package/.worktrees/2c37b1d7/src/change-list.js +290 -0
- package/.worktrees/2c37b1d7/src/change-risk-profile.js +339 -0
- package/.worktrees/2c37b1d7/src/check-primitives.js +65 -0
- package/.worktrees/2c37b1d7/src/classify-change.js +109 -0
- package/.worktrees/2c37b1d7/src/commit-suggest.js +202 -0
- package/.worktrees/2c37b1d7/src/config-cat.js +88 -0
- package/.worktrees/2c37b1d7/src/config-schema.js +328 -0
- package/.worktrees/2c37b1d7/src/constants.js +97 -0
- package/.worktrees/2c37b1d7/src/contract-matrix.js +533 -0
- package/.worktrees/2c37b1d7/src/datetime.js +20 -0
- package/.worktrees/2c37b1d7/src/db-engine.js +55 -0
- package/.worktrees/2c37b1d7/src/db.js +381 -0
- package/.worktrees/2c37b1d7/src/decision-distill.js +517 -0
- package/.worktrees/2c37b1d7/src/dispatch/backends/local-agent.js +155 -0
- package/.worktrees/2c37b1d7/src/dispatch/backends/sillyhub-mcp.js +245 -0
- package/.worktrees/2c37b1d7/src/dispatch/probe.js +246 -0
- package/.worktrees/2c37b1d7/src/dispatch/strategy.js +121 -0
- package/.worktrees/2c37b1d7/src/docs-check.js +825 -0
- package/.worktrees/2c37b1d7/src/docs-debt.js +393 -0
- package/.worktrees/2c37b1d7/src/docs-gate.js +107 -0
- package/.worktrees/2c37b1d7/src/doctor-diagnostics.js +1099 -0
- package/.worktrees/2c37b1d7/src/endpoint-extractor.js +409 -0
- package/.worktrees/2c37b1d7/src/foreign-declared.js +155 -0
- package/.worktrees/2c37b1d7/src/fs-atomic.js +73 -0
- package/.worktrees/2c37b1d7/src/git-helper.js +150 -0
- package/.worktrees/2c37b1d7/src/hooks/claude-pre-tool-use.cjs +130 -0
- package/.worktrees/2c37b1d7/src/hooks/worktree-guard.js +892 -0
- package/.worktrees/2c37b1d7/src/index.js +2854 -0
- package/.worktrees/2c37b1d7/src/init.js +626 -0
- package/.worktrees/2c37b1d7/src/knowledge-match.js +231 -0
- package/.worktrees/2c37b1d7/src/local-detect.js +128 -0
- package/.worktrees/2c37b1d7/src/local-register.js +104 -0
- package/.worktrees/2c37b1d7/src/machine-interface.js +543 -0
- package/.worktrees/2c37b1d7/src/migrate.js +127 -0
- package/.worktrees/2c37b1d7/src/module-impact.js +166 -0
- package/.worktrees/2c37b1d7/src/module-resolve.js +222 -0
- package/.worktrees/2c37b1d7/src/modules.js +580 -0
- package/.worktrees/2c37b1d7/src/plan-adopt-waves.js +126 -0
- package/.worktrees/2c37b1d7/src/progress/change-registry.js +336 -0
- package/.worktrees/2c37b1d7/src/progress/consistency-doctor.js +355 -0
- package/.worktrees/2c37b1d7/src/progress/shared.js +36 -0
- package/.worktrees/2c37b1d7/src/progress/stage-machine.js +594 -0
- package/.worktrees/2c37b1d7/src/progress/step-store.js +265 -0
- package/.worktrees/2c37b1d7/src/progress.js +1304 -0
- package/.worktrees/2c37b1d7/src/quick-recommend.js +115 -0
- package/.worktrees/2c37b1d7/src/quicklog.js +883 -0
- package/.worktrees/2c37b1d7/src/review-tier.js +77 -0
- package/.worktrees/2c37b1d7/src/run/command.js +1641 -0
- package/.worktrees/2c37b1d7/src/run/complete-handlers.js +1552 -0
- package/.worktrees/2c37b1d7/src/run/complete.js +1259 -0
- package/.worktrees/2c37b1d7/src/run/concurrent-detect.js +156 -0
- package/.worktrees/2c37b1d7/src/run/gates.js +1111 -0
- package/.worktrees/2c37b1d7/src/run/multi-repo-context.js +208 -0
- package/.worktrees/2c37b1d7/src/run/next.js +128 -0
- package/.worktrees/2c37b1d7/src/run/prompt.js +843 -0
- package/.worktrees/2c37b1d7/src/run/quick-audit.js +186 -0
- package/.worktrees/2c37b1d7/src/run/scan-profile.js +269 -0
- package/.worktrees/2c37b1d7/src/run/shared.js +1562 -0
- package/.worktrees/2c37b1d7/src/run/stage.js +587 -0
- package/.worktrees/2c37b1d7/src/run.js +23 -0
- package/.worktrees/2c37b1d7/src/scan-diff.js +388 -0
- package/.worktrees/2c37b1d7/src/scan-postcheck.js +524 -0
- package/.worktrees/2c37b1d7/src/scan-staleness.js +95 -0
- package/.worktrees/2c37b1d7/src/setup.js +414 -0
- package/.worktrees/2c37b1d7/src/sillyhub-mcp/client.js +597 -0
- package/.worktrees/2c37b1d7/src/sillyhub-mcp/config.js +62 -0
- package/.worktrees/2c37b1d7/src/spec-dir-typo.js +50 -0
- package/.worktrees/2c37b1d7/src/spec-sync.js +358 -0
- package/.worktrees/2c37b1d7/src/stage-contract-engine.js +171 -0
- package/.worktrees/2c37b1d7/src/stage-contract-spec.js +551 -0
- package/.worktrees/2c37b1d7/src/stage-contract.js +948 -0
- package/.worktrees/2c37b1d7/src/stage-review.js +597 -0
- package/.worktrees/2c37b1d7/src/stages/archive.js +199 -0
- package/.worktrees/2c37b1d7/src/stages/brainstorm-auto.js +285 -0
- package/.worktrees/2c37b1d7/src/stages/brainstorm.js +624 -0
- package/.worktrees/2c37b1d7/src/stages/cmd-existence.js +145 -0
- package/.worktrees/2c37b1d7/src/stages/doctor.js +540 -0
- package/.worktrees/2c37b1d7/src/stages/execute.js +1277 -0
- package/.worktrees/2c37b1d7/src/stages/explore.js +43 -0
- package/.worktrees/2c37b1d7/src/stages/index.js +29 -0
- package/.worktrees/2c37b1d7/src/stages/knowledge.js +514 -0
- package/.worktrees/2c37b1d7/src/stages/plan-postcheck.js +1398 -0
- package/.worktrees/2c37b1d7/src/stages/plan.js +655 -0
- package/.worktrees/2c37b1d7/src/stages/quick.js +167 -0
- package/.worktrees/2c37b1d7/src/stages/scan.js +608 -0
- package/.worktrees/2c37b1d7/src/stages/status.js +64 -0
- package/.worktrees/2c37b1d7/src/stages/verify.js +246 -0
- package/.worktrees/2c37b1d7/src/sync.js +1470 -0
- package/.worktrees/2c37b1d7/src/task-review.js +1498 -0
- package/.worktrees/2c37b1d7/src/taskcard-placeholders.js +21 -0
- package/.worktrees/2c37b1d7/src/taskcard.js +250 -0
- package/.worktrees/2c37b1d7/src/verify-postcheck.js +1718 -0
- package/.worktrees/2c37b1d7/src/verify-probes.js +327 -0
- package/.worktrees/2c37b1d7/src/version.js +19 -0
- package/.worktrees/2c37b1d7/src/workflow.js +600 -0
- package/.worktrees/2c37b1d7/src/workspace.js +125 -0
- package/.worktrees/2c37b1d7/src/worktree-apply.js +1611 -0
- package/.worktrees/2c37b1d7/src/worktree-deps.js +668 -0
- package/.worktrees/2c37b1d7/src/worktree.js +1849 -0
- package/.worktrees/2c37b1d7/templates/claude-instruction.md +23 -0
- package/.worktrees/2c37b1d7/templates/prompts/taskcard-rules.md +29 -0
- package/.worktrees/2c37b1d7/templates/prompts/testcase-design.md +12 -0
- package/.worktrees/2c37b1d7/templates/prompts/verify-probes.md +32 -0
- package/.worktrees/2c37b1d7/templates/workflows/archive-impact.yaml +79 -0
- package/.worktrees/2c37b1d7/templates/workflows/scan-docs.yaml +132 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-archive/SKILL.md +87 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-auto/SKILL.md +93 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-commit/SKILL.md +67 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-continue/SKILL.md +47 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-doctor/SKILL.md +76 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-execute/SKILL.md +214 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-explore/SKILL.md +102 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-export/SKILL.md +57 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-init/SKILL.md +177 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-knowledge/SKILL.md +270 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-plan/SKILL.md +156 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-quick/SKILL.md +116 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-resume/SKILL.md +70 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-scan/SKILL.md +79 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-state/SKILL.md +64 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-status/SKILL.md +54 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-verify/SKILL.md +87 -0
- package/.worktrees/542c4415/.claude/skills/sillyspec-workspace/SKILL.md +175 -0
- package/.worktrees/542c4415/.gitattributes +2 -0
- package/.worktrees/542c4415/.husky/pre-push +20 -0
- package/.worktrees/542c4415/README.md +203 -0
- package/.worktrees/542c4415/SKILL.md +91 -0
- package/.worktrees/542c4415/architecture-analysis.md +448 -0
- package/.worktrees/542c4415/bin/sillyspec.js +2 -0
- package/.worktrees/542c4415/eval/README.md +86 -0
- package/.worktrees/542c4415/eval/eval.config.json +28 -0
- package/.worktrees/542c4415/eval/lib/adapters/cli.mjs +63 -0
- package/.worktrees/542c4415/eval/lib/adapters/dryrun.mjs +27 -0
- package/.worktrees/542c4415/eval/lib/config.mjs +82 -0
- package/.worktrees/542c4415/eval/lib/db.mjs +76 -0
- package/.worktrees/542c4415/eval/lib/report.mjs +120 -0
- package/.worktrees/542c4415/eval/lib/runner.mjs +157 -0
- package/.worktrees/542c4415/eval/lib/tasks.mjs +73 -0
- package/.worktrees/542c4415/eval/lib/util.mjs +107 -0
- package/.worktrees/542c4415/eval/lib/workdir.mjs +30 -0
- package/.worktrees/542c4415/eval/run.mjs +83 -0
- package/.worktrees/542c4415/eval/tasks/001-slugify/files/package.json +6 -0
- package/.worktrees/542c4415/eval/tasks/001-slugify/solution/src/slugify.mjs +26 -0
- package/.worktrees/542c4415/eval/tasks/001-slugify/task.json +6 -0
- package/.worktrees/542c4415/eval/tasks/001-slugify/verify.mjs +28 -0
- package/.worktrees/542c4415/eval/tasks/002-each-day/files/package.json +6 -0
- package/.worktrees/542c4415/eval/tasks/002-each-day/files/src/dates.mjs +4 -0
- package/.worktrees/542c4415/eval/tasks/002-each-day/solution/src/dates.mjs +30 -0
- package/.worktrees/542c4415/eval/tasks/002-each-day/task.json +6 -0
- package/.worktrees/542c4415/eval/tasks/002-each-day/verify.mjs +31 -0
- package/.worktrees/542c4415/eval/tasks/003-word-report/files/data/notes.txt +5 -0
- package/.worktrees/542c4415/eval/tasks/003-word-report/files/package.json +6 -0
- package/.worktrees/542c4415/eval/tasks/003-word-report/solution/bin/report.mjs +36 -0
- package/.worktrees/542c4415/eval/tasks/003-word-report/task.json +6 -0
- package/.worktrees/542c4415/eval/tasks/003-word-report/verify.mjs +38 -0
- package/.worktrees/542c4415/logo.jpg +0 -0
- package/.worktrees/542c4415/package-lock.json +977 -0
- package/.worktrees/542c4415/package.json +41 -0
- package/.worktrees/542c4415/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -0
- package/.worktrees/542c4415/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -0
- package/.worktrees/542c4415/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/542c4415/packages/dashboard/dist/index.html +16 -0
- package/.worktrees/542c4415/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/542c4415/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/.worktrees/542c4415/packages/dashboard/dist/prototype-overview.html +256 -0
- package/.worktrees/542c4415/packages/dashboard/package.json +25 -0
- package/.worktrees/542c4415/packages/dashboard/server/executor.js +95 -0
- package/.worktrees/542c4415/packages/dashboard/server/index.js +679 -0
- package/.worktrees/542c4415/packages/dashboard/server/parser.js +526 -0
- package/.worktrees/542c4415/packages/dashboard/server/watcher.js +357 -0
- package/.worktrees/542c4415/src/agent-session-log.js +803 -0
- package/.worktrees/542c4415/src/change-list.js +290 -0
- package/.worktrees/542c4415/src/change-risk-profile.js +339 -0
- package/.worktrees/542c4415/src/check-primitives.js +65 -0
- package/.worktrees/542c4415/src/classify-change.js +109 -0
- package/.worktrees/542c4415/src/commit-suggest.js +202 -0
- package/.worktrees/542c4415/src/config-cat.js +88 -0
- package/.worktrees/542c4415/src/config-schema.js +328 -0
- package/.worktrees/542c4415/src/constants.js +97 -0
- package/.worktrees/542c4415/src/contract-matrix.js +533 -0
- package/.worktrees/542c4415/src/datetime.js +20 -0
- package/.worktrees/542c4415/src/db-engine.js +55 -0
- package/.worktrees/542c4415/src/db.js +381 -0
- package/.worktrees/542c4415/src/decision-distill.js +517 -0
- package/.worktrees/542c4415/src/dispatch/backends/local-agent.js +155 -0
- package/.worktrees/542c4415/src/dispatch/backends/sillyhub-mcp.js +245 -0
- package/.worktrees/542c4415/src/dispatch/probe.js +246 -0
- package/.worktrees/542c4415/src/dispatch/strategy.js +121 -0
- package/.worktrees/542c4415/src/docs-check.js +825 -0
- package/.worktrees/542c4415/src/docs-debt.js +393 -0
- package/.worktrees/542c4415/src/docs-gate.js +107 -0
- package/.worktrees/542c4415/src/doctor-diagnostics.js +1099 -0
- package/.worktrees/542c4415/src/endpoint-extractor.js +409 -0
- package/.worktrees/542c4415/src/foreign-declared.js +155 -0
- package/.worktrees/542c4415/src/fs-atomic.js +73 -0
- package/.worktrees/542c4415/src/git-helper.js +150 -0
- package/.worktrees/542c4415/src/hooks/claude-pre-tool-use.cjs +130 -0
- package/.worktrees/542c4415/src/hooks/worktree-guard.js +892 -0
- package/.worktrees/542c4415/src/index.js +2854 -0
- package/.worktrees/542c4415/src/init.js +626 -0
- package/.worktrees/542c4415/src/knowledge-match.js +231 -0
- package/.worktrees/542c4415/src/local-detect.js +128 -0
- package/.worktrees/542c4415/src/local-register.js +104 -0
- package/.worktrees/542c4415/src/machine-interface.js +543 -0
- package/.worktrees/542c4415/src/migrate.js +127 -0
- package/.worktrees/542c4415/src/module-impact.js +166 -0
- package/.worktrees/542c4415/src/module-resolve.js +222 -0
- package/.worktrees/542c4415/src/modules.js +580 -0
- package/.worktrees/542c4415/src/plan-adopt-waves.js +126 -0
- package/.worktrees/542c4415/src/progress/change-registry.js +336 -0
- package/.worktrees/542c4415/src/progress/consistency-doctor.js +355 -0
- package/.worktrees/542c4415/src/progress/shared.js +36 -0
- package/.worktrees/542c4415/src/progress/stage-machine.js +594 -0
- package/.worktrees/542c4415/src/progress/step-store.js +265 -0
- package/.worktrees/542c4415/src/progress.js +1304 -0
- package/.worktrees/542c4415/src/quick-recommend.js +115 -0
- package/.worktrees/542c4415/src/quicklog.js +883 -0
- package/.worktrees/542c4415/src/review-tier.js +77 -0
- package/.worktrees/542c4415/src/run/command.js +1641 -0
- package/.worktrees/542c4415/src/run/complete-handlers.js +1552 -0
- package/.worktrees/542c4415/src/run/complete.js +1259 -0
- package/.worktrees/542c4415/src/run/concurrent-detect.js +156 -0
- package/.worktrees/542c4415/src/run/gates.js +1111 -0
- package/.worktrees/542c4415/src/run/multi-repo-context.js +208 -0
- package/.worktrees/542c4415/src/run/next.js +128 -0
- package/.worktrees/542c4415/src/run/prompt.js +843 -0
- package/.worktrees/542c4415/src/run/quick-audit.js +186 -0
- package/.worktrees/542c4415/src/run/scan-profile.js +269 -0
- package/.worktrees/542c4415/src/run/shared.js +1562 -0
- package/.worktrees/542c4415/src/run/stage.js +587 -0
- package/.worktrees/542c4415/src/run.js +23 -0
- package/.worktrees/542c4415/src/scan-diff.js +388 -0
- package/.worktrees/542c4415/src/scan-postcheck.js +524 -0
- package/.worktrees/542c4415/src/scan-staleness.js +95 -0
- package/.worktrees/542c4415/src/setup.js +414 -0
- package/.worktrees/542c4415/src/sillyhub-mcp/client.js +597 -0
- package/.worktrees/542c4415/src/sillyhub-mcp/config.js +62 -0
- package/.worktrees/542c4415/src/spec-dir-typo.js +50 -0
- package/.worktrees/542c4415/src/spec-sync.js +358 -0
- package/.worktrees/542c4415/src/stage-contract-engine.js +171 -0
- package/.worktrees/542c4415/src/stage-contract-spec.js +551 -0
- package/.worktrees/542c4415/src/stage-contract.js +948 -0
- package/.worktrees/542c4415/src/stage-review.js +597 -0
- package/.worktrees/542c4415/src/stages/archive.js +199 -0
- package/.worktrees/542c4415/src/stages/brainstorm-auto.js +285 -0
- package/.worktrees/542c4415/src/stages/brainstorm.js +624 -0
- package/.worktrees/542c4415/src/stages/cmd-existence.js +145 -0
- package/.worktrees/542c4415/src/stages/doctor.js +540 -0
- package/.worktrees/542c4415/src/stages/execute.js +1277 -0
- package/.worktrees/542c4415/src/stages/explore.js +43 -0
- package/.worktrees/542c4415/src/stages/index.js +29 -0
- package/.worktrees/542c4415/src/stages/knowledge.js +514 -0
- package/.worktrees/542c4415/src/stages/plan-postcheck.js +1398 -0
- package/.worktrees/542c4415/src/stages/plan.js +655 -0
- package/.worktrees/542c4415/src/stages/quick.js +167 -0
- package/.worktrees/542c4415/src/stages/scan.js +608 -0
- package/.worktrees/542c4415/src/stages/status.js +64 -0
- package/.worktrees/542c4415/src/stages/verify.js +246 -0
- package/.worktrees/542c4415/src/sync.js +1470 -0
- package/.worktrees/542c4415/src/task-review.js +1498 -0
- package/.worktrees/542c4415/src/taskcard-placeholders.js +21 -0
- package/.worktrees/542c4415/src/taskcard.js +250 -0
- package/.worktrees/542c4415/src/verify-postcheck.js +1718 -0
- package/.worktrees/542c4415/src/verify-probes.js +327 -0
- package/.worktrees/542c4415/src/version.js +19 -0
- package/.worktrees/542c4415/src/workflow.js +600 -0
- package/.worktrees/542c4415/src/workspace.js +125 -0
- package/.worktrees/542c4415/src/worktree-apply.js +1611 -0
- package/.worktrees/542c4415/src/worktree-deps.js +668 -0
- package/.worktrees/542c4415/src/worktree.js +1849 -0
- package/.worktrees/542c4415/templates/claude-instruction.md +23 -0
- package/.worktrees/542c4415/templates/prompts/taskcard-rules.md +29 -0
- package/.worktrees/542c4415/templates/prompts/testcase-design.md +12 -0
- package/.worktrees/542c4415/templates/prompts/verify-probes.md +32 -0
- package/.worktrees/542c4415/templates/workflows/archive-impact.yaml +79 -0
- package/.worktrees/542c4415/templates/workflows/scan-docs.yaml +132 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-archive/SKILL.md +87 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-auto/SKILL.md +93 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-commit/SKILL.md +67 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-continue/SKILL.md +47 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-doctor/SKILL.md +76 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-execute/SKILL.md +214 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-explore/SKILL.md +102 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-export/SKILL.md +57 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-init/SKILL.md +177 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-knowledge/SKILL.md +270 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-plan/SKILL.md +156 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-propose/SKILL.md +87 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-quick/SKILL.md +116 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-resume/SKILL.md +70 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-scan/SKILL.md +79 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-state/SKILL.md +64 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-status/SKILL.md +54 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-verify/SKILL.md +87 -0
- package/.worktrees/8d2d0392/.claude/skills/sillyspec-workspace/SKILL.md +175 -0
- package/.worktrees/8d2d0392/.claude/skills/verify-per-user/SKILL.md +6 -0
- package/.worktrees/8d2d0392/.gitattributes +2 -0
- package/.worktrees/8d2d0392/.husky/pre-push +20 -0
- package/.worktrees/8d2d0392/README.md +203 -0
- package/.worktrees/8d2d0392/SKILL.md +91 -0
- package/.worktrees/8d2d0392/architecture-analysis.md +448 -0
- package/.worktrees/8d2d0392/bin/sillyspec.js +2 -0
- package/.worktrees/8d2d0392/eval/README.md +86 -0
- package/.worktrees/8d2d0392/eval/eval.config.json +28 -0
- package/.worktrees/8d2d0392/eval/lib/adapters/cli.mjs +63 -0
- package/.worktrees/8d2d0392/eval/lib/adapters/dryrun.mjs +27 -0
- package/.worktrees/8d2d0392/eval/lib/config.mjs +82 -0
- package/.worktrees/8d2d0392/eval/lib/db.mjs +76 -0
- package/.worktrees/8d2d0392/eval/lib/report.mjs +120 -0
- package/.worktrees/8d2d0392/eval/lib/runner.mjs +157 -0
- package/.worktrees/8d2d0392/eval/lib/tasks.mjs +73 -0
- package/.worktrees/8d2d0392/eval/lib/util.mjs +107 -0
- package/.worktrees/8d2d0392/eval/lib/workdir.mjs +30 -0
- package/.worktrees/8d2d0392/eval/run.mjs +83 -0
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/files/package.json +6 -0
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/solution/src/slugify.mjs +26 -0
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/task.json +6 -0
- package/.worktrees/8d2d0392/eval/tasks/001-slugify/verify.mjs +28 -0
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/package.json +6 -0
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/src/dates.mjs +4 -0
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/solution/src/dates.mjs +30 -0
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/task.json +6 -0
- package/.worktrees/8d2d0392/eval/tasks/002-each-day/verify.mjs +31 -0
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/data/notes.txt +5 -0
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/package.json +6 -0
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/solution/bin/report.mjs +36 -0
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/task.json +6 -0
- package/.worktrees/8d2d0392/eval/tasks/003-word-report/verify.mjs +38 -0
- package/.worktrees/8d2d0392/logo.jpg +0 -0
- package/.worktrees/8d2d0392/package-lock.json +977 -0
- package/.worktrees/8d2d0392/package.json +41 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/index.html +16 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-overview.html +256 -0
- package/.worktrees/8d2d0392/packages/dashboard/package.json +25 -0
- package/.worktrees/8d2d0392/packages/dashboard/server/executor.js +95 -0
- package/.worktrees/8d2d0392/packages/dashboard/server/index.js +679 -0
- package/.worktrees/8d2d0392/packages/dashboard/server/parser.js +526 -0
- package/.worktrees/8d2d0392/packages/dashboard/server/watcher.js +357 -0
- package/.worktrees/8d2d0392/src/agent-session-log.js +803 -0
- package/.worktrees/8d2d0392/src/change-list.js +290 -0
- package/.worktrees/8d2d0392/src/change-risk-profile.js +339 -0
- package/.worktrees/8d2d0392/src/check-primitives.js +65 -0
- package/.worktrees/8d2d0392/src/classify-change.js +109 -0
- package/.worktrees/8d2d0392/src/commit-suggest.js +202 -0
- package/.worktrees/8d2d0392/src/config-cat.js +88 -0
- package/.worktrees/8d2d0392/src/config-schema.js +328 -0
- package/.worktrees/8d2d0392/src/constants.js +97 -0
- package/.worktrees/8d2d0392/src/contract-matrix.js +533 -0
- package/.worktrees/8d2d0392/src/datetime.js +20 -0
- package/.worktrees/8d2d0392/src/db-engine.js +55 -0
- package/.worktrees/8d2d0392/src/db.js +381 -0
- package/.worktrees/8d2d0392/src/decision-distill.js +517 -0
- package/.worktrees/8d2d0392/src/dispatch/backends/local-agent.js +155 -0
- package/.worktrees/8d2d0392/src/dispatch/backends/sillyhub-mcp.js +245 -0
- package/.worktrees/8d2d0392/src/dispatch/probe.js +246 -0
- package/.worktrees/8d2d0392/src/dispatch/strategy.js +121 -0
- package/.worktrees/8d2d0392/src/docs-check.js +825 -0
- package/.worktrees/8d2d0392/src/docs-debt.js +393 -0
- package/.worktrees/8d2d0392/src/docs-gate.js +107 -0
- package/.worktrees/8d2d0392/src/doctor-diagnostics.js +1099 -0
- package/.worktrees/8d2d0392/src/endpoint-extractor.js +409 -0
- package/.worktrees/8d2d0392/src/foreign-declared.js +78 -0
- package/.worktrees/8d2d0392/src/fs-atomic.js +73 -0
- package/.worktrees/8d2d0392/src/git-helper.js +150 -0
- package/.worktrees/8d2d0392/src/hooks/claude-pre-tool-use.cjs +130 -0
- package/.worktrees/8d2d0392/src/hooks/worktree-guard.js +892 -0
- package/.worktrees/8d2d0392/src/index.js +2854 -0
- package/.worktrees/8d2d0392/src/init.js +626 -0
- package/.worktrees/8d2d0392/src/knowledge-match.js +231 -0
- package/.worktrees/8d2d0392/src/local-detect.js +128 -0
- package/.worktrees/8d2d0392/src/local-register.js +104 -0
- package/.worktrees/8d2d0392/src/machine-interface.js +543 -0
- package/.worktrees/8d2d0392/src/migrate.js +127 -0
- package/.worktrees/8d2d0392/src/module-impact.js +166 -0
- package/.worktrees/8d2d0392/src/module-resolve.js +222 -0
- package/.worktrees/8d2d0392/src/modules.js +580 -0
- package/.worktrees/8d2d0392/src/plan-adopt-waves.js +126 -0
- package/.worktrees/8d2d0392/src/progress/change-registry.js +336 -0
- package/.worktrees/8d2d0392/src/progress/consistency-doctor.js +355 -0
- package/.worktrees/8d2d0392/src/progress/shared.js +36 -0
- package/.worktrees/8d2d0392/src/progress/stage-machine.js +594 -0
- package/.worktrees/8d2d0392/src/progress/step-store.js +265 -0
- package/.worktrees/8d2d0392/src/progress.js +1304 -0
- package/.worktrees/8d2d0392/src/quick-recommend.js +115 -0
- package/.worktrees/8d2d0392/src/quicklog.js +883 -0
- package/.worktrees/8d2d0392/src/review-tier.js +77 -0
- package/.worktrees/8d2d0392/src/run/command.js +1641 -0
- package/.worktrees/8d2d0392/src/run/complete-handlers.js +1552 -0
- package/.worktrees/8d2d0392/src/run/complete.js +1259 -0
- package/.worktrees/8d2d0392/src/run/concurrent-detect.js +156 -0
- package/.worktrees/8d2d0392/src/run/gates.js +1094 -0
- package/.worktrees/8d2d0392/src/run/multi-repo-context.js +208 -0
- package/.worktrees/8d2d0392/src/run/next.js +128 -0
- package/.worktrees/8d2d0392/src/run/prompt.js +843 -0
- package/.worktrees/8d2d0392/src/run/quick-audit.js +186 -0
- package/.worktrees/8d2d0392/src/run/scan-profile.js +269 -0
- package/.worktrees/8d2d0392/src/run/shared.js +1562 -0
- package/.worktrees/8d2d0392/src/run/stage.js +587 -0
- package/.worktrees/8d2d0392/src/run.js +23 -0
- package/.worktrees/8d2d0392/src/scan-diff.js +388 -0
- package/.worktrees/8d2d0392/src/scan-postcheck.js +524 -0
- package/.worktrees/8d2d0392/src/scan-staleness.js +95 -0
- package/.worktrees/8d2d0392/src/setup.js +414 -0
- package/.worktrees/8d2d0392/src/sillyhub-mcp/client.js +597 -0
- package/.worktrees/8d2d0392/src/sillyhub-mcp/config.js +62 -0
- package/.worktrees/8d2d0392/src/spec-dir-typo.js +50 -0
- package/.worktrees/8d2d0392/src/spec-sync.js +358 -0
- package/.worktrees/8d2d0392/src/stage-contract-engine.js +171 -0
- package/.worktrees/8d2d0392/src/stage-contract-spec.js +551 -0
- package/.worktrees/8d2d0392/src/stage-contract.js +948 -0
- package/.worktrees/8d2d0392/src/stage-review.js +597 -0
- package/.worktrees/8d2d0392/src/stages/archive.js +199 -0
- package/.worktrees/8d2d0392/src/stages/brainstorm-auto.js +285 -0
- package/.worktrees/8d2d0392/src/stages/brainstorm.js +624 -0
- package/.worktrees/8d2d0392/src/stages/cmd-existence.js +145 -0
- package/.worktrees/8d2d0392/src/stages/doctor.js +540 -0
- package/.worktrees/8d2d0392/src/stages/execute.js +1277 -0
- package/.worktrees/8d2d0392/src/stages/explore.js +43 -0
- package/.worktrees/8d2d0392/src/stages/index.js +29 -0
- package/.worktrees/8d2d0392/src/stages/knowledge.js +514 -0
- package/.worktrees/8d2d0392/src/stages/plan-postcheck.js +1398 -0
- package/.worktrees/8d2d0392/src/stages/plan.js +651 -0
- package/.worktrees/8d2d0392/src/stages/quick.js +167 -0
- package/.worktrees/8d2d0392/src/stages/scan.js +608 -0
- package/.worktrees/8d2d0392/src/stages/status.js +64 -0
- package/.worktrees/8d2d0392/src/stages/verify.js +246 -0
- package/.worktrees/8d2d0392/src/sync.js +1470 -0
- package/.worktrees/8d2d0392/src/task-review.js +1498 -0
- package/.worktrees/8d2d0392/src/taskcard-placeholders.js +21 -0
- package/.worktrees/8d2d0392/src/taskcard.js +217 -0
- package/.worktrees/8d2d0392/src/verify-postcheck.js +1718 -0
- package/.worktrees/8d2d0392/src/verify-probes.js +327 -0
- package/.worktrees/8d2d0392/src/version.js +19 -0
- package/.worktrees/8d2d0392/src/workflow.js +600 -0
- package/.worktrees/8d2d0392/src/workspace.js +125 -0
- package/.worktrees/8d2d0392/src/worktree-apply.js +1611 -0
- package/.worktrees/8d2d0392/src/worktree-deps.js +576 -0
- package/.worktrees/8d2d0392/src/worktree.js +1838 -0
- package/.worktrees/8d2d0392/templates/claude-instruction.md +23 -0
- package/.worktrees/8d2d0392/templates/prompts/taskcard-rules.md +29 -0
- package/.worktrees/8d2d0392/templates/prompts/testcase-design.md +12 -0
- package/.worktrees/8d2d0392/templates/prompts/verify-probes.md +32 -0
- package/.worktrees/8d2d0392/templates/workflows/archive-impact.yaml +79 -0
- package/.worktrees/8d2d0392/templates/workflows/scan-docs.yaml +132 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-archive/SKILL.md +87 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-auto/SKILL.md +93 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-commit/SKILL.md +67 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-continue/SKILL.md +47 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-doctor/SKILL.md +76 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-execute/SKILL.md +214 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-explore/SKILL.md +102 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-export/SKILL.md +57 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-init/SKILL.md +177 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-knowledge/SKILL.md +270 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-plan/SKILL.md +156 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-quick/SKILL.md +116 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-resume/SKILL.md +70 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-scan/SKILL.md +79 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-state/SKILL.md +64 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-status/SKILL.md +54 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-verify/SKILL.md +87 -0
- package/.worktrees/c1eae35e/.claude/skills/sillyspec-workspace/SKILL.md +175 -0
- package/.worktrees/c1eae35e/.gitattributes +2 -0
- package/.worktrees/c1eae35e/.husky/pre-push +20 -0
- package/.worktrees/c1eae35e/README.md +203 -0
- package/.worktrees/c1eae35e/SKILL.md +91 -0
- package/.worktrees/c1eae35e/architecture-analysis.md +448 -0
- package/.worktrees/c1eae35e/bin/sillyspec.js +2 -0
- package/.worktrees/c1eae35e/eval/README.md +86 -0
- package/.worktrees/c1eae35e/eval/eval.config.json +28 -0
- package/.worktrees/c1eae35e/eval/lib/adapters/cli.mjs +63 -0
- package/.worktrees/c1eae35e/eval/lib/adapters/dryrun.mjs +27 -0
- package/.worktrees/c1eae35e/eval/lib/config.mjs +82 -0
- package/.worktrees/c1eae35e/eval/lib/db.mjs +76 -0
- package/.worktrees/c1eae35e/eval/lib/report.mjs +120 -0
- package/.worktrees/c1eae35e/eval/lib/runner.mjs +157 -0
- package/.worktrees/c1eae35e/eval/lib/tasks.mjs +73 -0
- package/.worktrees/c1eae35e/eval/lib/util.mjs +107 -0
- package/.worktrees/c1eae35e/eval/lib/workdir.mjs +30 -0
- package/.worktrees/c1eae35e/eval/run.mjs +83 -0
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/files/package.json +6 -0
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/solution/src/slugify.mjs +26 -0
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/task.json +6 -0
- package/.worktrees/c1eae35e/eval/tasks/001-slugify/verify.mjs +28 -0
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/package.json +6 -0
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/src/dates.mjs +4 -0
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/solution/src/dates.mjs +30 -0
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/task.json +6 -0
- package/.worktrees/c1eae35e/eval/tasks/002-each-day/verify.mjs +31 -0
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/data/notes.txt +5 -0
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/package.json +6 -0
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/solution/bin/report.mjs +36 -0
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/task.json +6 -0
- package/.worktrees/c1eae35e/eval/tasks/003-word-report/verify.mjs +38 -0
- package/.worktrees/c1eae35e/logo.jpg +0 -0
- package/.worktrees/c1eae35e/package-lock.json +977 -0
- package/.worktrees/c1eae35e/package.json +41 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/index.html +16 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-overview.html +256 -0
- package/.worktrees/c1eae35e/packages/dashboard/package.json +25 -0
- package/.worktrees/c1eae35e/packages/dashboard/server/executor.js +95 -0
- package/.worktrees/c1eae35e/packages/dashboard/server/index.js +679 -0
- package/.worktrees/c1eae35e/packages/dashboard/server/parser.js +526 -0
- package/.worktrees/c1eae35e/packages/dashboard/server/watcher.js +357 -0
- package/.worktrees/c1eae35e/src/agent-session-log.js +803 -0
- package/.worktrees/c1eae35e/src/change-list.js +290 -0
- package/.worktrees/c1eae35e/src/change-risk-profile.js +339 -0
- package/.worktrees/c1eae35e/src/check-primitives.js +65 -0
- package/.worktrees/c1eae35e/src/classify-change.js +109 -0
- package/.worktrees/c1eae35e/src/commit-suggest.js +202 -0
- package/.worktrees/c1eae35e/src/config-cat.js +88 -0
- package/.worktrees/c1eae35e/src/config-schema.js +328 -0
- package/.worktrees/c1eae35e/src/constants.js +97 -0
- package/.worktrees/c1eae35e/src/contract-matrix.js +533 -0
- package/.worktrees/c1eae35e/src/datetime.js +20 -0
- package/.worktrees/c1eae35e/src/db-engine.js +55 -0
- package/.worktrees/c1eae35e/src/db.js +381 -0
- package/.worktrees/c1eae35e/src/decision-distill.js +517 -0
- package/.worktrees/c1eae35e/src/dispatch/backends/local-agent.js +155 -0
- package/.worktrees/c1eae35e/src/dispatch/backends/sillyhub-mcp.js +245 -0
- package/.worktrees/c1eae35e/src/dispatch/probe.js +246 -0
- package/.worktrees/c1eae35e/src/dispatch/strategy.js +121 -0
- package/.worktrees/c1eae35e/src/docs-check.js +825 -0
- package/.worktrees/c1eae35e/src/docs-debt.js +393 -0
- package/.worktrees/c1eae35e/src/docs-gate.js +107 -0
- package/.worktrees/c1eae35e/src/doctor-diagnostics.js +1099 -0
- package/.worktrees/c1eae35e/src/endpoint-extractor.js +409 -0
- package/.worktrees/c1eae35e/src/foreign-declared.js +155 -0
- package/.worktrees/c1eae35e/src/fs-atomic.js +73 -0
- package/.worktrees/c1eae35e/src/git-helper.js +150 -0
- package/.worktrees/c1eae35e/src/hooks/claude-pre-tool-use.cjs +130 -0
- package/.worktrees/c1eae35e/src/hooks/worktree-guard.js +892 -0
- package/.worktrees/c1eae35e/src/index.js +2854 -0
- package/.worktrees/c1eae35e/src/init.js +626 -0
- package/.worktrees/c1eae35e/src/knowledge-match.js +231 -0
- package/.worktrees/c1eae35e/src/local-detect.js +128 -0
- package/.worktrees/c1eae35e/src/local-register.js +104 -0
- package/.worktrees/c1eae35e/src/machine-interface.js +543 -0
- package/.worktrees/c1eae35e/src/migrate.js +127 -0
- package/.worktrees/c1eae35e/src/module-impact.js +166 -0
- package/.worktrees/c1eae35e/src/module-resolve.js +222 -0
- package/.worktrees/c1eae35e/src/modules.js +580 -0
- package/.worktrees/c1eae35e/src/plan-adopt-waves.js +126 -0
- package/.worktrees/c1eae35e/src/progress/change-registry.js +336 -0
- package/.worktrees/c1eae35e/src/progress/consistency-doctor.js +355 -0
- package/.worktrees/c1eae35e/src/progress/shared.js +36 -0
- package/.worktrees/c1eae35e/src/progress/stage-machine.js +594 -0
- package/.worktrees/c1eae35e/src/progress/step-store.js +265 -0
- package/.worktrees/c1eae35e/src/progress.js +1304 -0
- package/.worktrees/c1eae35e/src/quick-recommend.js +115 -0
- package/.worktrees/c1eae35e/src/quicklog.js +883 -0
- package/.worktrees/c1eae35e/src/review-tier.js +77 -0
- package/.worktrees/c1eae35e/src/run/command.js +1641 -0
- package/.worktrees/c1eae35e/src/run/complete-handlers.js +1552 -0
- package/.worktrees/c1eae35e/src/run/complete.js +1259 -0
- package/.worktrees/c1eae35e/src/run/concurrent-detect.js +156 -0
- package/.worktrees/c1eae35e/src/run/gates.js +1111 -0
- package/.worktrees/c1eae35e/src/run/multi-repo-context.js +208 -0
- package/.worktrees/c1eae35e/src/run/next.js +128 -0
- package/.worktrees/c1eae35e/src/run/prompt.js +843 -0
- package/.worktrees/c1eae35e/src/run/quick-audit.js +186 -0
- package/.worktrees/c1eae35e/src/run/scan-profile.js +269 -0
- package/.worktrees/c1eae35e/src/run/shared.js +1562 -0
- package/.worktrees/c1eae35e/src/run/stage.js +587 -0
- package/.worktrees/c1eae35e/src/run.js +23 -0
- package/.worktrees/c1eae35e/src/scan-diff.js +388 -0
- package/.worktrees/c1eae35e/src/scan-postcheck.js +524 -0
- package/.worktrees/c1eae35e/src/scan-staleness.js +95 -0
- package/.worktrees/c1eae35e/src/setup.js +414 -0
- package/.worktrees/c1eae35e/src/sillyhub-mcp/client.js +597 -0
- package/.worktrees/c1eae35e/src/sillyhub-mcp/config.js +62 -0
- package/.worktrees/c1eae35e/src/spec-dir-typo.js +50 -0
- package/.worktrees/c1eae35e/src/spec-sync.js +358 -0
- package/.worktrees/c1eae35e/src/stage-contract-engine.js +171 -0
- package/.worktrees/c1eae35e/src/stage-contract-spec.js +551 -0
- package/.worktrees/c1eae35e/src/stage-contract.js +948 -0
- package/.worktrees/c1eae35e/src/stage-review.js +597 -0
- package/.worktrees/c1eae35e/src/stages/archive.js +199 -0
- package/.worktrees/c1eae35e/src/stages/brainstorm-auto.js +285 -0
- package/.worktrees/c1eae35e/src/stages/brainstorm.js +624 -0
- package/.worktrees/c1eae35e/src/stages/cmd-existence.js +145 -0
- package/.worktrees/c1eae35e/src/stages/doctor.js +540 -0
- package/.worktrees/c1eae35e/src/stages/execute.js +1277 -0
- package/.worktrees/c1eae35e/src/stages/explore.js +43 -0
- package/.worktrees/c1eae35e/src/stages/index.js +29 -0
- package/.worktrees/c1eae35e/src/stages/knowledge.js +514 -0
- package/.worktrees/c1eae35e/src/stages/plan-postcheck.js +1398 -0
- package/.worktrees/c1eae35e/src/stages/plan.js +655 -0
- package/.worktrees/c1eae35e/src/stages/quick.js +167 -0
- package/.worktrees/c1eae35e/src/stages/scan.js +608 -0
- package/.worktrees/c1eae35e/src/stages/status.js +64 -0
- package/.worktrees/c1eae35e/src/stages/verify.js +246 -0
- package/.worktrees/c1eae35e/src/sync.js +1470 -0
- package/.worktrees/c1eae35e/src/task-review.js +1498 -0
- package/.worktrees/c1eae35e/src/taskcard-placeholders.js +21 -0
- package/.worktrees/c1eae35e/src/taskcard.js +250 -0
- package/.worktrees/c1eae35e/src/verify-postcheck.js +1718 -0
- package/.worktrees/c1eae35e/src/verify-probes.js +327 -0
- package/.worktrees/c1eae35e/src/version.js +19 -0
- package/.worktrees/c1eae35e/src/workflow.js +600 -0
- package/.worktrees/c1eae35e/src/workspace.js +125 -0
- package/.worktrees/c1eae35e/src/worktree-apply.js +1611 -0
- package/.worktrees/c1eae35e/src/worktree-deps.js +668 -0
- package/.worktrees/c1eae35e/src/worktree.js +1849 -0
- package/.worktrees/c1eae35e/templates/claude-instruction.md +23 -0
- package/.worktrees/c1eae35e/templates/prompts/taskcard-rules.md +29 -0
- package/.worktrees/c1eae35e/templates/prompts/testcase-design.md +12 -0
- package/.worktrees/c1eae35e/templates/prompts/verify-probes.md +32 -0
- package/.worktrees/c1eae35e/templates/workflows/archive-impact.yaml +79 -0
- package/.worktrees/c1eae35e/templates/workflows/scan-docs.yaml +132 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-archive/SKILL.md +87 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-auto/SKILL.md +93 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-commit/SKILL.md +67 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-continue/SKILL.md +47 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-doctor/SKILL.md +76 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-execute/SKILL.md +214 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-explore/SKILL.md +102 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-export/SKILL.md +57 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-init/SKILL.md +177 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-knowledge/SKILL.md +270 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-plan/SKILL.md +156 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-propose/SKILL.md +87 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-quick/SKILL.md +116 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-resume/SKILL.md +70 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-scan/SKILL.md +79 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-state/SKILL.md +64 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-status/SKILL.md +54 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-verify/SKILL.md +87 -0
- package/.worktrees/dafc71ad/.claude/skills/sillyspec-workspace/SKILL.md +175 -0
- package/.worktrees/dafc71ad/.gitattributes +2 -0
- package/.worktrees/dafc71ad/.husky/pre-push +20 -0
- package/.worktrees/dafc71ad/README.md +203 -0
- package/.worktrees/dafc71ad/SKILL.md +91 -0
- package/.worktrees/dafc71ad/analysis.md +366 -0
- package/.worktrees/dafc71ad/architecture-analysis.md +448 -0
- package/.worktrees/dafc71ad/bin/sillyspec.js +2 -0
- package/.worktrees/dafc71ad/eval/README.md +86 -0
- package/.worktrees/dafc71ad/eval/eval.config.json +28 -0
- package/.worktrees/dafc71ad/eval/lib/adapters/cli.mjs +63 -0
- package/.worktrees/dafc71ad/eval/lib/adapters/dryrun.mjs +27 -0
- package/.worktrees/dafc71ad/eval/lib/config.mjs +82 -0
- package/.worktrees/dafc71ad/eval/lib/db.mjs +76 -0
- package/.worktrees/dafc71ad/eval/lib/report.mjs +120 -0
- package/.worktrees/dafc71ad/eval/lib/runner.mjs +157 -0
- package/.worktrees/dafc71ad/eval/lib/tasks.mjs +73 -0
- package/.worktrees/dafc71ad/eval/lib/util.mjs +107 -0
- package/.worktrees/dafc71ad/eval/lib/workdir.mjs +30 -0
- package/.worktrees/dafc71ad/eval/run.mjs +83 -0
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/files/package.json +6 -0
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/solution/src/slugify.mjs +26 -0
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/task.json +6 -0
- package/.worktrees/dafc71ad/eval/tasks/001-slugify/verify.mjs +28 -0
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/package.json +6 -0
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/src/dates.mjs +4 -0
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/solution/src/dates.mjs +30 -0
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/task.json +6 -0
- package/.worktrees/dafc71ad/eval/tasks/002-each-day/verify.mjs +31 -0
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/data/notes.txt +5 -0
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/package.json +6 -0
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/solution/bin/report.mjs +36 -0
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/task.json +6 -0
- package/.worktrees/dafc71ad/eval/tasks/003-word-report/verify.mjs +38 -0
- package/.worktrees/dafc71ad/logo.jpg +0 -0
- package/.worktrees/dafc71ad/package-lock.json +977 -0
- package/.worktrees/dafc71ad/package.json +41 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/index.html +16 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-overview.html +256 -0
- package/.worktrees/dafc71ad/packages/dashboard/package.json +25 -0
- package/.worktrees/dafc71ad/packages/dashboard/server/executor.js +95 -0
- package/.worktrees/dafc71ad/packages/dashboard/server/index.js +679 -0
- package/.worktrees/dafc71ad/packages/dashboard/server/parser.js +526 -0
- package/.worktrees/dafc71ad/packages/dashboard/server/watcher.js +357 -0
- package/.worktrees/dafc71ad/src/agent-session-log.js +803 -0
- package/.worktrees/dafc71ad/src/change-list.js +290 -0
- package/.worktrees/dafc71ad/src/change-risk-profile.js +339 -0
- package/.worktrees/dafc71ad/src/check-primitives.js +65 -0
- package/.worktrees/dafc71ad/src/classify-change.js +109 -0
- package/.worktrees/dafc71ad/src/commit-suggest.js +202 -0
- package/.worktrees/dafc71ad/src/config-cat.js +88 -0
- package/.worktrees/dafc71ad/src/config-schema.js +328 -0
- package/.worktrees/dafc71ad/src/constants.js +97 -0
- package/.worktrees/dafc71ad/src/contract-matrix.js +533 -0
- package/.worktrees/dafc71ad/src/datetime.js +20 -0
- package/.worktrees/dafc71ad/src/db-engine.js +55 -0
- package/.worktrees/dafc71ad/src/db.js +381 -0
- package/.worktrees/dafc71ad/src/decision-distill.js +517 -0
- package/.worktrees/dafc71ad/src/dispatch/backends/local-agent.js +155 -0
- package/.worktrees/dafc71ad/src/dispatch/backends/sillyhub-mcp.js +245 -0
- package/.worktrees/dafc71ad/src/dispatch/probe.js +246 -0
- package/.worktrees/dafc71ad/src/dispatch/strategy.js +121 -0
- package/.worktrees/dafc71ad/src/docs-check.js +825 -0
- package/.worktrees/dafc71ad/src/docs-debt.js +393 -0
- package/.worktrees/dafc71ad/src/docs-gate.js +107 -0
- package/.worktrees/dafc71ad/src/doctor-diagnostics.js +1099 -0
- package/.worktrees/dafc71ad/src/endpoint-extractor.js +409 -0
- package/.worktrees/dafc71ad/src/foreign-declared.js +155 -0
- package/.worktrees/dafc71ad/src/fs-atomic.js +73 -0
- package/.worktrees/dafc71ad/src/git-helper.js +150 -0
- package/.worktrees/dafc71ad/src/hooks/claude-pre-tool-use.cjs +130 -0
- package/.worktrees/dafc71ad/src/hooks/worktree-guard.js +892 -0
- package/.worktrees/dafc71ad/src/index.js +2854 -0
- package/.worktrees/dafc71ad/src/init.js +626 -0
- package/.worktrees/dafc71ad/src/knowledge-match.js +231 -0
- package/.worktrees/dafc71ad/src/local-detect.js +128 -0
- package/.worktrees/dafc71ad/src/local-register.js +104 -0
- package/.worktrees/dafc71ad/src/machine-interface.js +543 -0
- package/.worktrees/dafc71ad/src/migrate.js +127 -0
- package/.worktrees/dafc71ad/src/module-impact.js +166 -0
- package/.worktrees/dafc71ad/src/module-resolve.js +222 -0
- package/.worktrees/dafc71ad/src/modules.js +580 -0
- package/.worktrees/dafc71ad/src/plan-adopt-waves.js +126 -0
- package/.worktrees/dafc71ad/src/progress/change-registry.js +336 -0
- package/.worktrees/dafc71ad/src/progress/consistency-doctor.js +355 -0
- package/.worktrees/dafc71ad/src/progress/shared.js +36 -0
- package/.worktrees/dafc71ad/src/progress/stage-machine.js +594 -0
- package/.worktrees/dafc71ad/src/progress/step-store.js +265 -0
- package/.worktrees/dafc71ad/src/progress.js +1304 -0
- package/.worktrees/dafc71ad/src/quick-recommend.js +115 -0
- package/.worktrees/dafc71ad/src/quicklog.js +883 -0
- package/.worktrees/dafc71ad/src/review-tier.js +77 -0
- package/.worktrees/dafc71ad/src/run/command.js +1641 -0
- package/.worktrees/dafc71ad/src/run/complete-handlers.js +1552 -0
- package/.worktrees/dafc71ad/src/run/complete.js +1259 -0
- package/.worktrees/dafc71ad/src/run/concurrent-detect.js +156 -0
- package/.worktrees/dafc71ad/src/run/gates.js +1111 -0
- package/.worktrees/dafc71ad/src/run/multi-repo-context.js +208 -0
- package/.worktrees/dafc71ad/src/run/next.js +128 -0
- package/.worktrees/dafc71ad/src/run/prompt.js +843 -0
- package/.worktrees/dafc71ad/src/run/quick-audit.js +186 -0
- package/.worktrees/dafc71ad/src/run/scan-profile.js +269 -0
- package/.worktrees/dafc71ad/src/run/shared.js +1562 -0
- package/.worktrees/dafc71ad/src/run/stage.js +587 -0
- package/.worktrees/dafc71ad/src/run.js +23 -0
- package/.worktrees/dafc71ad/src/scan-diff.js +388 -0
- package/.worktrees/dafc71ad/src/scan-postcheck.js +524 -0
- package/.worktrees/dafc71ad/src/scan-staleness.js +95 -0
- package/.worktrees/dafc71ad/src/setup.js +414 -0
- package/.worktrees/dafc71ad/src/sillyhub-mcp/client.js +597 -0
- package/.worktrees/dafc71ad/src/sillyhub-mcp/config.js +62 -0
- package/.worktrees/dafc71ad/src/spec-dir-typo.js +50 -0
- package/.worktrees/dafc71ad/src/spec-sync.js +358 -0
- package/.worktrees/dafc71ad/src/stage-contract-engine.js +171 -0
- package/.worktrees/dafc71ad/src/stage-contract-spec.js +551 -0
- package/.worktrees/dafc71ad/src/stage-contract.js +948 -0
- package/.worktrees/dafc71ad/src/stage-review.js +597 -0
- package/.worktrees/dafc71ad/src/stages/archive.js +199 -0
- package/.worktrees/dafc71ad/src/stages/brainstorm-auto.js +285 -0
- package/.worktrees/dafc71ad/src/stages/brainstorm.js +624 -0
- package/.worktrees/dafc71ad/src/stages/cmd-existence.js +145 -0
- package/.worktrees/dafc71ad/src/stages/doctor.js +540 -0
- package/.worktrees/dafc71ad/src/stages/execute.js +1277 -0
- package/.worktrees/dafc71ad/src/stages/explore.js +43 -0
- package/.worktrees/dafc71ad/src/stages/index.js +29 -0
- package/.worktrees/dafc71ad/src/stages/knowledge.js +514 -0
- package/.worktrees/dafc71ad/src/stages/plan-postcheck.js +1398 -0
- package/.worktrees/dafc71ad/src/stages/plan.js +655 -0
- package/.worktrees/dafc71ad/src/stages/quick.js +167 -0
- package/.worktrees/dafc71ad/src/stages/scan.js +608 -0
- package/.worktrees/dafc71ad/src/stages/status.js +64 -0
- package/.worktrees/dafc71ad/src/stages/verify.js +246 -0
- package/.worktrees/dafc71ad/src/sync.js +1470 -0
- package/.worktrees/dafc71ad/src/task-review.js +1498 -0
- package/.worktrees/dafc71ad/src/taskcard-placeholders.js +21 -0
- package/.worktrees/dafc71ad/src/taskcard.js +250 -0
- package/.worktrees/dafc71ad/src/verify-postcheck.js +1718 -0
- package/.worktrees/dafc71ad/src/verify-probes.js +327 -0
- package/.worktrees/dafc71ad/src/version.js +19 -0
- package/.worktrees/dafc71ad/src/workflow.js +600 -0
- package/.worktrees/dafc71ad/src/workspace.js +125 -0
- package/.worktrees/dafc71ad/src/worktree-apply.js +1611 -0
- package/.worktrees/dafc71ad/src/worktree-deps.js +668 -0
- package/.worktrees/dafc71ad/src/worktree.js +1849 -0
- package/.worktrees/dafc71ad/templates/claude-instruction.md +23 -0
- package/.worktrees/dafc71ad/templates/prompts/taskcard-rules.md +29 -0
- package/.worktrees/dafc71ad/templates/prompts/testcase-design.md +12 -0
- package/.worktrees/dafc71ad/templates/prompts/verify-probes.md +32 -0
- package/.worktrees/dafc71ad/templates/workflows/archive-impact.yaml +79 -0
- package/.worktrees/dafc71ad/templates/workflows/scan-docs.yaml +132 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-archive/SKILL.md +87 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-auto/SKILL.md +93 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-commit/SKILL.md +67 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-continue/SKILL.md +47 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-doctor/SKILL.md +76 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-execute/SKILL.md +214 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-explore/SKILL.md +102 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-export/SKILL.md +57 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-init/SKILL.md +177 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-knowledge/SKILL.md +270 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-plan/SKILL.md +156 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-propose/SKILL.md +87 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-quick/SKILL.md +116 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-resume/SKILL.md +70 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-scan/SKILL.md +79 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-state/SKILL.md +64 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-status/SKILL.md +54 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-verify/SKILL.md +87 -0
- package/.worktrees/e58fcc4c/.claude/skills/sillyspec-workspace/SKILL.md +175 -0
- package/.worktrees/e58fcc4c/.gitattributes +2 -0
- package/.worktrees/e58fcc4c/.husky/pre-push +20 -0
- package/.worktrees/e58fcc4c/README.md +203 -0
- package/.worktrees/e58fcc4c/SKILL.md +91 -0
- package/.worktrees/e58fcc4c/architecture-analysis.md +503 -0
- package/.worktrees/e58fcc4c/bin/sillyspec.js +2 -0
- package/.worktrees/e58fcc4c/eval/README.md +86 -0
- package/.worktrees/e58fcc4c/eval/eval.config.json +28 -0
- package/.worktrees/e58fcc4c/eval/lib/adapters/cli.mjs +63 -0
- package/.worktrees/e58fcc4c/eval/lib/adapters/dryrun.mjs +27 -0
- package/.worktrees/e58fcc4c/eval/lib/config.mjs +82 -0
- package/.worktrees/e58fcc4c/eval/lib/db.mjs +76 -0
- package/.worktrees/e58fcc4c/eval/lib/report.mjs +120 -0
- package/.worktrees/e58fcc4c/eval/lib/runner.mjs +157 -0
- package/.worktrees/e58fcc4c/eval/lib/tasks.mjs +73 -0
- package/.worktrees/e58fcc4c/eval/lib/util.mjs +107 -0
- package/.worktrees/e58fcc4c/eval/lib/workdir.mjs +30 -0
- package/.worktrees/e58fcc4c/eval/run.mjs +83 -0
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/files/package.json +6 -0
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/solution/src/slugify.mjs +26 -0
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/task.json +6 -0
- package/.worktrees/e58fcc4c/eval/tasks/001-slugify/verify.mjs +28 -0
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/package.json +6 -0
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/src/dates.mjs +4 -0
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/solution/src/dates.mjs +30 -0
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/task.json +6 -0
- package/.worktrees/e58fcc4c/eval/tasks/002-each-day/verify.mjs +31 -0
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/data/notes.txt +5 -0
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/package.json +6 -0
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/solution/bin/report.mjs +36 -0
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/task.json +6 -0
- package/.worktrees/e58fcc4c/eval/tasks/003-word-report/verify.mjs +38 -0
- package/.worktrees/e58fcc4c/logo.jpg +0 -0
- package/.worktrees/e58fcc4c/package-lock.json +977 -0
- package/.worktrees/e58fcc4c/package.json +41 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/favicon.jpg +0 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/index.html +16 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/logo.jpg +0 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-overview.html +256 -0
- package/.worktrees/e58fcc4c/packages/dashboard/package.json +25 -0
- package/.worktrees/e58fcc4c/packages/dashboard/server/executor.js +95 -0
- package/.worktrees/e58fcc4c/packages/dashboard/server/index.js +679 -0
- package/.worktrees/e58fcc4c/packages/dashboard/server/parser.js +526 -0
- package/.worktrees/e58fcc4c/packages/dashboard/server/watcher.js +357 -0
- package/.worktrees/e58fcc4c/src/agent-session-log.js +803 -0
- package/.worktrees/e58fcc4c/src/change-list.js +290 -0
- package/.worktrees/e58fcc4c/src/change-risk-profile.js +339 -0
- package/.worktrees/e58fcc4c/src/check-primitives.js +65 -0
- package/.worktrees/e58fcc4c/src/classify-change.js +109 -0
- package/.worktrees/e58fcc4c/src/commit-suggest.js +202 -0
- package/.worktrees/e58fcc4c/src/config-cat.js +88 -0
- package/.worktrees/e58fcc4c/src/config-schema.js +328 -0
- package/.worktrees/e58fcc4c/src/constants.js +97 -0
- package/.worktrees/e58fcc4c/src/contract-matrix.js +533 -0
- package/.worktrees/e58fcc4c/src/datetime.js +20 -0
- package/.worktrees/e58fcc4c/src/db-engine.js +55 -0
- package/.worktrees/e58fcc4c/src/db.js +381 -0
- package/.worktrees/e58fcc4c/src/decision-distill.js +517 -0
- package/.worktrees/e58fcc4c/src/dispatch/backends/local-agent.js +155 -0
- package/.worktrees/e58fcc4c/src/dispatch/backends/sillyhub-mcp.js +245 -0
- package/.worktrees/e58fcc4c/src/dispatch/probe.js +246 -0
- package/.worktrees/e58fcc4c/src/dispatch/strategy.js +121 -0
- package/.worktrees/e58fcc4c/src/docs-check.js +825 -0
- package/.worktrees/e58fcc4c/src/docs-debt.js +393 -0
- package/.worktrees/e58fcc4c/src/docs-gate.js +107 -0
- package/.worktrees/e58fcc4c/src/doctor-diagnostics.js +1099 -0
- package/.worktrees/e58fcc4c/src/endpoint-extractor.js +409 -0
- package/.worktrees/e58fcc4c/src/foreign-declared.js +155 -0
- package/.worktrees/e58fcc4c/src/fs-atomic.js +73 -0
- package/.worktrees/e58fcc4c/src/git-helper.js +150 -0
- package/.worktrees/e58fcc4c/src/hooks/claude-pre-tool-use.cjs +130 -0
- package/.worktrees/e58fcc4c/src/hooks/worktree-guard.js +892 -0
- package/.worktrees/e58fcc4c/src/index.js +2854 -0
- package/.worktrees/e58fcc4c/src/init.js +626 -0
- package/.worktrees/e58fcc4c/src/knowledge-match.js +231 -0
- package/.worktrees/e58fcc4c/src/local-detect.js +128 -0
- package/.worktrees/e58fcc4c/src/local-register.js +104 -0
- package/.worktrees/e58fcc4c/src/machine-interface.js +543 -0
- package/.worktrees/e58fcc4c/src/migrate.js +127 -0
- package/.worktrees/e58fcc4c/src/module-impact.js +166 -0
- package/.worktrees/e58fcc4c/src/module-resolve.js +222 -0
- package/.worktrees/e58fcc4c/src/modules.js +580 -0
- package/.worktrees/e58fcc4c/src/plan-adopt-waves.js +126 -0
- package/.worktrees/e58fcc4c/src/progress/change-registry.js +336 -0
- package/.worktrees/e58fcc4c/src/progress/consistency-doctor.js +355 -0
- package/.worktrees/e58fcc4c/src/progress/shared.js +36 -0
- package/.worktrees/e58fcc4c/src/progress/stage-machine.js +594 -0
- package/.worktrees/e58fcc4c/src/progress/step-store.js +265 -0
- package/.worktrees/e58fcc4c/src/progress.js +1304 -0
- package/.worktrees/e58fcc4c/src/quick-recommend.js +115 -0
- package/.worktrees/e58fcc4c/src/quicklog.js +883 -0
- package/.worktrees/e58fcc4c/src/review-tier.js +77 -0
- package/.worktrees/e58fcc4c/src/run/command.js +1641 -0
- package/.worktrees/e58fcc4c/src/run/complete-handlers.js +1552 -0
- package/.worktrees/e58fcc4c/src/run/complete.js +1259 -0
- package/.worktrees/e58fcc4c/src/run/concurrent-detect.js +156 -0
- package/.worktrees/e58fcc4c/src/run/gates.js +1111 -0
- package/.worktrees/e58fcc4c/src/run/multi-repo-context.js +208 -0
- package/.worktrees/e58fcc4c/src/run/next.js +128 -0
- package/.worktrees/e58fcc4c/src/run/prompt.js +843 -0
- package/.worktrees/e58fcc4c/src/run/quick-audit.js +186 -0
- package/.worktrees/e58fcc4c/src/run/scan-profile.js +269 -0
- package/.worktrees/e58fcc4c/src/run/shared.js +1562 -0
- package/.worktrees/e58fcc4c/src/run/stage.js +587 -0
- package/.worktrees/e58fcc4c/src/run.js +23 -0
- package/.worktrees/e58fcc4c/src/scan-diff.js +388 -0
- package/.worktrees/e58fcc4c/src/scan-postcheck.js +524 -0
- package/.worktrees/e58fcc4c/src/scan-staleness.js +95 -0
- package/.worktrees/e58fcc4c/src/setup.js +414 -0
- package/.worktrees/e58fcc4c/src/sillyhub-mcp/client.js +597 -0
- package/.worktrees/e58fcc4c/src/sillyhub-mcp/config.js +62 -0
- package/.worktrees/e58fcc4c/src/spec-dir-typo.js +50 -0
- package/.worktrees/e58fcc4c/src/spec-sync.js +358 -0
- package/.worktrees/e58fcc4c/src/stage-contract-engine.js +171 -0
- package/.worktrees/e58fcc4c/src/stage-contract-spec.js +551 -0
- package/.worktrees/e58fcc4c/src/stage-contract.js +948 -0
- package/.worktrees/e58fcc4c/src/stage-review.js +597 -0
- package/.worktrees/e58fcc4c/src/stages/archive.js +199 -0
- package/.worktrees/e58fcc4c/src/stages/brainstorm-auto.js +285 -0
- package/.worktrees/e58fcc4c/src/stages/brainstorm.js +624 -0
- package/.worktrees/e58fcc4c/src/stages/cmd-existence.js +145 -0
- package/.worktrees/e58fcc4c/src/stages/doctor.js +540 -0
- package/.worktrees/e58fcc4c/src/stages/execute.js +1277 -0
- package/.worktrees/e58fcc4c/src/stages/explore.js +43 -0
- package/.worktrees/e58fcc4c/src/stages/index.js +29 -0
- package/.worktrees/e58fcc4c/src/stages/knowledge.js +514 -0
- package/.worktrees/e58fcc4c/src/stages/plan-postcheck.js +1398 -0
- package/.worktrees/e58fcc4c/src/stages/plan.js +655 -0
- package/.worktrees/e58fcc4c/src/stages/quick.js +167 -0
- package/.worktrees/e58fcc4c/src/stages/scan.js +608 -0
- package/.worktrees/e58fcc4c/src/stages/status.js +64 -0
- package/.worktrees/e58fcc4c/src/stages/verify.js +246 -0
- package/.worktrees/e58fcc4c/src/sync.js +1470 -0
- package/.worktrees/e58fcc4c/src/task-review.js +1498 -0
- package/.worktrees/e58fcc4c/src/taskcard-placeholders.js +21 -0
- package/.worktrees/e58fcc4c/src/taskcard.js +250 -0
- package/.worktrees/e58fcc4c/src/verify-postcheck.js +1718 -0
- package/.worktrees/e58fcc4c/src/verify-probes.js +327 -0
- package/.worktrees/e58fcc4c/src/version.js +19 -0
- package/.worktrees/e58fcc4c/src/workflow.js +600 -0
- package/.worktrees/e58fcc4c/src/workspace.js +125 -0
- package/.worktrees/e58fcc4c/src/worktree-apply.js +1611 -0
- package/.worktrees/e58fcc4c/src/worktree-deps.js +668 -0
- package/.worktrees/e58fcc4c/src/worktree.js +1849 -0
- package/.worktrees/e58fcc4c/templates/claude-instruction.md +23 -0
- package/.worktrees/e58fcc4c/templates/prompts/taskcard-rules.md +29 -0
- package/.worktrees/e58fcc4c/templates/prompts/testcase-design.md +12 -0
- package/.worktrees/e58fcc4c/templates/prompts/verify-probes.md +32 -0
- package/.worktrees/e58fcc4c/templates/workflows/archive-impact.yaml +79 -0
- package/.worktrees/e58fcc4c/templates/workflows/scan-docs.yaml +132 -0
- package/architecture-analysis.md +448 -0
- package/package.json +1 -1
- package/src/contract-matrix.js +7 -4
- package/src/endpoint-extractor.js +41 -52
- package/src/foreign-declared.js +88 -5
- package/src/fs-atomic.js +20 -3
- package/src/hooks/worktree-guard.js +9 -3
- package/src/index.js +36 -19
- package/src/module-impact.js +1 -1
- package/src/modules.js +23 -21
- package/src/progress/stage-machine.js +23 -0
- package/src/progress.js +38 -2
- package/src/quicklog.js +7 -5
- package/src/run/command.js +7 -6
- package/src/run/complete-handlers.js +6 -2
- package/src/run/complete.js +33 -20
- package/src/run/gates.js +31 -4
- package/src/run/next.js +4 -3
- package/src/run/prompt.js +66 -6
- package/src/run/scan-profile.js +1 -0
- package/src/run/shared.js +11 -5
- package/src/run/stage.js +15 -12
- package/src/scan-diff.js +4 -2
- package/src/stage-contract-spec.js +1 -1
- package/src/stage-contract.js +16 -8
- package/src/stages/brainstorm-auto.js +43 -1
- package/src/stages/brainstorm.js +24 -8
- package/src/stages/execute.js +36 -9
- package/src/stages/knowledge.js +18 -5
- package/src/stages/plan-postcheck.js +63 -7
- package/src/stages/plan.js +13 -6
- package/src/stages/verify.js +1 -1
- package/src/sync.js +27 -11
- package/src/task-review.js +5 -3
- package/src/taskcard.js +35 -0
- package/src/verify-postcheck.js +24 -13
- package/src/verify-probes.js +39 -13
- package/src/worktree-apply.js +481 -292
- package/src/worktree-deps.js +93 -1
- package/src/worktree.js +91 -21
- package/templates/prompts/taskcard-rules.md +1 -1
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worktree-deps.js — Worktree 依赖供给引擎
|
|
3
|
+
*
|
|
4
|
+
* 在 worktree.create() 的 baseline overlay 之后调用,让 worktree 立即可构建/测试。
|
|
5
|
+
* 策略:junction/symlink 快路径(lockfile 一致)+ install 兜底;多语言按 local.yaml
|
|
6
|
+
* project.type + lockfile 推断 install 命令。供给可失败,但状态写进 meta 供验证硬门读取。
|
|
7
|
+
*
|
|
8
|
+
* 见 change 2026-06-28-worktree-deps-provision / D-005@v1, D-007@v1。
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, readFileSync, realpathSync, lstatSync, readdirSync } from 'fs';
|
|
12
|
+
import { join, isAbsolute, relative, resolve as resolvePath, sep as pathSep } from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import { execFileSync } from 'child_process';
|
|
15
|
+
import { createHash } from 'crypto';
|
|
16
|
+
|
|
17
|
+
const LOCKFILES = ['pnpm-lock.yaml', 'package-lock.json', 'yarn.lock'];
|
|
18
|
+
const DEFAULT_TIMEOUT_MS = 300 * 1000;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 取目录下首个命中的 lockfile 的 sha256 前 16 位;
|
|
22
|
+
* 无 lockfile 则 hash package.json;都没有返回 null。
|
|
23
|
+
*/
|
|
24
|
+
export function lockfileHash(dir) {
|
|
25
|
+
if (!dir || !existsSync(dir)) return null;
|
|
26
|
+
for (const lf of LOCKFILES) {
|
|
27
|
+
const p = join(dir, lf);
|
|
28
|
+
if (existsSync(p)) {
|
|
29
|
+
return createHash('sha256').update(readFileSync(p)).digest('hex').slice(0, 16);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const pkg = join(dir, 'package.json');
|
|
33
|
+
if (existsSync(pkg)) {
|
|
34
|
+
return createHash('sha256').update(readFileSync(pkg)).digest('hex').slice(0, 16);
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** 命中目录下的 lockfile 文件名(用于判断 nodejs 子类)*/
|
|
40
|
+
function detectLockfile(dir) {
|
|
41
|
+
if (!dir || !existsSync(dir)) return null;
|
|
42
|
+
for (const lf of LOCKFILES) {
|
|
43
|
+
if (existsSync(join(dir, lf))) return lf;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 读取 local.yaml 文本(specBase 优先,回退 worktreePath/.sillyspec;不读 process.cwd 避免环境配置泄漏)。
|
|
50
|
+
* 返回 { text, source }——source 标记信任级(体检 SEC-01):
|
|
51
|
+
* - 'specBase':主仓配置,可信(其 commands.install 允许执行,仍过白名单+元字符门)
|
|
52
|
+
* - 'worktree':worktree 内副本,agent/子代理可写区——只作 project.type / modules 等
|
|
53
|
+
* 只读探测,其 commands.install 永不执行(否则绕过 worktree-guard 的危险命令拦截)
|
|
54
|
+
*/
|
|
55
|
+
function readLocalYamlSourced(specBase, worktreePath) {
|
|
56
|
+
if (specBase) {
|
|
57
|
+
const p = join(specBase, 'local.yaml');
|
|
58
|
+
if (existsSync(p)) return { text: readFileSync(p, 'utf8'), source: 'specBase' };
|
|
59
|
+
}
|
|
60
|
+
if (worktreePath) {
|
|
61
|
+
const p = join(worktreePath, '.sillyspec', 'local.yaml');
|
|
62
|
+
if (existsSync(p)) return { text: readFileSync(p, 'utf8'), source: 'worktree' };
|
|
63
|
+
}
|
|
64
|
+
return { text: null, source: null };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** 兼容旧签名:只要文本 */
|
|
68
|
+
function readLocalYaml(specBase, worktreePath) {
|
|
69
|
+
return readLocalYamlSourced(specBase, worktreePath).text;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** 从 local.yaml 文本提取 commands.install(轻量正则,不引 yaml 依赖,与 scan-postcheck 一致)*/
|
|
73
|
+
function extractUserInstall(yamlText) {
|
|
74
|
+
if (!yamlText) return null;
|
|
75
|
+
// 匹配 commands: 段下的 install: "..." 或 install: '...'(unavailable 视为无)
|
|
76
|
+
const m = yamlText.match(/install:\s*["']([^"']+)["']/);
|
|
77
|
+
if (m && m[1] && m[1].toLowerCase() !== 'unavailable') return m[1];
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** 从 local.yaml 提取 project.type;缺失时按文件特征推断 */
|
|
82
|
+
export function detectProjectType(worktreePath, specBase) {
|
|
83
|
+
const yamlText = readLocalYaml(specBase, worktreePath);
|
|
84
|
+
if (yamlText) {
|
|
85
|
+
const m = yamlText.match(/type:\s*(\S+)/);
|
|
86
|
+
if (m && m[1]) return m[1];
|
|
87
|
+
}
|
|
88
|
+
if (existsSync(join(worktreePath, 'pom.xml'))) return 'maven';
|
|
89
|
+
if (existsSync(join(worktreePath, 'build.gradle')) || existsSync(join(worktreePath, 'build.gradle.kts'))) return 'gradle';
|
|
90
|
+
if (existsSync(join(worktreePath, 'package.json'))) return 'nodejs';
|
|
91
|
+
// Python:pyproject.toml(uv/poetry/pdm)或 requirements.txt(pip)——治 worktree 内 ruff/pre-commit 等
|
|
92
|
+
// 二进制不供给(exec 复盘 3-②:detectProjectType 原无 python 分支,python 项目根被误判 generic → n/a)
|
|
93
|
+
if (existsSync(join(worktreePath, 'pyproject.toml')) || existsSync(join(worktreePath, 'requirements.txt'))) return 'python';
|
|
94
|
+
return 'generic';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** 按 project.type + lockfile 推断 install 命令(无 commands.install 时)*/
|
|
98
|
+
export function inferInstallCommand(projectType, worktreePath, userInstall) {
|
|
99
|
+
if (userInstall) return userInstall;
|
|
100
|
+
switch (projectType) {
|
|
101
|
+
case 'nodejs':
|
|
102
|
+
if (existsSync(join(worktreePath, 'pnpm-lock.yaml'))) return 'pnpm install --frozen-lockfile';
|
|
103
|
+
if (existsSync(join(worktreePath, 'package-lock.json'))) return 'npm ci';
|
|
104
|
+
if (existsSync(join(worktreePath, 'yarn.lock'))) return 'yarn install --frozen-lockfile';
|
|
105
|
+
return 'npm install'; // 无 lockfile 兜底(X-2)
|
|
106
|
+
case 'maven':
|
|
107
|
+
return 'mvn -o test';
|
|
108
|
+
case 'gradle':
|
|
109
|
+
// win32 cmd.exe 跑不了 ./gradlew(体检 BUG-08 同型):优先 gradlew.bat,否则全局 gradle
|
|
110
|
+
if (process.platform === 'win32') {
|
|
111
|
+
return existsSync(join(worktreePath, 'gradlew.bat')) ? 'gradlew.bat test' : 'gradle test';
|
|
112
|
+
}
|
|
113
|
+
return './gradlew test';
|
|
114
|
+
case 'python':
|
|
115
|
+
// uv 优先(现代 Python 工具链,pyproject.toml/uv.lock 项目走 uv sync 建 .venv + 装依赖,
|
|
116
|
+
// 与 execute worktree 环境预告一致);纯 requirements.txt(无 pyproject)回退 pip
|
|
117
|
+
if (existsSync(join(worktreePath, 'uv.lock')) || existsSync(join(worktreePath, 'pyproject.toml'))) return 'uv sync';
|
|
118
|
+
return 'pip install -r requirements.txt';
|
|
119
|
+
default:
|
|
120
|
+
return null; // generic → n/a
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** 在 worktreePath 创建 node_modules 链接到 mainNodeModules;失败回退 */
|
|
125
|
+
function tryLink(mainNodeModules, linkPath) {
|
|
126
|
+
// 已存在:确认是否已指向 main(幂等)
|
|
127
|
+
if (existsSync(linkPath)) {
|
|
128
|
+
try {
|
|
129
|
+
const resolved = realpathSync(linkPath);
|
|
130
|
+
const resolvedTarget = realpathSync(mainNodeModules);
|
|
131
|
+
if (resolved === resolvedTarget) return { ok: true, method: process.platform === 'win32' ? 'junction' : 'symlink' };
|
|
132
|
+
} catch {}
|
|
133
|
+
// 真实目录 ≠ 已有依赖(坑 provision-preexisting-dir-fake-linked,2026-08-23 实证:doctor --fix
|
|
134
|
+
// 报 re-provisioned 但链接没建——worktree node_modules 是 install 半途中断残留的真实目录时,
|
|
135
|
+
// realpath 不等 main → 被 preexisting 短路标 ok,根快路径据此写 depsStatus=linked,一个链接
|
|
136
|
+
// 都没建且后验证 existsSync 对空/残目录照样过)。真实目录 → ok:false + preexistingDir 标记,
|
|
137
|
+
// 交调用方决策:根快路径降级 tryInstall 真重建(宁可重装不说谎);linkOneDir 视为本地安装
|
|
138
|
+
// 保留(installed 语义,合法状态)。指向别处的 link 仍是「他者安装」,尊重不 clobber。
|
|
139
|
+
try {
|
|
140
|
+
if (!lstatSync(linkPath).isSymbolicLink()) {
|
|
141
|
+
return { ok: false, preexistingDir: true, error: `node_modules 已存在且为真实目录(非链接,疑似 install 残留): ${linkPath}` };
|
|
142
|
+
}
|
|
143
|
+
} catch {}
|
|
144
|
+
// 指向别处 → 不 clobber,视为已有依赖(installed 语义)
|
|
145
|
+
return { ok: true, method: 'install', preexisting: true };
|
|
146
|
+
}
|
|
147
|
+
// broken junction 清理(existsSync 对目标丢失的 junction/symlink 返回 false,但目录项占位会使
|
|
148
|
+
// mklink/ln 撞名失败 → 根:落 install 慢路径;子模块:linkOneDir failed。此坑在 _doctorReprovision
|
|
149
|
+
// 的解链段同样存在——它也用 existsSync 前置判断,broken junction 永远解不掉):lstat 是 link 而
|
|
150
|
+
// existsSync false → 删目录项后重建(rmdir 删 junction 不跟随 reparse,与 worktree.js 解链同款)。
|
|
151
|
+
try {
|
|
152
|
+
if (lstatSync(linkPath).isSymbolicLink()) {
|
|
153
|
+
if (process.platform === 'win32') {
|
|
154
|
+
execFileSync('cmd.exe', ['/c', 'rmdir', linkPath], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
155
|
+
} else {
|
|
156
|
+
unlinkSync(linkPath);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} catch { /* lstat 抛 = 目录项真不存在,直接建 */ }
|
|
160
|
+
try {
|
|
161
|
+
if (process.platform === 'win32') {
|
|
162
|
+
// execFileSync 数组形式不经 shell:POSIX 双引号内 `/$() 会执行、cmd.exe 双引号内 %VAR% 仍展开,
|
|
163
|
+
// linkPath 含 local.yaml 模块 path,属项目内可配置值(安全收敛,与 git-helper 同范式)
|
|
164
|
+
execFileSync('cmd.exe', ['/c', 'mklink', '/J', linkPath, mainNodeModules], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
165
|
+
} else {
|
|
166
|
+
execFileSync('ln', ['-s', mainNodeModules, linkPath], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
167
|
+
}
|
|
168
|
+
// 创建后实物复核(坑 provision-silent-fake-installed 第②层,2026-08-21 实证:doctor 报
|
|
169
|
+
// re-provisioned 成功但 junction 实际没建)——mklink/ln 退出码 0 不等于链接落盘(cmd.exe
|
|
170
|
+
// 垫片链存在静默失败面),lstat+existsSync 复核不存在即判失败,交由调用方走 install 兜底
|
|
171
|
+
//(junction(reparse point)与 symlink 的 lstat 均报 isSymbolicLink=true)
|
|
172
|
+
try {
|
|
173
|
+
const st = lstatSync(linkPath);
|
|
174
|
+
if (!st.isSymbolicLink() || !existsSync(linkPath)) {
|
|
175
|
+
return { ok: false, error: 'link 创建后复核失败:lstat 非 link 或路径不可达' };
|
|
176
|
+
}
|
|
177
|
+
} catch (e) {
|
|
178
|
+
return { ok: false, error: `link 创建后复核失败(lstat ${e.message})` };
|
|
179
|
+
}
|
|
180
|
+
return { ok: true, method: process.platform === 'win32' ? 'junction' : 'symlink' };
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return { ok: false, error: e.message };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 执行 install 命令(带超时)。
|
|
188
|
+
*
|
|
189
|
+
* 安全收口(体检 SEC-01):commands.install 来自 local.yaml 配置,若经 execSync(shell)
|
|
190
|
+
* 原样执行,yaml 里的 `$(...)`/反引号/`;` 必然被解释——且 worktree 副本属 agent 可写区。
|
|
191
|
+
* 三道门:
|
|
192
|
+
* 1. 调用方保证来源可信(provisionDeps 只对 source==='specBase' 的 userInstall 走到这里)
|
|
193
|
+
* 2. 可执行前缀白名单(包管理器家族)
|
|
194
|
+
* 3. shell 元字符黑名单(win32 额外拦 %,cmd.exe 会展开 %VAR%),通过后拆 argv 数组执行不经 shell
|
|
195
|
+
*
|
|
196
|
+
* 链式命令支持(坑 worktree-install-whitelist-monorepo-chain,2026-08-20 实证):monorepo 的
|
|
197
|
+
* commands.install 常为链式写法(`cd web && pnpm install` / `npm install && npm run build:pkg`),
|
|
198
|
+
* 旧实现整条过白名单 + 元字符门,`&&` 必拒 → depsStatus=failed → execute deps 门控卡死且无自愈
|
|
199
|
+
* 路径(改 local.yaml 成单命令对需要 post-install build 的 monorepo 不可行)。现按 `&&` 拆段
|
|
200
|
+
* 逐段校验执行:每段独立过白名单 + 元字符门(拆分后残余的单 `&`/`|`/`;` 仍被元字符门拦),
|
|
201
|
+
* 段内允许 `cd <相对子路径>`(resolve 后必须仍在 worktree 根内,防越界建产物/读外部),
|
|
202
|
+
* 全程 argv 数组执行不经 shell、任一段失败即停(&& 语义)。安全面不变:每个执行段仍是
|
|
203
|
+
* 白名单包管理器命令,`||`/管道/`;`/后台均不支持。
|
|
204
|
+
*/
|
|
205
|
+
const INSTALL_BINARY_WHITELIST = /^(?:\.\/)?(?:pnpm|npm|yarn|bun|mvn|gradle|gradlew|uv|pip|pip3|python|python3|poetry|make)(?:\.cmd|\.bat|\.exe)?(?:\s|$)/;
|
|
206
|
+
const SHELL_METACHARS = /[;&|<>$`\n]/;
|
|
207
|
+
const WIN_SHELL_METACHARS = /[;&|<>$`\n%]/;
|
|
208
|
+
const CD_SEGMENT_RE = /^cd\s+([^\s]+)$/;
|
|
209
|
+
|
|
210
|
+
function tryInstall(cmd, cwd, timeout) {
|
|
211
|
+
const trimmed = String(cmd || '').trim();
|
|
212
|
+
if (!trimmed) {
|
|
213
|
+
return { ok: false, error: 'install 命令为空' };
|
|
214
|
+
}
|
|
215
|
+
const metaRe = process.platform === 'win32' ? WIN_SHELL_METACHARS : SHELL_METACHARS;
|
|
216
|
+
// && 拆段(单段命令与原路径完全一致,零回归);空段(`a &&`/`&& b`)视为畸形命令拒绝
|
|
217
|
+
const segments = trimmed.split('&&').map(s => s.trim());
|
|
218
|
+
if (segments.some(s => s === '')) {
|
|
219
|
+
return { ok: false, error: `install 链式命令含空段,拒绝执行: ${trimmed}` };
|
|
220
|
+
}
|
|
221
|
+
let curCwd = cwd;
|
|
222
|
+
const root = resolvePath(cwd);
|
|
223
|
+
const planned = [];
|
|
224
|
+
for (const seg of segments) {
|
|
225
|
+
// 白名单先于元字符(保持原判定顺序):`curl … | sh` 报非白名单而非元字符,
|
|
226
|
+
// `npm install; rm …` 过白名单后被元字符门拦——两类拒绝语义与原实现一致
|
|
227
|
+
const cd = seg.match(CD_SEGMENT_RE);
|
|
228
|
+
if (!cd && !INSTALL_BINARY_WHITELIST.test(seg)) {
|
|
229
|
+
return { ok: false, error: `install 命令不在包管理器白名单内,拒绝执行: ${seg}(支持 && 链式与 cd <子目录> 段,各执行段仍须为白名单包管理器命令)` };
|
|
230
|
+
}
|
|
231
|
+
if (metaRe.test(seg)) {
|
|
232
|
+
return { ok: false, error: `install 命令段含 shell 元字符,拒绝执行: ${seg}(链式仅支持 &&;|| / 管道 / ; / 后台不支持)` };
|
|
233
|
+
}
|
|
234
|
+
if (cd) {
|
|
235
|
+
const target = resolvePath(curCwd, cd[1]);
|
|
236
|
+
if (target !== root && !target.startsWith(root + pathSep)) {
|
|
237
|
+
return { ok: false, error: `install 命令的 cd 段越出 worktree 根,拒绝执行: ${seg}(cwd ${cwd})` };
|
|
238
|
+
}
|
|
239
|
+
curCwd = target;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
planned.push(seg);
|
|
243
|
+
}
|
|
244
|
+
for (const seg of planned) {
|
|
245
|
+
const argv = seg.split(/\s+/);
|
|
246
|
+
try {
|
|
247
|
+
if (process.platform === 'win32') {
|
|
248
|
+
// Windows 包管理器是 .cmd 垫片,无 shell 的 spawn 无法解析——经 cmd.exe /c 传参;
|
|
249
|
+
// 元字符(含 %)已拦,残余风险与 tryLink 的 mklink 同款
|
|
250
|
+
execFileSync('cmd.exe', ['/c', ...argv], { cwd: curCwd, timeout, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
251
|
+
} else {
|
|
252
|
+
execFileSync(argv[0], argv.slice(1), { cwd: curCwd, timeout, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
253
|
+
}
|
|
254
|
+
} catch (e) {
|
|
255
|
+
const msg = e.killed ? `timeout after ${timeout}ms` : ((e.stderr && e.stderr.toString()) || e.message);
|
|
256
|
+
return { ok: false, error: `${seg} failed (cwd ${curCwd}): ${msg}` };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { ok: true };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** 目录是否含 nodejs 标记(package.json 或任一 lockfile)——识别 monorepo 里的 nodejs 子模块 */
|
|
263
|
+
function hasNodeMarker(dir) {
|
|
264
|
+
if (!dir || !existsSync(dir)) return false;
|
|
265
|
+
if (existsSync(join(dir, 'package.json'))) return true;
|
|
266
|
+
return LOCKFILES.some(lf => existsSync(join(dir, lf)));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 从 local.yaml 提取 modules 块的 path 列表(generic monorepo 子模块路径)。
|
|
271
|
+
* 兼容 inline flow(`frontend: { path: "frontend/" }`)与 block(`frontend:\n path: frontend/`)。
|
|
272
|
+
* 轻量正则,不引 yaml 依赖(与 extractUserInstall / scan-postcheck 风格一致)。
|
|
273
|
+
* 坑 execute-worktree-pnpm-monorepo-no-node-modules:generic 项目 worktree 子模块无 node_modules。
|
|
274
|
+
* @returns {string[]} 去重 + 去 trailing 斜杠的相对路径
|
|
275
|
+
*/
|
|
276
|
+
function extractModulePaths(yamlText) {
|
|
277
|
+
if (!yamlText) return [];
|
|
278
|
+
const idx = yamlText.search(/^modules:\s*$/m);
|
|
279
|
+
if (idx < 0) return [];
|
|
280
|
+
const nlIdx = yamlText.indexOf('\n', idx);
|
|
281
|
+
if (nlIdx < 0) return [];
|
|
282
|
+
let rest = yamlText.slice(nlIdx + 1);
|
|
283
|
+
const nextTop = rest.search(/^\S/m); // 下一个顶层 key(行首非空白)
|
|
284
|
+
const block = nextTop >= 0 ? rest.slice(0, nextTop) : rest;
|
|
285
|
+
const paths = [];
|
|
286
|
+
const re = /path:\s*["']?([^"'\s,}]+)/g;
|
|
287
|
+
let pm;
|
|
288
|
+
while ((pm = re.exec(block)) !== null) {
|
|
289
|
+
const p = pm[1].replace(/\/+$/, '').trim();
|
|
290
|
+
if (p && p !== '.') paths.push(p);
|
|
291
|
+
}
|
|
292
|
+
return [...new Set(paths)];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* modules 块 path 安全校验(体检 SEC-07):只允许 worktree 内的相对子路径——
|
|
297
|
+
* 拒绝绝对路径与 `..` 段,防止 local.yaml 配置把 junction/symlink 建到 worktree 之外。
|
|
298
|
+
*/
|
|
299
|
+
function isSafeModulePath(p) {
|
|
300
|
+
if (!p || isAbsolute(p)) return false;
|
|
301
|
+
const segs = p.split(/[\\/]+/);
|
|
302
|
+
return !segs.includes('..');
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* 对单个子模块目录 tryLink main 的 node_modules → wt 的 node_modules(modules 子模块专用)。
|
|
307
|
+
* 仅走 link 快路径(不 install——子模块 install 慢且易失败;lockfile 不一致时交给用户 pnpm install)。
|
|
308
|
+
* lockfile 一致才 link,避免误链不匹配的 deps。
|
|
309
|
+
*/
|
|
310
|
+
function linkOneDir(wtDir, mainDir) {
|
|
311
|
+
const mainNodeModules = join(mainDir, 'node_modules');
|
|
312
|
+
if (!existsSync(mainNodeModules)) return { status: 'skipped', reason: 'main 无 node_modules' };
|
|
313
|
+
const wtHash = lockfileHash(wtDir);
|
|
314
|
+
const mainHash = lockfileHash(mainDir);
|
|
315
|
+
if (wtHash && mainHash && wtHash !== mainHash) {
|
|
316
|
+
return { status: 'mismatch', reason: `lockfile 不一致 main=${mainHash} wt=${wtHash}` };
|
|
317
|
+
}
|
|
318
|
+
const r = tryLink(mainNodeModules, join(wtDir, 'node_modules'));
|
|
319
|
+
if (r.ok) return { status: 'linked', method: r.method };
|
|
320
|
+
// 真实目录 = 子模块本地安装过(合法状态,如 mismatch 后用户手动 pnpm install):保留为
|
|
321
|
+
// installed 真话,不假 linked 也不误报 failed(tryLink 的 preexistingDir 细分见其注释)
|
|
322
|
+
if (r.preexistingDir) return { status: 'installed', reason: '子模块 node_modules 为真实目录(本地安装),保留' };
|
|
323
|
+
return { status: 'failed', error: r.error };
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* 供给依赖。返回 deps 状态对象(合并进 meta)。两段:
|
|
328
|
+
* 1. 根目录供给(原有逻辑:lockfile 一致 link / 不一致 install / generic→根 n/a)
|
|
329
|
+
* 2. modules 块的 nodejs 子模块 link(generic monorepo:根无 deps 但 frontend/daemon 等子模块需要)
|
|
330
|
+
* generic + 子模块 link 成功时,整体 depsStatus 从 n/a 升级为 linked(deps gate 不再误判 unknown 阻断)。
|
|
331
|
+
*
|
|
332
|
+
* @param {string} worktreePath - worktree 根目录
|
|
333
|
+
* @param {string} mainCwd - 主 checkout 根目录(node_modules 来源)
|
|
334
|
+
* @param {{ specBase?: string, timeout?: number, force?: boolean }} opts
|
|
335
|
+
* - force=true(doctor --fix 强制重装):绕过根目录 lockfile 一致快路径(下方 line 216 区块),
|
|
336
|
+
* 强制走 install 分支重装。该快路径是 tryLink 的唯一根调用点,绕过它即同时绕过 tryLink
|
|
337
|
+
* 的 preexisting 幂等短路(101-110),实现"强制重装"语义。配合调用方先解 junction
|
|
338
|
+
* (worktree.js _doctorReprovision),避免 install 经 junction 误改主仓 node_modules。
|
|
339
|
+
* modules 子模块 link 不受 force 影响(仅根 install)。
|
|
340
|
+
* @returns {{ depsStatus, depsMethod, depsSource, depsLockHash, depsCheckedAt, depsError?, depsModules? }}
|
|
341
|
+
*/
|
|
342
|
+
export function provisionDeps(worktreePath, mainCwd, opts = {}) {
|
|
343
|
+
const { specBase = null, timeout = DEFAULT_TIMEOUT_MS, force = false } = opts;
|
|
344
|
+
const depsCheckedAt = new Date().toISOString();
|
|
345
|
+
const { text: yamlText, source: yamlSource } = readLocalYamlSourced(specBase, worktreePath);
|
|
346
|
+
const wtHash = lockfileHash(worktreePath);
|
|
347
|
+
|
|
348
|
+
// ── 1. 根目录供给 ──
|
|
349
|
+
const projectType = detectProjectType(worktreePath, specBase);
|
|
350
|
+
// SEC-01:commands.install 只信主仓 specBase 的 local.yaml——worktree 副本是 agent 可写区,
|
|
351
|
+
// 其 install 命令若执行等于绕过 worktree-guard 的危险命令拦截
|
|
352
|
+
const userInstall = yamlSource === 'specBase' ? extractUserInstall(yamlText) : null;
|
|
353
|
+
if (yamlSource === 'worktree' && extractUserInstall(yamlText)) {
|
|
354
|
+
console.warn('⚠️ worktree 内 local.yaml 的 commands.install 被忽略(agent 可写区,只信主仓 .sillyspec/local.yaml)');
|
|
355
|
+
}
|
|
356
|
+
const installCmd = inferInstallCommand(projectType, worktreePath, userInstall);
|
|
357
|
+
|
|
358
|
+
let result;
|
|
359
|
+
if (!installCmd) {
|
|
360
|
+
// generic / 无可执行 install → 根无 deps 动作(n/a);但下方 modules 子模块仍可能 link 升级
|
|
361
|
+
result = { depsStatus: 'n/a', depsMethod: null, depsSource: null, depsLockHash: wtHash };
|
|
362
|
+
} else {
|
|
363
|
+
// 快路径:main 有 node_modules 且 lockfile hash 一致 → junction/symlink
|
|
364
|
+
// force=true 时绕过(doctor --fix 强制重装;绕过此块即同时绕过 tryLink 101-110 幂等短路)
|
|
365
|
+
const mainNodeModules = mainCwd ? join(mainCwd, 'node_modules') : null;
|
|
366
|
+
const mainHash = lockfileHash(mainCwd);
|
|
367
|
+
let linked = false;
|
|
368
|
+
if (!force && mainNodeModules && existsSync(mainNodeModules) && mainHash && wtHash && mainHash === wtHash) {
|
|
369
|
+
const linkResult = tryLink(mainNodeModules, join(worktreePath, 'node_modules'));
|
|
370
|
+
if (linkResult.ok) {
|
|
371
|
+
result = {
|
|
372
|
+
depsStatus: 'linked',
|
|
373
|
+
depsMethod: linkResult.method,
|
|
374
|
+
depsSource: linkResult.preexisting ? 'install' : 'main-checkout',
|
|
375
|
+
depsLockHash: wtHash,
|
|
376
|
+
};
|
|
377
|
+
linked = true;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (!linked) {
|
|
381
|
+
// 兜底:install
|
|
382
|
+
const installResult = tryInstall(installCmd, worktreePath, timeout);
|
|
383
|
+
result = installResult.ok
|
|
384
|
+
? { depsStatus: 'installed', depsMethod: 'install', depsSource: 'install', depsLockHash: wtHash }
|
|
385
|
+
: { depsStatus: 'failed', depsMethod: null, depsSource: null, depsLockHash: wtHash, depsError: installResult.error };
|
|
386
|
+
}
|
|
387
|
+
// ── 结果后验证(坑 provision-silent-fake-installed,2026-08-21 Windows 实证;
|
|
388
|
+
// 坑 provision-monorepo-subpackage-fake-installed,2026-08-22 复发:pnpm monorepo
|
|
389
|
+
// workspace 根 package.json 的 dependencies 常为空(依赖在 frontend/daemon 子包),
|
|
390
|
+
// 只查根会把 installed 状态整体跳过——doctor 标 installed 但子包 node_modules 全缺,
|
|
391
|
+
// Wave 1 测试才挂)。分层校验:
|
|
392
|
+
// linked:根 junction 实存硬校验(link 声称成功必留痕);
|
|
393
|
+
// installed:校验目标集 = 根 + local.yaml modules 块声明的含 package.json 子模块,
|
|
394
|
+
// 其中【声明了依赖】的目录逐一要求 node_modules 存在(pnpm/npm/yarn workspace
|
|
395
|
+
// 安装都会给子包建 node_modules;无依赖声明的空壳目录合法地不建,不校验)。
|
|
396
|
+
// python/.venv、jvm 本地仓库本就不适用(整体仅 nodejs)。
|
|
397
|
+
if (projectType === 'nodejs') {
|
|
398
|
+
const pkgHasDeps = (dir) => {
|
|
399
|
+
try {
|
|
400
|
+
const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'))
|
|
401
|
+
return ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']
|
|
402
|
+
.some(k => pkg[k] && Object.keys(pkg[k]).length > 0)
|
|
403
|
+
} catch { return false }
|
|
404
|
+
}
|
|
405
|
+
// 目标集:根 + modules 块内含 package.json 的安全子模块(monorepo 子包)
|
|
406
|
+
const verifyDirs = [worktreePath]
|
|
407
|
+
for (const mp of extractModulePaths(yamlText)) {
|
|
408
|
+
if (!isSafeModulePath(mp)) continue
|
|
409
|
+
const sub = join(worktreePath, mp)
|
|
410
|
+
if (existsSync(join(sub, 'package.json'))) verifyDirs.push(sub)
|
|
411
|
+
}
|
|
412
|
+
const depsDeclaredDirs = verifyDirs.filter(pkgHasDeps)
|
|
413
|
+
const needVerify = result.depsStatus === 'linked'
|
|
414
|
+
|| (result.depsStatus === 'installed' && depsDeclaredDirs.length > 0)
|
|
415
|
+
if (needVerify) {
|
|
416
|
+
// linked 只验根(junction 语义);installed 验全部声明依赖的目标目录
|
|
417
|
+
const targets = result.depsStatus === 'linked' ? [worktreePath] : depsDeclaredDirs
|
|
418
|
+
const missing = targets.filter(dir => !existsSync(join(dir, 'node_modules')))
|
|
419
|
+
if (missing.length > 0) {
|
|
420
|
+
const missingRel = missing.map(dir => relative(worktreePath, dir) || '(根)')
|
|
421
|
+
result = {
|
|
422
|
+
depsStatus: 'failed', depsMethod: null, depsSource: null, depsLockHash: wtHash,
|
|
423
|
+
depsError: `${result.depsStatus} 后验证失败:${missingRel.join('、')} 的 node_modules 不存在(报成功但实际未落盘——Windows 静默失败面:cmd.exe 垫片解析/杀毒拦截/frozen-lockfile 快退)。` +
|
|
424
|
+
`手动兜底:进 worktree 手动跑 ${installCmd}(子包随 workspace 一起装),或对 lockfile 一致的目录用 junction:New-Item -ItemType Junction -Path "<目标>/node_modules" -Target "<主仓对应目录>/node_modules",然后重试 doctor --fix`,
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
result.depsCheckedAt = depsCheckedAt;
|
|
431
|
+
|
|
432
|
+
// ── 2. modules 块的 nodejs 子模块 link(坑 execute-worktree-pnpm-monorepo-no-node-modules)──
|
|
433
|
+
// generic monorepo(如 multi-agent-platform)worktree 子模块 frontend/sillyhub-daemon 无 node_modules,
|
|
434
|
+
// 跑 pnpm test 失败。读 local.yaml modules 块,对 nodejs 子模块 tryLink main 的 node_modules。
|
|
435
|
+
const modulePaths = extractModulePaths(yamlText);
|
|
436
|
+
const moduleResults = [];
|
|
437
|
+
for (const mp of modulePaths) {
|
|
438
|
+
if (!isSafeModulePath(mp)) {
|
|
439
|
+
moduleResults.push({ path: mp, status: 'skipped', reason: 'path 越界(绝对路径或 .. 段),拒绝 link' });
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
const wtDir = join(worktreePath, mp);
|
|
443
|
+
const mainDir = mainCwd ? join(mainCwd, mp) : null;
|
|
444
|
+
if (!existsSync(wtDir) || !mainDir || !hasNodeMarker(wtDir)) continue;
|
|
445
|
+
moduleResults.push({ path: mp, ...linkOneDir(wtDir, mainDir) });
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (moduleResults.length > 0) {
|
|
449
|
+
result.depsModules = moduleResults;
|
|
450
|
+
const linkedModules = moduleResults.filter(m => m.status === 'linked');
|
|
451
|
+
if (linkedModules.length > 0 && result.depsStatus === 'n/a') {
|
|
452
|
+
// 标 generic 但子模块 link 成功 → 升级为 linked(deps gate 不再误判 unknown 阻断 execute)
|
|
453
|
+
result.depsStatus = 'linked';
|
|
454
|
+
result.depsMethod = linkedModules[0].method;
|
|
455
|
+
result.depsSource = 'main-checkout';
|
|
456
|
+
}
|
|
457
|
+
// 子模块 link 后验证(坑 modules-submodule-link-verify,2026-08-23 实证:Windows 下漏链
|
|
458
|
+
// frontend node_modules——linkOneDir 报 linked 但 junction 实际未建或 main 侧本就没有)。
|
|
459
|
+
// linked 状态的子模块逐一核验 wt/<mp>/node_modules 实存:缺失降 failed 并给兜底指引
|
|
460
|
+
//(不静默放行——跑测试时才发现就晚了)。
|
|
461
|
+
for (const m of moduleResults) {
|
|
462
|
+
if (m.status !== 'linked') continue
|
|
463
|
+
const nmPath = join(worktreePath, m.path, 'node_modules')
|
|
464
|
+
if (!existsSync(nmPath)) {
|
|
465
|
+
m.status = 'failed'
|
|
466
|
+
m.error = `linked 后验证失败:${m.path}/node_modules 不存在(报成功但实际未落盘)。兜底:New-Item -ItemType Junction -Path "<wt>/${m.path}/node_modules" -Target "<主仓>/${m.path}/node_modules"`
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
const failedModules = moduleResults.filter(m => m.status === 'failed');
|
|
470
|
+
if (failedModules.length > 0) {
|
|
471
|
+
const fmsg = failedModules.map(m => `${m.path}: ${m.error}`).join('; ');
|
|
472
|
+
result.depsError = result.depsError ? `${result.depsError}; ${fmsg}` : fmsg;
|
|
473
|
+
}
|
|
474
|
+
// mismatch 可见性(坑 modules-mismatch-invisible,2026-08-23 实证:mismatch/skipped 只写
|
|
475
|
+
// depsModules 而 src 内零消费——doctor 报 re-provisioned 成功、子模块实际无链接且无任何
|
|
476
|
+
// 提示)。mismatch(worktree 与主仓 lockfile 不一致,link 不适用)摘要进 depsError:可见、
|
|
477
|
+
// 落 meta、doctor msg 带出(_doctorReprovision 不再抹);但不降级 depsStatus——mismatch 是
|
|
478
|
+
// 配置分叉态不是供给失败,降级会经 deps gate 卡死 execute(正确动作是用户在 worktree 跑
|
|
479
|
+
// pnpm install 或对齐 lockfile, doctor --fix 的 force 重装路径也会覆盖此场景)。
|
|
480
|
+
const mismatchModules = moduleResults.filter(m => m.status === 'mismatch');
|
|
481
|
+
if (mismatchModules.length > 0) {
|
|
482
|
+
const mmsg = `子模块 lockfile 与主仓不一致(未链接,本地 install 或对齐 lockfile): ${mismatchModules.map(m => m.path).join('、')}`;
|
|
483
|
+
result.depsError = result.depsError ? `${result.depsError}; ${mmsg}` : mmsg;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return result;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* 统一的 worktree deps 新鲜度判定(H1,change 2026-08-05-tooling-feedback-fixes)。
|
|
492
|
+
* 供 doctor(worktree.js)与 ensureDepsFreshness(run/stage.js)共用,消除两处双写漂移。
|
|
493
|
+
*
|
|
494
|
+
* 判定优先级:failed → missing → stale → main-drift → fresh
|
|
495
|
+
* - failed: meta.depsStatus==='failed'(上次供给失败,占最高优先级)
|
|
496
|
+
* - missing: depsStatus ∈ {linked, installed} 且 node_modules 不存在
|
|
497
|
+
* - stale: wtHash 与 meta.depsLockHash 不一致(worktree 自身 lockfile 在上次供给后变化)
|
|
498
|
+
* - main-drift: wtHash 与主仓 mainHash 不一致(主仓 lockfile 漂移;复用 linkOneDir 177-178 的 mismatch 判据)
|
|
499
|
+
* - fresh: 其余情况
|
|
500
|
+
*
|
|
501
|
+
* lockfileHash 返回 null(无 lockfile/package.json)时相关比较优雅降级——不报 stale / main-drift,
|
|
502
|
+
* 避免无 lockfile 项目(如纯 generic / 非 nodejs)误判漂移。
|
|
503
|
+
*
|
|
504
|
+
* @param {object} [meta] - worktree meta(读 depsStatus / depsLockHash / depsError)
|
|
505
|
+
* @param {string} wtPath - worktree 根目录
|
|
506
|
+
* @param {string} mainCwd - 主 checkout 根目录
|
|
507
|
+
* @returns {{ status: 'fresh'|'missing'|'stale'|'main-drift'|'failed', detail: string, wtHash: (string|null), mainHash: (string|null), metaLockHash: (string|null) }}
|
|
508
|
+
*/
|
|
509
|
+
export function checkDepsFreshness(meta, wtPath, mainCwd) {
|
|
510
|
+
const depsStatus = meta && meta.depsStatus ? meta.depsStatus : null;
|
|
511
|
+
const metaLockHash = meta && meta.depsLockHash ? meta.depsLockHash : null;
|
|
512
|
+
const wtHash = lockfileHash(wtPath);
|
|
513
|
+
const mainHash = lockfileHash(mainCwd);
|
|
514
|
+
|
|
515
|
+
// 1. failed 最高优先级(对齐 task-01 蓝图:failed → missing → stale → main-drift → fresh)
|
|
516
|
+
if (depsStatus === 'failed') {
|
|
517
|
+
return {
|
|
518
|
+
status: 'failed',
|
|
519
|
+
detail: '上次依赖供给失败' + (meta && meta.depsError ? ': ' + meta.depsError : ''),
|
|
520
|
+
wtHash, mainHash, metaLockHash,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// 2. missing:曾 link/install 但 node_modules 已丢失(对齐 doctor 914-915 / ensure 403)
|
|
525
|
+
const nmExists = wtPath ? existsSync(join(wtPath, 'node_modules')) : false;
|
|
526
|
+
if (['linked', 'installed'].includes(depsStatus) && !nmExists) {
|
|
527
|
+
return {
|
|
528
|
+
status: 'missing',
|
|
529
|
+
detail: `meta.depsStatus=${depsStatus} 但 node_modules 缺失`,
|
|
530
|
+
wtHash, mainHash, metaLockHash,
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// 2b. 子模块 missing(坑 modules-submodule-missing-no-selfheal):meta.depsModules 中 linked
|
|
535
|
+
// 状态的子模块逐一核验 wt/<mp>/node_modules 实存。provisionDeps 内的同款核验(坑
|
|
536
|
+
// modules-submodule-link-verify)只管供给时刻,此后 junction 被删(杀毒/手工误删/半途清理)
|
|
537
|
+
// 时本函数只查根(上方)→ 永远 fresh → doctor 不再报 → 漏链永不自愈。此处补 doctor 侧
|
|
538
|
+
// 闭环:缺失 → missing → doctor --fix 走 relinkFirst 重链(provisionDeps 非 force 路径
|
|
539
|
+
// 的 linkOneDir 对缺失目录直接重建 junction)。
|
|
540
|
+
if (Array.isArray(meta && meta.depsModules)) {
|
|
541
|
+
const missingMods = meta.depsModules.filter(m =>
|
|
542
|
+
m && m.status === 'linked' && typeof m.path === 'string'
|
|
543
|
+
&& !existsSync(join(wtPath, m.path, 'node_modules')));
|
|
544
|
+
if (missingMods.length > 0) {
|
|
545
|
+
return {
|
|
546
|
+
status: 'missing',
|
|
547
|
+
detail: `${missingMods.length} 个 linked 子模块 node_modules 缺失: ${missingMods.map(m => m.path).join('、')}`,
|
|
548
|
+
wtHash, mainHash, metaLockHash,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// 3. stale:worktree 自身 lockfile 与 meta 快照不一致(对齐 doctor 916-917 / ensure 404)
|
|
554
|
+
if (metaLockHash && wtHash && wtHash !== metaLockHash) {
|
|
555
|
+
return {
|
|
556
|
+
status: 'stale',
|
|
557
|
+
detail: `lockfile 变化 (${metaLockHash} -> ${wtHash})`,
|
|
558
|
+
wtHash, mainHash, metaLockHash,
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// 4. main-drift(新增):wtHash 与主仓 mainHash 不一致——主仓 lockfile 更新过、worktree 未跟
|
|
563
|
+
if (wtHash && mainHash && wtHash !== mainHash) {
|
|
564
|
+
return {
|
|
565
|
+
status: 'main-drift',
|
|
566
|
+
detail: `worktree lockfile 与主仓不一致 (wt=${wtHash} main=${mainHash})`,
|
|
567
|
+
wtHash, mainHash, metaLockHash,
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// 5. fresh
|
|
572
|
+
return {
|
|
573
|
+
status: 'fresh',
|
|
574
|
+
detail: '依赖新鲜',
|
|
575
|
+
wtHash, mainHash, metaLockHash,
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* editable install 越界探测(坑 worktree-editable-install-escape,2026-08-25 用户实证
|
|
581
|
+
* gen:types 坑):worktree 内 Python venv 的 editable install 指向 worktree 外(典型:
|
|
582
|
+
* 主仓 checkout 路径)时,gen:types / 后端命令 / pytest 静默加载 worktree 外的旧代码——
|
|
583
|
+
* 改动不生效且无任何报错,此前靠模块文档注意事项人工记忆,本函数把它 CLI 检查化
|
|
584
|
+
* (worktree doctor 调用)。
|
|
585
|
+
*
|
|
586
|
+
* 覆盖三种 editable 痕迹:
|
|
587
|
+
* 1. 路径型 .pth(setuptools 旧式):.pth 内容行即绝对路径
|
|
588
|
+
* 2. PEP 660 __editable__.<pkg>-*.pth + __editable___<pkg>_*_finder.py(MAPPING 表绝对路径)
|
|
589
|
+
* 3. *.dist-info/direct_url.json { dir_info.editable: true, url: file:///... }
|
|
590
|
+
* 判定统一为「目标路径 resolve 后不在 worktree 内」;venv/文件读取失败按无越界处理
|
|
591
|
+
* (doctor 体检语义,不阻断)。
|
|
592
|
+
*
|
|
593
|
+
* @param {string} wtPath worktree 根目录
|
|
594
|
+
* @returns {Array<{ pkg: string, target: string, via: string }>} 越界清单(空 = 干净或无 venv)
|
|
595
|
+
*/
|
|
596
|
+
export function detectEditableInstallEscape(wtPath) {
|
|
597
|
+
const offenders = [];
|
|
598
|
+
if (!wtPath || !existsSync(wtPath)) return offenders;
|
|
599
|
+
const wtRoot = resolvePath(wtPath);
|
|
600
|
+
const isEscape = (target) => {
|
|
601
|
+
if (!target || !isAbsolute(target)) return false;
|
|
602
|
+
const rel = relative(wtRoot, resolvePath(target));
|
|
603
|
+
return rel.startsWith('..') || isAbsolute(rel);
|
|
604
|
+
};
|
|
605
|
+
const seen = new Set();
|
|
606
|
+
const push = (pkg, target, via) => {
|
|
607
|
+
const key = `${pkg}|${target}`;
|
|
608
|
+
if (seen.has(key)) return;
|
|
609
|
+
seen.add(key);
|
|
610
|
+
offenders.push({ pkg, target, via });
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
for (const venvName of ['.venv', 'venv']) {
|
|
614
|
+
const venvDir = join(wtPath, venvName);
|
|
615
|
+
if (!existsSync(venvDir)) continue;
|
|
616
|
+
// site-packages 候选:Windows Lib/site-packages + POSIX lib/python*/site-packages
|
|
617
|
+
const spCandidates = [join(venvDir, 'Lib', 'site-packages')];
|
|
618
|
+
try {
|
|
619
|
+
for (const e of readdirSync(join(venvDir, 'lib'), { withFileTypes: true })) {
|
|
620
|
+
if (e.isDirectory() && e.name.toLowerCase().startsWith('python')) {
|
|
621
|
+
spCandidates.push(join(venvDir, 'lib', e.name, 'site-packages'));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
} catch { /* 无 lib 目录(Windows 布局)跳过 */ }
|
|
625
|
+
for (const sp of spCandidates) {
|
|
626
|
+
if (!existsSync(sp)) continue;
|
|
627
|
+
let entries = [];
|
|
628
|
+
try { entries = readdirSync(sp, { withFileTypes: true }); } catch { continue; }
|
|
629
|
+
for (const e of entries) {
|
|
630
|
+
if (!e.isFile()) continue;
|
|
631
|
+
const fp = join(sp, e.name);
|
|
632
|
+
if (e.name.endsWith('.pth')) {
|
|
633
|
+
let lines = [];
|
|
634
|
+
try { lines = readFileSync(fp, 'utf8').split('\n'); } catch { continue; }
|
|
635
|
+
for (const raw of lines) {
|
|
636
|
+
const line = raw.trim();
|
|
637
|
+
if (!line || line.startsWith('#') || line.startsWith('import ')) continue;
|
|
638
|
+
if (isEscape(line)) push(e.name.replace(/\.pth$/, ''), line, '.pth');
|
|
639
|
+
}
|
|
640
|
+
} else if (/^__editable___.+_finder\.py$/.test(e.name)) {
|
|
641
|
+
let src = '';
|
|
642
|
+
try { src = readFileSync(fp, 'utf8'); } catch { continue; }
|
|
643
|
+
const mm = /MAPPING\s*=\s*\{([\s\S]*?)\}/.exec(src);
|
|
644
|
+
if (!mm) continue;
|
|
645
|
+
const pkg = e.name.replace(/^__editable___/, '').replace(/_finder\.py$/, '');
|
|
646
|
+
for (const pm of mm[1].matchAll(/'((?:[^'\\]|\\.)*)'/g)) {
|
|
647
|
+
const target = pm[1].replace(/\\\\/g, '\\');
|
|
648
|
+
if (isEscape(target)) push(pkg, target, 'pep660-finder');
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
// direct_url.json(pip/uv 现代 editable 标记)
|
|
653
|
+
for (const e of entries) {
|
|
654
|
+
if (!e.isDirectory() || !e.name.endsWith('.dist-info')) continue;
|
|
655
|
+
const du = join(sp, e.name, 'direct_url.json');
|
|
656
|
+
if (!existsSync(du)) continue;
|
|
657
|
+
try {
|
|
658
|
+
const meta = JSON.parse(readFileSync(du, 'utf8'));
|
|
659
|
+
if (meta?.dir_info?.editable && typeof meta.url === 'string' && meta.url.startsWith('file://')) {
|
|
660
|
+
const target = fileURLToPath(meta.url);
|
|
661
|
+
if (isEscape(target)) push(e.name.replace(/\.dist-info$/, ''), target, 'direct_url');
|
|
662
|
+
}
|
|
663
|
+
} catch { /* 解析失败跳过 */ }
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return offenders;
|
|
668
|
+
}
|