gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.2e8b124f7
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/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +110 -37
- package/dist/resources/extensions/gsd/auto/orchestrator.js +13 -2
- package/dist/resources/extensions/gsd/auto/phases.js +104 -38
- 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-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +71 -20
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +278 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +79 -14
- package/dist/resources/extensions/gsd/auto-start.js +90 -14
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +102 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +178 -11
- package/dist/resources/extensions/gsd/auto.js +107 -54
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +5 -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 +52 -7
- 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 +8 -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 +138 -10
- 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 +10 -0
- 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 +38 -11
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +138 -0
- package/dist/resources/extensions/gsd/preferences.js +2 -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/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/slice-parallel-orchestrator.js +59 -2
- 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 +14 -4
- package/dist/resources/extensions/gsd/status-guards.js +14 -2
- 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 +6 -8
- package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
- 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/workflow-tool-executors.js +119 -0
- 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 +83 -19
- package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
- package/dist/resources/extensions/gsd/worktree-safety.js +33 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -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/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 +10 -10
- 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 +10 -10
- 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 +71 -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 +75 -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 +17 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +111 -38
- package/src/resources/extensions/gsd/auto/orchestrator.ts +13 -2
- package/src/resources/extensions/gsd/auto/phases.ts +127 -49
- 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-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +74 -20
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +312 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +83 -11
- package/src/resources/extensions/gsd/auto-start.ts +99 -12
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +124 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +195 -11
- package/src/resources/extensions/gsd/auto.ts +100 -42
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +5 -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 +52 -6
- 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 +8 -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 +166 -11
- 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 +11 -0
- 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 +49 -11
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-types.ts +33 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +145 -0
- package/src/resources/extensions/gsd/preferences.ts +5 -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/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/slice-parallel-orchestrator.ts +52 -1
- 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 +15 -4
- package/src/resources/extensions/gsd/status-guards.ts +16 -2
- 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/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 +300 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +197 -11
- 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 +129 -6
- 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-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 +4 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -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/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/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 +199 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- 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/migrate-validator-parsers.test.ts +24 -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 +1 -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 +59 -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 +78 -0
- 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/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-switch-abort-misclassification.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +72 -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 +86 -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.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +173 -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 +1 -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 +57 -2
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -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 +8 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
- 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/workflow-tool-executors.ts +135 -0
- 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 +93 -20
- package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
- package/src/resources/extensions/gsd/worktree-safety.ts +45 -6
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -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/tests/interview-notes-loop.test.ts +15 -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 → zCegwxH2e6vLp1vEZLLuZ}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → zCegwxH2e6vLp1vEZLLuZ}/_ssgManifest.js +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import test, { mock } from "node:test";
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
|
-
import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
6
|
+
import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
|
|
@@ -30,6 +30,11 @@ import type { LoopDeps } from "../auto/loop-deps.js";
|
|
|
30
30
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
31
31
|
import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
|
|
32
32
|
import type { SessionLockStatus } from "../session-lock.js";
|
|
33
|
+
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask } from "../gsd-db.js";
|
|
34
|
+
import { registerAutoWorker } from "../db/auto-workers.js";
|
|
35
|
+
import { claimMilestoneLease } from "../db/milestone-leases.js";
|
|
36
|
+
import { recordDispatchClaim, markCanceled } from "../db/unit-dispatches.js";
|
|
37
|
+
import { setRuntimeKv, getRuntimeKv } from "../db/runtime-kv.js";
|
|
33
38
|
|
|
34
39
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
35
40
|
|
|
@@ -129,6 +134,8 @@ function makeMockPi() {
|
|
|
129
134
|
setModelCalls.push(args);
|
|
130
135
|
return true;
|
|
131
136
|
},
|
|
137
|
+
getThinkingLevel: () => "off",
|
|
138
|
+
setThinkingLevel: () => {},
|
|
132
139
|
calls,
|
|
133
140
|
setModelCalls,
|
|
134
141
|
} as any;
|
|
@@ -965,6 +972,79 @@ test("autoLoop exits on terminal complete state", async (t) => {
|
|
|
965
972
|
);
|
|
966
973
|
});
|
|
967
974
|
|
|
975
|
+
test("autoLoop persists stuck counter reset when dispatch recovery continues", async () => {
|
|
976
|
+
_resetPendingResolve();
|
|
977
|
+
|
|
978
|
+
const ctx = makeMockCtx();
|
|
979
|
+
const pi = makeMockPi();
|
|
980
|
+
const basePath = realpathSync(mkdtempSync(join(tmpdir(), "gsd-stuck-counter-reset-")));
|
|
981
|
+
mkdirSync(join(basePath, ".gsd"), { recursive: true });
|
|
982
|
+
mkdirSync(join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
983
|
+
writeFileSync(
|
|
984
|
+
join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"),
|
|
985
|
+
"# Slice Plan\n\n- [ ] **T01:** task one\n",
|
|
986
|
+
);
|
|
987
|
+
writeFileSync(
|
|
988
|
+
join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-PLAN.md"),
|
|
989
|
+
"# Task Plan\n",
|
|
990
|
+
);
|
|
991
|
+
|
|
992
|
+
try {
|
|
993
|
+
openDatabase(join(basePath, ".gsd", "gsd.db"));
|
|
994
|
+
insertMilestone({ id: "M001", title: "Test Milestone", status: "active" });
|
|
995
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Test Slice", status: "pending" });
|
|
996
|
+
insertTask({ id: "T01", milestoneId: "M001", sliceId: "S01", title: "Task One", status: "pending" });
|
|
997
|
+
const workerId = registerAutoWorker({ projectRootRealpath: basePath });
|
|
998
|
+
const lease = claimMilestoneLease(workerId, "M001");
|
|
999
|
+
assert.equal(lease.ok, true);
|
|
1000
|
+
if (!lease.ok) return;
|
|
1001
|
+
|
|
1002
|
+
for (let i = 0; i < 2; i++) {
|
|
1003
|
+
const claim = recordDispatchClaim({
|
|
1004
|
+
traceId: `stuck-${i}`,
|
|
1005
|
+
workerId,
|
|
1006
|
+
milestoneLeaseToken: lease.token,
|
|
1007
|
+
milestoneId: "M001",
|
|
1008
|
+
sliceId: "S01",
|
|
1009
|
+
unitType: "plan-slice",
|
|
1010
|
+
unitId: "M001/S01",
|
|
1011
|
+
});
|
|
1012
|
+
assert.equal(claim.ok, true);
|
|
1013
|
+
if (!claim.ok) return;
|
|
1014
|
+
markCanceled(claim.dispatchId, "seed stuck window");
|
|
1015
|
+
}
|
|
1016
|
+
setRuntimeKv("global", basePath, "stuck_recovery_attempts", 1);
|
|
1017
|
+
|
|
1018
|
+
const s = makeLoopSession({
|
|
1019
|
+
basePath,
|
|
1020
|
+
originalBasePath: basePath,
|
|
1021
|
+
canonicalProjectRoot: basePath,
|
|
1022
|
+
});
|
|
1023
|
+
const deps = makeMockDeps({
|
|
1024
|
+
resolveDispatch: async () => ({
|
|
1025
|
+
action: "dispatch" as const,
|
|
1026
|
+
unitType: "plan-slice",
|
|
1027
|
+
unitId: "M001/S01",
|
|
1028
|
+
prompt: "plan the slice",
|
|
1029
|
+
}),
|
|
1030
|
+
invalidateAllCaches: () => {
|
|
1031
|
+
s.active = false;
|
|
1032
|
+
},
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
await autoLoop(ctx, pi, s, deps);
|
|
1036
|
+
|
|
1037
|
+
assert.equal(
|
|
1038
|
+
getRuntimeKv<number>("global", basePath, "stuck_recovery_attempts"),
|
|
1039
|
+
0,
|
|
1040
|
+
"dispatch-level artifact recovery exits through continue, so the reset counter must still persist",
|
|
1041
|
+
);
|
|
1042
|
+
} finally {
|
|
1043
|
+
try { closeDatabase(); } catch { /* noop */ }
|
|
1044
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
1047
|
+
|
|
968
1048
|
test("autoLoop stops before success notification when postflight stash restore needs recovery", async () => {
|
|
969
1049
|
_resetPendingResolve();
|
|
970
1050
|
|
|
@@ -1401,6 +1481,81 @@ test("autoLoop calls deriveState → resolveDispatch → runUnit in sequence", a
|
|
|
1401
1481
|
);
|
|
1402
1482
|
});
|
|
1403
1483
|
|
|
1484
|
+
test("autoLoop dev path dispatches orchestration.advance results without legacy resolveDispatch", async () => {
|
|
1485
|
+
_resetPendingResolve();
|
|
1486
|
+
|
|
1487
|
+
const ctx = makeMockCtx();
|
|
1488
|
+
ctx.ui.setStatus = () => {};
|
|
1489
|
+
ctx.sessionManager = { getSessionFile: () => "/tmp/session.json" };
|
|
1490
|
+
const pi = makeMockPi();
|
|
1491
|
+
const stateSnapshot = {
|
|
1492
|
+
phase: "executing",
|
|
1493
|
+
activeMilestone: { id: "M002", title: "Advance Milestone", status: "active" },
|
|
1494
|
+
activeSlice: { id: "S03", title: "Slice 3" },
|
|
1495
|
+
activeTask: { id: "T05" },
|
|
1496
|
+
registry: [{ id: "M002", status: "active" }],
|
|
1497
|
+
blockers: [],
|
|
1498
|
+
} as any;
|
|
1499
|
+
let advanceCalls = 0;
|
|
1500
|
+
let s: any;
|
|
1501
|
+
s = makeLoopSession({
|
|
1502
|
+
currentMilestoneId: "M002",
|
|
1503
|
+
orchestration: {
|
|
1504
|
+
start: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1505
|
+
advance: async () => {
|
|
1506
|
+
advanceCalls++;
|
|
1507
|
+
s.pendingOrchestrationDispatch = {
|
|
1508
|
+
unitType: "execute-task",
|
|
1509
|
+
unitId: "M002/S03/T05",
|
|
1510
|
+
prompt: "advance prompt",
|
|
1511
|
+
pauseAfterUatDispatch: false,
|
|
1512
|
+
state: stateSnapshot,
|
|
1513
|
+
mid: "M002",
|
|
1514
|
+
midTitle: "Advance Milestone",
|
|
1515
|
+
};
|
|
1516
|
+
return {
|
|
1517
|
+
kind: "advanced" as const,
|
|
1518
|
+
unit: { unitType: "execute-task", unitId: "M002/S03/T05" },
|
|
1519
|
+
stateSnapshot,
|
|
1520
|
+
};
|
|
1521
|
+
},
|
|
1522
|
+
resume: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1523
|
+
stop: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1524
|
+
getStatus: () => ({ phase: "running" as const, transitionCount: 1 }),
|
|
1525
|
+
},
|
|
1526
|
+
});
|
|
1527
|
+
|
|
1528
|
+
const deps = makeMockDeps({
|
|
1529
|
+
resolveDispatch: async () => {
|
|
1530
|
+
deps.callLog.push("resolveDispatch");
|
|
1531
|
+
throw new Error("legacy resolveDispatch must not run when orchestration is wired");
|
|
1532
|
+
},
|
|
1533
|
+
postUnitPostVerification: async () => {
|
|
1534
|
+
deps.callLog.push("postUnitPostVerification");
|
|
1535
|
+
s.active = false;
|
|
1536
|
+
return "continue" as const;
|
|
1537
|
+
},
|
|
1538
|
+
});
|
|
1539
|
+
|
|
1540
|
+
const loopPromise = autoLoop(ctx, pi, s, deps);
|
|
1541
|
+
await waitForMicrotasks(() => pi.calls.length === 1, "orchestration advance dispatch");
|
|
1542
|
+
resolveAgentEnd(makeEvent());
|
|
1543
|
+
await loopPromise;
|
|
1544
|
+
|
|
1545
|
+
assert.equal(advanceCalls, 1);
|
|
1546
|
+
assert.equal(
|
|
1547
|
+
deps.callLog.includes("resolveDispatch"),
|
|
1548
|
+
false,
|
|
1549
|
+
"orchestration.advance owns dev-path dispatch",
|
|
1550
|
+
);
|
|
1551
|
+
assert.equal(
|
|
1552
|
+
(pi.calls[0] as any[])[0].content,
|
|
1553
|
+
"advance prompt",
|
|
1554
|
+
"runUnit should receive the dispatch prompt captured by advance()",
|
|
1555
|
+
);
|
|
1556
|
+
assert.equal(s.pendingOrchestrationDispatch, null, "pending dispatch should be one-shot");
|
|
1557
|
+
});
|
|
1558
|
+
|
|
1404
1559
|
test("autoLoop journals post-unit finalize stop after completed unit", async () => {
|
|
1405
1560
|
_resetPendingResolve();
|
|
1406
1561
|
|
|
@@ -2725,6 +2880,89 @@ test("runUnitPhase pauses ghost completions before closeout and finalize side ef
|
|
|
2725
2880
|
);
|
|
2726
2881
|
});
|
|
2727
2882
|
|
|
2883
|
+
test("runUnitPhase records failed routing outcome when expected artifact is missing", async (t) => {
|
|
2884
|
+
_resetPendingResolve();
|
|
2885
|
+
|
|
2886
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-routing-artifact-missing-"));
|
|
2887
|
+
t.after(() => {
|
|
2888
|
+
_resetPendingResolve();
|
|
2889
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
2890
|
+
});
|
|
2891
|
+
|
|
2892
|
+
const recordedOutcomes: Array<{ unitType: string; tier: string; success: boolean }> = [];
|
|
2893
|
+
const deps = makeMockDeps({
|
|
2894
|
+
selectAndApplyModel: async () => ({
|
|
2895
|
+
routing: { tier: "light" } as any,
|
|
2896
|
+
appliedModel: null,
|
|
2897
|
+
}),
|
|
2898
|
+
recordOutcome: (unitType: string, tier: string, success: boolean) => {
|
|
2899
|
+
recordedOutcomes.push({ unitType, tier, success });
|
|
2900
|
+
},
|
|
2901
|
+
});
|
|
2902
|
+
const ctx = {
|
|
2903
|
+
...makeMockCtx(),
|
|
2904
|
+
ui: {
|
|
2905
|
+
notify: () => {},
|
|
2906
|
+
setStatus: () => {},
|
|
2907
|
+
setWorkingMessage: () => {},
|
|
2908
|
+
},
|
|
2909
|
+
sessionManager: {
|
|
2910
|
+
getEntries: () => [],
|
|
2911
|
+
},
|
|
2912
|
+
modelRegistry: {
|
|
2913
|
+
getProviderAuthMode: () => undefined,
|
|
2914
|
+
isProviderRequestReady: () => true,
|
|
2915
|
+
},
|
|
2916
|
+
} as any;
|
|
2917
|
+
const pi = {
|
|
2918
|
+
...makeMockPi(),
|
|
2919
|
+
sendMessage: () => {
|
|
2920
|
+
queueMicrotask(() => resolveAgentEnd({ messages: [{ role: "assistant" }] }));
|
|
2921
|
+
},
|
|
2922
|
+
} as any;
|
|
2923
|
+
const s = makeLoopSession({
|
|
2924
|
+
basePath,
|
|
2925
|
+
canonicalProjectRoot: basePath,
|
|
2926
|
+
originalBasePath: basePath,
|
|
2927
|
+
});
|
|
2928
|
+
let seq = 0;
|
|
2929
|
+
|
|
2930
|
+
const result = await runUnitPhase(
|
|
2931
|
+
{ ctx, pi, s, deps, prefs: undefined, iteration: 1, flowId: "flow-routing-outcome", nextSeq: () => ++seq },
|
|
2932
|
+
{
|
|
2933
|
+
unitType: "execute-task",
|
|
2934
|
+
unitId: "M001/S01/T01",
|
|
2935
|
+
prompt: "do work",
|
|
2936
|
+
finalPrompt: "do work",
|
|
2937
|
+
pauseAfterUatDispatch: false,
|
|
2938
|
+
state: {
|
|
2939
|
+
phase: "executing",
|
|
2940
|
+
activeMilestone: { id: "M001", title: "Milestone" },
|
|
2941
|
+
activeSlice: { id: "S01", title: "Slice" },
|
|
2942
|
+
activeTask: { id: "T01", title: "Task" },
|
|
2943
|
+
registry: [{ id: "M001", title: "Milestone", status: "active" }],
|
|
2944
|
+
recentDecisions: [],
|
|
2945
|
+
blockers: [],
|
|
2946
|
+
nextAction: "",
|
|
2947
|
+
progress: { milestones: { done: 0, total: 1 } },
|
|
2948
|
+
requirements: { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 },
|
|
2949
|
+
} as any,
|
|
2950
|
+
mid: "M001",
|
|
2951
|
+
midTitle: "Milestone",
|
|
2952
|
+
isRetry: false,
|
|
2953
|
+
previousTier: undefined,
|
|
2954
|
+
},
|
|
2955
|
+
{ recentUnits: [], stuckRecoveryAttempts: 0, consecutiveFinalizeTimeouts: 0 },
|
|
2956
|
+
);
|
|
2957
|
+
|
|
2958
|
+
assert.equal(result.action, "next");
|
|
2959
|
+
assert.deepEqual(
|
|
2960
|
+
recordedOutcomes,
|
|
2961
|
+
[{ unitType: "execute-task", tier: "light", success: false }],
|
|
2962
|
+
"routing history must treat missing artifacts as failed outcomes so retries can escalate",
|
|
2963
|
+
);
|
|
2964
|
+
});
|
|
2965
|
+
|
|
2728
2966
|
test("resolveAgentEndCancelled without args produces no errorContext field", async () => {
|
|
2729
2967
|
_resetPendingResolve();
|
|
2730
2968
|
|
|
@@ -2785,6 +3023,7 @@ test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)",
|
|
|
2785
3023
|
const s = makeLoopSession();
|
|
2786
3024
|
|
|
2787
3025
|
let preVerifyCallCount = 0;
|
|
3026
|
+
const currentUnitSnapshotsAtPreVerify: Array<{ type: string; id: string; startedAt: number } | null> = [];
|
|
2788
3027
|
// Pre-queued responses: first call returns "retry", second returns "continue"
|
|
2789
3028
|
const preVerifyResponses = ["retry", "continue"] as const;
|
|
2790
3029
|
|
|
@@ -2802,6 +3041,7 @@ test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)",
|
|
|
2802
3041
|
},
|
|
2803
3042
|
postUnitPreVerification: async () => {
|
|
2804
3043
|
deps.callLog.push("postUnitPreVerification");
|
|
3044
|
+
currentUnitSnapshotsAtPreVerify.push(s.currentUnit);
|
|
2805
3045
|
const response = preVerifyResponses[preVerifyCallCount++] ?? "continue";
|
|
2806
3046
|
if (response === "retry") {
|
|
2807
3047
|
s.pendingVerificationRetry = {
|
|
@@ -2832,6 +3072,11 @@ test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)",
|
|
|
2832
3072
|
await loopPromise;
|
|
2833
3073
|
|
|
2834
3074
|
assert.equal(preVerifyCallCount, 2, "preVerification should be called twice");
|
|
3075
|
+
assert.deepEqual(
|
|
3076
|
+
currentUnitSnapshotsAtPreVerify,
|
|
3077
|
+
[null, null],
|
|
3078
|
+
"currentUnit should be cleared before each preVerification run to prevent stale retry scope",
|
|
3079
|
+
);
|
|
2835
3080
|
|
|
2836
3081
|
const postVerifyCalls = deps.callLog.filter(
|
|
2837
3082
|
(c: string) => c === "runPostUnitVerification",
|
|
@@ -3353,6 +3598,60 @@ test("runDispatch runs stuck detection while artifact verification retry is pend
|
|
|
3353
3598
|
);
|
|
3354
3599
|
});
|
|
3355
3600
|
|
|
3601
|
+
test("runDispatch falls back to main when dispatch guard cannot read main branch (#5530)", async (t) => {
|
|
3602
|
+
_resetPendingResolve();
|
|
3603
|
+
|
|
3604
|
+
const ctx = makeMockCtx();
|
|
3605
|
+
const pi = makeMockPi();
|
|
3606
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-5530-main-branch-fallback-"));
|
|
3607
|
+
t.after(() => rmSync(basePath, { recursive: true, force: true }));
|
|
3608
|
+
|
|
3609
|
+
let guardBranch: string | null = null;
|
|
3610
|
+
const s = makeLoopSession({ basePath });
|
|
3611
|
+
const deps = makeMockDeps({
|
|
3612
|
+
getMainBranch: () => {
|
|
3613
|
+
throw new Error("fatal: detected dubious ownership");
|
|
3614
|
+
},
|
|
3615
|
+
getPriorSliceCompletionBlocker: (_basePath, mainBranch) => {
|
|
3616
|
+
guardBranch = mainBranch;
|
|
3617
|
+
return null;
|
|
3618
|
+
},
|
|
3619
|
+
});
|
|
3620
|
+
|
|
3621
|
+
const result = await runDispatch(
|
|
3622
|
+
{
|
|
3623
|
+
ctx,
|
|
3624
|
+
pi,
|
|
3625
|
+
s,
|
|
3626
|
+
deps,
|
|
3627
|
+
prefs: undefined,
|
|
3628
|
+
iteration: 1,
|
|
3629
|
+
flowId: "test-flow",
|
|
3630
|
+
nextSeq: () => 1,
|
|
3631
|
+
},
|
|
3632
|
+
{
|
|
3633
|
+
state: {
|
|
3634
|
+
phase: "executing",
|
|
3635
|
+
activeMilestone: { id: "M001", title: "Test", status: "active" },
|
|
3636
|
+
activeSlice: { id: "S01", title: "Slice 1" },
|
|
3637
|
+
activeTask: { id: "T01" },
|
|
3638
|
+
registry: [{ id: "M001", status: "active" }],
|
|
3639
|
+
blockers: [],
|
|
3640
|
+
} as any,
|
|
3641
|
+
mid: "M001",
|
|
3642
|
+
midTitle: "Test",
|
|
3643
|
+
},
|
|
3644
|
+
{
|
|
3645
|
+
recentUnits: [],
|
|
3646
|
+
stuckRecoveryAttempts: 0,
|
|
3647
|
+
consecutiveFinalizeTimeouts: 0,
|
|
3648
|
+
},
|
|
3649
|
+
);
|
|
3650
|
+
|
|
3651
|
+
assert.equal(guardBranch, "main");
|
|
3652
|
+
assert.equal(result.action, "next");
|
|
3653
|
+
});
|
|
3654
|
+
|
|
3356
3655
|
test("dispatch Worktree Safety stops unknown unit types with missing Tool Contract", async (t) => {
|
|
3357
3656
|
_resetPendingResolve();
|
|
3358
3657
|
|
|
@@ -13,6 +13,12 @@ import { RuleRegistry, setRegistry, resetRegistry } from "../rule-registry.js";
|
|
|
13
13
|
import type { UnifiedRule } from "../rule-types.js";
|
|
14
14
|
import { supportsStructuredQuestions } from "../workflow-mcp.js";
|
|
15
15
|
|
|
16
|
+
function assertBlockedResult(
|
|
17
|
+
result: Awaited<ReturnType<ReturnType<typeof createAutoOrchestrator>["advance"]>>,
|
|
18
|
+
): asserts result is Extract<typeof result, { kind: "blocked" }> {
|
|
19
|
+
assert.equal(result.kind, "blocked");
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
function makeState(): GSDState {
|
|
17
23
|
return {
|
|
18
24
|
activeMilestone: { id: "M001", title: "Milestone" },
|
|
@@ -119,13 +125,13 @@ test("advance() returns blocked when health gate denies", async () => {
|
|
|
119
125
|
|
|
120
126
|
const result = await orchestrator.advance();
|
|
121
127
|
|
|
122
|
-
|
|
128
|
+
assertBlockedResult(result);
|
|
123
129
|
assert.equal(result.reason, "doctor-block");
|
|
124
130
|
assert.equal(result.action, "pause");
|
|
125
131
|
assert.ok(calls.includes("gate:pre-dispatch-health-gate:manual-attention"));
|
|
126
132
|
});
|
|
127
133
|
|
|
128
|
-
test("advance() returns blocked
|
|
134
|
+
test("advance() returns blocked pause when resources are stale", async () => {
|
|
129
135
|
const { deps, calls } = makeDeps({
|
|
130
136
|
health: {
|
|
131
137
|
checkResourcesStale: () => "resources changed since session start",
|
|
@@ -137,14 +143,89 @@ test("advance() returns blocked stop when resources are stale", async () => {
|
|
|
137
143
|
|
|
138
144
|
const result = await orchestrator.advance();
|
|
139
145
|
|
|
140
|
-
|
|
146
|
+
assertBlockedResult(result);
|
|
141
147
|
assert.equal(result.reason, "resources changed since session start");
|
|
142
|
-
assert.equal(result.action, "
|
|
148
|
+
assert.equal(result.action, "pause");
|
|
143
149
|
assert.ok(calls.includes("gate:resource-version-guard:fail"));
|
|
144
150
|
assert.ok(!calls.includes("health.pre"));
|
|
145
151
|
assert.ok(!calls.includes("state.reconcile"));
|
|
146
152
|
});
|
|
147
153
|
|
|
154
|
+
test("advance() pre-dispatch parity: gate emissions and control-flow action match legacy branches", async () => {
|
|
155
|
+
type Scenario = {
|
|
156
|
+
name: string;
|
|
157
|
+
staleMsg: string | null;
|
|
158
|
+
gateResult: Awaited<ReturnType<AutoOrchestratorDeps["health"]["preAdvanceGate"]>>;
|
|
159
|
+
expectedKind: "advanced" | "blocked";
|
|
160
|
+
expectedAction?: "pause" | "stop";
|
|
161
|
+
expectedReason?: string;
|
|
162
|
+
expectedGates: string[];
|
|
163
|
+
};
|
|
164
|
+
const scenarios: Scenario[] = [
|
|
165
|
+
{
|
|
166
|
+
name: "pass",
|
|
167
|
+
staleMsg: null,
|
|
168
|
+
gateResult: { kind: "pass" },
|
|
169
|
+
expectedKind: "advanced",
|
|
170
|
+
expectedGates: [
|
|
171
|
+
"resource-version-guard:policy:pass:none:resource version guard passed:",
|
|
172
|
+
"pre-dispatch-health-gate:execution:pass:none:pre-dispatch health gate passed:",
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "resource-stale",
|
|
177
|
+
staleMsg: "resources changed since session start",
|
|
178
|
+
gateResult: { kind: "pass" },
|
|
179
|
+
expectedKind: "blocked",
|
|
180
|
+
expectedAction: "pause",
|
|
181
|
+
expectedReason: "resources changed since session start",
|
|
182
|
+
expectedGates: [
|
|
183
|
+
"resource-version-guard:policy:fail:policy:resource version guard blocked dispatch:resources changed since session start",
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "health-gate-fail",
|
|
188
|
+
staleMsg: null,
|
|
189
|
+
gateResult: { kind: "fail", reason: "doctor-block" },
|
|
190
|
+
expectedKind: "blocked",
|
|
191
|
+
expectedAction: "pause",
|
|
192
|
+
expectedReason: "doctor-block",
|
|
193
|
+
expectedGates: [
|
|
194
|
+
"resource-version-guard:policy:pass:none:resource version guard passed:",
|
|
195
|
+
"pre-dispatch-health-gate:execution:manual-attention:manual-attention:pre-dispatch health gate blocked dispatch:doctor-block",
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
|
|
200
|
+
for (const scenario of scenarios) {
|
|
201
|
+
const gateEvents: string[] = [];
|
|
202
|
+
const { deps } = makeDeps({
|
|
203
|
+
health: {
|
|
204
|
+
checkResourcesStale: () => scenario.staleMsg,
|
|
205
|
+
async preAdvanceGate() { return scenario.gateResult; },
|
|
206
|
+
async postAdvanceRecord() {},
|
|
207
|
+
},
|
|
208
|
+
uokGate: {
|
|
209
|
+
async emit(input) {
|
|
210
|
+
gateEvents.push(
|
|
211
|
+
`${input.gateId}:${input.gateType}:${input.outcome}:${input.failureClass}:${input.rationale}:${input.findings ?? ""}`,
|
|
212
|
+
);
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
217
|
+
const result = await orchestrator.advance();
|
|
218
|
+
|
|
219
|
+
assert.equal(result.kind, scenario.expectedKind, `${scenario.name} result kind`);
|
|
220
|
+
if (scenario.expectedKind === "blocked") {
|
|
221
|
+
assertBlockedResult(result);
|
|
222
|
+
assert.equal(result.action, scenario.expectedAction, `${scenario.name} blocked action`);
|
|
223
|
+
assert.equal(result.reason, scenario.expectedReason, `${scenario.name} blocked reason`);
|
|
224
|
+
}
|
|
225
|
+
assert.deepEqual(gateEvents, scenario.expectedGates, `${scenario.name} gate parity`);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
148
229
|
test("advance() continues past pre-dispatch health gate when it throws", async () => {
|
|
149
230
|
const { deps, calls } = makeDeps({
|
|
150
231
|
health: {
|
|
@@ -223,7 +304,7 @@ test("advance() blocks before dispatch when State Reconciliation blocks", async
|
|
|
223
304
|
|
|
224
305
|
const result = await orchestrator.advance();
|
|
225
306
|
|
|
226
|
-
|
|
307
|
+
assertBlockedResult(result);
|
|
227
308
|
assert.equal(result.reason, "state drift blocked");
|
|
228
309
|
assert.equal(result.action, "pause");
|
|
229
310
|
assert.ok(!calls.includes("dispatch.decide"));
|
|
@@ -243,7 +324,7 @@ test("advance() blocks before Runtime persistence when Tool Contract fails", asy
|
|
|
243
324
|
|
|
244
325
|
const result = await orchestrator.advance();
|
|
245
326
|
|
|
246
|
-
|
|
327
|
+
assertBlockedResult(result);
|
|
247
328
|
assert.equal(result.reason, "unknown Unit");
|
|
248
329
|
assert.equal(result.action, "pause");
|
|
249
330
|
assert.ok(!calls.includes("worktree.prepare"));
|
|
@@ -266,7 +347,7 @@ test("advance() blocks before Runtime persistence when Worktree Safety fails", a
|
|
|
266
347
|
|
|
267
348
|
const result = await orchestrator.advance();
|
|
268
349
|
|
|
269
|
-
|
|
350
|
+
assertBlockedResult(result);
|
|
270
351
|
assert.equal(result.reason, "worktree invalid");
|
|
271
352
|
assert.equal(result.action, "pause");
|
|
272
353
|
assert.ok(!calls.includes("journal:advance"));
|
|
@@ -274,6 +355,26 @@ test("advance() blocks before Runtime persistence when Worktree Safety fails", a
|
|
|
274
355
|
assert.ok(calls.includes("journal:advance-blocked"));
|
|
275
356
|
});
|
|
276
357
|
|
|
358
|
+
test("advance() allows non-worktree isolation prepare result", async () => {
|
|
359
|
+
const { deps, calls } = makeDeps({
|
|
360
|
+
worktree: {
|
|
361
|
+
async prepareForUnit() {
|
|
362
|
+
calls.push("worktree.prepare");
|
|
363
|
+
return { ok: true, reason: "isolation-not-worktree" };
|
|
364
|
+
},
|
|
365
|
+
async syncAfterUnit() { calls.push("worktree.sync"); },
|
|
366
|
+
async cleanupOnStop() { calls.push("worktree.cleanup"); },
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
370
|
+
|
|
371
|
+
const result = await orchestrator.advance();
|
|
372
|
+
|
|
373
|
+
assert.equal(result.kind, "advanced");
|
|
374
|
+
assert.ok(calls.includes("journal:advance"));
|
|
375
|
+
assert.ok(calls.includes("worktree.sync"));
|
|
376
|
+
});
|
|
377
|
+
|
|
277
378
|
test("advance() stops when dispatch has no next unit", async () => {
|
|
278
379
|
const { deps } = makeDeps({
|
|
279
380
|
dispatch: {
|
|
@@ -288,6 +389,52 @@ test("advance() stops when dispatch has no next unit", async () => {
|
|
|
288
389
|
assert.equal(orchestrator.getStatus().phase, "stopped");
|
|
289
390
|
});
|
|
290
391
|
|
|
392
|
+
test("advance() surfaces dispatch blocker reason instead of generic no remaining units", async () => {
|
|
393
|
+
const { deps, calls } = makeDeps({
|
|
394
|
+
dispatch: {
|
|
395
|
+
async decideNextUnit() {
|
|
396
|
+
return {
|
|
397
|
+
kind: "blocked",
|
|
398
|
+
reason: "Milestone M001 validation verdict is needs-remediation but all slices are complete.",
|
|
399
|
+
action: "pause",
|
|
400
|
+
};
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
405
|
+
|
|
406
|
+
const result = await orchestrator.advance();
|
|
407
|
+
|
|
408
|
+
assert.equal(result.kind, "blocked");
|
|
409
|
+
if (result.kind !== "blocked") return;
|
|
410
|
+
assert.equal(result.reason, "Milestone M001 validation verdict is needs-remediation but all slices are complete.");
|
|
411
|
+
assert.equal(result.action, "pause");
|
|
412
|
+
assert.ok(calls.includes("journal:advance-blocked"));
|
|
413
|
+
assert.ok(!calls.includes("journal:advance-stopped"));
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test("resume() returns blocked when advance detects a dispatch blocker", async () => {
|
|
417
|
+
const { deps } = makeDeps({
|
|
418
|
+
dispatch: {
|
|
419
|
+
async decideNextUnit() {
|
|
420
|
+
return {
|
|
421
|
+
kind: "blocked",
|
|
422
|
+
reason: "remediation required",
|
|
423
|
+
action: "pause",
|
|
424
|
+
};
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
429
|
+
|
|
430
|
+
const result = await orchestrator.resume();
|
|
431
|
+
|
|
432
|
+
assert.equal(result.kind, "blocked");
|
|
433
|
+
if (result.kind !== "blocked") return;
|
|
434
|
+
assert.equal(result.reason, "remediation required");
|
|
435
|
+
assert.equal(result.action, "pause");
|
|
436
|
+
});
|
|
437
|
+
|
|
291
438
|
test("advance() uses recovery on error", async () => {
|
|
292
439
|
const { deps, calls } = makeDeps({
|
|
293
440
|
runtime: {
|
|
@@ -319,7 +466,7 @@ test("advance() is idempotent for the same active unit", async () => {
|
|
|
319
466
|
assert.deepEqual(first.unit, { unitType: "execute-task", unitId: "T01" });
|
|
320
467
|
assert.equal(second.kind, "blocked");
|
|
321
468
|
assert.equal(second.reason, "idempotent advance: unit already active");
|
|
322
|
-
assert.equal(second.action, "
|
|
469
|
+
assert.equal(second.action, "pause");
|
|
323
470
|
|
|
324
471
|
const prepareCalls = calls.filter((c) => c === "worktree.prepare").length;
|
|
325
472
|
assert.equal(prepareCalls, 1);
|
|
@@ -614,7 +761,7 @@ test("stuck-loop: ring saturated with same unit blocks with action 'stop' and st
|
|
|
614
761
|
assert.equal(r.kind, "blocked", `round ${i} should be blocked`);
|
|
615
762
|
if (r.kind !== "blocked") return;
|
|
616
763
|
assert.equal(r.reason, "idempotent advance: unit already active");
|
|
617
|
-
assert.equal(r.action, "
|
|
764
|
+
assert.equal(r.action, "pause");
|
|
618
765
|
}
|
|
619
766
|
|
|
620
767
|
// The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop.
|
|
@@ -637,7 +784,7 @@ test("stuck-loop: idempotency block continues to fire with its own reason before
|
|
|
637
784
|
assert.equal(first.kind, "advanced");
|
|
638
785
|
assert.equal(second.kind, "blocked");
|
|
639
786
|
assert.equal(second.reason, "idempotent advance: unit already active");
|
|
640
|
-
assert.equal(second.action, "
|
|
787
|
+
assert.equal(second.action, "pause");
|
|
641
788
|
});
|
|
642
789
|
|
|
643
790
|
test("stuck-loop: start() resets the ring so a fresh saturation cycle is required", async () => {
|
|
@@ -658,6 +805,7 @@ test("stuck-loop: start() resets the ring so a fresh saturation cycle is require
|
|
|
658
805
|
const next = await orchestrator.advance();
|
|
659
806
|
assert.equal(next.kind, "blocked");
|
|
660
807
|
assert.equal(next.reason, "idempotent advance: unit already active");
|
|
808
|
+
assert.equal(next.action, "pause");
|
|
661
809
|
});
|
|
662
810
|
|
|
663
811
|
test("stuck-loop: resume() resets the ring", async () => {
|
|
@@ -674,6 +822,7 @@ test("stuck-loop: resume() resets the ring", async () => {
|
|
|
674
822
|
const next = await orchestrator.advance();
|
|
675
823
|
assert.equal(next.kind, "blocked");
|
|
676
824
|
assert.equal(next.reason, "idempotent advance: unit already active");
|
|
825
|
+
assert.equal(next.action, "pause");
|
|
677
826
|
});
|
|
678
827
|
|
|
679
828
|
test("stuck-loop: stop() resets the ring", async () => {
|
|
@@ -797,7 +946,9 @@ test("wired DispatchAdapter forwards session-derived dispatch inputs identically
|
|
|
797
946
|
assert.equal(adapterCtx.midTitle, directCtx.midTitle);
|
|
798
947
|
|
|
799
948
|
// Dispatch action equality: both flows reach the same dispatch decision.
|
|
800
|
-
|
|
949
|
+
if (!adapterResult || !("unitType" in adapterResult)) {
|
|
950
|
+
assert.fail("expected adapter result to be a dispatch decision");
|
|
951
|
+
}
|
|
801
952
|
assert.equal(adapterResult.unitType, "execute-task");
|
|
802
953
|
assert.equal(adapterResult.unitId, "T01");
|
|
803
954
|
assert.equal(adapterResult.reason, "test-capture");
|
|
@@ -853,9 +1004,11 @@ test("wired DispatchAdapter prefers caller-supplied dispatch inputs over ctx-der
|
|
|
853
1004
|
getActiveTools: () => [],
|
|
854
1005
|
} as any;
|
|
855
1006
|
const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
|
|
1007
|
+
const session = { basePath: "/tmp/session-fixture" } as any;
|
|
856
1008
|
|
|
857
1009
|
const result = await adapter.decideNextUnit({
|
|
858
1010
|
stateSnapshot,
|
|
1011
|
+
session,
|
|
859
1012
|
structuredQuestionsAvailable: "true",
|
|
860
1013
|
sessionContextWindow: 500_000,
|
|
861
1014
|
sessionProvider: "openai",
|
|
@@ -868,6 +1021,39 @@ test("wired DispatchAdapter prefers caller-supplied dispatch inputs over ctx-der
|
|
|
868
1021
|
assert.equal(captured[0].sessionContextWindow, 500_000);
|
|
869
1022
|
assert.equal(captured[0].sessionProvider, "openai");
|
|
870
1023
|
assert.equal(captured[0].modelRegistry, overrideModelRegistry);
|
|
1024
|
+
assert.equal(captured[0].session, session);
|
|
1025
|
+
} finally {
|
|
1026
|
+
resetRegistry();
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
test("wired DispatchAdapter preserves stop reason as a blocked decision", async () => {
|
|
1031
|
+
const stateSnapshot = makeState();
|
|
1032
|
+
const stopRule: UnifiedRule = {
|
|
1033
|
+
name: "test-stop",
|
|
1034
|
+
when: "dispatch",
|
|
1035
|
+
evaluation: "first-match",
|
|
1036
|
+
where: async () => ({
|
|
1037
|
+
action: "stop" as const,
|
|
1038
|
+
reason: "remediation blocker",
|
|
1039
|
+
level: "warning" as const,
|
|
1040
|
+
}),
|
|
1041
|
+
then: (r: unknown) => r,
|
|
1042
|
+
};
|
|
1043
|
+
setRegistry(new RuleRegistry([stopRule]));
|
|
1044
|
+
|
|
1045
|
+
try {
|
|
1046
|
+
const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as any;
|
|
1047
|
+
const pi = { getActiveTools: () => [] } as any;
|
|
1048
|
+
const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
|
|
1049
|
+
|
|
1050
|
+
const result = await adapter.decideNextUnit({ stateSnapshot });
|
|
1051
|
+
|
|
1052
|
+
assert.deepEqual(result, {
|
|
1053
|
+
kind: "blocked",
|
|
1054
|
+
reason: "remediation blocker",
|
|
1055
|
+
action: "pause",
|
|
1056
|
+
});
|
|
871
1057
|
} finally {
|
|
872
1058
|
resetRegistry();
|
|
873
1059
|
}
|