@opengsd/gsd-core 1.2.0-rc.1
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.ja-JP.md +870 -0
- package/README.ko-KR.md +861 -0
- package/README.md +301 -0
- package/README.pt-BR.md +492 -0
- package/README.zh-CN.md +842 -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 +668 -0
- package/agents/gsd-code-reviewer.md +387 -0
- package/agents/gsd-codebase-mapper.md +853 -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 +772 -0
- package/agents/gsd-framework-selector.md +160 -0
- package/agents/gsd-integration-checker.md +470 -0
- package/agents/gsd-intel-updater.md +342 -0
- package/agents/gsd-nyquist-auditor.md +203 -0
- package/agents/gsd-pattern-mapper.md +335 -0
- package/agents/gsd-phase-researcher.md +928 -0
- package/agents/gsd-plan-checker.md +978 -0
- package/agents/gsd-planner.md +1218 -0
- package/agents/gsd-project-researcher.md +677 -0
- package/agents/gsd-research-synthesizer.md +255 -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 +917 -0
- package/bin/install.js +10936 -0
- package/bin/lib/ui-safety-gate.cjs +107 -0
- package/commands/gsd/add-tests.md +42 -0
- package/commands/gsd/ai-integration-phase.md +37 -0
- package/commands/gsd/audit-fix.md +34 -0
- package/commands/gsd/audit-milestone.md +37 -0
- package/commands/gsd/audit-uat.md +24 -0
- package/commands/gsd/autonomous.md +46 -0
- package/commands/gsd/capture.md +62 -0
- package/commands/gsd/cleanup.md +24 -0
- package/commands/gsd/code-review.md +59 -0
- package/commands/gsd/complete-milestone.md +143 -0
- package/commands/gsd/config.md +56 -0
- package/commands/gsd/debug.md +52 -0
- package/commands/gsd/discuss-phase.md +76 -0
- package/commands/gsd/docs-update.md +49 -0
- package/commands/gsd/eval-review.md +33 -0
- package/commands/gsd/execute-phase.md +64 -0
- package/commands/gsd/explore.md +27 -0
- package/commands/gsd/extract-learnings.md +23 -0
- package/commands/gsd/fast.md +31 -0
- package/commands/gsd/forensics.md +57 -0
- package/commands/gsd/graphify.md +199 -0
- package/commands/gsd/health.md +31 -0
- package/commands/gsd/help.md +28 -0
- package/commands/gsd/import.md +41 -0
- package/commands/gsd/inbox.md +39 -0
- package/commands/gsd/ingest-docs.md +42 -0
- package/commands/gsd/manager.md +45 -0
- package/commands/gsd/map-codebase.md +83 -0
- package/commands/gsd/milestone-summary.md +51 -0
- package/commands/gsd/mvp-phase.md +45 -0
- package/commands/gsd/new-milestone.md +45 -0
- package/commands/gsd/new-project.md +47 -0
- package/commands/gsd/ns-context.md +23 -0
- package/commands/gsd/ns-ideate.md +24 -0
- package/commands/gsd/ns-manage.md +29 -0
- package/commands/gsd/ns-project.md +22 -0
- package/commands/gsd/ns-review.md +26 -0
- package/commands/gsd/ns-workflow.md +28 -0
- package/commands/gsd/pause-work.md +43 -0
- package/commands/gsd/phase.md +56 -0
- package/commands/gsd/plan-phase.md +62 -0
- package/commands/gsd/plan-review-convergence.md +59 -0
- package/commands/gsd/pr-branch.md +26 -0
- package/commands/gsd/profile-user.md +46 -0
- package/commands/gsd/progress.md +47 -0
- package/commands/gsd/quick.md +174 -0
- package/commands/gsd/resume-work.md +30 -0
- package/commands/gsd/review-backlog.md +63 -0
- package/commands/gsd/review.md +41 -0
- package/commands/gsd/secure-phase.md +36 -0
- package/commands/gsd/settings.md +29 -0
- package/commands/gsd/ship.md +24 -0
- package/commands/gsd/sketch.md +60 -0
- package/commands/gsd/spec-phase.md +63 -0
- package/commands/gsd/spike.md +57 -0
- package/commands/gsd/stats.md +19 -0
- package/commands/gsd/surface.md +155 -0
- package/commands/gsd/thread.md +24 -0
- package/commands/gsd/ui-phase.md +35 -0
- package/commands/gsd/ui-review.md +33 -0
- package/commands/gsd/ultraplan-phase.md +34 -0
- package/commands/gsd/undo.md +35 -0
- package/commands/gsd/update.md +48 -0
- package/commands/gsd/validate-phase.md +36 -0
- package/commands/gsd/verify-work.md +39 -0
- package/commands/gsd/workspace.md +52 -0
- package/commands/gsd/workstreams.md +70 -0
- package/get-shit-done/bin/check-latest-version.cjs +106 -0
- package/get-shit-done/bin/gsd-tools.cjs +1676 -0
- package/get-shit-done/bin/lib/active-workstream-store.cjs +302 -0
- package/get-shit-done/bin/lib/adr-parser.cjs +394 -0
- package/get-shit-done/bin/lib/agent-command-router.cjs +65 -0
- package/get-shit-done/bin/lib/artifacts.cjs +53 -0
- package/get-shit-done/bin/lib/audit.cjs +755 -0
- package/get-shit-done/bin/lib/check-command-router.cjs +333 -0
- package/get-shit-done/bin/lib/cjs-command-router-adapter.cjs +118 -0
- package/get-shit-done/bin/lib/clock.cjs +96 -0
- package/get-shit-done/bin/lib/clusters.cjs +135 -0
- package/get-shit-done/bin/lib/code-review-flags.cjs +74 -0
- package/get-shit-done/bin/lib/command-aliases.cjs +815 -0
- package/get-shit-done/bin/lib/command-arg-projection.cjs +62 -0
- package/get-shit-done/bin/lib/command-routing-hub.cjs +388 -0
- package/get-shit-done/bin/lib/commands.cjs +1188 -0
- package/get-shit-done/bin/lib/config-schema.cjs +31 -0
- package/get-shit-done/bin/lib/config.cjs +728 -0
- package/get-shit-done/bin/lib/configuration.cjs +248 -0
- package/get-shit-done/bin/lib/context-utilization.cjs +47 -0
- package/get-shit-done/bin/lib/core.cjs +2121 -0
- package/get-shit-done/bin/lib/decisions.cjs +116 -0
- package/get-shit-done/bin/lib/docs.cjs +270 -0
- package/get-shit-done/bin/lib/drift.cjs +388 -0
- package/get-shit-done/bin/lib/fallow-runner.cjs +109 -0
- package/get-shit-done/bin/lib/frontmatter.cjs +389 -0
- package/get-shit-done/bin/lib/gap-checker.cjs +205 -0
- package/get-shit-done/bin/lib/graphify.cjs +592 -0
- package/get-shit-done/bin/lib/gsd2-import.cjs +514 -0
- package/get-shit-done/bin/lib/init-command-router.cjs +58 -0
- package/get-shit-done/bin/lib/init.cjs +2112 -0
- package/get-shit-done/bin/lib/install-profiles.cjs +603 -0
- package/get-shit-done/bin/lib/installer-migration-authoring.cjs +117 -0
- package/get-shit-done/bin/lib/installer-migration-report.cjs +354 -0
- package/get-shit-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +220 -0
- package/get-shit-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +41 -0
- package/get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +80 -0
- package/get-shit-done/bin/lib/installer-migrations.cjs +778 -0
- package/get-shit-done/bin/lib/intel.cjs +708 -0
- package/get-shit-done/bin/lib/learnings.cjs +421 -0
- package/get-shit-done/bin/lib/milestone.cjs +314 -0
- package/get-shit-done/bin/lib/model-catalog.cjs +212 -0
- package/get-shit-done/bin/lib/model-profiles.cjs +31 -0
- package/get-shit-done/bin/lib/observability/event.cjs +82 -0
- package/get-shit-done/bin/lib/observability/logger.cjs +174 -0
- package/get-shit-done/bin/lib/observability/redaction.cjs +50 -0
- package/get-shit-done/bin/lib/package-identity.cjs +31 -0
- package/get-shit-done/bin/lib/phase-command-router.cjs +191 -0
- package/get-shit-done/bin/lib/phase-lifecycle.cjs +80 -0
- package/get-shit-done/bin/lib/phase.cjs +1607 -0
- package/get-shit-done/bin/lib/phases-command-router.cjs +39 -0
- package/get-shit-done/bin/lib/plan-scan.cjs +97 -0
- package/get-shit-done/bin/lib/planning-workspace.cjs +238 -0
- package/get-shit-done/bin/lib/profile-output.cjs +1141 -0
- package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
- package/get-shit-done/bin/lib/project-root.cjs +112 -0
- package/get-shit-done/bin/lib/prompt-budget.cjs +399 -0
- package/get-shit-done/bin/lib/review-reviewer-selection.cjs +125 -0
- package/get-shit-done/bin/lib/roadmap-command-router.cjs +28 -0
- package/get-shit-done/bin/lib/roadmap.cjs +650 -0
- package/get-shit-done/bin/lib/runtime-artifact-layout.cjs +301 -0
- package/get-shit-done/bin/lib/runtime-homes.cjs +222 -0
- package/get-shit-done/bin/lib/runtime-name-policy.cjs +83 -0
- package/get-shit-done/bin/lib/runtime-slash.cjs +112 -0
- package/get-shit-done/bin/lib/schema-detect.cjs +165 -0
- package/get-shit-done/bin/lib/secrets.cjs +32 -0
- package/get-shit-done/bin/lib/security.cjs +600 -0
- package/get-shit-done/bin/lib/semver-compare.cjs +35 -0
- package/get-shit-done/bin/lib/shell-command-projection.cjs +500 -0
- package/get-shit-done/bin/lib/state-command-router.cjs +252 -0
- package/get-shit-done/bin/lib/state-document.cjs +263 -0
- package/get-shit-done/bin/lib/state.cjs +2038 -0
- package/get-shit-done/bin/lib/surface.cjs +470 -0
- package/get-shit-done/bin/lib/task-command-router.cjs +81 -0
- package/get-shit-done/bin/lib/template.cjs +228 -0
- package/get-shit-done/bin/lib/uat.cjs +289 -0
- package/get-shit-done/bin/lib/update-context.cjs +209 -0
- package/get-shit-done/bin/lib/validate-command-router.cjs +83 -0
- package/get-shit-done/bin/lib/validate.cjs +92 -0
- package/get-shit-done/bin/lib/verify-command-router.cjs +40 -0
- package/get-shit-done/bin/lib/verify.cjs +1511 -0
- package/get-shit-done/bin/lib/workstream-inventory-builder.cjs +74 -0
- package/get-shit-done/bin/lib/workstream-inventory.cjs +146 -0
- package/get-shit-done/bin/lib/workstream-name-policy.cjs +94 -0
- package/get-shit-done/bin/lib/workstream.cjs +389 -0
- package/get-shit-done/bin/lib/worktree-safety.cjs +985 -0
- package/get-shit-done/bin/shared/config-defaults.manifest.json +97 -0
- package/get-shit-done/bin/shared/config-schema.manifest.json +175 -0
- package/get-shit-done/bin/shared/model-catalog.json +122 -0
- package/get-shit-done/bin/shared/runtime-aliases.manifest.json +75 -0
- package/get-shit-done/bin/verify-reapply-patches.cjs +352 -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 +23 -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 +814 -0
- package/get-shit-done/references/common-bug-patterns.md +114 -0
- package/get-shit-done/references/context-budget.md +85 -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/execute-mvp-tdd.md +81 -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 +298 -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 +245 -0
- package/get-shit-done/references/mvp-concepts.md +49 -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-chunked.md +49 -0
- package/get-shit-done/references/planner-gap-closure.md +62 -0
- package/get-shit-done/references/planner-graphify-auto-update.md +67 -0
- package/get-shit-done/references/planner-human-verify-mode.md +57 -0
- package/get-shit-done/references/planner-interface-context.md +62 -0
- package/get-shit-done/references/planner-mvp-mode.md +53 -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 +471 -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/scout-codebase.md +51 -0
- package/get-shit-done/references/skeleton-template.md +48 -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/spidr-splitting.md +69 -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/user-story-template.md +58 -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/verify-mvp-mode.md +85 -0
- package/get-shit-done/references/workstream-flag.md +111 -0
- package/get-shit-done/references/worktree-path-safety.md +89 -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 +77 -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 +62 -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 +195 -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/_runtime-launcher.snippet.sh +1 -0
- package/get-shit-done/workflows/add-backlog.md +91 -0
- package/get-shit-done/workflows/add-phase.md +113 -0
- package/get-shit-done/workflows/add-tests.md +355 -0
- package/get-shit-done/workflows/add-todo.md +161 -0
- package/get-shit-done/workflows/ai-integration-phase.md +295 -0
- package/get-shit-done/workflows/analyze-dependencies.md +96 -0
- package/get-shit-done/workflows/audit-fix.md +178 -0
- package/get-shit-done/workflows/audit-milestone.md +358 -0
- package/get-shit-done/workflows/audit-uat.md +110 -0
- package/get-shit-done/workflows/autonomous.md +795 -0
- package/get-shit-done/workflows/check-todos.md +180 -0
- package/get-shit-done/workflows/cleanup.md +155 -0
- package/get-shit-done/workflows/code-review-fix.md +502 -0
- package/get-shit-done/workflows/code-review.md +656 -0
- package/get-shit-done/workflows/complete-milestone.md +855 -0
- package/get-shit-done/workflows/debug.md +232 -0
- package/get-shit-done/workflows/diagnose-issues.md +241 -0
- package/get-shit-done/workflows/discovery-phase.md +291 -0
- package/get-shit-done/workflows/discuss-phase/modes/advisor.md +176 -0
- package/get-shit-done/workflows/discuss-phase/modes/all.md +28 -0
- package/get-shit-done/workflows/discuss-phase/modes/analyze.md +44 -0
- package/get-shit-done/workflows/discuss-phase/modes/auto.md +57 -0
- package/get-shit-done/workflows/discuss-phase/modes/batch.md +52 -0
- package/get-shit-done/workflows/discuss-phase/modes/chain.md +98 -0
- package/get-shit-done/workflows/discuss-phase/modes/default.md +141 -0
- package/get-shit-done/workflows/discuss-phase/modes/power.md +44 -0
- package/get-shit-done/workflows/discuss-phase/modes/text.md +55 -0
- package/get-shit-done/workflows/discuss-phase/templates/checkpoint.json +18 -0
- package/get-shit-done/workflows/discuss-phase/templates/context.md +136 -0
- package/get-shit-done/workflows/discuss-phase/templates/discussion-log.md +50 -0
- package/get-shit-done/workflows/discuss-phase-assumptions.md +675 -0
- package/get-shit-done/workflows/discuss-phase-power.md +291 -0
- package/get-shit-done/workflows/discuss-phase.md +499 -0
- package/get-shit-done/workflows/do.md +111 -0
- package/get-shit-done/workflows/docs-update.md +1162 -0
- package/get-shit-done/workflows/edit-phase.md +295 -0
- package/get-shit-done/workflows/eval-review.md +156 -0
- package/get-shit-done/workflows/execute-phase/steps/codebase-drift-gate.md +82 -0
- package/get-shit-done/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/get-shit-done/workflows/execute-phase/steps/post-merge-gate.md +117 -0
- package/get-shit-done/workflows/execute-phase.md +1709 -0
- package/get-shit-done/workflows/execute-plan.md +526 -0
- package/get-shit-done/workflows/explore.md +144 -0
- package/get-shit-done/workflows/extract-learnings.md +243 -0
- package/get-shit-done/workflows/fast.md +124 -0
- package/get-shit-done/workflows/forensics.md +279 -0
- package/get-shit-done/workflows/graduation.md +196 -0
- package/get-shit-done/workflows/health.md +224 -0
- package/get-shit-done/workflows/help/modes/brief.md +22 -0
- package/get-shit-done/workflows/help/modes/default.md +50 -0
- package/get-shit-done/workflows/help/modes/full.md +784 -0
- package/get-shit-done/workflows/help/modes/topic.md +74 -0
- package/get-shit-done/workflows/help.md +24 -0
- package/get-shit-done/workflows/import.md +254 -0
- package/get-shit-done/workflows/inbox.md +387 -0
- package/get-shit-done/workflows/ingest-docs.md +339 -0
- package/get-shit-done/workflows/insert-phase.md +152 -0
- package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
- package/get-shit-done/workflows/list-workspaces.md +57 -0
- package/get-shit-done/workflows/manager.md +393 -0
- package/get-shit-done/workflows/map-codebase.md +444 -0
- package/get-shit-done/workflows/milestone-summary.md +224 -0
- package/get-shit-done/workflows/mvp-phase.md +222 -0
- package/get-shit-done/workflows/new-milestone.md +635 -0
- package/get-shit-done/workflows/new-project.md +1555 -0
- package/get-shit-done/workflows/new-workspace.md +240 -0
- package/get-shit-done/workflows/next.md +299 -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 +244 -0
- package/get-shit-done/workflows/plan-milestone-gaps.md +281 -0
- package/get-shit-done/workflows/plan-phase.md +1809 -0
- package/get-shit-done/workflows/plan-review-convergence.md +346 -0
- package/get-shit-done/workflows/plant-seed.md +230 -0
- package/get-shit-done/workflows/pr-branch.md +157 -0
- package/get-shit-done/workflows/profile-user.md +453 -0
- package/get-shit-done/workflows/progress.md +699 -0
- package/get-shit-done/workflows/quick.md +1039 -0
- package/get-shit-done/workflows/reapply-patches.md +426 -0
- package/get-shit-done/workflows/remove-phase.md +156 -0
- package/get-shit-done/workflows/remove-workspace.md +108 -0
- package/get-shit-done/workflows/resume-project.md +332 -0
- package/get-shit-done/workflows/review.md +623 -0
- package/get-shit-done/workflows/scan.md +105 -0
- package/get-shit-done/workflows/secure-phase.md +180 -0
- package/get-shit-done/workflows/session-report.md +146 -0
- package/get-shit-done/workflows/settings-advanced.md +620 -0
- package/get-shit-done/workflows/settings-integrations.md +312 -0
- package/get-shit-done/workflows/settings.md +552 -0
- package/get-shit-done/workflows/ship.md +356 -0
- package/get-shit-done/workflows/sketch-wrap-up.md +286 -0
- package/get-shit-done/workflows/sketch.md +361 -0
- package/get-shit-done/workflows/spec-phase.md +262 -0
- package/get-shit-done/workflows/spike-wrap-up.md +307 -0
- package/get-shit-done/workflows/spike.md +453 -0
- package/get-shit-done/workflows/stats.md +80 -0
- package/get-shit-done/workflows/sync-skills.md +182 -0
- package/get-shit-done/workflows/thread.md +222 -0
- package/get-shit-done/workflows/transition.md +694 -0
- package/get-shit-done/workflows/ui-phase.md +328 -0
- package/get-shit-done/workflows/ui-review.md +193 -0
- package/get-shit-done/workflows/ultraplan-phase.md +199 -0
- package/get-shit-done/workflows/undo.md +314 -0
- package/get-shit-done/workflows/update.md +443 -0
- package/get-shit-done/workflows/validate-phase.md +179 -0
- package/get-shit-done/workflows/verify-phase.md +544 -0
- package/get-shit-done/workflows/verify-work.md +781 -0
- package/hooks/dist/gsd-check-update-worker.js +95 -0
- package/hooks/dist/gsd-check-update.js +64 -0
- package/hooks/dist/gsd-context-monitor.js +195 -0
- package/hooks/dist/gsd-graphify-update.sh +158 -0
- package/hooks/dist/gsd-phase-boundary.sh +47 -0
- package/hooks/dist/gsd-prompt-guard.js +97 -0
- package/hooks/dist/gsd-read-guard.js +101 -0
- package/hooks/dist/gsd-read-injection-scanner.js +203 -0
- package/hooks/dist/gsd-session-state.sh +59 -0
- package/hooks/dist/gsd-statusline.js +548 -0
- package/hooks/dist/gsd-update-banner.js +134 -0
- package/hooks/dist/gsd-validate-commit.sh +57 -0
- package/hooks/dist/gsd-workflow-guard.js +166 -0
- package/hooks/dist/lib/git-cmd.js +150 -0
- package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
- package/hooks/gsd-check-update-worker.js +95 -0
- package/hooks/gsd-check-update.js +64 -0
- package/hooks/gsd-context-monitor.js +195 -0
- package/hooks/gsd-graphify-update.sh +158 -0
- package/hooks/gsd-phase-boundary.sh +47 -0
- package/hooks/gsd-prompt-guard.js +97 -0
- package/hooks/gsd-read-guard.js +101 -0
- package/hooks/gsd-read-injection-scanner.js +203 -0
- package/hooks/gsd-session-state.sh +59 -0
- package/hooks/gsd-statusline.js +548 -0
- package/hooks/gsd-update-banner.js +134 -0
- package/hooks/gsd-validate-commit.sh +57 -0
- package/hooks/gsd-workflow-guard.js +166 -0
- package/hooks/lib/git-cmd.js +150 -0
- package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
- package/hooks/managed-hooks-registry.cjs +34 -0
- package/package.json +102 -0
- package/scripts/affected-tests-lib.cjs +541 -0
- package/scripts/audit-workflow-script-paths.cjs +73 -0
- package/scripts/base64-scan.sh +339 -0
- package/scripts/build-hooks.js +236 -0
- package/scripts/changeset/README.md +129 -0
- package/scripts/changeset/cli.cjs +392 -0
- package/scripts/changeset/github-release-notes.cjs +199 -0
- package/scripts/changeset/lint.cjs +110 -0
- package/scripts/changeset/new.cjs +137 -0
- package/scripts/changeset/parse.cjs +114 -0
- package/scripts/changeset/render.cjs +34 -0
- package/scripts/changeset/serialize.cjs +130 -0
- package/scripts/check-alias-drift.cjs +108 -0
- package/scripts/check-env.cjs +302 -0
- package/scripts/check-npm-integrity.cjs +209 -0
- package/scripts/ci-guard-runner.cjs +16 -0
- package/scripts/ci-prepare-test-scope.cjs +46 -0
- package/scripts/ci-rebase-check.cjs +85 -0
- package/scripts/ci-test-scope.cjs +302 -0
- package/scripts/command-contract-helpers.cjs +64 -0
- package/scripts/diff-touches-shipped-paths.cjs +147 -0
- package/scripts/fix-slash-commands.cjs +147 -0
- package/scripts/gen-inventory-manifest.cjs +109 -0
- package/scripts/generate-package-identity.cjs +104 -0
- package/scripts/lint-command-contract.cjs +108 -0
- package/scripts/lint-descriptions.cjs +83 -0
- package/scripts/lint-docs-required.cjs +222 -0
- package/scripts/lint-no-source-grep-extras.cjs +81 -0
- package/scripts/lint-no-source-grep.cjs +174 -0
- package/scripts/lint-package-identity-drift.cjs +141 -0
- package/scripts/lint-pr-check-project-dir.cjs +98 -0
- package/scripts/lint-shared-module-handsync.cjs +388 -0
- package/scripts/lint-shell-command-projection-drift.cjs +57 -0
- package/scripts/lint-skill-deps.cjs +180 -0
- package/scripts/lint-test-file-count.allowlist.json +36 -0
- package/scripts/lint-test-file-count.cjs +190 -0
- package/scripts/pr-template-policy.cjs +268 -0
- package/scripts/prompt-injection-scan.sh +203 -0
- package/scripts/release-tarball-smoke.cjs +627 -0
- package/scripts/run-affected-tests.cjs +6 -0
- package/scripts/run-cross-platform-tests.cjs +63 -0
- package/scripts/run-tests.cjs +282 -0
- package/scripts/secret-scan-lint.sh +231 -0
- package/scripts/secret-scan.sh +358 -0
- package/scripts/setup-branch-protection.sh +236 -0
- package/scripts/shared-module-handsync-allowlist.json +183 -0
- package/scripts/strip-prose-atrefs.cjs +106 -0
- package/scripts/sync-rulesets.sh +34 -0
- package/scripts/sync-runtime-launcher.cjs +402 -0
- package/scripts/test-failure-reasons.cjs +34 -0
- package/scripts/workflow-policy.cjs +450 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone — Milestone and requirements lifecycle operations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { escapeRegex, getMilestonePhaseFilter, extractOneLinerFromBody, output, error } = require('./core.cjs');
|
|
8
|
+
const { platformWriteSync, platformEnsureDir } = require('./shell-command-projection.cjs');
|
|
9
|
+
const { planningPaths } = require('./planning-workspace.cjs');
|
|
10
|
+
const { extractFrontmatter } = require('./frontmatter.cjs');
|
|
11
|
+
const { writeStateMd, stateReplaceFieldWithFallback } = require('./state.cjs');
|
|
12
|
+
const { formatGsdSlash, resolveRuntime } = require('./runtime-slash.cjs');
|
|
13
|
+
|
|
14
|
+
function cmdRequirementsMarkComplete(cwd, reqIdsRaw, raw) {
|
|
15
|
+
if (!reqIdsRaw || reqIdsRaw.length === 0) {
|
|
16
|
+
error('requirement IDs required. Usage: requirements mark-complete REQ-01,REQ-02 or REQ-01 REQ-02');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Accept comma-separated, space-separated, or bracket-wrapped: [REQ-01, REQ-02]
|
|
20
|
+
const reqIds = reqIdsRaw
|
|
21
|
+
.join(' ')
|
|
22
|
+
.replace(/[\[\]]/g, '')
|
|
23
|
+
.split(/[,\s]+/)
|
|
24
|
+
.map(r => r.trim())
|
|
25
|
+
.filter(Boolean);
|
|
26
|
+
|
|
27
|
+
if (reqIds.length === 0) {
|
|
28
|
+
error('no valid requirement IDs found');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const reqPath = planningPaths(cwd).requirements;
|
|
32
|
+
if (!fs.existsSync(reqPath)) {
|
|
33
|
+
output({ updated: false, reason: 'REQUIREMENTS.md not found', ids: reqIds }, raw, 'no requirements file');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let reqContent = fs.readFileSync(reqPath, 'utf-8');
|
|
38
|
+
const updated = [];
|
|
39
|
+
const alreadyComplete = [];
|
|
40
|
+
const notFound = [];
|
|
41
|
+
|
|
42
|
+
for (const reqId of reqIds) {
|
|
43
|
+
let found = false;
|
|
44
|
+
const reqEscaped = escapeRegex(reqId);
|
|
45
|
+
|
|
46
|
+
// Update checkbox: - [ ] **REQ-ID** → - [x] **REQ-ID**
|
|
47
|
+
// Use replace() directly and compare — avoids test()+replace() global regex
|
|
48
|
+
// lastIndex bug where test() advances state and replace() misses matches.
|
|
49
|
+
const checkboxPattern = new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${reqEscaped}\\*\\*)`, 'gi');
|
|
50
|
+
const afterCheckbox = reqContent.replace(checkboxPattern, '$1x$2');
|
|
51
|
+
if (afterCheckbox !== reqContent) {
|
|
52
|
+
reqContent = afterCheckbox;
|
|
53
|
+
found = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Update traceability table: | REQ-ID | Phase N | Pending | → | REQ-ID | Phase N | Complete |
|
|
57
|
+
const tablePattern = new RegExp(`(\\|\\s*${reqEscaped}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`, 'gi');
|
|
58
|
+
const afterTable = reqContent.replace(tablePattern, '$1 Complete $2');
|
|
59
|
+
if (afterTable !== reqContent) {
|
|
60
|
+
reqContent = afterTable;
|
|
61
|
+
found = true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (found) {
|
|
65
|
+
updated.push(reqId);
|
|
66
|
+
} else {
|
|
67
|
+
// Check if already complete before declaring not_found.
|
|
68
|
+
// Non-global flag is fine here — we only need to know if a match exists.
|
|
69
|
+
const doneCheckbox = new RegExp(`-\\s*\\[x\\]\\s*\\*\\*${reqEscaped}\\*\\*`, 'i');
|
|
70
|
+
const doneTable = new RegExp(`\\|\\s*${reqEscaped}\\s*\\|[^|]+\\|\\s*Complete\\s*\\|`, 'i');
|
|
71
|
+
if (doneCheckbox.test(reqContent) || doneTable.test(reqContent)) {
|
|
72
|
+
alreadyComplete.push(reqId);
|
|
73
|
+
} else {
|
|
74
|
+
notFound.push(reqId);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (updated.length > 0) {
|
|
80
|
+
platformWriteSync(reqPath, reqContent);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
output({
|
|
84
|
+
updated: updated.length > 0,
|
|
85
|
+
marked_complete: updated,
|
|
86
|
+
already_complete: alreadyComplete,
|
|
87
|
+
not_found: notFound,
|
|
88
|
+
total: reqIds.length,
|
|
89
|
+
}, raw, `${updated.length}/${reqIds.length} requirements marked complete`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function cmdMilestoneComplete(cwd, version, options, raw) {
|
|
93
|
+
if (!version) {
|
|
94
|
+
error('version required for milestone complete (e.g., v1.0)');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const roadmapPath = planningPaths(cwd).roadmap;
|
|
98
|
+
const reqPath = planningPaths(cwd).requirements;
|
|
99
|
+
const statePath = planningPaths(cwd).state;
|
|
100
|
+
const milestonesPath = path.join(cwd, '.planning', 'MILESTONES.md');
|
|
101
|
+
const archiveDir = path.join(cwd, '.planning', 'milestones');
|
|
102
|
+
const phasesDir = planningPaths(cwd).phases;
|
|
103
|
+
const today = new Date().toISOString().split('T')[0];
|
|
104
|
+
const milestoneName = options.name || version;
|
|
105
|
+
|
|
106
|
+
// Ensure archive directory exists
|
|
107
|
+
platformEnsureDir(archiveDir);
|
|
108
|
+
|
|
109
|
+
// Scope stats and accomplishments to only the phases belonging to the
|
|
110
|
+
// current milestone's ROADMAP. Uses the shared filter from core.cjs
|
|
111
|
+
// (same logic used by cmdPhasesList and other callers).
|
|
112
|
+
const isDirInMilestone = getMilestonePhaseFilter(cwd, version);
|
|
113
|
+
if (isDirInMilestone.missingExplicitVersion) {
|
|
114
|
+
error(`no phases found for milestone ${version} in ROADMAP.md`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Gather stats from phases (scoped to current milestone only)
|
|
118
|
+
let phaseCount = 0;
|
|
119
|
+
let totalPlans = 0;
|
|
120
|
+
let totalTasks = 0;
|
|
121
|
+
const accomplishments = [];
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
|
125
|
+
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort();
|
|
126
|
+
|
|
127
|
+
for (const dir of dirs) {
|
|
128
|
+
if (!isDirInMilestone(dir)) continue;
|
|
129
|
+
|
|
130
|
+
phaseCount++;
|
|
131
|
+
const phaseFiles = fs.readdirSync(path.join(phasesDir, dir));
|
|
132
|
+
const plans = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md');
|
|
133
|
+
const summaries = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
134
|
+
totalPlans += plans.length;
|
|
135
|
+
|
|
136
|
+
// Extract one-liners from summaries
|
|
137
|
+
for (const s of summaries) {
|
|
138
|
+
try {
|
|
139
|
+
const content = fs.readFileSync(path.join(phasesDir, dir, s), 'utf-8');
|
|
140
|
+
const fm = extractFrontmatter(content);
|
|
141
|
+
const oneLiner = fm['one-liner'] || extractOneLinerFromBody(content);
|
|
142
|
+
if (oneLiner) {
|
|
143
|
+
accomplishments.push(oneLiner);
|
|
144
|
+
}
|
|
145
|
+
// Count tasks: prefer **Tasks:** N from Performance section,
|
|
146
|
+
// then <task XML tags, then ## Task N markdown headers
|
|
147
|
+
const tasksFieldMatch = content.match(/\*\*Tasks:\*\*\s*(\d+)/);
|
|
148
|
+
if (tasksFieldMatch) {
|
|
149
|
+
totalTasks += parseInt(tasksFieldMatch[1], 10);
|
|
150
|
+
} else {
|
|
151
|
+
const xmlTaskMatches = content.match(/<task[\s>]/gi) || [];
|
|
152
|
+
const mdTaskMatches = content.match(/##\s*Task\s*\d+/gi) || [];
|
|
153
|
+
totalTasks += xmlTaskMatches.length || mdTaskMatches.length;
|
|
154
|
+
}
|
|
155
|
+
} catch { /* intentionally empty */ }
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} catch { /* intentionally empty */ }
|
|
159
|
+
|
|
160
|
+
// Archive ROADMAP.md
|
|
161
|
+
if (fs.existsSync(roadmapPath)) {
|
|
162
|
+
const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
|
|
163
|
+
platformWriteSync(path.join(archiveDir, `${version}-ROADMAP.md`), roadmapContent);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Archive REQUIREMENTS.md
|
|
167
|
+
if (fs.existsSync(reqPath)) {
|
|
168
|
+
const reqContent = fs.readFileSync(reqPath, 'utf-8');
|
|
169
|
+
const archiveHeader = `# Requirements Archive: ${version} ${milestoneName}\n\n**Archived:** ${today}\n**Status:** SHIPPED\n\nFor current requirements, see \`.planning/REQUIREMENTS.md\`.\n\n---\n\n`;
|
|
170
|
+
platformWriteSync(path.join(archiveDir, `${version}-REQUIREMENTS.md`), archiveHeader + reqContent);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Archive audit file if exists
|
|
174
|
+
const auditFile = path.join(cwd, '.planning', `${version}-MILESTONE-AUDIT.md`);
|
|
175
|
+
if (fs.existsSync(auditFile)) {
|
|
176
|
+
fs.renameSync(auditFile, path.join(archiveDir, `${version}-MILESTONE-AUDIT.md`));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Create/append MILESTONES.md entry
|
|
180
|
+
const accomplishmentsList = accomplishments.map(a => `- ${a}`).join('\n');
|
|
181
|
+
const milestoneEntry = `## ${version} ${milestoneName} (Shipped: ${today})\n\n**Phases completed:** ${phaseCount} phases, ${totalPlans} plans, ${totalTasks} tasks\n\n**Key accomplishments:**\n${accomplishmentsList || '- (none recorded)'}\n\n---\n\n`;
|
|
182
|
+
|
|
183
|
+
if (fs.existsSync(milestonesPath)) {
|
|
184
|
+
const existing = fs.readFileSync(milestonesPath, 'utf-8');
|
|
185
|
+
if (!existing.trim()) {
|
|
186
|
+
// Empty file — treat like new
|
|
187
|
+
platformWriteSync(milestonesPath, `# Milestones\n\n${milestoneEntry}`);
|
|
188
|
+
} else {
|
|
189
|
+
// Insert after the header line(s) for reverse chronological order (newest first)
|
|
190
|
+
const headerMatch = existing.match(/^(#{1,3}\s+[^\n]*\n\n?)/);
|
|
191
|
+
if (headerMatch) {
|
|
192
|
+
const header = headerMatch[1];
|
|
193
|
+
const rest = existing.slice(header.length);
|
|
194
|
+
platformWriteSync(milestonesPath, header + milestoneEntry + rest);
|
|
195
|
+
} else {
|
|
196
|
+
// No recognizable header — prepend the entry
|
|
197
|
+
platformWriteSync(milestonesPath, milestoneEntry + existing);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
platformWriteSync(milestonesPath, `# Milestones\n\n${milestoneEntry}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Update STATE.md — keep frontmatter/body semantically aligned after closure
|
|
205
|
+
if (fs.existsSync(statePath)) {
|
|
206
|
+
let stateContent = fs.readFileSync(statePath, 'utf-8');
|
|
207
|
+
|
|
208
|
+
stateContent = stateReplaceFieldWithFallback(stateContent, 'Status', null, `${version} milestone complete`);
|
|
209
|
+
stateContent = stateReplaceFieldWithFallback(stateContent, 'Last Activity', 'Last activity', today);
|
|
210
|
+
stateContent = stateReplaceFieldWithFallback(stateContent, 'Last Activity Description', null,
|
|
211
|
+
`${version} milestone completed and archived`);
|
|
212
|
+
|
|
213
|
+
// Reset Current Position narrative so resume/progress flows do not keep
|
|
214
|
+
// pointing at closed-phase execution instructions.
|
|
215
|
+
const positionPattern = /(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i;
|
|
216
|
+
const closedPositionBody =
|
|
217
|
+
`\nPhase: Milestone ${version} complete\n` +
|
|
218
|
+
`Plan: —\n` +
|
|
219
|
+
`Status: Awaiting next milestone\n` +
|
|
220
|
+
`Last activity: ${today} — Milestone ${version} completed and archived\n\n`;
|
|
221
|
+
if (positionPattern.test(stateContent)) {
|
|
222
|
+
stateContent = stateContent.replace(positionPattern, (_m, header) => `${header}${closedPositionBody}`);
|
|
223
|
+
} else {
|
|
224
|
+
stateContent = `${stateContent.trimEnd()}\n\n## Current Position\n${closedPositionBody}`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Normalize operator-next-step tails that can become stale after close.
|
|
228
|
+
const operatorPattern = /(##\s*Operator Next Steps\s*\n)([\s\S]*?)(?=\n##|$)/i;
|
|
229
|
+
if (operatorPattern.test(stateContent)) {
|
|
230
|
+
stateContent = stateContent.replace(
|
|
231
|
+
operatorPattern,
|
|
232
|
+
`$1\n- Start the next milestone with ${formatGsdSlash('new-milestone', resolveRuntime(cwd))}\n\n`,
|
|
233
|
+
);
|
|
234
|
+
} else {
|
|
235
|
+
stateContent = `${stateContent.trimEnd()}\n\n## Operator Next Steps\n\n- Start the next milestone with ${formatGsdSlash('new-milestone', resolveRuntime(cwd))}\n`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
writeStateMd(statePath, stateContent, cwd);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Archive phase directories if requested
|
|
242
|
+
let phasesArchived = false;
|
|
243
|
+
if (options.archivePhases) {
|
|
244
|
+
try {
|
|
245
|
+
const phaseArchiveDir = path.join(archiveDir, `${version}-phases`);
|
|
246
|
+
platformEnsureDir(phaseArchiveDir);
|
|
247
|
+
|
|
248
|
+
const phaseEntries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
|
249
|
+
const phaseDirNames = phaseEntries.filter(e => e.isDirectory()).map(e => e.name);
|
|
250
|
+
let archivedCount = 0;
|
|
251
|
+
for (const dir of phaseDirNames) {
|
|
252
|
+
if (!isDirInMilestone(dir)) continue;
|
|
253
|
+
fs.renameSync(path.join(phasesDir, dir), path.join(phaseArchiveDir, dir));
|
|
254
|
+
archivedCount++;
|
|
255
|
+
}
|
|
256
|
+
phasesArchived = archivedCount > 0;
|
|
257
|
+
} catch { /* intentionally empty */ }
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const result = {
|
|
261
|
+
version,
|
|
262
|
+
name: milestoneName,
|
|
263
|
+
date: today,
|
|
264
|
+
phases: phaseCount,
|
|
265
|
+
plans: totalPlans,
|
|
266
|
+
tasks: totalTasks,
|
|
267
|
+
accomplishments,
|
|
268
|
+
archived: {
|
|
269
|
+
roadmap: fs.existsSync(path.join(archiveDir, `${version}-ROADMAP.md`)),
|
|
270
|
+
requirements: fs.existsSync(path.join(archiveDir, `${version}-REQUIREMENTS.md`)),
|
|
271
|
+
audit: fs.existsSync(path.join(archiveDir, `${version}-MILESTONE-AUDIT.md`)),
|
|
272
|
+
phases: phasesArchived,
|
|
273
|
+
},
|
|
274
|
+
milestones_updated: true,
|
|
275
|
+
state_updated: fs.existsSync(statePath),
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
output(result, raw);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function cmdPhasesClear(cwd, raw, args) {
|
|
282
|
+
const phasesDir = planningPaths(cwd).phases;
|
|
283
|
+
const confirm = Array.isArray(args) && args.includes('--confirm');
|
|
284
|
+
let cleared = 0;
|
|
285
|
+
|
|
286
|
+
if (fs.existsSync(phasesDir)) {
|
|
287
|
+
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
|
288
|
+
const dirs = entries.filter(e => e.isDirectory() && !/^999(?:\.|$)/.test(e.name));
|
|
289
|
+
|
|
290
|
+
if (dirs.length > 0 && !confirm) {
|
|
291
|
+
error(
|
|
292
|
+
`phases clear would delete ${dirs.length} phase director${dirs.length === 1 ? 'y' : 'ies'}. ` +
|
|
293
|
+
`Pass --confirm to proceed.`
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
try {
|
|
298
|
+
for (const entry of dirs) {
|
|
299
|
+
fs.rmSync(path.join(phasesDir, entry.name), { recursive: true, force: true });
|
|
300
|
+
cleared++;
|
|
301
|
+
}
|
|
302
|
+
} catch (e) {
|
|
303
|
+
error('Failed to clear phases directory: ' + e.message);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
output({ cleared }, raw, `${cleared} phase director${cleared === 1 ? 'y' : 'ies'} cleared`);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
module.exports = {
|
|
311
|
+
cmdRequirementsMarkComplete,
|
|
312
|
+
cmdMilestoneComplete,
|
|
313
|
+
cmdPhasesClear,
|
|
314
|
+
};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
|
|
5
|
+
// Resolve model-catalog.json via a prioritised candidate list so the module
|
|
6
|
+
// works in every layout:
|
|
7
|
+
//
|
|
8
|
+
// 1. Co-located install path — get-shit-done/bin/shared/model-catalog.json
|
|
9
|
+
// Written by bin/install.js (#3288 fix). This is the canonical post-install
|
|
10
|
+
// location across all runtimes (Claude Code, Codex, OpenCode, etc.).
|
|
11
|
+
//
|
|
12
|
+
// 2. Source-repo dev path — sdk/shared/model-catalog.json
|
|
13
|
+
// Three levels up from bin/lib/: works when running directly from the
|
|
14
|
+
// open-gsd/gsd-core clone (the original path introduced by #3230).
|
|
15
|
+
//
|
|
16
|
+
// 3. GSD_MODEL_CATALOG env override — allows test harnesses and custom
|
|
17
|
+
// deployments to point at an arbitrary catalog file.
|
|
18
|
+
//
|
|
19
|
+
// Throws with a diagnostic message that lists all candidates when none resolve,
|
|
20
|
+
// so MODULE_NOT_FOUND surfaces as a clear actionable error (PRED.k301).
|
|
21
|
+
const _catalogCandidates = [
|
|
22
|
+
path.resolve(__dirname, '..', 'shared', 'model-catalog.json'),
|
|
23
|
+
path.resolve(__dirname, '..', '..', '..', 'sdk', 'shared', 'model-catalog.json'),
|
|
24
|
+
process.env.GSD_MODEL_CATALOG ? path.resolve(process.env.GSD_MODEL_CATALOG) : null,
|
|
25
|
+
].filter(Boolean);
|
|
26
|
+
|
|
27
|
+
let catalog = null;
|
|
28
|
+
let _catalogLastErr = null;
|
|
29
|
+
for (const _p of _catalogCandidates) {
|
|
30
|
+
try {
|
|
31
|
+
catalog = require(_p);
|
|
32
|
+
break;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
// Only treat missing-file errors as recoverable — rethrow parse errors,
|
|
35
|
+
// permission errors, and any other real failures so they surface clearly
|
|
36
|
+
// instead of being silently swallowed (CR finding, PR #3293).
|
|
37
|
+
const isMissingCandidate =
|
|
38
|
+
(e && e.code === 'MODULE_NOT_FOUND' && String(e.message || '').includes(_p)) ||
|
|
39
|
+
(e && e.code === 'ENOENT');
|
|
40
|
+
if (!isMissingCandidate) throw e;
|
|
41
|
+
_catalogLastErr = e;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!catalog) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`model-catalog.json not found. Tried:\n${_catalogCandidates.map((p) => ` ${p}`).join('\n')}\nLast error: ${_catalogLastErr?.message}`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const VALID_PROFILES = [...catalog.profiles];
|
|
51
|
+
const VALID_PHASE_TYPES = new Set(catalog.phaseTypes);
|
|
52
|
+
const VALID_AGENT_TIERS = new Set(Object.keys(catalog.adaptiveTierMap));
|
|
53
|
+
|
|
54
|
+
const MODEL_PROFILES = Object.fromEntries(
|
|
55
|
+
Object.entries(catalog.agents).map(([agent, meta]) => [agent, {
|
|
56
|
+
quality: meta.golden,
|
|
57
|
+
balanced: meta.balanced,
|
|
58
|
+
budget: meta.budget,
|
|
59
|
+
adaptive: catalog.adaptiveTierMap[meta.routingTier],
|
|
60
|
+
}])
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const AGENT_TO_PHASE_TYPE = Object.fromEntries(
|
|
64
|
+
Object.entries(catalog.agents).map(([agent, meta]) => [agent, meta.phaseType])
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const AGENT_DEFAULT_TIERS = Object.fromEntries(
|
|
68
|
+
Object.entries(catalog.agents).map(([agent, meta]) => [agent, meta.routingTier])
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const MODEL_ALIAS_MAP = Object.fromEntries(
|
|
72
|
+
Object.entries(catalog.runtimeTierDefaults.claude).map(([tier, entry]) => [tier, entry?.model])
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const RUNTIME_PROFILE_MAP = Object.fromEntries(
|
|
76
|
+
Object.entries(catalog.runtimeTierDefaults)
|
|
77
|
+
.map(([runtime, tiers]) => [
|
|
78
|
+
runtime,
|
|
79
|
+
Object.fromEntries(
|
|
80
|
+
Object.entries(tiers).filter(([, entry]) => entry).map(([tier, entry]) => [tier, entry])
|
|
81
|
+
),
|
|
82
|
+
])
|
|
83
|
+
.filter(([, tiers]) => Object.keys(tiers).length > 0)
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const KNOWN_RUNTIMES = new Set(Object.keys(catalog.runtimeTierDefaults));
|
|
87
|
+
const RUNTIMES_WITH_REASONING_EFFORT = new Set(
|
|
88
|
+
Object.entries(catalog.runtimeTierDefaults)
|
|
89
|
+
.filter(([, tiers]) => Object.values(tiers).some((entry) => entry && entry.reasoning_effort))
|
|
90
|
+
.map(([runtime]) => runtime)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
function nextTier(currentTier) {
|
|
94
|
+
const order = ['light', 'standard', 'heavy'];
|
|
95
|
+
const idx = order.indexOf(String(currentTier));
|
|
96
|
+
if (idx === -1) return null;
|
|
97
|
+
return order[Math.min(idx + 1, order.length - 1)];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function formatAgentToModelMapAsTable(agentToModelMap) {
|
|
101
|
+
const agentWidth = Math.max('Agent'.length, ...Object.keys(agentToModelMap).map((a) => a.length));
|
|
102
|
+
const modelWidth = Math.max('Model'.length, ...Object.values(agentToModelMap).map((m) => m.length));
|
|
103
|
+
const sep = '─'.repeat(agentWidth + 2) + '┼' + '─'.repeat(modelWidth + 2);
|
|
104
|
+
const header = ` ${'Agent'.padEnd(agentWidth)} │ ${'Model'.padEnd(modelWidth)}`;
|
|
105
|
+
let out = `${header}\n${sep}\n`;
|
|
106
|
+
for (const [agent, model] of Object.entries(agentToModelMap)) {
|
|
107
|
+
out += ` ${agent.padEnd(agentWidth)} │ ${model.padEnd(modelWidth)}\n`;
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getAgentToModelMapForProfile(normalizedProfile) {
|
|
113
|
+
const profile = VALID_PROFILES.includes(normalizedProfile) ? normalizedProfile : 'balanced';
|
|
114
|
+
const out = {};
|
|
115
|
+
for (const [agent, profiles] of Object.entries(MODEL_PROFILES)) {
|
|
116
|
+
out[agent] = profile === 'inherit' ? 'inherit' : (profiles[profile] ?? profiles.balanced);
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ─── Effort rendering ────────────────────────────────────────────────────────
|
|
122
|
+
//
|
|
123
|
+
// Universal effort ladder: minimal < low < medium < high < xhigh < max
|
|
124
|
+
//
|
|
125
|
+
// Each runtime supports a subset. The unique tails must be clamped when emitting
|
|
126
|
+
// to a runtime that does not support them:
|
|
127
|
+
// - 'max' is Anthropic-only: Codex does not support it -> clamp to 'xhigh'
|
|
128
|
+
// - 'minimal' is Codex-only: Claude does not support it -> clamp to 'low'
|
|
129
|
+
//
|
|
130
|
+
// Rendering maps the universal effort string to the runtime's native parameter.
|
|
131
|
+
|
|
132
|
+
const EFFORT_RENDERING = {
|
|
133
|
+
// Claude Code subagent effort: output_config.effort frontmatter key /
|
|
134
|
+
// CLAUDE_CODE_EFFORT_LEVEL env. Supports: low, medium, high, xhigh, max.
|
|
135
|
+
// Does NOT support 'minimal' (Codex-only) -> clamp to 'low'.
|
|
136
|
+
claude: {
|
|
137
|
+
param: 'output_config.effort',
|
|
138
|
+
channel: 'frontmatter',
|
|
139
|
+
supported: new Set(['low', 'medium', 'high', 'xhigh', 'max']),
|
|
140
|
+
clamp(level) {
|
|
141
|
+
if (level === 'minimal') return 'low';
|
|
142
|
+
return level;
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
// Codex Responses API reasoning.effort. Supports: minimal, low, medium, high, xhigh.
|
|
146
|
+
// Does NOT support 'max' (Anthropic-only) -> clamp to 'xhigh'.
|
|
147
|
+
codex: {
|
|
148
|
+
param: 'model_reasoning_effort',
|
|
149
|
+
channel: 'api',
|
|
150
|
+
supported: new Set(['minimal', 'low', 'medium', 'high', 'xhigh']),
|
|
151
|
+
clamp(level) {
|
|
152
|
+
if (level === 'max') return 'xhigh';
|
|
153
|
+
return level;
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Render a universal effort string for a specific runtime.
|
|
160
|
+
*
|
|
161
|
+
* Returns { value (clamped), param, channel } where:
|
|
162
|
+
* - value: the clamped effort string safe to pass to the runtime
|
|
163
|
+
* - param: the native parameter name (e.g. 'output_config.effort')
|
|
164
|
+
* - channel: how the value is propagated ('frontmatter', 'api', null)
|
|
165
|
+
*
|
|
166
|
+
* Unknown runtimes return { value: universalEffort, param: null, channel: null }
|
|
167
|
+
* so callers can always read .value safely.
|
|
168
|
+
*/
|
|
169
|
+
function renderEffortForRuntime(runtime, universalEffort) {
|
|
170
|
+
const spec = EFFORT_RENDERING[runtime];
|
|
171
|
+
if (!spec) {
|
|
172
|
+
return { value: universalEffort, param: null, channel: null };
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
value: spec.clamp(universalEffort),
|
|
176
|
+
param: spec.param,
|
|
177
|
+
channel: spec.channel,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ─── Fast mode propagation ───────────────────────────────────────────────────
|
|
182
|
+
//
|
|
183
|
+
// RUNTIMES_WITH_FAST_MODE is the set of runtimes where fast_mode=true can be
|
|
184
|
+
// propagated to a SPAWNED SUBAGENT via a native mechanism.
|
|
185
|
+
//
|
|
186
|
+
// Claude Code has NO per-subagent fast-mode mechanism — /fast is a session-level
|
|
187
|
+
// toggle only. Emitting a `fast_mode: true` frontmatter key on a Claude subagent
|
|
188
|
+
// would be a SILENT NO-OP, which is why 'claude' is deliberately excluded here.
|
|
189
|
+
//
|
|
190
|
+
// Only API-direct runtimes ('api') accept a speed:"fast" field in the request.
|
|
191
|
+
// Codex and other runtimes do not expose per-call fast_mode either.
|
|
192
|
+
const RUNTIMES_WITH_FAST_MODE = new Set(['api']);
|
|
193
|
+
|
|
194
|
+
module.exports = {
|
|
195
|
+
catalog,
|
|
196
|
+
MODEL_PROFILES,
|
|
197
|
+
VALID_PROFILES,
|
|
198
|
+
AGENT_TO_PHASE_TYPE,
|
|
199
|
+
VALID_PHASE_TYPES,
|
|
200
|
+
AGENT_DEFAULT_TIERS,
|
|
201
|
+
VALID_AGENT_TIERS,
|
|
202
|
+
MODEL_ALIAS_MAP,
|
|
203
|
+
RUNTIME_PROFILE_MAP,
|
|
204
|
+
KNOWN_RUNTIMES,
|
|
205
|
+
RUNTIMES_WITH_REASONING_EFFORT,
|
|
206
|
+
nextTier,
|
|
207
|
+
formatAgentToModelMapAsTable,
|
|
208
|
+
getAgentToModelMapForProfile,
|
|
209
|
+
EFFORT_RENDERING,
|
|
210
|
+
renderEffortForRuntime,
|
|
211
|
+
RUNTIMES_WITH_FAST_MODE,
|
|
212
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
MODEL_PROFILES,
|
|
5
|
+
VALID_PROFILES,
|
|
6
|
+
AGENT_TO_PHASE_TYPE,
|
|
7
|
+
VALID_PHASE_TYPES,
|
|
8
|
+
AGENT_DEFAULT_TIERS,
|
|
9
|
+
VALID_AGENT_TIERS,
|
|
10
|
+
nextTier,
|
|
11
|
+
formatAgentToModelMapAsTable,
|
|
12
|
+
getAgentToModelMapForProfile,
|
|
13
|
+
EFFORT_RENDERING,
|
|
14
|
+
renderEffortForRuntime,
|
|
15
|
+
RUNTIMES_WITH_FAST_MODE,
|
|
16
|
+
} = require('./model-catalog.cjs');
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
MODEL_PROFILES,
|
|
20
|
+
VALID_PROFILES,
|
|
21
|
+
AGENT_TO_PHASE_TYPE,
|
|
22
|
+
VALID_PHASE_TYPES,
|
|
23
|
+
AGENT_DEFAULT_TIERS,
|
|
24
|
+
VALID_AGENT_TIERS,
|
|
25
|
+
nextTier,
|
|
26
|
+
formatAgentToModelMapAsTable,
|
|
27
|
+
getAgentToModelMapForProfile,
|
|
28
|
+
EFFORT_RENDERING,
|
|
29
|
+
renderEffortForRuntime,
|
|
30
|
+
RUNTIMES_WITH_FAST_MODE,
|
|
31
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DispatchEvent shape factory — issue #177 (ADR-0174 P1.3), extended in #178 (P1.4).
|
|
5
|
+
*
|
|
6
|
+
* Creates a structured event record for every Hub dispatch, used by
|
|
7
|
+
* DispatchLogger to emit stderr errors and opt-in file audit trails.
|
|
8
|
+
*
|
|
9
|
+
* Shape:
|
|
10
|
+
* traceId: string — UUID v4, generated per dispatch
|
|
11
|
+
* parentTraceId: string|undefined — propagated from the caller when it is a canonical UUID v4
|
|
12
|
+
* (RFC 4122); invalid values are silently coerced to undefined.
|
|
13
|
+
* Enables a future init-composer (Phase 2) to correlate child
|
|
14
|
+
* dispatches to their parent via the audit file.
|
|
15
|
+
* command: string — the dispatched verb
|
|
16
|
+
* args?: unknown — only present when includeArgs === true
|
|
17
|
+
* result: { kind: 'ok' | 'UnknownCommand' | 'InvalidArgs' | 'HandlerRefusal' | 'HandlerFailure', ...payload }
|
|
18
|
+
* timestamp: string — ISO 8601
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const { randomUUID } = require('crypto');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Canonical UUID v4 regex (RFC 4122).
|
|
25
|
+
* - 36 characters total (32 hex + 4 hyphens)
|
|
26
|
+
* - Version nibble: 4
|
|
27
|
+
* - Variant bits: [89ab]
|
|
28
|
+
* - Case-insensitive: accepts both upper- and lowercase hex
|
|
29
|
+
*
|
|
30
|
+
* Used to validate parentTraceId before propagation. traceId is always
|
|
31
|
+
* generated internally by crypto.randomUUID() and is guaranteed valid.
|
|
32
|
+
*/
|
|
33
|
+
const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns true only when value is a canonical UUID v4 string.
|
|
37
|
+
* Any other value (non-string, wrong format, wrong version/variant) → false.
|
|
38
|
+
*
|
|
39
|
+
* @param {unknown} value
|
|
40
|
+
* @returns {boolean}
|
|
41
|
+
*/
|
|
42
|
+
function isValidParentTraceId(value) {
|
|
43
|
+
return typeof value === 'string' && UUID_V4_REGEX.test(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a DispatchEvent.
|
|
48
|
+
*
|
|
49
|
+
* @param {object} opts
|
|
50
|
+
* @param {string} opts.command - The dispatched command verb.
|
|
51
|
+
* @param {unknown} [opts.args] - Raw args passed to the hub.
|
|
52
|
+
* @param {object} opts.result - The HubResult returned by the hub.
|
|
53
|
+
* @param {boolean} [opts.includeArgs=false] - When true, include args in the event.
|
|
54
|
+
* @param {string} [opts.parentTraceId] - Must be a canonical UUID v4 (RFC 4122).
|
|
55
|
+
* Invalid values (non-string, wrong format, wrong version/variant) are silently coerced
|
|
56
|
+
* to undefined — no stderr warn is emitted. This prevents correlation poisoning from
|
|
57
|
+
* unvalidated caller input while keeping the factory pure and side-effect-free.
|
|
58
|
+
* @returns {object} Immutable DispatchEvent record.
|
|
59
|
+
*/
|
|
60
|
+
function makeDispatchEvent({ command, args, result, includeArgs = false, parentTraceId }) {
|
|
61
|
+
// Validate parentTraceId against UUID v4 format before propagation.
|
|
62
|
+
// Invalid inputs (empty string, non-UUID, UUID v1, oversized, etc.) are silently
|
|
63
|
+
// coerced to undefined. Silent coercion keeps the factory pure — no side effects,
|
|
64
|
+
// no log spam on bad input, consistent with how non-string values already collapse.
|
|
65
|
+
const resolvedParentTraceId = isValidParentTraceId(parentTraceId) ? parentTraceId : undefined;
|
|
66
|
+
|
|
67
|
+
const event = {
|
|
68
|
+
traceId: randomUUID(),
|
|
69
|
+
parentTraceId: resolvedParentTraceId,
|
|
70
|
+
command: String(command),
|
|
71
|
+
result,
|
|
72
|
+
timestamp: new Date().toISOString(),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
if (includeArgs && args !== undefined) {
|
|
76
|
+
event.args = args;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return Object.freeze(event);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { makeDispatchEvent };
|