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
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// File Purpose: Git service integration and commit-message tests.
|
|
3
3
|
import { describe, test } from 'node:test';
|
|
4
4
|
import assert from 'node:assert/strict';
|
|
5
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, symlinkSync, readFileSync } from "node:fs";
|
|
5
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, symlinkSync, readFileSync, chmodSync } from "node:fs";
|
|
6
6
|
import { join, dirname } from "node:path";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
|
-
import { execSync } from "node:child_process";
|
|
8
|
+
import { execFileSync, execSync } from "node:child_process";
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
inferCommitType,
|
|
@@ -371,6 +371,18 @@ describe('git-service', async () => {
|
|
|
371
371
|
return dir;
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
function gitRun(args: string[], cwd: string): string {
|
|
375
|
+
return execFileSync("git", args, {
|
|
376
|
+
cwd,
|
|
377
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
378
|
+
encoding: "utf-8",
|
|
379
|
+
env: {
|
|
380
|
+
...process.env,
|
|
381
|
+
GIT_ALLOW_PROTOCOL: "file",
|
|
382
|
+
},
|
|
383
|
+
}).trim();
|
|
384
|
+
}
|
|
385
|
+
|
|
374
386
|
// ─── GitServiceImpl: smart staging ─────────────────────────────────────
|
|
375
387
|
|
|
376
388
|
test('GitServiceImpl: smart staging', () => {
|
|
@@ -413,6 +425,96 @@ describe('git-service', async () => {
|
|
|
413
425
|
rmSync(repo, { recursive: true, force: true });
|
|
414
426
|
});
|
|
415
427
|
|
|
428
|
+
test('GitServiceImpl: task autoCommit skips keyFiles inside submodules', () => {
|
|
429
|
+
const repo = initTempRepo();
|
|
430
|
+
const subSrc = mkdtempSync(join(tmpdir(), "gsd-git-submodule-src-"));
|
|
431
|
+
|
|
432
|
+
try {
|
|
433
|
+
gitRun(["init", "-b", "main"], subSrc);
|
|
434
|
+
gitRun(["config", "user.name", "Pi Test"], subSrc);
|
|
435
|
+
gitRun(["config", "user.email", "pi@example.com"], subSrc);
|
|
436
|
+
createFile(subSrc, "tracked.txt", "initial\n");
|
|
437
|
+
gitRun(["add", "-A"], subSrc);
|
|
438
|
+
gitRun(["commit", "-m", "init submodule"], subSrc);
|
|
439
|
+
|
|
440
|
+
gitRun(["-c", "protocol.file.allow=always", "submodule", "add", `file://${subSrc}`, "sub"], repo);
|
|
441
|
+
gitRun(["commit", "-m", "add submodule"], repo);
|
|
442
|
+
|
|
443
|
+
createFile(repo, "sub/copied.txt", "copied from source\n");
|
|
444
|
+
createFile(repo, "src/feature.ts", "export const feature = true;\n");
|
|
445
|
+
createFile(repo, "src/unrelated.ts", "export const unrelated = true;\n");
|
|
446
|
+
|
|
447
|
+
const svc = new GitServiceImpl(repo);
|
|
448
|
+
const taskContext: TaskCommitContext = {
|
|
449
|
+
taskId: "S01/T01",
|
|
450
|
+
taskDisplayId: "T01",
|
|
451
|
+
taskTitle: "fix submodule staging",
|
|
452
|
+
milestoneId: "M001",
|
|
453
|
+
milestoneTitle: "Submodule auto commit",
|
|
454
|
+
sliceId: "S01",
|
|
455
|
+
sliceTitle: "Commit scoped files",
|
|
456
|
+
oneLiner: "Fixed auto commit when key files include submodule paths",
|
|
457
|
+
keyFiles: ["sub/copied.txt", "src/feature.ts"],
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
const result = svc.autoCommit("execute-task", "M001/S01/T01", [], taskContext);
|
|
461
|
+
|
|
462
|
+
assert.ok(result !== null, "autoCommit should commit non-submodule changes");
|
|
463
|
+
const committed = gitRun(["show", "--name-only", "--format=", "HEAD"], repo);
|
|
464
|
+
assert.ok(committed.includes("src/feature.ts"), "non-submodule keyFile is committed");
|
|
465
|
+
assert.ok(!committed.includes("sub/copied.txt"), "submodule inner keyFile is not pathspec-staged");
|
|
466
|
+
assert.ok(!committed.includes("src/unrelated.ts"), "scoped staging does not fall back to smartStage");
|
|
467
|
+
} finally {
|
|
468
|
+
rmSync(repo, { recursive: true, force: true });
|
|
469
|
+
rmSync(subSrc, { recursive: true, force: true });
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test('GitServiceImpl: all keyFiles inside submodules falls back to smartStage', () => {
|
|
474
|
+
const repo = initTempRepo();
|
|
475
|
+
const subSrc = mkdtempSync(join(tmpdir(), "gsd-git-all-submodule-src-"));
|
|
476
|
+
|
|
477
|
+
try {
|
|
478
|
+
gitRun(["init", "-b", "main"], subSrc);
|
|
479
|
+
gitRun(["config", "user.name", "Pi Test"], subSrc);
|
|
480
|
+
gitRun(["config", "user.email", "pi@example.com"], subSrc);
|
|
481
|
+
createFile(subSrc, "tracked.txt", "initial\n");
|
|
482
|
+
gitRun(["add", "-A"], subSrc);
|
|
483
|
+
gitRun(["commit", "-m", "init submodule"], subSrc);
|
|
484
|
+
|
|
485
|
+
gitRun(["-c", "protocol.file.allow=always", "submodule", "add", `file://${subSrc}`, "sub"], repo);
|
|
486
|
+
gitRun(["commit", "-m", "add submodule"], repo);
|
|
487
|
+
|
|
488
|
+
createFile(repo, "sub/file1.txt", "inside submodule\n");
|
|
489
|
+
createFile(repo, "sub/file2.txt", "also inside\n");
|
|
490
|
+
createFile(repo, "src/real.ts", "export const real = true;\n");
|
|
491
|
+
|
|
492
|
+
const svc = new GitServiceImpl(repo);
|
|
493
|
+
const taskContext: TaskCommitContext = {
|
|
494
|
+
taskId: "S01/T02",
|
|
495
|
+
taskDisplayId: "T02",
|
|
496
|
+
taskTitle: "all keyFiles inside submodule",
|
|
497
|
+
milestoneId: "M001",
|
|
498
|
+
milestoneTitle: "Submodule auto commit",
|
|
499
|
+
sliceId: "S01",
|
|
500
|
+
sliceTitle: "Commit scoped files",
|
|
501
|
+
oneLiner: "Fell back when all key files are inside submodules",
|
|
502
|
+
keyFiles: ["sub", "sub/file1.txt", "sub/file2.txt"],
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
const result = svc.autoCommit("execute-task", "M001/S01/T02", [], taskContext);
|
|
506
|
+
|
|
507
|
+
assert.ok(result !== null, "autoCommit falls back to smartStage when all keyFiles are filtered");
|
|
508
|
+
const committed = gitRun(["show", "--name-only", "--format=", "HEAD"], repo);
|
|
509
|
+
assert.ok(!committed.includes("sub/file1.txt"), "submodule keyFile is not committed");
|
|
510
|
+
assert.ok(!committed.includes("sub/file2.txt"), "submodule keyFile is not committed");
|
|
511
|
+
assert.ok(committed.includes("src/real.ts"), "smartStage fallback commits other dirty files");
|
|
512
|
+
} finally {
|
|
513
|
+
rmSync(repo, { recursive: true, force: true });
|
|
514
|
+
rmSync(subSrc, { recursive: true, force: true });
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
416
518
|
// ─── GitServiceImpl: smart staging excludes tracked runtime files ──────
|
|
417
519
|
|
|
418
520
|
test('GitServiceImpl: smart staging excludes tracked runtime files', () => {
|
|
@@ -529,6 +631,92 @@ describe('git-service', async () => {
|
|
|
529
631
|
rmSync(repo, { recursive: true, force: true });
|
|
530
632
|
});
|
|
531
633
|
|
|
634
|
+
test('GitServiceImpl: autoCommit retries once when pre-commit rewrites files', () => {
|
|
635
|
+
const repo = initTempRepo();
|
|
636
|
+
const svc = new GitServiceImpl(repo);
|
|
637
|
+
|
|
638
|
+
const hookPath = join(repo, ".git", "hooks", "pre-commit");
|
|
639
|
+
const countFile = join(repo, ".git", "pre-commit-count");
|
|
640
|
+
writeFileSync(
|
|
641
|
+
hookPath,
|
|
642
|
+
[
|
|
643
|
+
"#!/bin/sh",
|
|
644
|
+
`count_file="${countFile}"`,
|
|
645
|
+
"count=0",
|
|
646
|
+
"[ -f \"$count_file\" ] && count=$(cat \"$count_file\")",
|
|
647
|
+
"count=$((count + 1))",
|
|
648
|
+
"echo \"$count\" > \"$count_file\"",
|
|
649
|
+
"if [ \"$count\" -eq 1 ]; then",
|
|
650
|
+
" printf 'export const fixed = true;\\n' > src/fix-me.ts",
|
|
651
|
+
" exit 1",
|
|
652
|
+
"fi",
|
|
653
|
+
"exit 0",
|
|
654
|
+
"",
|
|
655
|
+
].join("\n"),
|
|
656
|
+
"utf-8",
|
|
657
|
+
);
|
|
658
|
+
chmodSync(hookPath, 0o755);
|
|
659
|
+
|
|
660
|
+
createFile(repo, "src/fix-me.ts", "export const fixed = false;\n");
|
|
661
|
+
const msg = svc.autoCommit("execute-task", "M001/S01/T04");
|
|
662
|
+
|
|
663
|
+
assert.ok(msg !== null, "autoCommit succeeds after one retry for hook rewrites");
|
|
664
|
+
assert.equal(run("git rev-list --count HEAD", repo), "2", "exactly one new commit created");
|
|
665
|
+
assert.equal(readFileSync(join(repo, "src/fix-me.ts"), "utf-8"), "export const fixed = true;\n"); // allow-source-grep: verifies pre-commit output inside the temp repo fixture, not product source.
|
|
666
|
+
assert.equal(readFileSync(countFile, "utf-8").trim(), "2", "pre-commit hook ran twice");
|
|
667
|
+
|
|
668
|
+
rmSync(repo, { recursive: true, force: true });
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
test('GitServiceImpl: autoCommit retry preserves task-scoped staging', () => {
|
|
672
|
+
const repo = initTempRepo();
|
|
673
|
+
const svc = new GitServiceImpl(repo);
|
|
674
|
+
|
|
675
|
+
const hookPath = join(repo, ".git", "hooks", "pre-commit");
|
|
676
|
+
const countFile = join(repo, ".git", "pre-commit-count");
|
|
677
|
+
writeFileSync(
|
|
678
|
+
hookPath,
|
|
679
|
+
[
|
|
680
|
+
"#!/bin/sh",
|
|
681
|
+
`count_file="${countFile}"`,
|
|
682
|
+
"count=0",
|
|
683
|
+
"[ -f \"$count_file\" ] && count=$(cat \"$count_file\")",
|
|
684
|
+
"count=$((count + 1))",
|
|
685
|
+
"echo \"$count\" > \"$count_file\"",
|
|
686
|
+
"if [ \"$count\" -eq 1 ]; then",
|
|
687
|
+
" printf 'export const fixed = true;\\n' > src/task.ts",
|
|
688
|
+
" exit 1",
|
|
689
|
+
"fi",
|
|
690
|
+
"exit 0",
|
|
691
|
+
"",
|
|
692
|
+
].join("\n"),
|
|
693
|
+
"utf-8",
|
|
694
|
+
);
|
|
695
|
+
chmodSync(hookPath, 0o755);
|
|
696
|
+
|
|
697
|
+
createFile(repo, "src/task.ts", "export const fixed = false;\n");
|
|
698
|
+
createFile(repo, "src/unrelated.ts", "export const unrelated = true;\n");
|
|
699
|
+
|
|
700
|
+
const msg = svc.autoCommit("execute-task", "M001/S01/T05", [], {
|
|
701
|
+
taskId: "S01/T05",
|
|
702
|
+
taskTitle: "update task file",
|
|
703
|
+
oneLiner: "Updated task file after hook rewrite",
|
|
704
|
+
keyFiles: ["src/task.ts"],
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
assert.ok(msg !== null, "autoCommit succeeds after retry with task-scoped staging");
|
|
708
|
+
assert.equal(readFileSync(countFile, "utf-8").trim(), "2", "pre-commit hook ran twice");
|
|
709
|
+
|
|
710
|
+
const committed = run("git show --name-only --format= HEAD", repo);
|
|
711
|
+
assert.ok(committed.includes("src/task.ts"), "task file is committed after retry");
|
|
712
|
+
assert.ok(!committed.includes("src/unrelated.ts"), "retry does not widen staging to unrelated dirty files");
|
|
713
|
+
|
|
714
|
+
const status = run("git status --porcelain", repo);
|
|
715
|
+
assert.ok(status.includes("src/unrelated.ts"), "unrelated dirty file remains in working tree");
|
|
716
|
+
|
|
717
|
+
rmSync(repo, { recursive: true, force: true });
|
|
718
|
+
});
|
|
719
|
+
|
|
532
720
|
test('GitServiceImpl: task context keyFiles scope autoCommit staging', () => {
|
|
533
721
|
const repo = initTempRepo();
|
|
534
722
|
const svc = new GitServiceImpl(repo);
|
|
@@ -608,6 +796,33 @@ describe('git-service', async () => {
|
|
|
608
796
|
rmSync(repo, { recursive: true, force: true });
|
|
609
797
|
});
|
|
610
798
|
|
|
799
|
+
// Regression: #5529. Some executors emit keyFiles relative to a monorepo
|
|
800
|
+
// subproject root (e.g. `src/...`) instead of the repo root
|
|
801
|
+
// (`frontend/src/...`). When none of those keyFiles exist at repo root,
|
|
802
|
+
// scoped staging must fall back to smartStage instead of failing the turn.
|
|
803
|
+
test('GitServiceImpl: repo-relative keyFiles mismatch falls back to smartStage', () => {
|
|
804
|
+
const repo = initTempRepo();
|
|
805
|
+
const svc = new GitServiceImpl(repo);
|
|
806
|
+
|
|
807
|
+
createFile(repo, "frontend/src/lib/onboarding-contract.ts", "export const contract = true;");
|
|
808
|
+
|
|
809
|
+
const msg = svc.autoCommit("execute-task", "M001/S01/T04", [], {
|
|
810
|
+
taskId: "S01/T04",
|
|
811
|
+
taskTitle: "fix scoped keyFiles path handling",
|
|
812
|
+
oneLiner: "Handled repo-relative keyFiles mismatch",
|
|
813
|
+
keyFiles: ["src/lib/onboarding-contract.ts"],
|
|
814
|
+
});
|
|
815
|
+
assert.ok(msg !== null, "autoCommit falls back to smartStage when scoped keyFiles are invalid at repo root");
|
|
816
|
+
|
|
817
|
+
const committed = run("git show --name-only --format= HEAD", repo);
|
|
818
|
+
assert.ok(
|
|
819
|
+
committed.includes("frontend/src/lib/onboarding-contract.ts"),
|
|
820
|
+
"smartStage fallback stages real dirty files when keyFiles are scoped to a subproject root",
|
|
821
|
+
);
|
|
822
|
+
|
|
823
|
+
rmSync(repo, { recursive: true, force: true });
|
|
824
|
+
});
|
|
825
|
+
|
|
611
826
|
test('GitServiceImpl: task context keyFiles ignores gitignored build outputs', () => {
|
|
612
827
|
const repo = initTempRepo();
|
|
613
828
|
const svc = new GitServiceImpl(repo);
|
|
@@ -1066,6 +1281,15 @@ describe('git-service', async () => {
|
|
|
1066
1281
|
rmSync(repo, { recursive: true, force: true });
|
|
1067
1282
|
});
|
|
1068
1283
|
|
|
1284
|
+
test('Integration branch: rejects milestone branches', () => {
|
|
1285
|
+
const repo = initBranchTestRepo();
|
|
1286
|
+
|
|
1287
|
+
writeIntegrationBranch(repo, "M001", "milestone/M001");
|
|
1288
|
+
assert.deepStrictEqual(readIntegrationBranch(repo, "M001"), null, "milestone branches are not recorded as integration branch");
|
|
1289
|
+
|
|
1290
|
+
rmSync(repo, { recursive: true, force: true });
|
|
1291
|
+
});
|
|
1292
|
+
|
|
1069
1293
|
// ─── writeIntegrationBranch: still records legitimate branches ────────
|
|
1070
1294
|
|
|
1071
1295
|
test('Integration branch: records non-ephemeral gsd branches', () => {
|
|
@@ -883,7 +883,7 @@ describe("dispatch failure modes", () => {
|
|
|
883
883
|
assert.ok(runUatIdx < uatGateIdx, "run-uat should precede uat-verdict-gate");
|
|
884
884
|
});
|
|
885
885
|
|
|
886
|
-
test("UAT verdict gate: ASSESSMENT FAIL
|
|
886
|
+
test("UAT verdict gate: ASSESSMENT FAIL does not hard-stop progression", async () => {
|
|
887
887
|
base = createFullFixture();
|
|
888
888
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
889
889
|
insertMilestone({ id: "M001", title: "Active", status: "active" });
|
|
@@ -908,11 +908,7 @@ describe("dispatch failure modes", () => {
|
|
|
908
908
|
ctx.prefs = { uat_dispatch: true } as any;
|
|
909
909
|
|
|
910
910
|
const result = await getUatVerdictGate().match(ctx);
|
|
911
|
-
assert.equal(result
|
|
912
|
-
assert.ok(
|
|
913
|
-
(result as any).reason?.includes('UAT verdict for S01 is "fail"'),
|
|
914
|
-
"stop reason should report normalized ASSESSMENT verdict",
|
|
915
|
-
);
|
|
911
|
+
assert.equal(result, null, "ASSESSMENT FAIL should not hard-stop progression");
|
|
916
912
|
});
|
|
917
913
|
|
|
918
914
|
test("UAT verdict gate: ROADMAP fallback gates done slices when DB is unavailable", async () => {
|
|
@@ -964,15 +960,11 @@ describe("dispatch failure modes", () => {
|
|
|
964
960
|
ctx.prefs = { uat_dispatch: true } as any;
|
|
965
961
|
|
|
966
962
|
const result = await getUatVerdictGate().match(ctx);
|
|
967
|
-
assert.equal(result
|
|
968
|
-
assert.ok(
|
|
969
|
-
(result as any).reason?.includes('UAT verdict for S01 is "needs-remediation"'),
|
|
970
|
-
"stop reason should report normalized ASSESSMENT verdict from disk fallback",
|
|
971
|
-
);
|
|
963
|
+
assert.equal(result, null, "ROADMAP done slices should not hard-stop progression without DB");
|
|
972
964
|
});
|
|
973
965
|
|
|
974
966
|
for (const status of ["done", "skipped"]) {
|
|
975
|
-
test(`UAT verdict gate: legacy closed status "${status}"
|
|
967
|
+
test(`UAT verdict gate: legacy closed status "${status}" does not hard-stop progression`, async () => {
|
|
976
968
|
base = createFullFixture();
|
|
977
969
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
978
970
|
insertMilestone({ id: "M001", title: "Active", status: "active" });
|
|
@@ -997,15 +989,7 @@ describe("dispatch failure modes", () => {
|
|
|
997
989
|
ctx.prefs = { uat_dispatch: true } as any;
|
|
998
990
|
|
|
999
991
|
const result = await getUatVerdictGate().match(ctx);
|
|
1000
|
-
assert.equal(
|
|
1001
|
-
result?.action,
|
|
1002
|
-
"stop",
|
|
1003
|
-
`${status} slices should be treated as closed for UAT verdict gating`,
|
|
1004
|
-
);
|
|
1005
|
-
assert.ok(
|
|
1006
|
-
(result as any).reason?.includes('UAT verdict for S01 is "needs-remediation"'),
|
|
1007
|
-
"stop reason should report normalized ASSESSMENT verdict",
|
|
1008
|
-
);
|
|
992
|
+
assert.equal(result, null, `${status} slices should not hard-stop progression`);
|
|
1009
993
|
});
|
|
1010
994
|
}
|
|
1011
995
|
});
|
package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
openDatabase,
|
|
32
32
|
closeDatabase,
|
|
33
33
|
insertMilestone,
|
|
34
|
+
insertAssessment,
|
|
34
35
|
insertSlice,
|
|
35
36
|
insertTask,
|
|
36
37
|
getTask,
|
|
@@ -280,6 +281,16 @@ function makeMilestoneParams(milestoneId: string): Record<string, unknown> {
|
|
|
280
281
|
};
|
|
281
282
|
}
|
|
282
283
|
|
|
284
|
+
function insertPassingMilestoneValidation(milestoneId: string): void {
|
|
285
|
+
insertAssessment({
|
|
286
|
+
path: `.gsd/milestones/${milestoneId}/${milestoneId}-VALIDATION.md`,
|
|
287
|
+
milestoneId,
|
|
288
|
+
status: "pass",
|
|
289
|
+
scope: "milestone-validation",
|
|
290
|
+
fullContent: "# Validation\n\nverdict: PASS",
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
283
294
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
284
295
|
// Test Suite
|
|
285
296
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -424,6 +435,7 @@ describe("state-machine-live-validation", () => {
|
|
|
424
435
|
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Impl", status: "complete" });
|
|
425
436
|
insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", title: "Test", status: "complete" });
|
|
426
437
|
insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Impl", status: "complete" });
|
|
438
|
+
insertPassingMilestoneValidation("M001");
|
|
427
439
|
|
|
428
440
|
const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
|
|
429
441
|
assert.ok(!("error" in result), `expected success, got: ${JSON.stringify(result)}`);
|
|
@@ -528,6 +540,7 @@ describe("state-machine-live-validation", () => {
|
|
|
528
540
|
base = createFullFixture();
|
|
529
541
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
530
542
|
insertMilestone({ id: "M001", title: "Active", status: "active" });
|
|
543
|
+
insertPassingMilestoneValidation("M001");
|
|
531
544
|
|
|
532
545
|
const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
|
|
533
546
|
assert.ok("error" in result);
|
|
@@ -542,6 +555,7 @@ describe("state-machine-live-validation", () => {
|
|
|
542
555
|
insertSlice({ id: "S02", milestoneId: "M001", status: "in_progress" });
|
|
543
556
|
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
|
|
544
557
|
insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", status: "pending" });
|
|
558
|
+
insertPassingMilestoneValidation("M001");
|
|
545
559
|
|
|
546
560
|
const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
|
|
547
561
|
assert.ok("error" in result);
|
|
@@ -555,6 +569,7 @@ describe("state-machine-live-validation", () => {
|
|
|
555
569
|
// Slice marked complete but task is still pending — simulates inconsistent state
|
|
556
570
|
insertSlice({ id: "S01", milestoneId: "M001", status: "complete" });
|
|
557
571
|
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
|
|
572
|
+
insertPassingMilestoneValidation("M001");
|
|
558
573
|
|
|
559
574
|
const result = await handleCompleteMilestone(makeMilestoneParams("M001") as any, base);
|
|
560
575
|
assert.ok("error" in result);
|
package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts
CHANGED
|
@@ -195,6 +195,11 @@ describe("infrastructure error detection", () => {
|
|
|
195
195
|
assert.equal(isInfrastructureError(err), "EAGAIN");
|
|
196
196
|
});
|
|
197
197
|
|
|
198
|
+
test("ENOBUFS (no buffer space available) is detected", () => {
|
|
199
|
+
const err = Object.assign(new Error("spawnSync git ENOBUFS"), { code: "ENOBUFS" });
|
|
200
|
+
assert.equal(isInfrastructureError(err), "ENOBUFS");
|
|
201
|
+
});
|
|
202
|
+
|
|
198
203
|
test("SQLite WAL corruption is detected via message scan", () => {
|
|
199
204
|
const err = new Error("database disk image is malformed");
|
|
200
205
|
assert.equal(isInfrastructureError(err), "SQLITE_CORRUPT");
|
|
@@ -223,7 +228,7 @@ describe("infrastructure error detection", () => {
|
|
|
223
228
|
test("all INFRA_ERROR_CODES are covered", () => {
|
|
224
229
|
const expectedCodes = [
|
|
225
230
|
"ENOSPC", "ENOMEM", "EROFS", "EDQUOT", "EMFILE",
|
|
226
|
-
"ENFILE", "EAGAIN", "ECONNREFUSED", "ENOTFOUND", "ENETUNREACH",
|
|
231
|
+
"ENFILE", "EAGAIN", "ENOBUFS", "ECONNREFUSED", "ENOTFOUND", "ENETUNREACH",
|
|
227
232
|
];
|
|
228
233
|
for (const code of expectedCodes) {
|
|
229
234
|
assert.ok(INFRA_ERROR_CODES.has(code), `${code} should be in INFRA_ERROR_CODES`);
|
|
@@ -5,6 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
|
|
8
|
+
import { _handlePausedSessionResumeRecoveryForTest } from "../auto.ts";
|
|
8
9
|
import { assessInterruptedSession } from "../interrupted-session.ts";
|
|
9
10
|
import {
|
|
10
11
|
openDatabase,
|
|
@@ -186,6 +187,45 @@ test("direct /gsd auto source only resumes paused-session metadata for recoverab
|
|
|
186
187
|
assert.ok(source.includes('|| !!freshStartAssessment.lock'));
|
|
187
188
|
});
|
|
188
189
|
|
|
190
|
+
test("direct /gsd auto skips paused-session replay when recovered unit already completed", async () => {
|
|
191
|
+
const base = makeTmpBase();
|
|
192
|
+
try {
|
|
193
|
+
writeRoadmap(base, false);
|
|
194
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
195
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
196
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
197
|
+
writeFileSync(
|
|
198
|
+
join(sliceDir, "S01-PLAN.md"),
|
|
199
|
+
[
|
|
200
|
+
"# S01: Test Slice",
|
|
201
|
+
"",
|
|
202
|
+
"## Tasks",
|
|
203
|
+
"",
|
|
204
|
+
"- [ ] **T01: First task** `est:1h`",
|
|
205
|
+
].join("\n"),
|
|
206
|
+
"utf-8",
|
|
207
|
+
);
|
|
208
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan\n\nDo the thing.\n", "utf-8");
|
|
209
|
+
|
|
210
|
+
const state = {
|
|
211
|
+
pausedSessionFile: join(base, ".gsd", "activity", "paused-session.jsonl"),
|
|
212
|
+
currentUnit: null,
|
|
213
|
+
pausedUnitType: "plan-slice",
|
|
214
|
+
pausedUnitId: "M001/S01",
|
|
215
|
+
pendingCrashRecovery: "stale-recovery-prompt",
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const result = _handlePausedSessionResumeRecoveryForTest(base, state);
|
|
219
|
+
assert.equal(result.skippedReplay, true);
|
|
220
|
+
assert.equal(state.pausedSessionFile, null);
|
|
221
|
+
assert.equal(state.pendingCrashRecovery, null);
|
|
222
|
+
assert.equal(state.pausedUnitType, null);
|
|
223
|
+
assert.equal(state.pausedUnitId, null);
|
|
224
|
+
} finally {
|
|
225
|
+
cleanup(base);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
189
229
|
test("auto module imports successfully after interrupted-session changes", async () => {
|
|
190
230
|
const mod = await import(`../auto.ts?ts=${Date.now()}-${Math.random()}`);
|
|
191
231
|
assert.equal(typeof mod.startAuto, "function");
|
|
@@ -22,6 +22,7 @@ import type { IterationContext, LoopState, PreDispatchData, IterationData } from
|
|
|
22
22
|
import type { SessionLockStatus } from "../session-lock.js";
|
|
23
23
|
import { runDispatch, runUnitPhase, runPreDispatch, runFinalize } from "../auto/phases.js";
|
|
24
24
|
import { readUnitRuntimeRecord } from "../unit-runtime.js";
|
|
25
|
+
import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
|
|
25
26
|
import {
|
|
26
27
|
closeDatabase,
|
|
27
28
|
insertMilestone,
|
|
@@ -160,6 +161,8 @@ function makeIC(
|
|
|
160
161
|
pi: {
|
|
161
162
|
sendMessage: () => {},
|
|
162
163
|
setModel: async () => true,
|
|
164
|
+
getThinkingLevel: () => "off",
|
|
165
|
+
setThinkingLevel: () => {},
|
|
163
166
|
} as any,
|
|
164
167
|
s: makeSession(),
|
|
165
168
|
deps,
|
|
@@ -633,7 +636,7 @@ test("runDispatch clears execute-task stuck state when artifacts and DB status a
|
|
|
633
636
|
assert.equal(stopCalls, 0, "closed DB task should not hard-stop the loop");
|
|
634
637
|
assert.equal(invalidateCalls, 1, "closed DB task recovery should invalidate caches once");
|
|
635
638
|
assert.deepEqual(loopState.recentUnits, [], "closed DB task recovery should clear the stuck window");
|
|
636
|
-
assert.equal(loopState.stuckRecoveryAttempts,
|
|
639
|
+
assert.equal(loopState.stuckRecoveryAttempts, 1, "closed DB task recovery should preserve the recovery counter");
|
|
637
640
|
});
|
|
638
641
|
|
|
639
642
|
test("runDispatch clears stuck state after Level 1 artifact recovery", async (t) => {
|
|
@@ -700,7 +703,7 @@ test("runDispatch clears stuck state after Level 1 artifact recovery", async (t)
|
|
|
700
703
|
assert.equal(invalidateCalls, 1, "Level 1 artifact recovery should invalidate caches");
|
|
701
704
|
assert.equal(stopCalls, 0, "Level 1 artifact recovery should not hard-stop");
|
|
702
705
|
assert.deepEqual(loopState.recentUnits, [], "Level 1 artifact recovery should clear the stuck window");
|
|
703
|
-
assert.equal(loopState.stuckRecoveryAttempts,
|
|
706
|
+
assert.equal(loopState.stuckRecoveryAttempts, 1, "Level 1 artifact recovery should preserve the recovery counter");
|
|
704
707
|
});
|
|
705
708
|
|
|
706
709
|
test("runDispatch escapes Level 2 stuck stop when artifact verifies after cache invalidation", async (t) => {
|
|
@@ -825,7 +828,7 @@ test("runUnitPhase emits unit-start and unit-end with causedBy reference", async
|
|
|
825
828
|
assert.equal(endEvents[0].flowId, ic.flowId);
|
|
826
829
|
assert.equal((endEvents[0].data as any).unitType, "execute-task");
|
|
827
830
|
assert.equal((endEvents[0].data as any).unitId, "M001/S01/T01");
|
|
828
|
-
assert.equal((endEvents[0].data as any).status, "
|
|
831
|
+
assert.equal((endEvents[0].data as any).status, "no-artifact");
|
|
829
832
|
|
|
830
833
|
// Verify causedBy: unit-end references unit-start's seq
|
|
831
834
|
assert.ok(endEvents[0].causedBy, "unit-end must have a causedBy reference");
|
|
@@ -868,6 +871,49 @@ test("runUnitPhase increments unitDispatchCount for repeated artifact-missing re
|
|
|
868
871
|
assert.equal(ic.s.unitDispatchCount.get("execute-task/M001/S01/T01"), 2);
|
|
869
872
|
});
|
|
870
873
|
|
|
874
|
+
test("runUnitPhase pre-dispatch model validation failures do not emit unit-start or dispatch runtime state", async (t) => {
|
|
875
|
+
const capture = createEventCapture();
|
|
876
|
+
const base = mkdtempSync(join(tmpdir(), `gsd-pre-dispatch-block-${randomUUID()}`));
|
|
877
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
878
|
+
|
|
879
|
+
const deps = makeMockDeps(capture, {
|
|
880
|
+
selectAndApplyModel: async () => {
|
|
881
|
+
throw new ModelPolicyDispatchBlockedError("execute-task", "M001/S01/T01", []);
|
|
882
|
+
},
|
|
883
|
+
});
|
|
884
|
+
const ic = makeIC(deps, {
|
|
885
|
+
s: {
|
|
886
|
+
...makeSession(),
|
|
887
|
+
basePath: base,
|
|
888
|
+
} as any,
|
|
889
|
+
});
|
|
890
|
+
const iterData: IterationData = {
|
|
891
|
+
unitType: "execute-task",
|
|
892
|
+
unitId: "M001/S01/T01",
|
|
893
|
+
prompt: "do stuff",
|
|
894
|
+
finalPrompt: "do stuff",
|
|
895
|
+
pauseAfterUatDispatch: false,
|
|
896
|
+
state: { phase: "executing", activeMilestone: { id: "M001" }, activeSlice: { id: "S01" }, registry: [], blockers: [] } as any,
|
|
897
|
+
mid: "M001",
|
|
898
|
+
midTitle: "Test",
|
|
899
|
+
isRetry: false,
|
|
900
|
+
previousTier: undefined,
|
|
901
|
+
};
|
|
902
|
+
const loopState: LoopState = { recentUnits: [{ key: "execute-task/M001/S01/T01" }], stuckRecoveryAttempts: 0, consecutiveFinalizeTimeouts: 0 };
|
|
903
|
+
|
|
904
|
+
await assert.rejects(() => runUnitPhase(ic, iterData, loopState), ModelPolicyDispatchBlockedError);
|
|
905
|
+
await assert.rejects(() => runUnitPhase(ic, iterData, loopState), ModelPolicyDispatchBlockedError);
|
|
906
|
+
|
|
907
|
+
const startEvents = capture.events.filter(e => e.eventType === "unit-start");
|
|
908
|
+
assert.equal(startEvents.length, 0, "pre-dispatch validation failures must not emit unit-start");
|
|
909
|
+
assert.equal(ic.s.unitDispatchCount.get("execute-task/M001/S01/T01") ?? 0, 0, "dispatch count must not increment on pre-dispatch validation failure");
|
|
910
|
+
assert.equal(
|
|
911
|
+
readUnitRuntimeRecord(base, "execute-task", "M001/S01/T01"),
|
|
912
|
+
null,
|
|
913
|
+
"pre-dispatch validation failures must not persist a dispatched runtime record",
|
|
914
|
+
);
|
|
915
|
+
});
|
|
916
|
+
|
|
871
917
|
test("all events from a mock iteration have monotonically increasing seq and same flowId", async () => {
|
|
872
918
|
const capture = createEventCapture();
|
|
873
919
|
const { resolveAgentEnd, _resetPendingResolve } = await import("../auto/resolve.js");
|
|
@@ -206,6 +206,38 @@ describe("queryJournal", () => {
|
|
|
206
206
|
assert.ok(results.every(e => e.eventType === "dispatch-match"));
|
|
207
207
|
});
|
|
208
208
|
|
|
209
|
+
test("keeps auto-orchestrator events separate from auto-loop events", () => {
|
|
210
|
+
emitJournalEvent(base, makeEntry({ eventType: "iteration-start", seq: 0 }));
|
|
211
|
+
emitJournalEvent(base, makeEntry({ eventType: "dispatch-match", seq: 1 }));
|
|
212
|
+
emitJournalEvent(
|
|
213
|
+
base,
|
|
214
|
+
makeEntry({
|
|
215
|
+
eventType: "orchestrator-iteration-start",
|
|
216
|
+
seq: 2,
|
|
217
|
+
data: { source: "auto-orchestrator", name: "start" },
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
emitJournalEvent(
|
|
221
|
+
base,
|
|
222
|
+
makeEntry({
|
|
223
|
+
eventType: "orchestrator-dispatch-match",
|
|
224
|
+
seq: 3,
|
|
225
|
+
data: { source: "auto-orchestrator", name: "advance" },
|
|
226
|
+
}),
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const loopMatches = queryJournal(base, { eventType: "dispatch-match" });
|
|
230
|
+
const orchestratorMatches = queryJournal(base, { eventType: "orchestrator-dispatch-match" });
|
|
231
|
+
|
|
232
|
+
assert.equal(loopMatches.length, 1, "loop dispatch telemetry should not include orchestrator advances");
|
|
233
|
+
assert.equal(orchestratorMatches.length, 1, "forensics needs orchestrator advances under their own type");
|
|
234
|
+
assert.equal(orchestratorMatches[0].seq, 3);
|
|
235
|
+
assert.deepEqual(orchestratorMatches[0].data, {
|
|
236
|
+
source: "auto-orchestrator",
|
|
237
|
+
name: "advance",
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
|
|
209
241
|
test("filters by unitId (from data.unitId)", () => {
|
|
210
242
|
emitJournalEvent(
|
|
211
243
|
base,
|