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,595 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD Tools Bridge — programmatic access to GSD planning operations.
|
|
3
|
+
*
|
|
4
|
+
* By default routes commands through the SDK **query registry** (same handlers as
|
|
5
|
+
* `gsd-remix-sdk query`) so `PhaseRunner`, `InitRunner`, and `GSD` share contracts with
|
|
6
|
+
* the typed CLI. Runner hot-path helpers (`initPhaseOp`, `phasePlanIndex`,
|
|
7
|
+
* `phaseComplete`, `initNewProject`, `configSet`, `commit`) call
|
|
8
|
+
* `registry.dispatch()` with canonical keys when native query is active, avoiding
|
|
9
|
+
* repeated argv resolution. When a workstream is set, dispatches to `gsd-tools.cjs` so
|
|
10
|
+
* workstream env stays aligned with CJS.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { execFile } from 'node:child_process';
|
|
14
|
+
import { readFile } from 'node:fs/promises';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import type { InitNewProjectInfo, PhaseOpInfo, PhasePlanIndex, RoadmapAnalysis } from './types.js';
|
|
20
|
+
import type { GSDEventStream } from './event-stream.js';
|
|
21
|
+
import { GSDError, exitCodeFor } from './errors.js';
|
|
22
|
+
import { createRegistry } from './query/index.js';
|
|
23
|
+
import { resolveQueryArgv } from './query/registry.js';
|
|
24
|
+
import { normalizeQueryCommand } from './query/normalize-query-command.js';
|
|
25
|
+
import { formatStateLoadRawStdout } from './query/state-project-load.js';
|
|
26
|
+
|
|
27
|
+
// ─── Error type ──────────────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
export class GSDToolsError extends Error {
|
|
30
|
+
constructor(
|
|
31
|
+
message: string,
|
|
32
|
+
public readonly command: string,
|
|
33
|
+
public readonly args: string[],
|
|
34
|
+
public readonly exitCode: number | null,
|
|
35
|
+
public readonly stderr: string,
|
|
36
|
+
options?: { cause?: unknown },
|
|
37
|
+
) {
|
|
38
|
+
super(message, options);
|
|
39
|
+
this.name = 'GSDToolsError';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ─── GSDTools class ──────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
46
|
+
const BUNDLED_GSD_TOOLS_PATH = fileURLToPath(
|
|
47
|
+
new URL('../../get-shit-done/bin/gsd-tools.cjs', import.meta.url),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
function formatRegistryRawStdout(matchedCmd: string, data: unknown): string {
|
|
51
|
+
if (matchedCmd === 'state.load') {
|
|
52
|
+
return formatStateLoadRawStdout(data);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (matchedCmd === 'commit') {
|
|
56
|
+
const d = data as Record<string, unknown>;
|
|
57
|
+
if (d.committed === true) {
|
|
58
|
+
return d.hash != null ? String(d.hash) : 'committed';
|
|
59
|
+
}
|
|
60
|
+
if (d.committed === false) {
|
|
61
|
+
const r = String(d.reason ?? '');
|
|
62
|
+
if (
|
|
63
|
+
r.includes('commit_docs') ||
|
|
64
|
+
r.includes('skipped') ||
|
|
65
|
+
r.includes('gitignored') ||
|
|
66
|
+
r === 'skipped_commit_docs_false'
|
|
67
|
+
) {
|
|
68
|
+
return 'skipped';
|
|
69
|
+
}
|
|
70
|
+
if (r.includes('nothing') || r.includes('nothing_to_commit')) {
|
|
71
|
+
return 'nothing';
|
|
72
|
+
}
|
|
73
|
+
return r || 'nothing';
|
|
74
|
+
}
|
|
75
|
+
return JSON.stringify(data, null, 2);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (matchedCmd === 'config-set') {
|
|
79
|
+
const d = data as Record<string, unknown>;
|
|
80
|
+
if ((d.updated === true || d.set === true) && d.key !== undefined) {
|
|
81
|
+
const v = d.value;
|
|
82
|
+
if (v === null || v === undefined) {
|
|
83
|
+
return `${d.key}=`;
|
|
84
|
+
}
|
|
85
|
+
if (typeof v === 'object') {
|
|
86
|
+
return `${d.key}=${JSON.stringify(v)}`;
|
|
87
|
+
}
|
|
88
|
+
return `${d.key}=${String(v)}`;
|
|
89
|
+
}
|
|
90
|
+
return JSON.stringify(data, null, 2);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (matchedCmd === 'state.begin-phase' || matchedCmd === 'state begin-phase') {
|
|
94
|
+
const d = data as Record<string, unknown>;
|
|
95
|
+
const u = d.updated as string[] | undefined;
|
|
96
|
+
return Array.isArray(u) && u.length > 0 ? 'true' : 'false';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (typeof data === 'string') {
|
|
100
|
+
return data;
|
|
101
|
+
}
|
|
102
|
+
return JSON.stringify(data, null, 2);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export class GSDTools {
|
|
106
|
+
private readonly projectDir: string;
|
|
107
|
+
private readonly gsdToolsPath: string;
|
|
108
|
+
private readonly timeoutMs: number;
|
|
109
|
+
private readonly workstream?: string;
|
|
110
|
+
private readonly registry: ReturnType<typeof createRegistry>;
|
|
111
|
+
private readonly preferNativeQuery: boolean;
|
|
112
|
+
|
|
113
|
+
constructor(opts: {
|
|
114
|
+
projectDir: string;
|
|
115
|
+
gsdToolsPath?: string;
|
|
116
|
+
timeoutMs?: number;
|
|
117
|
+
workstream?: string;
|
|
118
|
+
/** When set, mutation handlers emit the same events as `gsd-remix-sdk query`. */
|
|
119
|
+
eventStream?: GSDEventStream;
|
|
120
|
+
/** Correlation id for mutation events when `eventStream` is set. */
|
|
121
|
+
sessionId?: string;
|
|
122
|
+
/**
|
|
123
|
+
* When true (default), route known commands through the SDK query registry.
|
|
124
|
+
* Set false in tests that substitute a mock `gsdToolsPath` script.
|
|
125
|
+
*/
|
|
126
|
+
preferNativeQuery?: boolean;
|
|
127
|
+
}) {
|
|
128
|
+
this.projectDir = opts.projectDir;
|
|
129
|
+
this.gsdToolsPath =
|
|
130
|
+
opts.gsdToolsPath ?? resolveGsdToolsPath(opts.projectDir);
|
|
131
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
132
|
+
this.workstream = opts.workstream;
|
|
133
|
+
this.preferNativeQuery = opts.preferNativeQuery ?? true;
|
|
134
|
+
this.registry = createRegistry(opts.eventStream, opts.sessionId);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private shouldUseNativeQuery(): boolean {
|
|
138
|
+
return this.preferNativeQuery && !this.workstream;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private nativeMatch(command: string, args: string[]) {
|
|
142
|
+
const [normCmd, normArgs] = normalizeQueryCommand(command, args);
|
|
143
|
+
const tokens = [normCmd, ...normArgs];
|
|
144
|
+
return resolveQueryArgv(tokens, this.registry);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private toToolsError(command: string, args: string[], err: unknown): GSDToolsError {
|
|
148
|
+
if (err instanceof GSDError) {
|
|
149
|
+
return new GSDToolsError(
|
|
150
|
+
err.message,
|
|
151
|
+
command,
|
|
152
|
+
args,
|
|
153
|
+
exitCodeFor(err.classification),
|
|
154
|
+
'',
|
|
155
|
+
{ cause: err },
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
159
|
+
return new GSDToolsError(
|
|
160
|
+
msg,
|
|
161
|
+
command,
|
|
162
|
+
args,
|
|
163
|
+
1,
|
|
164
|
+
'',
|
|
165
|
+
err instanceof Error ? { cause: err } : undefined,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Enforce {@link GSDTools.timeoutMs} for in-process registry dispatches so native
|
|
171
|
+
* routing cannot hang indefinitely (subprocess path already uses `execFile` timeout).
|
|
172
|
+
*/
|
|
173
|
+
private async withRegistryDispatchTimeout<T>(
|
|
174
|
+
legacyCommand: string,
|
|
175
|
+
legacyArgs: string[],
|
|
176
|
+
work: Promise<T>,
|
|
177
|
+
): Promise<T> {
|
|
178
|
+
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
179
|
+
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
180
|
+
timeoutId = setTimeout(() => {
|
|
181
|
+
reject(
|
|
182
|
+
new GSDToolsError(
|
|
183
|
+
`gsd-tools timed out after ${this.timeoutMs}ms: ${legacyCommand} ${legacyArgs.join(' ')}`,
|
|
184
|
+
legacyCommand,
|
|
185
|
+
legacyArgs,
|
|
186
|
+
null,
|
|
187
|
+
'',
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
}, this.timeoutMs);
|
|
191
|
+
});
|
|
192
|
+
try {
|
|
193
|
+
// Promise.race rejects when the timeout fires but does not cancel the handler promise;
|
|
194
|
+
// native handlers may still run to completion (unlike subprocess + execFile timeout).
|
|
195
|
+
return await Promise.race([work, timeoutPromise]);
|
|
196
|
+
} finally {
|
|
197
|
+
if (timeoutId !== undefined) {
|
|
198
|
+
clearTimeout(timeoutId);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Direct registry dispatch for a known handler key — skips `resolveQueryArgv` on the hot path
|
|
205
|
+
* used by PhaseRunner / InitRunner (`initPhaseOp`, `phasePlanIndex`, etc.).
|
|
206
|
+
* When native query is off (e.g. workstream or tests with `preferNativeQuery: false`), delegates to `exec`.
|
|
207
|
+
*
|
|
208
|
+
* When native query is on, `registry.dispatch` failures are wrapped as {@link GSDToolsError} and
|
|
209
|
+
* **not** retried via the legacy `gsd-tools.cjs` subprocess — callers see the handler error
|
|
210
|
+
* explicitly. Only commands with no registry match fall through to subprocess routing in {@link exec}.
|
|
211
|
+
*/
|
|
212
|
+
private async dispatchNativeJson(
|
|
213
|
+
legacyCommand: string,
|
|
214
|
+
legacyArgs: string[],
|
|
215
|
+
registryCmd: string,
|
|
216
|
+
registryArgs: string[],
|
|
217
|
+
): Promise<unknown> {
|
|
218
|
+
if (!this.shouldUseNativeQuery()) {
|
|
219
|
+
return this.exec(legacyCommand, legacyArgs);
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
const result = await this.withRegistryDispatchTimeout(
|
|
223
|
+
legacyCommand,
|
|
224
|
+
legacyArgs,
|
|
225
|
+
this.registry.dispatch(registryCmd, registryArgs, this.projectDir),
|
|
226
|
+
);
|
|
227
|
+
return result.data;
|
|
228
|
+
} catch (err) {
|
|
229
|
+
if (err instanceof GSDToolsError) throw err;
|
|
230
|
+
throw this.toToolsError(legacyCommand, legacyArgs, err);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Same as {@link dispatchNativeJson} for handlers whose CLI contract is raw stdout (`execRaw`),
|
|
236
|
+
* including the same “no silent fallback to CJS on handler failure” behaviour.
|
|
237
|
+
*/
|
|
238
|
+
private async dispatchNativeRaw(
|
|
239
|
+
legacyCommand: string,
|
|
240
|
+
legacyArgs: string[],
|
|
241
|
+
registryCmd: string,
|
|
242
|
+
registryArgs: string[],
|
|
243
|
+
): Promise<string> {
|
|
244
|
+
if (!this.shouldUseNativeQuery()) {
|
|
245
|
+
return this.execRaw(legacyCommand, legacyArgs);
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
const result = await this.withRegistryDispatchTimeout(
|
|
249
|
+
legacyCommand,
|
|
250
|
+
legacyArgs,
|
|
251
|
+
this.registry.dispatch(registryCmd, registryArgs, this.projectDir),
|
|
252
|
+
);
|
|
253
|
+
return formatRegistryRawStdout(registryCmd, result.data).trim();
|
|
254
|
+
} catch (err) {
|
|
255
|
+
if (err instanceof GSDToolsError) throw err;
|
|
256
|
+
throw this.toToolsError(legacyCommand, legacyArgs, err);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ─── Core exec ───────────────────────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Execute a gsd-tools command and return parsed JSON output.
|
|
264
|
+
* Handles the `@file:` prefix pattern for large results.
|
|
265
|
+
*
|
|
266
|
+
* With native query enabled, a matching registry handler runs in-process;
|
|
267
|
+
* if that handler throws, the error is surfaced (no automatic fallback to `gsd-tools.cjs`).
|
|
268
|
+
*/
|
|
269
|
+
async exec(command: string, args: string[] = []): Promise<unknown> {
|
|
270
|
+
if (this.shouldUseNativeQuery()) {
|
|
271
|
+
const matched = this.nativeMatch(command, args);
|
|
272
|
+
if (matched) {
|
|
273
|
+
try {
|
|
274
|
+
const result = await this.withRegistryDispatchTimeout(
|
|
275
|
+
command,
|
|
276
|
+
args,
|
|
277
|
+
this.registry.dispatch(matched.cmd, matched.args, this.projectDir),
|
|
278
|
+
);
|
|
279
|
+
return result.data;
|
|
280
|
+
} catch (err) {
|
|
281
|
+
if (err instanceof GSDToolsError) throw err;
|
|
282
|
+
throw this.toToolsError(command, args, err);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const wsArgs = this.workstream ? ['--ws', this.workstream] : [];
|
|
288
|
+
const fullArgs = [this.gsdToolsPath, command, ...args, ...wsArgs];
|
|
289
|
+
|
|
290
|
+
return new Promise<unknown>((resolve, reject) => {
|
|
291
|
+
const child = execFile(
|
|
292
|
+
process.execPath,
|
|
293
|
+
fullArgs,
|
|
294
|
+
{
|
|
295
|
+
cwd: this.projectDir,
|
|
296
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
297
|
+
timeout: this.timeoutMs,
|
|
298
|
+
env: { ...process.env },
|
|
299
|
+
},
|
|
300
|
+
async (error, stdout, stderr) => {
|
|
301
|
+
const stderrStr = stderr?.toString() ?? '';
|
|
302
|
+
|
|
303
|
+
if (error) {
|
|
304
|
+
if (error.killed || (error as NodeJS.ErrnoException).code === 'ETIMEDOUT') {
|
|
305
|
+
reject(
|
|
306
|
+
new GSDToolsError(
|
|
307
|
+
`gsd-tools timed out after ${this.timeoutMs}ms: ${command} ${args.join(' ')}`,
|
|
308
|
+
command,
|
|
309
|
+
args,
|
|
310
|
+
null,
|
|
311
|
+
stderrStr,
|
|
312
|
+
),
|
|
313
|
+
);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
reject(
|
|
318
|
+
new GSDToolsError(
|
|
319
|
+
`gsd-tools exited with code ${error.code ?? 'unknown'}: ${command} ${args.join(' ')}${stderrStr ? `\n${stderrStr}` : ''}`,
|
|
320
|
+
command,
|
|
321
|
+
args,
|
|
322
|
+
typeof error.code === 'number' ? error.code : (error as { status?: number }).status ?? 1,
|
|
323
|
+
stderrStr,
|
|
324
|
+
),
|
|
325
|
+
);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const raw = stdout?.toString() ?? '';
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
const parsed = await this.parseOutput(raw);
|
|
333
|
+
resolve(parsed);
|
|
334
|
+
} catch (parseErr) {
|
|
335
|
+
reject(
|
|
336
|
+
new GSDToolsError(
|
|
337
|
+
`Failed to parse gsd-tools output for "${command}": ${parseErr instanceof Error ? parseErr.message : String(parseErr)}\nRaw output: ${raw.slice(0, 500)}`,
|
|
338
|
+
command,
|
|
339
|
+
args,
|
|
340
|
+
0,
|
|
341
|
+
stderrStr,
|
|
342
|
+
),
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
child.on('error', (err) => {
|
|
349
|
+
reject(
|
|
350
|
+
new GSDToolsError(
|
|
351
|
+
`Failed to execute gsd-tools: ${err.message}`,
|
|
352
|
+
command,
|
|
353
|
+
args,
|
|
354
|
+
null,
|
|
355
|
+
'',
|
|
356
|
+
),
|
|
357
|
+
);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Parse gsd-tools output, handling `@file:` prefix.
|
|
364
|
+
*/
|
|
365
|
+
private async parseOutput(raw: string): Promise<unknown> {
|
|
366
|
+
const trimmed = raw.trim();
|
|
367
|
+
|
|
368
|
+
if (trimmed === '') {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
let jsonStr = trimmed;
|
|
373
|
+
if (jsonStr.startsWith('@file:')) {
|
|
374
|
+
const filePath = jsonStr.slice(6).trim();
|
|
375
|
+
try {
|
|
376
|
+
jsonStr = await readFile(filePath, 'utf-8');
|
|
377
|
+
} catch (err) {
|
|
378
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
379
|
+
throw new Error(`Failed to read gsd-tools @file: indirection at "${filePath}": ${reason}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return JSON.parse(jsonStr);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// ─── Raw exec (no JSON parsing) ───────────────────────────────────────
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Execute a gsd-tools command and return raw stdout without JSON parsing.
|
|
390
|
+
* Use for commands like `config-set` that return plain text, not JSON.
|
|
391
|
+
*/
|
|
392
|
+
async execRaw(command: string, args: string[] = []): Promise<string> {
|
|
393
|
+
if (this.shouldUseNativeQuery()) {
|
|
394
|
+
const matched = this.nativeMatch(command, args);
|
|
395
|
+
if (matched) {
|
|
396
|
+
try {
|
|
397
|
+
const result = await this.withRegistryDispatchTimeout(
|
|
398
|
+
command,
|
|
399
|
+
args,
|
|
400
|
+
this.registry.dispatch(matched.cmd, matched.args, this.projectDir),
|
|
401
|
+
);
|
|
402
|
+
return formatRegistryRawStdout(matched.cmd, result.data).trim();
|
|
403
|
+
} catch (err) {
|
|
404
|
+
if (err instanceof GSDToolsError) throw err;
|
|
405
|
+
throw this.toToolsError(command, args, err);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const wsArgs = this.workstream ? ['--ws', this.workstream] : [];
|
|
411
|
+
const fullArgs = [this.gsdToolsPath, command, ...args, ...wsArgs, '--raw'];
|
|
412
|
+
|
|
413
|
+
return new Promise<string>((resolve, reject) => {
|
|
414
|
+
const child = execFile(
|
|
415
|
+
process.execPath,
|
|
416
|
+
fullArgs,
|
|
417
|
+
{
|
|
418
|
+
cwd: this.projectDir,
|
|
419
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
420
|
+
timeout: this.timeoutMs,
|
|
421
|
+
env: { ...process.env },
|
|
422
|
+
},
|
|
423
|
+
(error, stdout, stderr) => {
|
|
424
|
+
const stderrStr = stderr?.toString() ?? '';
|
|
425
|
+
if (error) {
|
|
426
|
+
reject(
|
|
427
|
+
new GSDToolsError(
|
|
428
|
+
`gsd-tools exited with code ${error.code ?? 'unknown'}: ${command} ${args.join(' ')}${stderrStr ? `\n${stderrStr}` : ''}`,
|
|
429
|
+
command,
|
|
430
|
+
args,
|
|
431
|
+
typeof error.code === 'number' ? error.code : (error as { status?: number }).status ?? 1,
|
|
432
|
+
stderrStr,
|
|
433
|
+
),
|
|
434
|
+
);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
resolve((stdout?.toString() ?? '').trim());
|
|
438
|
+
},
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
child.on('error', (err) => {
|
|
442
|
+
reject(
|
|
443
|
+
new GSDToolsError(
|
|
444
|
+
`Failed to execute gsd-tools: ${err.message}`,
|
|
445
|
+
command,
|
|
446
|
+
args,
|
|
447
|
+
null,
|
|
448
|
+
'',
|
|
449
|
+
),
|
|
450
|
+
);
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ─── Typed convenience methods ─────────────────────────────────────────
|
|
456
|
+
|
|
457
|
+
async stateLoad(): Promise<string> {
|
|
458
|
+
return this.dispatchNativeRaw('state', ['load'], 'state.load', []);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
async roadmapAnalyze(): Promise<RoadmapAnalysis> {
|
|
462
|
+
return this.exec('roadmap', ['analyze']) as Promise<RoadmapAnalysis>;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
async phaseComplete(phase: string): Promise<string> {
|
|
466
|
+
return this.dispatchNativeRaw('phase', ['complete', phase], 'phase.complete', [phase]);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
async commit(message: string, files?: string[]): Promise<string> {
|
|
470
|
+
const args = [message];
|
|
471
|
+
if (files?.length) {
|
|
472
|
+
args.push('--files', ...files);
|
|
473
|
+
}
|
|
474
|
+
return this.dispatchNativeRaw('commit', args, 'commit', args);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
async verifySummary(path: string): Promise<string> {
|
|
478
|
+
return this.execRaw('verify-summary', [path]);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
async initExecutePhase(phase: string): Promise<string> {
|
|
482
|
+
return this.execRaw('state', ['begin-phase', '--phase', phase]);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Query phase state from gsd-tools.cjs `init phase-op`.
|
|
487
|
+
* Returns a typed PhaseOpInfo describing what exists on disk for this phase.
|
|
488
|
+
*/
|
|
489
|
+
async initPhaseOp(phaseNumber: string): Promise<PhaseOpInfo> {
|
|
490
|
+
const result = await this.dispatchNativeJson(
|
|
491
|
+
'init',
|
|
492
|
+
['phase-op', phaseNumber],
|
|
493
|
+
'init.phase-op',
|
|
494
|
+
[phaseNumber],
|
|
495
|
+
);
|
|
496
|
+
return result as PhaseOpInfo;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Get a config value via the `config-get` surface (CJS and registry use the same key path).
|
|
501
|
+
*/
|
|
502
|
+
async configGet(key: string): Promise<string | null> {
|
|
503
|
+
const result = await this.dispatchNativeJson(
|
|
504
|
+
'config-get',
|
|
505
|
+
[key],
|
|
506
|
+
'config-get',
|
|
507
|
+
[key],
|
|
508
|
+
);
|
|
509
|
+
return result as string | null;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Begin phase state tracking in gsd-tools.cjs.
|
|
514
|
+
*/
|
|
515
|
+
async stateBeginPhase(phaseNumber: string): Promise<string> {
|
|
516
|
+
return this.execRaw('state', ['begin-phase', '--phase', phaseNumber]);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Get the plan index for a phase, grouping plans into dependency waves.
|
|
521
|
+
* Returns typed PhasePlanIndex with wave assignments and completion status.
|
|
522
|
+
*/
|
|
523
|
+
async phasePlanIndex(phaseNumber: string): Promise<PhasePlanIndex> {
|
|
524
|
+
const result = await this.dispatchNativeJson(
|
|
525
|
+
'phase-plan-index',
|
|
526
|
+
[phaseNumber],
|
|
527
|
+
'phase-plan-index',
|
|
528
|
+
[phaseNumber],
|
|
529
|
+
);
|
|
530
|
+
return result as PhasePlanIndex;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Query new-project init state from gsd-tools.cjs `init new-project`.
|
|
535
|
+
* Returns project metadata, model configs, brownfield detection, etc.
|
|
536
|
+
*/
|
|
537
|
+
async initNewProject(): Promise<InitNewProjectInfo> {
|
|
538
|
+
const result = await this.dispatchNativeJson('init', ['new-project'], 'init.new-project', []);
|
|
539
|
+
return result as InitNewProjectInfo;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Set a config value via gsd-tools.cjs `config-set`.
|
|
544
|
+
* Handles type coercion (booleans, numbers, JSON) on the gsd-tools side.
|
|
545
|
+
* Note: config-set returns `key=value` text, not JSON, so we use execRaw.
|
|
546
|
+
*/
|
|
547
|
+
async configSet(key: string, value: string): Promise<string> {
|
|
548
|
+
return this.dispatchNativeRaw('config-set', [key, value], 'config-set', [key, value]);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Run `gsd-remix-sdk query` semantics in-process: normalize argv, resolve registry, dispatch.
|
|
554
|
+
* Returns handler JSON payload (same as stdout from the `gsd-remix-sdk query` CLI without `--pick`).
|
|
555
|
+
*/
|
|
556
|
+
export async function runGsdToolsQuery(projectDir: string, queryArgv: string[]): Promise<unknown> {
|
|
557
|
+
const { createRegistry } = await import('./query/index.js');
|
|
558
|
+
const { resolveQueryArgv } = await import('./query/registry.js');
|
|
559
|
+
const { normalizeQueryCommand } = await import('./query/normalize-query-command.js');
|
|
560
|
+
const { GSDError, ErrorClassification } = await import('./errors.js');
|
|
561
|
+
|
|
562
|
+
if (queryArgv.length === 0 || !queryArgv[0]) {
|
|
563
|
+
throw new GSDError('runGsdToolsQuery requires a command', ErrorClassification.Validation);
|
|
564
|
+
}
|
|
565
|
+
const queryCommand = queryArgv[0];
|
|
566
|
+
const [normCmd, normArgs] = normalizeQueryCommand(queryCommand, queryArgv.slice(1));
|
|
567
|
+
const registry = createRegistry();
|
|
568
|
+
const tokens = [normCmd, ...normArgs];
|
|
569
|
+
const matched = resolveQueryArgv(tokens, registry);
|
|
570
|
+
if (!matched) {
|
|
571
|
+
throw new GSDError(
|
|
572
|
+
`Unknown command: "${tokens.join(' ')}". No native handler registered.`,
|
|
573
|
+
ErrorClassification.Validation,
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
const result = await registry.dispatch(matched.cmd, matched.args, projectDir);
|
|
577
|
+
return result.data;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// ─── Path resolution ────────────────────────────────────────────────────────
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Resolve gsd-tools.cjs path.
|
|
584
|
+
* Probe order: SDK-bundled repo copy → `project/.claude/get-shit-done/` →
|
|
585
|
+
* `~/.claude/get-shit-done/`.
|
|
586
|
+
*/
|
|
587
|
+
export function resolveGsdToolsPath(projectDir: string): string {
|
|
588
|
+
const candidates = [
|
|
589
|
+
BUNDLED_GSD_TOOLS_PATH,
|
|
590
|
+
join(projectDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'),
|
|
591
|
+
join(homedir(), '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'),
|
|
592
|
+
];
|
|
593
|
+
|
|
594
|
+
return candidates.find(candidate => existsSync(candidate)) ?? candidates[candidates.length - 1]!;
|
|
595
|
+
}
|