gsd-remix 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +939 -0
- package/README.zh-CN.md +876 -0
- package/agents/gsd-advisor-researcher.md +127 -0
- package/agents/gsd-ai-researcher.md +133 -0
- package/agents/gsd-assumptions-analyzer.md +105 -0
- package/agents/gsd-code-fixer.md +517 -0
- package/agents/gsd-code-reviewer.md +371 -0
- package/agents/gsd-codebase-mapper.md +781 -0
- package/agents/gsd-debug-session-manager.md +314 -0
- package/agents/gsd-debugger.md +1452 -0
- package/agents/gsd-doc-classifier.md +168 -0
- package/agents/gsd-doc-synthesizer.md +204 -0
- package/agents/gsd-doc-verifier.md +217 -0
- package/agents/gsd-doc-writer.md +615 -0
- package/agents/gsd-domain-researcher.md +153 -0
- package/agents/gsd-eval-auditor.md +191 -0
- package/agents/gsd-eval-planner.md +154 -0
- package/agents/gsd-executor.md +603 -0
- package/agents/gsd-framework-selector.md +160 -0
- package/agents/gsd-integration-checker.md +470 -0
- package/agents/gsd-intel-updater.md +334 -0
- package/agents/gsd-nyquist-auditor.md +203 -0
- package/agents/gsd-pattern-mapper.md +335 -0
- package/agents/gsd-phase-researcher.md +841 -0
- package/agents/gsd-plan-checker.md +978 -0
- package/agents/gsd-planner.md +1251 -0
- package/agents/gsd-project-researcher.md +677 -0
- package/agents/gsd-research-synthesizer.md +247 -0
- package/agents/gsd-roadmapper.md +688 -0
- package/agents/gsd-security-auditor.md +155 -0
- package/agents/gsd-ui-auditor.md +495 -0
- package/agents/gsd-ui-checker.md +309 -0
- package/agents/gsd-ui-researcher.md +380 -0
- package/agents/gsd-user-profiler.md +171 -0
- package/agents/gsd-verifier.md +830 -0
- package/bin/install.js +7062 -0
- package/commands/gsd/add-backlog.md +79 -0
- package/commands/gsd/add-phase.md +43 -0
- package/commands/gsd/add-tests.md +41 -0
- package/commands/gsd/add-todo.md +47 -0
- package/commands/gsd/ai-integration-phase.md +36 -0
- package/commands/gsd/analyze-dependencies.md +34 -0
- package/commands/gsd/audit-fix.md +33 -0
- package/commands/gsd/audit-milestone.md +36 -0
- package/commands/gsd/audit-uat.md +24 -0
- package/commands/gsd/autonomous.md +46 -0
- package/commands/gsd/check-todos.md +45 -0
- package/commands/gsd/cleanup.md +23 -0
- package/commands/gsd/code-review-fix.md +52 -0
- package/commands/gsd/code-review.md +55 -0
- package/commands/gsd/complete-milestone.md +136 -0
- package/commands/gsd/debug.md +263 -0
- package/commands/gsd/discuss-phase.md +69 -0
- package/commands/gsd/do.md +30 -0
- package/commands/gsd/docs-update.md +48 -0
- package/commands/gsd/eval-review.md +32 -0
- package/commands/gsd/execute-phase.md +63 -0
- package/commands/gsd/explore.md +27 -0
- package/commands/gsd/extract_learnings.md +22 -0
- package/commands/gsd/fast.md +30 -0
- package/commands/gsd/forensics.md +56 -0
- package/commands/gsd/from-gsd2.md +47 -0
- package/commands/gsd/graphify.md +201 -0
- package/commands/gsd/health.md +22 -0
- package/commands/gsd/help.md +24 -0
- package/commands/gsd/import.md +37 -0
- package/commands/gsd/inbox.md +38 -0
- package/commands/gsd/ingest-docs.md +42 -0
- package/commands/gsd/insert-phase.md +32 -0
- package/commands/gsd/intel.md +179 -0
- package/commands/gsd/join-discord.md +19 -0
- package/commands/gsd/list-phase-assumptions.md +46 -0
- package/commands/gsd/list-workspaces.md +19 -0
- package/commands/gsd/manager.md +40 -0
- package/commands/gsd/map-codebase.md +71 -0
- package/commands/gsd/milestone-summary.md +51 -0
- package/commands/gsd/new-milestone.md +44 -0
- package/commands/gsd/new-project.md +46 -0
- package/commands/gsd/new-workspace.md +44 -0
- package/commands/gsd/next.md +28 -0
- package/commands/gsd/note.md +34 -0
- package/commands/gsd/pause-work.md +38 -0
- package/commands/gsd/plan-milestone-gaps.md +34 -0
- package/commands/gsd/plan-phase.md +52 -0
- package/commands/gsd/plan-review-convergence.md +52 -0
- package/commands/gsd/plant-seed.md +28 -0
- package/commands/gsd/pr-branch.md +25 -0
- package/commands/gsd/profile-user.md +46 -0
- package/commands/gsd/progress.md +25 -0
- package/commands/gsd/quick.md +173 -0
- package/commands/gsd/reapply-patches.md +331 -0
- package/commands/gsd/remove-phase.md +31 -0
- package/commands/gsd/remove-workspace.md +26 -0
- package/commands/gsd/research-phase.md +195 -0
- package/commands/gsd/resume-work.md +40 -0
- package/commands/gsd/review-backlog.md +62 -0
- package/commands/gsd/review.md +40 -0
- package/commands/gsd/scan.md +26 -0
- package/commands/gsd/secure-phase.md +35 -0
- package/commands/gsd/session-report.md +19 -0
- package/commands/gsd/set-profile.md +12 -0
- package/commands/gsd/settings.md +36 -0
- package/commands/gsd/ship.md +23 -0
- package/commands/gsd/sketch-wrap-up.md +31 -0
- package/commands/gsd/sketch.md +49 -0
- package/commands/gsd/spec-phase.md +62 -0
- package/commands/gsd/spike-wrap-up.md +31 -0
- package/commands/gsd/spike.md +46 -0
- package/commands/gsd/stats.md +18 -0
- package/commands/gsd/sync-skills.md +19 -0
- package/commands/gsd/thread.md +227 -0
- package/commands/gsd/ui-phase.md +34 -0
- package/commands/gsd/ui-review.md +32 -0
- package/commands/gsd/ultraplan-phase.md +33 -0
- package/commands/gsd/undo.md +34 -0
- package/commands/gsd/update.md +37 -0
- package/commands/gsd/validate-phase.md +35 -0
- package/commands/gsd/verify-work.md +38 -0
- package/commands/gsd/workstreams.md +69 -0
- package/get-shit-done/bin/gsd-tools.cjs +1263 -0
- package/get-shit-done/bin/lib/artifacts.cjs +52 -0
- package/get-shit-done/bin/lib/audit.cjs +757 -0
- package/get-shit-done/bin/lib/commands.cjs +1023 -0
- package/get-shit-done/bin/lib/config-schema.cjs +79 -0
- package/get-shit-done/bin/lib/config.cjs +463 -0
- package/get-shit-done/bin/lib/core.cjs +1794 -0
- package/get-shit-done/bin/lib/docs.cjs +267 -0
- package/get-shit-done/bin/lib/frontmatter.cjs +379 -0
- package/get-shit-done/bin/lib/graphify.cjs +494 -0
- package/get-shit-done/bin/lib/gsd2-import.cjs +511 -0
- package/get-shit-done/bin/lib/init.cjs +1878 -0
- package/get-shit-done/bin/lib/intel.cjs +639 -0
- package/get-shit-done/bin/lib/learnings.cjs +378 -0
- package/get-shit-done/bin/lib/milestone.cjs +283 -0
- package/get-shit-done/bin/lib/model-profiles.cjs +71 -0
- package/get-shit-done/bin/lib/phase.cjs +1058 -0
- package/get-shit-done/bin/lib/profile-output.cjs +1080 -0
- package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
- package/get-shit-done/bin/lib/roadmap.cjs +523 -0
- package/get-shit-done/bin/lib/schema-detect.cjs +238 -0
- package/get-shit-done/bin/lib/security.cjs +504 -0
- package/get-shit-done/bin/lib/state.cjs +1649 -0
- package/get-shit-done/bin/lib/template.cjs +226 -0
- package/get-shit-done/bin/lib/uat.cjs +288 -0
- package/get-shit-done/bin/lib/verify.cjs +1184 -0
- package/get-shit-done/bin/lib/workstream.cjs +495 -0
- package/get-shit-done/bin/repair-sdk.cjs +177 -0
- package/get-shit-done/contexts/dev.md +21 -0
- package/get-shit-done/contexts/research.md +22 -0
- package/get-shit-done/contexts/review.md +22 -0
- package/get-shit-done/references/agent-contracts.md +79 -0
- package/get-shit-done/references/ai-evals.md +156 -0
- package/get-shit-done/references/ai-frameworks.md +186 -0
- package/get-shit-done/references/artifact-types.md +131 -0
- package/get-shit-done/references/autonomous-smart-discuss.md +277 -0
- package/get-shit-done/references/checkpoints.md +808 -0
- package/get-shit-done/references/common-bug-patterns.md +114 -0
- package/get-shit-done/references/context-budget.md +49 -0
- package/get-shit-done/references/continuation-format.md +253 -0
- package/get-shit-done/references/debugger-philosophy.md +76 -0
- package/get-shit-done/references/decimal-phase-calculation.md +64 -0
- package/get-shit-done/references/doc-conflict-engine.md +91 -0
- package/get-shit-done/references/domain-probes.md +125 -0
- package/get-shit-done/references/executor-examples.md +110 -0
- package/get-shit-done/references/few-shot-examples/plan-checker.md +73 -0
- package/get-shit-done/references/few-shot-examples/verifier.md +109 -0
- package/get-shit-done/references/gate-prompts.md +100 -0
- package/get-shit-done/references/gates.md +70 -0
- package/get-shit-done/references/git-integration.md +295 -0
- package/get-shit-done/references/git-planning-commit.md +40 -0
- package/get-shit-done/references/ios-scaffold.md +123 -0
- package/get-shit-done/references/mandatory-initial-read.md +2 -0
- package/get-shit-done/references/model-profile-resolution.md +38 -0
- package/get-shit-done/references/model-profiles.md +145 -0
- package/get-shit-done/references/phase-argument-parsing.md +61 -0
- package/get-shit-done/references/planner-antipatterns.md +89 -0
- package/get-shit-done/references/planner-gap-closure.md +62 -0
- package/get-shit-done/references/planner-reviews.md +39 -0
- package/get-shit-done/references/planner-revision.md +87 -0
- package/get-shit-done/references/planner-source-audit.md +73 -0
- package/get-shit-done/references/planning-config.md +460 -0
- package/get-shit-done/references/project-skills-discovery.md +19 -0
- package/get-shit-done/references/questioning.md +162 -0
- package/get-shit-done/references/revision-loop.md +97 -0
- package/get-shit-done/references/sketch-interactivity.md +41 -0
- package/get-shit-done/references/sketch-theme-system.md +94 -0
- package/get-shit-done/references/sketch-tooling.md +45 -0
- package/get-shit-done/references/sketch-variant-patterns.md +81 -0
- package/get-shit-done/references/tdd.md +330 -0
- package/get-shit-done/references/thinking-models-debug.md +44 -0
- package/get-shit-done/references/thinking-models-execution.md +50 -0
- package/get-shit-done/references/thinking-models-planning.md +62 -0
- package/get-shit-done/references/thinking-models-research.md +50 -0
- package/get-shit-done/references/thinking-models-verification.md +55 -0
- package/get-shit-done/references/thinking-partner.md +96 -0
- package/get-shit-done/references/ui-brand.md +160 -0
- package/get-shit-done/references/universal-anti-patterns.md +63 -0
- package/get-shit-done/references/user-profiling.md +681 -0
- package/get-shit-done/references/verification-overrides.md +227 -0
- package/get-shit-done/references/verification-patterns.md +612 -0
- package/get-shit-done/references/workstream-flag.md +111 -0
- package/get-shit-done/templates/AI-SPEC.md +246 -0
- package/get-shit-done/templates/DEBUG.md +169 -0
- package/get-shit-done/templates/README.md +76 -0
- package/get-shit-done/templates/SECURITY.md +61 -0
- package/get-shit-done/templates/UAT.md +265 -0
- package/get-shit-done/templates/UI-SPEC.md +100 -0
- package/get-shit-done/templates/VALIDATION.md +76 -0
- package/get-shit-done/templates/claude-md.md +145 -0
- package/get-shit-done/templates/codebase/architecture.md +255 -0
- package/get-shit-done/templates/codebase/concerns.md +310 -0
- package/get-shit-done/templates/codebase/conventions.md +307 -0
- package/get-shit-done/templates/codebase/integrations.md +280 -0
- package/get-shit-done/templates/codebase/stack.md +186 -0
- package/get-shit-done/templates/codebase/structure.md +285 -0
- package/get-shit-done/templates/codebase/testing.md +480 -0
- package/get-shit-done/templates/config.json +56 -0
- package/get-shit-done/templates/context.md +352 -0
- package/get-shit-done/templates/continue-here.md +78 -0
- package/get-shit-done/templates/copilot-instructions.md +7 -0
- package/get-shit-done/templates/debug-subagent-prompt.md +91 -0
- package/get-shit-done/templates/dev-preferences.md +21 -0
- package/get-shit-done/templates/discovery.md +146 -0
- package/get-shit-done/templates/discussion-log.md +63 -0
- package/get-shit-done/templates/milestone-archive.md +123 -0
- package/get-shit-done/templates/milestone.md +115 -0
- package/get-shit-done/templates/phase-prompt.md +610 -0
- package/get-shit-done/templates/planner-subagent-prompt.md +117 -0
- package/get-shit-done/templates/project.md +186 -0
- package/get-shit-done/templates/requirements.md +231 -0
- package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
- package/get-shit-done/templates/research-project/FEATURES.md +147 -0
- package/get-shit-done/templates/research-project/PITFALLS.md +200 -0
- package/get-shit-done/templates/research-project/STACK.md +120 -0
- package/get-shit-done/templates/research-project/SUMMARY.md +170 -0
- package/get-shit-done/templates/research.md +592 -0
- package/get-shit-done/templates/retrospective.md +54 -0
- package/get-shit-done/templates/roadmap.md +202 -0
- package/get-shit-done/templates/spec.md +307 -0
- package/get-shit-done/templates/state.md +184 -0
- package/get-shit-done/templates/summary-complex.md +59 -0
- package/get-shit-done/templates/summary-minimal.md +41 -0
- package/get-shit-done/templates/summary-standard.md +48 -0
- package/get-shit-done/templates/summary.md +248 -0
- package/get-shit-done/templates/user-profile.md +146 -0
- package/get-shit-done/templates/user-setup.md +311 -0
- package/get-shit-done/templates/verification-report.md +322 -0
- package/get-shit-done/workflows/add-phase.md +112 -0
- package/get-shit-done/workflows/add-tests.md +354 -0
- package/get-shit-done/workflows/add-todo.md +160 -0
- package/get-shit-done/workflows/ai-integration-phase.md +284 -0
- package/get-shit-done/workflows/analyze-dependencies.md +96 -0
- package/get-shit-done/workflows/audit-fix.md +175 -0
- package/get-shit-done/workflows/audit-milestone.md +340 -0
- package/get-shit-done/workflows/audit-uat.md +109 -0
- package/get-shit-done/workflows/autonomous.md +789 -0
- package/get-shit-done/workflows/check-todos.md +179 -0
- package/get-shit-done/workflows/cleanup.md +154 -0
- package/get-shit-done/workflows/code-review-fix.md +497 -0
- package/get-shit-done/workflows/code-review.md +515 -0
- package/get-shit-done/workflows/complete-milestone.md +847 -0
- package/get-shit-done/workflows/diagnose-issues.md +238 -0
- package/get-shit-done/workflows/discovery-phase.md +291 -0
- package/get-shit-done/workflows/discuss-phase-assumptions.md +670 -0
- package/get-shit-done/workflows/discuss-phase-power.md +308 -0
- package/get-shit-done/workflows/discuss-phase.md +1378 -0
- package/get-shit-done/workflows/do.md +110 -0
- package/get-shit-done/workflows/docs-update.md +1155 -0
- package/get-shit-done/workflows/eval-review.md +155 -0
- package/get-shit-done/workflows/execute-phase.md +1677 -0
- package/get-shit-done/workflows/execute-plan.md +533 -0
- package/get-shit-done/workflows/explore.md +141 -0
- package/get-shit-done/workflows/extract_learnings.md +242 -0
- package/get-shit-done/workflows/fast.md +105 -0
- package/get-shit-done/workflows/forensics.md +265 -0
- package/get-shit-done/workflows/graduation.md +195 -0
- package/get-shit-done/workflows/health.md +314 -0
- package/get-shit-done/workflows/help.md +667 -0
- package/get-shit-done/workflows/import.md +246 -0
- package/get-shit-done/workflows/inbox.md +387 -0
- package/get-shit-done/workflows/ingest-docs.md +328 -0
- package/get-shit-done/workflows/insert-phase.md +130 -0
- package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
- package/get-shit-done/workflows/list-workspaces.md +56 -0
- package/get-shit-done/workflows/manager.md +365 -0
- package/get-shit-done/workflows/map-codebase.md +393 -0
- package/get-shit-done/workflows/milestone-summary.md +223 -0
- package/get-shit-done/workflows/new-milestone.md +611 -0
- package/get-shit-done/workflows/new-project.md +1391 -0
- package/get-shit-done/workflows/new-workspace.md +239 -0
- package/get-shit-done/workflows/next.md +220 -0
- package/get-shit-done/workflows/node-repair.md +92 -0
- package/get-shit-done/workflows/note.md +158 -0
- package/get-shit-done/workflows/pause-work.md +243 -0
- package/get-shit-done/workflows/plan-milestone-gaps.md +273 -0
- package/get-shit-done/workflows/plan-phase.md +1349 -0
- package/get-shit-done/workflows/plan-review-convergence.md +254 -0
- package/get-shit-done/workflows/plant-seed.md +172 -0
- package/get-shit-done/workflows/pr-branch.md +157 -0
- package/get-shit-done/workflows/profile-user.md +452 -0
- package/get-shit-done/workflows/progress.md +619 -0
- package/get-shit-done/workflows/quick.md +970 -0
- package/get-shit-done/workflows/remove-phase.md +155 -0
- package/get-shit-done/workflows/remove-workspace.md +92 -0
- package/get-shit-done/workflows/research-phase.md +89 -0
- package/get-shit-done/workflows/resume-project.md +326 -0
- package/get-shit-done/workflows/review.md +344 -0
- package/get-shit-done/workflows/scan.md +102 -0
- package/get-shit-done/workflows/secure-phase.md +166 -0
- package/get-shit-done/workflows/session-report.md +146 -0
- package/get-shit-done/workflows/settings.md +319 -0
- package/get-shit-done/workflows/ship.md +302 -0
- package/get-shit-done/workflows/sketch-wrap-up.md +283 -0
- package/get-shit-done/workflows/sketch.md +286 -0
- package/get-shit-done/workflows/spec-phase.md +262 -0
- package/get-shit-done/workflows/spike-wrap-up.md +281 -0
- package/get-shit-done/workflows/spike.md +362 -0
- package/get-shit-done/workflows/stats.md +60 -0
- package/get-shit-done/workflows/sync-skills.md +182 -0
- package/get-shit-done/workflows/transition.md +693 -0
- package/get-shit-done/workflows/ui-phase.md +323 -0
- package/get-shit-done/workflows/ui-review.md +190 -0
- package/get-shit-done/workflows/ultraplan-phase.md +189 -0
- package/get-shit-done/workflows/undo.md +314 -0
- package/get-shit-done/workflows/update.md +587 -0
- package/get-shit-done/workflows/validate-phase.md +176 -0
- package/get-shit-done/workflows/verify-phase.md +465 -0
- package/get-shit-done/workflows/verify-work.md +740 -0
- package/hooks/dist/gsd-check-update-worker.js +108 -0
- package/hooks/dist/gsd-check-update.js +64 -0
- package/hooks/dist/gsd-context-monitor.js +192 -0
- package/hooks/dist/gsd-phase-boundary.sh +28 -0
- package/hooks/dist/gsd-prompt-guard.js +97 -0
- package/hooks/dist/gsd-read-guard.js +82 -0
- package/hooks/dist/gsd-read-injection-scanner.js +152 -0
- package/hooks/dist/gsd-session-state.sh +34 -0
- package/hooks/dist/gsd-statusline.js +293 -0
- package/hooks/dist/gsd-validate-commit.sh +48 -0
- package/hooks/dist/gsd-workflow-guard.js +94 -0
- package/hooks/gsd-check-update-worker.js +108 -0
- package/hooks/gsd-check-update.js +64 -0
- package/hooks/gsd-context-monitor.js +192 -0
- package/hooks/gsd-phase-boundary.sh +28 -0
- package/hooks/gsd-prompt-guard.js +97 -0
- package/hooks/gsd-read-guard.js +82 -0
- package/hooks/gsd-read-injection-scanner.js +152 -0
- package/hooks/gsd-session-state.sh +34 -0
- package/hooks/gsd-statusline.js +293 -0
- package/hooks/gsd-validate-commit.sh +48 -0
- package/hooks/gsd-workflow-guard.js +94 -0
- package/package.json +59 -0
- package/scripts/base64-scan.sh +262 -0
- package/scripts/build-hooks.js +95 -0
- package/scripts/gen-inventory-manifest.cjs +109 -0
- package/scripts/prompt-injection-scan.sh +201 -0
- package/scripts/run-tests.cjs +33 -0
- package/scripts/secret-scan.sh +227 -0
- package/sdk/package-lock.json +1998 -0
- package/sdk/package.json +52 -0
- package/sdk/prompts/agents/gsd-executor.md +110 -0
- package/sdk/prompts/agents/gsd-phase-researcher.md +158 -0
- package/sdk/prompts/agents/gsd-plan-checker.md +160 -0
- package/sdk/prompts/agents/gsd-planner.md +214 -0
- package/sdk/prompts/agents/gsd-project-researcher.md +323 -0
- package/sdk/prompts/agents/gsd-research-synthesizer.md +237 -0
- package/sdk/prompts/agents/gsd-roadmapper.md +670 -0
- package/sdk/prompts/agents/gsd-verifier.md +159 -0
- package/sdk/prompts/templates/project.md +186 -0
- package/sdk/prompts/templates/requirements.md +231 -0
- package/sdk/prompts/templates/research-project/ARCHITECTURE.md +204 -0
- package/sdk/prompts/templates/research-project/FEATURES.md +147 -0
- package/sdk/prompts/templates/research-project/PITFALLS.md +200 -0
- package/sdk/prompts/templates/research-project/STACK.md +120 -0
- package/sdk/prompts/templates/research-project/SUMMARY.md +170 -0
- package/sdk/prompts/templates/roadmap.md +202 -0
- package/sdk/prompts/templates/state.md +175 -0
- package/sdk/prompts/workflows/discuss-phase.md +126 -0
- package/sdk/prompts/workflows/execute-plan.md +106 -0
- package/sdk/prompts/workflows/plan-phase.md +84 -0
- package/sdk/prompts/workflows/research-phase.md +45 -0
- package/sdk/prompts/workflows/verify-phase.md +142 -0
- package/sdk/src/assembled-prompts.test.ts +349 -0
- package/sdk/src/cli-transport.test.ts +388 -0
- package/sdk/src/cli-transport.ts +130 -0
- package/sdk/src/cli.test.ts +383 -0
- package/sdk/src/cli.ts +670 -0
- package/sdk/src/config.test.ts +168 -0
- package/sdk/src/config.ts +177 -0
- package/sdk/src/context-engine.test.ts +295 -0
- package/sdk/src/context-engine.ts +170 -0
- package/sdk/src/context-truncation.test.ts +163 -0
- package/sdk/src/context-truncation.ts +233 -0
- package/sdk/src/e2e.integration.test.ts +178 -0
- package/sdk/src/errors.ts +72 -0
- package/sdk/src/event-stream.test.ts +661 -0
- package/sdk/src/event-stream.ts +441 -0
- package/sdk/src/failure-memory.test.ts +457 -0
- package/sdk/src/failure-memory.ts +1324 -0
- package/sdk/src/golden/capture.ts +95 -0
- package/sdk/src/golden/fixtures/generate-slug.golden.json +1 -0
- package/sdk/src/golden/fixtures/profile-sample-sessions/demo-project/sample.jsonl +3 -0
- package/sdk/src/golden/fixtures/summary-extract-sample.md +26 -0
- package/sdk/src/golden/fixtures/uat-render-checkpoint-sample.md +15 -0
- package/sdk/src/golden/golden-integration-covered.ts +30 -0
- package/sdk/src/golden/golden-mutation-covered.ts +7 -0
- package/sdk/src/golden/golden-policy.test.ts +8 -0
- package/sdk/src/golden/golden-policy.ts +112 -0
- package/sdk/src/golden/golden.integration.test.ts +373 -0
- package/sdk/src/golden/init-golden-normalize.ts +15 -0
- package/sdk/src/golden/read-only-golden-rows.ts +77 -0
- package/sdk/src/golden/read-only-parity.integration.test.ts +125 -0
- package/sdk/src/golden/registry-canonical-commands.ts +31 -0
- package/sdk/src/gsd-tools.test.ts +409 -0
- package/sdk/src/gsd-tools.ts +595 -0
- package/sdk/src/headless-prompts.test.ts +159 -0
- package/sdk/src/index.ts +333 -0
- package/sdk/src/init-e2e.integration.test.ts +136 -0
- package/sdk/src/init-runner.test.ts +783 -0
- package/sdk/src/init-runner.ts +735 -0
- package/sdk/src/lifecycle-e2e.integration.test.ts +258 -0
- package/sdk/src/logger.test.ts +149 -0
- package/sdk/src/logger.ts +113 -0
- package/sdk/src/milestone-runner.test.ts +421 -0
- package/sdk/src/phase-prompt.test.ts +538 -0
- package/sdk/src/phase-prompt.ts +264 -0
- package/sdk/src/phase-runner-types.test.ts +421 -0
- package/sdk/src/phase-runner.integration.test.ts +377 -0
- package/sdk/src/phase-runner.test.ts +2333 -0
- package/sdk/src/phase-runner.ts +1203 -0
- package/sdk/src/plan-parser.test.ts +528 -0
- package/sdk/src/plan-parser.ts +427 -0
- package/sdk/src/prompt-builder.test.ts +306 -0
- package/sdk/src/prompt-builder.ts +193 -0
- package/sdk/src/prompt-sanitizer.test.ts +260 -0
- package/sdk/src/prompt-sanitizer.ts +71 -0
- package/sdk/src/query/QUERY-HANDLERS.md +317 -0
- package/sdk/src/query/audit-open.ts +722 -0
- package/sdk/src/query/check-auto-mode.test.ts +77 -0
- package/sdk/src/query/check-auto-mode.ts +50 -0
- package/sdk/src/query/check-completion.test.ts +113 -0
- package/sdk/src/query/check-completion.ts +182 -0
- package/sdk/src/query/check-gates.test.ts +103 -0
- package/sdk/src/query/check-gates.ts +112 -0
- package/sdk/src/query/check-ship-ready.test.ts +77 -0
- package/sdk/src/query/check-ship-ready.ts +103 -0
- package/sdk/src/query/check-verification-status.test.ts +143 -0
- package/sdk/src/query/check-verification-status.ts +160 -0
- package/sdk/src/query/commit.test.ts +202 -0
- package/sdk/src/query/commit.ts +301 -0
- package/sdk/src/query/config-gates.test.ts +89 -0
- package/sdk/src/query/config-gates.ts +69 -0
- package/sdk/src/query/config-mutation.test.ts +365 -0
- package/sdk/src/query/config-mutation.ts +497 -0
- package/sdk/src/query/config-query.test.ts +161 -0
- package/sdk/src/query/config-query.ts +190 -0
- package/sdk/src/query/context-history.test.ts +165 -0
- package/sdk/src/query/context-history.ts +467 -0
- package/sdk/src/query/decomposed-handlers.test.ts +365 -0
- package/sdk/src/query/detect-custom-files.ts +97 -0
- package/sdk/src/query/detect-phase-type.test.ts +105 -0
- package/sdk/src/query/detect-phase-type.ts +141 -0
- package/sdk/src/query/docs-init.ts +257 -0
- package/sdk/src/query/failure-capture.ts +58 -0
- package/sdk/src/query/frontmatter-array.test.ts +14 -0
- package/sdk/src/query/frontmatter-mutation.test.ts +259 -0
- package/sdk/src/query/frontmatter-mutation.ts +343 -0
- package/sdk/src/query/frontmatter.test.ts +281 -0
- package/sdk/src/query/frontmatter.ts +397 -0
- package/sdk/src/query/helpers.test.ts +426 -0
- package/sdk/src/query/helpers.ts +482 -0
- package/sdk/src/query/index.ts +586 -0
- package/sdk/src/query/init-complex.test.ts +232 -0
- package/sdk/src/query/init-complex.ts +578 -0
- package/sdk/src/query/init.test.ts +522 -0
- package/sdk/src/query/init.ts +1046 -0
- package/sdk/src/query/intel.test.ts +90 -0
- package/sdk/src/query/intel.ts +404 -0
- package/sdk/src/query/normalize-query-command.test.ts +50 -0
- package/sdk/src/query/normalize-query-command.ts +56 -0
- package/sdk/src/query/phase-lifecycle.test.ts +1126 -0
- package/sdk/src/query/phase-lifecycle.ts +1799 -0
- package/sdk/src/query/phase-list-queries.test.ts +88 -0
- package/sdk/src/query/phase-list-queries.ts +152 -0
- package/sdk/src/query/phase-ready.test.ts +65 -0
- package/sdk/src/query/phase-ready.ts +158 -0
- package/sdk/src/query/phase.test.ts +307 -0
- package/sdk/src/query/phase.ts +340 -0
- package/sdk/src/query/pipeline.test.ts +169 -0
- package/sdk/src/query/pipeline.ts +243 -0
- package/sdk/src/query/plan-execution-route.test.ts +166 -0
- package/sdk/src/query/plan-execution-route.ts +209 -0
- package/sdk/src/query/plan-task-structure.test.ts +65 -0
- package/sdk/src/query/plan-task-structure.ts +63 -0
- package/sdk/src/query/profile-extract-messages.ts +247 -0
- package/sdk/src/query/profile-output.ts +908 -0
- package/sdk/src/query/profile-questionnaire-data.ts +181 -0
- package/sdk/src/query/profile-sample.ts +184 -0
- package/sdk/src/query/profile-scan-sessions.ts +174 -0
- package/sdk/src/query/profile.test.ts +74 -0
- package/sdk/src/query/profile.ts +337 -0
- package/sdk/src/query/progress.test.ts +156 -0
- package/sdk/src/query/progress.ts +566 -0
- package/sdk/src/query/registry.test.ts +216 -0
- package/sdk/src/query/registry.ts +174 -0
- package/sdk/src/query/requirements-extract-from-plans.test.ts +58 -0
- package/sdk/src/query/requirements-extract-from-plans.ts +86 -0
- package/sdk/src/query/roadmap-update-plan-progress.ts +132 -0
- package/sdk/src/query/roadmap.test.ts +359 -0
- package/sdk/src/query/roadmap.ts +591 -0
- package/sdk/src/query/route-next-action.test.ts +61 -0
- package/sdk/src/query/route-next-action.ts +345 -0
- package/sdk/src/query/runtime-health.ts +7 -0
- package/sdk/src/query/schema-detect.ts +189 -0
- package/sdk/src/query/skill-manifest.ts +214 -0
- package/sdk/src/query/skills.test.ts +80 -0
- package/sdk/src/query/skills.ts +62 -0
- package/sdk/src/query/state-mutation.test.ts +450 -0
- package/sdk/src/query/state-mutation.ts +1444 -0
- package/sdk/src/query/state-project-load.ts +109 -0
- package/sdk/src/query/state.test.ts +347 -0
- package/sdk/src/query/state.ts +397 -0
- package/sdk/src/query/summary.test.ts +95 -0
- package/sdk/src/query/summary.ts +296 -0
- package/sdk/src/query/template.test.ts +180 -0
- package/sdk/src/query/template.ts +242 -0
- package/sdk/src/query/uat.test.ts +77 -0
- package/sdk/src/query/uat.ts +314 -0
- package/sdk/src/query/utils.test.ts +82 -0
- package/sdk/src/query/utils.ts +92 -0
- package/sdk/src/query/validate.test.ts +656 -0
- package/sdk/src/query/validate.ts +807 -0
- package/sdk/src/query/verify.test.ts +414 -0
- package/sdk/src/query/verify.ts +645 -0
- package/sdk/src/query/websearch.test.ts +31 -0
- package/sdk/src/query/websearch.ts +82 -0
- package/sdk/src/query/workspace.test.ts +119 -0
- package/sdk/src/query/workspace.ts +131 -0
- package/sdk/src/query/workstream.test.ts +51 -0
- package/sdk/src/query/workstream.ts +434 -0
- package/sdk/src/research-gate.test.ts +190 -0
- package/sdk/src/research-gate.ts +94 -0
- package/sdk/src/runtime-health.test.ts +176 -0
- package/sdk/src/runtime-health.ts +387 -0
- package/sdk/src/session-runner.test.ts +98 -0
- package/sdk/src/session-runner.ts +299 -0
- package/sdk/src/tool-scoping.test.ts +160 -0
- package/sdk/src/tool-scoping.ts +61 -0
- package/sdk/src/types.ts +917 -0
- package/sdk/src/workstream-utils.ts +33 -0
- package/sdk/src/ws-flag.test.ts +285 -0
- package/sdk/src/ws-transport.test.ts +161 -0
- package/sdk/src/ws-transport.ts +93 -0
- package/sdk/tsconfig.json +20 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for STATE.md mutation handlers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
6
|
+
import { mkdtemp, writeFile, readFile, rm, mkdir } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { tmpdir } from 'node:os';
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
|
|
11
|
+
// ─── Helpers (internal) ─────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
/** Minimal STATE.md for testing. */
|
|
14
|
+
const MINIMAL_STATE = `---
|
|
15
|
+
gsd_state_version: 1.0
|
|
16
|
+
milestone: v3.0
|
|
17
|
+
milestone_name: SDK-First Migration
|
|
18
|
+
status: executing
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Project State
|
|
22
|
+
|
|
23
|
+
## Project Reference
|
|
24
|
+
|
|
25
|
+
**Core value:** Test project
|
|
26
|
+
|
|
27
|
+
## Current Position
|
|
28
|
+
|
|
29
|
+
Phase: 10 (Read-Only Queries) — EXECUTING
|
|
30
|
+
Plan: 2 of 3
|
|
31
|
+
Status: Executing Phase 10
|
|
32
|
+
Last activity: 2026-04-08 -- Phase 10 execution started
|
|
33
|
+
|
|
34
|
+
Progress: [░░░░░░░░░░] 50%
|
|
35
|
+
|
|
36
|
+
## Performance Metrics
|
|
37
|
+
|
|
38
|
+
**Velocity:**
|
|
39
|
+
|
|
40
|
+
| Phase | Duration | Tasks | Files |
|
|
41
|
+
|-------|----------|-------|-------|
|
|
42
|
+
|
|
43
|
+
## Accumulated Context
|
|
44
|
+
|
|
45
|
+
### Decisions
|
|
46
|
+
|
|
47
|
+
None yet.
|
|
48
|
+
|
|
49
|
+
### Pending Todos
|
|
50
|
+
|
|
51
|
+
None yet.
|
|
52
|
+
|
|
53
|
+
### Blockers/Concerns
|
|
54
|
+
|
|
55
|
+
None yet.
|
|
56
|
+
|
|
57
|
+
## Session Continuity
|
|
58
|
+
|
|
59
|
+
Last session: 2026-04-07T10:00:00.000Z
|
|
60
|
+
Stopped at: Completed 10-02-PLAN.md
|
|
61
|
+
Resume file: None
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
/** Create a minimal .planning directory for testing. */
|
|
65
|
+
async function setupTestProject(tmpDir: string, stateContent?: string): Promise<string> {
|
|
66
|
+
const planningDir = join(tmpDir, '.planning');
|
|
67
|
+
await mkdir(planningDir, { recursive: true });
|
|
68
|
+
await mkdir(join(planningDir, 'phases'), { recursive: true });
|
|
69
|
+
await writeFile(join(planningDir, 'STATE.md'), stateContent || MINIMAL_STATE, 'utf-8');
|
|
70
|
+
// Minimal ROADMAP.md for buildStateFrontmatter
|
|
71
|
+
await writeFile(join(planningDir, 'ROADMAP.md'), '# Roadmap\n\n## Current Milestone: v3.0 SDK-First Migration\n\n### Phase 10: Read-Only Queries\n\nGoal: Port queries.\n', 'utf-8');
|
|
72
|
+
await writeFile(join(planningDir, 'config.json'), '{"model_profile":"balanced"}', 'utf-8');
|
|
73
|
+
return tmpDir;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ─── Import tests ───────────────────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
describe('state-mutation imports', () => {
|
|
79
|
+
it('exports stateUpdate handler', async () => {
|
|
80
|
+
const mod = await import('./state-mutation.js');
|
|
81
|
+
expect(typeof mod.stateUpdate).toBe('function');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('exports statePatch handler', async () => {
|
|
85
|
+
const mod = await import('./state-mutation.js');
|
|
86
|
+
expect(typeof mod.statePatch).toBe('function');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('exports stateBeginPhase handler', async () => {
|
|
90
|
+
const mod = await import('./state-mutation.js');
|
|
91
|
+
expect(typeof mod.stateBeginPhase).toBe('function');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('exports stateAdvancePlan handler', async () => {
|
|
95
|
+
const mod = await import('./state-mutation.js');
|
|
96
|
+
expect(typeof mod.stateAdvancePlan).toBe('function');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('exports stateRecordMetric handler', async () => {
|
|
100
|
+
const mod = await import('./state-mutation.js');
|
|
101
|
+
expect(typeof mod.stateRecordMetric).toBe('function');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('exports stateUpdateProgress handler', async () => {
|
|
105
|
+
const mod = await import('./state-mutation.js');
|
|
106
|
+
expect(typeof mod.stateUpdateProgress).toBe('function');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('exports stateAddDecision handler', async () => {
|
|
110
|
+
const mod = await import('./state-mutation.js');
|
|
111
|
+
expect(typeof mod.stateAddDecision).toBe('function');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('exports stateAddBlocker handler', async () => {
|
|
115
|
+
const mod = await import('./state-mutation.js');
|
|
116
|
+
expect(typeof mod.stateAddBlocker).toBe('function');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('exports stateResolveBlocker handler', async () => {
|
|
120
|
+
const mod = await import('./state-mutation.js');
|
|
121
|
+
expect(typeof mod.stateResolveBlocker).toBe('function');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('exports stateRecordSession handler', async () => {
|
|
125
|
+
const mod = await import('./state-mutation.js');
|
|
126
|
+
expect(typeof mod.stateRecordSession).toBe('function');
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// ─── stateReplaceField ──────────────────────────────────────────────────────
|
|
131
|
+
|
|
132
|
+
describe('stateReplaceField', () => {
|
|
133
|
+
it('replaces bold format field', async () => {
|
|
134
|
+
const { stateReplaceField } = await import('./state-mutation.js');
|
|
135
|
+
const content = '**Status:** executing\n**Plan:** 1';
|
|
136
|
+
const result = stateReplaceField(content, 'Status', 'done');
|
|
137
|
+
expect(result).toContain('**Status:** done');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('replaces plain format field', async () => {
|
|
141
|
+
const { stateReplaceField } = await import('./state-mutation.js');
|
|
142
|
+
const content = 'Status: executing\nPlan: 1';
|
|
143
|
+
const result = stateReplaceField(content, 'Status', 'done');
|
|
144
|
+
expect(result).toContain('Status: done');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('returns null when field not found', async () => {
|
|
148
|
+
const { stateReplaceField } = await import('./state-mutation.js');
|
|
149
|
+
const result = stateReplaceField('no fields here', 'Missing', 'value');
|
|
150
|
+
expect(result).toBeNull();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('is case-insensitive', async () => {
|
|
154
|
+
const { stateReplaceField } = await import('./state-mutation.js');
|
|
155
|
+
const content = '**status:** executing';
|
|
156
|
+
const result = stateReplaceField(content, 'Status', 'done');
|
|
157
|
+
expect(result).toContain('done');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// ─── acquireStateLock / releaseStateLock ─────────────────────────────────────
|
|
162
|
+
|
|
163
|
+
describe('acquireStateLock / releaseStateLock', () => {
|
|
164
|
+
let tmpDir: string;
|
|
165
|
+
|
|
166
|
+
beforeEach(async () => {
|
|
167
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-lock-'));
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
afterEach(async () => {
|
|
171
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('creates and removes lockfile', async () => {
|
|
175
|
+
const { acquireStateLock, releaseStateLock } = await import('./state-mutation.js');
|
|
176
|
+
const statePath = join(tmpDir, 'STATE.md');
|
|
177
|
+
await writeFile(statePath, 'test', 'utf-8');
|
|
178
|
+
|
|
179
|
+
const lockPath = await acquireStateLock(statePath);
|
|
180
|
+
expect(existsSync(lockPath)).toBe(true);
|
|
181
|
+
|
|
182
|
+
await releaseStateLock(lockPath);
|
|
183
|
+
expect(existsSync(lockPath)).toBe(false);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('tracks lockPath in _heldStateLocks on acquire and removes on release', async () => {
|
|
187
|
+
const { acquireStateLock, releaseStateLock, _heldStateLocks } = await import('./state-mutation.js');
|
|
188
|
+
const statePath = join(tmpDir, 'STATE.md');
|
|
189
|
+
await writeFile(statePath, 'test', 'utf-8');
|
|
190
|
+
|
|
191
|
+
const lockPath = await acquireStateLock(statePath);
|
|
192
|
+
expect(_heldStateLocks.has(lockPath)).toBe(true);
|
|
193
|
+
|
|
194
|
+
await releaseStateLock(lockPath);
|
|
195
|
+
expect(_heldStateLocks.has(lockPath)).toBe(false);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('returns lockPath on non-EEXIST errors instead of throwing', async () => {
|
|
199
|
+
// Simulate a non-EEXIST error by using a path in a non-existent directory
|
|
200
|
+
// This triggers ENOENT (not EEXIST), which should return lockPath gracefully
|
|
201
|
+
const { acquireStateLock } = await import('./state-mutation.js');
|
|
202
|
+
const badPath = join(tmpDir, 'nonexistent-dir', 'subdir', 'STATE.md');
|
|
203
|
+
|
|
204
|
+
// Should NOT throw — should return lockPath gracefully
|
|
205
|
+
const lockPath = await acquireStateLock(badPath);
|
|
206
|
+
expect(lockPath).toBe(badPath + '.lock');
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// ─── stateUpdate ────────────────────────────────────────────────────────────
|
|
211
|
+
|
|
212
|
+
describe('stateUpdate', () => {
|
|
213
|
+
let tmpDir: string;
|
|
214
|
+
|
|
215
|
+
beforeEach(async () => {
|
|
216
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-state-update-'));
|
|
217
|
+
await setupTestProject(tmpDir);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
afterEach(async () => {
|
|
221
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('updates a single field and round-trips through stateLoad', async () => {
|
|
225
|
+
const { stateUpdate } = await import('./state-mutation.js');
|
|
226
|
+
const { stateJson } = await import('./state.js');
|
|
227
|
+
|
|
228
|
+
const result = await stateUpdate(['Status', 'Phase complete'], tmpDir);
|
|
229
|
+
const data = result.data as Record<string, unknown>;
|
|
230
|
+
expect(data.updated).toBe(true);
|
|
231
|
+
|
|
232
|
+
// Verify round-trip
|
|
233
|
+
const loaded = await stateJson([], tmpDir);
|
|
234
|
+
const loadedData = loaded.data as Record<string, unknown>;
|
|
235
|
+
// Status gets normalized by buildStateFrontmatter
|
|
236
|
+
expect(loadedData.status).toBeTruthy();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('returns updated false when field not found', async () => {
|
|
240
|
+
const { stateUpdate } = await import('./state-mutation.js');
|
|
241
|
+
|
|
242
|
+
const result = await stateUpdate(['NonExistentField', 'value'], tmpDir);
|
|
243
|
+
const data = result.data as Record<string, unknown>;
|
|
244
|
+
expect(data.updated).toBe(false);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('throws on missing args', async () => {
|
|
248
|
+
const { stateUpdate } = await import('./state-mutation.js');
|
|
249
|
+
|
|
250
|
+
await expect(stateUpdate([], tmpDir)).rejects.toThrow(/field and value required/);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// ─── statePatch ─────────────────────────────────────────────────────────────
|
|
255
|
+
|
|
256
|
+
describe('statePatch', () => {
|
|
257
|
+
let tmpDir: string;
|
|
258
|
+
|
|
259
|
+
beforeEach(async () => {
|
|
260
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-state-patch-'));
|
|
261
|
+
await setupTestProject(tmpDir);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
afterEach(async () => {
|
|
265
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('updates multiple fields in one lock cycle', async () => {
|
|
269
|
+
const { statePatch } = await import('./state-mutation.js');
|
|
270
|
+
|
|
271
|
+
const patches = JSON.stringify({ Status: 'done', Progress: '100%' });
|
|
272
|
+
const result = await statePatch([patches], tmpDir);
|
|
273
|
+
const data = result.data as Record<string, unknown>;
|
|
274
|
+
expect((data.updated as string[]).length).toBeGreaterThan(0);
|
|
275
|
+
|
|
276
|
+
// Verify file was updated
|
|
277
|
+
const content = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
278
|
+
expect(content).toContain('done');
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// ─── stateBeginPhase ────────────────────────────────────────────────────────
|
|
283
|
+
|
|
284
|
+
describe('stateBeginPhase', () => {
|
|
285
|
+
let tmpDir: string;
|
|
286
|
+
|
|
287
|
+
beforeEach(async () => {
|
|
288
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-state-begin-'));
|
|
289
|
+
await setupTestProject(tmpDir);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
afterEach(async () => {
|
|
293
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('sets all expected fields', async () => {
|
|
297
|
+
const { stateBeginPhase } = await import('./state-mutation.js');
|
|
298
|
+
|
|
299
|
+
const result = await stateBeginPhase(['11', 'State Mutations', '3'], tmpDir);
|
|
300
|
+
const data = result.data as Record<string, unknown>;
|
|
301
|
+
expect(data.phase).toBe('11');
|
|
302
|
+
|
|
303
|
+
const content = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
304
|
+
expect(content).toContain('Executing Phase 11');
|
|
305
|
+
expect(content).toContain('State Mutations');
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// ─── Bug #2420: flag-form args not parsed ────────────────────────────
|
|
309
|
+
it('bug-2420: parses --phase/--name/--plans flag-form args correctly', async () => {
|
|
310
|
+
const { stateBeginPhase } = await import('./state-mutation.js');
|
|
311
|
+
|
|
312
|
+
// This is how execute-phase.md calls it: flag form
|
|
313
|
+
const result = await stateBeginPhase(
|
|
314
|
+
['--phase', '99', '--name', 'probe-test', '--plans', '1'],
|
|
315
|
+
tmpDir
|
|
316
|
+
);
|
|
317
|
+
const data = result.data as Record<string, unknown>;
|
|
318
|
+
|
|
319
|
+
// Must return the actual values, not the flag names
|
|
320
|
+
expect(data.phase).toBe('99');
|
|
321
|
+
expect(data.name).toBe('probe-test');
|
|
322
|
+
expect(data.plan_count).toBe(1);
|
|
323
|
+
|
|
324
|
+
// STATE.md must contain clean output, not literal "--phase"
|
|
325
|
+
const content = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
326
|
+
expect(content).not.toContain('--phase');
|
|
327
|
+
expect(content).not.toContain('--name');
|
|
328
|
+
expect(content).not.toContain('--plans');
|
|
329
|
+
expect(content).toContain('Executing Phase 99');
|
|
330
|
+
expect(content).toContain('probe-test');
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it('bug-2420: positional args still work after flag-parsing fix', async () => {
|
|
334
|
+
const { stateBeginPhase } = await import('./state-mutation.js');
|
|
335
|
+
|
|
336
|
+
const result = await stateBeginPhase(['42', 'Positional Test', '5'], tmpDir);
|
|
337
|
+
const data = result.data as Record<string, unknown>;
|
|
338
|
+
expect(data.phase).toBe('42');
|
|
339
|
+
expect(data.name).toBe('Positional Test');
|
|
340
|
+
expect(data.plan_count).toBe(5);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('bug-2420: flag parser throws when a flag value is missing (next token is a flag)', async () => {
|
|
344
|
+
const { stateBeginPhase } = await import('./state-mutation.js');
|
|
345
|
+
|
|
346
|
+
// --phase has no value — next token is --name, which is itself a flag.
|
|
347
|
+
await expect(
|
|
348
|
+
stateBeginPhase(['--phase', '--name', 'Title', '--plans', '1'], tmpDir)
|
|
349
|
+
).rejects.toThrow('missing value for --phase');
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it('does not treat argv after named flags as positional name/plans', async () => {
|
|
353
|
+
const { stateBeginPhase } = await import('./state-mutation.js');
|
|
354
|
+
|
|
355
|
+
const result = await stateBeginPhase(['--phase', '2', '--plans', '3'], tmpDir);
|
|
356
|
+
const data = result.data as Record<string, unknown>;
|
|
357
|
+
expect(data.phase).toBe('2');
|
|
358
|
+
expect(data.phase_name).toBeFalsy();
|
|
359
|
+
expect(data.plan_count).toBe(3);
|
|
360
|
+
|
|
361
|
+
const content = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
362
|
+
expect(content).toContain('Plan: 1 of 3');
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// ─── stateAdvancePlan ───────────────────────────────────────────────────────
|
|
367
|
+
|
|
368
|
+
describe('stateAdvancePlan', () => {
|
|
369
|
+
let tmpDir: string;
|
|
370
|
+
|
|
371
|
+
beforeEach(async () => {
|
|
372
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-state-advance-'));
|
|
373
|
+
await setupTestProject(tmpDir);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
afterEach(async () => {
|
|
377
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('increments plan counter', async () => {
|
|
381
|
+
const { stateAdvancePlan } = await import('./state-mutation.js');
|
|
382
|
+
|
|
383
|
+
const result = await stateAdvancePlan([], tmpDir);
|
|
384
|
+
const data = result.data as Record<string, unknown>;
|
|
385
|
+
expect(data.advanced).toBe(true);
|
|
386
|
+
expect(data.current_plan).toBe(3);
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// ─── stateAddDecision ───────────────────────────────────────────────────────
|
|
391
|
+
|
|
392
|
+
describe('stateAddDecision', () => {
|
|
393
|
+
let tmpDir: string;
|
|
394
|
+
|
|
395
|
+
beforeEach(async () => {
|
|
396
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-state-decision-'));
|
|
397
|
+
await setupTestProject(tmpDir);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
afterEach(async () => {
|
|
401
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it('appends decision and removes placeholder', async () => {
|
|
405
|
+
const { stateAddDecision } = await import('./state-mutation.js');
|
|
406
|
+
|
|
407
|
+
const result = await stateAddDecision(
|
|
408
|
+
['--phase', '10', '--summary', 'Use lockfile atomicity'],
|
|
409
|
+
tmpDir,
|
|
410
|
+
);
|
|
411
|
+
const data = result.data as Record<string, unknown>;
|
|
412
|
+
expect(data.added).toBe(true);
|
|
413
|
+
|
|
414
|
+
const content = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
415
|
+
expect(content).toContain('Use lockfile atomicity');
|
|
416
|
+
// Verify "None yet." was removed from the Decisions section specifically
|
|
417
|
+
const decisionsMatch = content.match(/###?\s*Decisions\s*\n([\s\S]*?)(?=\n###?|\n##[^#]|$)/i);
|
|
418
|
+
expect(decisionsMatch).not.toBeNull();
|
|
419
|
+
expect(decisionsMatch![1]).not.toContain('None yet.');
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
// ─── stateRecordSession ─────────────────────────────────────────────────────
|
|
424
|
+
|
|
425
|
+
describe('stateRecordSession', () => {
|
|
426
|
+
let tmpDir: string;
|
|
427
|
+
|
|
428
|
+
beforeEach(async () => {
|
|
429
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-state-session-'));
|
|
430
|
+
await setupTestProject(tmpDir);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
afterEach(async () => {
|
|
434
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
it('updates session fields', async () => {
|
|
438
|
+
const { stateRecordSession } = await import('./state-mutation.js');
|
|
439
|
+
|
|
440
|
+
const result = await stateRecordSession(
|
|
441
|
+
['--stopped-at', 'Completed 11-01-PLAN.md', '--resume-file', 'None'],
|
|
442
|
+
tmpDir,
|
|
443
|
+
);
|
|
444
|
+
const data = result.data as Record<string, unknown>;
|
|
445
|
+
expect(data.recorded).toBe(true);
|
|
446
|
+
|
|
447
|
+
const content = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
448
|
+
expect(content).toContain('Completed 11-01-PLAN.md');
|
|
449
|
+
});
|
|
450
|
+
});
|