@ai-is-gonna/get-tasks-done 0.2.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 +249 -0
- package/agents/gtd-advisor-researcher.md +127 -0
- package/agents/gtd-ai-researcher.md +133 -0
- package/agents/gtd-assumptions-analyzer.md +105 -0
- package/agents/gtd-code-fixer.md +668 -0
- package/agents/gtd-code-reviewer.md +387 -0
- package/agents/gtd-codebase-mapper.md +853 -0
- package/agents/gtd-debug-session-manager.md +314 -0
- package/agents/gtd-debugger.md +1452 -0
- package/agents/gtd-doc-classifier.md +168 -0
- package/agents/gtd-doc-synthesizer.md +204 -0
- package/agents/gtd-doc-verifier.md +217 -0
- package/agents/gtd-doc-writer.md +615 -0
- package/agents/gtd-domain-researcher.md +153 -0
- package/agents/gtd-eval-auditor.md +191 -0
- package/agents/gtd-eval-planner.md +154 -0
- package/agents/gtd-framework-selector.md +160 -0
- package/agents/gtd-integration-checker.md +470 -0
- package/agents/gtd-intel-updater.md +342 -0
- package/agents/gtd-nyquist-auditor.md +203 -0
- package/agents/gtd-pattern-mapper.md +335 -0
- package/agents/gtd-phase-researcher.md +928 -0
- package/agents/gtd-plan-checker.md +1000 -0
- package/agents/gtd-planner.md +926 -0
- package/agents/gtd-project-researcher.md +677 -0
- package/agents/gtd-research-synthesizer.md +247 -0
- package/agents/gtd-roadmapper.md +688 -0
- package/agents/gtd-security-auditor.md +155 -0
- package/agents/gtd-task-executor.md +166 -0
- package/agents/gtd-ui-auditor.md +495 -0
- package/agents/gtd-ui-checker.md +309 -0
- package/agents/gtd-ui-researcher.md +380 -0
- package/agents/gtd-user-profiler.md +171 -0
- package/agents/gtd-verifier.md +917 -0
- package/bin/gtd-sdk.js +37 -0
- package/bin/install.js +11358 -0
- package/commands/gtd/add-tests.md +42 -0
- package/commands/gtd/ai-integration-phase.md +37 -0
- package/commands/gtd/audit-fix.md +34 -0
- package/commands/gtd/audit-milestone.md +37 -0
- package/commands/gtd/audit-uat.md +24 -0
- package/commands/gtd/autonomous.md +46 -0
- package/commands/gtd/capture.md +62 -0
- package/commands/gtd/cleanup.md +24 -0
- package/commands/gtd/code-review.md +59 -0
- package/commands/gtd/complete-milestone.md +143 -0
- package/commands/gtd/config.md +58 -0
- package/commands/gtd/debug.md +52 -0
- package/commands/gtd/discuss-phase.md +76 -0
- package/commands/gtd/docs-update.md +49 -0
- package/commands/gtd/eval-review.md +33 -0
- package/commands/gtd/explore.md +27 -0
- package/commands/gtd/export-phase-issues.md +43 -0
- package/commands/gtd/extract-learnings.md +23 -0
- package/commands/gtd/fast.md +31 -0
- package/commands/gtd/forensics.md +57 -0
- package/commands/gtd/graphify.md +199 -0
- package/commands/gtd/health.md +31 -0
- package/commands/gtd/help.md +28 -0
- package/commands/gtd/import.md +35 -0
- package/commands/gtd/inbox.md +39 -0
- package/commands/gtd/ingest-docs.md +42 -0
- package/commands/gtd/manager.md +45 -0
- package/commands/gtd/map-codebase.md +83 -0
- package/commands/gtd/milestone-summary.md +51 -0
- package/commands/gtd/mvp-phase.md +45 -0
- package/commands/gtd/new-milestone.md +45 -0
- package/commands/gtd/new-project.md +47 -0
- package/commands/gtd/ns-context.md +23 -0
- package/commands/gtd/ns-ideate.md +24 -0
- package/commands/gtd/ns-manage.md +28 -0
- package/commands/gtd/ns-project.md +22 -0
- package/commands/gtd/ns-review.md +26 -0
- package/commands/gtd/ns-workflow.md +30 -0
- package/commands/gtd/orchestrate-tasks.md +83 -0
- package/commands/gtd/pause-work.md +43 -0
- package/commands/gtd/phase.md +56 -0
- package/commands/gtd/plan-phase.md +62 -0
- package/commands/gtd/plan-review-convergence.md +59 -0
- package/commands/gtd/pr-branch.md +26 -0
- package/commands/gtd/profile-user.md +46 -0
- package/commands/gtd/progress.md +46 -0
- package/commands/gtd/quick.md +174 -0
- package/commands/gtd/resume-work.md +30 -0
- package/commands/gtd/review-backlog.md +63 -0
- package/commands/gtd/review.md +41 -0
- package/commands/gtd/secure-phase.md +36 -0
- package/commands/gtd/settings.md +29 -0
- package/commands/gtd/sketch.md +60 -0
- package/commands/gtd/spec-phase.md +63 -0
- package/commands/gtd/spike.md +57 -0
- package/commands/gtd/stats.md +19 -0
- package/commands/gtd/surface.md +130 -0
- package/commands/gtd/thread.md +24 -0
- package/commands/gtd/ui-phase.md +35 -0
- package/commands/gtd/ui-review.md +33 -0
- package/commands/gtd/ultraplan-phase.md +34 -0
- package/commands/gtd/undo.md +35 -0
- package/commands/gtd/update.md +48 -0
- package/commands/gtd/validate-phase.md +36 -0
- package/commands/gtd/verify-work.md +39 -0
- package/commands/gtd/work-task-issue.md +45 -0
- package/commands/gtd/workspace.md +52 -0
- package/commands/gtd/workstreams.md +70 -0
- package/get-tasks-done/bin/check-latest-version.cjs +104 -0
- package/get-tasks-done/bin/gtd-tools.cjs +1264 -0
- package/get-tasks-done/bin/lib/active-workstream-store.cjs +85 -0
- package/get-tasks-done/bin/lib/adr-parser.cjs +394 -0
- package/get-tasks-done/bin/lib/artifacts.cjs +53 -0
- package/get-tasks-done/bin/lib/audit.cjs +755 -0
- package/get-tasks-done/bin/lib/cjs-command-router-adapter.cjs +39 -0
- package/get-tasks-done/bin/lib/clusters.cjs +147 -0
- package/get-tasks-done/bin/lib/command-aliases.generated.cjs +830 -0
- package/get-tasks-done/bin/lib/commands.cjs +1031 -0
- package/get-tasks-done/bin/lib/config-schema.cjs +31 -0
- package/get-tasks-done/bin/lib/config.cjs +621 -0
- package/get-tasks-done/bin/lib/configuration.generated.cjs +253 -0
- package/get-tasks-done/bin/lib/context-utilization.cjs +47 -0
- package/get-tasks-done/bin/lib/core.cjs +1921 -0
- package/get-tasks-done/bin/lib/decisions.cjs +48 -0
- package/get-tasks-done/bin/lib/docs.cjs +270 -0
- package/get-tasks-done/bin/lib/drift.cjs +388 -0
- package/get-tasks-done/bin/lib/export-phase-issues.cjs +1862 -0
- package/get-tasks-done/bin/lib/fallow-runner.cjs +109 -0
- package/get-tasks-done/bin/lib/frontmatter.cjs +389 -0
- package/get-tasks-done/bin/lib/gap-checker.cjs +197 -0
- package/get-tasks-done/bin/lib/github-api-client.cjs +97 -0
- package/get-tasks-done/bin/lib/github-repo.cjs +154 -0
- package/get-tasks-done/bin/lib/graphify.cjs +592 -0
- package/get-tasks-done/bin/lib/gtd2-import.cjs +514 -0
- package/get-tasks-done/bin/lib/init-command-router.cjs +65 -0
- package/get-tasks-done/bin/lib/init.cjs +1898 -0
- package/get-tasks-done/bin/lib/install-profiles.cjs +589 -0
- package/get-tasks-done/bin/lib/installer-migration-authoring.cjs +117 -0
- package/get-tasks-done/bin/lib/installer-migration-report.cjs +354 -0
- package/get-tasks-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +220 -0
- package/get-tasks-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +41 -0
- package/get-tasks-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +80 -0
- package/get-tasks-done/bin/lib/installer-migrations/003-legacy-acronym-install-cleanup.cjs +135 -0
- package/get-tasks-done/bin/lib/installer-migrations.cjs +703 -0
- package/get-tasks-done/bin/lib/intel.cjs +643 -0
- package/get-tasks-done/bin/lib/learnings.cjs +379 -0
- package/get-tasks-done/bin/lib/milestone.cjs +314 -0
- package/get-tasks-done/bin/lib/model-catalog.cjs +143 -0
- package/get-tasks-done/bin/lib/model-profiles.cjs +27 -0
- package/get-tasks-done/bin/lib/orchestrate-tasks.cjs +2166 -0
- package/get-tasks-done/bin/lib/phase-command-router.cjs +96 -0
- package/get-tasks-done/bin/lib/phase.cjs +1422 -0
- package/get-tasks-done/bin/lib/phases-command-router.cjs +39 -0
- package/get-tasks-done/bin/lib/plan-scan.cjs +138 -0
- package/get-tasks-done/bin/lib/planning-workspace.cjs +361 -0
- package/get-tasks-done/bin/lib/profile-output.cjs +1132 -0
- package/get-tasks-done/bin/lib/profile-pipeline.cjs +539 -0
- package/get-tasks-done/bin/lib/project-root.generated.cjs +117 -0
- package/get-tasks-done/bin/lib/review-reviewer-selection.cjs +125 -0
- package/get-tasks-done/bin/lib/roadmap-command-router.cjs +23 -0
- package/get-tasks-done/bin/lib/roadmap.cjs +621 -0
- package/get-tasks-done/bin/lib/runtime-homes.cjs +178 -0
- package/get-tasks-done/bin/lib/runtime-slash.cjs +109 -0
- package/get-tasks-done/bin/lib/schema-detect.cjs +238 -0
- package/get-tasks-done/bin/lib/secrets.cjs +33 -0
- package/get-tasks-done/bin/lib/security.cjs +504 -0
- package/get-tasks-done/bin/lib/shell-command-projection.cjs +548 -0
- package/get-tasks-done/bin/lib/state-command-router.cjs +318 -0
- package/get-tasks-done/bin/lib/state-document.cjs +12 -0
- package/get-tasks-done/bin/lib/state-document.generated.cjs +127 -0
- package/get-tasks-done/bin/lib/state.cjs +1917 -0
- package/get-tasks-done/bin/lib/surface.cjs +398 -0
- package/get-tasks-done/bin/lib/task-issue-shared.cjs +64 -0
- package/get-tasks-done/bin/lib/template.cjs +228 -0
- package/get-tasks-done/bin/lib/uat.cjs +289 -0
- package/get-tasks-done/bin/lib/validate-command-router.cjs +57 -0
- package/get-tasks-done/bin/lib/verify-command-router.cjs +34 -0
- package/get-tasks-done/bin/lib/verify.cjs +1557 -0
- package/get-tasks-done/bin/lib/work-task-issue.cjs +3429 -0
- package/get-tasks-done/bin/lib/workstream-inventory-builder.generated.cjs +79 -0
- package/get-tasks-done/bin/lib/workstream-inventory.cjs +132 -0
- package/get-tasks-done/bin/lib/workstream-name-policy.cjs +33 -0
- package/get-tasks-done/bin/lib/workstream.cjs +374 -0
- package/get-tasks-done/bin/lib/worktree-safety.cjs +563 -0
- package/get-tasks-done/bin/verify-reapply-patches.cjs +247 -0
- package/get-tasks-done/contexts/dev.md +21 -0
- package/get-tasks-done/contexts/research.md +22 -0
- package/get-tasks-done/contexts/review.md +23 -0
- package/get-tasks-done/references/agent-contracts.md +79 -0
- package/get-tasks-done/references/ai-evals.md +156 -0
- package/get-tasks-done/references/ai-frameworks.md +186 -0
- package/get-tasks-done/references/artifact-types.md +131 -0
- package/get-tasks-done/references/autonomous-smart-discuss.md +277 -0
- package/get-tasks-done/references/checkpoints.md +814 -0
- package/get-tasks-done/references/common-bug-patterns.md +114 -0
- package/get-tasks-done/references/context-budget.md +85 -0
- package/get-tasks-done/references/continuation-format.md +253 -0
- package/get-tasks-done/references/debugger-philosophy.md +76 -0
- package/get-tasks-done/references/decimal-phase-calculation.md +64 -0
- package/get-tasks-done/references/doc-conflict-engine.md +91 -0
- package/get-tasks-done/references/domain-probes.md +125 -0
- package/get-tasks-done/references/execute-mvp-tdd.md +81 -0
- package/get-tasks-done/references/executor-examples.md +110 -0
- package/get-tasks-done/references/few-shot-examples/plan-checker.md +73 -0
- package/get-tasks-done/references/few-shot-examples/verifier.md +109 -0
- package/get-tasks-done/references/gate-prompts.md +100 -0
- package/get-tasks-done/references/gates.md +70 -0
- package/get-tasks-done/references/git-integration.md +298 -0
- package/get-tasks-done/references/git-planning-commit.md +40 -0
- package/get-tasks-done/references/ios-scaffold.md +123 -0
- package/get-tasks-done/references/mandatory-initial-read.md +2 -0
- package/get-tasks-done/references/model-profile-resolution.md +38 -0
- package/get-tasks-done/references/model-profiles.md +245 -0
- package/get-tasks-done/references/mvp-concepts.md +49 -0
- package/get-tasks-done/references/phase-argument-parsing.md +61 -0
- package/get-tasks-done/references/plan-checker-task-atomicity.md +73 -0
- package/get-tasks-done/references/planner-antipatterns.md +89 -0
- package/get-tasks-done/references/planner-chunked.md +49 -0
- package/get-tasks-done/references/planner-execution-flow.md +85 -0
- package/get-tasks-done/references/planner-gap-closure.md +71 -0
- package/get-tasks-done/references/planner-graphify-auto-update.md +67 -0
- package/get-tasks-done/references/planner-human-verify-mode.md +57 -0
- package/get-tasks-done/references/planner-mvp-mode.md +53 -0
- package/get-tasks-done/references/planner-reviews.md +39 -0
- package/get-tasks-done/references/planner-revision.md +87 -0
- package/get-tasks-done/references/planner-source-audit.md +73 -0
- package/get-tasks-done/references/planning-config.md +463 -0
- package/get-tasks-done/references/project-skills-discovery.md +19 -0
- package/get-tasks-done/references/questioning.md +162 -0
- package/get-tasks-done/references/revision-loop.md +97 -0
- package/get-tasks-done/references/scout-codebase.md +51 -0
- package/get-tasks-done/references/skeleton-template.md +48 -0
- package/get-tasks-done/references/sketch-interactivity.md +41 -0
- package/get-tasks-done/references/sketch-theme-system.md +94 -0
- package/get-tasks-done/references/sketch-tooling.md +45 -0
- package/get-tasks-done/references/sketch-variant-patterns.md +81 -0
- package/get-tasks-done/references/spidr-splitting.md +69 -0
- package/get-tasks-done/references/tdd.md +330 -0
- package/get-tasks-done/references/thinking-models-debug.md +44 -0
- package/get-tasks-done/references/thinking-models-execution.md +50 -0
- package/get-tasks-done/references/thinking-models-planning.md +62 -0
- package/get-tasks-done/references/thinking-models-research.md +50 -0
- package/get-tasks-done/references/thinking-models-verification.md +55 -0
- package/get-tasks-done/references/thinking-partner.md +96 -0
- package/get-tasks-done/references/ui-brand.md +160 -0
- package/get-tasks-done/references/universal-anti-patterns.md +63 -0
- package/get-tasks-done/references/user-profiling.md +681 -0
- package/get-tasks-done/references/user-story-template.md +58 -0
- package/get-tasks-done/references/verification-overrides.md +227 -0
- package/get-tasks-done/references/verification-patterns.md +612 -0
- package/get-tasks-done/references/verify-mvp-mode.md +85 -0
- package/get-tasks-done/references/workstream-flag.md +111 -0
- package/get-tasks-done/references/worktree-path-safety.md +89 -0
- package/get-tasks-done/templates/AI-SPEC.md +246 -0
- package/get-tasks-done/templates/DEBUG.md +169 -0
- package/get-tasks-done/templates/README.md +77 -0
- package/get-tasks-done/templates/SECURITY.md +61 -0
- package/get-tasks-done/templates/UAT.md +265 -0
- package/get-tasks-done/templates/UI-SPEC.md +100 -0
- package/get-tasks-done/templates/VALIDATION.md +76 -0
- package/get-tasks-done/templates/claude-md.md +147 -0
- package/get-tasks-done/templates/codebase/architecture.md +255 -0
- package/get-tasks-done/templates/codebase/concerns.md +310 -0
- package/get-tasks-done/templates/codebase/conventions.md +307 -0
- package/get-tasks-done/templates/codebase/integrations.md +280 -0
- package/get-tasks-done/templates/codebase/stack.md +186 -0
- package/get-tasks-done/templates/codebase/structure.md +285 -0
- package/get-tasks-done/templates/codebase/testing.md +480 -0
- package/get-tasks-done/templates/config.json +55 -0
- package/get-tasks-done/templates/context.md +352 -0
- package/get-tasks-done/templates/continue-here.md +78 -0
- package/get-tasks-done/templates/copilot-instructions.md +8 -0
- package/get-tasks-done/templates/debug-subagent-prompt.md +91 -0
- package/get-tasks-done/templates/dev-preferences.md +21 -0
- package/get-tasks-done/templates/discovery.md +146 -0
- package/get-tasks-done/templates/discussion-log.md +63 -0
- package/get-tasks-done/templates/milestone-archive.md +123 -0
- package/get-tasks-done/templates/milestone.md +115 -0
- package/get-tasks-done/templates/phase-prompt.md +616 -0
- package/get-tasks-done/templates/planner-subagent-prompt.md +118 -0
- package/get-tasks-done/templates/project.md +186 -0
- package/get-tasks-done/templates/requirements.md +231 -0
- package/get-tasks-done/templates/research-project/ARCHITECTURE.md +204 -0
- package/get-tasks-done/templates/research-project/FEATURES.md +147 -0
- package/get-tasks-done/templates/research-project/PITFALLS.md +200 -0
- package/get-tasks-done/templates/research-project/STACK.md +120 -0
- package/get-tasks-done/templates/research-project/SUMMARY.md +170 -0
- package/get-tasks-done/templates/research.md +592 -0
- package/get-tasks-done/templates/retrospective.md +54 -0
- package/get-tasks-done/templates/roadmap.md +202 -0
- package/get-tasks-done/templates/spec.md +307 -0
- package/get-tasks-done/templates/state.md +184 -0
- package/get-tasks-done/templates/summary-complex.md +59 -0
- package/get-tasks-done/templates/summary-minimal.md +41 -0
- package/get-tasks-done/templates/summary-standard.md +48 -0
- package/get-tasks-done/templates/summary.md +248 -0
- package/get-tasks-done/templates/user-profile.md +146 -0
- package/get-tasks-done/templates/user-setup.md +311 -0
- package/get-tasks-done/templates/verification-report.md +322 -0
- package/get-tasks-done/workflows/add-backlog.md +90 -0
- package/get-tasks-done/workflows/add-phase.md +112 -0
- package/get-tasks-done/workflows/add-tests.md +354 -0
- package/get-tasks-done/workflows/add-todo.md +160 -0
- package/get-tasks-done/workflows/ai-integration-phase.md +294 -0
- package/get-tasks-done/workflows/analyze-dependencies.md +96 -0
- package/get-tasks-done/workflows/audit-fix.md +177 -0
- package/get-tasks-done/workflows/audit-milestone.md +357 -0
- package/get-tasks-done/workflows/audit-uat.md +109 -0
- package/get-tasks-done/workflows/autonomous.md +790 -0
- package/get-tasks-done/workflows/check-todos.md +179 -0
- package/get-tasks-done/workflows/cleanup.md +154 -0
- package/get-tasks-done/workflows/code-review-fix.md +501 -0
- package/get-tasks-done/workflows/code-review.md +613 -0
- package/get-tasks-done/workflows/complete-milestone.md +854 -0
- package/get-tasks-done/workflows/debug.md +231 -0
- package/get-tasks-done/workflows/diagnose-issues.md +240 -0
- package/get-tasks-done/workflows/discovery-phase.md +291 -0
- package/get-tasks-done/workflows/discuss-phase/modes/advisor.md +175 -0
- package/get-tasks-done/workflows/discuss-phase/modes/all.md +28 -0
- package/get-tasks-done/workflows/discuss-phase/modes/analyze.md +44 -0
- package/get-tasks-done/workflows/discuss-phase/modes/auto.md +56 -0
- package/get-tasks-done/workflows/discuss-phase/modes/batch.md +52 -0
- package/get-tasks-done/workflows/discuss-phase/modes/chain.md +97 -0
- package/get-tasks-done/workflows/discuss-phase/modes/default.md +141 -0
- package/get-tasks-done/workflows/discuss-phase/modes/power.md +44 -0
- package/get-tasks-done/workflows/discuss-phase/modes/text.md +55 -0
- package/get-tasks-done/workflows/discuss-phase/templates/checkpoint.json +18 -0
- package/get-tasks-done/workflows/discuss-phase/templates/context.md +136 -0
- package/get-tasks-done/workflows/discuss-phase/templates/discussion-log.md +50 -0
- package/get-tasks-done/workflows/discuss-phase-assumptions.md +674 -0
- package/get-tasks-done/workflows/discuss-phase-power.md +291 -0
- package/get-tasks-done/workflows/discuss-phase.md +499 -0
- package/get-tasks-done/workflows/do.md +110 -0
- package/get-tasks-done/workflows/docs-update.md +1161 -0
- package/get-tasks-done/workflows/edit-phase.md +294 -0
- package/get-tasks-done/workflows/eval-review.md +155 -0
- package/get-tasks-done/workflows/explore.md +143 -0
- package/get-tasks-done/workflows/export-phase-issues.md +74 -0
- package/get-tasks-done/workflows/extract-learnings.md +242 -0
- package/get-tasks-done/workflows/fast.md +105 -0
- package/get-tasks-done/workflows/forensics.md +278 -0
- package/get-tasks-done/workflows/graduation.md +195 -0
- package/get-tasks-done/workflows/health.md +223 -0
- package/get-tasks-done/workflows/help/modes/brief.md +24 -0
- package/get-tasks-done/workflows/help/modes/default.md +52 -0
- package/get-tasks-done/workflows/help/modes/full.md +813 -0
- package/get-tasks-done/workflows/help/modes/topic.md +74 -0
- package/get-tasks-done/workflows/help.md +24 -0
- package/get-tasks-done/workflows/import.md +253 -0
- package/get-tasks-done/workflows/inbox.md +87 -0
- package/get-tasks-done/workflows/ingest-docs.md +339 -0
- package/get-tasks-done/workflows/insert-phase.md +151 -0
- package/get-tasks-done/workflows/list-phase-assumptions.md +178 -0
- package/get-tasks-done/workflows/list-workspaces.md +56 -0
- package/get-tasks-done/workflows/manager.md +393 -0
- package/get-tasks-done/workflows/map-codebase.md +443 -0
- package/get-tasks-done/workflows/milestone-summary.md +223 -0
- package/get-tasks-done/workflows/mvp-phase.md +221 -0
- package/get-tasks-done/workflows/new-milestone.md +634 -0
- package/get-tasks-done/workflows/new-project.md +1443 -0
- package/get-tasks-done/workflows/new-workspace.md +239 -0
- package/get-tasks-done/workflows/next.md +220 -0
- package/get-tasks-done/workflows/node-repair.md +92 -0
- package/get-tasks-done/workflows/note.md +158 -0
- package/get-tasks-done/workflows/orchestrate-tasks.md +209 -0
- package/get-tasks-done/workflows/pause-work.md +243 -0
- package/get-tasks-done/workflows/plan-milestone-gaps.md +280 -0
- package/get-tasks-done/workflows/plan-phase.md +1756 -0
- package/get-tasks-done/workflows/plan-review-convergence.md +329 -0
- package/get-tasks-done/workflows/plant-seed.md +229 -0
- package/get-tasks-done/workflows/pr-branch.md +156 -0
- package/get-tasks-done/workflows/profile-user.md +452 -0
- package/get-tasks-done/workflows/progress.md +668 -0
- package/get-tasks-done/workflows/quick.md +1169 -0
- package/get-tasks-done/workflows/reapply-patches.md +390 -0
- package/get-tasks-done/workflows/remove-phase.md +155 -0
- package/get-tasks-done/workflows/remove-workspace.md +107 -0
- package/get-tasks-done/workflows/resume-project.md +329 -0
- package/get-tasks-done/workflows/review.md +459 -0
- package/get-tasks-done/workflows/scan.md +104 -0
- package/get-tasks-done/workflows/secure-phase.md +179 -0
- package/get-tasks-done/workflows/session-report.md +146 -0
- package/get-tasks-done/workflows/settings-advanced.md +532 -0
- package/get-tasks-done/workflows/settings-integrations.md +281 -0
- package/get-tasks-done/workflows/settings.md +502 -0
- package/get-tasks-done/workflows/sketch-wrap-up.md +285 -0
- package/get-tasks-done/workflows/sketch.md +360 -0
- package/get-tasks-done/workflows/spec-phase.md +262 -0
- package/get-tasks-done/workflows/spike-wrap-up.md +306 -0
- package/get-tasks-done/workflows/spike.md +452 -0
- package/get-tasks-done/workflows/stats.md +79 -0
- package/get-tasks-done/workflows/sync-skills.md +182 -0
- package/get-tasks-done/workflows/thread.md +221 -0
- package/get-tasks-done/workflows/transition.md +693 -0
- package/get-tasks-done/workflows/ui-phase.md +327 -0
- package/get-tasks-done/workflows/ui-review.md +192 -0
- package/get-tasks-done/workflows/ultraplan-phase.md +198 -0
- package/get-tasks-done/workflows/undo.md +314 -0
- package/get-tasks-done/workflows/update.md +644 -0
- package/get-tasks-done/workflows/validate-phase.md +178 -0
- package/get-tasks-done/workflows/verify-phase.md +543 -0
- package/get-tasks-done/workflows/verify-work.md +797 -0
- package/get-tasks-done/workflows/work-task-issue.md +249 -0
- package/hooks/dist/gtd-check-update-worker.js +117 -0
- package/hooks/dist/gtd-check-update.js +64 -0
- package/hooks/dist/gtd-context-monitor.js +192 -0
- package/hooks/dist/gtd-phase-boundary.sh +47 -0
- package/hooks/dist/gtd-prompt-guard.js +97 -0
- package/hooks/dist/gtd-read-guard.js +101 -0
- package/hooks/dist/gtd-read-injection-scanner.js +152 -0
- package/hooks/dist/gtd-session-state.sh +59 -0
- package/hooks/dist/gtd-statusline.js +537 -0
- package/hooks/dist/gtd-update-banner.js +134 -0
- package/hooks/dist/gtd-validate-commit.sh +57 -0
- package/hooks/dist/gtd-workflow-guard.js +94 -0
- package/hooks/gtd-check-update-worker.js +117 -0
- package/hooks/gtd-check-update.js +64 -0
- package/hooks/gtd-context-monitor.js +192 -0
- package/hooks/gtd-graphify-update.sh +152 -0
- package/hooks/gtd-phase-boundary.sh +47 -0
- package/hooks/gtd-prompt-guard.js +97 -0
- package/hooks/gtd-read-guard.js +101 -0
- package/hooks/gtd-read-injection-scanner.js +152 -0
- package/hooks/gtd-session-state.sh +59 -0
- package/hooks/gtd-statusline.js +537 -0
- package/hooks/gtd-update-banner.js +134 -0
- package/hooks/gtd-validate-commit.sh +57 -0
- package/hooks/gtd-workflow-guard.js +94 -0
- package/hooks/lib/git-cmd.js +150 -0
- package/hooks/lib/gtd-graphify-rebuild.sh +65 -0
- package/package.json +85 -0
- package/scripts/audit-workflow-script-paths.cjs +73 -0
- package/scripts/base64-scan.sh +262 -0
- package/scripts/build-hooks.js +187 -0
- package/scripts/command-contract-helpers.cjs +61 -0
- package/scripts/fix-slash-commands.cjs +106 -0
- package/scripts/lint-command-contract.cjs +108 -0
- package/scripts/lint-descriptions.cjs +83 -0
- package/scripts/lint-no-source-grep-extras.cjs +81 -0
- package/scripts/lint-no-source-grep.cjs +174 -0
- package/scripts/lint-pr-check-project-dir.cjs +94 -0
- package/scripts/lint-shell-command-projection-drift.cjs +57 -0
- package/scripts/lint-skill-deps.cjs +180 -0
- package/scripts/prompt-injection-scan.sh +201 -0
- package/scripts/run-tests.cjs +33 -0
- package/scripts/secret-scan.sh +227 -0
- package/scripts/strip-prose-atrefs.cjs +106 -0
- package/scripts/verify-tarball-sdk-dist.sh +69 -0
- package/sdk/dist/cli-transport.d.ts +19 -0
- package/sdk/dist/cli-transport.d.ts.map +1 -0
- package/sdk/dist/cli-transport.js +104 -0
- package/sdk/dist/cli-transport.js.map +1 -0
- package/sdk/dist/cli.d.ts +46 -0
- package/sdk/dist/cli.d.ts.map +1 -0
- package/sdk/dist/cli.js +511 -0
- package/sdk/dist/cli.js.map +1 -0
- package/sdk/dist/config.d.ts +107 -0
- package/sdk/dist/config.d.ts.map +1 -0
- package/sdk/dist/config.js +115 -0
- package/sdk/dist/config.js.map +1 -0
- package/sdk/dist/configuration/index.d.ts +85 -0
- package/sdk/dist/configuration/index.d.ts.map +1 -0
- package/sdk/dist/configuration/index.js +257 -0
- package/sdk/dist/configuration/index.js.map +1 -0
- package/sdk/dist/context-engine.d.ts +49 -0
- package/sdk/dist/context-engine.d.ts.map +1 -0
- package/sdk/dist/context-engine.js +142 -0
- package/sdk/dist/context-engine.js.map +1 -0
- package/sdk/dist/context-truncation.d.ts +33 -0
- package/sdk/dist/context-truncation.d.ts.map +1 -0
- package/sdk/dist/context-truncation.js +197 -0
- package/sdk/dist/context-truncation.js.map +1 -0
- package/sdk/dist/errors.d.ts +46 -0
- package/sdk/dist/errors.d.ts.map +1 -0
- package/sdk/dist/errors.js +64 -0
- package/sdk/dist/errors.js.map +1 -0
- package/sdk/dist/event-stream.d.ts +53 -0
- package/sdk/dist/event-stream.d.ts.map +1 -0
- package/sdk/dist/event-stream.js +321 -0
- package/sdk/dist/event-stream.js.map +1 -0
- package/sdk/dist/golden/capture.d.ts +15 -0
- package/sdk/dist/golden/capture.d.ts.map +1 -0
- package/sdk/dist/golden/capture.js +67 -0
- package/sdk/dist/golden/capture.js.map +1 -0
- package/sdk/dist/golden/golden-integration-covered.d.ts +6 -0
- package/sdk/dist/golden/golden-integration-covered.d.ts.map +1 -0
- package/sdk/dist/golden/golden-integration-covered.js +30 -0
- package/sdk/dist/golden/golden-integration-covered.js.map +1 -0
- package/sdk/dist/golden/golden-mutation-covered.d.ts +7 -0
- package/sdk/dist/golden/golden-mutation-covered.d.ts.map +1 -0
- package/sdk/dist/golden/golden-mutation-covered.js +17 -0
- package/sdk/dist/golden/golden-mutation-covered.js.map +1 -0
- package/sdk/dist/golden/golden-policy.d.ts +10 -0
- package/sdk/dist/golden/golden-policy.d.ts.map +1 -0
- package/sdk/dist/golden/golden-policy.js +97 -0
- package/sdk/dist/golden/golden-policy.js.map +1 -0
- package/sdk/dist/golden/init-golden-normalize.d.ts +8 -0
- package/sdk/dist/golden/init-golden-normalize.d.ts.map +1 -0
- package/sdk/dist/golden/init-golden-normalize.js +14 -0
- package/sdk/dist/golden/init-golden-normalize.js.map +1 -0
- package/sdk/dist/golden/read-only-golden-rows.d.ts +20 -0
- package/sdk/dist/golden/read-only-golden-rows.d.ts.map +1 -0
- package/sdk/dist/golden/read-only-golden-rows.js +67 -0
- package/sdk/dist/golden/read-only-golden-rows.js.map +1 -0
- package/sdk/dist/golden/registry-canonical-commands.d.ts +6 -0
- package/sdk/dist/golden/registry-canonical-commands.d.ts.map +1 -0
- package/sdk/dist/golden/registry-canonical-commands.js +30 -0
- package/sdk/dist/golden/registry-canonical-commands.js.map +1 -0
- package/sdk/dist/gtd-tools-error.d.ts +23 -0
- package/sdk/dist/gtd-tools-error.d.ts.map +1 -0
- package/sdk/dist/gtd-tools-error.js +29 -0
- package/sdk/dist/gtd-tools-error.js.map +1 -0
- package/sdk/dist/gtd-tools.d.ts +102 -0
- package/sdk/dist/gtd-tools.d.ts.map +1 -0
- package/sdk/dist/gtd-tools.js +222 -0
- package/sdk/dist/gtd-tools.js.map +1 -0
- package/sdk/dist/gtd-transport-policy.d.ts +10 -0
- package/sdk/dist/gtd-transport-policy.d.ts.map +1 -0
- package/sdk/dist/gtd-transport-policy.js +32 -0
- package/sdk/dist/gtd-transport-policy.js.map +1 -0
- package/sdk/dist/gtd-transport.d.ts +39 -0
- package/sdk/dist/gtd-transport.d.ts.map +1 -0
- package/sdk/dist/gtd-transport.js +78 -0
- package/sdk/dist/gtd-transport.js.map +1 -0
- package/sdk/dist/index.d.ts +127 -0
- package/sdk/dist/index.d.ts.map +1 -0
- package/sdk/dist/index.js +298 -0
- package/sdk/dist/index.js.map +1 -0
- package/sdk/dist/init-runner.d.ts +90 -0
- package/sdk/dist/init-runner.d.ts.map +1 -0
- package/sdk/dist/init-runner.js +613 -0
- package/sdk/dist/init-runner.js.map +1 -0
- package/sdk/dist/logger.d.ts +50 -0
- package/sdk/dist/logger.d.ts.map +1 -0
- package/sdk/dist/logger.js +70 -0
- package/sdk/dist/logger.js.map +1 -0
- package/sdk/dist/model-catalog.d.ts +33 -0
- package/sdk/dist/model-catalog.d.ts.map +1 -0
- package/sdk/dist/model-catalog.js +34 -0
- package/sdk/dist/model-catalog.js.map +1 -0
- package/sdk/dist/phase-prompt.d.ts +71 -0
- package/sdk/dist/phase-prompt.d.ts.map +1 -0
- package/sdk/dist/phase-prompt.js +208 -0
- package/sdk/dist/phase-prompt.js.map +1 -0
- package/sdk/dist/phase-runner.d.ts +145 -0
- package/sdk/dist/phase-runner.d.ts.map +1 -0
- package/sdk/dist/phase-runner.js +1206 -0
- package/sdk/dist/phase-runner.js.map +1 -0
- package/sdk/dist/plan-atomicity.d.ts +26 -0
- package/sdk/dist/plan-atomicity.d.ts.map +1 -0
- package/sdk/dist/plan-atomicity.js +116 -0
- package/sdk/dist/plan-atomicity.js.map +1 -0
- package/sdk/dist/plan-parser.d.ts +55 -0
- package/sdk/dist/plan-parser.d.ts.map +1 -0
- package/sdk/dist/plan-parser.js +391 -0
- package/sdk/dist/plan-parser.js.map +1 -0
- package/sdk/dist/planning-journal.d.ts +64 -0
- package/sdk/dist/planning-journal.d.ts.map +1 -0
- package/sdk/dist/planning-journal.js +88 -0
- package/sdk/dist/planning-journal.js.map +1 -0
- package/sdk/dist/planning-runtime.d.ts +67 -0
- package/sdk/dist/planning-runtime.d.ts.map +1 -0
- package/sdk/dist/planning-runtime.js +58 -0
- package/sdk/dist/planning-runtime.js.map +1 -0
- package/sdk/dist/project-root/index.d.ts +46 -0
- package/sdk/dist/project-root/index.d.ts.map +1 -0
- package/sdk/dist/project-root/index.js +138 -0
- package/sdk/dist/project-root/index.js.map +1 -0
- package/sdk/dist/prompt-builder.d.ts +44 -0
- package/sdk/dist/prompt-builder.d.ts.map +1 -0
- package/sdk/dist/prompt-builder.js +180 -0
- package/sdk/dist/prompt-builder.js.map +1 -0
- package/sdk/dist/prompt-sanitizer.d.ts +35 -0
- package/sdk/dist/prompt-sanitizer.d.ts.map +1 -0
- package/sdk/dist/prompt-sanitizer.js +101 -0
- package/sdk/dist/prompt-sanitizer.js.map +1 -0
- package/sdk/dist/query/active-workstream-store.d.ts +7 -0
- package/sdk/dist/query/active-workstream-store.d.ts.map +1 -0
- package/sdk/dist/query/active-workstream-store.js +56 -0
- package/sdk/dist/query/active-workstream-store.js.map +1 -0
- package/sdk/dist/query/agent-failure-classifier.d.ts +37 -0
- package/sdk/dist/query/agent-failure-classifier.d.ts.map +1 -0
- package/sdk/dist/query/agent-failure-classifier.js +82 -0
- package/sdk/dist/query/agent-failure-classifier.js.map +1 -0
- package/sdk/dist/query/audit-open.d.ts +46 -0
- package/sdk/dist/query/audit-open.d.ts.map +1 -0
- package/sdk/dist/query/audit-open.js +662 -0
- package/sdk/dist/query/audit-open.js.map +1 -0
- package/sdk/dist/query/check-auto-mode.d.ts +13 -0
- package/sdk/dist/query/check-auto-mode.d.ts.map +1 -0
- package/sdk/dist/query/check-auto-mode.js +40 -0
- package/sdk/dist/query/check-auto-mode.js.map +1 -0
- package/sdk/dist/query/check-completion.d.ts +10 -0
- package/sdk/dist/query/check-completion.d.ts.map +1 -0
- package/sdk/dist/query/check-completion.js +157 -0
- package/sdk/dist/query/check-completion.js.map +1 -0
- package/sdk/dist/query/check-decision-coverage.d.ts +33 -0
- package/sdk/dist/query/check-decision-coverage.d.ts.map +1 -0
- package/sdk/dist/query/check-decision-coverage.js +472 -0
- package/sdk/dist/query/check-decision-coverage.js.map +1 -0
- package/sdk/dist/query/check-gates.d.ts +10 -0
- package/sdk/dist/query/check-gates.d.ts.map +1 -0
- package/sdk/dist/query/check-gates.js +89 -0
- package/sdk/dist/query/check-gates.js.map +1 -0
- package/sdk/dist/query/check-verification-status.d.ts +10 -0
- package/sdk/dist/query/check-verification-status.d.ts.map +1 -0
- package/sdk/dist/query/check-verification-status.js +142 -0
- package/sdk/dist/query/check-verification-status.js.map +1 -0
- package/sdk/dist/query/command-aliases.generated.d.ts +31 -0
- package/sdk/dist/query/command-aliases.generated.d.ts.map +1 -0
- package/sdk/dist/query/command-aliases.generated.js +134 -0
- package/sdk/dist/query/command-aliases.generated.js.map +1 -0
- package/sdk/dist/query/command-catalog.d.ts +9 -0
- package/sdk/dist/query/command-catalog.d.ts.map +1 -0
- package/sdk/dist/query/command-catalog.js +17 -0
- package/sdk/dist/query/command-catalog.js.map +1 -0
- package/sdk/dist/query/command-definition.d.ts +19 -0
- package/sdk/dist/query/command-definition.d.ts.map +1 -0
- package/sdk/dist/query/command-definition.js +44 -0
- package/sdk/dist/query/command-definition.js.map +1 -0
- package/sdk/dist/query/command-family-handlers.d.ts +3 -0
- package/sdk/dist/query/command-family-handlers.d.ts.map +1 -0
- package/sdk/dist/query/command-family-handlers.js +93 -0
- package/sdk/dist/query/command-family-handlers.js.map +1 -0
- package/sdk/dist/query/command-manifest.d.ts +2 -0
- package/sdk/dist/query/command-manifest.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.init.d.ts +6 -0
- package/sdk/dist/query/command-manifest.init.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.init.js +22 -0
- package/sdk/dist/query/command-manifest.init.js.map +1 -0
- package/sdk/dist/query/command-manifest.js +17 -0
- package/sdk/dist/query/command-manifest.js.map +1 -0
- package/sdk/dist/query/command-manifest.non-family.d.ts +9 -0
- package/sdk/dist/query/command-manifest.non-family.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.non-family.js +62 -0
- package/sdk/dist/query/command-manifest.non-family.js.map +1 -0
- package/sdk/dist/query/command-manifest.phase.d.ts +6 -0
- package/sdk/dist/query/command-manifest.phase.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.phase.js +15 -0
- package/sdk/dist/query/command-manifest.phase.js.map +1 -0
- package/sdk/dist/query/command-manifest.phases.d.ts +7 -0
- package/sdk/dist/query/command-manifest.phases.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.phases.js +10 -0
- package/sdk/dist/query/command-manifest.phases.js.map +1 -0
- package/sdk/dist/query/command-manifest.roadmap.d.ts +6 -0
- package/sdk/dist/query/command-manifest.roadmap.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.roadmap.js +10 -0
- package/sdk/dist/query/command-manifest.roadmap.js.map +1 -0
- package/sdk/dist/query/command-manifest.state.d.ts +9 -0
- package/sdk/dist/query/command-manifest.state.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.state.js +30 -0
- package/sdk/dist/query/command-manifest.state.js.map +1 -0
- package/sdk/dist/query/command-manifest.types.d.ts +12 -0
- package/sdk/dist/query/command-manifest.types.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.types.js +2 -0
- package/sdk/dist/query/command-manifest.types.js.map +1 -0
- package/sdk/dist/query/command-manifest.validate.d.ts +6 -0
- package/sdk/dist/query/command-manifest.validate.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.validate.js +10 -0
- package/sdk/dist/query/command-manifest.validate.js.map +1 -0
- package/sdk/dist/query/command-manifest.verify.d.ts +6 -0
- package/sdk/dist/query/command-manifest.verify.d.ts.map +1 -0
- package/sdk/dist/query/command-manifest.verify.js +14 -0
- package/sdk/dist/query/command-manifest.verify.js.map +1 -0
- package/sdk/dist/query/command-static-catalog-domain.d.ts +3 -0
- package/sdk/dist/query/command-static-catalog-domain.d.ts.map +1 -0
- package/sdk/dist/query/command-static-catalog-domain.js +120 -0
- package/sdk/dist/query/command-static-catalog-domain.js.map +1 -0
- package/sdk/dist/query/command-static-catalog-foundation.d.ts +7 -0
- package/sdk/dist/query/command-static-catalog-foundation.d.ts.map +1 -0
- package/sdk/dist/query/command-static-catalog-foundation.js +95 -0
- package/sdk/dist/query/command-static-catalog-foundation.js.map +1 -0
- package/sdk/dist/query/command-topology.d.ts +32 -0
- package/sdk/dist/query/command-topology.d.ts.map +1 -0
- package/sdk/dist/query/command-topology.js +66 -0
- package/sdk/dist/query/command-topology.js.map +1 -0
- package/sdk/dist/query/commands-list.d.ts +14 -0
- package/sdk/dist/query/commands-list.d.ts.map +1 -0
- package/sdk/dist/query/commands-list.js +18 -0
- package/sdk/dist/query/commands-list.js.map +1 -0
- package/sdk/dist/query/commit.d.ts +79 -0
- package/sdk/dist/query/commit.d.ts.map +1 -0
- package/sdk/dist/query/commit.js +340 -0
- package/sdk/dist/query/commit.js.map +1 -0
- package/sdk/dist/query/config-gates.d.ts +12 -0
- package/sdk/dist/query/config-gates.d.ts.map +1 -0
- package/sdk/dist/query/config-gates.js +66 -0
- package/sdk/dist/query/config-gates.js.map +1 -0
- package/sdk/dist/query/config-mutation.d.ts +86 -0
- package/sdk/dist/query/config-mutation.d.ts.map +1 -0
- package/sdk/dist/query/config-mutation.js +445 -0
- package/sdk/dist/query/config-mutation.js.map +1 -0
- package/sdk/dist/query/config-query.d.ts +57 -0
- package/sdk/dist/query/config-query.d.ts.map +1 -0
- package/sdk/dist/query/config-query.js +208 -0
- package/sdk/dist/query/config-query.js.map +1 -0
- package/sdk/dist/query/config-schema.d.ts +19 -0
- package/sdk/dist/query/config-schema.d.ts.map +1 -0
- package/sdk/dist/query/config-schema.js +26 -0
- package/sdk/dist/query/config-schema.js.map +1 -0
- package/sdk/dist/query/decisions.d.ts +58 -0
- package/sdk/dist/query/decisions.d.ts.map +1 -0
- package/sdk/dist/query/decisions.js +161 -0
- package/sdk/dist/query/decisions.js.map +1 -0
- package/sdk/dist/query/detect-custom-files.d.ts +11 -0
- package/sdk/dist/query/detect-custom-files.d.ts.map +1 -0
- package/sdk/dist/query/detect-custom-files.js +89 -0
- package/sdk/dist/query/detect-custom-files.js.map +1 -0
- package/sdk/dist/query/detect-phase-type.d.ts +9 -0
- package/sdk/dist/query/detect-phase-type.d.ts.map +1 -0
- package/sdk/dist/query/detect-phase-type.js +124 -0
- package/sdk/dist/query/detect-phase-type.js.map +1 -0
- package/sdk/dist/query/docs-init.d.ts +26 -0
- package/sdk/dist/query/docs-init.d.ts.map +1 -0
- package/sdk/dist/query/docs-init.js +231 -0
- package/sdk/dist/query/docs-init.js.map +1 -0
- package/sdk/dist/query/fallow-audit.d.ts +44 -0
- package/sdk/dist/query/fallow-audit.d.ts.map +1 -0
- package/sdk/dist/query/fallow-audit.js +44 -0
- package/sdk/dist/query/fallow-audit.js.map +1 -0
- package/sdk/dist/query/frontmatter-mutation.d.ts +77 -0
- package/sdk/dist/query/frontmatter-mutation.d.ts.map +1 -0
- package/sdk/dist/query/frontmatter-mutation.js +317 -0
- package/sdk/dist/query/frontmatter-mutation.js.map +1 -0
- package/sdk/dist/query/frontmatter.d.ts +93 -0
- package/sdk/dist/query/frontmatter.d.ts.map +1 -0
- package/sdk/dist/query/frontmatter.js +365 -0
- package/sdk/dist/query/frontmatter.js.map +1 -0
- package/sdk/dist/query/helpers.d.ts +167 -0
- package/sdk/dist/query/helpers.d.ts.map +1 -0
- package/sdk/dist/query/helpers.js +495 -0
- package/sdk/dist/query/helpers.js.map +1 -0
- package/sdk/dist/query/index.d.ts +8 -0
- package/sdk/dist/query/index.d.ts.map +1 -0
- package/sdk/dist/query/index.js +6 -0
- package/sdk/dist/query/index.js.map +1 -0
- package/sdk/dist/query/init-complex.d.ts +47 -0
- package/sdk/dist/query/init-complex.d.ts.map +1 -0
- package/sdk/dist/query/init-complex.js +723 -0
- package/sdk/dist/query/init-complex.js.map +1 -0
- package/sdk/dist/query/init.d.ts +98 -0
- package/sdk/dist/query/init.d.ts.map +1 -0
- package/sdk/dist/query/init.js +1074 -0
- package/sdk/dist/query/init.js.map +1 -0
- package/sdk/dist/query/intel.d.ts +43 -0
- package/sdk/dist/query/intel.d.ts.map +1 -0
- package/sdk/dist/query/intel.js +416 -0
- package/sdk/dist/query/intel.js.map +1 -0
- package/sdk/dist/query/mutation-event-decorator.d.ts +5 -0
- package/sdk/dist/query/mutation-event-decorator.d.ts.map +1 -0
- package/sdk/dist/query/mutation-event-decorator.js +28 -0
- package/sdk/dist/query/mutation-event-decorator.js.map +1 -0
- package/sdk/dist/query/mutation-event-mapper.d.ts +4 -0
- package/sdk/dist/query/mutation-event-mapper.d.ts.map +1 -0
- package/sdk/dist/query/mutation-event-mapper.js +70 -0
- package/sdk/dist/query/mutation-event-mapper.js.map +1 -0
- package/sdk/dist/query/mvp.d.ts +113 -0
- package/sdk/dist/query/mvp.d.ts.map +1 -0
- package/sdk/dist/query/mvp.js +225 -0
- package/sdk/dist/query/mvp.js.map +1 -0
- package/sdk/dist/query/phase-filesystem-adapter.d.ts +4 -0
- package/sdk/dist/query/phase-filesystem-adapter.d.ts.map +1 -0
- package/sdk/dist/query/phase-filesystem-adapter.js +33 -0
- package/sdk/dist/query/phase-filesystem-adapter.js.map +1 -0
- package/sdk/dist/query/phase-lifecycle-policy.d.ts +34 -0
- package/sdk/dist/query/phase-lifecycle-policy.d.ts.map +1 -0
- package/sdk/dist/query/phase-lifecycle-policy.js +138 -0
- package/sdk/dist/query/phase-lifecycle-policy.js.map +1 -0
- package/sdk/dist/query/phase-lifecycle.d.ts +116 -0
- package/sdk/dist/query/phase-lifecycle.d.ts.map +1 -0
- package/sdk/dist/query/phase-lifecycle.js +1486 -0
- package/sdk/dist/query/phase-lifecycle.js.map +1 -0
- package/sdk/dist/query/phase-list-queries.d.ts +18 -0
- package/sdk/dist/query/phase-list-queries.d.ts.map +1 -0
- package/sdk/dist/query/phase-list-queries.js +129 -0
- package/sdk/dist/query/phase-list-queries.js.map +1 -0
- package/sdk/dist/query/phase-ready.d.ts +9 -0
- package/sdk/dist/query/phase-ready.d.ts.map +1 -0
- package/sdk/dist/query/phase-ready.js +132 -0
- package/sdk/dist/query/phase-ready.js.map +1 -0
- package/sdk/dist/query/phase-roadmap-mutation.d.ts +13 -0
- package/sdk/dist/query/phase-roadmap-mutation.d.ts.map +1 -0
- package/sdk/dist/query/phase-roadmap-mutation.js +65 -0
- package/sdk/dist/query/phase-roadmap-mutation.js.map +1 -0
- package/sdk/dist/query/phase.d.ts +48 -0
- package/sdk/dist/query/phase.d.ts.map +1 -0
- package/sdk/dist/query/phase.js +451 -0
- package/sdk/dist/query/phase.js.map +1 -0
- package/sdk/dist/query/pipeline.d.ts +53 -0
- package/sdk/dist/query/pipeline.d.ts.map +1 -0
- package/sdk/dist/query/pipeline.js +198 -0
- package/sdk/dist/query/pipeline.js.map +1 -0
- package/sdk/dist/query/plan-scan.d.ts +14 -0
- package/sdk/dist/query/plan-scan.d.ts.map +1 -0
- package/sdk/dist/query/plan-scan.js +70 -0
- package/sdk/dist/query/plan-scan.js.map +1 -0
- package/sdk/dist/query/plan-task-structure.d.ts +9 -0
- package/sdk/dist/query/plan-task-structure.d.ts.map +1 -0
- package/sdk/dist/query/plan-task-structure.js +59 -0
- package/sdk/dist/query/plan-task-structure.js.map +1 -0
- package/sdk/dist/query/profile-extract-messages.d.ts +40 -0
- package/sdk/dist/query/profile-extract-messages.d.ts.map +1 -0
- package/sdk/dist/query/profile-extract-messages.js +195 -0
- package/sdk/dist/query/profile-extract-messages.js.map +1 -0
- package/sdk/dist/query/profile-output.d.ts +11 -0
- package/sdk/dist/query/profile-output.d.ts.map +1 -0
- package/sdk/dist/query/profile-output.js +873 -0
- package/sdk/dist/query/profile-output.js.map +1 -0
- package/sdk/dist/query/profile-questionnaire-data.d.ts +21 -0
- package/sdk/dist/query/profile-questionnaire-data.d.ts.map +1 -0
- package/sdk/dist/query/profile-questionnaire-data.js +171 -0
- package/sdk/dist/query/profile-questionnaire-data.js.map +1 -0
- package/sdk/dist/query/profile-sample.d.ts +22 -0
- package/sdk/dist/query/profile-sample.d.ts.map +1 -0
- package/sdk/dist/query/profile-sample.js +136 -0
- package/sdk/dist/query/profile-sample.js.map +1 -0
- package/sdk/dist/query/profile-scan-sessions.d.ts +49 -0
- package/sdk/dist/query/profile-scan-sessions.d.ts.map +1 -0
- package/sdk/dist/query/profile-scan-sessions.js +137 -0
- package/sdk/dist/query/profile-scan-sessions.js.map +1 -0
- package/sdk/dist/query/profile.d.ts +61 -0
- package/sdk/dist/query/profile.d.ts.map +1 -0
- package/sdk/dist/query/profile.js +307 -0
- package/sdk/dist/query/profile.js.map +1 -0
- package/sdk/dist/query/progress.d.ts +77 -0
- package/sdk/dist/query/progress.d.ts.map +1 -0
- package/sdk/dist/query/progress.js +481 -0
- package/sdk/dist/query/progress.js.map +1 -0
- package/sdk/dist/query/query-cli-adapter.d.ts +8 -0
- package/sdk/dist/query/query-cli-adapter.d.ts.map +1 -0
- package/sdk/dist/query/query-cli-adapter.js +32 -0
- package/sdk/dist/query/query-cli-adapter.js.map +1 -0
- package/sdk/dist/query/query-cli-output.d.ts +9 -0
- package/sdk/dist/query/query-cli-output.d.ts.map +1 -0
- package/sdk/dist/query/query-cli-output.js +54 -0
- package/sdk/dist/query/query-cli-output.js.map +1 -0
- package/sdk/dist/query/query-command-diagnosis.d.ts +6 -0
- package/sdk/dist/query/query-command-diagnosis.d.ts.map +1 -0
- package/sdk/dist/query/query-command-diagnosis.js +6 -0
- package/sdk/dist/query/query-command-diagnosis.js.map +1 -0
- package/sdk/dist/query/query-command-resolution-strategy.d.ts +29 -0
- package/sdk/dist/query/query-command-resolution-strategy.d.ts.map +1 -0
- package/sdk/dist/query/query-command-resolution-strategy.js +103 -0
- package/sdk/dist/query/query-command-resolution-strategy.js.map +1 -0
- package/sdk/dist/query/query-command-semantics.d.ts +7 -0
- package/sdk/dist/query/query-command-semantics.d.ts.map +1 -0
- package/sdk/dist/query/query-command-semantics.js +7 -0
- package/sdk/dist/query/query-command-semantics.js.map +1 -0
- package/sdk/dist/query/query-dispatch-contract.d.ts +21 -0
- package/sdk/dist/query/query-dispatch-contract.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-contract.js +2 -0
- package/sdk/dist/query/query-dispatch-contract.js.map +1 -0
- package/sdk/dist/query/query-dispatch-error-mapper.d.ts +6 -0
- package/sdk/dist/query/query-dispatch-error-mapper.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-error-mapper.js +6 -0
- package/sdk/dist/query/query-dispatch-error-mapper.js.map +1 -0
- package/sdk/dist/query/query-dispatch-formatting.d.ts +6 -0
- package/sdk/dist/query/query-dispatch-formatting.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-formatting.js +6 -0
- package/sdk/dist/query/query-dispatch-formatting.js.map +1 -0
- package/sdk/dist/query/query-dispatch-input-validation.d.ts +6 -0
- package/sdk/dist/query/query-dispatch-input-validation.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-input-validation.js +6 -0
- package/sdk/dist/query/query-dispatch-input-validation.js.map +1 -0
- package/sdk/dist/query/query-dispatch-observability.d.ts +2 -0
- package/sdk/dist/query/query-dispatch-observability.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-observability.js +7 -0
- package/sdk/dist/query/query-dispatch-observability.js.map +1 -0
- package/sdk/dist/query/query-dispatch-plan.d.ts +6 -0
- package/sdk/dist/query/query-dispatch-plan.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-plan.js +6 -0
- package/sdk/dist/query/query-dispatch-plan.js.map +1 -0
- package/sdk/dist/query/query-dispatch-result-builder.d.ts +6 -0
- package/sdk/dist/query/query-dispatch-result-builder.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch-result-builder.js +6 -0
- package/sdk/dist/query/query-dispatch-result-builder.js.map +1 -0
- package/sdk/dist/query/query-dispatch.d.ts +48 -0
- package/sdk/dist/query/query-dispatch.d.ts.map +1 -0
- package/sdk/dist/query/query-dispatch.js +205 -0
- package/sdk/dist/query/query-dispatch.js.map +1 -0
- package/sdk/dist/query/query-error-details-schema.d.ts +19 -0
- package/sdk/dist/query/query-error-details-schema.d.ts.map +1 -0
- package/sdk/dist/query/query-error-details-schema.js +10 -0
- package/sdk/dist/query/query-error-details-schema.js.map +1 -0
- package/sdk/dist/query/query-error-taxonomy.d.ts +38 -0
- package/sdk/dist/query/query-error-taxonomy.d.ts.map +1 -0
- package/sdk/dist/query/query-error-taxonomy.js +74 -0
- package/sdk/dist/query/query-error-taxonomy.js.map +1 -0
- package/sdk/dist/query/query-fallback-bridge-adapter.d.ts +14 -0
- package/sdk/dist/query/query-fallback-bridge-adapter.d.ts.map +1 -0
- package/sdk/dist/query/query-fallback-bridge-adapter.js +33 -0
- package/sdk/dist/query/query-fallback-bridge-adapter.js.map +1 -0
- package/sdk/dist/query/query-fallback-executor.d.ts +11 -0
- package/sdk/dist/query/query-fallback-executor.d.ts.map +1 -0
- package/sdk/dist/query/query-fallback-executor.js +31 -0
- package/sdk/dist/query/query-fallback-executor.js.map +1 -0
- package/sdk/dist/query/query-fallback-output-classifier.d.ts +6 -0
- package/sdk/dist/query/query-fallback-output-classifier.d.ts.map +1 -0
- package/sdk/dist/query/query-fallback-output-classifier.js +27 -0
- package/sdk/dist/query/query-fallback-output-classifier.js.map +1 -0
- package/sdk/dist/query/query-fallback-policy.d.ts +6 -0
- package/sdk/dist/query/query-fallback-policy.d.ts.map +1 -0
- package/sdk/dist/query/query-fallback-policy.js +7 -0
- package/sdk/dist/query/query-fallback-policy.js.map +1 -0
- package/sdk/dist/query/query-native-dispatch-adapter.d.ts +7 -0
- package/sdk/dist/query/query-native-dispatch-adapter.d.ts.map +1 -0
- package/sdk/dist/query/query-native-dispatch-adapter.js +6 -0
- package/sdk/dist/query/query-native-dispatch-adapter.js.map +1 -0
- package/sdk/dist/query/query-policy-capability.d.ts +10 -0
- package/sdk/dist/query/query-policy-capability.d.ts.map +1 -0
- package/sdk/dist/query/query-policy-capability.js +17 -0
- package/sdk/dist/query/query-policy-capability.js.map +1 -0
- package/sdk/dist/query/query-runtime-context.d.ts +19 -0
- package/sdk/dist/query/query-runtime-context.d.ts.map +1 -0
- package/sdk/dist/query/query-runtime-context.js +31 -0
- package/sdk/dist/query/query-runtime-context.js.map +1 -0
- package/sdk/dist/query/query-unknown-command-hints.d.ts +2 -0
- package/sdk/dist/query/query-unknown-command-hints.d.ts.map +1 -0
- package/sdk/dist/query/query-unknown-command-hints.js +6 -0
- package/sdk/dist/query/query-unknown-command-hints.js.map +1 -0
- package/sdk/dist/query/registry-assembly-descriptor.d.ts +12 -0
- package/sdk/dist/query/registry-assembly-descriptor.d.ts.map +1 -0
- package/sdk/dist/query/registry-assembly-descriptor.js +61 -0
- package/sdk/dist/query/registry-assembly-descriptor.js.map +1 -0
- package/sdk/dist/query/registry-assembly-invariants.d.ts +30 -0
- package/sdk/dist/query/registry-assembly-invariants.d.ts.map +1 -0
- package/sdk/dist/query/registry-assembly-invariants.js +77 -0
- package/sdk/dist/query/registry-assembly-invariants.js.map +1 -0
- package/sdk/dist/query/registry-assembly.d.ts +10 -0
- package/sdk/dist/query/registry-assembly.d.ts.map +1 -0
- package/sdk/dist/query/registry-assembly.js +53 -0
- package/sdk/dist/query/registry-assembly.js.map +1 -0
- package/sdk/dist/query/registry.d.ts +90 -0
- package/sdk/dist/query/registry.d.ts.map +1 -0
- package/sdk/dist/query/registry.js +129 -0
- package/sdk/dist/query/registry.js.map +1 -0
- package/sdk/dist/query/requirements-extract-from-plans.d.ts +9 -0
- package/sdk/dist/query/requirements-extract-from-plans.d.ts.map +1 -0
- package/sdk/dist/query/requirements-extract-from-plans.js +76 -0
- package/sdk/dist/query/requirements-extract-from-plans.js.map +1 -0
- package/sdk/dist/query/roadmap-update-plan-progress.d.ts +11 -0
- package/sdk/dist/query/roadmap-update-plan-progress.d.ts.map +1 -0
- package/sdk/dist/query/roadmap-update-plan-progress.js +124 -0
- package/sdk/dist/query/roadmap-update-plan-progress.js.map +1 -0
- package/sdk/dist/query/roadmap.d.ts +137 -0
- package/sdk/dist/query/roadmap.d.ts.map +1 -0
- package/sdk/dist/query/roadmap.js +753 -0
- package/sdk/dist/query/roadmap.js.map +1 -0
- package/sdk/dist/query/route-next-action.d.ts +9 -0
- package/sdk/dist/query/route-next-action.d.ts.map +1 -0
- package/sdk/dist/query/route-next-action.js +342 -0
- package/sdk/dist/query/route-next-action.js.map +1 -0
- package/sdk/dist/query/schema-detect.d.ts +21 -0
- package/sdk/dist/query/schema-detect.d.ts.map +1 -0
- package/sdk/dist/query/schema-detect.js +146 -0
- package/sdk/dist/query/schema-detect.js.map +1 -0
- package/sdk/dist/query/secrets.d.ts +27 -0
- package/sdk/dist/query/secrets.d.ts.map +1 -0
- package/sdk/dist/query/secrets.js +42 -0
- package/sdk/dist/query/secrets.js.map +1 -0
- package/sdk/dist/query/skill-manifest.d.ts +50 -0
- package/sdk/dist/query/skill-manifest.d.ts.map +1 -0
- package/sdk/dist/query/skill-manifest.js +171 -0
- package/sdk/dist/query/skill-manifest.js.map +1 -0
- package/sdk/dist/query/skills.d.ts +27 -0
- package/sdk/dist/query/skills.d.ts.map +1 -0
- package/sdk/dist/query/skills.js +137 -0
- package/sdk/dist/query/skills.js.map +1 -0
- package/sdk/dist/query/state-document.d.ts +14 -0
- package/sdk/dist/query/state-document.d.ts.map +1 -0
- package/sdk/dist/query/state-document.js +110 -0
- package/sdk/dist/query/state-document.js.map +1 -0
- package/sdk/dist/query/state-mutation.d.ts +224 -0
- package/sdk/dist/query/state-mutation.d.ts.map +1 -0
- package/sdk/dist/query/state-mutation.js +1539 -0
- package/sdk/dist/query/state-mutation.js.map +1 -0
- package/sdk/dist/query/state-project-load.d.ts +23 -0
- package/sdk/dist/query/state-project-load.d.ts.map +1 -0
- package/sdk/dist/query/state-project-load.js +75 -0
- package/sdk/dist/query/state-project-load.js.map +1 -0
- package/sdk/dist/query/state.d.ts +78 -0
- package/sdk/dist/query/state.d.ts.map +1 -0
- package/sdk/dist/query/state.js +430 -0
- package/sdk/dist/query/state.js.map +1 -0
- package/sdk/dist/query/summary.d.ts +18 -0
- package/sdk/dist/query/summary.d.ts.map +1 -0
- package/sdk/dist/query/summary.js +249 -0
- package/sdk/dist/query/summary.js.map +1 -0
- package/sdk/dist/query/task-issues.d.ts +5 -0
- package/sdk/dist/query/task-issues.d.ts.map +1 -0
- package/sdk/dist/query/task-issues.js +72 -0
- package/sdk/dist/query/task-issues.js.map +1 -0
- package/sdk/dist/query/template.d.ts +46 -0
- package/sdk/dist/query/template.d.ts.map +1 -0
- package/sdk/dist/query/template.js +210 -0
- package/sdk/dist/query/template.js.map +1 -0
- package/sdk/dist/query/uat.d.ts +34 -0
- package/sdk/dist/query/uat.d.ts.map +1 -0
- package/sdk/dist/query/uat.js +339 -0
- package/sdk/dist/query/uat.js.map +1 -0
- package/sdk/dist/query/utils.d.ts +59 -0
- package/sdk/dist/query/utils.d.ts.map +1 -0
- package/sdk/dist/query/utils.js +74 -0
- package/sdk/dist/query/utils.js.map +1 -0
- package/sdk/dist/query/validate.d.ts +67 -0
- package/sdk/dist/query/validate.d.ts.map +1 -0
- package/sdk/dist/query/validate.js +908 -0
- package/sdk/dist/query/validate.js.map +1 -0
- package/sdk/dist/query/verify.d.ts +110 -0
- package/sdk/dist/query/verify.d.ts.map +1 -0
- package/sdk/dist/query/verify.js +647 -0
- package/sdk/dist/query/verify.js.map +1 -0
- package/sdk/dist/query/websearch.d.ts +24 -0
- package/sdk/dist/query/websearch.d.ts.map +1 -0
- package/sdk/dist/query/websearch.js +68 -0
- package/sdk/dist/query/websearch.js.map +1 -0
- package/sdk/dist/query/workspace.d.ts +62 -0
- package/sdk/dist/query/workspace.d.ts.map +1 -0
- package/sdk/dist/query/workspace.js +104 -0
- package/sdk/dist/query/workspace.js.map +1 -0
- package/sdk/dist/query/workstream-inventory.d.ts +24 -0
- package/sdk/dist/query/workstream-inventory.d.ts.map +1 -0
- package/sdk/dist/query/workstream-inventory.js +120 -0
- package/sdk/dist/query/workstream-inventory.js.map +1 -0
- package/sdk/dist/query/workstream.d.ts +35 -0
- package/sdk/dist/query/workstream.d.ts.map +1 -0
- package/sdk/dist/query/workstream.js +298 -0
- package/sdk/dist/query/workstream.js.map +1 -0
- package/sdk/dist/query/worktree.d.ts +3 -0
- package/sdk/dist/query/worktree.d.ts.map +1 -0
- package/sdk/dist/query/worktree.js +36 -0
- package/sdk/dist/query/worktree.js.map +1 -0
- package/sdk/dist/query-command-executor.d.ts +22 -0
- package/sdk/dist/query-command-executor.d.ts.map +1 -0
- package/sdk/dist/query-command-executor.js +22 -0
- package/sdk/dist/query-command-executor.js.map +1 -0
- package/sdk/dist/query-execution-policy.d.ts +24 -0
- package/sdk/dist/query-execution-policy.d.ts.map +1 -0
- package/sdk/dist/query-execution-policy.js +27 -0
- package/sdk/dist/query-execution-policy.js.map +1 -0
- package/sdk/dist/query-failure-classification.d.ts +9 -0
- package/sdk/dist/query-failure-classification.d.ts.map +1 -0
- package/sdk/dist/query-failure-classification.js +32 -0
- package/sdk/dist/query-failure-classification.js.map +1 -0
- package/sdk/dist/query-gtd-tools-path.d.ts +2 -0
- package/sdk/dist/query-gtd-tools-path.d.ts.map +1 -0
- package/sdk/dist/query-gtd-tools-path.js +2 -0
- package/sdk/dist/query-gtd-tools-path.js.map +1 -0
- package/sdk/dist/query-gtd-tools-runtime.d.ts +20 -0
- package/sdk/dist/query-gtd-tools-runtime.d.ts.map +1 -0
- package/sdk/dist/query-gtd-tools-runtime.js +47 -0
- package/sdk/dist/query-gtd-tools-runtime.js.map +1 -0
- package/sdk/dist/query-hotpath-methods.d.ts +19 -0
- package/sdk/dist/query-hotpath-methods.d.ts.map +1 -0
- package/sdk/dist/query-hotpath-methods.js +34 -0
- package/sdk/dist/query-hotpath-methods.js.map +1 -0
- package/sdk/dist/query-native-direct-adapter.d.ts +20 -0
- package/sdk/dist/query-native-direct-adapter.d.ts.map +1 -0
- package/sdk/dist/query-native-direct-adapter.js +52 -0
- package/sdk/dist/query-native-direct-adapter.js.map +1 -0
- package/sdk/dist/query-native-hotpath-adapter.d.ts +15 -0
- package/sdk/dist/query-native-hotpath-adapter.d.ts.map +1 -0
- package/sdk/dist/query-native-hotpath-adapter.js +32 -0
- package/sdk/dist/query-native-hotpath-adapter.js.map +1 -0
- package/sdk/dist/query-raw-output-projection.d.ts +6 -0
- package/sdk/dist/query-raw-output-projection.d.ts.map +1 -0
- package/sdk/dist/query-raw-output-projection.js +67 -0
- package/sdk/dist/query-raw-output-projection.js.map +1 -0
- package/sdk/dist/query-runtime-bridge.d.ts +61 -0
- package/sdk/dist/query-runtime-bridge.d.ts.map +1 -0
- package/sdk/dist/query-runtime-bridge.js +144 -0
- package/sdk/dist/query-runtime-bridge.js.map +1 -0
- package/sdk/dist/query-subprocess-adapter.d.ts +18 -0
- package/sdk/dist/query-subprocess-adapter.d.ts.map +1 -0
- package/sdk/dist/query-subprocess-adapter.js +92 -0
- package/sdk/dist/query-subprocess-adapter.js.map +1 -0
- package/sdk/dist/query-tools-error-factory.d.ts +16 -0
- package/sdk/dist/query-tools-error-factory.d.ts.map +1 -0
- package/sdk/dist/query-tools-error-factory.js +33 -0
- package/sdk/dist/query-tools-error-factory.js.map +1 -0
- package/sdk/dist/research-gate.d.ts +24 -0
- package/sdk/dist/research-gate.d.ts.map +1 -0
- package/sdk/dist/research-gate.js +70 -0
- package/sdk/dist/research-gate.js.map +1 -0
- package/sdk/dist/runtime-bridge-sync/index.d.ts +96 -0
- package/sdk/dist/runtime-bridge-sync/index.d.ts.map +1 -0
- package/sdk/dist/runtime-bridge-sync/index.js +109 -0
- package/sdk/dist/runtime-bridge-sync/index.js.map +1 -0
- package/sdk/dist/runtime-bridge-sync/worker.d.ts +2 -0
- package/sdk/dist/runtime-bridge-sync/worker.d.ts.map +1 -0
- package/sdk/dist/runtime-bridge-sync/worker.js +138 -0
- package/sdk/dist/runtime-bridge-sync/worker.js.map +1 -0
- package/sdk/dist/runtime-gate.d.ts +14 -0
- package/sdk/dist/runtime-gate.d.ts.map +1 -0
- package/sdk/dist/runtime-gate.js +48 -0
- package/sdk/dist/runtime-gate.js.map +1 -0
- package/sdk/dist/sdk-package-compatibility.d.ts +40 -0
- package/sdk/dist/sdk-package-compatibility.d.ts.map +1 -0
- package/sdk/dist/sdk-package-compatibility.js +94 -0
- package/sdk/dist/sdk-package-compatibility.js.map +1 -0
- package/sdk/dist/session-runner.d.ts +40 -0
- package/sdk/dist/session-runner.d.ts.map +1 -0
- package/sdk/dist/session-runner.js +274 -0
- package/sdk/dist/session-runner.js.map +1 -0
- package/sdk/dist/task-issues/adapters.d.ts +94 -0
- package/sdk/dist/task-issues/adapters.d.ts.map +1 -0
- package/sdk/dist/task-issues/adapters.js +2 -0
- package/sdk/dist/task-issues/adapters.js.map +1 -0
- package/sdk/dist/task-issues/core.d.ts +16 -0
- package/sdk/dist/task-issues/core.d.ts.map +1 -0
- package/sdk/dist/task-issues/core.js +283 -0
- package/sdk/dist/task-issues/core.js.map +1 -0
- package/sdk/dist/task-issues/export-phase-issues.d.ts +326 -0
- package/sdk/dist/task-issues/export-phase-issues.d.ts.map +1 -0
- package/sdk/dist/task-issues/export-phase-issues.js +1675 -0
- package/sdk/dist/task-issues/export-phase-issues.js.map +1 -0
- package/sdk/dist/task-issues/github-api-client.d.ts +23 -0
- package/sdk/dist/task-issues/github-api-client.d.ts.map +1 -0
- package/sdk/dist/task-issues/github-api-client.js +66 -0
- package/sdk/dist/task-issues/github-api-client.js.map +1 -0
- package/sdk/dist/task-issues/github-repo.d.ts +4 -0
- package/sdk/dist/task-issues/github-repo.d.ts.map +1 -0
- package/sdk/dist/task-issues/github-repo.js +108 -0
- package/sdk/dist/task-issues/github-repo.js.map +1 -0
- package/sdk/dist/task-issues/orchestrate-tasks.d.ts +319 -0
- package/sdk/dist/task-issues/orchestrate-tasks.d.ts.map +1 -0
- package/sdk/dist/task-issues/orchestrate-tasks.js +2040 -0
- package/sdk/dist/task-issues/orchestrate-tasks.js.map +1 -0
- package/sdk/dist/task-issues/plan-scan.d.ts +13 -0
- package/sdk/dist/task-issues/plan-scan.d.ts.map +1 -0
- package/sdk/dist/task-issues/plan-scan.js +70 -0
- package/sdk/dist/task-issues/plan-scan.js.map +1 -0
- package/sdk/dist/task-issues/runtime-slash.d.ts +4 -0
- package/sdk/dist/task-issues/runtime-slash.d.ts.map +1 -0
- package/sdk/dist/task-issues/runtime-slash.js +40 -0
- package/sdk/dist/task-issues/runtime-slash.js.map +1 -0
- package/sdk/dist/task-issues/task-issue-shared.d.ts +18 -0
- package/sdk/dist/task-issues/task-issue-shared.d.ts.map +1 -0
- package/sdk/dist/task-issues/task-issue-shared.js +44 -0
- package/sdk/dist/task-issues/task-issue-shared.js.map +1 -0
- package/sdk/dist/task-issues/types.d.ts +30 -0
- package/sdk/dist/task-issues/types.d.ts.map +1 -0
- package/sdk/dist/task-issues/types.js +2 -0
- package/sdk/dist/task-issues/types.js.map +1 -0
- package/sdk/dist/task-issues/work-task-issue.d.ts +1199 -0
- package/sdk/dist/task-issues/work-task-issue.d.ts.map +1 -0
- package/sdk/dist/task-issues/work-task-issue.js +3255 -0
- package/sdk/dist/task-issues/work-task-issue.js.map +1 -0
- package/sdk/dist/task-issues/worktree-safety.d.ts +5 -0
- package/sdk/dist/task-issues/worktree-safety.d.ts.map +1 -0
- package/sdk/dist/task-issues/worktree-safety.js +18 -0
- package/sdk/dist/task-issues/worktree-safety.js.map +1 -0
- package/sdk/dist/tool-scoping.d.ts +31 -0
- package/sdk/dist/tool-scoping.d.ts.map +1 -0
- package/sdk/dist/tool-scoping.js +54 -0
- package/sdk/dist/tool-scoping.js.map +1 -0
- package/sdk/dist/types.d.ts +795 -0
- package/sdk/dist/types.d.ts.map +1 -0
- package/sdk/dist/types.js +77 -0
- package/sdk/dist/types.js.map +1 -0
- package/sdk/dist/workstream-inventory/builder.d.ts +88 -0
- package/sdk/dist/workstream-inventory/builder.d.ts.map +1 -0
- package/sdk/dist/workstream-inventory/builder.js +84 -0
- package/sdk/dist/workstream-inventory/builder.js.map +1 -0
- package/sdk/dist/workstream-name-policy.d.ts +13 -0
- package/sdk/dist/workstream-name-policy.d.ts.map +1 -0
- package/sdk/dist/workstream-name-policy.js +24 -0
- package/sdk/dist/workstream-name-policy.js.map +1 -0
- package/sdk/dist/workstream-utils.d.ts +23 -0
- package/sdk/dist/workstream-utils.d.ts.map +1 -0
- package/sdk/dist/workstream-utils.js +34 -0
- package/sdk/dist/workstream-utils.js.map +1 -0
- package/sdk/dist/ws-transport.d.ts +32 -0
- package/sdk/dist/ws-transport.d.ts.map +1 -0
- package/sdk/dist/ws-transport.js +84 -0
- package/sdk/dist/ws-transport.js.map +1 -0
- package/sdk/package-lock.json +2530 -0
- package/sdk/package.json +67 -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/shared/config-defaults.manifest.json +71 -0
- package/sdk/shared/config-schema.manifest.json +139 -0
- package/sdk/shared/model-catalog.json +122 -0
- package/sdk/src/assembled-prompts.test.ts +349 -0
- package/sdk/src/bug-3589-planning-paths-validation.test.ts +89 -0
- package/sdk/src/bug-3591-gtdtools-runtime-workstream.test.ts +179 -0
- package/sdk/src/cli-transport.test.ts +388 -0
- package/sdk/src/cli-transport.ts +130 -0
- package/sdk/src/cli.test.ts +426 -0
- package/sdk/src/cli.ts +589 -0
- package/sdk/src/config.test.ts +277 -0
- package/sdk/src/config.ts +201 -0
- package/sdk/src/configuration/index.test.ts +318 -0
- package/sdk/src/configuration/index.ts +325 -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 +181 -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/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 +17 -0
- package/sdk/src/golden/golden-policy.test.ts +8 -0
- package/sdk/src/golden/golden-policy.ts +118 -0
- package/sdk/src/golden/golden.integration.test.ts +897 -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 +133 -0
- package/sdk/src/golden/registry-canonical-commands.ts +31 -0
- package/sdk/src/gtd-tools-error.test.ts +21 -0
- package/sdk/src/gtd-tools-error.ts +65 -0
- package/sdk/src/gtd-tools.test.ts +472 -0
- package/sdk/src/gtd-tools.ts +285 -0
- package/sdk/src/gtd-transport-policy.test.ts +34 -0
- package/sdk/src/gtd-transport-policy.ts +48 -0
- package/sdk/src/gtd-transport.test.ts +292 -0
- package/sdk/src/gtd-transport.ts +117 -0
- package/sdk/src/index.ts +371 -0
- package/sdk/src/init-e2e.integration.test.ts +138 -0
- package/sdk/src/init-runner.test.ts +740 -0
- package/sdk/src/init-runner.ts +734 -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/model-catalog.ts +77 -0
- package/sdk/src/phase-prompt.test.ts +536 -0
- package/sdk/src/phase-prompt.ts +257 -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 +2720 -0
- package/sdk/src/phase-runner.ts +1442 -0
- package/sdk/src/plan-atomicity.test.ts +220 -0
- package/sdk/src/plan-atomicity.ts +162 -0
- package/sdk/src/plan-parser.test.ts +579 -0
- package/sdk/src/plan-parser.ts +433 -0
- package/sdk/src/planning-journal.test.ts +70 -0
- package/sdk/src/planning-journal.ts +153 -0
- package/sdk/src/planning-runtime.test.ts +29 -0
- package/sdk/src/planning-runtime.ts +100 -0
- package/sdk/src/project-root/index.test.ts +186 -0
- package/sdk/src/project-root/index.ts +144 -0
- package/sdk/src/prompt-builder.test.ts +318 -0
- package/sdk/src/prompt-builder.ts +218 -0
- package/sdk/src/prompt-sanitizer.test.ts +260 -0
- package/sdk/src/prompt-sanitizer.ts +116 -0
- package/sdk/src/query/QUERY-HANDLERS.md +346 -0
- package/sdk/src/query/active-workstream-store.ts +50 -0
- package/sdk/src/query/agent-failure-classifier.test.ts +157 -0
- package/sdk/src/query/agent-failure-classifier.ts +104 -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 +49 -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-decision-coverage.test.ts +519 -0
- package/sdk/src/query/check-decision-coverage.ts +554 -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-verification-status.test.ts +143 -0
- package/sdk/src/query/check-verification-status.ts +160 -0
- package/sdk/src/query/command-aliases.generated.ts +155 -0
- package/sdk/src/query/command-catalog.ts +31 -0
- package/sdk/src/query/command-definition.test.ts +47 -0
- package/sdk/src/query/command-definition.ts +70 -0
- package/sdk/src/query/command-family-handlers.ts +116 -0
- package/sdk/src/query/command-manifest.init.ts +23 -0
- package/sdk/src/query/command-manifest.non-family.ts +89 -0
- package/sdk/src/query/command-manifest.phase.ts +16 -0
- package/sdk/src/query/command-manifest.phases.ts +11 -0
- package/sdk/src/query/command-manifest.roadmap.ts +11 -0
- package/sdk/src/query/command-manifest.state.ts +31 -0
- package/sdk/src/query/command-manifest.ts +17 -0
- package/sdk/src/query/command-manifest.types.ts +13 -0
- package/sdk/src/query/command-manifest.validate.ts +11 -0
- package/sdk/src/query/command-manifest.verify.ts +15 -0
- package/sdk/src/query/command-resolution.test.ts +70 -0
- package/sdk/src/query/command-seam-coverage.test.ts +118 -0
- package/sdk/src/query/command-static-catalog-domain.ts +121 -0
- package/sdk/src/query/command-static-catalog-foundation.ts +100 -0
- package/sdk/src/query/command-topology.test.ts +28 -0
- package/sdk/src/query/command-topology.ts +114 -0
- package/sdk/src/query/commands-list.test.ts +36 -0
- package/sdk/src/query/commands-list.ts +19 -0
- package/sdk/src/query/commit.test.ts +485 -0
- package/sdk/src/query/commit.ts +383 -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 +572 -0
- package/sdk/src/query/config-mutation.ts +484 -0
- package/sdk/src/query/config-query.test.ts +367 -0
- package/sdk/src/query/config-query.ts +244 -0
- package/sdk/src/query/config-schema.ts +35 -0
- package/sdk/src/query/decisions.test.ts +215 -0
- package/sdk/src/query/decisions.ts +192 -0
- package/sdk/src/query/decomposed-handlers.test.ts +431 -0
- package/sdk/src/query/detect-custom-files.test.ts +115 -0
- package/sdk/src/query/detect-custom-files.ts +96 -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 +258 -0
- package/sdk/src/query/fallow-audit.ts +88 -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 +326 -0
- package/sdk/src/query/frontmatter.ts +395 -0
- package/sdk/src/query/helpers.test.ts +615 -0
- package/sdk/src/query/helpers.ts +523 -0
- package/sdk/src/query/index-thin-seam.test.ts +16 -0
- package/sdk/src/query/index.ts +9 -0
- package/sdk/src/query/init-complex.test.ts +616 -0
- package/sdk/src/query/init-complex.ts +805 -0
- package/sdk/src/query/init-progress-precedence.test.ts +177 -0
- package/sdk/src/query/init-workstream-milestone-op.test.ts +321 -0
- package/sdk/src/query/init.test.ts +645 -0
- package/sdk/src/query/init.ts +1167 -0
- package/sdk/src/query/intel.test.ts +90 -0
- package/sdk/src/query/intel.ts +404 -0
- package/sdk/src/query/mutation-event-decorator.test.ts +45 -0
- package/sdk/src/query/mutation-event-decorator.ts +37 -0
- package/sdk/src/query/mutation-event-mapper.test.ts +33 -0
- package/sdk/src/query/mutation-event-mapper.ts +102 -0
- package/sdk/src/query/mvp.test.ts +335 -0
- package/sdk/src/query/mvp.ts +292 -0
- package/sdk/src/query/normalize-query-command.test.ts +102 -0
- package/sdk/src/query/phase-filesystem-adapter.ts +35 -0
- package/sdk/src/query/phase-lifecycle-policy.ts +171 -0
- package/sdk/src/query/phase-lifecycle.test.ts +1750 -0
- package/sdk/src/query/phase-lifecycle.ts +1833 -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 +159 -0
- package/sdk/src/query/phase-roadmap-mutation.ts +77 -0
- package/sdk/src/query/phase.test.ts +651 -0
- package/sdk/src/query/phase.ts +550 -0
- package/sdk/src/query/pipeline.test.ts +169 -0
- package/sdk/src/query/pipeline.ts +243 -0
- package/sdk/src/query/plan-scan.test.ts +35 -0
- package/sdk/src/query/plan-scan.ts +82 -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/policy-convergence.test.ts +28 -0
- package/sdk/src/query/profile-extract-messages.ts +247 -0
- package/sdk/src/query/profile-output.ts +929 -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 +136 -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/query-cli-adapter.test.ts +79 -0
- package/sdk/src/query/query-cli-adapter.ts +39 -0
- package/sdk/src/query/query-cli-output.test.ts +33 -0
- package/sdk/src/query/query-cli-output.ts +63 -0
- package/sdk/src/query/query-command-diagnosis.test.ts +22 -0
- package/sdk/src/query/query-command-diagnosis.ts +5 -0
- package/sdk/src/query/query-command-resolution-strategy.test.ts +34 -0
- package/sdk/src/query/query-command-resolution-strategy.ts +121 -0
- package/sdk/src/query/query-command-semantics.test.ts +22 -0
- package/sdk/src/query/query-command-semantics.ts +22 -0
- package/sdk/src/query/query-dispatch-contract.ts +30 -0
- package/sdk/src/query/query-dispatch-error-mapper.test.ts +62 -0
- package/sdk/src/query/query-dispatch-error-mapper.ts +5 -0
- package/sdk/src/query/query-dispatch-formatting.test.ts +28 -0
- package/sdk/src/query/query-dispatch-formatting.ts +5 -0
- package/sdk/src/query/query-dispatch-input-validation.test.ts +23 -0
- package/sdk/src/query/query-dispatch-input-validation.ts +5 -0
- package/sdk/src/query/query-dispatch-observability.test.ts +10 -0
- package/sdk/src/query/query-dispatch-observability.ts +6 -0
- package/sdk/src/query/query-dispatch-plan.test.ts +25 -0
- package/sdk/src/query/query-dispatch-plan.ts +5 -0
- package/sdk/src/query/query-dispatch-result-builder.test.ts +16 -0
- package/sdk/src/query/query-dispatch-result-builder.ts +5 -0
- package/sdk/src/query/query-dispatch.test.ts +399 -0
- package/sdk/src/query/query-dispatch.ts +275 -0
- package/sdk/src/query/query-error-details-schema.ts +29 -0
- package/sdk/src/query/query-error-taxonomy.test.ts +39 -0
- package/sdk/src/query/query-error-taxonomy.ts +117 -0
- package/sdk/src/query/query-fallback-bridge-adapter.test.ts +32 -0
- package/sdk/src/query/query-fallback-bridge-adapter.ts +54 -0
- package/sdk/src/query/query-fallback-executor.test.ts +82 -0
- package/sdk/src/query/query-fallback-executor.ts +44 -0
- package/sdk/src/query/query-fallback-output-classifier.test.ts +36 -0
- package/sdk/src/query/query-fallback-output-classifier.ts +31 -0
- package/sdk/src/query/query-fallback-policy.test.ts +13 -0
- package/sdk/src/query/query-fallback-policy.ts +11 -0
- package/sdk/src/query/query-native-dispatch-adapter.ts +16 -0
- package/sdk/src/query/query-policy-capability.test.ts +10 -0
- package/sdk/src/query/query-policy-capability.ts +26 -0
- package/sdk/src/query/query-policy-snapshot.test.ts +9 -0
- package/sdk/src/query/query-registry-capability.test.ts +14 -0
- package/sdk/src/query/query-runtime-context.ts +44 -0
- package/sdk/src/query/query-unknown-command-hints.test.ts +9 -0
- package/sdk/src/query/query-unknown-command-hints.ts +5 -0
- package/sdk/src/query/registry-assembly-descriptor.ts +87 -0
- package/sdk/src/query/registry-assembly-invariants.ts +127 -0
- package/sdk/src/query/registry-assembly.test.ts +138 -0
- package/sdk/src/query/registry-assembly.ts +78 -0
- package/sdk/src/query/registry.test.ts +208 -0
- package/sdk/src/query/registry.ts +142 -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.test.ts +233 -0
- package/sdk/src/query/roadmap-update-plan-progress.ts +159 -0
- package/sdk/src/query/roadmap.test.ts +1181 -0
- package/sdk/src/query/roadmap.ts +894 -0
- package/sdk/src/query/route-next-action.test.ts +142 -0
- package/sdk/src/query/route-next-action.ts +370 -0
- package/sdk/src/query/schema-detect.ts +189 -0
- package/sdk/src/query/secrets.test.ts +66 -0
- package/sdk/src/query/secrets.ts +43 -0
- package/sdk/src/query/skill-manifest.test.ts +62 -0
- package/sdk/src/query/skill-manifest.ts +216 -0
- package/sdk/src/query/skills.test.ts +234 -0
- package/sdk/src/query/skills.ts +143 -0
- package/sdk/src/query/state-document.test.ts +197 -0
- package/sdk/src/query/state-document.ts +129 -0
- package/sdk/src/query/state-mutation.test.ts +1198 -0
- package/sdk/src/query/state-mutation.ts +1718 -0
- package/sdk/src/query/state-project-load.ts +80 -0
- package/sdk/src/query/state.test.ts +616 -0
- package/sdk/src/query/state.ts +463 -0
- package/sdk/src/query/sub-repos-root.integration.test.ts +79 -0
- package/sdk/src/query/summary.test.ts +95 -0
- package/sdk/src/query/summary.ts +296 -0
- package/sdk/src/query/task-issues.ts +86 -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 +365 -0
- package/sdk/src/query/utils.test.ts +82 -0
- package/sdk/src/query/utils.ts +106 -0
- package/sdk/src/query/validate.test.ts +831 -0
- package/sdk/src/query/validate.ts +952 -0
- package/sdk/src/query/verify.test.ts +416 -0
- package/sdk/src/query/verify.ts +711 -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 +120 -0
- package/sdk/src/query/workspace.ts +145 -0
- package/sdk/src/query/workstream-inventory.ts +143 -0
- package/sdk/src/query/workstream.test.ts +153 -0
- package/sdk/src/query/workstream.ts +324 -0
- package/sdk/src/query/worktree.ts +39 -0
- package/sdk/src/query-command-executor.ts +31 -0
- package/sdk/src/query-execution-policy.test.ts +52 -0
- package/sdk/src/query-execution-policy.ts +46 -0
- package/sdk/src/query-failure-classification.test.ts +23 -0
- package/sdk/src/query-failure-classification.ts +42 -0
- package/sdk/src/query-gtd-tools-path.ts +1 -0
- package/sdk/src/query-gtd-tools-runtime.ts +89 -0
- package/sdk/src/query-hotpath-methods.ts +48 -0
- package/sdk/src/query-native-direct-adapter.test.ts +35 -0
- package/sdk/src/query-native-direct-adapter.ts +70 -0
- package/sdk/src/query-native-hotpath-adapter.test.ts +43 -0
- package/sdk/src/query-native-hotpath-adapter.ts +45 -0
- package/sdk/src/query-raw-output-projection.test.ts +39 -0
- package/sdk/src/query-raw-output-projection.ts +74 -0
- package/sdk/src/query-runtime-bridge.test.ts +150 -0
- package/sdk/src/query-runtime-bridge.ts +215 -0
- package/sdk/src/query-runtime-seam-coverage.test.ts +20 -0
- package/sdk/src/query-subprocess-adapter.test.ts +84 -0
- package/sdk/src/query-subprocess-adapter.ts +146 -0
- package/sdk/src/query-tools-error-factory.test.ts +35 -0
- package/sdk/src/query-tools-error-factory.ts +76 -0
- package/sdk/src/research-gate.test.ts +190 -0
- package/sdk/src/research-gate.ts +94 -0
- package/sdk/src/runtime-bridge-options.test.ts +33 -0
- package/sdk/src/runtime-bridge-sync/index.test.ts +164 -0
- package/sdk/src/runtime-bridge-sync/index.ts +154 -0
- package/sdk/src/runtime-bridge-sync/projectdir-regression.test.ts +151 -0
- package/sdk/src/runtime-bridge-sync/worker.ts +181 -0
- package/sdk/src/runtime-gate.test.ts +84 -0
- package/sdk/src/runtime-gate.ts +52 -0
- package/sdk/src/sdk-package-compatibility.test.ts +100 -0
- package/sdk/src/sdk-package-compatibility.ts +149 -0
- package/sdk/src/session-runner.test.ts +164 -0
- package/sdk/src/session-runner.ts +327 -0
- package/sdk/src/task-issues/adapters.ts +86 -0
- package/sdk/src/task-issues/core.ts +287 -0
- package/sdk/src/task-issues/export-phase-issues.ts +1862 -0
- package/sdk/src/task-issues/github-api-client.ts +107 -0
- package/sdk/src/task-issues/github-repo.ts +111 -0
- package/sdk/src/task-issues/orchestrate-tasks.ts +2167 -0
- package/sdk/src/task-issues/plan-scan.ts +78 -0
- package/sdk/src/task-issues/runtime-slash.ts +37 -0
- package/sdk/src/task-issues/task-issue-shared.ts +48 -0
- package/sdk/src/task-issues/types.ts +34 -0
- package/sdk/src/task-issues/work-task-issue.ts +3429 -0
- package/sdk/src/task-issues/worktree-safety.ts +15 -0
- package/sdk/src/task-issues-sdk.test.ts +182 -0
- package/sdk/src/tool-scoping.test.ts +160 -0
- package/sdk/src/tool-scoping.ts +61 -0
- package/sdk/src/types.ts +928 -0
- package/sdk/src/workflow-agent-skills-consistency.test.ts +98 -0
- package/sdk/src/workstream-inventory/builder.test.ts +241 -0
- package/sdk/src/workstream-inventory/builder.ts +170 -0
- package/sdk/src/workstream-name-policy.ts +24 -0
- package/sdk/src/workstream-utils.ts +36 -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,1486 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase lifecycle handlers — add, insert, scaffold operations.
|
|
3
|
+
*
|
|
4
|
+
* Ported from get-tasks-done/bin/lib/phase.cjs and commands.cjs.
|
|
5
|
+
* Provides phaseAdd (append phase), phaseAddBatch (append multiple phases),
|
|
6
|
+
* phaseInsert (decimal phase insertion), and phaseScaffold (template file/directory creation).
|
|
7
|
+
*
|
|
8
|
+
* Shared helpers replaceInCurrentMilestone and readModifyWriteRoadmapMd
|
|
9
|
+
* are exported for use by downstream handlers (phaseComplete in Plan 03).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { phaseAdd, phaseInsert, phaseScaffold } from './phase-lifecycle.js';
|
|
14
|
+
*
|
|
15
|
+
* await phaseAdd(['New Feature'], '/project');
|
|
16
|
+
* await phaseInsert(['10', 'Urgent Fix'], '/project');
|
|
17
|
+
* await phaseScaffold(['context', '9'], '/project');
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { readFile, writeFile, mkdir, readdir, rename, rm } from 'node:fs/promises';
|
|
21
|
+
import { existsSync } from 'node:fs';
|
|
22
|
+
import { join, relative } from 'node:path';
|
|
23
|
+
import { GTDError, ErrorClassification } from '../errors.js';
|
|
24
|
+
import { escapeRegex, normalizeMd, normalizePhaseName, comparePhaseNum, phaseTokenMatches, toPosixPath, planningPaths, } from './helpers.js';
|
|
25
|
+
import { extractFrontmatter } from './frontmatter.js';
|
|
26
|
+
import { extractCurrentMilestone } from './roadmap.js';
|
|
27
|
+
import { getMilestonePhaseFilter } from './state.js';
|
|
28
|
+
import { acquireStateLock, readModifyWriteStateMdFull, releaseStateLock, stateReplaceField, } from './state-mutation.js';
|
|
29
|
+
import { stateExtractField, stateReplaceFieldWithFallback } from './state-document.js';
|
|
30
|
+
import { assertNoNullBytes, assertSafePhaseDirName, assertSafeProjectCode, buildPhaseRoadmapEntry, collectDecimalSuffixesFromDirNames, collectDecimalSuffixesFromRoadmap, computeNextDecimalPhase, computeNextSequentialPhaseId, computePhaseDirectory, extractOneLinerFromBody, generatePhaseSlug, parseMultiwordArg, } from './phase-lifecycle-policy.js';
|
|
31
|
+
import { archiveDirectories, ensureDirectoryWithGitkeep, listDirectories, } from './phase-filesystem-adapter.js';
|
|
32
|
+
import { readModifyWriteRoadmapMd, replaceInCurrentMilestone, } from './phase-roadmap-mutation.js';
|
|
33
|
+
export { readModifyWriteRoadmapMd, replaceInCurrentMilestone };
|
|
34
|
+
// ─── phaseAdd handler ───────────────────────────────────────────────────
|
|
35
|
+
/**
|
|
36
|
+
* Query handler for phase.add.
|
|
37
|
+
*
|
|
38
|
+
* Port of cmdPhaseAdd from phase.cjs lines 312-392.
|
|
39
|
+
* Creates a new phase directory with .gitkeep, appends a phase section
|
|
40
|
+
* to ROADMAP.md before the last "---" separator.
|
|
41
|
+
*
|
|
42
|
+
* @param args - description (required), optional customId, optional --dry-run flag.
|
|
43
|
+
* Recognized flags: --dry-run (compute result without writing to disk).
|
|
44
|
+
* Any other --flag argument is rejected with a validation error.
|
|
45
|
+
* @param projectDir - Project root directory
|
|
46
|
+
* @returns QueryResult with { phase_number, padded, name, slug, directory, naming_mode }
|
|
47
|
+
* In --dry-run mode also includes { dry_run: true, roadmap_entry: string }
|
|
48
|
+
*/
|
|
49
|
+
export const phaseAdd = async (args, projectDir, workstream) => {
|
|
50
|
+
// ── Flag parsing ────────────────────────────────────────────────────────
|
|
51
|
+
// Separate recognized flags from positional args. Any unrecognized --flag
|
|
52
|
+
// is rejected immediately so it is never silently absorbed into positional slots.
|
|
53
|
+
const RECOGNIZED_FLAGS = new Set(['--dry-run']);
|
|
54
|
+
let dryRun = false;
|
|
55
|
+
const positional = [];
|
|
56
|
+
for (const arg of args) {
|
|
57
|
+
if (arg.startsWith('--')) {
|
|
58
|
+
if (!RECOGNIZED_FLAGS.has(arg)) {
|
|
59
|
+
throw new GTDError(`Unknown flag ${arg} for phase.add`, ErrorClassification.Validation);
|
|
60
|
+
}
|
|
61
|
+
if (arg === '--dry-run')
|
|
62
|
+
dryRun = true;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
positional.push(arg);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const description = positional[0];
|
|
69
|
+
if (!description) {
|
|
70
|
+
throw new GTDError('description required for phase add', ErrorClassification.Validation);
|
|
71
|
+
}
|
|
72
|
+
assertNoNullBytes(description, 'description');
|
|
73
|
+
const configPath = planningPaths(projectDir, workstream).config;
|
|
74
|
+
let config = {};
|
|
75
|
+
try {
|
|
76
|
+
config = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
77
|
+
}
|
|
78
|
+
catch { /* use defaults */ }
|
|
79
|
+
const slug = generatePhaseSlug(description);
|
|
80
|
+
// positional[1] is the optional customId — flags are already stripped
|
|
81
|
+
const customId = positional[1] || null;
|
|
82
|
+
// Optional project code prefix (e.g., 'CK' -> 'CK-01-foundation')
|
|
83
|
+
const projectCode = config.project_code || '';
|
|
84
|
+
assertSafeProjectCode(projectCode);
|
|
85
|
+
const prefix = projectCode ? `${projectCode}-` : '';
|
|
86
|
+
// ── Helper: compute newPhaseId / dirName / computedPhaseEntry from raw ROADMAP content ──
|
|
87
|
+
// Extracted as a local async function so it can be called both inside the
|
|
88
|
+
// roadmap lock (non-dry-run) and outside (dry-run, where no write occurs and
|
|
89
|
+
// there is no race condition to guard against).
|
|
90
|
+
const computePhaseFields = async (rawRoadmapContent) => {
|
|
91
|
+
const milestoneContent = await extractCurrentMilestone(rawRoadmapContent, projectDir);
|
|
92
|
+
const phasesDir = planningPaths(projectDir, workstream).phases;
|
|
93
|
+
const dirNames = await listDirectories(phasesDir);
|
|
94
|
+
const nextSequentialPhaseId = computeNextSequentialPhaseId(milestoneContent, dirNames);
|
|
95
|
+
const { phaseId: resolvedPhaseId, dirName: resolvedDirName } = computePhaseDirectory(config.phase_naming, slug, prefix, nextSequentialPhaseId, customId || undefined);
|
|
96
|
+
if (!resolvedDirName) {
|
|
97
|
+
throw new GTDError('Phase directory name was not computed', ErrorClassification.Execution);
|
|
98
|
+
}
|
|
99
|
+
if (resolvedPhaseId === '') {
|
|
100
|
+
throw new GTDError('Phase ID was not computed', ErrorClassification.Execution);
|
|
101
|
+
}
|
|
102
|
+
const resolvedEntry = buildPhaseRoadmapEntry(resolvedPhaseId, description, config.phase_naming);
|
|
103
|
+
return { resolvedPhaseId, resolvedDirName, resolvedEntry };
|
|
104
|
+
};
|
|
105
|
+
let newPhaseId = '';
|
|
106
|
+
let dirName = '';
|
|
107
|
+
let computedPhaseEntry = '';
|
|
108
|
+
if (dryRun) {
|
|
109
|
+
// Dry-run: no write, no race condition — compute outside the lock.
|
|
110
|
+
const roadmapPath = planningPaths(projectDir, workstream).roadmap;
|
|
111
|
+
let rawRoadmapContent = '';
|
|
112
|
+
try {
|
|
113
|
+
rawRoadmapContent = await readFile(roadmapPath, 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
catch { /* ROADMAP.md may not exist yet */ }
|
|
116
|
+
const { resolvedPhaseId, resolvedDirName, resolvedEntry } = await computePhaseFields(rawRoadmapContent);
|
|
117
|
+
newPhaseId = resolvedPhaseId;
|
|
118
|
+
dirName = resolvedDirName;
|
|
119
|
+
computedPhaseEntry = resolvedEntry;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Real write path: hold the roadmap lock across the entire read → compute → write
|
|
123
|
+
// cycle so that two concurrent phase.add calls cannot both observe the same
|
|
124
|
+
// maxPhase and produce duplicate phase IDs.
|
|
125
|
+
await readModifyWriteRoadmapMd(projectDir, async (roadmapRaw) => {
|
|
126
|
+
const { resolvedPhaseId, resolvedDirName, resolvedEntry } = await computePhaseFields(roadmapRaw);
|
|
127
|
+
newPhaseId = resolvedPhaseId;
|
|
128
|
+
dirName = resolvedDirName;
|
|
129
|
+
computedPhaseEntry = resolvedEntry;
|
|
130
|
+
const dirPath = join(planningPaths(projectDir, workstream).phases, dirName);
|
|
131
|
+
// Create directory with .gitkeep so git tracks empty folders
|
|
132
|
+
await ensureDirectoryWithGitkeep(dirPath);
|
|
133
|
+
// Find insertion point: before last "---" or at end
|
|
134
|
+
const lastSeparator = roadmapRaw.lastIndexOf('\n---');
|
|
135
|
+
if (lastSeparator > 0) {
|
|
136
|
+
return roadmapRaw.slice(0, lastSeparator) + computedPhaseEntry + roadmapRaw.slice(lastSeparator);
|
|
137
|
+
}
|
|
138
|
+
return roadmapRaw + computedPhaseEntry;
|
|
139
|
+
}, workstream);
|
|
140
|
+
}
|
|
141
|
+
const result = {
|
|
142
|
+
phase_number: typeof newPhaseId === 'number' ? newPhaseId : String(newPhaseId),
|
|
143
|
+
padded: typeof newPhaseId === 'number' ? String(newPhaseId).padStart(2, '0') : String(newPhaseId),
|
|
144
|
+
name: description,
|
|
145
|
+
slug,
|
|
146
|
+
directory: toPosixPath(relative(projectDir, join(planningPaths(projectDir, workstream).phases, dirName))),
|
|
147
|
+
naming_mode: config.phase_naming || 'sequential',
|
|
148
|
+
};
|
|
149
|
+
if (dryRun) {
|
|
150
|
+
result.dry_run = true;
|
|
151
|
+
result.roadmap_entry = computedPhaseEntry;
|
|
152
|
+
}
|
|
153
|
+
return { data: result };
|
|
154
|
+
};
|
|
155
|
+
// ─── phaseAddBatch handler ────────────────────────────────────────────────
|
|
156
|
+
/**
|
|
157
|
+
* Query handler for phase.add-batch.
|
|
158
|
+
*
|
|
159
|
+
* Port of cmdPhaseAddBatch from phase.cjs lines 411-478.
|
|
160
|
+
* Appends multiple phases in one locked ROADMAP pass (sequential or custom naming).
|
|
161
|
+
*
|
|
162
|
+
* @param args - Either `--descriptions` followed by a JSON array string, or one description per arg (`--raw` ignored)
|
|
163
|
+
*/
|
|
164
|
+
export const phaseAddBatch = async (args, projectDir, workstream) => {
|
|
165
|
+
let descriptions;
|
|
166
|
+
const descIdx = args.indexOf('--descriptions');
|
|
167
|
+
if (descIdx !== -1 && args[descIdx + 1] !== undefined) {
|
|
168
|
+
try {
|
|
169
|
+
const parsed = JSON.parse(args[descIdx + 1]);
|
|
170
|
+
if (!Array.isArray(parsed)) {
|
|
171
|
+
throw new GTDError('--descriptions must be a JSON array', ErrorClassification.Validation);
|
|
172
|
+
}
|
|
173
|
+
descriptions = parsed.map((x) => String(x));
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
if (e instanceof GTDError)
|
|
177
|
+
throw e;
|
|
178
|
+
throw new GTDError('--descriptions must be a valid JSON array', ErrorClassification.Validation);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
descriptions = args.filter((a) => a !== '--raw');
|
|
183
|
+
}
|
|
184
|
+
if (descriptions.length === 0) {
|
|
185
|
+
throw new GTDError('descriptions array required for phase add-batch', ErrorClassification.Validation);
|
|
186
|
+
}
|
|
187
|
+
for (const d of descriptions) {
|
|
188
|
+
assertNoNullBytes(d, 'description');
|
|
189
|
+
if (!d.trim()) {
|
|
190
|
+
throw new GTDError('description must be non-empty', ErrorClassification.Validation);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const roadmapPath = planningPaths(projectDir, workstream).roadmap;
|
|
194
|
+
if (!existsSync(roadmapPath)) {
|
|
195
|
+
throw new GTDError('ROADMAP.md not found', ErrorClassification.Validation);
|
|
196
|
+
}
|
|
197
|
+
let config = {};
|
|
198
|
+
try {
|
|
199
|
+
config = JSON.parse(await readFile(planningPaths(projectDir, workstream).config, 'utf-8'));
|
|
200
|
+
}
|
|
201
|
+
catch { /* use defaults */ }
|
|
202
|
+
const projectCode = config.project_code || '';
|
|
203
|
+
assertSafeProjectCode(projectCode);
|
|
204
|
+
const prefix = projectCode ? `${projectCode}-` : '';
|
|
205
|
+
const added = [];
|
|
206
|
+
await readModifyWriteRoadmapMd(projectDir, async (initialContent) => {
|
|
207
|
+
let rawContent = initialContent;
|
|
208
|
+
const content = await extractCurrentMilestone(rawContent, projectDir);
|
|
209
|
+
let maxPhase = 0;
|
|
210
|
+
if (config.phase_naming !== 'custom') {
|
|
211
|
+
const phasesOnDisk = planningPaths(projectDir, workstream).phases;
|
|
212
|
+
const dirNames = await listDirectories(phasesOnDisk);
|
|
213
|
+
maxPhase = computeNextSequentialPhaseId(content, dirNames) - 1;
|
|
214
|
+
}
|
|
215
|
+
for (const description of descriptions) {
|
|
216
|
+
const slug = generatePhaseSlug(description);
|
|
217
|
+
let newPhaseId;
|
|
218
|
+
let dirName;
|
|
219
|
+
if (config.phase_naming === 'custom') {
|
|
220
|
+
// Match CJS cmdPhaseAddBatch: slug.toUpperCase().replace(/-/g, '-') (identity on hyphens)
|
|
221
|
+
newPhaseId = slug.toUpperCase();
|
|
222
|
+
dirName = `${prefix}${newPhaseId}-${slug}`;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
maxPhase += 1;
|
|
226
|
+
newPhaseId = maxPhase;
|
|
227
|
+
dirName = `${prefix}${String(newPhaseId).padStart(2, '0')}-${slug}`;
|
|
228
|
+
}
|
|
229
|
+
assertSafePhaseDirName(dirName);
|
|
230
|
+
const dirPath = join(planningPaths(projectDir, workstream).phases, dirName);
|
|
231
|
+
await ensureDirectoryWithGitkeep(dirPath);
|
|
232
|
+
const phaseEntry = buildPhaseRoadmapEntry(newPhaseId, description, config.phase_naming);
|
|
233
|
+
const lastSeparator = rawContent.lastIndexOf('\n---');
|
|
234
|
+
rawContent =
|
|
235
|
+
lastSeparator > 0
|
|
236
|
+
? rawContent.slice(0, lastSeparator) + phaseEntry + rawContent.slice(lastSeparator)
|
|
237
|
+
: rawContent + phaseEntry;
|
|
238
|
+
added.push({
|
|
239
|
+
phase_number: typeof newPhaseId === 'number' ? newPhaseId : String(newPhaseId),
|
|
240
|
+
padded: typeof newPhaseId === 'number' ? String(newPhaseId).padStart(2, '0') : String(newPhaseId),
|
|
241
|
+
name: description,
|
|
242
|
+
slug,
|
|
243
|
+
directory: toPosixPath(relative(projectDir, join(planningPaths(projectDir, workstream).phases, dirName))),
|
|
244
|
+
naming_mode: config.phase_naming || 'sequential',
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return rawContent;
|
|
248
|
+
}, workstream);
|
|
249
|
+
return { data: { phases: added, count: added.length } };
|
|
250
|
+
};
|
|
251
|
+
// ─── phaseInsert handler ────────────────────────────────────────────────
|
|
252
|
+
/**
|
|
253
|
+
* Query handler for phase.insert.
|
|
254
|
+
*
|
|
255
|
+
* Port of cmdPhaseInsert from phase.cjs lines 394-492.
|
|
256
|
+
* Creates a decimal phase directory after a target phase, inserting
|
|
257
|
+
* the phase section in ROADMAP.md after the target.
|
|
258
|
+
*
|
|
259
|
+
* @param args - args[0]: afterPhase (required), args[1]: description (required)
|
|
260
|
+
* @param projectDir - Project root directory
|
|
261
|
+
* @returns QueryResult with { phase_number, after_phase, name, slug, directory }
|
|
262
|
+
*/
|
|
263
|
+
export const phaseInsert = async (args, projectDir, workstream) => {
|
|
264
|
+
const afterPhase = args[0];
|
|
265
|
+
const description = args[1];
|
|
266
|
+
if (!afterPhase || !description) {
|
|
267
|
+
throw new GTDError('after-phase and description required for phase insert', ErrorClassification.Validation);
|
|
268
|
+
}
|
|
269
|
+
assertNoNullBytes(afterPhase, 'afterPhase');
|
|
270
|
+
assertNoNullBytes(description, 'description');
|
|
271
|
+
const slug = generatePhaseSlug(description);
|
|
272
|
+
let decimalPhase = '';
|
|
273
|
+
let dirName = '';
|
|
274
|
+
await readModifyWriteRoadmapMd(projectDir, async (rawContent) => {
|
|
275
|
+
const content = await extractCurrentMilestone(rawContent, projectDir);
|
|
276
|
+
// Normalize input then strip leading zeros for flexible matching
|
|
277
|
+
const normalizedAfter = normalizePhaseName(afterPhase);
|
|
278
|
+
const unpadded = normalizedAfter.replace(/^0+/, '');
|
|
279
|
+
const afterPhaseEscaped = unpadded.replace(/\./g, '\\.');
|
|
280
|
+
const targetPattern = new RegExp(`#{2,4}\\s*Phase\\s+0*${afterPhaseEscaped}:`, 'i');
|
|
281
|
+
if (!targetPattern.test(content)) {
|
|
282
|
+
throw new GTDError(`Phase ${afterPhase} not found in ROADMAP.md`, ErrorClassification.Validation);
|
|
283
|
+
}
|
|
284
|
+
// Calculate next decimal by scanning both directories AND ROADMAP.md entries
|
|
285
|
+
const phasesDir = planningPaths(projectDir, workstream).phases;
|
|
286
|
+
const normalizedBase = normalizePhaseName(afterPhase);
|
|
287
|
+
const decimalSet = new Set();
|
|
288
|
+
try {
|
|
289
|
+
const dirs = await listDirectories(phasesDir);
|
|
290
|
+
for (const suffix of collectDecimalSuffixesFromDirNames(normalizedBase, dirs)) {
|
|
291
|
+
decimalSet.add(suffix);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch { /* intentionally empty */ }
|
|
295
|
+
// Also scan ROADMAP.md content for decimal entries
|
|
296
|
+
for (const suffix of collectDecimalSuffixesFromRoadmap(normalizedBase, rawContent)) {
|
|
297
|
+
decimalSet.add(suffix);
|
|
298
|
+
}
|
|
299
|
+
decimalPhase = computeNextDecimalPhase(normalizedBase, decimalSet).next;
|
|
300
|
+
// Optional project code prefix
|
|
301
|
+
let insertConfig = {};
|
|
302
|
+
try {
|
|
303
|
+
insertConfig = JSON.parse(await readFile(planningPaths(projectDir, workstream).config, 'utf-8'));
|
|
304
|
+
}
|
|
305
|
+
catch { /* use defaults */ }
|
|
306
|
+
const projectCode = insertConfig.project_code || '';
|
|
307
|
+
assertSafeProjectCode(projectCode);
|
|
308
|
+
const pfx = projectCode ? `${projectCode}-` : '';
|
|
309
|
+
dirName = `${pfx}${decimalPhase}-${slug}`;
|
|
310
|
+
assertSafePhaseDirName(dirName);
|
|
311
|
+
const dirPath = join(phasesDir, dirName);
|
|
312
|
+
// Create directory with .gitkeep
|
|
313
|
+
await ensureDirectoryWithGitkeep(dirPath);
|
|
314
|
+
// Build phase entry
|
|
315
|
+
const phaseEntry = `\n### Phase ${decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gtd-plan-phase ${decimalPhase} to break down)\n`;
|
|
316
|
+
// Insert after the target phase section
|
|
317
|
+
const headerPattern = new RegExp(`(#{2,4}\\s*Phase\\s+0*${afterPhaseEscaped}:[^\\n]*\\n)`, 'i');
|
|
318
|
+
const headerMatch = rawContent.match(headerPattern);
|
|
319
|
+
if (!headerMatch) {
|
|
320
|
+
throw new GTDError(`Could not find Phase ${afterPhase} header`, ErrorClassification.Execution);
|
|
321
|
+
}
|
|
322
|
+
const headerIdx = rawContent.indexOf(headerMatch[0]);
|
|
323
|
+
const afterHeader = rawContent.slice(headerIdx + headerMatch[0].length);
|
|
324
|
+
const nextPhaseMatch = afterHeader.match(/\n#{2,4}\s+Phase\s+\d/i);
|
|
325
|
+
let insertIdx;
|
|
326
|
+
if (nextPhaseMatch && nextPhaseMatch.index !== undefined) {
|
|
327
|
+
insertIdx = headerIdx + headerMatch[0].length + nextPhaseMatch.index;
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
insertIdx = rawContent.length;
|
|
331
|
+
}
|
|
332
|
+
return rawContent.slice(0, insertIdx) + phaseEntry + rawContent.slice(insertIdx);
|
|
333
|
+
}, workstream);
|
|
334
|
+
if (!decimalPhase) {
|
|
335
|
+
throw new GTDError('Decimal phase was not computed', ErrorClassification.Execution);
|
|
336
|
+
}
|
|
337
|
+
if (!dirName) {
|
|
338
|
+
throw new GTDError('Phase directory name was not computed', ErrorClassification.Execution);
|
|
339
|
+
}
|
|
340
|
+
const result = {
|
|
341
|
+
phase_number: decimalPhase,
|
|
342
|
+
after_phase: afterPhase,
|
|
343
|
+
name: description,
|
|
344
|
+
slug,
|
|
345
|
+
directory: toPosixPath(relative(projectDir, join(planningPaths(projectDir, workstream).phases, dirName))),
|
|
346
|
+
};
|
|
347
|
+
return { data: result };
|
|
348
|
+
};
|
|
349
|
+
// ─── phaseScaffold handler ──────────────────────────────────────────────
|
|
350
|
+
/**
|
|
351
|
+
* Internal helper: find phase directory matching a phase identifier.
|
|
352
|
+
*
|
|
353
|
+
* Reuses the same logic as findPhase handler but returns just the directory info.
|
|
354
|
+
*/
|
|
355
|
+
async function findPhaseDir(projectDir, phase, workstream) {
|
|
356
|
+
const phasesDir = planningPaths(projectDir, workstream).phases;
|
|
357
|
+
const normalized = normalizePhaseName(phase);
|
|
358
|
+
const dirs = await listDirectories(phasesDir);
|
|
359
|
+
const match = dirs.find((d) => phaseTokenMatches(d, normalized));
|
|
360
|
+
if (!match)
|
|
361
|
+
return null;
|
|
362
|
+
// Extract phase name from directory
|
|
363
|
+
const dirMatch = match.match(/^(?:[A-Z]{1,6}-)?\d+[A-Z]?(?:\.\d+)*-(.+)/i);
|
|
364
|
+
const phaseName = dirMatch ? dirMatch[1] : null;
|
|
365
|
+
return {
|
|
366
|
+
dirPath: join(phasesDir, match),
|
|
367
|
+
dirName: match,
|
|
368
|
+
phaseName,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Query handler for phase.scaffold.
|
|
373
|
+
*
|
|
374
|
+
* Port of cmdScaffold from commands.cjs lines 750-806.
|
|
375
|
+
* Creates template files (context, uat, verification) or phase directories.
|
|
376
|
+
*
|
|
377
|
+
* @param args - Positional `[type, phase, name?]` **or** gtd-tools style
|
|
378
|
+
* `[type, '--phase', N, '--name', title]` (name may be multiple words).
|
|
379
|
+
* @param projectDir - Project root directory
|
|
380
|
+
* @returns QueryResult with { created, path } or { created: false, reason: 'already_exists' }
|
|
381
|
+
*/
|
|
382
|
+
function normalizeScaffoldArgs(args) {
|
|
383
|
+
const type = args[0];
|
|
384
|
+
if (!type || !args.includes('--phase')) {
|
|
385
|
+
return args;
|
|
386
|
+
}
|
|
387
|
+
const phaseIdx = args.indexOf('--phase');
|
|
388
|
+
const phase = phaseIdx !== -1 && args[phaseIdx + 1] && !args[phaseIdx + 1].startsWith('--')
|
|
389
|
+
? args[phaseIdx + 1]
|
|
390
|
+
: '';
|
|
391
|
+
const nameIdx = args.indexOf('--name');
|
|
392
|
+
let name;
|
|
393
|
+
if (nameIdx !== -1) {
|
|
394
|
+
const tail = args.slice(nameIdx + 1);
|
|
395
|
+
const stop = tail.findIndex(a => a.startsWith('--'));
|
|
396
|
+
const parts = stop === -1 ? tail : tail.slice(0, stop);
|
|
397
|
+
name = parts.join(' ').trim() || undefined;
|
|
398
|
+
}
|
|
399
|
+
return [type, phase, ...(name !== undefined && name !== '' ? [name] : [])];
|
|
400
|
+
}
|
|
401
|
+
export const phaseScaffold = async (args, projectDir, workstream) => {
|
|
402
|
+
const normalized = normalizeScaffoldArgs(args);
|
|
403
|
+
const type = normalized[0];
|
|
404
|
+
const phase = normalized[1];
|
|
405
|
+
const name = normalized[2] || undefined;
|
|
406
|
+
if (!type) {
|
|
407
|
+
throw new GTDError('type required for scaffold', ErrorClassification.Validation);
|
|
408
|
+
}
|
|
409
|
+
const validTypes = new Set(['context', 'uat', 'verification', 'phase-dir']);
|
|
410
|
+
if (!validTypes.has(type)) {
|
|
411
|
+
throw new GTDError(`Unknown scaffold type: ${type}. Available: context, uat, verification, phase-dir`, ErrorClassification.Validation);
|
|
412
|
+
}
|
|
413
|
+
if (phase) {
|
|
414
|
+
assertNoNullBytes(phase, 'phase');
|
|
415
|
+
}
|
|
416
|
+
if (name) {
|
|
417
|
+
assertNoNullBytes(name, 'name');
|
|
418
|
+
}
|
|
419
|
+
const padded = phase ? normalizePhaseName(phase) : '00';
|
|
420
|
+
const today = new Date().toISOString().split('T')[0];
|
|
421
|
+
// Handle phase-dir type separately
|
|
422
|
+
if (type === 'phase-dir') {
|
|
423
|
+
if (!phase || !name) {
|
|
424
|
+
throw new GTDError('phase and name required for phase-dir scaffold', ErrorClassification.Validation);
|
|
425
|
+
}
|
|
426
|
+
const slug = generatePhaseSlug(name);
|
|
427
|
+
// #3287: apply project_code prefix to stay consistent with phase.add/phase.insert
|
|
428
|
+
let scaffoldConfig = {};
|
|
429
|
+
try {
|
|
430
|
+
scaffoldConfig = JSON.parse(await readFile(planningPaths(projectDir, workstream).config, 'utf-8'));
|
|
431
|
+
}
|
|
432
|
+
catch { /* use defaults */ }
|
|
433
|
+
const scaffoldProjectCode = scaffoldConfig.project_code || '';
|
|
434
|
+
assertSafeProjectCode(scaffoldProjectCode);
|
|
435
|
+
const scaffoldPrefix = scaffoldProjectCode ? `${scaffoldProjectCode}-` : '';
|
|
436
|
+
const dirNameNew = `${scaffoldPrefix}${padded}-${slug}`;
|
|
437
|
+
assertSafePhaseDirName(dirNameNew, 'scaffold phase directory');
|
|
438
|
+
const phasesParent = planningPaths(projectDir, workstream).phases;
|
|
439
|
+
await mkdir(phasesParent, { recursive: true });
|
|
440
|
+
const dirPath = join(phasesParent, dirNameNew);
|
|
441
|
+
await ensureDirectoryWithGitkeep(dirPath);
|
|
442
|
+
return {
|
|
443
|
+
data: {
|
|
444
|
+
created: true,
|
|
445
|
+
directory: toPosixPath(relative(projectDir, dirPath)),
|
|
446
|
+
path: dirPath,
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
// For context/uat/verification types, find the phase directory
|
|
451
|
+
const phaseInfo = phase ? await findPhaseDir(projectDir, phase, workstream) : null;
|
|
452
|
+
if (phase && !phaseInfo) {
|
|
453
|
+
throw new GTDError(`Phase ${phase} directory not found`, ErrorClassification.Blocked);
|
|
454
|
+
}
|
|
455
|
+
const phaseDir = phaseInfo.dirPath;
|
|
456
|
+
const phaseName = name || phaseInfo?.phaseName || 'Unnamed';
|
|
457
|
+
let filePath;
|
|
458
|
+
let content;
|
|
459
|
+
switch (type) {
|
|
460
|
+
case 'context': {
|
|
461
|
+
filePath = join(phaseDir, `${padded}-CONTEXT.md`);
|
|
462
|
+
content = `---\nphase: "${padded}"\nname: "${phaseName}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${phaseName} — Context\n\n## Decisions\n\n_Decisions will be captured during /gtd-discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
case 'uat': {
|
|
466
|
+
filePath = join(phaseDir, `${padded}-UAT.md`);
|
|
467
|
+
content = `---\nphase: "${padded}"\nname: "${phaseName}"\ncreated: ${today}\nstatus: pending\n---\n\n# Phase ${phase}: ${phaseName} — User Acceptance Testing\n\n## Test Results\n\n| # | Test | Status | Notes |\n|---|------|--------|-------|\n\n## Summary\n\n_Pending UAT_\n`;
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
case 'verification': {
|
|
471
|
+
filePath = join(phaseDir, `${padded}-VERIFICATION.md`);
|
|
472
|
+
content = `---\nphase: "${padded}"\nname: "${phaseName}"\ncreated: ${today}\nstatus: pending\n---\n\n# Phase ${phase}: ${phaseName} — Verification\n\n## Goal-Backward Verification\n\n**Phase Goal:** [From ROADMAP.md]\n\n## Checks\n\n| # | Requirement | Status | Evidence |\n|---|------------|--------|----------|\n\n## Result\n\n_Pending verification_\n`;
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
default:
|
|
476
|
+
throw new GTDError(`Unknown scaffold type: ${type}`, ErrorClassification.Validation);
|
|
477
|
+
}
|
|
478
|
+
// Check if file already exists
|
|
479
|
+
if (existsSync(filePath)) {
|
|
480
|
+
return {
|
|
481
|
+
data: {
|
|
482
|
+
created: false,
|
|
483
|
+
reason: 'already_exists',
|
|
484
|
+
path: filePath,
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
await writeFile(filePath, content, 'utf-8');
|
|
489
|
+
const relPath = toPosixPath(relative(projectDir, filePath));
|
|
490
|
+
return { data: { created: true, path: relPath } };
|
|
491
|
+
};
|
|
492
|
+
// ─── renameDecimalPhases ───────────────────────────────────────────────
|
|
493
|
+
/**
|
|
494
|
+
* Renumber sibling decimal phases after a decimal phase is removed.
|
|
495
|
+
*
|
|
496
|
+
* Port of renameDecimalPhases from phase.cjs lines 499-524.
|
|
497
|
+
* e.g. removing 06.2 -> 06.3 becomes 06.2, 06.4 becomes 06.3, etc.
|
|
498
|
+
* Renames directories AND files inside them that contain the old phase ID.
|
|
499
|
+
*
|
|
500
|
+
* CRITICAL: Sorted in DESCENDING order to avoid rename conflicts.
|
|
501
|
+
*
|
|
502
|
+
* @param phasesDir - Path to the phases directory
|
|
503
|
+
* @param baseInt - The integer part of the decimal phase (e.g. "06")
|
|
504
|
+
* @param removedDecimal - The decimal part that was removed (e.g. 2 for 06.2)
|
|
505
|
+
* @returns { renamedDirs, renamedFiles }
|
|
506
|
+
*/
|
|
507
|
+
async function renameDecimalPhases(phasesDir, baseInt, removedDecimal) {
|
|
508
|
+
const renamedDirs = [];
|
|
509
|
+
const renamedFiles = [];
|
|
510
|
+
const decPattern = new RegExp(`^${escapeRegex(baseInt)}\\.(\\d+)-(.+)$`);
|
|
511
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
512
|
+
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
513
|
+
const toRename = dirs
|
|
514
|
+
.map(dir => {
|
|
515
|
+
const m = dir.match(decPattern);
|
|
516
|
+
return m ? { dir, oldDecimal: parseInt(m[1], 10), slug: m[2] } : null;
|
|
517
|
+
})
|
|
518
|
+
.filter((item) => item !== null && item.oldDecimal > removedDecimal)
|
|
519
|
+
.sort((a, b) => b.oldDecimal - a.oldDecimal); // DESCENDING to avoid conflicts
|
|
520
|
+
for (const item of toRename) {
|
|
521
|
+
const newDecimal = item.oldDecimal - 1;
|
|
522
|
+
const oldPhaseId = `${baseInt}.${item.oldDecimal}`;
|
|
523
|
+
const newPhaseId = `${baseInt}.${newDecimal}`;
|
|
524
|
+
const newDirName = `${baseInt}.${newDecimal}-${item.slug}`;
|
|
525
|
+
await rename(join(phasesDir, item.dir), join(phasesDir, newDirName));
|
|
526
|
+
renamedDirs.push({ from: item.dir, to: newDirName });
|
|
527
|
+
// Rename files inside that contain the old phase ID
|
|
528
|
+
const files = await readdir(join(phasesDir, newDirName));
|
|
529
|
+
for (const f of files) {
|
|
530
|
+
if (f.includes(oldPhaseId)) {
|
|
531
|
+
const newFileName = f.replace(oldPhaseId, newPhaseId);
|
|
532
|
+
await rename(join(phasesDir, newDirName, f), join(phasesDir, newDirName, newFileName));
|
|
533
|
+
renamedFiles.push({ from: f, to: newFileName });
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return { renamedDirs, renamedFiles };
|
|
538
|
+
}
|
|
539
|
+
// ─── renameIntegerPhases ───────────────────────────────────────────────
|
|
540
|
+
/**
|
|
541
|
+
* Renumber all integer phases after a removed integer phase.
|
|
542
|
+
*
|
|
543
|
+
* Port of renameIntegerPhases from phase.cjs lines 531-564.
|
|
544
|
+
* e.g. removing phase 5 -> phase 6 becomes 5, phase 7 becomes 6, etc.
|
|
545
|
+
* Handles letter suffixes (12A) and decimals (6.1).
|
|
546
|
+
*
|
|
547
|
+
* CRITICAL: Sorted in DESCENDING order to avoid rename conflicts.
|
|
548
|
+
*
|
|
549
|
+
* @param phasesDir - Path to the phases directory
|
|
550
|
+
* @param removedInt - The integer phase number that was removed
|
|
551
|
+
* @returns { renamedDirs, renamedFiles }
|
|
552
|
+
*/
|
|
553
|
+
async function renameIntegerPhases(phasesDir, removedInt) {
|
|
554
|
+
const renamedDirs = [];
|
|
555
|
+
const renamedFiles = [];
|
|
556
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
557
|
+
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
558
|
+
const toRename = dirs
|
|
559
|
+
.map(dir => {
|
|
560
|
+
const m = dir.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);
|
|
561
|
+
if (!m)
|
|
562
|
+
return null;
|
|
563
|
+
const dirInt = parseInt(m[1], 10);
|
|
564
|
+
if (dirInt <= removedInt)
|
|
565
|
+
return null;
|
|
566
|
+
return {
|
|
567
|
+
dir,
|
|
568
|
+
oldInt: dirInt,
|
|
569
|
+
letter: m[2] ? m[2].toUpperCase() : '',
|
|
570
|
+
decimal: m[3] !== undefined ? parseInt(m[3], 10) : null,
|
|
571
|
+
slug: m[4],
|
|
572
|
+
};
|
|
573
|
+
})
|
|
574
|
+
.filter((item) => item !== null)
|
|
575
|
+
.sort((a, b) => a.oldInt !== b.oldInt
|
|
576
|
+
? b.oldInt - a.oldInt
|
|
577
|
+
: (b.decimal ?? 0) - (a.decimal ?? 0)); // DESCENDING
|
|
578
|
+
for (const item of toRename) {
|
|
579
|
+
const newInt = item.oldInt - 1;
|
|
580
|
+
const newPadded = String(newInt).padStart(2, '0');
|
|
581
|
+
const oldPadded = String(item.oldInt).padStart(2, '0');
|
|
582
|
+
const letterSuffix = item.letter || '';
|
|
583
|
+
const decimalSuffix = item.decimal !== null ? `.${item.decimal}` : '';
|
|
584
|
+
const oldPrefix = `${oldPadded}${letterSuffix}${decimalSuffix}`;
|
|
585
|
+
const newPrefix = `${newPadded}${letterSuffix}${decimalSuffix}`;
|
|
586
|
+
const newDirName = `${newPrefix}-${item.slug}`;
|
|
587
|
+
await rename(join(phasesDir, item.dir), join(phasesDir, newDirName));
|
|
588
|
+
renamedDirs.push({ from: item.dir, to: newDirName });
|
|
589
|
+
// Rename files that start with the old prefix
|
|
590
|
+
const files = await readdir(join(phasesDir, newDirName));
|
|
591
|
+
for (const f of files) {
|
|
592
|
+
if (f.startsWith(oldPrefix)) {
|
|
593
|
+
const newFileName = newPrefix + f.slice(oldPrefix.length);
|
|
594
|
+
await rename(join(phasesDir, newDirName, f), join(phasesDir, newDirName, newFileName));
|
|
595
|
+
renamedFiles.push({ from: f, to: newFileName });
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return { renamedDirs, renamedFiles };
|
|
600
|
+
}
|
|
601
|
+
// ─── updateRoadmapAfterPhaseRemoval ────────────────────────────────────
|
|
602
|
+
/**
|
|
603
|
+
* Remove a phase section from ROADMAP.md and renumber subsequent integer phases.
|
|
604
|
+
*
|
|
605
|
+
* Port of updateRoadmapAfterPhaseRemoval from phase.cjs lines 569-595.
|
|
606
|
+
* Uses readModifyWriteRoadmapMd for atomic writes.
|
|
607
|
+
*
|
|
608
|
+
* @param projectDir - Project root directory
|
|
609
|
+
* @param targetPhase - Phase identifier that was removed
|
|
610
|
+
* @param isDecimal - Whether the removed phase was a decimal phase
|
|
611
|
+
* @param removedInt - The integer part of the removed phase
|
|
612
|
+
*/
|
|
613
|
+
async function updateRoadmapAfterPhaseRemoval(projectDir, targetPhase, isDecimal, removedInt, workstream) {
|
|
614
|
+
await readModifyWriteRoadmapMd(projectDir, (content) => {
|
|
615
|
+
const escaped = escapeRegex(targetPhase);
|
|
616
|
+
// Remove the phase section (header + body until next phase header or end)
|
|
617
|
+
content = content.replace(new RegExp(`\\n?#{2,4}\\s*Phase\\s+${escaped}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s+Phase\\s+\\d|$)`, 'i'), '');
|
|
618
|
+
// Remove checkbox lines referencing the phase
|
|
619
|
+
content = content.replace(new RegExp(`\\n?-\\s*\\[[ x]\\]\\s*.*Phase\\s+${escaped}[:\\s][^\\n]*`, 'gi'), '');
|
|
620
|
+
// Remove table rows referencing the phase
|
|
621
|
+
content = content.replace(new RegExp(`\\n?\\|\\s*${escaped}\\.?\\s[^|]*\\|[^\\n]*`, 'gi'), '');
|
|
622
|
+
// For integer phase removal, renumber all subsequent phases in ROADMAP text
|
|
623
|
+
if (!isDecimal) {
|
|
624
|
+
const MAX_PHASE = 99;
|
|
625
|
+
for (let oldNum = MAX_PHASE; oldNum > removedInt; oldNum--) {
|
|
626
|
+
const newNum = oldNum - 1;
|
|
627
|
+
const oldStr = String(oldNum);
|
|
628
|
+
const newStr = String(newNum);
|
|
629
|
+
const oldPad = oldStr.padStart(2, '0');
|
|
630
|
+
const newPad = newStr.padStart(2, '0');
|
|
631
|
+
// Renumber phase headers: ### Phase N:
|
|
632
|
+
content = content.replace(new RegExp(`(#{2,4}\\s*Phase\\s+)${escapeRegex(oldStr)}(\\s*:)`, 'gi'), `$1${newStr}$2`);
|
|
633
|
+
// Renumber inline Phase N references
|
|
634
|
+
content = content.replace(new RegExp(`(Phase\\s+)${escapeRegex(oldStr)}([:\\s])`, 'g'), `$1${newStr}$2`);
|
|
635
|
+
// Renumber padded plan references: 07-01 -> 06-01
|
|
636
|
+
content = content.replace(new RegExp(`${escapeRegex(oldPad)}-(\\d{2})`, 'g'), `${newPad}-$1`);
|
|
637
|
+
// Renumber table row phase numbers: | 7. -> | 6.
|
|
638
|
+
content = content.replace(new RegExp(`(\\|\\s*)${escapeRegex(oldStr)}\\.\\s`, 'g'), `$1${newStr}. `);
|
|
639
|
+
// Renumber depends-on references
|
|
640
|
+
content = content.replace(new RegExp(`(\\*\\*Depends on:\\*\\*\\s*Phase\\s+)${escapeRegex(oldStr)}\\b`, 'gi'), `$1${newStr}`);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return content;
|
|
644
|
+
}, workstream);
|
|
645
|
+
}
|
|
646
|
+
// ─── phaseRemove handler ───────────────────────────────────────────────
|
|
647
|
+
/**
|
|
648
|
+
* Query handler for phase.remove.
|
|
649
|
+
*
|
|
650
|
+
* Port of cmdPhaseRemove from phase.cjs lines 597-661.
|
|
651
|
+
* Deletes phase directory, renumbers subsequent phases on disk,
|
|
652
|
+
* updates ROADMAP.md (removes section + renumbers), and decrements
|
|
653
|
+
* STATE.md total_phases count.
|
|
654
|
+
*
|
|
655
|
+
* @param args - args[0]: targetPhase (required), args[1]: '--force' (optional)
|
|
656
|
+
* @param projectDir - Project root directory
|
|
657
|
+
* @returns QueryResult with { removed, directory_deleted, renamed_directories, renamed_files, roadmap_updated, state_updated }
|
|
658
|
+
*/
|
|
659
|
+
export const phaseRemove = async (args, projectDir, workstream) => {
|
|
660
|
+
let force = false;
|
|
661
|
+
const positional = [];
|
|
662
|
+
for (const token of args) {
|
|
663
|
+
if (token === '--force') {
|
|
664
|
+
force = true;
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
if (token.startsWith('--')) {
|
|
668
|
+
throw new GTDError(`phase remove does not support ${token}`, ErrorClassification.Validation);
|
|
669
|
+
}
|
|
670
|
+
positional.push(token);
|
|
671
|
+
}
|
|
672
|
+
if (positional.length > 1) {
|
|
673
|
+
throw new GTDError('phase remove accepts exactly one phase number', ErrorClassification.Validation);
|
|
674
|
+
}
|
|
675
|
+
const targetPhase = positional[0];
|
|
676
|
+
if (!targetPhase) {
|
|
677
|
+
throw new GTDError('phase number required for phase remove', ErrorClassification.Validation);
|
|
678
|
+
}
|
|
679
|
+
assertNoNullBytes(targetPhase, 'targetPhase');
|
|
680
|
+
const paths = planningPaths(projectDir, workstream);
|
|
681
|
+
const phasesDir = paths.phases;
|
|
682
|
+
if (!existsSync(paths.roadmap)) {
|
|
683
|
+
throw new GTDError('ROADMAP.md not found', ErrorClassification.Validation);
|
|
684
|
+
}
|
|
685
|
+
const normalized = normalizePhaseName(targetPhase);
|
|
686
|
+
const isDecimal = targetPhase.includes('.');
|
|
687
|
+
// Find target directory
|
|
688
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
689
|
+
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
690
|
+
const targetDir = dirs.find(d => phaseTokenMatches(d, normalized)) ?? null;
|
|
691
|
+
if (!targetDir) {
|
|
692
|
+
throw new GTDError(`Phase ${targetPhase} not found`, ErrorClassification.Validation);
|
|
693
|
+
}
|
|
694
|
+
// Guard against removing executed work
|
|
695
|
+
if (!force) {
|
|
696
|
+
const files = await readdir(join(phasesDir, targetDir));
|
|
697
|
+
const summaries = files.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
698
|
+
if (summaries.length > 0) {
|
|
699
|
+
throw new GTDError(`Phase ${targetPhase} has ${summaries.length} executed plan(s). Use --force to remove anyway.`, ErrorClassification.Validation);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
// Delete directory
|
|
703
|
+
await rm(join(phasesDir, targetDir), { recursive: true, force: true });
|
|
704
|
+
// Renumber subsequent phases on disk
|
|
705
|
+
let renamedDirs = [];
|
|
706
|
+
let renamedFiles = [];
|
|
707
|
+
try {
|
|
708
|
+
let renamed;
|
|
709
|
+
if (isDecimal) {
|
|
710
|
+
const parts = normalized.split('.');
|
|
711
|
+
if (parts.length < 2 || !parts[1]) {
|
|
712
|
+
throw new GTDError(`Invalid decimal phase identifier: ${targetPhase}`, ErrorClassification.Validation);
|
|
713
|
+
}
|
|
714
|
+
const decimalPart = parseInt(parts[1], 10);
|
|
715
|
+
if (isNaN(decimalPart)) {
|
|
716
|
+
throw new GTDError(`Invalid decimal part in phase: ${targetPhase}`, ErrorClassification.Validation);
|
|
717
|
+
}
|
|
718
|
+
renamed = await renameDecimalPhases(phasesDir, parts[0], decimalPart);
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
renamed = await renameIntegerPhases(phasesDir, parseInt(normalized, 10));
|
|
722
|
+
}
|
|
723
|
+
renamedDirs = renamed.renamedDirs;
|
|
724
|
+
renamedFiles = renamed.renamedFiles;
|
|
725
|
+
}
|
|
726
|
+
catch { /* intentionally empty — renaming is best-effort */ }
|
|
727
|
+
// Update ROADMAP.md
|
|
728
|
+
await updateRoadmapAfterPhaseRemoval(projectDir, targetPhase, isDecimal, parseInt(normalized, 10), workstream);
|
|
729
|
+
// Update STATE.md: decrement total_phases
|
|
730
|
+
let stateUpdated = false;
|
|
731
|
+
const statePath = paths.state;
|
|
732
|
+
if (existsSync(statePath)) {
|
|
733
|
+
const lockPath = await acquireStateLock(statePath);
|
|
734
|
+
try {
|
|
735
|
+
let stateContent = await readFile(statePath, 'utf-8');
|
|
736
|
+
// Decrement total_phases in frontmatter
|
|
737
|
+
const totalPhasesMatch = stateContent.match(/total_phases:\s*(\d+)/);
|
|
738
|
+
if (totalPhasesMatch) {
|
|
739
|
+
const oldTotal = parseInt(totalPhasesMatch[1], 10);
|
|
740
|
+
stateContent = stateContent.replace(/total_phases:\s*\d+/, `total_phases: ${oldTotal - 1}`);
|
|
741
|
+
}
|
|
742
|
+
// Decrement "of N" pattern in body (e.g., "Plan: 2 of 3")
|
|
743
|
+
const ofMatch = stateContent.match(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i);
|
|
744
|
+
if (ofMatch) {
|
|
745
|
+
stateContent = stateContent.replace(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i, `$1${parseInt(ofMatch[2], 10) - 1}$3`);
|
|
746
|
+
}
|
|
747
|
+
// Also try stateReplaceField for "Total Phases" field
|
|
748
|
+
const totalRaw = stateExtractField(stateContent, 'Total Phases');
|
|
749
|
+
if (totalRaw) {
|
|
750
|
+
const replaced = stateReplaceField(stateContent, 'Total Phases', String(parseInt(totalRaw, 10) - 1));
|
|
751
|
+
if (replaced)
|
|
752
|
+
stateContent = replaced;
|
|
753
|
+
}
|
|
754
|
+
await writeFile(statePath, stateContent, 'utf-8');
|
|
755
|
+
stateUpdated = true;
|
|
756
|
+
}
|
|
757
|
+
finally {
|
|
758
|
+
await releaseStateLock(lockPath);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
data: {
|
|
763
|
+
removed: targetPhase,
|
|
764
|
+
directory_deleted: targetDir,
|
|
765
|
+
renamed_directories: renamedDirs,
|
|
766
|
+
renamed_files: renamedFiles,
|
|
767
|
+
roadmap_updated: true,
|
|
768
|
+
state_updated: stateUpdated,
|
|
769
|
+
},
|
|
770
|
+
};
|
|
771
|
+
};
|
|
772
|
+
// ─── updatePerformanceMetricsSection ───────────────────────────────────────
|
|
773
|
+
/**
|
|
774
|
+
* Update the Performance Metrics section in STATE.md content.
|
|
775
|
+
*
|
|
776
|
+
* Port of updatePerformanceMetricsSection from state.cjs lines 1125-1156.
|
|
777
|
+
* Updates "Total plans completed" counter and upserts a row in the By Phase table.
|
|
778
|
+
*
|
|
779
|
+
* @param content - STATE.md content
|
|
780
|
+
* @param phaseNum - Phase number being completed
|
|
781
|
+
* @param planCount - Total number of plans in the phase
|
|
782
|
+
* @param summaryCount - Number of completed summaries
|
|
783
|
+
* @returns Modified content
|
|
784
|
+
*/
|
|
785
|
+
function updatePerformanceMetricsSection(content, phaseNum, planCount, summaryCount) {
|
|
786
|
+
// Update Velocity: Total plans completed
|
|
787
|
+
const totalMatch = content.match(/Total plans completed:\s*(\d+|\[N\])/);
|
|
788
|
+
const prevTotal = totalMatch && totalMatch[1] !== '[N]' ? parseInt(totalMatch[1], 10) : 0;
|
|
789
|
+
const newTotal = prevTotal + summaryCount;
|
|
790
|
+
content = content.replace(/Total plans completed:\s*(\d+|\[N\])/, `Total plans completed: ${newTotal}`);
|
|
791
|
+
// Update By Phase table — upsert row for this phase
|
|
792
|
+
const byPhaseTablePattern = /(\|\s*Phase\s*\|\s*Plans\s*\|\s*Total\s*\|\s*Avg\/Plan\s*\|[ \t]*\n\|(?:[- :\t]+\|)+[ \t]*\n)((?:[ \t]*\|[^\n]*\n)*)(?=\n|$)/i;
|
|
793
|
+
const byPhaseMatch = content.match(byPhaseTablePattern);
|
|
794
|
+
if (byPhaseMatch) {
|
|
795
|
+
let tableBody = byPhaseMatch[2].trim();
|
|
796
|
+
const phaseRowPattern = new RegExp(`^\\|\\s*${escapeRegex(String(phaseNum))}\\s*\\|.*$`, 'm');
|
|
797
|
+
const newRow = `| ${phaseNum} | ${summaryCount} | - | - |`;
|
|
798
|
+
if (phaseRowPattern.test(tableBody)) {
|
|
799
|
+
// Update existing row
|
|
800
|
+
tableBody = tableBody.replace(new RegExp(`^\\|\\s*${escapeRegex(String(phaseNum))}\\s*\\|.*$`, 'm'), newRow);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
// Remove placeholder row and add new row
|
|
804
|
+
tableBody = tableBody.replace(/^\|\s*-\s*\|\s*-\s*\|\s*-\s*\|\s*-\s*\|$/m, '').trim();
|
|
805
|
+
tableBody = tableBody ? tableBody + '\n' + newRow : newRow;
|
|
806
|
+
}
|
|
807
|
+
content = content.replace(byPhaseTablePattern, `$1${tableBody}\n`);
|
|
808
|
+
}
|
|
809
|
+
return content;
|
|
810
|
+
}
|
|
811
|
+
// ─── phaseComplete handler ────────────────────────────────────────────────
|
|
812
|
+
/**
|
|
813
|
+
* Query handler for phase.complete.
|
|
814
|
+
*
|
|
815
|
+
* Port of cmdPhaseComplete from phase.cjs lines 663-932.
|
|
816
|
+
* Marks a phase as done — updates ROADMAP.md (checkbox, progress table,
|
|
817
|
+
* plan count, plan checkboxes), REQUIREMENTS.md (requirement checkboxes,
|
|
818
|
+
* traceability table), and STATE.md (current phase, status, progress,
|
|
819
|
+
* performance metrics) atomically with per-file locks.
|
|
820
|
+
*
|
|
821
|
+
* @param args - args[0]: phaseNum (required)
|
|
822
|
+
* @param projectDir - Project root directory
|
|
823
|
+
* @returns QueryResult with completion details and warnings
|
|
824
|
+
*/
|
|
825
|
+
export const phaseComplete = async (args, projectDir, workstream) => {
|
|
826
|
+
const phaseNum = args[0];
|
|
827
|
+
if (!phaseNum) {
|
|
828
|
+
throw new GTDError('phase number required for phase complete', ErrorClassification.Validation);
|
|
829
|
+
}
|
|
830
|
+
assertNoNullBytes(phaseNum, 'phaseNum');
|
|
831
|
+
const paths = planningPaths(projectDir, workstream);
|
|
832
|
+
const today = new Date().toISOString().split('T')[0];
|
|
833
|
+
// Step A: Validate phase exists and get info
|
|
834
|
+
const phaseInfo = await findPhaseDir(projectDir, phaseNum, workstream);
|
|
835
|
+
if (!phaseInfo) {
|
|
836
|
+
throw new GTDError(`Phase ${phaseNum} not found`, ErrorClassification.Validation);
|
|
837
|
+
}
|
|
838
|
+
const phaseDir = phaseInfo.dirPath;
|
|
839
|
+
let phaseFiles;
|
|
840
|
+
try {
|
|
841
|
+
phaseFiles = await readdir(phaseDir);
|
|
842
|
+
}
|
|
843
|
+
catch {
|
|
844
|
+
phaseFiles = [];
|
|
845
|
+
}
|
|
846
|
+
const plans = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md');
|
|
847
|
+
const summaries = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
848
|
+
const planCount = plans.length;
|
|
849
|
+
const summaryCount = summaries.length;
|
|
850
|
+
let requirementsUpdated = false;
|
|
851
|
+
// Step B: Check for verification warnings (non-blocking)
|
|
852
|
+
const warnings = [];
|
|
853
|
+
for (const file of phaseFiles.filter(f => f.includes('-UAT') && f.endsWith('.md'))) {
|
|
854
|
+
try {
|
|
855
|
+
const content = await readFile(join(phaseDir, file), 'utf-8');
|
|
856
|
+
if (/result: pending/.test(content))
|
|
857
|
+
warnings.push(`${file}: has pending tests`);
|
|
858
|
+
if (/result: blocked/.test(content))
|
|
859
|
+
warnings.push(`${file}: has blocked tests`);
|
|
860
|
+
if (/status: partial/.test(content))
|
|
861
|
+
warnings.push(`${file}: testing incomplete (partial)`);
|
|
862
|
+
if (/status: diagnosed/.test(content))
|
|
863
|
+
warnings.push(`${file}: has diagnosed gaps`);
|
|
864
|
+
}
|
|
865
|
+
catch { /* intentionally empty */ }
|
|
866
|
+
}
|
|
867
|
+
for (const file of phaseFiles.filter(f => f.includes('-VERIFICATION') && f.endsWith('.md'))) {
|
|
868
|
+
try {
|
|
869
|
+
const content = await readFile(join(phaseDir, file), 'utf-8');
|
|
870
|
+
if (/status: human_needed/.test(content))
|
|
871
|
+
warnings.push(`${file}: needs human verification`);
|
|
872
|
+
if (/status: gaps_found/.test(content))
|
|
873
|
+
warnings.push(`${file}: has unresolved gaps`);
|
|
874
|
+
}
|
|
875
|
+
catch { /* intentionally empty */ }
|
|
876
|
+
}
|
|
877
|
+
// Step C: Update ROADMAP.md atomically
|
|
878
|
+
if (existsSync(paths.roadmap)) {
|
|
879
|
+
await readModifyWriteRoadmapMd(projectDir, async (roadmapContent) => {
|
|
880
|
+
const phaseEscaped = escapeRegex(phaseNum);
|
|
881
|
+
// Checkbox: - [ ] Phase N: -> - [x] Phase N: (...completed DATE)
|
|
882
|
+
const checkboxPattern = new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseEscaped}[:\\s][^\\n]*)`, 'i');
|
|
883
|
+
roadmapContent = replaceInCurrentMilestone(roadmapContent, checkboxPattern, `$1x$2 (completed ${today})`);
|
|
884
|
+
// Progress table: update Status to Complete, add date
|
|
885
|
+
const tableRowPattern = new RegExp(`^(\\|\\s*${phaseEscaped}\\.?\\s[^|]*(?:\\|[^\\n]*))$`, 'im');
|
|
886
|
+
roadmapContent = roadmapContent.replace(tableRowPattern, (fullRow) => {
|
|
887
|
+
const cells = fullRow.split('|').slice(1, -1);
|
|
888
|
+
if (cells.length === 5) {
|
|
889
|
+
cells[2] = ` ${summaryCount}/${planCount} `;
|
|
890
|
+
cells[3] = ' Complete ';
|
|
891
|
+
cells[4] = ` ${today} `;
|
|
892
|
+
}
|
|
893
|
+
else if (cells.length === 4) {
|
|
894
|
+
cells[1] = ` ${summaryCount}/${planCount} `;
|
|
895
|
+
cells[2] = ' Complete ';
|
|
896
|
+
cells[3] = ` ${today} `;
|
|
897
|
+
}
|
|
898
|
+
return '|' + cells.join('|') + '|';
|
|
899
|
+
});
|
|
900
|
+
// Update plan count in phase section
|
|
901
|
+
const planCountPattern = new RegExp(`(#{2,4}\\s*Phase\\s+${phaseEscaped}(?:(?!\\n#{2,4})[\\s\\S])*?\\*\\*Plans:\\*\\*[ \\t]*)[^\\n]+`, 'i');
|
|
902
|
+
roadmapContent = replaceInCurrentMilestone(roadmapContent, planCountPattern, `$1${summaryCount}/${planCount} plans complete`);
|
|
903
|
+
// Mark completed plan checkboxes
|
|
904
|
+
for (const summaryFile of summaries) {
|
|
905
|
+
const planId = summaryFile.replace('-SUMMARY.md', '').replace('SUMMARY.md', '');
|
|
906
|
+
if (!planId)
|
|
907
|
+
continue;
|
|
908
|
+
const planEscaped = escapeRegex(planId);
|
|
909
|
+
const planCheckboxPattern = new RegExp(`(-\\s*\\[) (\\]\\s*(?:\\*\\*)?${planEscaped}(?:\\*\\*)?)`, 'i');
|
|
910
|
+
roadmapContent = roadmapContent.replace(planCheckboxPattern, '$1x$2');
|
|
911
|
+
}
|
|
912
|
+
// Step D: Update REQUIREMENTS.md
|
|
913
|
+
const reqPath = paths.requirements;
|
|
914
|
+
if (existsSync(reqPath)) {
|
|
915
|
+
const currentMilestoneRoadmap = await extractCurrentMilestone(roadmapContent, projectDir);
|
|
916
|
+
const phaseSectionMatch = currentMilestoneRoadmap.match(new RegExp(`(#{2,4}\\s*Phase\\s+${phaseEscaped}[:\\s][\\s\\S]*?)(?=#{2,4}\\s*Phase\\s+|$)`, 'i'));
|
|
917
|
+
const sectionText = phaseSectionMatch ? phaseSectionMatch[1] : '';
|
|
918
|
+
const reqMatch = sectionText.match(/\*\*Requirements\*?\*?:?\s*([^\n]+)/i);
|
|
919
|
+
if (reqMatch) {
|
|
920
|
+
const reqIds = reqMatch[1].replace(/[[\]]/g, '').split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
|
|
921
|
+
let reqContent = await readFile(reqPath, 'utf-8');
|
|
922
|
+
for (const reqId of reqIds) {
|
|
923
|
+
const reqEscaped = escapeRegex(reqId);
|
|
924
|
+
// Update checkbox: - [ ] **REQ-ID** -> - [x] **REQ-ID**
|
|
925
|
+
reqContent = reqContent.replace(new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${reqEscaped}\\*\\*)`, 'gi'), '$1x$2');
|
|
926
|
+
// Update traceability table: Pending/In Progress -> Complete
|
|
927
|
+
reqContent = reqContent.replace(new RegExp(`(\\|\\s*${reqEscaped}\\s*\\|[^|]+\\|)\\s*(?:Pending|In Progress)\\s*(\\|)`, 'gi'), '$1 Complete $2');
|
|
928
|
+
}
|
|
929
|
+
await writeFile(reqPath, reqContent, 'utf-8');
|
|
930
|
+
requirementsUpdated = true;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
return roadmapContent;
|
|
934
|
+
}, workstream);
|
|
935
|
+
}
|
|
936
|
+
// Step E: Find next phase — filesystem first, then ROADMAP.md fallback
|
|
937
|
+
let nextPhaseNum = null;
|
|
938
|
+
let nextPhaseName = null;
|
|
939
|
+
let isLastPhase = true;
|
|
940
|
+
// Tracks whether the completed phase belongs to the primary milestone in STATE.md.
|
|
941
|
+
// When false (parallel-milestone case, Bug #2676), the milestone filter is bypassed
|
|
942
|
+
// for next-phase detection so phases from the same secondary milestone are visible.
|
|
943
|
+
let completedPhaseInPrimaryMilestone = true;
|
|
944
|
+
try {
|
|
945
|
+
const isDirInMilestone = await getMilestonePhaseFilter(projectDir, workstream);
|
|
946
|
+
const entries = await readdir(paths.phases, { withFileTypes: true });
|
|
947
|
+
const allDirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
948
|
+
// Guard: if the completed phase's directory is not in the current-milestone filter
|
|
949
|
+
// set, the filter was built from a different (primary) milestone in STATE.md.
|
|
950
|
+
// In that case skip the filter so we can find the true next phase on disk.
|
|
951
|
+
// This handles parallel-milestone workflows where STATE.md's `milestone:` field
|
|
952
|
+
// points at the primary milestone but the phase being completed belongs to a
|
|
953
|
+
// secondary in-flight milestone. (Bug #2676)
|
|
954
|
+
const completedDirInFilter = allDirs.some((d) => {
|
|
955
|
+
const dm = d.match(/^(\d+[A-Z]?(?:\.\d+)*)-?/i);
|
|
956
|
+
return dm && comparePhaseNum(dm[1], phaseNum) === 0 && isDirInMilestone(d);
|
|
957
|
+
});
|
|
958
|
+
completedPhaseInPrimaryMilestone = completedDirInFilter;
|
|
959
|
+
const effectiveFilter = completedDirInFilter ? isDirInMilestone : (_d) => true;
|
|
960
|
+
const dirs = allDirs
|
|
961
|
+
.filter(effectiveFilter)
|
|
962
|
+
.sort((a, b) => comparePhaseNum(a, b));
|
|
963
|
+
for (const dir of dirs) {
|
|
964
|
+
const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);
|
|
965
|
+
if (dm) {
|
|
966
|
+
if (comparePhaseNum(dm[1], phaseNum) > 0) {
|
|
967
|
+
nextPhaseNum = dm[1];
|
|
968
|
+
nextPhaseName = dm[2] || null;
|
|
969
|
+
isLastPhase = false;
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
catch { /* intentionally empty */ }
|
|
976
|
+
// Fallback: check ROADMAP.md for phases not yet scaffolded.
|
|
977
|
+
// When the completed phase is from a parallel (non-primary) milestone, scan the
|
|
978
|
+
// full ROADMAP rather than the primary-milestone slice so 41.3 is visible when
|
|
979
|
+
// completing 41.2 for a secondary milestone. (Bug #2676)
|
|
980
|
+
if (isLastPhase && existsSync(paths.roadmap)) {
|
|
981
|
+
try {
|
|
982
|
+
const roadmapContent = await readFile(paths.roadmap, 'utf-8');
|
|
983
|
+
const roadmapForPhases = completedPhaseInPrimaryMilestone
|
|
984
|
+
? await extractCurrentMilestone(roadmapContent, projectDir)
|
|
985
|
+
: roadmapContent;
|
|
986
|
+
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
|
|
987
|
+
let pm;
|
|
988
|
+
while ((pm = phasePattern.exec(roadmapForPhases)) !== null) {
|
|
989
|
+
if (comparePhaseNum(pm[1], phaseNum) > 0) {
|
|
990
|
+
nextPhaseNum = pm[1];
|
|
991
|
+
nextPhaseName = pm[2].replace(/\(INSERTED\)/i, '').trim().toLowerCase().replace(/\s+/g, '-');
|
|
992
|
+
isLastPhase = false;
|
|
993
|
+
break;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
catch { /* intentionally empty */ }
|
|
998
|
+
}
|
|
999
|
+
// Step F: Update STATE.md atomically
|
|
1000
|
+
let stateUpdated = false;
|
|
1001
|
+
if (existsSync(paths.state)) {
|
|
1002
|
+
const lockPath = await acquireStateLock(paths.state);
|
|
1003
|
+
try {
|
|
1004
|
+
const rawState = await readFile(paths.state, 'utf-8');
|
|
1005
|
+
// Split into frontmatter and body to prevent field replacement from
|
|
1006
|
+
// matching YAML keys (e.g., `status:` in frontmatter vs `Status:` in body).
|
|
1007
|
+
// Pattern 11: Strip frontmatter before modifier (from Phase 11 decisions).
|
|
1008
|
+
const fmMatch = rawState.match(/^(---\r?\n[\s\S]*?\r?\n---)\s*/);
|
|
1009
|
+
let frontmatter = fmMatch ? fmMatch[1] : '';
|
|
1010
|
+
let body = fmMatch ? rawState.slice(fmMatch[0].length) : rawState;
|
|
1011
|
+
// Update Current Phase — preserve "X of Y (Name)" compound format
|
|
1012
|
+
const phaseValue = nextPhaseNum || phaseNum;
|
|
1013
|
+
const existingPhaseField = stateExtractField(body, 'Current Phase')
|
|
1014
|
+
|| stateExtractField(body, 'Phase');
|
|
1015
|
+
let newPhaseValue = String(phaseValue);
|
|
1016
|
+
if (existingPhaseField) {
|
|
1017
|
+
const totalMatch = existingPhaseField.match(/of\s+(\d+)/);
|
|
1018
|
+
const nameMatch = existingPhaseField.match(/\(([^)]+)\)/);
|
|
1019
|
+
if (totalMatch) {
|
|
1020
|
+
const total = totalMatch[1];
|
|
1021
|
+
const nameStr = nextPhaseName
|
|
1022
|
+
? ` (${nextPhaseName.replace(/-/g, ' ')})`
|
|
1023
|
+
: (nameMatch ? ` (${nameMatch[1]})` : '');
|
|
1024
|
+
newPhaseValue = `${phaseValue} of ${total}${nameStr}`;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
body = stateReplaceFieldWithFallback(body, 'Current Phase', 'Phase', newPhaseValue);
|
|
1028
|
+
// Update Status
|
|
1029
|
+
body = stateReplaceFieldWithFallback(body, 'Status', null, isLastPhase ? 'Milestone complete' : 'Ready to plan');
|
|
1030
|
+
// Update Current Plan
|
|
1031
|
+
body = stateReplaceFieldWithFallback(body, 'Current Plan', 'Plan', 'Not started');
|
|
1032
|
+
// Update Last Activity
|
|
1033
|
+
body = stateReplaceFieldWithFallback(body, 'Last Activity', 'Last activity', today);
|
|
1034
|
+
// Update Performance Metrics section (operates on body only)
|
|
1035
|
+
body = updatePerformanceMetricsSection(body, phaseNum, planCount, summaryCount);
|
|
1036
|
+
// ── Root cause 1 fix: derive completed_phases from ROADMAP, not blind increment ──
|
|
1037
|
+
// Read the freshly-updated ROADMAP (after Step C) to count Complete rows.
|
|
1038
|
+
// This makes phase.complete idempotent: running it twice on the same phase
|
|
1039
|
+
// produces the same completed_phases value.
|
|
1040
|
+
let derivedCompletedPhases = null;
|
|
1041
|
+
let derivedTotalPhases = null;
|
|
1042
|
+
let derivedTotalPlans = null;
|
|
1043
|
+
if (existsSync(paths.roadmap)) {
|
|
1044
|
+
try {
|
|
1045
|
+
const freshRoadmap = await readFile(paths.roadmap, 'utf-8');
|
|
1046
|
+
// Count Complete rows in the progress table (Status column = "Complete")
|
|
1047
|
+
const tableCompletePattern = /\|\s*\d+[A-Z]?\S*\s*\|[^|]*\|\s*Complete\s*\|/gi;
|
|
1048
|
+
const completeMatches = freshRoadmap.match(tableCompletePattern);
|
|
1049
|
+
derivedCompletedPhases = completeMatches ? completeMatches.length : null;
|
|
1050
|
+
// Count total phase rows in progress table (header + separator + data rows)
|
|
1051
|
+
// Identify the progress table by looking for Phase|Plans|Status|Completed header
|
|
1052
|
+
const progressTableMatch = freshRoadmap.match(/\|\s*Phase\s*\|\s*Plans\s*\|\s*Status\s*\|\s*Completed\s*\|(.*\n)*?(?:\n|$)/i);
|
|
1053
|
+
if (progressTableMatch) {
|
|
1054
|
+
const tableText = progressTableMatch[0];
|
|
1055
|
+
const dataRowPattern = /^\|\s*\d+[A-Z]?\S*\s*\|/gm;
|
|
1056
|
+
const dataRows = tableText.match(dataRowPattern);
|
|
1057
|
+
derivedTotalPhases = dataRows ? dataRows.length : null;
|
|
1058
|
+
}
|
|
1059
|
+
// Sum plan counts from M/N or 0/N columns in the progress table
|
|
1060
|
+
let totalPlansSum = 0;
|
|
1061
|
+
const planCellPattern = /\|\s*\d+[A-Z]?\S*\s*\|\s*(\d+)\/(\d+)\s*\|/gi;
|
|
1062
|
+
let pm;
|
|
1063
|
+
while ((pm = planCellPattern.exec(freshRoadmap)) !== null) {
|
|
1064
|
+
totalPlansSum += parseInt(pm[2], 10);
|
|
1065
|
+
}
|
|
1066
|
+
if (totalPlansSum > 0)
|
|
1067
|
+
derivedTotalPlans = totalPlansSum;
|
|
1068
|
+
}
|
|
1069
|
+
catch { /* intentionally empty — fall through to existing values */ }
|
|
1070
|
+
}
|
|
1071
|
+
// Count completed plans from all SUMMARY files across phase dirs
|
|
1072
|
+
let derivedCompletedPlans = null;
|
|
1073
|
+
try {
|
|
1074
|
+
const phaseEntries = await readdir(paths.phases, { withFileTypes: true });
|
|
1075
|
+
let summaryTotal = 0;
|
|
1076
|
+
for (const entry of phaseEntries) {
|
|
1077
|
+
if (!entry.isDirectory())
|
|
1078
|
+
continue;
|
|
1079
|
+
try {
|
|
1080
|
+
const files = await readdir(join(paths.phases, entry.name));
|
|
1081
|
+
summaryTotal += files.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md').length;
|
|
1082
|
+
}
|
|
1083
|
+
catch { /* intentionally empty */ }
|
|
1084
|
+
}
|
|
1085
|
+
derivedCompletedPlans = summaryTotal;
|
|
1086
|
+
}
|
|
1087
|
+
catch { /* intentionally empty */ }
|
|
1088
|
+
// ── Root cause 2 fix: update all stale frontmatter fields ──
|
|
1089
|
+
// completed_phases — derived from ROADMAP (idempotent)
|
|
1090
|
+
if (derivedCompletedPhases !== null && frontmatter.includes('completed_phases:')) {
|
|
1091
|
+
frontmatter = frontmatter.replace(/completed_phases:\s*\d+/, `completed_phases: ${derivedCompletedPhases}`);
|
|
1092
|
+
}
|
|
1093
|
+
// total_phases — keep in sync with ROADMAP
|
|
1094
|
+
if (derivedTotalPhases !== null && frontmatter.includes('total_phases:')) {
|
|
1095
|
+
frontmatter = frontmatter.replace(/total_phases:\s*\d+/, `total_phases: ${derivedTotalPhases}`);
|
|
1096
|
+
}
|
|
1097
|
+
// total_plans — derived from ROADMAP plan column sums
|
|
1098
|
+
if (derivedTotalPlans !== null && frontmatter.includes('total_plans:')) {
|
|
1099
|
+
frontmatter = frontmatter.replace(/total_plans:\s*\d+/, `total_plans: ${derivedTotalPlans}`);
|
|
1100
|
+
}
|
|
1101
|
+
// completed_plans — count of SUMMARY files on disk
|
|
1102
|
+
if (derivedCompletedPlans !== null && frontmatter.includes('completed_plans:')) {
|
|
1103
|
+
frontmatter = frontmatter.replace(/completed_plans:\s*\d+/, `completed_plans: ${derivedCompletedPlans}`);
|
|
1104
|
+
}
|
|
1105
|
+
// percent — recompute from fresh derived values
|
|
1106
|
+
const effectiveCompleted = derivedCompletedPhases ?? parseInt(frontmatter.match(/completed_phases:\s*(\d+)/)?.[1] ?? '0', 10);
|
|
1107
|
+
const effectiveTotal = derivedTotalPhases ?? parseInt(frontmatter.match(/total_phases:\s*(\d+)/)?.[1] ?? '0', 10);
|
|
1108
|
+
if (effectiveTotal > 0 && frontmatter.includes('percent:')) {
|
|
1109
|
+
const newPercent = Math.round((effectiveCompleted / effectiveTotal) * 100);
|
|
1110
|
+
frontmatter = frontmatter.replace(/(percent:\s*)\d+/, `$1${newPercent}`);
|
|
1111
|
+
}
|
|
1112
|
+
// last_updated — refresh to current timestamp
|
|
1113
|
+
const nowIso = new Date().toISOString();
|
|
1114
|
+
if (frontmatter.includes('last_updated:')) {
|
|
1115
|
+
frontmatter = frontmatter.replace(/last_updated:\s*\S+/, `last_updated: ${nowIso}`);
|
|
1116
|
+
}
|
|
1117
|
+
// stopped_at — set to phase completion message
|
|
1118
|
+
const stoppedAtValue = isLastPhase
|
|
1119
|
+
? `Milestone complete (Phase ${phaseNum} was final phase)`
|
|
1120
|
+
: `Phase ${phaseNum} complete (${summaryCount}/${planCount}) — ready to discuss Phase ${nextPhaseNum}`;
|
|
1121
|
+
if (frontmatter.includes('stopped_at:')) {
|
|
1122
|
+
frontmatter = frontmatter.replace(/stopped_at:\s*.+/, `stopped_at: ${stoppedAtValue}`);
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
// Insert stopped_at before closing ---
|
|
1126
|
+
frontmatter = frontmatter.replace(/(---\s*)$/, `stopped_at: ${stoppedAtValue}\n$1`);
|
|
1127
|
+
}
|
|
1128
|
+
// ── Root cause 2 fix: update body Current focus ──
|
|
1129
|
+
const focusValue = isLastPhase
|
|
1130
|
+
? 'Milestone complete'
|
|
1131
|
+
: (nextPhaseName
|
|
1132
|
+
? `Phase ${nextPhaseNum} — ${nextPhaseName.replace(/-/g, ' ')}`
|
|
1133
|
+
: `Phase ${nextPhaseNum}`);
|
|
1134
|
+
const focusPattern = /(\*\*Current focus:\*\*\s*).*/i;
|
|
1135
|
+
if (focusPattern.test(body)) {
|
|
1136
|
+
body = body.replace(focusPattern, (_m, prefix) => `${prefix}${focusValue}`);
|
|
1137
|
+
}
|
|
1138
|
+
// Update frontmatter status field
|
|
1139
|
+
frontmatter = frontmatter.replace(/status:\s*.+/, `status: ${isLastPhase ? 'milestone_complete' : 'ready_to_plan'}`);
|
|
1140
|
+
// Reassemble and write
|
|
1141
|
+
const stateContent = frontmatter + '\n\n' + body;
|
|
1142
|
+
await writeFile(paths.state, stateContent, 'utf-8');
|
|
1143
|
+
stateUpdated = true;
|
|
1144
|
+
}
|
|
1145
|
+
finally {
|
|
1146
|
+
await releaseStateLock(lockPath);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// Step G: Return result
|
|
1150
|
+
return {
|
|
1151
|
+
data: {
|
|
1152
|
+
completed_phase: phaseNum,
|
|
1153
|
+
phase_name: phaseInfo.phaseName,
|
|
1154
|
+
plans_executed: `${summaryCount}/${planCount}`,
|
|
1155
|
+
next_phase: nextPhaseNum,
|
|
1156
|
+
next_phase_name: nextPhaseName,
|
|
1157
|
+
is_last_phase: isLastPhase,
|
|
1158
|
+
date: today,
|
|
1159
|
+
roadmap_updated: existsSync(paths.roadmap),
|
|
1160
|
+
state_updated: stateUpdated,
|
|
1161
|
+
requirements_updated: requirementsUpdated,
|
|
1162
|
+
warnings,
|
|
1163
|
+
has_warnings: warnings.length > 0,
|
|
1164
|
+
},
|
|
1165
|
+
};
|
|
1166
|
+
};
|
|
1167
|
+
// ─── phasesClear handler ──────────────────────────────────────────────────
|
|
1168
|
+
/**
|
|
1169
|
+
* Query handler for phases.clear.
|
|
1170
|
+
*
|
|
1171
|
+
* Port of cmdPhasesClear from milestone.cjs lines 250-277.
|
|
1172
|
+
* Deletes all phase directories except 999.x backlog phases.
|
|
1173
|
+
* Requires --confirm flag to proceed.
|
|
1174
|
+
*
|
|
1175
|
+
* @param args - args[0]: '--confirm' to proceed (optional)
|
|
1176
|
+
* @param projectDir - Project root directory
|
|
1177
|
+
* @returns QueryResult with { cleared: count }
|
|
1178
|
+
*/
|
|
1179
|
+
export const phasesClear = async (args, projectDir, workstream) => {
|
|
1180
|
+
const phasesDir = planningPaths(projectDir, workstream).phases;
|
|
1181
|
+
const confirm = Array.isArray(args) && args.includes('--confirm');
|
|
1182
|
+
let cleared = 0;
|
|
1183
|
+
if (existsSync(phasesDir)) {
|
|
1184
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
1185
|
+
const dirs = entries.filter(e => e.isDirectory() && !/^999(?:\.|$)/.test(e.name));
|
|
1186
|
+
if (dirs.length > 0 && !confirm) {
|
|
1187
|
+
throw new GTDError(`phases clear would delete ${dirs.length} phase director${dirs.length === 1 ? 'y' : 'ies'}. ` +
|
|
1188
|
+
`Pass --confirm to proceed.`, ErrorClassification.Validation);
|
|
1189
|
+
}
|
|
1190
|
+
for (const entry of dirs) {
|
|
1191
|
+
await rm(join(phasesDir, entry.name), { recursive: true, force: true });
|
|
1192
|
+
cleared++;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
return { data: { cleared } };
|
|
1196
|
+
};
|
|
1197
|
+
// ─── phasesArchive handler ────────────────────────────────────────────────
|
|
1198
|
+
/**
|
|
1199
|
+
* Query handler for phases.archive.
|
|
1200
|
+
*
|
|
1201
|
+
* Extracted from cmdMilestoneComplete, milestone.cjs lines 210-227.
|
|
1202
|
+
* Moves milestone phase directories to milestones/{version}-phases/.
|
|
1203
|
+
*
|
|
1204
|
+
* @param args - args[0]: version string (e.g., "v3.0")
|
|
1205
|
+
* @param projectDir - Project root directory
|
|
1206
|
+
* @returns QueryResult with { archived: count, version, archive_directory }
|
|
1207
|
+
*/
|
|
1208
|
+
export const phasesList = async (args, projectDir, workstream) => {
|
|
1209
|
+
const paths = planningPaths(projectDir, workstream);
|
|
1210
|
+
const phasesDir = paths.phases;
|
|
1211
|
+
const typeIdx = args.indexOf('--type');
|
|
1212
|
+
const phaseIdx = args.indexOf('--phase');
|
|
1213
|
+
const type = typeIdx !== -1 ? args[typeIdx + 1] : null;
|
|
1214
|
+
const phase = phaseIdx !== -1 ? args[phaseIdx + 1] : null;
|
|
1215
|
+
const includeArchived = args.includes('--include-archived');
|
|
1216
|
+
if (!existsSync(phasesDir)) {
|
|
1217
|
+
return { data: type ? { files: [], count: 0 } : { directories: [], count: 0 } };
|
|
1218
|
+
}
|
|
1219
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
1220
|
+
let dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
1221
|
+
if (includeArchived) {
|
|
1222
|
+
const milestonesDir = join(paths.planning, 'milestones');
|
|
1223
|
+
if (existsSync(milestonesDir)) {
|
|
1224
|
+
const milestoneEntries = await readdir(milestonesDir, { withFileTypes: true });
|
|
1225
|
+
for (const mDir of milestoneEntries.filter(e => e.isDirectory() && e.name.endsWith('-phases'))) {
|
|
1226
|
+
const milestone = mDir.name.replace(/-phases$/, '');
|
|
1227
|
+
const archivedEntries = await readdir(join(milestonesDir, mDir.name), { withFileTypes: true });
|
|
1228
|
+
for (const a of archivedEntries.filter(e => e.isDirectory())) {
|
|
1229
|
+
dirs.push(`${a.name} [${milestone}]`);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
dirs.sort((a, b) => comparePhaseNum(a, b));
|
|
1235
|
+
if (phase) {
|
|
1236
|
+
const normalized = normalizePhaseName(phase);
|
|
1237
|
+
const match = dirs.find(d => phaseTokenMatches(d, normalized));
|
|
1238
|
+
if (!match) {
|
|
1239
|
+
return { data: { files: [], count: 0, phase_dir: null, error: 'Phase not found' } };
|
|
1240
|
+
}
|
|
1241
|
+
dirs = [match];
|
|
1242
|
+
}
|
|
1243
|
+
if (type) {
|
|
1244
|
+
const files = [];
|
|
1245
|
+
for (const dir of dirs) {
|
|
1246
|
+
const dirPath = join(phasesDir, dir);
|
|
1247
|
+
if (!existsSync(dirPath))
|
|
1248
|
+
continue;
|
|
1249
|
+
const dirFiles = await readdir(dirPath);
|
|
1250
|
+
let filtered;
|
|
1251
|
+
if (type === 'plans') {
|
|
1252
|
+
filtered = dirFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md');
|
|
1253
|
+
}
|
|
1254
|
+
else if (type === 'summaries') {
|
|
1255
|
+
filtered = dirFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
1256
|
+
}
|
|
1257
|
+
else {
|
|
1258
|
+
filtered = dirFiles;
|
|
1259
|
+
}
|
|
1260
|
+
files.push(...filtered.sort());
|
|
1261
|
+
}
|
|
1262
|
+
return { data: { files, count: files.length, phase_dir: phase ? dirs[0]?.replace(/^\d+(?:\.\d+)*-?/, '') : null } };
|
|
1263
|
+
}
|
|
1264
|
+
return { data: { directories: dirs, count: dirs.length } };
|
|
1265
|
+
};
|
|
1266
|
+
export const phaseNextDecimal = async (args, projectDir, workstream) => {
|
|
1267
|
+
const basePhase = args[0];
|
|
1268
|
+
if (!basePhase) {
|
|
1269
|
+
throw new GTDError('base phase number required', ErrorClassification.Validation);
|
|
1270
|
+
}
|
|
1271
|
+
assertNoNullBytes(basePhase, 'basePhase');
|
|
1272
|
+
const paths = planningPaths(projectDir, workstream);
|
|
1273
|
+
const phasesDir = paths.phases;
|
|
1274
|
+
const normalized = normalizePhaseName(basePhase);
|
|
1275
|
+
const decimalSet = new Set();
|
|
1276
|
+
let baseExists = false;
|
|
1277
|
+
const dirNames = await listDirectories(phasesDir);
|
|
1278
|
+
baseExists = dirNames.some((d) => phaseTokenMatches(d, normalized));
|
|
1279
|
+
for (const suffix of collectDecimalSuffixesFromDirNames(normalized, dirNames)) {
|
|
1280
|
+
decimalSet.add(suffix);
|
|
1281
|
+
}
|
|
1282
|
+
const roadmapPath = paths.roadmap;
|
|
1283
|
+
if (existsSync(roadmapPath)) {
|
|
1284
|
+
try {
|
|
1285
|
+
const roadmapContent = await readFile(roadmapPath, 'utf-8');
|
|
1286
|
+
for (const suffix of collectDecimalSuffixesFromRoadmap(normalized, roadmapContent)) {
|
|
1287
|
+
decimalSet.add(suffix);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
catch { /* ROADMAP.md read failure is non-fatal */ }
|
|
1291
|
+
}
|
|
1292
|
+
const { next: nextDecimal, existing: existingDecimals } = computeNextDecimalPhase(normalized, decimalSet);
|
|
1293
|
+
return {
|
|
1294
|
+
data: {
|
|
1295
|
+
found: baseExists,
|
|
1296
|
+
base_phase: normalized,
|
|
1297
|
+
next: nextDecimal,
|
|
1298
|
+
existing: existingDecimals,
|
|
1299
|
+
},
|
|
1300
|
+
};
|
|
1301
|
+
};
|
|
1302
|
+
export const phasesArchive = async (args, projectDir, workstream) => {
|
|
1303
|
+
const version = args[0];
|
|
1304
|
+
if (!version) {
|
|
1305
|
+
throw new GTDError('version required for phases archive', ErrorClassification.Validation);
|
|
1306
|
+
}
|
|
1307
|
+
assertNoNullBytes(version, 'version');
|
|
1308
|
+
const paths = planningPaths(projectDir, workstream);
|
|
1309
|
+
const phasesDir = paths.phases;
|
|
1310
|
+
const isDirInMilestone = await getMilestonePhaseFilter(projectDir, workstream);
|
|
1311
|
+
const archiveDir = join(paths.planning, 'milestones', `${version}-phases`);
|
|
1312
|
+
const archivedCount = await archiveDirectories(phasesDir, archiveDir, (dirName) => isDirInMilestone(dirName));
|
|
1313
|
+
return {
|
|
1314
|
+
data: {
|
|
1315
|
+
archived: archivedCount,
|
|
1316
|
+
version,
|
|
1317
|
+
archive_directory: toPosixPath(relative(projectDir, archiveDir)),
|
|
1318
|
+
},
|
|
1319
|
+
};
|
|
1320
|
+
};
|
|
1321
|
+
// ─── milestoneComplete ────────────────────────────────────────────────────
|
|
1322
|
+
/**
|
|
1323
|
+
* Query handler for `milestone.complete` — port of `cmdMilestoneComplete` from `milestone.cjs`.
|
|
1324
|
+
*/
|
|
1325
|
+
export const milestoneComplete = async (args, projectDir, workstream) => {
|
|
1326
|
+
const version = args[0];
|
|
1327
|
+
if (!version) {
|
|
1328
|
+
throw new GTDError('version required for milestone complete (e.g., v1.0)', ErrorClassification.Validation);
|
|
1329
|
+
}
|
|
1330
|
+
// #3259: defense-in-depth — reject --help / -h as a version value before
|
|
1331
|
+
// any disk write, regardless of whether the dispatcher guard intercepted first.
|
|
1332
|
+
if (version === '--help' || version === '-h') {
|
|
1333
|
+
throw new GTDError(`"${version}" is not a valid milestone version; see \`gtd-sdk query --help\` for command list`, ErrorClassification.Validation);
|
|
1334
|
+
}
|
|
1335
|
+
assertNoNullBytes(version, 'version');
|
|
1336
|
+
const nameOpt = parseMultiwordArg(args, 'name');
|
|
1337
|
+
const archivePhases = args.includes('--archive-phases');
|
|
1338
|
+
const paths = planningPaths(projectDir, workstream);
|
|
1339
|
+
const roadmapPath = paths.roadmap;
|
|
1340
|
+
const reqPath = paths.requirements;
|
|
1341
|
+
const statePath = paths.state;
|
|
1342
|
+
const milestonesPath = join(paths.planning, 'MILESTONES.md');
|
|
1343
|
+
const archiveDir = join(paths.planning, 'milestones');
|
|
1344
|
+
const phasesDir = paths.phases;
|
|
1345
|
+
const today = new Date().toISOString().split('T')[0];
|
|
1346
|
+
const milestoneName = nameOpt || version;
|
|
1347
|
+
await mkdir(archiveDir, { recursive: true });
|
|
1348
|
+
const isDirInMilestone = await getMilestonePhaseFilter(projectDir, workstream);
|
|
1349
|
+
let phaseCount = 0;
|
|
1350
|
+
let totalPlans = 0;
|
|
1351
|
+
let totalTasks = 0;
|
|
1352
|
+
const accomplishments = [];
|
|
1353
|
+
try {
|
|
1354
|
+
const dirs = (await listDirectories(phasesDir)).sort();
|
|
1355
|
+
for (const dir of dirs) {
|
|
1356
|
+
if (!isDirInMilestone(dir))
|
|
1357
|
+
continue;
|
|
1358
|
+
phaseCount++;
|
|
1359
|
+
const phaseFiles = await readdir(join(phasesDir, dir));
|
|
1360
|
+
const plans = phaseFiles.filter((f) => f.endsWith('-PLAN.md') || f === 'PLAN.md');
|
|
1361
|
+
const summaries = phaseFiles.filter((f) => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
1362
|
+
totalPlans += plans.length;
|
|
1363
|
+
for (const s of summaries) {
|
|
1364
|
+
try {
|
|
1365
|
+
const content = await readFile(join(phasesDir, dir, s), 'utf-8');
|
|
1366
|
+
const fm = extractFrontmatter(content);
|
|
1367
|
+
const oneLiner = fm['one-liner'] || extractOneLinerFromBody(content);
|
|
1368
|
+
if (oneLiner) {
|
|
1369
|
+
accomplishments.push(oneLiner);
|
|
1370
|
+
}
|
|
1371
|
+
const tasksFieldMatch = content.match(/\*\*Tasks:\*\*\s*(\d+)/);
|
|
1372
|
+
if (tasksFieldMatch) {
|
|
1373
|
+
totalTasks += parseInt(tasksFieldMatch[1], 10);
|
|
1374
|
+
}
|
|
1375
|
+
else {
|
|
1376
|
+
const xmlTaskMatches = content.match(/<task[\s>]/gi) || [];
|
|
1377
|
+
const mdTaskMatches = content.match(/##\s*Task\s*\d+/gi) || [];
|
|
1378
|
+
totalTasks += xmlTaskMatches.length || mdTaskMatches.length;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
catch {
|
|
1382
|
+
/* intentionally empty */
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
catch {
|
|
1388
|
+
/* intentionally empty */
|
|
1389
|
+
}
|
|
1390
|
+
if (existsSync(roadmapPath)) {
|
|
1391
|
+
const roadmapContent = await readFile(roadmapPath, 'utf-8');
|
|
1392
|
+
await writeFile(join(archiveDir, `${version}-ROADMAP.md`), roadmapContent, 'utf-8');
|
|
1393
|
+
}
|
|
1394
|
+
if (existsSync(reqPath)) {
|
|
1395
|
+
const reqContent = await readFile(reqPath, 'utf-8');
|
|
1396
|
+
const archiveHeader = `# Requirements Archive: ${version} ${milestoneName}\n\n` +
|
|
1397
|
+
`**Archived:** ${today}\n**Status:** SHIPPED\n\n` +
|
|
1398
|
+
`For current requirements, see \`.planning/REQUIREMENTS.md\`.\n\n---\n\n`;
|
|
1399
|
+
await writeFile(join(archiveDir, `${version}-REQUIREMENTS.md`), archiveHeader + reqContent, 'utf-8');
|
|
1400
|
+
}
|
|
1401
|
+
const auditFile = join(projectDir, '.planning', `${version}-MILESTONE-AUDIT.md`);
|
|
1402
|
+
if (existsSync(auditFile)) {
|
|
1403
|
+
await rename(auditFile, join(archiveDir, `${version}-MILESTONE-AUDIT.md`));
|
|
1404
|
+
}
|
|
1405
|
+
const accomplishmentsList = accomplishments.map((a) => `- ${a}`).join('\n');
|
|
1406
|
+
const milestoneEntry = `## ${version} ${milestoneName} (Shipped: ${today})\n\n` +
|
|
1407
|
+
`**Phases completed:** ${phaseCount} phases, ${totalPlans} plans, ${totalTasks} tasks\n\n` +
|
|
1408
|
+
`**Key accomplishments:**\n${accomplishmentsList || '- (none recorded)'}\n\n---\n\n`;
|
|
1409
|
+
if (existsSync(milestonesPath)) {
|
|
1410
|
+
const existing = await readFile(milestonesPath, 'utf-8');
|
|
1411
|
+
if (!existing.trim()) {
|
|
1412
|
+
await writeFile(milestonesPath, normalizeMd(`# Milestones\n\n${milestoneEntry}`), 'utf-8');
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
const headerMatch = existing.match(/^(#{1,3}\s+[^\n]*\n\n?)/);
|
|
1416
|
+
if (headerMatch) {
|
|
1417
|
+
const header = headerMatch[1];
|
|
1418
|
+
const rest = existing.slice(header.length);
|
|
1419
|
+
await writeFile(milestonesPath, normalizeMd(header + milestoneEntry + rest), 'utf-8');
|
|
1420
|
+
}
|
|
1421
|
+
else {
|
|
1422
|
+
await writeFile(milestonesPath, normalizeMd(milestoneEntry + existing), 'utf-8');
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
else {
|
|
1427
|
+
await writeFile(milestonesPath, normalizeMd(`# Milestones\n\n${milestoneEntry}`), 'utf-8');
|
|
1428
|
+
}
|
|
1429
|
+
if (existsSync(statePath)) {
|
|
1430
|
+
await readModifyWriteStateMdFull(projectDir, (stateContent) => {
|
|
1431
|
+
let next = stateReplaceFieldWithFallback(stateContent, 'Status', null, `${version} milestone complete`);
|
|
1432
|
+
next = stateReplaceFieldWithFallback(next, 'Last Activity', 'Last activity', today);
|
|
1433
|
+
next = stateReplaceFieldWithFallback(next, 'Last Activity Description', null, `${version} milestone completed and archived`);
|
|
1434
|
+
const positionPattern = /(##\s*Current Position\s*\n)([\s\S]*?)(?=\n##|$)/i;
|
|
1435
|
+
const closedPositionBody = `\nPhase: Milestone ${version} complete\n` +
|
|
1436
|
+
`Plan: —\n` +
|
|
1437
|
+
`Status: Awaiting next milestone\n` +
|
|
1438
|
+
`Last activity: ${today} — Milestone ${version} completed and archived\n\n`;
|
|
1439
|
+
if (positionPattern.test(next)) {
|
|
1440
|
+
next = next.replace(positionPattern, (_m, header) => `${header}${closedPositionBody}`);
|
|
1441
|
+
}
|
|
1442
|
+
else {
|
|
1443
|
+
next = `${next.trimEnd()}\n\n## Current Position\n${closedPositionBody}`;
|
|
1444
|
+
}
|
|
1445
|
+
const operatorPattern = /(##\s*Operator Next Steps\s*\n)([\s\S]*?)(?=\n##|$)/i;
|
|
1446
|
+
if (operatorPattern.test(next)) {
|
|
1447
|
+
next = next.replace(operatorPattern, `$1\n- Start the next milestone with /gtd-new-milestone\n\n`);
|
|
1448
|
+
}
|
|
1449
|
+
else {
|
|
1450
|
+
next = `${next.trimEnd()}\n\n## Operator Next Steps\n\n- Start the next milestone with /gtd-new-milestone\n`;
|
|
1451
|
+
}
|
|
1452
|
+
return next;
|
|
1453
|
+
}, workstream);
|
|
1454
|
+
}
|
|
1455
|
+
let phasesArchived = false;
|
|
1456
|
+
if (archivePhases) {
|
|
1457
|
+
try {
|
|
1458
|
+
const phaseArchiveDir = join(archiveDir, `${version}-phases`);
|
|
1459
|
+
const archivedCount = await archiveDirectories(phasesDir, phaseArchiveDir, (dirName) => isDirInMilestone(dirName));
|
|
1460
|
+
phasesArchived = archivedCount > 0;
|
|
1461
|
+
}
|
|
1462
|
+
catch {
|
|
1463
|
+
/* intentionally empty */
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
return {
|
|
1467
|
+
data: {
|
|
1468
|
+
version,
|
|
1469
|
+
name: milestoneName,
|
|
1470
|
+
date: today,
|
|
1471
|
+
phases: phaseCount,
|
|
1472
|
+
plans: totalPlans,
|
|
1473
|
+
tasks: totalTasks,
|
|
1474
|
+
accomplishments,
|
|
1475
|
+
archived: {
|
|
1476
|
+
roadmap: existsSync(join(archiveDir, `${version}-ROADMAP.md`)),
|
|
1477
|
+
requirements: existsSync(join(archiveDir, `${version}-REQUIREMENTS.md`)),
|
|
1478
|
+
audit: existsSync(join(archiveDir, `${version}-MILESTONE-AUDIT.md`)),
|
|
1479
|
+
phases: phasesArchived,
|
|
1480
|
+
},
|
|
1481
|
+
milestones_updated: true,
|
|
1482
|
+
state_updated: existsSync(statePath),
|
|
1483
|
+
},
|
|
1484
|
+
};
|
|
1485
|
+
};
|
|
1486
|
+
//# sourceMappingURL=phase-lifecycle.js.map
|