gsd-pi 2.80.0-dev.4ea7d80e7 → 2.80.0-dev.4edec4620
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 +4 -2
- package/dist/claude-cli-check.d.ts +30 -0
- package/dist/claude-cli-check.js +18 -7
- package/dist/cli.js +0 -19
- package/dist/headless-query.d.ts +10 -0
- package/dist/headless-query.js +6 -4
- package/dist/loader-entrypoint.d.ts +8 -0
- package/dist/loader-entrypoint.js +27 -0
- package/dist/loader.js +2 -11
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.js +6 -3
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +40 -3
- package/dist/resources/extensions/github-sync/sync.js +4 -1
- package/dist/resources/extensions/gsd/auto/loop.js +103 -9
- package/dist/resources/extensions/gsd/auto/phases.js +240 -139
- package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
- package/dist/resources/extensions/gsd/auto/session.js +8 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +18 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +104 -86
- package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
- package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
- package/dist/resources/extensions/gsd/auto-start.js +238 -12
- package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +209 -81
- package/dist/resources/extensions/gsd/auto.js +159 -44
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -10
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +30 -20
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -54
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +19 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
- package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
- package/dist/resources/extensions/gsd/commands-config.js +1 -1
- package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
- package/dist/resources/extensions/gsd/context-budget.js +37 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
- package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
- package/dist/resources/extensions/gsd/detection.js +106 -0
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
- package/dist/resources/extensions/gsd/git-service.js +73 -5
- package/dist/resources/extensions/gsd/gsd-db.js +46 -13
- package/dist/resources/extensions/gsd/guided-flow.js +147 -46
- package/dist/resources/extensions/gsd/health-widget.js +3 -0
- package/dist/resources/extensions/gsd/init-wizard.js +4 -1
- package/dist/resources/extensions/gsd/memory-store.js +69 -12
- package/dist/resources/extensions/gsd/migrate/command.js +40 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
- package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -23
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/quick.js +34 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
- package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
- package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
- package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
- package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
- package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
- package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- package/dist/resources/extensions/gsd/worktree-resolver.js +90 -22
- package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- 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 +2 -2
- 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_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 +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +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/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/middleware.js +3 -3
- 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/8359.e059d86b255fce1c.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
- package/dist/welcome-screen.d.ts +2 -0
- package/dist/welcome-screen.js +9 -7
- package/package.json +3 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -17
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
- package/packages/mcp-server/src/workflow-tools.ts +30 -16
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +2 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
- package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
- package/packages/pi-agent-core/dist/token-audit.js +221 -0
- package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
- package/packages/pi-agent-core/dist/types.d.ts +9 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-agent-core/src/agent.ts +8 -0
- package/packages/pi-agent-core/src/index.ts +2 -0
- package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
- package/packages/pi-agent-core/src/token-audit.ts +287 -0
- package/packages/pi-agent-core/src/types.ts +14 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +9 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
- package/packages/pi-ai/src/providers/anthropic.ts +22 -9
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
- package/packages/pi-ai/src/types.ts +3 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +30 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +17 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +52 -7
- 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 +6 -2
- 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 +11 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +6 -6
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +5 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +41 -3
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +81 -4
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
- package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
- package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +89 -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/tool-card-cleanup-and-success-runtime.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +155 -7
- 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 +31 -6
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.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 +22 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +40 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +59 -7
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +6 -2
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
- package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +5 -3
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +8 -5
- package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -2
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +92 -4
- package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
- package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
- package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
- package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
- package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
- package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
- package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
- package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
- package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +119 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +180 -7
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +39 -8
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +24 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +18 -8
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/tui.ts +20 -8
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +42 -3
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +67 -0
- package/src/resources/extensions/github-sync/sync.ts +8 -1
- package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
- package/src/resources/extensions/gsd/auto/loop.ts +134 -16
- package/src/resources/extensions/gsd/auto/phases.ts +328 -200
- package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
- package/src/resources/extensions/gsd/auto/session.ts +8 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +20 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +117 -88
- package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
- package/src/resources/extensions/gsd/auto-start.ts +286 -15
- package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +241 -72
- package/src/resources/extensions/gsd/auto.ts +208 -39
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -8
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +32 -19
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +379 -54
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
- package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
- package/src/resources/extensions/gsd/commands-config.ts +1 -1
- package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
- package/src/resources/extensions/gsd/context-budget.ts +44 -2
- package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
- package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
- package/src/resources/extensions/gsd/detection.ts +128 -0
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
- package/src/resources/extensions/gsd/git-service.ts +87 -10
- package/src/resources/extensions/gsd/gsd-db.ts +50 -13
- package/src/resources/extensions/gsd/guided-flow.ts +173 -53
- package/src/resources/extensions/gsd/health-widget.ts +3 -0
- package/src/resources/extensions/gsd/init-wizard.ts +5 -1
- package/src/resources/extensions/gsd/memory-store.ts +77 -12
- package/src/resources/extensions/gsd/migrate/command.ts +47 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
- package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -23
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/quick.ts +37 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
- package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +433 -11
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +160 -11
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
- package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
- package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
- package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
- package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
- package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
- package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
- package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
- package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
- package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
- package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
- package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
- package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
- package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +203 -4
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
- package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
- package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
- package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
- package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
- package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
- package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/src/resources/extensions/gsd/worktree-resolver.ts +119 -20
- package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
- package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
- /package/dist/web/standalone/.next/static/{vIAZSyxIuvqNkCvXt9oqb → eeMbUJZnoHp7l3SZHeXY9}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vIAZSyxIuvqNkCvXt9oqb → eeMbUJZnoHp7l3SZHeXY9}/_ssgManifest.js +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Auto-loop pipeline phases, merge closeout, and finalize handling.
|
|
1
3
|
/**
|
|
2
4
|
* auto/phases.ts — Pipeline phases for the auto-loop.
|
|
3
5
|
*
|
|
@@ -13,22 +15,22 @@ import { detectStuck } from "./detect-stuck.js";
|
|
|
13
15
|
import { runUnit } from "./run-unit.js";
|
|
14
16
|
import { debugLog } from "../debug-logger.js";
|
|
15
17
|
import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
|
|
16
|
-
import {
|
|
18
|
+
import { classifyProject } from "../detection.js";
|
|
17
19
|
import { MergeConflictError } from "../git-service.js";
|
|
18
20
|
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
19
21
|
import { pauseAutoForProviderError } from "../provider-error-pause.js";
|
|
20
22
|
import { resumeAutoAfterProviderDelay } from "../bootstrap/provider-error-resume.js";
|
|
21
23
|
import { join, basename } from "node:path";
|
|
22
|
-
import { existsSync, cpSync
|
|
24
|
+
import { existsSync, cpSync } from "node:fs";
|
|
23
25
|
import { logWarning, logError, _resetLogs, drainLogs, drainAndSummarize, formatForNotification, hasAnyIssues, } from "../workflow-logger.js";
|
|
24
26
|
import { gsdRoot } from "../paths.js";
|
|
25
27
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
26
|
-
import { verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps } from "../auto-recovery.js";
|
|
28
|
+
import { verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
|
|
27
29
|
import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
28
30
|
import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "./finalize-timeout.js";
|
|
29
31
|
import { getEligibleSlices } from "../slice-parallel-eligibility.js";
|
|
30
32
|
import { startSliceParallel } from "../slice-parallel-orchestrator.js";
|
|
31
|
-
import { isDbAvailable, getMilestoneSlices
|
|
33
|
+
import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
|
|
32
34
|
import { ensurePlanV2Graph, isEmptyPlanV2GraphResult, isMissingFinalizedContextResult } from "../uok/plan-v2.js";
|
|
33
35
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
34
36
|
import { UokGateRunner } from "../uok/gate-runner.js";
|
|
@@ -42,12 +44,10 @@ import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit,
|
|
|
42
44
|
function isSamePathLocal(a, b) {
|
|
43
45
|
return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
|
|
44
46
|
}
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return true;
|
|
50
|
-
return refreshOpenDatabaseFromDisk();
|
|
47
|
+
export function shouldDegradeEmptyWorktreeToProjectRoot(worktreeClassification, projectRootClassification) {
|
|
48
|
+
return (worktreeClassification.kind === "greenfield" &&
|
|
49
|
+
projectRootClassification.kind !== "greenfield" &&
|
|
50
|
+
projectRootClassification.kind !== "invalid-repo");
|
|
51
51
|
}
|
|
52
52
|
// ─── Session timeout auto-resume state ────────────────────────────────────────
|
|
53
53
|
let consecutiveSessionTimeouts = 0;
|
|
@@ -78,9 +78,15 @@ const PLAN_V2_GATE_PHASES = new Set([
|
|
|
78
78
|
"validating-milestone",
|
|
79
79
|
"completing-milestone",
|
|
80
80
|
]);
|
|
81
|
-
function shouldRunPlanV2Gate(phase) {
|
|
81
|
+
export function shouldRunPlanV2Gate(phase) {
|
|
82
82
|
return PLAN_V2_GATE_PHASES.has(phase);
|
|
83
83
|
}
|
|
84
|
+
export function _shouldProceedWithInvalidRepoClassificationForTest(reason, hasGit) {
|
|
85
|
+
return reason === "missing .git" && hasGit;
|
|
86
|
+
}
|
|
87
|
+
export function _resolveCurrentUnitStartedAtForTest(currentUnit) {
|
|
88
|
+
return currentUnit?.startedAt;
|
|
89
|
+
}
|
|
84
90
|
/**
|
|
85
91
|
* Generate and write an HTML milestone report snapshot.
|
|
86
92
|
* Extracted from the milestone-transition block in autoLoop.
|
|
@@ -136,6 +142,85 @@ async function closeoutAndStop(ctx, pi, s, deps, reason) {
|
|
|
136
142
|
}
|
|
137
143
|
await deps.stopAuto(ctx, pi, reason);
|
|
138
144
|
}
|
|
145
|
+
async function stopOnPostflightRecoveryNeeded(ic, result, milestoneId) {
|
|
146
|
+
if (!result.needsManualRecovery)
|
|
147
|
+
return null;
|
|
148
|
+
const { ctx, pi, deps } = ic;
|
|
149
|
+
const reason = `Post-merge stash restore failed for milestone ${milestoneId}`;
|
|
150
|
+
ctx.ui.notify(`${reason}. Resolve the working tree before resuming auto-mode. ${result.message}`, "error");
|
|
151
|
+
await deps.stopAuto(ctx, pi, reason);
|
|
152
|
+
return { action: "break", reason: "postflight-stash-restore-failed" };
|
|
153
|
+
}
|
|
154
|
+
async function restorePreflightStashOrStop(ic, preflight, milestoneId) {
|
|
155
|
+
if (!preflight.stashPushed)
|
|
156
|
+
return null;
|
|
157
|
+
const { ctx, s, deps } = ic;
|
|
158
|
+
const result = deps.postflightPopStash(s.originalBasePath || s.basePath, milestoneId, preflight.stashMarker, ctx.ui.notify.bind(ctx.ui));
|
|
159
|
+
return stopOnPostflightRecoveryNeeded(ic, result, milestoneId);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Run a milestone merge surrounded by preflight stash + always-on postflight
|
|
163
|
+
* pop. The previous code popped the stash only after a successful merge, which
|
|
164
|
+
* leaked `gsd-preflight-stash:M00x:*` entries whenever `mergeAndExit` threw —
|
|
165
|
+
* leaving the user's pre-merge working tree silently stashed away after a
|
|
166
|
+
* merge-conflict or other merge error. This helper restores the stash on
|
|
167
|
+
* every exit path, then surfaces the merge or stash failure (in priority
|
|
168
|
+
* order) as the loop's stop reason.
|
|
169
|
+
*
|
|
170
|
+
* Returns a `break` action when auto-mode must stop, or `null` when the merge
|
|
171
|
+
* succeeded and the stash (if any) was restored cleanly.
|
|
172
|
+
*/
|
|
173
|
+
export async function _runMilestoneMergeWithStashRestore(ic, milestoneId) {
|
|
174
|
+
const { ctx, pi, s, deps } = ic;
|
|
175
|
+
const preflight = deps.preflightCleanRoot(s.originalBasePath || s.basePath, milestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
176
|
+
let mergeError = null;
|
|
177
|
+
try {
|
|
178
|
+
deps.resolver.mergeAndExit(milestoneId, ctx.ui);
|
|
179
|
+
s.milestoneMergedInPhases = true;
|
|
180
|
+
}
|
|
181
|
+
catch (mergeErr) {
|
|
182
|
+
mergeError = mergeErr;
|
|
183
|
+
}
|
|
184
|
+
// Always attempt to restore the stashed working tree, even on merge error.
|
|
185
|
+
// postflightPopStash itself does not throw; failures surface via the
|
|
186
|
+
// PostflightResult.needsManualRecovery flag.
|
|
187
|
+
let stashResult = null;
|
|
188
|
+
if (preflight.stashPushed) {
|
|
189
|
+
stashResult = deps.postflightPopStash(s.originalBasePath || s.basePath, milestoneId, preflight.stashMarker, ctx.ui.notify.bind(ctx.ui));
|
|
190
|
+
}
|
|
191
|
+
// Merge failure takes priority over stash recovery — the merge is the
|
|
192
|
+
// authoritative gate. If the stash also needed manual recovery, the user
|
|
193
|
+
// already saw the postflightPopStash notify above.
|
|
194
|
+
if (mergeError) {
|
|
195
|
+
if (mergeError instanceof MergeConflictError) {
|
|
196
|
+
ctx.ui.notify(`Merge conflict: ${mergeError.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
|
|
197
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${milestoneId}`);
|
|
198
|
+
return { action: "break", reason: "merge-conflict" };
|
|
199
|
+
}
|
|
200
|
+
logError("engine", "Milestone merge failed with non-conflict error", {
|
|
201
|
+
milestone: milestoneId,
|
|
202
|
+
error: String(mergeError),
|
|
203
|
+
});
|
|
204
|
+
ctx.ui.notify(`Merge failed: ${mergeError instanceof Error ? mergeError.message : String(mergeError)}. Resolve and run /gsd auto to resume.`, "error");
|
|
205
|
+
await deps.stopAuto(ctx, pi, `Merge error on milestone ${milestoneId}: ${String(mergeError)}`);
|
|
206
|
+
return { action: "break", reason: "merge-failed" };
|
|
207
|
+
}
|
|
208
|
+
if (stashResult) {
|
|
209
|
+
return stopOnPostflightRecoveryNeeded(ic, stashResult, milestoneId);
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
export async function _runMilestoneMergeOnceWithStashRestore(ic, milestoneId) {
|
|
214
|
+
if (ic.s.milestoneMergedInPhases) {
|
|
215
|
+
debugLog("autoLoop", {
|
|
216
|
+
phase: "milestone-merge-skip",
|
|
217
|
+
reason: "already-merged-in-phases",
|
|
218
|
+
milestoneId,
|
|
219
|
+
});
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return _runMilestoneMergeWithStashRestore(ic, milestoneId);
|
|
223
|
+
}
|
|
139
224
|
async function emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, errorContext) {
|
|
140
225
|
ic.deps.emitJournalEvent({
|
|
141
226
|
ts: new Date().toISOString(),
|
|
@@ -477,28 +562,12 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
477
562
|
s.unitLifetimeDispatches.clear();
|
|
478
563
|
loopState.recentUnits.length = 0;
|
|
479
564
|
loopState.stuckRecoveryAttempts = 0;
|
|
480
|
-
// Worktree lifecycle on milestone transition — merge current, enter next
|
|
481
|
-
// #2909: preflight
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
catch (mergeErr) {
|
|
487
|
-
if (mergeErr instanceof MergeConflictError) {
|
|
488
|
-
// Real code conflicts — stop the loop instead of retrying forever (#2330)
|
|
489
|
-
ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
|
|
490
|
-
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
491
|
-
return { action: "break", reason: "merge-conflict" };
|
|
492
|
-
}
|
|
493
|
-
// Non-conflict merge errors — stop auto to avoid advancing with unmerged work
|
|
494
|
-
logError("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId, error: String(mergeErr) });
|
|
495
|
-
ctx.ui.notify(`Merge failed: ${mergeErr instanceof Error ? mergeErr.message : String(mergeErr)}. Resolve and run /gsd auto to resume.`, "error");
|
|
496
|
-
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
497
|
-
return { action: "break", reason: "merge-failed" };
|
|
498
|
-
}
|
|
499
|
-
// #2909: postflight — restore stashed changes after successful merge
|
|
500
|
-
if (preflightTransition.stashPushed) {
|
|
501
|
-
deps.postflightPopStash(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
565
|
+
// Worktree lifecycle on milestone transition — merge current, enter next.
|
|
566
|
+
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
567
|
+
{
|
|
568
|
+
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
569
|
+
if (stop)
|
|
570
|
+
return stop;
|
|
502
571
|
}
|
|
503
572
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
504
573
|
deps.invalidateAllCaches();
|
|
@@ -552,30 +621,12 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
552
621
|
}
|
|
553
622
|
const incomplete = state.registry.filter((m) => m.status !== "complete" && m.status !== "parked");
|
|
554
623
|
if (incomplete.length === 0 && state.registry.length > 0) {
|
|
555
|
-
// All milestones complete — merge milestone branch before stopping
|
|
624
|
+
// All milestones complete — merge milestone branch before stopping.
|
|
556
625
|
if (s.currentMilestoneId) {
|
|
557
|
-
// #2909: preflight
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
// Prevent stopAuto from attempting the same merge (#2645)
|
|
562
|
-
s.milestoneMergedInPhases = true;
|
|
563
|
-
}
|
|
564
|
-
catch (mergeErr) {
|
|
565
|
-
if (mergeErr instanceof MergeConflictError) {
|
|
566
|
-
ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
|
|
567
|
-
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
568
|
-
return { action: "break", reason: "merge-conflict" };
|
|
569
|
-
}
|
|
570
|
-
logError("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId, error: String(mergeErr) });
|
|
571
|
-
ctx.ui.notify(`Merge failed: ${mergeErr instanceof Error ? mergeErr.message : String(mergeErr)}. Resolve and run /gsd auto to resume.`, "error");
|
|
572
|
-
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
573
|
-
return { action: "break", reason: "merge-failed" };
|
|
574
|
-
}
|
|
575
|
-
// #2909: postflight — restore stashed changes after successful merge
|
|
576
|
-
if (preflightAllComplete.stashPushed) {
|
|
577
|
-
deps.postflightPopStash(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
578
|
-
}
|
|
626
|
+
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
627
|
+
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
628
|
+
if (stop)
|
|
629
|
+
return stop;
|
|
579
630
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
580
631
|
}
|
|
581
632
|
deps.sendDesktopNotification("GSD", "All milestones complete!", "success", "milestone", basename(s.originalBasePath || s.basePath));
|
|
@@ -638,30 +689,12 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
638
689
|
}
|
|
639
690
|
// Terminal: complete
|
|
640
691
|
if (state.phase === "complete") {
|
|
641
|
-
// Milestone merge on complete (before closeout so branch state is clean)
|
|
692
|
+
// Milestone merge on complete (before closeout so branch state is clean).
|
|
642
693
|
if (s.currentMilestoneId) {
|
|
643
|
-
// #2909: preflight
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
// Prevent stopAuto from attempting the same merge (#2645)
|
|
648
|
-
s.milestoneMergedInPhases = true;
|
|
649
|
-
}
|
|
650
|
-
catch (mergeErr) {
|
|
651
|
-
if (mergeErr instanceof MergeConflictError) {
|
|
652
|
-
ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
|
|
653
|
-
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
654
|
-
return { action: "break", reason: "merge-conflict" };
|
|
655
|
-
}
|
|
656
|
-
logError("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId, error: String(mergeErr) });
|
|
657
|
-
ctx.ui.notify(`Merge failed: ${mergeErr instanceof Error ? mergeErr.message : String(mergeErr)}. Resolve and run /gsd auto to resume.`, "error");
|
|
658
|
-
await deps.stopAuto(ctx, pi, `Merge error on milestone ${s.currentMilestoneId}: ${String(mergeErr)}`);
|
|
659
|
-
return { action: "break", reason: "merge-failed" };
|
|
660
|
-
}
|
|
661
|
-
// #2909: postflight — restore stashed changes after successful merge
|
|
662
|
-
if (preflightComplete.stashPushed) {
|
|
663
|
-
deps.postflightPopStash(s.originalBasePath || s.basePath, s.currentMilestoneId, ctx.ui.notify.bind(ctx.ui));
|
|
664
|
-
}
|
|
694
|
+
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
695
|
+
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
696
|
+
if (stop)
|
|
697
|
+
return stop;
|
|
665
698
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
666
699
|
}
|
|
667
700
|
deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone", basename(s.originalBasePath || s.basePath));
|
|
@@ -754,6 +787,48 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
754
787
|
let unitId = dispatchResult.unitId;
|
|
755
788
|
let prompt = dispatchResult.prompt;
|
|
756
789
|
const pauseAfterUatDispatch = dispatchResult.pauseAfterDispatch ?? false;
|
|
790
|
+
// Resolve hooks and prior-slice gating before health/stuck accounting so
|
|
791
|
+
// those checks run against the final dispatch unit.
|
|
792
|
+
const preDispatchResult = deps.runPreDispatchHooks(unitType, unitId, prompt, s.basePath);
|
|
793
|
+
if (preDispatchResult.firedHooks.length > 0) {
|
|
794
|
+
ctx.ui.notify(`Pre-dispatch hook${preDispatchResult.firedHooks.length > 1 ? "s" : ""}: ${preDispatchResult.firedHooks.join(", ")}`, "info");
|
|
795
|
+
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "pre-dispatch-hook", data: { firedHooks: preDispatchResult.firedHooks, action: preDispatchResult.action } });
|
|
796
|
+
}
|
|
797
|
+
if (preDispatchResult.action === "skip") {
|
|
798
|
+
ctx.ui.notify(`Skipping ${unitType} ${unitId} (pre-dispatch hook).`, "info");
|
|
799
|
+
await new Promise((r) => setImmediate(r));
|
|
800
|
+
return { action: "continue" };
|
|
801
|
+
}
|
|
802
|
+
if (preDispatchResult.action === "replace") {
|
|
803
|
+
prompt = preDispatchResult.prompt ?? prompt;
|
|
804
|
+
if (preDispatchResult.unitType)
|
|
805
|
+
unitType = preDispatchResult.unitType;
|
|
806
|
+
}
|
|
807
|
+
else if (preDispatchResult.prompt) {
|
|
808
|
+
prompt = preDispatchResult.prompt;
|
|
809
|
+
}
|
|
810
|
+
const guardBasePath = _resolveDispatchGuardBasePath(s);
|
|
811
|
+
const priorSliceBlocker = deps.getPriorSliceCompletionBlocker(guardBasePath, deps.getMainBranch(guardBasePath), unitType, unitId);
|
|
812
|
+
if (priorSliceBlocker) {
|
|
813
|
+
await deps.stopAuto(ctx, pi, priorSliceBlocker);
|
|
814
|
+
debugLog("autoLoop", { phase: "exit", reason: "prior-slice-blocker" });
|
|
815
|
+
return { action: "break", reason: "prior-slice-blocker" };
|
|
816
|
+
}
|
|
817
|
+
// Execute-task needs a real writable checkout. The same health check also
|
|
818
|
+
// exists in runUnitPhase, but the stuck-window detector runs before that
|
|
819
|
+
// phase. Check here too so repeated derivations of a broken worktree stop
|
|
820
|
+
// with the actionable worktree error instead of the generic stuck-loop error.
|
|
821
|
+
if (s.basePath && unitType === "execute-task") {
|
|
822
|
+
const gitMarker = join(s.basePath, ".git");
|
|
823
|
+
const hasGit = deps.existsSync(gitMarker);
|
|
824
|
+
if (!hasGit) {
|
|
825
|
+
const msg = `Worktree health check failed: ${s.basePath} has no .git — refusing to dispatch ${unitType} ${unitId}`;
|
|
826
|
+
debugLog("autoLoop", { phase: "dispatch-worktree-health-fail", basePath: s.basePath, hasGit });
|
|
827
|
+
ctx.ui.notify(msg, "error");
|
|
828
|
+
await deps.stopAuto(ctx, pi, msg);
|
|
829
|
+
return { action: "break", reason: "worktree-invalid" };
|
|
830
|
+
}
|
|
831
|
+
}
|
|
757
832
|
// ── Sliding-window stuck detection with graduated recovery ──
|
|
758
833
|
const derivedKey = `${unitType}/${unitId}`;
|
|
759
834
|
// Always record this dispatch in the sliding window so detectStuck() has
|
|
@@ -795,11 +870,18 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
795
870
|
level: 1,
|
|
796
871
|
action: "artifact-found",
|
|
797
872
|
});
|
|
798
|
-
|
|
799
|
-
if (!
|
|
800
|
-
ctx.ui.notify(
|
|
873
|
+
const recoveryDb = refreshRecoveryDbForArtifact(unitType, unitId);
|
|
874
|
+
if (!recoveryDb.ok) {
|
|
875
|
+
ctx.ui.notify(recoveryDb.fatal
|
|
876
|
+
? `${recoveryDb.message} Pausing auto-mode for manual recovery.`
|
|
877
|
+
: `${recoveryDb.message} Keeping stuck state for retry.`, "warning");
|
|
878
|
+
if (recoveryDb.fatal) {
|
|
879
|
+
await deps.pauseAuto(ctx, pi);
|
|
880
|
+
return { action: "break", reason: recoveryDb.reason };
|
|
881
|
+
}
|
|
801
882
|
return { action: "continue" };
|
|
802
883
|
}
|
|
884
|
+
ctx.ui.notify(`Stuck recovery: artifact for ${unitType} ${unitId} found on disk. Invalidating caches.`, "info");
|
|
803
885
|
deps.invalidateAllCaches();
|
|
804
886
|
loopState.recentUnits.length = 0;
|
|
805
887
|
loopState.stuckRecoveryAttempts = 0;
|
|
@@ -818,13 +900,20 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
818
900
|
level: 2,
|
|
819
901
|
action: "artifact-found",
|
|
820
902
|
});
|
|
821
|
-
|
|
822
|
-
if (
|
|
903
|
+
const recoveryDb = refreshRecoveryDbForArtifact(unitType, unitId);
|
|
904
|
+
if (recoveryDb.ok) {
|
|
905
|
+
ctx.ui.notify(`Stuck recovery: artifact for ${unitType} ${unitId} found on disk after cache invalidation. Continuing.`, "info");
|
|
823
906
|
loopState.recentUnits.length = 0;
|
|
824
907
|
loopState.stuckRecoveryAttempts = 0;
|
|
825
908
|
return { action: "continue" };
|
|
826
909
|
}
|
|
827
|
-
ctx.ui.notify(
|
|
910
|
+
ctx.ui.notify(recoveryDb.fatal
|
|
911
|
+
? `${recoveryDb.message} Pausing auto-mode for manual recovery.`
|
|
912
|
+
: `${recoveryDb.message} Stopping for manual recovery.`, "warning");
|
|
913
|
+
if (recoveryDb.fatal) {
|
|
914
|
+
await deps.pauseAuto(ctx, pi);
|
|
915
|
+
return { action: "break", reason: recoveryDb.reason };
|
|
916
|
+
}
|
|
828
917
|
}
|
|
829
918
|
debugLog("autoLoop", {
|
|
830
919
|
phase: "stuck-detected",
|
|
@@ -856,32 +945,6 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
856
945
|
}
|
|
857
946
|
}
|
|
858
947
|
}
|
|
859
|
-
// Pre-dispatch hooks
|
|
860
|
-
const preDispatchResult = deps.runPreDispatchHooks(unitType, unitId, prompt, s.basePath);
|
|
861
|
-
if (preDispatchResult.firedHooks.length > 0) {
|
|
862
|
-
ctx.ui.notify(`Pre-dispatch hook${preDispatchResult.firedHooks.length > 1 ? "s" : ""}: ${preDispatchResult.firedHooks.join(", ")}`, "info");
|
|
863
|
-
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "pre-dispatch-hook", data: { firedHooks: preDispatchResult.firedHooks, action: preDispatchResult.action } });
|
|
864
|
-
}
|
|
865
|
-
if (preDispatchResult.action === "skip") {
|
|
866
|
-
ctx.ui.notify(`Skipping ${unitType} ${unitId} (pre-dispatch hook).`, "info");
|
|
867
|
-
await new Promise((r) => setImmediate(r));
|
|
868
|
-
return { action: "continue" };
|
|
869
|
-
}
|
|
870
|
-
if (preDispatchResult.action === "replace") {
|
|
871
|
-
prompt = preDispatchResult.prompt ?? prompt;
|
|
872
|
-
if (preDispatchResult.unitType)
|
|
873
|
-
unitType = preDispatchResult.unitType;
|
|
874
|
-
}
|
|
875
|
-
else if (preDispatchResult.prompt) {
|
|
876
|
-
prompt = preDispatchResult.prompt;
|
|
877
|
-
}
|
|
878
|
-
const guardBasePath = _resolveDispatchGuardBasePath(s);
|
|
879
|
-
const priorSliceBlocker = deps.getPriorSliceCompletionBlocker(guardBasePath, deps.getMainBranch(guardBasePath), unitType, unitId);
|
|
880
|
-
if (priorSliceBlocker) {
|
|
881
|
-
await deps.stopAuto(ctx, pi, priorSliceBlocker);
|
|
882
|
-
debugLog("autoLoop", { phase: "exit", reason: "prior-slice-blocker" });
|
|
883
|
-
return { action: "break", reason: "prior-slice-blocker" };
|
|
884
|
-
}
|
|
885
948
|
return {
|
|
886
949
|
action: "next",
|
|
887
950
|
data: {
|
|
@@ -1084,8 +1147,9 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1084
1147
|
// Verify the working directory is a valid git checkout with project
|
|
1085
1148
|
// files before dispatching work. A broken worktree causes agents to
|
|
1086
1149
|
// hallucinate summaries since they cannot read or write any files.
|
|
1087
|
-
// Uses
|
|
1088
|
-
//
|
|
1150
|
+
// Uses project classification so project presence is not conflated with
|
|
1151
|
+
// ecosystem marker detection. Static/minimal repos become untyped-existing.
|
|
1152
|
+
let projectClassification = null;
|
|
1089
1153
|
if (s.basePath && unitType === "execute-task") {
|
|
1090
1154
|
const gitMarker = join(s.basePath, ".git");
|
|
1091
1155
|
const hasGit = deps.existsSync(gitMarker);
|
|
@@ -1096,30 +1160,45 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1096
1160
|
await deps.stopAuto(ctx, pi, msg);
|
|
1097
1161
|
return { action: "break", reason: "worktree-invalid" };
|
|
1098
1162
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1163
|
+
projectClassification = classifyProject(s.basePath);
|
|
1164
|
+
if (projectClassification.kind === "invalid-repo") {
|
|
1165
|
+
const msg = `Worktree health check failed: ${s.basePath} classified as invalid-repo (${projectClassification.reason}) — refusing to dispatch ${unitType} ${unitId}`;
|
|
1166
|
+
debugLog("runUnitPhase", { phase: "worktree-health-invalid-repo", basePath: s.basePath, classification: projectClassification });
|
|
1167
|
+
if (_shouldProceedWithInvalidRepoClassificationForTest(projectClassification.reason, hasGit)) {
|
|
1168
|
+
ctx.ui.notify(`Warning: ${s.basePath} project classification could not confirm .git; assuming it has no project content yet — proceeding as greenfield project because worktree health reported .git present`, "warning");
|
|
1169
|
+
}
|
|
1170
|
+
else {
|
|
1171
|
+
ctx.ui.notify(msg, "error");
|
|
1172
|
+
await deps.stopAuto(ctx, pi, msg);
|
|
1173
|
+
return { action: "break", reason: "worktree-invalid" };
|
|
1174
|
+
}
|
|
1107
1175
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1176
|
+
else if (projectClassification.kind === "greenfield") {
|
|
1177
|
+
const projectRoot = s.canonicalProjectRoot;
|
|
1178
|
+
if (!isSamePathLocal(s.basePath, projectRoot)) {
|
|
1179
|
+
const projectRootClassification = classifyProject(projectRoot);
|
|
1180
|
+
if (shouldDegradeEmptyWorktreeToProjectRoot(projectClassification, projectRootClassification)) {
|
|
1181
|
+
debugLog("runUnitPhase", {
|
|
1182
|
+
phase: "worktree-health-degrade-to-project-root",
|
|
1183
|
+
worktreePath: s.basePath,
|
|
1184
|
+
projectRoot,
|
|
1185
|
+
worktreeClassification: projectClassification,
|
|
1186
|
+
projectRootClassification,
|
|
1187
|
+
});
|
|
1188
|
+
ctx.ui.notify(`Warning: ${s.basePath} has no project content, but ${projectRoot} does. Continuing in project root because the milestone worktree cannot represent untracked project files.`, "warning");
|
|
1189
|
+
s.basePath = projectRoot;
|
|
1190
|
+
s.isolationDegraded = true;
|
|
1191
|
+
projectClassification = projectRootClassification;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
if (projectClassification.kind === "greenfield") {
|
|
1196
|
+
debugLog("runUnitPhase", { phase: "worktree-health-greenfield", basePath: s.basePath, classification: projectClassification });
|
|
1197
|
+
ctx.ui.notify(`Warning: ${s.basePath} has no project content yet — proceeding as greenfield project`, "warning");
|
|
1198
|
+
}
|
|
1199
|
+
else if (projectClassification.kind === "untyped-existing") {
|
|
1200
|
+
debugLog("runUnitPhase", { phase: "worktree-health-untyped-existing", basePath: s.basePath, classification: projectClassification });
|
|
1201
|
+
ctx.ui.notify(`Notice: ${s.basePath} has existing project content but no recognized tooling markers — using generic file-level workflow guidance`, "info");
|
|
1123
1202
|
}
|
|
1124
1203
|
}
|
|
1125
1204
|
// Detect retry and capture previous tier for escalation
|
|
@@ -1182,6 +1261,16 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1182
1261
|
}
|
|
1183
1262
|
// Prompt injection
|
|
1184
1263
|
let finalPrompt = prompt;
|
|
1264
|
+
if (unitType === "execute-task") {
|
|
1265
|
+
projectClassification ??= classifyProject(s.basePath);
|
|
1266
|
+
if (projectClassification.kind === "untyped-existing") {
|
|
1267
|
+
const samples = projectClassification.contentFiles.slice(0, 8).join(", ") || "project files";
|
|
1268
|
+
finalPrompt +=
|
|
1269
|
+
"\n\n**Project classification:** Existing untyped project. No recognized build/tooling markers were detected, " +
|
|
1270
|
+
"so use generic file-level workflow guidance. Task plans and completion summaries must list every concrete " +
|
|
1271
|
+
`project file changed in \`files\` or \`expected_output\`. Detected content sample: ${samples}.`;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1185
1274
|
if (s.pendingVerificationRetry) {
|
|
1186
1275
|
const retryCtx = s.pendingVerificationRetry;
|
|
1187
1276
|
s.pendingVerificationRetry = null;
|
|
@@ -1457,7 +1546,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1457
1546
|
{
|
|
1458
1547
|
const currentLedger = deps.getLedger();
|
|
1459
1548
|
if (currentLedger?.units) {
|
|
1460
|
-
const lastUnit = [...currentLedger.units].reverse().find((u) => u.type === unitType && u.id === unitId && u.startedAt === s.currentUnit
|
|
1549
|
+
const lastUnit = [...currentLedger.units].reverse().find((u) => u.type === unitType && u.id === unitId && u.startedAt === _resolveCurrentUnitStartedAtForTest(s.currentUnit));
|
|
1461
1550
|
if (lastUnit && lastUnit.toolCalls === 0) {
|
|
1462
1551
|
if (USER_DRIVEN_DEEP_UNITS.has(unitType) && isAwaitingUserInput(s.lastUnitAgentEndMessages ?? undefined)) {
|
|
1463
1552
|
debugLog("runUnitPhase", {
|
|
@@ -1476,7 +1565,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1476
1565
|
ctx.ui.notify(`${unitType} ${unitId} completed with 0 tool calls — context exhaustion, will retry`, "warning");
|
|
1477
1566
|
// Fall through to next iteration where dispatch will re-derive
|
|
1478
1567
|
// and re-dispatch this unit.
|
|
1479
|
-
return { action: "next", data: { unitStartedAt: s.currentUnit
|
|
1568
|
+
return { action: "next", data: { unitStartedAt: _resolveCurrentUnitStartedAtForTest(s.currentUnit), requestDispatchedAt: unitResult.requestDispatchedAt } };
|
|
1480
1569
|
}
|
|
1481
1570
|
}
|
|
1482
1571
|
}
|
|
@@ -1530,7 +1619,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1530
1619
|
}
|
|
1531
1620
|
s.checkpointSha = null;
|
|
1532
1621
|
}
|
|
1533
|
-
return { action: "next", data: { unitStartedAt: s.currentUnit
|
|
1622
|
+
return { action: "next", data: { unitStartedAt: _resolveCurrentUnitStartedAtForTest(s.currentUnit), requestDispatchedAt: unitResult.requestDispatchedAt } };
|
|
1534
1623
|
}
|
|
1535
1624
|
// ─── runFinalize ──────────────────────────────────────────────────────────────
|
|
1536
1625
|
/**
|
|
@@ -1663,8 +1752,20 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1663
1752
|
debugLog("autoLoop", { phase: "exit", reason: "step-wizard" });
|
|
1664
1753
|
return { action: "break", reason: "step-wizard" };
|
|
1665
1754
|
}
|
|
1755
|
+
if (preUnitSnapshot?.type === "complete-milestone" && s.currentMilestoneId) {
|
|
1756
|
+
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
1757
|
+
if (stop)
|
|
1758
|
+
return stop;
|
|
1759
|
+
}
|
|
1666
1760
|
// Both pre and post verification completed without timeout — reset counter
|
|
1667
1761
|
loopState.consecutiveFinalizeTimeouts = 0;
|
|
1762
|
+
if (preUnitSnapshot) {
|
|
1763
|
+
writeUnitRuntimeRecord(s.basePath, preUnitSnapshot.type, preUnitSnapshot.id, preUnitSnapshot.startedAt, {
|
|
1764
|
+
phase: "finalized",
|
|
1765
|
+
lastProgressAt: Date.now(),
|
|
1766
|
+
lastProgressKind: "finalize-success",
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1668
1769
|
s.currentUnit = null;
|
|
1669
1770
|
clearCurrentPhase();
|
|
1670
1771
|
// Surface accumulated workflow-logger issues for this unit to the user.
|
|
@@ -17,6 +17,9 @@ import { bumpTurnGeneration } from "./turn-epoch.js";
|
|
|
17
17
|
// scoped pendingResolve + pendingAgentEndQueue pattern.
|
|
18
18
|
let _currentResolve = null;
|
|
19
19
|
let _sessionSwitchInFlight = false;
|
|
20
|
+
let _pendingSwitchCancellation = null;
|
|
21
|
+
let _sessionSwitchAbortGraceUntil = 0;
|
|
22
|
+
const DEFAULT_SESSION_SWITCH_ABORT_GRACE_MS = 2_000;
|
|
20
23
|
// ─── Setters (needed for cross-module mutation) ─────────────────────────────
|
|
21
24
|
export function _setCurrentResolve(fn) {
|
|
22
25
|
_currentResolve = fn;
|
|
@@ -24,9 +27,23 @@ export function _setCurrentResolve(fn) {
|
|
|
24
27
|
export function _setSessionSwitchInFlight(v) {
|
|
25
28
|
_sessionSwitchInFlight = v;
|
|
26
29
|
}
|
|
30
|
+
export function _markSessionSwitchAbortGraceWindow(durationMs = DEFAULT_SESSION_SWITCH_ABORT_GRACE_MS) {
|
|
31
|
+
_sessionSwitchAbortGraceUntil = Math.max(_sessionSwitchAbortGraceUntil, Date.now() + durationMs);
|
|
32
|
+
}
|
|
33
|
+
export function _clearSessionSwitchAbortGraceWindow() {
|
|
34
|
+
_sessionSwitchAbortGraceUntil = 0;
|
|
35
|
+
}
|
|
36
|
+
export function isSessionSwitchAbortGraceActive(now = Date.now()) {
|
|
37
|
+
return now < _sessionSwitchAbortGraceUntil;
|
|
38
|
+
}
|
|
27
39
|
export function _clearCurrentResolve() {
|
|
28
40
|
_currentResolve = null;
|
|
29
41
|
}
|
|
42
|
+
export function _consumePendingSwitchCancellation() {
|
|
43
|
+
const pending = _pendingSwitchCancellation;
|
|
44
|
+
_pendingSwitchCancellation = null;
|
|
45
|
+
return pending;
|
|
46
|
+
}
|
|
30
47
|
// ─── resolveAgentEnd ─────────────────────────────────────────────────────────
|
|
31
48
|
/**
|
|
32
49
|
* Called from the agent_end event handler in index.ts to resolve the
|
|
@@ -90,8 +107,18 @@ export function resolveAgentEndCancelled(errorContext) {
|
|
|
90
107
|
debugLog("resolveAgentEndCancelled", { status: "resolving-cancelled" });
|
|
91
108
|
const r = _currentResolve;
|
|
92
109
|
_currentResolve = null;
|
|
110
|
+
_pendingSwitchCancellation = null;
|
|
93
111
|
r({ status: "cancelled", ...(errorContext ? { errorContext } : {}) });
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
if (_sessionSwitchInFlight) {
|
|
115
|
+
bumpTurnGeneration(`cancelled-during-switch:${errorContext?.category ?? "unknown"}`);
|
|
116
|
+
_pendingSwitchCancellation = errorContext ? { errorContext } : {};
|
|
117
|
+
debugLog("resolveAgentEndCancelled", { status: "queued-during-switch" });
|
|
118
|
+
return false;
|
|
94
119
|
}
|
|
120
|
+
debugLog("resolveAgentEndCancelled", { status: "no-pending-resolve" });
|
|
121
|
+
return false;
|
|
95
122
|
}
|
|
96
123
|
// ─── resetPendingResolve (test helper) ───────────────────────────────────────
|
|
97
124
|
/**
|
|
@@ -101,6 +128,8 @@ export function resolveAgentEndCancelled(errorContext) {
|
|
|
101
128
|
export function _resetPendingResolve() {
|
|
102
129
|
_currentResolve = null;
|
|
103
130
|
_sessionSwitchInFlight = false;
|
|
131
|
+
_pendingSwitchCancellation = null;
|
|
132
|
+
_sessionSwitchAbortGraceUntil = 0;
|
|
104
133
|
}
|
|
105
134
|
export function _hasPendingResolveForTest() {
|
|
106
135
|
return _currentResolve !== null;
|