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
|
@@ -30,11 +30,13 @@ function initGitRepoIn(base: string, isolation: "worktree" | "branch" | "none"):
|
|
|
30
30
|
}
|
|
31
31
|
import {
|
|
32
32
|
WorktreeLifecycle,
|
|
33
|
+
resetRecentWorktreeMergeFailuresForTest,
|
|
33
34
|
type WorktreeLifecycleDeps,
|
|
34
35
|
type NotifyCtx,
|
|
35
36
|
} from "../worktree-lifecycle.js";
|
|
36
37
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
37
38
|
import { type TaskCommitContext } from "../worktree.js";
|
|
39
|
+
import { MergeConflictError } from "../git-service.js";
|
|
38
40
|
|
|
39
41
|
// ADR-016 phase 2 / C-track retired all worktree-manager + cache + prefs
|
|
40
42
|
// fields from `WorktreeLifecycleDeps`. Tests still pass them as overrides
|
|
@@ -141,6 +143,20 @@ function readJournalEntries(basePath: string): JournalEntry[] {
|
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
145
|
|
|
146
|
+
function setupMergeWorktree(basePath: string, milestoneId: string): string {
|
|
147
|
+
initGitRepoIn(basePath, "worktree");
|
|
148
|
+
execFileSync("git", ["checkout", "-b", `milestone/${milestoneId}`], { cwd: basePath, stdio: "pipe" });
|
|
149
|
+
execFileSync("git", ["checkout", "main"], { cwd: basePath, stdio: "pipe" });
|
|
150
|
+
const wt = join(basePath, ".gsd", "worktrees", milestoneId);
|
|
151
|
+
execFileSync("git", ["worktree", "add", wt, `milestone/${milestoneId}`], { cwd: basePath, stdio: "pipe" });
|
|
152
|
+
mkdirSync(join(basePath, ".gsd", "milestones", milestoneId), { recursive: true });
|
|
153
|
+
writeFileSync(
|
|
154
|
+
join(basePath, ".gsd", "milestones", milestoneId, `${milestoneId}-ROADMAP.md`),
|
|
155
|
+
`# ${milestoneId}\n- [x] S01: Slice one\n`,
|
|
156
|
+
);
|
|
157
|
+
return wt;
|
|
158
|
+
}
|
|
159
|
+
|
|
144
160
|
// ─── Tests ───────────────────────────────────────────────────────────────────
|
|
145
161
|
|
|
146
162
|
describe("worktree journal events", () => {
|
|
@@ -148,6 +164,7 @@ describe("worktree journal events", () => {
|
|
|
148
164
|
const originalCwd = process.cwd();
|
|
149
165
|
|
|
150
166
|
beforeEach(() => {
|
|
167
|
+
resetRecentWorktreeMergeFailuresForTest();
|
|
151
168
|
// realpathSync to match what `auto-worktree.ts` returns from
|
|
152
169
|
// `resolveWorktreeProjectRoot` (macOS resolves `/var` → `/private/var`).
|
|
153
170
|
tmp = realpathSync(mkdtempSync(join(tmpdir(), "wt-journal-")));
|
|
@@ -284,17 +301,7 @@ describe("worktree journal events", () => {
|
|
|
284
301
|
});
|
|
285
302
|
|
|
286
303
|
test("mergeAndExit emits worktree-merge-failed on error", () => {
|
|
287
|
-
|
|
288
|
-
execFileSync("git", ["checkout", "-b", "milestone/M001"], { cwd: tmp, stdio: "pipe" });
|
|
289
|
-
execFileSync("git", ["checkout", "main"], { cwd: tmp, stdio: "pipe" });
|
|
290
|
-
const wt = join(tmp, ".gsd", "worktrees", "M001");
|
|
291
|
-
execFileSync("git", ["worktree", "add", wt, "milestone/M001"], { cwd: tmp, stdio: "pipe" });
|
|
292
|
-
mkdirSync(join(tmp, ".gsd", "milestones", "M001"), { recursive: true });
|
|
293
|
-
writeFileSync(
|
|
294
|
-
join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
295
|
-
"# M001\n- [x] S01: Slice one\n",
|
|
296
|
-
);
|
|
297
|
-
|
|
304
|
+
const wt = setupMergeWorktree(tmp, "M001");
|
|
298
305
|
const s = makeSession({ basePath: wt, originalBasePath: tmp });
|
|
299
306
|
const deps = makeDeps({
|
|
300
307
|
mergeMilestoneToMain: () => { throw new Error("conflict in main"); },
|
|
@@ -318,11 +325,56 @@ describe("worktree journal events", () => {
|
|
|
318
325
|
);
|
|
319
326
|
}
|
|
320
327
|
|
|
328
|
+
new WorktreeLifecycle(s, deps).exitMilestone(
|
|
329
|
+
"M001",
|
|
330
|
+
{ merge: true },
|
|
331
|
+
makeNotifyCtx(),
|
|
332
|
+
);
|
|
333
|
+
|
|
321
334
|
const entries = readJournalEntries(tmp);
|
|
322
|
-
const
|
|
335
|
+
const failures = entries.filter(e => e.eventType === "worktree-merge-failed");
|
|
336
|
+
const failed = failures[0];
|
|
323
337
|
assert.ok(failed, "worktree-merge-failed event should be emitted");
|
|
324
338
|
assert.equal(failed!.data?.milestoneId, "M001");
|
|
325
339
|
assert.equal(failed!.data?.error, "conflict in main");
|
|
340
|
+
assert.equal(failures.length, 1, "duplicate merge failures are journaled once");
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test("merge failure dedupe uses stable conflict category and expires", (t) => {
|
|
344
|
+
let now = 1_000_000;
|
|
345
|
+
t.mock.method(Date, "now", () => now);
|
|
346
|
+
const wt = setupMergeWorktree(tmp, "M001");
|
|
347
|
+
const s = makeSession({ basePath: wt, originalBasePath: tmp });
|
|
348
|
+
let attempt = 0;
|
|
349
|
+
const deps = makeDeps({
|
|
350
|
+
mergeMilestoneToMain: () => {
|
|
351
|
+
attempt += 1;
|
|
352
|
+
throw new MergeConflictError(
|
|
353
|
+
attempt === 1 ? ["src/a.ts"] : ["src/b.ts", "src/c.ts"],
|
|
354
|
+
"squash",
|
|
355
|
+
"milestone/M001",
|
|
356
|
+
"main",
|
|
357
|
+
);
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
const lifecycle = new WorktreeLifecycle(s, deps);
|
|
361
|
+
|
|
362
|
+
lifecycle.exitMilestone("M001", { merge: true }, makeNotifyCtx());
|
|
363
|
+
lifecycle.exitMilestone("M001", { merge: true }, makeNotifyCtx());
|
|
364
|
+
|
|
365
|
+
let failures = readJournalEntries(tmp).filter(e => e.eventType === "worktree-merge-failed");
|
|
366
|
+
assert.equal(failures.length, 1, "variable conflict filenames should not bypass dedupe");
|
|
367
|
+
assert.match(
|
|
368
|
+
String(failures[0]!.data?.error),
|
|
369
|
+
/src\/a\.ts/,
|
|
370
|
+
"journal payload keeps the original error message",
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
now += 60_001;
|
|
374
|
+
lifecycle.exitMilestone("M001", { merge: true }, makeNotifyCtx());
|
|
375
|
+
|
|
376
|
+
failures = readJournalEntries(tmp).filter(e => e.eventType === "worktree-merge-failed");
|
|
377
|
+
assert.equal(failures.length, 2, "same merge failure is journaled again after dedupe expiry");
|
|
326
378
|
});
|
|
327
379
|
|
|
328
380
|
test("journal entries have valid flowId, seq, and ts fields", () => {
|
|
@@ -8,6 +8,7 @@ import { join } from "node:path";
|
|
|
8
8
|
import { execFileSync } from "node:child_process";
|
|
9
9
|
import {
|
|
10
10
|
WorktreeLifecycle,
|
|
11
|
+
mergeMilestoneStandalone,
|
|
11
12
|
resolvePausedResumeBasePath,
|
|
12
13
|
type WorktreeLifecycleDeps,
|
|
13
14
|
type WorktreeLifecycleTestOverrides,
|
|
@@ -213,7 +214,7 @@ test("enterMilestone returns ok:true mode:none when isolation disabled", () => {
|
|
|
213
214
|
|
|
214
215
|
test("enterMilestone returns ok:false reason:isolation-degraded when session degraded", () => {
|
|
215
216
|
const s = makeSession({ isolationDegraded: true });
|
|
216
|
-
const deps = makeDeps();
|
|
217
|
+
const deps = makeDeps({ getIsolationMode: () => "branch" });
|
|
217
218
|
const ctx = makeCtx();
|
|
218
219
|
const lifecycle = new WorktreeLifecycle(s, deps);
|
|
219
220
|
|
|
@@ -225,7 +226,37 @@ test("enterMilestone returns ok:false reason:isolation-degraded when session deg
|
|
|
225
226
|
}
|
|
226
227
|
assert.equal(s.basePath, "/project");
|
|
227
228
|
assert.equal(s.milestoneLeaseToken, null);
|
|
228
|
-
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test("enterMilestone falls back to branch mode when session is degraded in worktree isolation", (t) => {
|
|
232
|
+
const previousCwd = process.cwd();
|
|
233
|
+
const base = makeGitRepoBase({ isolation: "worktree" });
|
|
234
|
+
t.after(() => cleanupRepoBase(base, previousCwd));
|
|
235
|
+
|
|
236
|
+
const s = makeSession({
|
|
237
|
+
basePath: base,
|
|
238
|
+
originalBasePath: base,
|
|
239
|
+
isolationDegraded: true,
|
|
240
|
+
});
|
|
241
|
+
const deps = makeDeps();
|
|
242
|
+
const ctx = makeCtx();
|
|
243
|
+
const lifecycle = new WorktreeLifecycle(s, deps);
|
|
244
|
+
|
|
245
|
+
const result = lifecycle.enterMilestone("M001", ctx);
|
|
246
|
+
|
|
247
|
+
assert.equal(result.ok, true, `expected ok:true, got: ${JSON.stringify(result)}`);
|
|
248
|
+
if (result.ok) {
|
|
249
|
+
assert.equal(result.mode, "branch");
|
|
250
|
+
assert.equal(result.path, base);
|
|
251
|
+
}
|
|
252
|
+
assert.equal(s.basePath, base);
|
|
253
|
+
assert.equal(
|
|
254
|
+
ctx.messages.some((m) =>
|
|
255
|
+
m.level === "warning" &&
|
|
256
|
+
m.msg.includes("Worktree isolation is degraded. Fell back to branch"),
|
|
257
|
+
),
|
|
258
|
+
true,
|
|
259
|
+
);
|
|
229
260
|
});
|
|
230
261
|
|
|
231
262
|
test("enterMilestone returns ok:false reason:creation-failed and degrades session on worktree throw", (t) => {
|
|
@@ -538,6 +569,31 @@ test("restoreToProjectRoot is no-op when originalBasePath is empty", () => {
|
|
|
538
569
|
assert.equal(deps.calls.filter((c) => c.fn === "gitServiceFactory").length, 0);
|
|
539
570
|
});
|
|
540
571
|
|
|
572
|
+
test("restoreToProjectRoot completes session-state restore even when chdir fails (ADR-016 phase 3, #5693)", () => {
|
|
573
|
+
// The verb attempts process.chdir to s.basePath after restoring it. The
|
|
574
|
+
// chdir is best-effort; failure must not abort the session-state restore.
|
|
575
|
+
// We exercise that contract by pointing originalBasePath at a path that
|
|
576
|
+
// cannot be chdir'd into.
|
|
577
|
+
const s = makeSession();
|
|
578
|
+
s.originalBasePath = "/this/path/should/not/exist/in/any/test/env";
|
|
579
|
+
s.basePath = "/project/.gsd/worktrees/M001";
|
|
580
|
+
const deps = makeDeps();
|
|
581
|
+
const lifecycle = new WorktreeLifecycle(s, deps);
|
|
582
|
+
|
|
583
|
+
// Capture cwd so we can confirm we did NOT successfully chdir.
|
|
584
|
+
const cwdBefore = process.cwd();
|
|
585
|
+
lifecycle.restoreToProjectRoot();
|
|
586
|
+
|
|
587
|
+
// Session-state restore happened despite chdir failure.
|
|
588
|
+
assert.equal(s.basePath, "/this/path/should/not/exist/in/any/test/env");
|
|
589
|
+
assert.equal(
|
|
590
|
+
deps.calls.filter((c) => c.fn === "gitServiceFactory").length,
|
|
591
|
+
1,
|
|
592
|
+
);
|
|
593
|
+
// cwd is unchanged because chdir threw and was swallowed.
|
|
594
|
+
assert.equal(process.cwd(), cwdBefore);
|
|
595
|
+
});
|
|
596
|
+
|
|
541
597
|
// ─── adoptSessionRoot (ADR-016 phase 2 / B2, issue #5620) ─────────────────────
|
|
542
598
|
|
|
543
599
|
test("adoptSessionRoot sets basePath and seeds originalBasePath on a fresh session", () => {
|
|
@@ -595,6 +651,21 @@ test("adoptSessionRoot does not chdir, rebuild git service, or invalidate caches
|
|
|
595
651
|
assert.equal(deps.calls.filter((c) => c.fn === "invalidateAllCaches").length, 0);
|
|
596
652
|
});
|
|
597
653
|
|
|
654
|
+
test("mergeMilestoneStandalone fails loud when both base paths are empty", () => {
|
|
655
|
+
const deps = makeDeps();
|
|
656
|
+
assert.throws(
|
|
657
|
+
() =>
|
|
658
|
+
mergeMilestoneStandalone(deps, {
|
|
659
|
+
originalBasePath: "",
|
|
660
|
+
worktreeBasePath: "",
|
|
661
|
+
milestoneId: "M001",
|
|
662
|
+
isolationDegraded: false,
|
|
663
|
+
notify: () => {},
|
|
664
|
+
}),
|
|
665
|
+
/requires originalBasePath or worktreeBasePath/,
|
|
666
|
+
);
|
|
667
|
+
});
|
|
668
|
+
|
|
598
669
|
// ─── resumeFromPausedSession (ADR-016 phase 2 / B3, issue #5621) ──────────────
|
|
599
670
|
|
|
600
671
|
test("resumeFromPausedSession adopts the persisted worktree path when it exists", (t) => {
|
|
@@ -86,6 +86,31 @@ test("#2684: syncGsdStateToWorktree forward-syncs PREFERENCES.md when missing fr
|
|
|
86
86
|
);
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
+
test("syncGsdStateToWorktree creates missing worktree .gsd and projects DECISIONS.md", (t) => {
|
|
90
|
+
const mainBase = makeTempDir("main");
|
|
91
|
+
const wtBase = makeTempDir("wt");
|
|
92
|
+
t.after(() => cleanup(mainBase, wtBase));
|
|
93
|
+
|
|
94
|
+
const decisions = "# Decisions\n\n- D001: Test decision\n";
|
|
95
|
+
writeFile(mainBase, ".gsd/DECISIONS.md", decisions);
|
|
96
|
+
|
|
97
|
+
const result = syncGsdStateToWorktree(mainBase, wtBase);
|
|
98
|
+
|
|
99
|
+
assert.ok(
|
|
100
|
+
existsSync(join(wtBase, ".gsd", "DECISIONS.md")),
|
|
101
|
+
"DECISIONS.md should be projected into worktree .gsd",
|
|
102
|
+
);
|
|
103
|
+
assert.equal(
|
|
104
|
+
readFileSync(join(wtBase, ".gsd", "DECISIONS.md"), "utf-8"),
|
|
105
|
+
decisions,
|
|
106
|
+
"DECISIONS.md content should match project root projection",
|
|
107
|
+
);
|
|
108
|
+
assert.ok(
|
|
109
|
+
result.synced.includes("DECISIONS.md"),
|
|
110
|
+
"DECISIONS.md should appear in synced list",
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
89
114
|
test("syncGsdStateToWorktree still accepts legacy lowercase preferences.md", (t) => {
|
|
90
115
|
const mainBase = makeTempDir("main");
|
|
91
116
|
const wtBase = makeTempDir("wt");
|
|
@@ -129,6 +129,50 @@ describe("Worktree Safety module", () => {
|
|
|
129
129
|
assert.equal(result.details?.expectedRoot, unitRoot);
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
+
test("accepts project root for source-writing Unit when isolation mode is none", () => {
|
|
133
|
+
const safety = createWorktreeSafetyModule({
|
|
134
|
+
existsSync: () => true,
|
|
135
|
+
lstatSync: () => ({ isFile: () => true }),
|
|
136
|
+
listRegisteredWorktrees: () => [{ path: projectRoot, branch: "main" }],
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const result = safety.validateUnitRoot({
|
|
140
|
+
unitType: "execute-task",
|
|
141
|
+
unitId: "M001/S01/T01",
|
|
142
|
+
writeScope: "source-writing",
|
|
143
|
+
projectRoot,
|
|
144
|
+
unitRoot: projectRoot,
|
|
145
|
+
milestoneId: "M001",
|
|
146
|
+
isolationMode: "none",
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
assert.equal(result.ok, true);
|
|
150
|
+
assert.equal(result.kind, "safe");
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test("rejects non-project root for source-writing Unit when isolation mode is none", () => {
|
|
154
|
+
const safety = createWorktreeSafetyModule({
|
|
155
|
+
existsSync: () => true,
|
|
156
|
+
lstatSync: () => ({ isFile: () => true }),
|
|
157
|
+
listRegisteredWorktrees: () => [{ path: unitRoot, branch: "main" }],
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const result = safety.validateUnitRoot({
|
|
161
|
+
unitType: "execute-task",
|
|
162
|
+
unitId: "M001/S01/T01",
|
|
163
|
+
writeScope: "source-writing",
|
|
164
|
+
projectRoot,
|
|
165
|
+
unitRoot,
|
|
166
|
+
milestoneId: "M001",
|
|
167
|
+
isolationMode: "none",
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
assert.equal(result.ok, false);
|
|
171
|
+
assert.equal(result.kind, "invalid-root");
|
|
172
|
+
assert.equal(result.details?.expectedRoot, projectRoot);
|
|
173
|
+
assert.equal(result.details?.unitRoot, unitRoot);
|
|
174
|
+
});
|
|
175
|
+
|
|
132
176
|
test("rejects a standalone repository masquerading as a worktree", () => {
|
|
133
177
|
unlinkSync(join(unitRoot, ".git"));
|
|
134
178
|
mkdirSync(join(unitRoot, ".git"), { recursive: true });
|
|
@@ -189,6 +233,52 @@ describe("Worktree Safety module", () => {
|
|
|
189
233
|
assert.equal(result.kind, "worktree-unregistered");
|
|
190
234
|
});
|
|
191
235
|
|
|
236
|
+
test("attempts prune recovery once for unregistered worktrees and tracks failed roots", () => {
|
|
237
|
+
let pruneCalls = 0;
|
|
238
|
+
let listCalls = 0;
|
|
239
|
+
const safety = createWorktreeSafetyModule({
|
|
240
|
+
existsSync: () => true,
|
|
241
|
+
lstatSync: () => ({ isFile: () => true }),
|
|
242
|
+
pruneRegisteredWorktrees: () => {
|
|
243
|
+
pruneCalls += 1;
|
|
244
|
+
},
|
|
245
|
+
listRegisteredWorktrees: () => {
|
|
246
|
+
listCalls += 1;
|
|
247
|
+
return [];
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const first = safety.validateUnitRoot({
|
|
252
|
+
unitType: "execute-task",
|
|
253
|
+
unitId: "M001/S01/T01",
|
|
254
|
+
writeScope: "source-writing",
|
|
255
|
+
projectRoot,
|
|
256
|
+
unitRoot,
|
|
257
|
+
milestoneId: "M001",
|
|
258
|
+
});
|
|
259
|
+
assert.equal(first.ok, false);
|
|
260
|
+
assert.equal(first.kind, "worktree-unregistered");
|
|
261
|
+
assert.equal(first.details?.attemptedPrune, true);
|
|
262
|
+
assert.equal(first.details?.trackedAsFailed, true);
|
|
263
|
+
assert.equal(pruneCalls, 1);
|
|
264
|
+
assert.equal(listCalls, 2);
|
|
265
|
+
|
|
266
|
+
const second = safety.validateUnitRoot({
|
|
267
|
+
unitType: "execute-task",
|
|
268
|
+
unitId: "M001/S01/T01",
|
|
269
|
+
writeScope: "source-writing",
|
|
270
|
+
projectRoot,
|
|
271
|
+
unitRoot,
|
|
272
|
+
milestoneId: "M001",
|
|
273
|
+
});
|
|
274
|
+
assert.equal(second.ok, false);
|
|
275
|
+
assert.equal(second.kind, "worktree-unregistered");
|
|
276
|
+
assert.equal(second.details?.attemptedPrune, false);
|
|
277
|
+
assert.equal(second.details?.trackedAsFailed, true);
|
|
278
|
+
assert.equal(pruneCalls, 1);
|
|
279
|
+
assert.equal(listCalls, 3);
|
|
280
|
+
});
|
|
281
|
+
|
|
192
282
|
test("converts registered worktree list failures into typed failures", () => {
|
|
193
283
|
const safety = createWorktreeSafetyModule({
|
|
194
284
|
existsSync: () => true,
|
|
@@ -607,4 +607,99 @@ describe('worktree-sync-milestones', async () => {
|
|
|
607
607
|
rmSync(wtBase, { recursive: true, force: true });
|
|
608
608
|
}
|
|
609
609
|
}
|
|
610
|
+
|
|
611
|
+
// ─── 16. pre-dispatch sync projects missing future milestone top-level artifacts (#5687) ──
|
|
612
|
+
console.log('\n=== 16. pre-dispatch sync projects missing future milestone top-level artifacts (#5687) ===');
|
|
613
|
+
{
|
|
614
|
+
const mainBase = createBase('main');
|
|
615
|
+
const wtBase = createBase('wt');
|
|
616
|
+
|
|
617
|
+
try {
|
|
618
|
+
// Canonical .gsd has M003 context draft that complete-milestone needs.
|
|
619
|
+
const mainM003 = join(mainBase, '.gsd', 'milestones', 'M003');
|
|
620
|
+
mkdirSync(mainM003, { recursive: true });
|
|
621
|
+
writeFileSync(join(mainM003, 'M003-CONTEXT-DRAFT.md'), '# M003 Context Draft');
|
|
622
|
+
writeFileSync(join(mainM003, 'M003-ROADMAP.md'), '# M003 Roadmap');
|
|
623
|
+
|
|
624
|
+
// Worktree only has skeletal roadmap for M003.
|
|
625
|
+
const wtM003 = join(wtBase, '.gsd', 'milestones', 'M003');
|
|
626
|
+
mkdirSync(wtM003, { recursive: true });
|
|
627
|
+
writeFileSync(join(wtM003, 'M003-ROADMAP.md'), '# WT Roadmap');
|
|
628
|
+
|
|
629
|
+
// Worktree has current milestone file that must not be overwritten.
|
|
630
|
+
const mainM002 = join(mainBase, '.gsd', 'milestones', 'M002');
|
|
631
|
+
mkdirSync(mainM002, { recursive: true });
|
|
632
|
+
writeFileSync(join(mainM002, 'M002-ROADMAP.md'), '# Main M002 Roadmap');
|
|
633
|
+
const wtM002 = join(wtBase, '.gsd', 'milestones', 'M002');
|
|
634
|
+
mkdirSync(wtM002, { recursive: true });
|
|
635
|
+
writeFileSync(join(wtM002, 'M002-ROADMAP.md'), '# Worktree M002 Roadmap');
|
|
636
|
+
|
|
637
|
+
// Canonical .gsd has M004 with no corresponding worktree directory at all.
|
|
638
|
+
const mainM004 = join(mainBase, '.gsd', 'milestones', 'M004');
|
|
639
|
+
mkdirSync(mainM004, { recursive: true });
|
|
640
|
+
writeFileSync(join(mainM004, 'M004-CONTEXT-DRAFT.md'), '# M004 Context Draft');
|
|
641
|
+
|
|
642
|
+
syncProjectRootToWorktree(mainBase, wtBase, 'M002');
|
|
643
|
+
|
|
644
|
+
assert.ok(
|
|
645
|
+
existsSync(join(wtBase, '.gsd', 'milestones', 'M003', 'M003-CONTEXT-DRAFT.md')),
|
|
646
|
+
'#5687: future milestone context draft projected into worktree',
|
|
647
|
+
);
|
|
648
|
+
assert.equal(
|
|
649
|
+
readFileSync(join(wtBase, '.gsd', 'milestones', 'M003', 'M003-ROADMAP.md'), 'utf-8'),
|
|
650
|
+
'# WT Roadmap',
|
|
651
|
+
'#5687: existing worktree-local M003 file is not overwritten',
|
|
652
|
+
);
|
|
653
|
+
assert.equal(
|
|
654
|
+
readFileSync(join(wtBase, '.gsd', 'milestones', 'M002', 'M002-ROADMAP.md'), 'utf-8'),
|
|
655
|
+
'# Worktree M002 Roadmap',
|
|
656
|
+
'#5687: existing worktree-local files are not overwritten',
|
|
657
|
+
);
|
|
658
|
+
assert.ok(
|
|
659
|
+
existsSync(join(wtBase, '.gsd', 'milestones', 'M004', 'M004-CONTEXT-DRAFT.md')),
|
|
660
|
+
'#5687: future milestone context draft projected into worktree when no wt dir existed',
|
|
661
|
+
);
|
|
662
|
+
} finally {
|
|
663
|
+
cleanup(mainBase);
|
|
664
|
+
cleanup(wtBase);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// ─── 17. pre-dispatch sync creates absent worktree milestone dir before projecting artifacts (#5687) ──
|
|
669
|
+
console.log('\n=== 17. pre-dispatch sync creates absent worktree milestone dir before projecting artifacts (#5687) ===');
|
|
670
|
+
{
|
|
671
|
+
const mainBase = createBase('main');
|
|
672
|
+
const wtBase = createBase('wt');
|
|
673
|
+
|
|
674
|
+
try {
|
|
675
|
+
// Canonical .gsd has a future milestone M004 with a context draft.
|
|
676
|
+
const mainM004 = join(mainBase, '.gsd', 'milestones', 'M004');
|
|
677
|
+
mkdirSync(mainM004, { recursive: true });
|
|
678
|
+
writeFileSync(join(mainM004, 'M004-CONTEXT-DRAFT.md'), '# M004 Context Draft');
|
|
679
|
+
|
|
680
|
+
// Active milestone M002 exists in both main and worktree.
|
|
681
|
+
const mainM002 = join(mainBase, '.gsd', 'milestones', 'M002');
|
|
682
|
+
mkdirSync(mainM002, { recursive: true });
|
|
683
|
+
writeFileSync(join(mainM002, 'M002-ROADMAP.md'), '# Main M002 Roadmap');
|
|
684
|
+
const wtM002 = join(wtBase, '.gsd', 'milestones', 'M002');
|
|
685
|
+
mkdirSync(wtM002, { recursive: true });
|
|
686
|
+
writeFileSync(join(wtM002, 'M002-ROADMAP.md'), '# Worktree M002 Roadmap');
|
|
687
|
+
|
|
688
|
+
// M004 does NOT exist in the worktree at all before sync.
|
|
689
|
+
assert.ok(
|
|
690
|
+
!existsSync(join(wtBase, '.gsd', 'milestones', 'M004')),
|
|
691
|
+
'#5687: worktree M004 dir must not exist before sync',
|
|
692
|
+
);
|
|
693
|
+
|
|
694
|
+
syncProjectRootToWorktree(mainBase, wtBase, 'M002');
|
|
695
|
+
|
|
696
|
+
assert.ok(
|
|
697
|
+
existsSync(join(wtBase, '.gsd', 'milestones', 'M004', 'M004-CONTEXT-DRAFT.md')),
|
|
698
|
+
'#5687: context draft projected into worktree even when milestone dir was absent',
|
|
699
|
+
);
|
|
700
|
+
} finally {
|
|
701
|
+
cleanup(mainBase);
|
|
702
|
+
cleanup(wtBase);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
610
705
|
});
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
emitWorktreeOrphaned,
|
|
19
19
|
emitAutoExit,
|
|
20
20
|
emitCanonicalRootRedirect,
|
|
21
|
+
normalizeAutoExitReason,
|
|
21
22
|
summarizeWorktreeTelemetry,
|
|
22
23
|
percentile,
|
|
23
24
|
} from "../worktree-telemetry.ts";
|
|
@@ -87,6 +88,7 @@ test("emitAutoExit records reason and unmerged-work signal", () => {
|
|
|
87
88
|
try {
|
|
88
89
|
emitAutoExit(base, {
|
|
89
90
|
reason: "pause",
|
|
91
|
+
rawReason: "Operation aborted",
|
|
90
92
|
milestoneId: "M003",
|
|
91
93
|
milestoneMerged: false,
|
|
92
94
|
isolationMode: "worktree",
|
|
@@ -95,12 +97,26 @@ test("emitAutoExit records reason and unmerged-work signal", () => {
|
|
|
95
97
|
const entries = queryJournal(base, { eventType: "auto-exit" });
|
|
96
98
|
assert.equal(entries.length, 1);
|
|
97
99
|
assert.equal(entries[0].data?.reason, "pause");
|
|
100
|
+
assert.equal(entries[0].data?.rawReason, "Operation aborted");
|
|
98
101
|
assert.equal(entries[0].data?.milestoneMerged, false);
|
|
99
102
|
assert.equal(entries[0].data?.isolationMode, "worktree");
|
|
100
103
|
assert.equal(entries[0].data?.worktreeActive, true);
|
|
101
104
|
} finally { cleanup(base); }
|
|
102
105
|
});
|
|
103
106
|
|
|
107
|
+
test("normalizeAutoExitReason maps new buckets and ignores casing", () => {
|
|
108
|
+
const cases: Array<{ rawReason: string; expected: string }> = [
|
|
109
|
+
{ rawReason: "Provider Error: timeout", expected: "provider-error" },
|
|
110
|
+
{ rawReason: "SESSION CREATION failed", expected: "session-failed" },
|
|
111
|
+
{ rawReason: "Operation Aborted by upstream", expected: "stream-aborted" },
|
|
112
|
+
{ rawReason: "AUTO-MODE STOPPED by user", expected: "unit-aborted" },
|
|
113
|
+
{ rawReason: "Pausing Auto-Mode after 3 retries", expected: "verification-exhausted" },
|
|
114
|
+
];
|
|
115
|
+
for (const { rawReason, expected } of cases) {
|
|
116
|
+
assert.equal(normalizeAutoExitReason(rawReason), expected);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
104
120
|
test("summarizeWorktreeTelemetry only counts unmerged exits from active worktrees", (t) => {
|
|
105
121
|
const base = makeTmpBase();
|
|
106
122
|
t.after(() => cleanup(base));
|
|
@@ -123,6 +123,20 @@ describe("shouldBlockWorktreeWrite (#5199)", () => {
|
|
|
123
123
|
assert.equal(result.block, false);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
test("Case 6b: relative write from active worktree cwd is allowed", () => {
|
|
127
|
+
projectRoot = makeProject("worktree");
|
|
128
|
+
const inside = join(projectRoot, ".gsd", "worktrees", "M001");
|
|
129
|
+
mkdirSync(inside, { recursive: true });
|
|
130
|
+
const result = shouldBlockWorktreeWrite(
|
|
131
|
+
"write",
|
|
132
|
+
"DESIGN.md",
|
|
133
|
+
inside,
|
|
134
|
+
/* isAutoLive */ true,
|
|
135
|
+
null,
|
|
136
|
+
);
|
|
137
|
+
assert.equal(result.block, false);
|
|
138
|
+
});
|
|
139
|
+
|
|
126
140
|
test("Case 7: isolation=worktree, auto active, effectiveBasePath is project root (cwd never flipped) → block", () => {
|
|
127
141
|
projectRoot = makeProject("worktree");
|
|
128
142
|
const result = shouldBlockWorktreeWrite(
|
|
@@ -136,6 +150,19 @@ describe("shouldBlockWorktreeWrite (#5199)", () => {
|
|
|
136
150
|
assert.match(result.reason ?? "", /HARD BLOCK/);
|
|
137
151
|
});
|
|
138
152
|
|
|
153
|
+
test("Case 7b: relative write from project root cwd is blocked", () => {
|
|
154
|
+
projectRoot = makeProject("worktree");
|
|
155
|
+
const result = shouldBlockWorktreeWrite(
|
|
156
|
+
"write",
|
|
157
|
+
"DESIGN.md",
|
|
158
|
+
projectRoot,
|
|
159
|
+
/* isAutoLive */ true,
|
|
160
|
+
null,
|
|
161
|
+
);
|
|
162
|
+
assert.equal(result.block, true);
|
|
163
|
+
assert.match(result.reason ?? "", /HARD BLOCK/);
|
|
164
|
+
});
|
|
165
|
+
|
|
139
166
|
test("Case 8: bootstrap unit type active → allow", () => {
|
|
140
167
|
projectRoot = makeProject("worktree");
|
|
141
168
|
for (const unitType of ["discuss-milestone", "plan-milestone", "init"]) {
|
|
@@ -26,6 +26,7 @@ const PLANNING_DISPATCH_REVIEW: ToolsPolicy = {
|
|
|
26
26
|
};
|
|
27
27
|
const READ_ONLY: ToolsPolicy = { mode: 'read-only' };
|
|
28
28
|
const ALL: ToolsPolicy = { mode: 'all' };
|
|
29
|
+
const VERIFICATION: ToolsPolicy = { mode: 'verification' };
|
|
29
30
|
const DOCS: ToolsPolicy = {
|
|
30
31
|
mode: 'docs',
|
|
31
32
|
allowedPathGlobs: ['docs/**', 'README.md', 'README.*.md', 'CHANGELOG.md', '*.md'],
|
|
@@ -116,6 +117,11 @@ test('planning-unit: allows read-only bash (cat)', () => {
|
|
|
116
117
|
assert.strictEqual(r.block, false);
|
|
117
118
|
});
|
|
118
119
|
|
|
120
|
+
test('planning-unit: allows read-only bash prefixed with cd', () => {
|
|
121
|
+
const r = shouldBlockPlanningUnit('bash', 'cd .gsd && cat PROJECT.md', BASE, 'plan-slice', PLANNING_DISPATCH);
|
|
122
|
+
assert.strictEqual(r.block, false);
|
|
123
|
+
});
|
|
124
|
+
|
|
119
125
|
test('planning-unit: blocks mutating bash (rm -rf)', () => {
|
|
120
126
|
const r = shouldBlockPlanningUnit('bash', 'rm -rf /tmp/foo', BASE, 'discuss-milestone', PLANNING);
|
|
121
127
|
assert.strictEqual(r.block, true);
|
|
@@ -157,6 +163,13 @@ test('planning-dispatch: allows subagent dispatch (delegated recon/planner durin
|
|
|
157
163
|
assert.strictEqual(r.block, false);
|
|
158
164
|
});
|
|
159
165
|
|
|
166
|
+
test('planning-dispatch: allows markdown agent filenames after identity normalization', () => {
|
|
167
|
+
const agentClasses = extractSubagentAgentClasses({ agent: 'scout.md' });
|
|
168
|
+
assert.deepEqual(agentClasses, ['scout']);
|
|
169
|
+
const r = shouldBlockPlanningUnit('subagent', '', BASE, 'plan-slice', PLANNING_DISPATCH, agentClasses);
|
|
170
|
+
assert.strictEqual(r.block, false);
|
|
171
|
+
});
|
|
172
|
+
|
|
160
173
|
test('planning-dispatch: allows task dispatch (delegated recon/planner during slice planning)', () => {
|
|
161
174
|
const r = shouldBlockPlanningUnit('task', '', BASE, 'plan-slice', PLANNING_DISPATCH, ['planner']);
|
|
162
175
|
assert.strictEqual(r.block, false);
|
|
@@ -172,6 +185,22 @@ test('planning-dispatch: extracts subagent classes from single, parallel, and ch
|
|
|
172
185
|
extractSubagentAgentClasses({ chain: [{ agent: 'reviewer' }, { agent: 'security' }] }),
|
|
173
186
|
['reviewer', 'security'],
|
|
174
187
|
);
|
|
188
|
+
assert.deepEqual(
|
|
189
|
+
extractSubagentAgentClasses({
|
|
190
|
+
chain: [
|
|
191
|
+
{ agent: 'scout' },
|
|
192
|
+
{ parallel: [{ agent: 'reviewer' }, { agent: ' security ' }] },
|
|
193
|
+
],
|
|
194
|
+
}),
|
|
195
|
+
['scout', 'reviewer', 'security'],
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('planning-dispatch: extracts subagent classes without recursing through cycles', () => {
|
|
200
|
+
const input: { agent: string; parallel?: unknown[] } = { agent: 'scout' };
|
|
201
|
+
input.parallel = [input, { agent: 'reviewer' }];
|
|
202
|
+
|
|
203
|
+
assert.deepEqual(extractSubagentAgentClasses(input), ['scout', 'reviewer']);
|
|
175
204
|
});
|
|
176
205
|
|
|
177
206
|
test('planning-dispatch: blocks subagent dispatch when agentClasses is undefined (stale caller shim)', () => {
|
|
@@ -315,6 +344,36 @@ test('all-mode: execute-task can dispatch subagents', () => {
|
|
|
315
344
|
assert.strictEqual(r.block, false);
|
|
316
345
|
});
|
|
317
346
|
|
|
347
|
+
// ─── verification mode: bash allowed, writes still scoped ─────────────────
|
|
348
|
+
|
|
349
|
+
test('verification-mode: run-uat can run build commands', () => {
|
|
350
|
+
const r = shouldBlockPlanningUnit('bash', 'npm run build 2>&1', BASE, 'run-uat', VERIFICATION);
|
|
351
|
+
assert.strictEqual(r.block, false);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
test('verification-mode: run-uat blocks destructive bash (rm -rf)', () => {
|
|
355
|
+
const r = shouldBlockPlanningUnit('bash', 'rm -rf dist', BASE, 'run-uat', VERIFICATION);
|
|
356
|
+
assert.strictEqual(r.block, true);
|
|
357
|
+
assert.match(r.reason!, /bash is restricted to build\/test verification commands/);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
test('verification-mode: run-uat allows read-only investigative bash (git status)', () => {
|
|
361
|
+
const r = shouldBlockPlanningUnit('bash', 'git status', BASE, 'run-uat', VERIFICATION);
|
|
362
|
+
assert.strictEqual(r.block, false);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test('verification-mode: run-uat still blocks user source edits', () => {
|
|
366
|
+
const r = shouldBlockPlanningUnit('edit', join(BASE, 'src', 'main.ts'), BASE, 'run-uat', VERIFICATION);
|
|
367
|
+
assert.strictEqual(r.block, true);
|
|
368
|
+
assert.match(r.reason!, /tools-policy "verification"/);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
test('verification-mode: run-uat still blocks subagent dispatch', () => {
|
|
372
|
+
const r = shouldBlockPlanningUnit('subagent', '', BASE, 'run-uat', VERIFICATION);
|
|
373
|
+
assert.strictEqual(r.block, true);
|
|
374
|
+
assert.match(r.reason!, /subagent dispatch is not permitted/);
|
|
375
|
+
});
|
|
376
|
+
|
|
318
377
|
// ─── read-only mode ───────────────────────────────────────────────────────
|
|
319
378
|
|
|
320
379
|
test('read-only: blocks any edit even to .gsd/', () => {
|