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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// First non-empty source wins.
|
|
5
5
|
|
|
6
6
|
import { spawnSync, type SpawnSyncReturns } from "node:child_process";
|
|
7
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
+
import { existsSync, readFileSync, readdirSync, type Dirent } from "node:fs";
|
|
8
8
|
import { join, basename } from "node:path";
|
|
9
9
|
import type { AuditWarning, RuntimeError, VerificationCheck, VerificationResult } from "./types.js";
|
|
10
10
|
import { DEFAULT_COMMAND_TIMEOUT_MS } from "./constants.js";
|
|
@@ -44,7 +44,9 @@ const PACKAGE_SCRIPT_KEYS = ["typecheck", "lint", "test"] as const;
|
|
|
44
44
|
* 1. Explicit preference commands
|
|
45
45
|
* 2. Task plan verify field (split on &&)
|
|
46
46
|
* 3. package.json scripts (typecheck, lint, test)
|
|
47
|
-
* 4.
|
|
47
|
+
* 4. Python pytest project markers
|
|
48
|
+
* 5. Dependency-free Node test files
|
|
49
|
+
* 6. None found
|
|
48
50
|
*/
|
|
49
51
|
export function discoverCommands(options: DiscoverCommandsOptions): DiscoveredCommands {
|
|
50
52
|
// 1. Preference commands
|
|
@@ -91,10 +93,89 @@ export function discoverCommands(options: DiscoverCommandsOptions): DiscoveredCo
|
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
const pythonCommand = discoverPythonPytestCommand(options.cwd);
|
|
97
|
+
if (pythonCommand) {
|
|
98
|
+
return { commands: [pythonCommand], source: "python-project" };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const nodeTestCommand = discoverNodeTestFileCommand(options.cwd);
|
|
102
|
+
if (nodeTestCommand) {
|
|
103
|
+
return { commands: [nodeTestCommand], source: "node-test-file" };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 6. Nothing found
|
|
95
107
|
return { commands: [], source: "none" };
|
|
96
108
|
}
|
|
97
109
|
|
|
110
|
+
function discoverNodeTestFileCommand(cwd: string): string | null {
|
|
111
|
+
let entries: Dirent[];
|
|
112
|
+
try {
|
|
113
|
+
entries = readdirSync(cwd, { withFileTypes: true });
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const testFile = entries
|
|
119
|
+
.filter((entry) => entry.isFile())
|
|
120
|
+
.map((entry) => entry.name)
|
|
121
|
+
.filter((name) => /^test-[A-Za-z0-9._-]+\.js$|^[A-Za-z0-9._-]+\.test\.js$/.test(name))
|
|
122
|
+
.sort()[0];
|
|
123
|
+
|
|
124
|
+
return testFile ? `node ${testFile}` : null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function discoverPythonPytestCommand(cwd: string): string | null {
|
|
128
|
+
const hasPythonTestFiles = hasPythonTests(join(cwd, "tests"));
|
|
129
|
+
const hasPytestConfig = existsSync(join(cwd, "pytest.ini"));
|
|
130
|
+
const pyprojectPath = join(cwd, "pyproject.toml");
|
|
131
|
+
const hasPyproject = existsSync(pyprojectPath);
|
|
132
|
+
|
|
133
|
+
if (!hasPythonTestFiles && !hasPytestConfig && !hasPyproject) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (hasPytestConfig || hasPythonTestFiles) {
|
|
138
|
+
return "python3 -m pytest";
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const pyproject = readFileSync(pyprojectPath, "utf-8");
|
|
143
|
+
if (
|
|
144
|
+
pyproject.includes("[tool.pytest]") ||
|
|
145
|
+
pyproject.includes("[tool.pytest.") ||
|
|
146
|
+
pyproject.includes("[pytest]") ||
|
|
147
|
+
pyproject.includes("[tool:pytest]")
|
|
148
|
+
) {
|
|
149
|
+
return "python3 -m pytest";
|
|
150
|
+
}
|
|
151
|
+
} catch {
|
|
152
|
+
// Ignore unreadable pyproject.toml and fall through.
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function hasPythonTests(dir: string): boolean {
|
|
159
|
+
let entries: Dirent[];
|
|
160
|
+
try {
|
|
161
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
162
|
+
} catch {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
for (const entry of entries) {
|
|
167
|
+
const path = join(dir, entry.name);
|
|
168
|
+
if (entry.isDirectory() && hasPythonTests(path)) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
if (entry.isFile() && /^test_.*\.py$|^.*_test\.py$/.test(entry.name)) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
98
179
|
// ─── Failure Context Formatting ──────────────────────────────────────────────
|
|
99
180
|
|
|
100
181
|
/** Maximum chars of stderr to include per failed check in failure context. */
|
|
@@ -144,7 +225,7 @@ export function formatFailureContext(result: VerificationResult): string {
|
|
|
144
225
|
// ─── Gate Execution ─────────────────────────────────────────────────────────
|
|
145
226
|
|
|
146
227
|
/** Characters that indicate shell injection when found in a command string. */
|
|
147
|
-
const SHELL_INJECTION_PATTERN = /[
|
|
228
|
+
const SHELL_INJECTION_PATTERN = /[;|`<>]|\$\(/;
|
|
148
229
|
|
|
149
230
|
/**
|
|
150
231
|
* Known executable first-tokens that are safe to run.
|
|
@@ -182,6 +263,7 @@ const KNOWN_COMMAND_PREFIXES = new Set([
|
|
|
182
263
|
* Heuristics (any true → prose-like):
|
|
183
264
|
* 1. First token starts with an uppercase letter and the string has 4+ words
|
|
184
265
|
* 2. String contains commas followed by spaces (prose clause structure)
|
|
266
|
+
* 3. First token has no ASCII letters or digits and the string has 4+ words
|
|
185
267
|
*/
|
|
186
268
|
export function isLikelyCommand(cmd: string): boolean {
|
|
187
269
|
const trimmed = cmd.trim();
|
|
@@ -208,6 +290,9 @@ export function isLikelyCommand(cmd: string): boolean {
|
|
|
208
290
|
// First token has uppercase letters and no path separators → prose
|
|
209
291
|
if (/[A-Z]/.test(firstToken) && !firstToken.includes("/")) return false;
|
|
210
292
|
|
|
293
|
+
// Non-ASCII prose with multiple words should not be executed as a command.
|
|
294
|
+
if (!/[A-Za-z0-9]/.test(firstToken) && tokens.length >= 4) return false;
|
|
295
|
+
|
|
211
296
|
return true;
|
|
212
297
|
}
|
|
213
298
|
|
|
@@ -215,9 +300,19 @@ export function isLikelyCommand(cmd: string): boolean {
|
|
|
215
300
|
* Validate a command string for obvious shell injection patterns.
|
|
216
301
|
* Returns the command unchanged if safe, or null if suspicious.
|
|
217
302
|
*/
|
|
303
|
+
export function validateVerificationCommand(cmd: string): { ok: true } | { ok: false; reason: string } {
|
|
304
|
+
if (SHELL_INJECTION_PATTERN.test(cmd)) {
|
|
305
|
+
return { ok: false, reason: "contains shell control syntax such as pipes, redirects, semicolons, backticks, or command substitution" };
|
|
306
|
+
}
|
|
307
|
+
if (!isLikelyCommand(cmd)) {
|
|
308
|
+
return { ok: false, reason: "does not look like a runnable command" };
|
|
309
|
+
}
|
|
310
|
+
return { ok: true };
|
|
311
|
+
}
|
|
312
|
+
|
|
218
313
|
function sanitizeCommand(cmd: string): string | null {
|
|
219
|
-
|
|
220
|
-
if (!
|
|
314
|
+
const validation = validateVerificationCommand(cmd);
|
|
315
|
+
if (!validation.ok) return null;
|
|
221
316
|
return cmd;
|
|
222
317
|
}
|
|
223
318
|
|
|
@@ -229,6 +324,30 @@ export interface RunVerificationGateOptions {
|
|
|
229
324
|
commandTimeoutMs?: number;
|
|
230
325
|
}
|
|
231
326
|
|
|
327
|
+
export interface VerificationTarget {
|
|
328
|
+
id: string;
|
|
329
|
+
cwd: string;
|
|
330
|
+
preferenceCommands?: string[];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function mergeDiscoverySource(
|
|
334
|
+
sources: VerificationResult["discoverySource"][],
|
|
335
|
+
): VerificationResult["discoverySource"] {
|
|
336
|
+
if (sources.length === 0) return "none";
|
|
337
|
+
const first = sources[0];
|
|
338
|
+
if (sources.every((source) => source === first)) return first;
|
|
339
|
+
const precedence: VerificationResult["discoverySource"][] = [
|
|
340
|
+
"preference",
|
|
341
|
+
"task-plan",
|
|
342
|
+
"package-json",
|
|
343
|
+
"python-project",
|
|
344
|
+
];
|
|
345
|
+
for (const source of precedence) {
|
|
346
|
+
if (sources.includes(source)) return source;
|
|
347
|
+
}
|
|
348
|
+
return "none";
|
|
349
|
+
}
|
|
350
|
+
|
|
232
351
|
/**
|
|
233
352
|
* Run the verification gate: discover commands, execute each via spawnSync,
|
|
234
353
|
* and return a structured result.
|
|
@@ -305,6 +424,51 @@ export function runVerificationGate(options: RunVerificationGateOptions): Verifi
|
|
|
305
424
|
};
|
|
306
425
|
}
|
|
307
426
|
|
|
427
|
+
export function runVerificationGateForTargets(options: {
|
|
428
|
+
targets: VerificationTarget[];
|
|
429
|
+
preferenceCommands?: string[];
|
|
430
|
+
taskPlanVerify?: string;
|
|
431
|
+
commandTimeoutMs?: number;
|
|
432
|
+
}): VerificationResult {
|
|
433
|
+
const timestamp = Date.now();
|
|
434
|
+
if (options.targets.length === 0) {
|
|
435
|
+
return {
|
|
436
|
+
passed: true,
|
|
437
|
+
checks: [],
|
|
438
|
+
discoverySource: "none",
|
|
439
|
+
timestamp,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const checks: VerificationCheck[] = [];
|
|
444
|
+
const sources: VerificationResult["discoverySource"][] = [];
|
|
445
|
+
let passed = true;
|
|
446
|
+
|
|
447
|
+
for (const target of options.targets) {
|
|
448
|
+
const result = runVerificationGate({
|
|
449
|
+
cwd: target.cwd,
|
|
450
|
+
preferenceCommands: options.preferenceCommands ?? target.preferenceCommands,
|
|
451
|
+
taskPlanVerify: options.taskPlanVerify,
|
|
452
|
+
commandTimeoutMs: options.commandTimeoutMs,
|
|
453
|
+
});
|
|
454
|
+
passed = passed && result.passed;
|
|
455
|
+
sources.push(result.discoverySource);
|
|
456
|
+
for (const check of result.checks) {
|
|
457
|
+
checks.push({
|
|
458
|
+
...check,
|
|
459
|
+
command: target.id === "project" ? check.command : `[${target.id}] ${check.command}`,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return {
|
|
465
|
+
passed,
|
|
466
|
+
checks,
|
|
467
|
+
discoverySource: mergeDiscoverySource(sources),
|
|
468
|
+
timestamp,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
308
472
|
// ─── Runtime Error Capture ──────────────────────────────────────────────────
|
|
309
473
|
|
|
310
474
|
/** Maximum characters of browser console text to retain per entry. */
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Host-owned verification verdict policy for auto-mode units.
|
|
3
|
+
|
|
4
|
+
import type { VerificationResult as VerificationGateResult } from "./types.js";
|
|
5
|
+
|
|
6
|
+
export type VerificationVerdictReason =
|
|
7
|
+
| "passed"
|
|
8
|
+
| "no-host-checks"
|
|
9
|
+
| "checks-failed";
|
|
10
|
+
|
|
11
|
+
export interface VerificationVerdict {
|
|
12
|
+
passed: boolean;
|
|
13
|
+
reason: VerificationVerdictReason;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
failureContext: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function decideVerificationVerdict(
|
|
19
|
+
unitType: string,
|
|
20
|
+
result: VerificationGateResult,
|
|
21
|
+
): VerificationVerdict {
|
|
22
|
+
if (unitType === "execute-task" && result.discoverySource === "none" && result.checks.length === 0) {
|
|
23
|
+
return {
|
|
24
|
+
passed: false,
|
|
25
|
+
reason: "no-host-checks",
|
|
26
|
+
retryable: false,
|
|
27
|
+
failureContext:
|
|
28
|
+
"No runnable host-owned verification command was discovered. Add project verification_commands or a runnable task-plan Verify command before completing this execute-task.",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!result.passed) {
|
|
33
|
+
return {
|
|
34
|
+
passed: false,
|
|
35
|
+
reason: "checks-failed",
|
|
36
|
+
retryable: true,
|
|
37
|
+
failureContext: "",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
passed: true,
|
|
43
|
+
reason: "passed",
|
|
44
|
+
retryable: false,
|
|
45
|
+
failureContext: "",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -109,6 +109,7 @@ export function snapshotState(): StateManifest {
|
|
|
109
109
|
proof_level: (r["proof_level"] as string) ?? "",
|
|
110
110
|
integration_closure: (r["integration_closure"] as string) ?? "",
|
|
111
111
|
observability_impact: (r["observability_impact"] as string) ?? "",
|
|
112
|
+
target_repositories: JSON.parse((r["target_repositories"] as string) || "[]"),
|
|
112
113
|
sequence: toNumeric(r["sequence"], 0) as number,
|
|
113
114
|
replan_triggered_at: (r["replan_triggered_at"] as string) ?? null,
|
|
114
115
|
is_sketch: toNumeric(r["is_sketch"], 0) as number,
|
|
@@ -141,6 +142,7 @@ export function snapshotState(): StateManifest {
|
|
|
141
142
|
expected_output: JSON.parse((r["expected_output"] as string) || "[]"),
|
|
142
143
|
observability_impact: (r["observability_impact"] as string) ?? "",
|
|
143
144
|
full_plan_md: (r["full_plan_md"] as string) ?? "",
|
|
145
|
+
target_repositories: JSON.parse((r["target_repositories"] as string) || "[]"),
|
|
144
146
|
sequence: toNumeric(r["sequence"], 0) as number,
|
|
145
147
|
blocker_source: (r["blocker_source"] as string) ?? "",
|
|
146
148
|
escalation_pending: toNumeric(r["escalation_pending"], 0) as number,
|
|
@@ -18,6 +18,7 @@ export interface WorkflowCapabilityOptions {
|
|
|
18
18
|
unitType?: string;
|
|
19
19
|
authMode?: "apiKey" | "oauth" | "externalCli" | "none";
|
|
20
20
|
baseUrl?: string;
|
|
21
|
+
activeTools?: string[];
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const MCP_WORKFLOW_TOOL_SURFACE = new Set([
|
|
@@ -383,6 +384,15 @@ function hasAskUserQuestionsTool(activeTools: string[]): boolean {
|
|
|
383
384
|
});
|
|
384
385
|
}
|
|
385
386
|
|
|
387
|
+
function hasRequiredTool(requiredTool: string, activeTools: string[]): boolean {
|
|
388
|
+
return activeTools.some((toolName) => {
|
|
389
|
+
if (toolName === requiredTool) return true;
|
|
390
|
+
if (!toolName.startsWith("mcp__")) return false;
|
|
391
|
+
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
392
|
+
return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === requiredTool;
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
386
396
|
function workflowMcpStructuredQuestionsOptIn(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
387
397
|
const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS;
|
|
388
398
|
return value === "1" || value === "true";
|
|
@@ -423,8 +433,15 @@ export function getWorkflowTransportSupportError(
|
|
|
423
433
|
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: the GSD workflow MCP server is not configured or discoverable. Detected Claude Code model but no workflow MCP. Please run /gsd mcp init . from your project root. You can also configure GSD_WORKFLOW_MCP_COMMAND, build packages/mcp-server/dist/cli.js, or install gsd-mcp-server on PATH.`;
|
|
424
434
|
}
|
|
425
435
|
|
|
426
|
-
const
|
|
436
|
+
const uniqueRequired = [...new Set(requiredTools)];
|
|
437
|
+
const missing = (options.activeTools && options.activeTools.length > 0)
|
|
438
|
+
? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
|
|
439
|
+
: uniqueRequired.filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
|
|
427
440
|
if (missing.length === 0) return null;
|
|
428
441
|
|
|
442
|
+
if (options.activeTools && options.activeTools.length > 0) {
|
|
443
|
+
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the active runtime toolset currently exposes only ${options.activeTools.slice().sort().join(", ")}.`;
|
|
444
|
+
}
|
|
445
|
+
|
|
429
446
|
return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${Array.from(MCP_WORKFLOW_TOOL_SURFACE).sort().join(", ")}.`;
|
|
430
447
|
}
|
|
@@ -195,11 +195,11 @@ export function renderSummaryContent(
|
|
|
195
195
|
|
|
196
196
|
// ── Frontmatter (YAML list format, matches parseSummary() expectations) ──
|
|
197
197
|
const keyFilesYaml = taskRow.key_files && taskRow.key_files.length > 0
|
|
198
|
-
? taskRow.key_files.map(f => ` - ${f}`).join("\n")
|
|
199
|
-
: "
|
|
198
|
+
? `\n${taskRow.key_files.map(f => ` - ${f}`).join("\n")}`
|
|
199
|
+
: " []";
|
|
200
200
|
const keyDecisionsYaml = taskRow.key_decisions && taskRow.key_decisions.length > 0
|
|
201
|
-
? taskRow.key_decisions.map(d => ` - ${d}`).join("\n")
|
|
202
|
-
: "
|
|
201
|
+
? `\n${taskRow.key_decisions.map(d => ` - ${d}`).join("\n")}`
|
|
202
|
+
: " []";
|
|
203
203
|
|
|
204
204
|
// Derive verification_result from evidence if available
|
|
205
205
|
const evidenceList = evidence ?? [];
|
|
@@ -230,10 +230,8 @@ export function renderSummaryContent(
|
|
|
230
230
|
id: ${taskRow.id}
|
|
231
231
|
parent: ${sliceId}
|
|
232
232
|
milestone: ${milestoneId}
|
|
233
|
-
key_files
|
|
234
|
-
|
|
235
|
-
key_decisions:
|
|
236
|
-
${keyDecisionsYaml}
|
|
233
|
+
key_files:${keyFilesYaml}
|
|
234
|
+
key_decisions:${keyDecisionsYaml}
|
|
237
235
|
duration: ${taskRow.duration || ""}
|
|
238
236
|
verification_result: ${verificationResult}
|
|
239
237
|
completed_at: ${taskRow.completed_at || ""}
|
|
@@ -23,6 +23,7 @@ import { join } from "node:path";
|
|
|
23
23
|
|
|
24
24
|
import type { AutoSession } from "./auto/session.js";
|
|
25
25
|
import { debugLog } from "./debug-logger.js";
|
|
26
|
+
import { logWarning } from "./workflow-logger.js";
|
|
26
27
|
import { emitJournalEvent } from "./journal.js";
|
|
27
28
|
import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js";
|
|
28
29
|
import {
|
|
@@ -76,6 +77,13 @@ import {
|
|
|
76
77
|
teardownAutoWorktree,
|
|
77
78
|
} from "./auto-worktree.js";
|
|
78
79
|
|
|
80
|
+
const recentWorktreeMergeFailures = new Map<string, number>();
|
|
81
|
+
const MERGE_FAILURE_DEDUPE_MS = 60_000;
|
|
82
|
+
|
|
83
|
+
export function resetRecentWorktreeMergeFailuresForTest(): void {
|
|
84
|
+
recentWorktreeMergeFailures.clear();
|
|
85
|
+
}
|
|
86
|
+
|
|
79
87
|
// ─── Types ───────────────────────────────────────────────────────────────
|
|
80
88
|
|
|
81
89
|
export interface NotifyCtx {
|
|
@@ -513,19 +521,9 @@ export function _enterMilestoneCore(
|
|
|
513
521
|
};
|
|
514
522
|
}
|
|
515
523
|
|
|
516
|
-
if (s.isolationDegraded) {
|
|
517
|
-
debugLog("WorktreeLifecycle", {
|
|
518
|
-
action: "enterMilestone",
|
|
519
|
-
milestoneId,
|
|
520
|
-
skipped: true,
|
|
521
|
-
reason: "isolation-degraded",
|
|
522
|
-
});
|
|
523
|
-
return { ok: false, reason: "isolation-degraded" };
|
|
524
|
-
}
|
|
525
|
-
|
|
526
524
|
// Phase B: claim a milestone lease before any worktree mutation. Two
|
|
527
525
|
// workers cannot enter the same milestone concurrently. Best-effort:
|
|
528
|
-
//
|
|
526
|
+
// warn if no worker registered (single-worker fallback) or skip if DB
|
|
529
527
|
// unavailable; reuse existing lease if we already hold it on this
|
|
530
528
|
// milestone (re-entry within the same session).
|
|
531
529
|
if (s.workerId) {
|
|
@@ -618,6 +616,11 @@ export function _enterMilestoneCore(
|
|
|
618
616
|
});
|
|
619
617
|
}
|
|
620
618
|
}
|
|
619
|
+
} else {
|
|
620
|
+
logWarning(
|
|
621
|
+
"worktree",
|
|
622
|
+
`enterMilestone(${milestoneId}) ran before auto worker registration; milestone lease was not claimed.`,
|
|
623
|
+
);
|
|
621
624
|
}
|
|
622
625
|
|
|
623
626
|
// Resolve the project root for worktree operations via shared helper.
|
|
@@ -626,6 +629,38 @@ export function _enterMilestoneCore(
|
|
|
626
629
|
const basePath = resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
627
630
|
const mode = getIsolationMode(basePath);
|
|
628
631
|
|
|
632
|
+
if (s.isolationDegraded) {
|
|
633
|
+
if (mode === "worktree") {
|
|
634
|
+
try {
|
|
635
|
+
lifecycleEnterBranchMode(deps, basePath, milestoneId);
|
|
636
|
+
s.basePath = basePath;
|
|
637
|
+
rebuildGitService(s, deps);
|
|
638
|
+
invalidateAllCaches();
|
|
639
|
+
ctx.notify(
|
|
640
|
+
`Worktree isolation is degraded. Fell back to branch milestone/${milestoneId}.`,
|
|
641
|
+
"warning",
|
|
642
|
+
);
|
|
643
|
+
return { ok: true, mode: "branch", path: basePath };
|
|
644
|
+
} catch (err) {
|
|
645
|
+
debugLog("WorktreeLifecycle", {
|
|
646
|
+
action: "enterMilestone",
|
|
647
|
+
milestoneId,
|
|
648
|
+
skipped: true,
|
|
649
|
+
reason: "isolation-degraded",
|
|
650
|
+
fallback: "branch-failed",
|
|
651
|
+
error: err instanceof Error ? err.message : String(err),
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
debugLog("WorktreeLifecycle", {
|
|
656
|
+
action: "enterMilestone",
|
|
657
|
+
milestoneId,
|
|
658
|
+
skipped: true,
|
|
659
|
+
reason: "isolation-degraded",
|
|
660
|
+
});
|
|
661
|
+
return { ok: false, reason: "isolation-degraded" };
|
|
662
|
+
}
|
|
663
|
+
|
|
629
664
|
if (mode === "none") {
|
|
630
665
|
debugLog("WorktreeLifecycle", {
|
|
631
666
|
action: "enterMilestone",
|
|
@@ -836,6 +871,32 @@ function rebuildGitService(
|
|
|
836
871
|
s.gitService = deps.gitServiceFactory(s.basePath);
|
|
837
872
|
}
|
|
838
873
|
|
|
874
|
+
function emitWorktreeMergeFailedOnce(
|
|
875
|
+
basePath: string,
|
|
876
|
+
milestoneId: string,
|
|
877
|
+
err: unknown,
|
|
878
|
+
): void {
|
|
879
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
880
|
+
const errorCategory = err instanceof Error ? err.name : "Error";
|
|
881
|
+
const now = Date.now();
|
|
882
|
+
const key = `${basePath}\0${milestoneId}\0${errorCategory}`;
|
|
883
|
+
const previous = recentWorktreeMergeFailures.get(key);
|
|
884
|
+
if (previous && now - previous < MERGE_FAILURE_DEDUPE_MS) return;
|
|
885
|
+
for (const [candidate, ts] of recentWorktreeMergeFailures) {
|
|
886
|
+
if (now - ts >= MERGE_FAILURE_DEDUPE_MS) {
|
|
887
|
+
recentWorktreeMergeFailures.delete(candidate);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
emitJournalEvent(basePath, {
|
|
891
|
+
ts: new Date().toISOString(),
|
|
892
|
+
flowId: randomUUID(),
|
|
893
|
+
seq: 0,
|
|
894
|
+
eventType: "worktree-merge-failed",
|
|
895
|
+
data: { milestoneId, error: msg },
|
|
896
|
+
});
|
|
897
|
+
recentWorktreeMergeFailures.set(key, now);
|
|
898
|
+
}
|
|
899
|
+
|
|
839
900
|
// ─── Session-less merge entry (ADR-016 phase 2 / A1) ─────────────────────
|
|
840
901
|
|
|
841
902
|
/**
|
|
@@ -985,13 +1046,7 @@ function _mergeWorktreeModeImpl(
|
|
|
985
1046
|
error: msg,
|
|
986
1047
|
fallback: "chdir-to-project-root",
|
|
987
1048
|
});
|
|
988
|
-
|
|
989
|
-
ts: new Date().toISOString(),
|
|
990
|
-
flowId: randomUUID(),
|
|
991
|
-
seq: 0,
|
|
992
|
-
eventType: "worktree-merge-failed",
|
|
993
|
-
data: { milestoneId, error: msg },
|
|
994
|
-
});
|
|
1049
|
+
emitWorktreeMergeFailedOnce(originalBasePath || worktreeBasePath, milestoneId, err);
|
|
995
1050
|
// Surface a clear, actionable error. Worktree and milestone branch
|
|
996
1051
|
// are intentionally preserved — nothing has been deleted. User can
|
|
997
1052
|
// retry /gsd dispatch complete-milestone or merge manually once the
|
|
@@ -1181,6 +1236,11 @@ export function mergeMilestoneStandalone(
|
|
|
1181
1236
|
): MergeStandaloneResult {
|
|
1182
1237
|
const { originalBasePath, worktreeBasePath, milestoneId, notify } = mctx;
|
|
1183
1238
|
validateMilestoneId(milestoneId);
|
|
1239
|
+
if (!originalBasePath && !worktreeBasePath) {
|
|
1240
|
+
throw new Error(
|
|
1241
|
+
`Internal error: mergeMilestoneStandalone(${milestoneId}) requires originalBasePath or worktreeBasePath.`,
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1184
1244
|
|
|
1185
1245
|
if (mctx.isolationDegraded) {
|
|
1186
1246
|
if (originalBasePath) {
|
|
@@ -1702,16 +1762,34 @@ export class WorktreeLifecycle {
|
|
|
1702
1762
|
}
|
|
1703
1763
|
|
|
1704
1764
|
/**
|
|
1705
|
-
* Restore `s.basePath` to `s.originalBasePath
|
|
1706
|
-
* No-op when `originalBasePath` is empty (fresh
|
|
1765
|
+
* Restore `s.basePath` to `s.originalBasePath`, chdir process cwd, and
|
|
1766
|
+
* rebuild `s.gitService`. No-op when `originalBasePath` is empty (fresh
|
|
1767
|
+
* sessions).
|
|
1707
1768
|
*
|
|
1708
1769
|
* Used by error/cleanup paths that need the session to behave as if the
|
|
1709
1770
|
* worktree was never entered. Does NOT teardown the worktree directory —
|
|
1710
1771
|
* callers that need teardown go through `exitMilestone({ merge: false })`.
|
|
1772
|
+
*
|
|
1773
|
+
* ADR-016 phase 3 (#5693): chdir lives inside the verb so callers do not
|
|
1774
|
+
* pair `restoreToProjectRoot()` with a redundant `process.chdir`. The
|
|
1775
|
+
* chdir runs BEFORE the throwable work (`rebuildGitService`, cache
|
|
1776
|
+
* invalidation) so that cleanup-path cwd is restored even if the
|
|
1777
|
+
* downstream rebuild throws. The chdir itself is best-effort; failure is
|
|
1778
|
+
* logged via debugLog and swallowed.
|
|
1711
1779
|
*/
|
|
1712
1780
|
restoreToProjectRoot(): void {
|
|
1713
1781
|
if (!this.s.originalBasePath) return;
|
|
1714
1782
|
this.s.basePath = this.s.originalBasePath;
|
|
1783
|
+
try {
|
|
1784
|
+
process.chdir(this.s.basePath);
|
|
1785
|
+
} catch (err) {
|
|
1786
|
+
debugLog("WorktreeLifecycle", {
|
|
1787
|
+
action: "restoreToProjectRoot",
|
|
1788
|
+
result: "chdir-failed",
|
|
1789
|
+
basePath: this.s.basePath,
|
|
1790
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1715
1793
|
rebuildGitService(this.s, this.deps);
|
|
1716
1794
|
invalidateAllCaches();
|
|
1717
1795
|
}
|
|
@@ -241,7 +241,19 @@ export function createWorktree(basePath: string, name: string, opts: { branch?:
|
|
|
241
241
|
const gitFilePath = join(wtPath, ".git");
|
|
242
242
|
if (!existsSync(gitFilePath)) {
|
|
243
243
|
logWarning("reconcile", `Removing stale worktree directory (no .git file): ${wtPath}`, { worktree: name });
|
|
244
|
-
|
|
244
|
+
try {
|
|
245
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
246
|
+
} catch (error) {
|
|
247
|
+
const code = (error as NodeJS.ErrnoException)?.code;
|
|
248
|
+
if (code === "EPERM" || code === "EBUSY") {
|
|
249
|
+
throw new GSDError(
|
|
250
|
+
GSD_GIT_ERROR,
|
|
251
|
+
`Cannot remove stale worktree directory at ${wtPath} (${code}: directory may be locked by another process). Close editors/antivirus/git tools using this path and retry.`,
|
|
252
|
+
{ cause: error as Error },
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
245
257
|
} else {
|
|
246
258
|
throw new GSDError(GSD_STALE_STATE, `Worktree "${name}" already exists at ${wtPath}`);
|
|
247
259
|
}
|
|
@@ -618,7 +630,7 @@ export function removeWorktree(
|
|
|
618
630
|
try {
|
|
619
631
|
rmSync(nestedGitPath, { recursive: true, force: true });
|
|
620
632
|
logWarning("reconcile",
|
|
621
|
-
`Removed nested .git directory from scaffolded project to prevent data loss
|
|
633
|
+
`Removed nested .git directory from scaffolded project to prevent data loss`,
|
|
622
634
|
{ worktree: name, nestedRepo: nestedDir },
|
|
623
635
|
);
|
|
624
636
|
} catch {
|