gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.1b44e695b
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/README.md +93 -18
- package/dist/cli.js +20 -9
- package/dist/headless-ui.js +13 -6
- package/dist/headless.js +9 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +1 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +122 -40
- package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
- package/dist/resources/extensions/gsd/auto/phases.js +134 -49
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-budget.js +9 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +144 -30
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
- package/dist/resources/extensions/gsd/auto-start.js +99 -16
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +146 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
- package/dist/resources/extensions/gsd/auto.js +135 -74
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
- package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +10 -3
- package/dist/resources/extensions/gsd/git-service.js +152 -15
- package/dist/resources/extensions/gsd/gsd-db.js +76 -33
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +110 -117
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/init-wizard.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
- package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
- package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-types.js +3 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
- package/dist/resources/extensions/gsd/preferences.js +6 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/repo-identity.js +39 -22
- package/dist/resources/extensions/gsd/repository-registry.js +44 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
- package/dist/resources/extensions/gsd/session-lock.js +15 -2
- package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +28 -7
- package/dist/resources/extensions/gsd/status-guards.js +14 -2
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
- package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
- package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +142 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
- package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
- package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
- package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/shared/interview-ui.js +6 -4
- package/dist/resources/extensions/shared/next-action-ui.js +13 -5
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/resources/skills/forensics/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -7
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/package.json +4 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +13 -4
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +82 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +106 -27
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +108 -27
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +123 -40
- package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
- package/src/resources/extensions/gsd/auto/phases.ts +160 -60
- package/src/resources/extensions/gsd/auto/session.ts +16 -0
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-budget.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +164 -29
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
- package/src/resources/extensions/gsd/auto-start.ts +109 -14
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +174 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
- package/src/resources/extensions/gsd/auto.ts +172 -81
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
- package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +9 -3
- package/src/resources/extensions/gsd/git-service.ts +182 -16
- package/src/resources/extensions/gsd/gsd-db.ts +80 -31
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +142 -134
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/init-wizard.ts +17 -2
- package/src/resources/extensions/gsd/journal.ts +8 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
- package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
- package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-types.ts +35 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
- package/src/resources/extensions/gsd/preferences.ts +9 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/repo-identity.ts +45 -25
- package/src/resources/extensions/gsd/repository-registry.ts +77 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
- package/src/resources/extensions/gsd/session-lock.ts +15 -2
- package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +33 -7
- package/src/resources/extensions/gsd/status-guards.ts +16 -2
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +775 -34
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
- package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
- package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +170 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
- package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
- package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
- package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/shared/interview-ui.ts +6 -4
- package/src/resources/extensions/shared/next-action-ui.ts +11 -5
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/src/resources/skills/forensics/SKILL.md +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_ssgManifest.js +0 -0
|
@@ -20,6 +20,22 @@ import { handlePrBranch } from "../../commands-pr-branch.js";
|
|
|
20
20
|
import { currentDirectoryRoot, projectRoot } from "../context.js";
|
|
21
21
|
|
|
22
22
|
export async function handleOpsCommand(trimmed: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<boolean> {
|
|
23
|
+
const directDispatchAlias = new Map<string, string>([
|
|
24
|
+
["research-milestone", "research"],
|
|
25
|
+
["research-slice", "research"],
|
|
26
|
+
["plan-milestone", "plan"],
|
|
27
|
+
["plan-slice", "plan"],
|
|
28
|
+
["execute-task", "execute"],
|
|
29
|
+
["complete-slice", "complete"],
|
|
30
|
+
["validate-milestone", "uat"],
|
|
31
|
+
["complete-milestone", "complete"],
|
|
32
|
+
]);
|
|
33
|
+
const aliasPhase = directDispatchAlias.get(trimmed);
|
|
34
|
+
if (aliasPhase) {
|
|
35
|
+
await dispatchDirectPhase(ctx, pi, aliasPhase, projectRoot());
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
if (trimmed === "init") {
|
|
24
40
|
const { detectProjectState } = await import("../../detection.js");
|
|
25
41
|
const { handleReinit, showProjectInit } = await import("../../init-wizard.js");
|
|
@@ -188,6 +204,11 @@ Examples:
|
|
|
188
204
|
await dispatchDirectPhase(ctx, pi, phase, projectRoot());
|
|
189
205
|
return true;
|
|
190
206
|
}
|
|
207
|
+
if (trimmed === "verdict" || trimmed.startsWith("verdict ")) {
|
|
208
|
+
const { handleVerdict } = await import("../../commands-verdict.js");
|
|
209
|
+
await handleVerdict(trimmed.replace(/^verdict\s*/, "").trim(), ctx, projectRoot());
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
191
212
|
if (trimmed === "notifications" || trimmed.startsWith("notifications ")) {
|
|
192
213
|
const { handleNotificationsCommand } = await import("./notifications-handler.js");
|
|
193
214
|
await handleNotificationsCommand(trimmed.replace(/^notifications\s*/, "").trim(), ctx, pi);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { importExtensionModule, type ExtensionAPI, type ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
2
|
+
import { VISUAL_BRIEF_MODES } from "../visual-brief/prompts.js";
|
|
2
3
|
|
|
3
4
|
const TOP_LEVEL_SUBCOMMANDS = [
|
|
4
5
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
@@ -8,6 +9,7 @@ const TOP_LEVEL_SUBCOMMANDS = [
|
|
|
8
9
|
{ cmd: "pause", desc: "Pause auto-mode (preserves state, /gsd auto to resume)" },
|
|
9
10
|
{ cmd: "status", desc: "Progress dashboard" },
|
|
10
11
|
{ cmd: "visualize", desc: "Open workflow visualizer" },
|
|
12
|
+
{ cmd: "brief", desc: "Generate a visual HTML brief" },
|
|
11
13
|
{ cmd: "queue", desc: "Queue and reorder future milestones" },
|
|
12
14
|
{ cmd: "quick", desc: "Execute a quick task without full planning overhead" },
|
|
13
15
|
{ cmd: "discuss", desc: "Discuss architecture and decisions" },
|
|
@@ -87,6 +89,14 @@ function getGsdArgumentCompletions(prefix: string) {
|
|
|
87
89
|
], "next");
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
if (parts[0] === "brief" && parts.length <= 2) {
|
|
93
|
+
return filterStartsWith(
|
|
94
|
+
partial,
|
|
95
|
+
VISUAL_BRIEF_MODES.map((mode) => ({ cmd: mode.mode, desc: mode.description })),
|
|
96
|
+
"brief",
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
90
100
|
if ((parts[0] === "new-project" || parts[0] === "new-milestone") && parts.length <= 2) {
|
|
91
101
|
return filterStartsWith(partial, [
|
|
92
102
|
{ cmd: "--deep", desc: "Enable deep planning mode (staged project-level discovery)" },
|
|
@@ -123,6 +123,8 @@ export async function handleDoctor(args: string, ctx: ExtensionCommandContext, p
|
|
|
123
123
|
const { jsonMode, dryRun, fixFlag, includeBuild, includeTests, mode, requestedScope } = parseDoctorArgs(args);
|
|
124
124
|
const scope = await selectDoctorScope(projectRoot(), requestedScope);
|
|
125
125
|
const effectiveScope = mode === "audit" ? requestedScope : scope;
|
|
126
|
+
const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
|
|
127
|
+
await ensureDbOpen(projectRoot());
|
|
126
128
|
const report = await runGSDDoctor(projectRoot(), {
|
|
127
129
|
fix: mode === "fix" || mode === "heal" || dryRun || fixFlag,
|
|
128
130
|
dryRun,
|
|
@@ -32,6 +32,11 @@ export interface McpServerDetail extends McpServerStatus {
|
|
|
32
32
|
tools: string[];
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
export function hasHostMcpTool(systemPrompt: string, serverName: string): boolean {
|
|
36
|
+
const marker = `mcp__${serverName}__`;
|
|
37
|
+
return systemPrompt.includes(marker);
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
export function formatMcpInitResult(
|
|
36
41
|
status: "created" | "updated" | "unchanged",
|
|
37
42
|
configPath: string,
|
|
@@ -184,6 +189,7 @@ export async function handleMcpStatus(
|
|
|
184
189
|
const trimmed = args.trim();
|
|
185
190
|
const lowered = trimmed.toLowerCase();
|
|
186
191
|
const configs = readMcpConfigs();
|
|
192
|
+
const systemPrompt = ctx.getSystemPrompt();
|
|
187
193
|
|
|
188
194
|
// /gsd mcp init [dir]
|
|
189
195
|
if (!lowered || lowered === "status") {
|
|
@@ -233,6 +239,7 @@ export async function handleMcpStatus(
|
|
|
233
239
|
} catch {
|
|
234
240
|
// mcp-client may not expose status helpers — that's fine
|
|
235
241
|
}
|
|
242
|
+
if (!connected && !error && hasHostMcpTool(systemPrompt, serverName)) connected = true;
|
|
236
243
|
|
|
237
244
|
ctx.ui.notify(
|
|
238
245
|
formatMcpServerDetail({
|
|
@@ -270,6 +277,7 @@ export async function handleMcpStatus(
|
|
|
270
277
|
} catch {
|
|
271
278
|
// Fall back to unknown state
|
|
272
279
|
}
|
|
280
|
+
if (!connected && !error && hasHostMcpTool(systemPrompt, config.name)) connected = true;
|
|
273
281
|
|
|
274
282
|
statuses.push({
|
|
275
283
|
name: config.name,
|
|
@@ -587,10 +587,18 @@ async function configureModels(ctx: ExtensionCommandContext, prefs: Record<strin
|
|
|
587
587
|
const models: Record<string, unknown> = (prefs.models as Record<string, unknown>) ?? {};
|
|
588
588
|
|
|
589
589
|
const availableModels = ctx.modelRegistry.getAvailable();
|
|
590
|
-
|
|
590
|
+
// Call getAllWithDiscovered as a method so `this` stays bound to the
|
|
591
|
+
// registry — invoking a detached reference loses `this` and the method's
|
|
592
|
+
// internal `this.models` access throws.
|
|
593
|
+
const registry = ctx.modelRegistry as { getAllWithDiscovered?: () => typeof availableModels };
|
|
594
|
+
const availableProviders = new Set(availableModels.map((m) => m.provider));
|
|
595
|
+
const selectableModels = typeof registry.getAllWithDiscovered === "function"
|
|
596
|
+
? registry.getAllWithDiscovered().filter((m) => availableProviders.has(m.provider))
|
|
597
|
+
: availableModels;
|
|
598
|
+
if (selectableModels.length > 0) {
|
|
591
599
|
// Group models by provider, sorted alphabetically
|
|
592
|
-
const byProvider = new Map<string, typeof
|
|
593
|
-
for (const m of
|
|
600
|
+
const byProvider = new Map<string, typeof selectableModels>();
|
|
601
|
+
for (const m of selectableModels) {
|
|
594
602
|
let group = byProvider.get(m.provider);
|
|
595
603
|
if (!group) {
|
|
596
604
|
group = [];
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
import { loadFile } from "./files.js";
|
|
4
|
+
import { resolveMilestoneFile } from "./paths.js";
|
|
5
|
+
import { deriveState } from "./state.js";
|
|
6
|
+
import { executeValidateMilestone } from "./tools/workflow-tool-executors.js";
|
|
7
|
+
import {
|
|
8
|
+
VALIDATION_VERDICTS,
|
|
9
|
+
extractVerdict,
|
|
10
|
+
isValidMilestoneVerdict,
|
|
11
|
+
type ValidationVerdict,
|
|
12
|
+
} from "./verdict-parser.js";
|
|
13
|
+
|
|
14
|
+
const USAGE =
|
|
15
|
+
'Usage: /gsd verdict <pass|needs-attention|needs-remediation> [--milestone Mxxx] [--rationale "..."]';
|
|
16
|
+
|
|
17
|
+
interface ParsedArgs {
|
|
18
|
+
verdict?: ValidationVerdict;
|
|
19
|
+
milestoneId?: string;
|
|
20
|
+
rationale?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ParsedValidation {
|
|
24
|
+
verdict: string | undefined;
|
|
25
|
+
remediationRound: number;
|
|
26
|
+
successCriteriaChecklist: string;
|
|
27
|
+
sliceDeliveryAudit: string;
|
|
28
|
+
crossSliceIntegration: string;
|
|
29
|
+
requirementCoverage: string;
|
|
30
|
+
verificationClasses?: string;
|
|
31
|
+
verdictRationale: string;
|
|
32
|
+
remediationPlan?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function tokenize(raw: string): string[] {
|
|
36
|
+
const tokens: string[] = [];
|
|
37
|
+
const re = /"([^"]*)"|(\S+)/g;
|
|
38
|
+
let match: RegExpExecArray | null;
|
|
39
|
+
while ((match = re.exec(raw)) !== null) {
|
|
40
|
+
tokens.push(match[1] ?? match[2]);
|
|
41
|
+
}
|
|
42
|
+
return tokens;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function parseArgs(raw: string): ParsedArgs | { error: string } {
|
|
46
|
+
const tokens = tokenize(raw);
|
|
47
|
+
const out: ParsedArgs = {};
|
|
48
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
49
|
+
const t = tokens[i];
|
|
50
|
+
if (t === "--milestone") {
|
|
51
|
+
const next = tokens[++i];
|
|
52
|
+
if (!next) return { error: "--milestone requires a milestone ID" };
|
|
53
|
+
out.milestoneId = next;
|
|
54
|
+
} else if (t === "--rationale") {
|
|
55
|
+
const next = tokens[++i];
|
|
56
|
+
if (next == null) return { error: "--rationale requires a value" };
|
|
57
|
+
out.rationale = next;
|
|
58
|
+
} else if (!out.verdict) {
|
|
59
|
+
if (!isValidMilestoneVerdict(t)) {
|
|
60
|
+
return {
|
|
61
|
+
error: `Invalid verdict "${t}". Must be one of: ${VALIDATION_VERDICTS.join(", ")}`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
out.verdict = t;
|
|
65
|
+
} else {
|
|
66
|
+
return { error: `Unexpected argument: ${t}` };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function extractRemediationRound(content: string): number {
|
|
73
|
+
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
74
|
+
if (!fm) return 0;
|
|
75
|
+
const m = fm[1].match(/^remediation_round:\s*(\d+)/im);
|
|
76
|
+
return m ? Number.parseInt(m[1], 10) : 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function extractSection(content: string, heading: string): string | undefined {
|
|
80
|
+
const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
81
|
+
// Match section bodies bounded by the next "## " heading or end-of-string.
|
|
82
|
+
// Leading "\n" prefix lets a single pattern handle first-line headings too.
|
|
83
|
+
// No /m flag — we want `$` to mean end-of-string, not end-of-line.
|
|
84
|
+
const re = new RegExp(`\\n## ${escaped}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`);
|
|
85
|
+
const m = ("\n" + content).match(re);
|
|
86
|
+
if (!m) return undefined;
|
|
87
|
+
return m[1].replace(/\s+$/, "");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function parseValidationFile(content: string): ParsedValidation {
|
|
91
|
+
return {
|
|
92
|
+
verdict: extractVerdict(content),
|
|
93
|
+
remediationRound: extractRemediationRound(content),
|
|
94
|
+
successCriteriaChecklist: extractSection(content, "Success Criteria Checklist") ?? "",
|
|
95
|
+
sliceDeliveryAudit: extractSection(content, "Slice Delivery Audit") ?? "",
|
|
96
|
+
crossSliceIntegration: extractSection(content, "Cross-Slice Integration") ?? "",
|
|
97
|
+
requirementCoverage: extractSection(content, "Requirement Coverage") ?? "",
|
|
98
|
+
verificationClasses: extractSection(content, "Verification Class Compliance"),
|
|
99
|
+
verdictRationale: extractSection(content, "Verdict Rationale") ?? "",
|
|
100
|
+
remediationPlan: extractSection(content, "Remediation Plan"),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function handleVerdict(
|
|
105
|
+
rawArgs: string,
|
|
106
|
+
ctx: ExtensionCommandContext,
|
|
107
|
+
basePath: string,
|
|
108
|
+
): Promise<void> {
|
|
109
|
+
if (!rawArgs.trim()) {
|
|
110
|
+
ctx.ui.notify(USAGE, "warning");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const parsed = parseArgs(rawArgs);
|
|
115
|
+
if ("error" in parsed) {
|
|
116
|
+
ctx.ui.notify(`${parsed.error}\n${USAGE}`, "warning");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (!parsed.verdict) {
|
|
120
|
+
ctx.ui.notify(USAGE, "warning");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let milestoneId = parsed.milestoneId;
|
|
125
|
+
if (!milestoneId) {
|
|
126
|
+
const state = await deriveState(basePath);
|
|
127
|
+
if (!state.activeMilestone) {
|
|
128
|
+
ctx.ui.notify(
|
|
129
|
+
"No active milestone — pass --milestone Mxxx to target a specific milestone.",
|
|
130
|
+
"warning",
|
|
131
|
+
);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
milestoneId = state.activeMilestone.id;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const validationPath = resolveMilestoneFile(basePath, milestoneId, "VALIDATION");
|
|
138
|
+
if (!validationPath) {
|
|
139
|
+
ctx.ui.notify(
|
|
140
|
+
`No VALIDATION file found for ${milestoneId}. Run gsd_validate_milestone first to produce one.`,
|
|
141
|
+
"warning",
|
|
142
|
+
);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const existing = await loadFile(validationPath);
|
|
146
|
+
if (!existing) {
|
|
147
|
+
ctx.ui.notify(
|
|
148
|
+
`Could not read VALIDATION file for ${milestoneId} (${validationPath}).`,
|
|
149
|
+
"warning",
|
|
150
|
+
);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const current = parseValidationFile(existing);
|
|
155
|
+
|
|
156
|
+
if (parsed.verdict !== "pass" && !parsed.rationale) {
|
|
157
|
+
ctx.ui.notify(
|
|
158
|
+
`--rationale is required when overriding to ${parsed.verdict}.`,
|
|
159
|
+
"warning",
|
|
160
|
+
);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const verdictRationale =
|
|
165
|
+
parsed.rationale ?? "Manually overridden via /gsd verdict";
|
|
166
|
+
|
|
167
|
+
const result = await executeValidateMilestone(
|
|
168
|
+
{
|
|
169
|
+
milestoneId,
|
|
170
|
+
verdict: parsed.verdict,
|
|
171
|
+
remediationRound: current.remediationRound,
|
|
172
|
+
successCriteriaChecklist: current.successCriteriaChecklist,
|
|
173
|
+
sliceDeliveryAudit: current.sliceDeliveryAudit,
|
|
174
|
+
crossSliceIntegration: current.crossSliceIntegration,
|
|
175
|
+
requirementCoverage: current.requirementCoverage,
|
|
176
|
+
verificationClasses: current.verificationClasses,
|
|
177
|
+
verdictRationale,
|
|
178
|
+
remediationPlan: current.remediationPlan,
|
|
179
|
+
},
|
|
180
|
+
basePath,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
if (result.isError) {
|
|
184
|
+
const msg =
|
|
185
|
+
result.content[0]?.type === "text" ? result.content[0].text : "Unknown error";
|
|
186
|
+
ctx.ui.notify(msg, "error");
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const prevVerdict = current.verdict ?? "unknown";
|
|
191
|
+
ctx.ui.notify(
|
|
192
|
+
`Milestone ${milestoneId} verdict: ${prevVerdict} -> ${parsed.verdict}`,
|
|
193
|
+
"success",
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (parsed.verdict === "needs-remediation") {
|
|
197
|
+
ctx.ui.notify(
|
|
198
|
+
"Follow up with gsd_reassess_roadmap to add remediation slices, then re-run /gsd auto.",
|
|
199
|
+
"info",
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -30,9 +30,13 @@ import { join } from "node:path";
|
|
|
30
30
|
import {
|
|
31
31
|
findStaleWorkerForProject,
|
|
32
32
|
getAllAutoWorkers,
|
|
33
|
+
markWorkerCrashed,
|
|
34
|
+
markWorkerStopping,
|
|
35
|
+
markWorkerStoppingByPid,
|
|
33
36
|
type AutoWorkerRow,
|
|
34
37
|
} from "./db/auto-workers.js";
|
|
35
|
-
import {
|
|
38
|
+
import { forceReleaseLeasesForWorker } from "./db/milestone-leases.js";
|
|
39
|
+
import { markLatestActiveForWorkerCanceled, type DispatchStatus } from "./db/unit-dispatches.js";
|
|
36
40
|
import { getRuntimeKv, setRuntimeKv, deleteRuntimeKv } from "./db/runtime-kv.js";
|
|
37
41
|
import { _getAdapter, isDbAvailable } from "./gsd-db.js";
|
|
38
42
|
import { gsdRoot, normalizeRealPath } from "./paths.js";
|
|
@@ -56,6 +60,15 @@ function lockPath(basePath: string): string {
|
|
|
56
60
|
return join(gsdRoot(basePath), effectiveLockFile());
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
function clearLegacyLockFile(basePath: string): void {
|
|
64
|
+
try {
|
|
65
|
+
const p = lockPath(basePath);
|
|
66
|
+
if (existsSync(p)) unlinkSync(p);
|
|
67
|
+
} catch {
|
|
68
|
+
// Best-effort.
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
function readLegacyLock(basePath: string): LockData | null {
|
|
60
73
|
try {
|
|
61
74
|
const p = lockPath(basePath);
|
|
@@ -185,12 +198,18 @@ export function writeLock(
|
|
|
185
198
|
// Best-effort — never throw from the lock writer.
|
|
186
199
|
}
|
|
187
200
|
|
|
188
|
-
if (!isDbAvailable()
|
|
201
|
+
if (!isDbAvailable()) return;
|
|
189
202
|
try {
|
|
190
203
|
const projectRoot = normalizeRealPath(basePath);
|
|
191
204
|
const worker = findActiveWorkerForCurrentProcess(projectRoot);
|
|
192
205
|
if (!worker) return;
|
|
193
|
-
|
|
206
|
+
if (sessionFile) {
|
|
207
|
+
setRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY, sessionFile);
|
|
208
|
+
} else {
|
|
209
|
+
// Preliminary unit locks (before runUnit/newSession settles) must clear
|
|
210
|
+
// any prior pointer so crash recovery cannot ingest stale cross-unit context.
|
|
211
|
+
deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
|
|
212
|
+
}
|
|
194
213
|
} catch {
|
|
195
214
|
// Best-effort — never throw from the lock writer.
|
|
196
215
|
}
|
|
@@ -204,18 +223,48 @@ export function writeLock(
|
|
|
204
223
|
* stale session-file pointer.
|
|
205
224
|
*/
|
|
206
225
|
export function clearLock(basePath: string): void {
|
|
226
|
+
clearLegacyLockFile(basePath);
|
|
227
|
+
|
|
228
|
+
if (!isDbAvailable()) return;
|
|
207
229
|
try {
|
|
208
|
-
const
|
|
209
|
-
|
|
230
|
+
const projectRoot = normalizeRealPath(basePath);
|
|
231
|
+
const staleWorker = findStaleWorkerForProject(projectRoot);
|
|
232
|
+
if (staleWorker) {
|
|
233
|
+
markWorkerCrashed(staleWorker.worker_id);
|
|
234
|
+
forceReleaseLeasesForWorker(staleWorker.worker_id);
|
|
235
|
+
deleteRuntimeKv("worker", staleWorker.worker_id, SESSION_FILE_KV_KEY);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const lock = readLegacyLock(basePath);
|
|
239
|
+
if (lock?.pid) markWorkerStoppingByPid(projectRoot, lock.pid);
|
|
240
|
+
const worker = findActiveWorkerForCurrentProcess(projectRoot);
|
|
241
|
+
if (worker) deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
|
|
242
|
+
|
|
243
|
+
const stale = findStaleWorkerForProject(projectRoot);
|
|
244
|
+
if (stale) {
|
|
245
|
+
markWorkerStopping(stale.worker_id);
|
|
246
|
+
deleteRuntimeKv("worker", stale.worker_id, SESSION_FILE_KV_KEY);
|
|
247
|
+
}
|
|
210
248
|
} catch {
|
|
211
249
|
// Best-effort.
|
|
212
250
|
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Clear a stale DB-backed worker lock after readCrashLock/findStaleWorkerForProject
|
|
255
|
+
* has identified a dead worker. Unlike clearLock(), this targets the stale
|
|
256
|
+
* worker row instead of the current process's active worker.
|
|
257
|
+
*/
|
|
258
|
+
export function clearStaleWorkerLock(basePath: string): void {
|
|
259
|
+
clearLegacyLockFile(basePath);
|
|
213
260
|
|
|
214
261
|
if (!isDbAvailable()) return;
|
|
215
262
|
try {
|
|
216
263
|
const projectRoot = normalizeRealPath(basePath);
|
|
217
|
-
const worker =
|
|
264
|
+
const worker = findStaleWorkerForProject(projectRoot);
|
|
218
265
|
if (!worker) return;
|
|
266
|
+
markLatestActiveForWorkerCanceled(worker.worker_id, "crash-recovered");
|
|
267
|
+
markWorkerCrashed(worker.worker_id);
|
|
219
268
|
deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
|
|
220
269
|
} catch {
|
|
221
270
|
// Best-effort.
|
|
@@ -157,6 +157,31 @@ export function markWorkerStopping(workerId: string): void {
|
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Mark the active worker row for a specific PID/project root as stopping.
|
|
162
|
+
* Used when we detect a dead PID from lock metadata before heartbeat expiry.
|
|
163
|
+
*/
|
|
164
|
+
export function markWorkerStoppingByPid(
|
|
165
|
+
projectRootRealpath: string,
|
|
166
|
+
pid: number,
|
|
167
|
+
): void {
|
|
168
|
+
if (!isDbAvailable()) return;
|
|
169
|
+
if (!Number.isInteger(pid) || pid <= 0) return;
|
|
170
|
+
const db = _getAdapter()!;
|
|
171
|
+
transaction(() => {
|
|
172
|
+
db.prepare(
|
|
173
|
+
`UPDATE workers
|
|
174
|
+
SET status = 'stopping'
|
|
175
|
+
WHERE pid = :pid
|
|
176
|
+
AND project_root_realpath = :project_root
|
|
177
|
+
AND status = 'active'`,
|
|
178
|
+
).run({
|
|
179
|
+
":pid": pid,
|
|
180
|
+
":project_root": projectRootRealpath,
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
160
185
|
/**
|
|
161
186
|
* Return all workers whose status is 'active' AND whose heartbeat is within
|
|
162
187
|
* the TTL window. Workers older than the TTL are NOT auto-marked crashed
|
|
@@ -242,6 +267,18 @@ export function findStaleWorkerForProject(
|
|
|
242
267
|
const db = _getAdapter()!;
|
|
243
268
|
const cutoffMs = Date.now() - HEARTBEAT_TTL_SECONDS * 1000;
|
|
244
269
|
const cutoffIso = new Date(cutoffMs).toISOString();
|
|
270
|
+
|
|
271
|
+
const latestActiveRow = db.prepare(
|
|
272
|
+
`SELECT worker_id, host, pid, started_at, version,
|
|
273
|
+
last_heartbeat_at, status, project_root_realpath
|
|
274
|
+
FROM workers
|
|
275
|
+
WHERE project_root_realpath = :project_root
|
|
276
|
+
AND status = 'active'
|
|
277
|
+
ORDER BY started_at DESC
|
|
278
|
+
LIMIT 1`,
|
|
279
|
+
).get({ ":project_root": projectRootRealpath }) as AutoWorkerRow | undefined;
|
|
280
|
+
if (latestActiveRow && !isWorkerProcessAlive(latestActiveRow)) return latestActiveRow;
|
|
281
|
+
|
|
245
282
|
const row = db.prepare(
|
|
246
283
|
`SELECT worker_id, host, pid, started_at, version,
|
|
247
284
|
last_heartbeat_at, status, project_root_realpath
|
|
@@ -255,6 +255,32 @@ export function releaseMilestoneLease(
|
|
|
255
255
|
});
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Force-release all held leases for a worker.
|
|
260
|
+
*
|
|
261
|
+
* Used by crash recovery once PID liveness has confirmed the worker is dead.
|
|
262
|
+
* No fencing token is required because this path is cleanup-only for a
|
|
263
|
+
* non-running process.
|
|
264
|
+
*/
|
|
265
|
+
export function forceReleaseLeasesForWorker(workerId: string): number {
|
|
266
|
+
if (!isDbAvailable()) return 0;
|
|
267
|
+
const db = _getAdapter()!;
|
|
268
|
+
let changes = 0;
|
|
269
|
+
transaction(() => {
|
|
270
|
+
const result = db.prepare(
|
|
271
|
+
`UPDATE milestone_leases
|
|
272
|
+
SET status = 'released'
|
|
273
|
+
WHERE worker_id = :worker_id
|
|
274
|
+
AND status = 'held'`,
|
|
275
|
+
).run({ ":worker_id": workerId });
|
|
276
|
+
changes =
|
|
277
|
+
typeof (result as { changes?: unknown }).changes === "number"
|
|
278
|
+
? (result as { changes: number }).changes
|
|
279
|
+
: 0;
|
|
280
|
+
});
|
|
281
|
+
return changes;
|
|
282
|
+
}
|
|
283
|
+
|
|
258
284
|
/**
|
|
259
285
|
* Read current lease row for diagnostics. Returns null if no row exists.
|
|
260
286
|
*/
|
|
@@ -524,17 +524,18 @@ export function getRecentUnitKeysForProjectRoot(
|
|
|
524
524
|
if (!isDbAvailable()) return [];
|
|
525
525
|
const db = _getAdapter()!;
|
|
526
526
|
const rows = db.prepare(
|
|
527
|
-
`SELECT ud.unit_id
|
|
527
|
+
`SELECT ud.unit_type, ud.unit_id
|
|
528
528
|
FROM unit_dispatches ud
|
|
529
529
|
INNER JOIN workers w ON w.worker_id = ud.worker_id
|
|
530
530
|
WHERE w.project_root_realpath = :project_root_realpath
|
|
531
|
+
AND w.status != 'crashed'
|
|
531
532
|
ORDER BY ud.started_at DESC, ud.id DESC
|
|
532
533
|
LIMIT :limit`,
|
|
533
534
|
).all({
|
|
534
535
|
":project_root_realpath": projectRootRealpath,
|
|
535
536
|
":limit": limit,
|
|
536
|
-
}) as Array<{ unit_id: string }>;
|
|
537
|
-
return rows.reverse().map((r) => ({ key: r.unit_id }));
|
|
537
|
+
}) as Array<{ unit_type: string; unit_id: string }>;
|
|
538
|
+
return rows.reverse().map((r) => ({ key: `${r.unit_type}/${r.unit_id}` }));
|
|
538
539
|
}
|
|
539
540
|
|
|
540
541
|
/**
|
|
@@ -168,6 +168,7 @@ export function createBaseSchemaObjects(db: DbAdapter, hooks: BaseSchemaHooks):
|
|
|
168
168
|
proof_level TEXT NOT NULL DEFAULT '',
|
|
169
169
|
integration_closure TEXT NOT NULL DEFAULT '',
|
|
170
170
|
observability_impact TEXT NOT NULL DEFAULT '',
|
|
171
|
+
target_repositories TEXT NOT NULL DEFAULT '[]',
|
|
171
172
|
sequence INTEGER DEFAULT 0,
|
|
172
173
|
replan_triggered_at TEXT DEFAULT NULL,
|
|
173
174
|
is_sketch INTEGER NOT NULL DEFAULT 0,
|
|
@@ -208,6 +209,7 @@ export function createBaseSchemaObjects(db: DbAdapter, hooks: BaseSchemaHooks):
|
|
|
208
209
|
expected_output TEXT NOT NULL DEFAULT '[]',
|
|
209
210
|
observability_impact TEXT NOT NULL DEFAULT '',
|
|
210
211
|
full_plan_md TEXT NOT NULL DEFAULT '',
|
|
212
|
+
target_repositories TEXT NOT NULL DEFAULT '[]',
|
|
211
213
|
sequence INTEGER DEFAULT 0,
|
|
212
214
|
PRIMARY KEY (milestone_id, slice_id, id),
|
|
213
215
|
FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
|
|
@@ -424,6 +424,11 @@ export function applyMigrationV28MemoryLastHitAt(db: DbAdapter): void {
|
|
|
424
424
|
ensureColumn(db, "memories", "last_hit_at", "ALTER TABLE memories ADD COLUMN last_hit_at TEXT DEFAULT NULL");
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
export function applyMigrationV29RepositoryTargets(db: DbAdapter): void {
|
|
428
|
+
ensureColumn(db, "slices", "target_repositories", "ALTER TABLE slices ADD COLUMN target_repositories TEXT NOT NULL DEFAULT '[]'");
|
|
429
|
+
ensureColumn(db, "tasks", "target_repositories", "ALTER TABLE tasks ADD COLUMN target_repositories TEXT NOT NULL DEFAULT '[]'");
|
|
430
|
+
}
|
|
431
|
+
|
|
427
432
|
export interface MigrationV22Hooks {
|
|
428
433
|
copyQualityGateRowsToRepairedTable(db: DbAdapter): void;
|
|
429
434
|
}
|
|
@@ -22,6 +22,7 @@ export interface SliceRow {
|
|
|
22
22
|
replan_triggered_at: string | null;
|
|
23
23
|
is_sketch: number;
|
|
24
24
|
sketch_scope: string;
|
|
25
|
+
target_repositories?: string[];
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export interface TaskRow {
|
|
@@ -55,6 +56,7 @@ export interface TaskRow {
|
|
|
55
56
|
escalation_awaiting_review: number;
|
|
56
57
|
escalation_artifact_path: string | null;
|
|
57
58
|
escalation_override_applied_at: string | null;
|
|
59
|
+
target_repositories?: string[];
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
type DbRow = Record<string, unknown>;
|
|
@@ -107,6 +109,7 @@ export function rowToSlice(row: DbRow): SliceRow {
|
|
|
107
109
|
replan_triggered_at: (row["replan_triggered_at"] as string) ?? null,
|
|
108
110
|
is_sketch: (row["is_sketch"] as number) ?? 0,
|
|
109
111
|
sketch_scope: (row["sketch_scope"] as string) ?? "",
|
|
112
|
+
target_repositories: parseTaskArrayColumn(row["target_repositories"]),
|
|
110
113
|
};
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -142,5 +145,6 @@ export function rowToTask(row: DbRow): TaskRow {
|
|
|
142
145
|
escalation_awaiting_review: (row["escalation_awaiting_review"] as number) ?? 0,
|
|
143
146
|
escalation_artifact_path: (row["escalation_artifact_path"] as string) ?? null,
|
|
144
147
|
escalation_override_applied_at: (row["escalation_override_applied_at"] as string) ?? null,
|
|
148
|
+
target_repositories: parseTaskArrayColumn(row["target_repositories"]),
|
|
145
149
|
};
|
|
146
150
|
}
|