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,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract test: all headless prompt files in sdk/prompts/ must contain
|
|
3
|
+
* zero instances of blocked interactive patterns.
|
|
4
|
+
*
|
|
5
|
+
* This prevents regression — any new prompt file or edit that reintroduces
|
|
6
|
+
* interactive mechanics will fail this test.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from 'vitest';
|
|
9
|
+
import { readFile } from 'node:fs/promises';
|
|
10
|
+
import { join, dirname } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { readdirSync } from 'node:fs';
|
|
13
|
+
|
|
14
|
+
// ─── Paths ───────────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const promptsDir = join(__dirname, '..', 'prompts');
|
|
18
|
+
const workflowsDir = join(promptsDir, 'workflows');
|
|
19
|
+
const agentsDir = join(promptsDir, 'agents');
|
|
20
|
+
|
|
21
|
+
// ─── Blocked patterns ────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Patterns that MUST NOT appear in headless prompts.
|
|
25
|
+
* Each entry: [label for reporting, regex].
|
|
26
|
+
*/
|
|
27
|
+
const BLOCKED_PATTERNS: Array<[string, RegExp]> = [
|
|
28
|
+
['AskUserQuestion', /AskUserQuestion\s*\(/],
|
|
29
|
+
['SlashCommand', /SlashCommand\s*\(/],
|
|
30
|
+
['/gsd: command', /\/gsd:\S+/],
|
|
31
|
+
['@file: reference', /@file:\S+/],
|
|
32
|
+
['STOP + wait directive', /\bSTOP\b\s+(?:and\s+)?(?:wait|ask)/i],
|
|
33
|
+
['bare STOP directive', /^\s*STOP\s*[.!]?\s*$/m],
|
|
34
|
+
['wait for user', /\bwait\s+for\s+(?:the\s+)?user\b/i],
|
|
35
|
+
['ask the user', /\bask\s+the\s+user\b/i],
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
// ─── Expected files ──────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
const EXPECTED_WORKFLOWS = [
|
|
41
|
+
'execute-plan.md',
|
|
42
|
+
'research-phase.md',
|
|
43
|
+
'plan-phase.md',
|
|
44
|
+
'verify-phase.md',
|
|
45
|
+
'discuss-phase.md',
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const EXPECTED_AGENTS = [
|
|
49
|
+
'gsd-executor.md',
|
|
50
|
+
'gsd-phase-researcher.md',
|
|
51
|
+
'gsd-planner.md',
|
|
52
|
+
'gsd-verifier.md',
|
|
53
|
+
'gsd-plan-checker.md',
|
|
54
|
+
'gsd-project-researcher.md',
|
|
55
|
+
'gsd-research-synthesizer.md',
|
|
56
|
+
'gsd-roadmapper.md',
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const templatesDir = join(promptsDir, 'templates');
|
|
60
|
+
const researchTemplatesDir = join(templatesDir, 'research-project');
|
|
61
|
+
|
|
62
|
+
const EXPECTED_TEMPLATES = [
|
|
63
|
+
'project.md',
|
|
64
|
+
'requirements.md',
|
|
65
|
+
'roadmap.md',
|
|
66
|
+
'state.md',
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const EXPECTED_RESEARCH_TEMPLATES = [
|
|
70
|
+
'ARCHITECTURE.md',
|
|
71
|
+
'FEATURES.md',
|
|
72
|
+
'PITFALLS.md',
|
|
73
|
+
'STACK.md',
|
|
74
|
+
'SUMMARY.md',
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
// ─── Tests ───────────────────────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
describe('headless prompt contract', () => {
|
|
80
|
+
describe('file inventory', () => {
|
|
81
|
+
it('has all expected workflow files', () => {
|
|
82
|
+
const actual = readdirSync(workflowsDir).sort();
|
|
83
|
+
expect(actual).toEqual(EXPECTED_WORKFLOWS.sort());
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('has all expected agent files', () => {
|
|
87
|
+
const actual = readdirSync(agentsDir).sort();
|
|
88
|
+
expect(actual).toEqual(EXPECTED_AGENTS.sort());
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('zero interactive patterns in workflow prompts', () => {
|
|
93
|
+
for (const filename of EXPECTED_WORKFLOWS) {
|
|
94
|
+
describe(filename, () => {
|
|
95
|
+
for (const [label, pattern] of BLOCKED_PATTERNS) {
|
|
96
|
+
it(`contains no ${label}`, async () => {
|
|
97
|
+
const content = await readFile(join(workflowsDir, filename), 'utf-8');
|
|
98
|
+
const matches = content.match(new RegExp(pattern.source, pattern.flags + 'g'));
|
|
99
|
+
expect(matches, `Found ${label} in ${filename}: ${matches?.join(', ')}`).toBeNull();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('zero interactive patterns in agent prompts', () => {
|
|
107
|
+
for (const filename of EXPECTED_AGENTS) {
|
|
108
|
+
describe(filename, () => {
|
|
109
|
+
for (const [label, pattern] of BLOCKED_PATTERNS) {
|
|
110
|
+
it(`contains no ${label}`, async () => {
|
|
111
|
+
const content = await readFile(join(agentsDir, filename), 'utf-8');
|
|
112
|
+
const matches = content.match(new RegExp(pattern.source, pattern.flags + 'g'));
|
|
113
|
+
expect(matches, `Found ${label} in ${filename}: ${matches?.join(', ')}`).toBeNull();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('template file inventory', () => {
|
|
121
|
+
it('has all expected top-level template files', () => {
|
|
122
|
+
const actual = readdirSync(templatesDir).filter(f => f.endsWith('.md')).sort();
|
|
123
|
+
expect(actual).toEqual(EXPECTED_TEMPLATES.sort());
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('has all expected research-project template files', () => {
|
|
127
|
+
const actual = readdirSync(researchTemplatesDir).sort();
|
|
128
|
+
expect(actual).toEqual(EXPECTED_RESEARCH_TEMPLATES.sort());
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('zero interactive patterns in template prompts', () => {
|
|
133
|
+
for (const filename of EXPECTED_TEMPLATES) {
|
|
134
|
+
describe(filename, () => {
|
|
135
|
+
for (const [label, pattern] of BLOCKED_PATTERNS) {
|
|
136
|
+
it(`contains no ${label}`, async () => {
|
|
137
|
+
const content = await readFile(join(templatesDir, filename), 'utf-8');
|
|
138
|
+
const matches = content.match(new RegExp(pattern.source, pattern.flags + 'g'));
|
|
139
|
+
expect(matches, `Found ${label} in ${filename}: ${matches?.join(', ')}`).toBeNull();
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('zero interactive patterns in research-project templates', () => {
|
|
147
|
+
for (const filename of EXPECTED_RESEARCH_TEMPLATES) {
|
|
148
|
+
describe(filename, () => {
|
|
149
|
+
for (const [label, pattern] of BLOCKED_PATTERNS) {
|
|
150
|
+
it(`contains no ${label}`, async () => {
|
|
151
|
+
const content = await readFile(join(researchTemplatesDir, filename), 'utf-8');
|
|
152
|
+
const matches = content.match(new RegExp(pattern.source, pattern.flags + 'g'));
|
|
153
|
+
expect(matches, `Found ${label} in ${filename}: ${matches?.join(', ')}`).toBeNull();
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
package/sdk/src/index.ts
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD SDK — Public API for running GSD plans programmatically.
|
|
3
|
+
*
|
|
4
|
+
* The GSD class composes plan parsing, config loading, prompt building,
|
|
5
|
+
* and session running into a single `executePlan()` call.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { GSD } from '@gsd-remix/sdk';
|
|
10
|
+
*
|
|
11
|
+
* const gsd = new GSD({ projectDir: '/path/to/project' });
|
|
12
|
+
* const result = await gsd.executePlan('.planning/phases/01-auth/01-auth-01-PLAN.md');
|
|
13
|
+
*
|
|
14
|
+
* if (result.success) {
|
|
15
|
+
* console.log(`Plan completed in ${result.durationMs}ms, cost: $${result.totalCostUsd}`);
|
|
16
|
+
* } else {
|
|
17
|
+
* console.error(`Plan failed: ${result.error?.messages.join(', ')}`);
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { readFile } from 'node:fs/promises';
|
|
23
|
+
import { join, resolve } from 'node:path';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
|
|
26
|
+
import type { GSDOptions, PlanResult, SessionOptions, GSDEvent, TransportHandler, PhaseRunnerOptions, PhaseRunnerResult, MilestoneRunnerOptions, MilestoneRunnerResult, RoadmapPhaseInfo } from './types.js';
|
|
27
|
+
import { GSDEventType } from './types.js';
|
|
28
|
+
import { parsePlan, parsePlanFile } from './plan-parser.js';
|
|
29
|
+
import { loadConfig } from './config.js';
|
|
30
|
+
import { GSDTools, resolveGsdToolsPath } from './gsd-tools.js';
|
|
31
|
+
import { runPlanSession } from './session-runner.js';
|
|
32
|
+
import { buildExecutorPrompt, parseAgentTools } from './prompt-builder.js';
|
|
33
|
+
import { GSDEventStream } from './event-stream.js';
|
|
34
|
+
import { PhaseRunner } from './phase-runner.js';
|
|
35
|
+
import { ContextEngine } from './context-engine.js';
|
|
36
|
+
import { PromptFactory } from './phase-prompt.js';
|
|
37
|
+
|
|
38
|
+
// ─── GSD class ───────────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
export class GSD {
|
|
41
|
+
private readonly projectDir: string;
|
|
42
|
+
private readonly gsdToolsPath: string;
|
|
43
|
+
private readonly sessionId?: string;
|
|
44
|
+
private readonly defaultModel?: string;
|
|
45
|
+
private readonly defaultMaxBudgetUsd: number;
|
|
46
|
+
private readonly defaultMaxTurns: number;
|
|
47
|
+
private readonly autoMode: boolean;
|
|
48
|
+
private readonly workstream?: string;
|
|
49
|
+
readonly eventStream: GSDEventStream;
|
|
50
|
+
|
|
51
|
+
constructor(options: GSDOptions) {
|
|
52
|
+
this.projectDir = resolve(options.projectDir);
|
|
53
|
+
this.gsdToolsPath =
|
|
54
|
+
options.gsdToolsPath ?? resolveGsdToolsPath(this.projectDir);
|
|
55
|
+
this.sessionId = options.sessionId;
|
|
56
|
+
this.defaultModel = options.model;
|
|
57
|
+
this.defaultMaxBudgetUsd = options.maxBudgetUsd ?? 5.0;
|
|
58
|
+
this.defaultMaxTurns = options.maxTurns ?? 50;
|
|
59
|
+
this.autoMode = options.autoMode ?? false;
|
|
60
|
+
this.workstream = options.workstream;
|
|
61
|
+
this.eventStream = new GSDEventStream();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Execute a single GSD plan file.
|
|
66
|
+
*
|
|
67
|
+
* Reads the plan from disk, parses it, loads project config,
|
|
68
|
+
* optionally reads the agent definition, then runs a query() session.
|
|
69
|
+
*
|
|
70
|
+
* @param planPath - Path to the PLAN.md file (absolute or relative to projectDir)
|
|
71
|
+
* @param options - Per-execution overrides
|
|
72
|
+
* @returns PlanResult with cost, duration, success/error status
|
|
73
|
+
*/
|
|
74
|
+
async executePlan(planPath: string, options?: SessionOptions): Promise<PlanResult> {
|
|
75
|
+
// Resolve plan path relative to project dir
|
|
76
|
+
const absolutePlanPath = resolve(this.projectDir, planPath);
|
|
77
|
+
|
|
78
|
+
// Parse the plan
|
|
79
|
+
const plan = await parsePlanFile(absolutePlanPath);
|
|
80
|
+
|
|
81
|
+
// Load project config
|
|
82
|
+
const config = await loadConfig(this.projectDir, this.workstream);
|
|
83
|
+
|
|
84
|
+
// Try to load agent definition for tool restrictions
|
|
85
|
+
const agentDef = await this.loadAgentDefinition();
|
|
86
|
+
|
|
87
|
+
// Merge defaults with per-call options
|
|
88
|
+
const sessionOptions: SessionOptions = {
|
|
89
|
+
maxTurns: options?.maxTurns ?? this.defaultMaxTurns,
|
|
90
|
+
maxBudgetUsd: options?.maxBudgetUsd ?? this.defaultMaxBudgetUsd,
|
|
91
|
+
model: options?.model ?? this.defaultModel,
|
|
92
|
+
cwd: options?.cwd ?? this.projectDir,
|
|
93
|
+
allowedTools: options?.allowedTools,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return runPlanSession(plan, config, sessionOptions, agentDef, this.eventStream, {
|
|
97
|
+
phase: undefined, // Phase context set by higher-level orchestrators
|
|
98
|
+
planName: plan.frontmatter.plan,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Subscribe a simple handler to receive all GSD events.
|
|
104
|
+
*/
|
|
105
|
+
onEvent(handler: (event: GSDEvent) => void): void {
|
|
106
|
+
this.eventStream.on('event', handler);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Subscribe a transport handler to receive all GSD events.
|
|
111
|
+
* Transports provide structured onEvent/close lifecycle.
|
|
112
|
+
*/
|
|
113
|
+
addTransport(handler: TransportHandler): void {
|
|
114
|
+
this.eventStream.addTransport(handler);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Create a GSDTools instance for state management operations.
|
|
119
|
+
*/
|
|
120
|
+
createTools(): GSDTools {
|
|
121
|
+
return new GSDTools({
|
|
122
|
+
projectDir: this.projectDir,
|
|
123
|
+
gsdToolsPath: this.gsdToolsPath,
|
|
124
|
+
workstream: this.workstream,
|
|
125
|
+
eventStream: this.eventStream,
|
|
126
|
+
sessionId: this.sessionId,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Run a full phase lifecycle: discuss → research → plan → execute → verify → advance.
|
|
132
|
+
*
|
|
133
|
+
* Creates the necessary collaborators (GSDTools, PromptFactory, ContextEngine),
|
|
134
|
+
* loads project config, instantiates a PhaseRunner, and delegates to `runner.run()`.
|
|
135
|
+
*
|
|
136
|
+
* @param phaseNumber - The phase number to execute (e.g. "01", "02")
|
|
137
|
+
* @param options - Per-phase overrides for budget, turns, model, and callbacks
|
|
138
|
+
* @returns PhaseRunnerResult with per-step results, overall success, cost, and timing
|
|
139
|
+
*/
|
|
140
|
+
async runPhase(phaseNumber: string, options?: PhaseRunnerOptions): Promise<PhaseRunnerResult> {
|
|
141
|
+
const tools = this.createTools();
|
|
142
|
+
const promptFactory = new PromptFactory();
|
|
143
|
+
const contextEngine = new ContextEngine(this.projectDir, undefined, undefined, this.workstream);
|
|
144
|
+
const config = await loadConfig(this.projectDir, this.workstream);
|
|
145
|
+
|
|
146
|
+
// Auto mode: force auto_advance on and skip_discuss off so self-discuss kicks in
|
|
147
|
+
if (this.autoMode) {
|
|
148
|
+
config.workflow.auto_advance = true;
|
|
149
|
+
config.workflow.skip_discuss = false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const runner = new PhaseRunner({
|
|
153
|
+
projectDir: this.projectDir,
|
|
154
|
+
tools,
|
|
155
|
+
promptFactory,
|
|
156
|
+
contextEngine,
|
|
157
|
+
eventStream: this.eventStream,
|
|
158
|
+
config,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return runner.run(phaseNumber, options);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Run a full milestone: discover phases, execute each incomplete one in order,
|
|
166
|
+
* re-discover after each completion to catch dynamically inserted phases.
|
|
167
|
+
*
|
|
168
|
+
* @param prompt - The user prompt describing the milestone goal
|
|
169
|
+
* @param options - Per-milestone overrides for budget, turns, model, and callbacks
|
|
170
|
+
* @returns MilestoneRunnerResult with per-phase results, overall success, cost, and timing
|
|
171
|
+
*/
|
|
172
|
+
async run(prompt: string, options?: MilestoneRunnerOptions): Promise<MilestoneRunnerResult> {
|
|
173
|
+
const tools = this.createTools();
|
|
174
|
+
const startTime = Date.now();
|
|
175
|
+
const phaseResults: PhaseRunnerResult[] = [];
|
|
176
|
+
let success = true;
|
|
177
|
+
|
|
178
|
+
// Discover initial phases
|
|
179
|
+
const initialAnalysis = await tools.roadmapAnalyze();
|
|
180
|
+
const incompletePhases = this.filterAndSortPhases(initialAnalysis.phases);
|
|
181
|
+
|
|
182
|
+
// Emit MilestoneStart
|
|
183
|
+
this.eventStream.emitEvent({
|
|
184
|
+
type: GSDEventType.MilestoneStart,
|
|
185
|
+
timestamp: new Date().toISOString(),
|
|
186
|
+
sessionId: `milestone-${Date.now()}`,
|
|
187
|
+
phaseCount: incompletePhases.length,
|
|
188
|
+
prompt,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Loop through phases, re-discovering after each completion
|
|
192
|
+
let currentPhases = incompletePhases;
|
|
193
|
+
|
|
194
|
+
while (currentPhases.length > 0) {
|
|
195
|
+
const phase = currentPhases[0];
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
const result = await this.runPhase(phase.number, options);
|
|
199
|
+
phaseResults.push(result);
|
|
200
|
+
|
|
201
|
+
if (!result.success) {
|
|
202
|
+
success = false;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Notify callback if present; stop if requested
|
|
207
|
+
if (options?.onPhaseComplete) {
|
|
208
|
+
const verdict = await options.onPhaseComplete(result, phase);
|
|
209
|
+
if (verdict === 'stop') {
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Re-discover phases to catch dynamically inserted ones
|
|
215
|
+
const updatedAnalysis = await tools.roadmapAnalyze();
|
|
216
|
+
currentPhases = this.filterAndSortPhases(updatedAnalysis.phases);
|
|
217
|
+
} catch (err) {
|
|
218
|
+
// Phase threw an unexpected error — record as failure and stop
|
|
219
|
+
phaseResults.push({
|
|
220
|
+
phaseNumber: phase.number,
|
|
221
|
+
phaseName: phase.phase_name,
|
|
222
|
+
steps: [],
|
|
223
|
+
success: false,
|
|
224
|
+
totalCostUsd: 0,
|
|
225
|
+
totalDurationMs: 0,
|
|
226
|
+
});
|
|
227
|
+
success = false;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const totalCostUsd = phaseResults.reduce((sum, r) => sum + r.totalCostUsd, 0);
|
|
233
|
+
const totalDurationMs = Date.now() - startTime;
|
|
234
|
+
|
|
235
|
+
// Emit MilestoneComplete
|
|
236
|
+
this.eventStream.emitEvent({
|
|
237
|
+
type: GSDEventType.MilestoneComplete,
|
|
238
|
+
timestamp: new Date().toISOString(),
|
|
239
|
+
sessionId: `milestone-${Date.now()}`,
|
|
240
|
+
success,
|
|
241
|
+
totalCostUsd,
|
|
242
|
+
totalDurationMs,
|
|
243
|
+
phasesCompleted: phaseResults.filter(r => r.success).length,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
success,
|
|
248
|
+
phases: phaseResults,
|
|
249
|
+
totalCostUsd,
|
|
250
|
+
totalDurationMs,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Filter to incomplete phases and sort numerically.
|
|
256
|
+
* Uses parseFloat to handle decimal phase numbers (e.g. '5.1').
|
|
257
|
+
*/
|
|
258
|
+
private filterAndSortPhases(phases: RoadmapPhaseInfo[]): RoadmapPhaseInfo[] {
|
|
259
|
+
return phases
|
|
260
|
+
.filter(p => !p.roadmap_complete)
|
|
261
|
+
.sort((a, b) => parseFloat(a.number) - parseFloat(b.number));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Load the gsd-executor agent definition if available.
|
|
266
|
+
* Falls back gracefully — returns undefined if not found.
|
|
267
|
+
*/
|
|
268
|
+
private async loadAgentDefinition(): Promise<string | undefined> {
|
|
269
|
+
const paths = [
|
|
270
|
+
// Repo-local GSD installation
|
|
271
|
+
join(this.projectDir, '.claude', 'get-shit-done', 'agents', 'gsd-executor.md'),
|
|
272
|
+
// Repo-local agents directory
|
|
273
|
+
join(this.projectDir, '.claude', 'agents', 'gsd-executor.md'),
|
|
274
|
+
// Global home directory
|
|
275
|
+
join(homedir(), '.claude', 'agents', 'gsd-executor.md'),
|
|
276
|
+
join(this.projectDir, 'agents', 'gsd-executor.md'),
|
|
277
|
+
];
|
|
278
|
+
|
|
279
|
+
for (const p of paths) {
|
|
280
|
+
try {
|
|
281
|
+
return await readFile(p, 'utf-8');
|
|
282
|
+
} catch {
|
|
283
|
+
// Not found at this path, try next
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ─── Re-exports for advanced usage ──────────────────────────────────────────
|
|
292
|
+
|
|
293
|
+
export { parsePlan, parsePlanFile } from './plan-parser.js';
|
|
294
|
+
export { loadConfig } from './config.js';
|
|
295
|
+
export type { GSDConfig } from './config.js';
|
|
296
|
+
export { GSDTools, GSDToolsError, resolveGsdToolsPath } from './gsd-tools.js';
|
|
297
|
+
export { runPlanSession, runPhaseStepSession } from './session-runner.js';
|
|
298
|
+
export { buildExecutorPrompt, parseAgentTools } from './prompt-builder.js';
|
|
299
|
+
export * from './types.js';
|
|
300
|
+
|
|
301
|
+
// S02: Event stream, context, prompt, and logging modules
|
|
302
|
+
export { GSDEventStream } from './event-stream.js';
|
|
303
|
+
export type { EventStreamContext } from './event-stream.js';
|
|
304
|
+
export { ContextEngine, PHASE_FILE_MANIFEST } from './context-engine.js';
|
|
305
|
+
export type { FileSpec } from './context-engine.js';
|
|
306
|
+
export { truncateMarkdown, extractCurrentMilestone, DEFAULT_TRUNCATION_OPTIONS } from './context-truncation.js';
|
|
307
|
+
export type { TruncationOptions } from './context-truncation.js';
|
|
308
|
+
export { getToolsForPhase, PHASE_AGENT_MAP, PHASE_DEFAULT_TOOLS } from './tool-scoping.js';
|
|
309
|
+
export { checkResearchGate } from './research-gate.js';
|
|
310
|
+
export type { ResearchGateResult } from './research-gate.js';
|
|
311
|
+
export { PromptFactory, extractBlock, extractSteps, PHASE_WORKFLOW_MAP } from './phase-prompt.js';
|
|
312
|
+
export { GSDLogger } from './logger.js';
|
|
313
|
+
export type { LogLevel, LogEntry, GSDLoggerOptions } from './logger.js';
|
|
314
|
+
|
|
315
|
+
// S03: Phase lifecycle state machine
|
|
316
|
+
export { PhaseRunner, PhaseRunnerError } from './phase-runner.js';
|
|
317
|
+
export type { PhaseRunnerDeps, VerificationOutcome } from './phase-runner.js';
|
|
318
|
+
|
|
319
|
+
// S05: Transports
|
|
320
|
+
export { CLITransport } from './cli-transport.js';
|
|
321
|
+
export { WSTransport } from './ws-transport.js';
|
|
322
|
+
export type { WSTransportOptions } from './ws-transport.js';
|
|
323
|
+
|
|
324
|
+
// Query registry argv normalization (matches `gsd-remix-sdk query` and `GSDTools` hot path)
|
|
325
|
+
export { createRegistry, normalizeQueryCommand } from './query/index.js';
|
|
326
|
+
|
|
327
|
+
// Workstream utilities
|
|
328
|
+
export { validateWorkstreamName, relPlanningPath } from './workstream-utils.js';
|
|
329
|
+
|
|
330
|
+
// Init workflow
|
|
331
|
+
export { InitRunner } from './init-runner.js';
|
|
332
|
+
export type { InitRunnerDeps } from './init-runner.js';
|
|
333
|
+
export type { InitConfig, InitResult, InitStepResult, InitStepName } from './types.js';
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E integration test — proves InitRunner.run() drives real Agent SDK
|
|
3
|
+
* sessions for the gsd-remix-sdk init workflow.
|
|
4
|
+
*
|
|
5
|
+
* Requires Claude Code CLI (`claude`) installed and authenticated.
|
|
6
|
+
* Skips gracefully if CLI is unavailable.
|
|
7
|
+
*
|
|
8
|
+
* This test proves the headless init pipeline can bootstrap a real project
|
|
9
|
+
* without human intervention: setup → config → PROJECT.md → research →
|
|
10
|
+
* synthesis → requirements → roadmap.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
14
|
+
import { execSync } from 'node:child_process';
|
|
15
|
+
import { mkdtemp, rm, readFile, stat } from 'node:fs/promises';
|
|
16
|
+
import { existsSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { tmpdir } from 'node:os';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
|
|
21
|
+
import { InitRunner } from './init-runner.js';
|
|
22
|
+
import { GSDTools, resolveGsdToolsPath } from './gsd-tools.js';
|
|
23
|
+
import { GSDEventStream } from './event-stream.js';
|
|
24
|
+
import { GSDEventType } from './types.js';
|
|
25
|
+
import type { GSDEvent } from './types.js';
|
|
26
|
+
|
|
27
|
+
// ─── CLI availability check ─────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
let cliAvailable = false;
|
|
30
|
+
try {
|
|
31
|
+
execSync('which claude', { stdio: 'ignore' });
|
|
32
|
+
cliAvailable = true;
|
|
33
|
+
} catch {
|
|
34
|
+
cliAvailable = false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
38
|
+
const sdkPromptsDir = join(__dirname, '..', 'prompts');
|
|
39
|
+
const GSD_TOOLS_PATH = resolveGsdToolsPath(process.cwd());
|
|
40
|
+
const gsdToolsAvailable = existsSync(GSD_TOOLS_PATH);
|
|
41
|
+
|
|
42
|
+
// ─── Test suite ──────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
describe.skipIf(!cliAvailable || !gsdToolsAvailable)('E2E: InitRunner.run() full workflow', () => {
|
|
45
|
+
let tmpDir: string;
|
|
46
|
+
let events: GSDEvent[];
|
|
47
|
+
|
|
48
|
+
beforeAll(async () => {
|
|
49
|
+
tmpDir = await mkdtemp(join(tmpdir(), 'gsd-remix-sdk-init-e2e-'));
|
|
50
|
+
|
|
51
|
+
// Initialize git in the temp dir (required by InitRunner)
|
|
52
|
+
execSync('git init', { cwd: tmpDir, stdio: 'ignore' });
|
|
53
|
+
execSync('git config user.email "test@test.com"', { cwd: tmpDir, stdio: 'ignore' });
|
|
54
|
+
execSync('git config user.name "Test"', { cwd: tmpDir, stdio: 'ignore' });
|
|
55
|
+
}, 30_000);
|
|
56
|
+
|
|
57
|
+
afterAll(async () => {
|
|
58
|
+
if (tmpDir) {
|
|
59
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('InitRunner.run() bootstraps a project without human intervention', async () => {
|
|
64
|
+
events = [];
|
|
65
|
+
const eventStream = new GSDEventStream();
|
|
66
|
+
eventStream.on('event', (e: GSDEvent) => events.push(e));
|
|
67
|
+
|
|
68
|
+
const tools = new GSDTools({
|
|
69
|
+
projectDir: tmpDir,
|
|
70
|
+
gsdToolsPath: GSD_TOOLS_PATH,
|
|
71
|
+
timeoutMs: 30_000,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const runner = new InitRunner({
|
|
75
|
+
projectDir: tmpDir,
|
|
76
|
+
tools,
|
|
77
|
+
eventStream,
|
|
78
|
+
config: {
|
|
79
|
+
maxBudgetPerSession: 1.0,
|
|
80
|
+
maxTurnsPerSession: 15,
|
|
81
|
+
},
|
|
82
|
+
sdkPromptsDir,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const result = await runner.run('Build a CLI tool that prints hello world');
|
|
86
|
+
|
|
87
|
+
// ── Assert: pipeline executed (success OR at least 3+ steps completed) ──
|
|
88
|
+
const completedSteps = result.steps.filter(s => s.success);
|
|
89
|
+
const pipelineProgressed = result.success || completedSteps.length >= 3;
|
|
90
|
+
expect(pipelineProgressed).toBe(true);
|
|
91
|
+
|
|
92
|
+
// ── Assert: config.json artifact created ──
|
|
93
|
+
// config.json is written directly by InitRunner (not by Claude session)
|
|
94
|
+
// so it should always exist if the config step succeeded
|
|
95
|
+
const configStep = result.steps.find(s => s.step === 'config');
|
|
96
|
+
if (configStep?.success) {
|
|
97
|
+
const configPath = join(tmpDir, '.planning', 'config.json');
|
|
98
|
+
const configStat = await stat(configPath).catch(() => null);
|
|
99
|
+
expect(configStat).not.toBeNull();
|
|
100
|
+
|
|
101
|
+
if (configStat) {
|
|
102
|
+
const configContent = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
103
|
+
expect(configContent.workflow.auto_advance).toBe(true);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ── Assert: PROJECT.md created if project step succeeded ──
|
|
108
|
+
const projectStep = result.steps.find(s => s.step === 'project');
|
|
109
|
+
if (projectStep?.success) {
|
|
110
|
+
const projectPath = join(tmpDir, '.planning', 'PROJECT.md');
|
|
111
|
+
const projectStat = await stat(projectPath).catch(() => null);
|
|
112
|
+
expect(projectStat).not.toBeNull();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ── Assert: events captured include InitStart and at least one InitStepComplete ──
|
|
116
|
+
const initStartEvents = events.filter(e => e.type === GSDEventType.InitStart);
|
|
117
|
+
expect(initStartEvents.length).toBe(1);
|
|
118
|
+
|
|
119
|
+
const stepCompleteEvents = events.filter(e => e.type === GSDEventType.InitStepComplete);
|
|
120
|
+
expect(stepCompleteEvents.length).toBeGreaterThanOrEqual(1);
|
|
121
|
+
|
|
122
|
+
// ── Assert: InitComplete event emitted ──
|
|
123
|
+
const initCompleteEvents = events.filter(e => e.type === GSDEventType.InitComplete);
|
|
124
|
+
expect(initCompleteEvents.length).toBe(1);
|
|
125
|
+
|
|
126
|
+
// ── Assert: cost and duration are tracked ──
|
|
127
|
+
expect(result.totalDurationMs).toBeGreaterThan(0);
|
|
128
|
+
expect(typeof result.totalCostUsd).toBe('number');
|
|
129
|
+
|
|
130
|
+
// ── Assert: artifacts list is populated ──
|
|
131
|
+
if (result.success) {
|
|
132
|
+
expect(result.artifacts.length).toBeGreaterThan(0);
|
|
133
|
+
expect(result.artifacts).toContain('.planning/config.json');
|
|
134
|
+
}
|
|
135
|
+
}, 600_000); // 10 minute timeout for the full 7-session init workflow
|
|
136
|
+
});
|