gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.cf9433f56
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/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/github-sync/templates.js +39 -8
- package/dist/resources/extensions/gsd/auto/loop.js +48 -10
- package/dist/resources/extensions/gsd/auto/phases.js +66 -45
- package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +32 -16
- package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +124 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
- package/dist/resources/extensions/gsd/auto-start.js +2 -3
- 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.js +77 -5
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +36 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +27 -20
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
- package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
- 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/custom-workflow-engine.js +22 -2
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
- package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
- package/dist/resources/extensions/gsd/detection.js +106 -0
- package/dist/resources/extensions/gsd/git-service.js +36 -4
- package/dist/resources/extensions/gsd/graph.js +9 -3
- package/dist/resources/extensions/gsd/gsd-db.js +146 -13
- package/dist/resources/extensions/gsd/guided-flow.js +82 -16
- 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/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
- package/dist/resources/extensions/gsd/pre-execution-checks.js +7 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +19 -19
- 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/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/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/working-output-messages.js +64 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- package/dist/resources/extensions/gsd/worktree-resolver.js +33 -17
- 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 +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.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/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- 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 +1 -1
- 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-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- 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/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/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
- package/package.json +12 -8
- package/packages/contracts/package.json +1 -1
- 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-ai/dist/models/fake-model.d.ts +12 -0
- package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/fake-model.js +27 -0
- package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/index.js +8 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
- package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/fake.js +319 -0
- package/packages/pi-ai/dist/providers/fake.js.map +1 -0
- package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
- package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
- package/packages/pi-ai/src/models/fake-model.ts +30 -0
- package/packages/pi-ai/src/models/index.ts +9 -0
- package/packages/pi-ai/src/providers/fake.ts +376 -0
- package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
- 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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
- 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 +76 -0
- 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/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 +17 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +99 -0
- 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 +7 -0
- 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/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -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 +33 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
- 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/adaptive-layout.d.ts +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
- 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 +17 -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 +109 -17
- 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 +69 -2
- 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 +93 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -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-state.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -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 +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
- 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 +10 -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.ts +8 -0
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
- 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/runner.test.ts +110 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +19 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +7 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -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/__tests__/style.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
- package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/index.d.ts +1 -0
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +2 -0
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/style.d.ts +41 -0
- package/packages/pi-tui/dist/style.d.ts.map +1 -0
- package/packages/pi-tui/dist/style.js +158 -0
- package/packages/pi-tui/dist/style.js.map +1 -0
- package/packages/pi-tui/dist/tui.d.ts +0 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +21 -16
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
- package/packages/pi-tui/src/index.ts +9 -0
- package/packages/pi-tui/src/style.ts +225 -0
- package/packages/pi-tui/src/tui.ts +23 -16
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +18 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +36 -27
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/github-sync/templates.ts +38 -8
- package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +67 -18
- package/src/resources/extensions/gsd/auto/phases.ts +77 -48
- package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +42 -15
- package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
- package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
- package/src/resources/extensions/gsd/auto-prompts.ts +133 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
- package/src/resources/extensions/gsd/auto-start.ts +7 -6
- 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.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -2
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +27 -19
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
- package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
- package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
- 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/custom-workflow-engine.ts +24 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
- package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
- package/src/resources/extensions/gsd/detection.ts +128 -0
- package/src/resources/extensions/gsd/git-service.ts +46 -8
- package/src/resources/extensions/gsd/graph.ts +12 -5
- package/src/resources/extensions/gsd/gsd-db.ts +168 -13
- package/src/resources/extensions/gsd/guided-flow.ts +98 -16
- 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/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
- package/src/resources/extensions/gsd/pre-execution-checks.ts +7 -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 +19 -19
- 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/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/tests/auto-abort-pause-regression.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +155 -5
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +88 -2
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
- 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 +112 -6
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
- package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
- package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
- 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/fixtures/pr-body/commands-ship-basic.md +52 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +234 -0
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -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/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +38 -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 +19 -0
- package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
- 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/signal-handlers.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
- 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-resolver.test.ts +63 -1
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
- 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/working-output-messages.ts +120 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/src/resources/extensions/gsd/worktree-resolver.ts +36 -15
- package/packages/contracts/tsconfig.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → -5nHJWzSdG-WkPMul_khA}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → -5nHJWzSdG-WkPMul_khA}/_ssgManifest.js +0 -0
|
@@ -32,13 +32,13 @@ import { detectStuck } from "./detect-stuck.js";
|
|
|
32
32
|
import { runUnit } from "./run-unit.js";
|
|
33
33
|
import { debugLog } from "../debug-logger.js";
|
|
34
34
|
import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
|
|
35
|
-
import {
|
|
35
|
+
import { classifyProject } from "../detection.js";
|
|
36
36
|
import { MergeConflictError } from "../git-service.js";
|
|
37
37
|
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
38
38
|
import { pauseAutoForProviderError } from "../provider-error-pause.js";
|
|
39
39
|
import { resumeAutoAfterProviderDelay } from "../bootstrap/provider-error-resume.js";
|
|
40
40
|
import { join, basename } from "node:path";
|
|
41
|
-
import { existsSync, cpSync
|
|
41
|
+
import { existsSync, cpSync } from "node:fs";
|
|
42
42
|
import {
|
|
43
43
|
logWarning,
|
|
44
44
|
logError,
|
|
@@ -50,12 +50,12 @@ import {
|
|
|
50
50
|
} from "../workflow-logger.js";
|
|
51
51
|
import { gsdRoot } from "../paths.js";
|
|
52
52
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
53
|
-
import { verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps } from "../auto-recovery.js";
|
|
53
|
+
import { verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
|
|
54
54
|
import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
55
55
|
import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "./finalize-timeout.js";
|
|
56
56
|
import { getEligibleSlices } from "../slice-parallel-eligibility.js";
|
|
57
57
|
import { startSliceParallel } from "../slice-parallel-orchestrator.js";
|
|
58
|
-
import { isDbAvailable, getMilestoneSlices
|
|
58
|
+
import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
|
|
59
59
|
import type { MinimalModelRegistry } from "../context-budget.js";
|
|
60
60
|
import { ensurePlanV2Graph, isEmptyPlanV2GraphResult, isMissingFinalizedContextResult } from "../uok/plan-v2.js";
|
|
61
61
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
@@ -76,12 +76,6 @@ function isSamePathLocal(a: string, b: string): boolean {
|
|
|
76
76
|
return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function refreshPlanSliceRecoveryDbIfNeeded(unitType: string): boolean {
|
|
80
|
-
if (unitType !== "plan-slice") return true;
|
|
81
|
-
if (!isDbAvailable()) return true;
|
|
82
|
-
return refreshOpenDatabaseFromDisk();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
79
|
// ─── Session timeout auto-resume state ────────────────────────────────────────
|
|
86
80
|
|
|
87
81
|
let consecutiveSessionTimeouts = 0;
|
|
@@ -684,6 +678,7 @@ export async function runPreDispatch(
|
|
|
684
678
|
deps.postflightPopStash(
|
|
685
679
|
s.originalBasePath || s.basePath,
|
|
686
680
|
s.currentMilestoneId!,
|
|
681
|
+
preflightTransition.stashMarker,
|
|
687
682
|
ctx.ui.notify.bind(ctx.ui),
|
|
688
683
|
);
|
|
689
684
|
}
|
|
@@ -797,6 +792,7 @@ export async function runPreDispatch(
|
|
|
797
792
|
deps.postflightPopStash(
|
|
798
793
|
s.originalBasePath || s.basePath,
|
|
799
794
|
s.currentMilestoneId,
|
|
795
|
+
preflightAllComplete.stashMarker,
|
|
800
796
|
ctx.ui.notify.bind(ctx.ui),
|
|
801
797
|
);
|
|
802
798
|
}
|
|
@@ -925,6 +921,7 @@ export async function runPreDispatch(
|
|
|
925
921
|
deps.postflightPopStash(
|
|
926
922
|
s.originalBasePath || s.basePath,
|
|
927
923
|
s.currentMilestoneId,
|
|
924
|
+
preflightComplete.stashMarker,
|
|
928
925
|
ctx.ui.notify.bind(ctx.ui),
|
|
929
926
|
);
|
|
930
927
|
}
|
|
@@ -1097,17 +1094,24 @@ export async function runDispatch(
|
|
|
1097
1094
|
level: 1,
|
|
1098
1095
|
action: "artifact-found",
|
|
1099
1096
|
});
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
"info",
|
|
1103
|
-
);
|
|
1104
|
-
if (!refreshPlanSliceRecoveryDbIfNeeded(unitType)) {
|
|
1097
|
+
const recoveryDb = refreshRecoveryDbForArtifact(unitType, unitId);
|
|
1098
|
+
if (!recoveryDb.ok) {
|
|
1105
1099
|
ctx.ui.notify(
|
|
1106
|
-
|
|
1100
|
+
recoveryDb.fatal
|
|
1101
|
+
? `${recoveryDb.message} Pausing auto-mode for manual recovery.`
|
|
1102
|
+
: `${recoveryDb.message} Keeping stuck state for retry.`,
|
|
1107
1103
|
"warning",
|
|
1108
1104
|
);
|
|
1105
|
+
if (recoveryDb.fatal) {
|
|
1106
|
+
await deps.pauseAuto(ctx, pi);
|
|
1107
|
+
return { action: "break", reason: recoveryDb.reason };
|
|
1108
|
+
}
|
|
1109
1109
|
return { action: "continue" };
|
|
1110
1110
|
}
|
|
1111
|
+
ctx.ui.notify(
|
|
1112
|
+
`Stuck recovery: artifact for ${unitType} ${unitId} found on disk. Invalidating caches.`,
|
|
1113
|
+
"info",
|
|
1114
|
+
);
|
|
1111
1115
|
deps.invalidateAllCaches();
|
|
1112
1116
|
loopState.recentUnits.length = 0;
|
|
1113
1117
|
loopState.stuckRecoveryAttempts = 0;
|
|
@@ -1132,19 +1136,26 @@ export async function runDispatch(
|
|
|
1132
1136
|
level: 2,
|
|
1133
1137
|
action: "artifact-found",
|
|
1134
1138
|
});
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1139
|
+
const recoveryDb = refreshRecoveryDbForArtifact(unitType, unitId);
|
|
1140
|
+
if (recoveryDb.ok) {
|
|
1141
|
+
ctx.ui.notify(
|
|
1142
|
+
`Stuck recovery: artifact for ${unitType} ${unitId} found on disk after cache invalidation. Continuing.`,
|
|
1143
|
+
"info",
|
|
1144
|
+
);
|
|
1140
1145
|
loopState.recentUnits.length = 0;
|
|
1141
1146
|
loopState.stuckRecoveryAttempts = 0;
|
|
1142
1147
|
return { action: "continue" };
|
|
1143
1148
|
}
|
|
1144
1149
|
ctx.ui.notify(
|
|
1145
|
-
|
|
1150
|
+
recoveryDb.fatal
|
|
1151
|
+
? `${recoveryDb.message} Pausing auto-mode for manual recovery.`
|
|
1152
|
+
: `${recoveryDb.message} Stopping for manual recovery.`,
|
|
1146
1153
|
"warning",
|
|
1147
1154
|
);
|
|
1155
|
+
if (recoveryDb.fatal) {
|
|
1156
|
+
await deps.pauseAuto(ctx, pi);
|
|
1157
|
+
return { action: "break", reason: recoveryDb.reason };
|
|
1158
|
+
}
|
|
1148
1159
|
}
|
|
1149
1160
|
debugLog("autoLoop", {
|
|
1150
1161
|
phase: "stuck-detected",
|
|
@@ -1484,8 +1495,9 @@ export async function runUnitPhase(
|
|
|
1484
1495
|
// Verify the working directory is a valid git checkout with project
|
|
1485
1496
|
// files before dispatching work. A broken worktree causes agents to
|
|
1486
1497
|
// hallucinate summaries since they cannot read or write any files.
|
|
1487
|
-
// Uses
|
|
1488
|
-
//
|
|
1498
|
+
// Uses project classification so project presence is not conflated with
|
|
1499
|
+
// ecosystem marker detection. Static/minimal repos become untyped-existing.
|
|
1500
|
+
let projectClassification: ReturnType<typeof classifyProject> | null = null;
|
|
1489
1501
|
if (s.basePath && unitType === "execute-task") {
|
|
1490
1502
|
const gitMarker = join(s.basePath, ".git");
|
|
1491
1503
|
const hasGit = deps.existsSync(gitMarker);
|
|
@@ -1496,30 +1508,29 @@ export async function runUnitPhase(
|
|
|
1496
1508
|
await deps.stopAuto(ctx, pi, msg);
|
|
1497
1509
|
return { action: "break", reason: "worktree-invalid" };
|
|
1498
1510
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
ctx.ui.notify(`Warning: ${s.basePath} has no recognized project files — proceeding as greenfield project`, "warning");
|
|
1511
|
+
projectClassification = classifyProject(s.basePath);
|
|
1512
|
+
if (projectClassification.kind === "invalid-repo") {
|
|
1513
|
+
const msg = `Worktree health check failed: ${s.basePath} classified as invalid-repo (${projectClassification.reason}) — refusing to dispatch ${unitType} ${unitId}`;
|
|
1514
|
+
debugLog("runUnitPhase", { phase: "worktree-health-invalid-repo", basePath: s.basePath, classification: projectClassification });
|
|
1515
|
+
if (projectClassification.reason === "missing .git" && hasGit) {
|
|
1516
|
+
ctx.ui.notify(
|
|
1517
|
+
`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`,
|
|
1518
|
+
"warning",
|
|
1519
|
+
);
|
|
1520
|
+
} else {
|
|
1521
|
+
ctx.ui.notify(msg, "error");
|
|
1522
|
+
await deps.stopAuto(ctx, pi, msg);
|
|
1523
|
+
return { action: "break", reason: "worktree-invalid" };
|
|
1524
|
+
}
|
|
1525
|
+
} else if (projectClassification.kind === "greenfield") {
|
|
1526
|
+
debugLog("runUnitPhase", { phase: "worktree-health-greenfield", basePath: s.basePath, classification: projectClassification });
|
|
1527
|
+
ctx.ui.notify(`Warning: ${s.basePath} has no project content yet — proceeding as greenfield project`, "warning");
|
|
1528
|
+
} else if (projectClassification.kind === "untyped-existing") {
|
|
1529
|
+
debugLog("runUnitPhase", { phase: "worktree-health-untyped-existing", basePath: s.basePath, classification: projectClassification });
|
|
1530
|
+
ctx.ui.notify(
|
|
1531
|
+
`Notice: ${s.basePath} has existing project content but no recognized tooling markers — using generic file-level workflow guidance`,
|
|
1532
|
+
"info",
|
|
1533
|
+
);
|
|
1523
1534
|
}
|
|
1524
1535
|
}
|
|
1525
1536
|
|
|
@@ -1598,6 +1609,17 @@ export async function runUnitPhase(
|
|
|
1598
1609
|
// Prompt injection
|
|
1599
1610
|
let finalPrompt = prompt;
|
|
1600
1611
|
|
|
1612
|
+
if (unitType === "execute-task") {
|
|
1613
|
+
projectClassification ??= classifyProject(s.basePath);
|
|
1614
|
+
if (projectClassification.kind === "untyped-existing") {
|
|
1615
|
+
const samples = projectClassification.contentFiles.slice(0, 8).join(", ") || "project files";
|
|
1616
|
+
finalPrompt +=
|
|
1617
|
+
"\n\n**Project classification:** Existing untyped project. No recognized build/tooling markers were detected, " +
|
|
1618
|
+
"so use generic file-level workflow guidance. Task plans and completion summaries must list every concrete " +
|
|
1619
|
+
`project file changed in \`files\` or \`expected_output\`. Detected content sample: ${samples}.`;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1601
1623
|
if (s.pendingVerificationRetry) {
|
|
1602
1624
|
const retryCtx = s.pendingVerificationRetry;
|
|
1603
1625
|
s.pendingVerificationRetry = null;
|
|
@@ -2251,6 +2273,13 @@ export async function runFinalize(
|
|
|
2251
2273
|
|
|
2252
2274
|
// Both pre and post verification completed without timeout — reset counter
|
|
2253
2275
|
loopState.consecutiveFinalizeTimeouts = 0;
|
|
2276
|
+
if (preUnitSnapshot) {
|
|
2277
|
+
writeUnitRuntimeRecord(s.basePath, preUnitSnapshot.type, preUnitSnapshot.id, preUnitSnapshot.startedAt, {
|
|
2278
|
+
phase: "finalized",
|
|
2279
|
+
lastProgressAt: Date.now(),
|
|
2280
|
+
lastProgressKind: "finalize-success",
|
|
2281
|
+
});
|
|
2282
|
+
}
|
|
2254
2283
|
s.currentUnit = null;
|
|
2255
2284
|
clearCurrentPhase();
|
|
2256
2285
|
|
|
@@ -22,6 +22,7 @@ import { bumpTurnGeneration } from "./turn-epoch.js";
|
|
|
22
22
|
|
|
23
23
|
let _currentResolve: ((result: UnitResult) => void) | null = null;
|
|
24
24
|
let _sessionSwitchInFlight = false;
|
|
25
|
+
let _pendingSwitchCancellation: { errorContext?: ErrorContext } | null = null;
|
|
25
26
|
|
|
26
27
|
// ─── Setters (needed for cross-module mutation) ─────────────────────────────
|
|
27
28
|
|
|
@@ -37,6 +38,12 @@ export function _clearCurrentResolve(): void {
|
|
|
37
38
|
_currentResolve = null;
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
export function _consumePendingSwitchCancellation(): { errorContext?: ErrorContext } | null {
|
|
42
|
+
const pending = _pendingSwitchCancellation;
|
|
43
|
+
_pendingSwitchCancellation = null;
|
|
44
|
+
return pending;
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
// ─── resolveAgentEnd ─────────────────────────────────────────────────────────
|
|
41
48
|
|
|
42
49
|
/**
|
|
@@ -96,7 +103,7 @@ export function bumpAndResolveSynthetic(reason: string): void {
|
|
|
96
103
|
* blocks to ensure the autoLoop is never stuck awaiting a promise that
|
|
97
104
|
* will never resolve. Safe to call when no resolver is pending (no-op).
|
|
98
105
|
*/
|
|
99
|
-
export function resolveAgentEndCancelled(errorContext?: ErrorContext):
|
|
106
|
+
export function resolveAgentEndCancelled(errorContext?: ErrorContext): boolean {
|
|
100
107
|
if (_currentResolve) {
|
|
101
108
|
// Cancellation supersedes the in-flight turn the same way timeout
|
|
102
109
|
// recovery does — bump the turn epoch so any lingering writes from the
|
|
@@ -107,8 +114,22 @@ export function resolveAgentEndCancelled(errorContext?: ErrorContext): void {
|
|
|
107
114
|
debugLog("resolveAgentEndCancelled", { status: "resolving-cancelled" });
|
|
108
115
|
const r = _currentResolve;
|
|
109
116
|
_currentResolve = null;
|
|
117
|
+
_pendingSwitchCancellation = null;
|
|
110
118
|
r({ status: "cancelled", ...(errorContext ? { errorContext } : {}) });
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (_sessionSwitchInFlight) {
|
|
123
|
+
bumpTurnGeneration(
|
|
124
|
+
`cancelled-during-switch:${errorContext?.category ?? "unknown"}`,
|
|
125
|
+
);
|
|
126
|
+
_pendingSwitchCancellation = errorContext ? { errorContext } : {};
|
|
127
|
+
debugLog("resolveAgentEndCancelled", { status: "queued-during-switch" });
|
|
128
|
+
return false;
|
|
111
129
|
}
|
|
130
|
+
|
|
131
|
+
debugLog("resolveAgentEndCancelled", { status: "no-pending-resolve" });
|
|
132
|
+
return false;
|
|
112
133
|
}
|
|
113
134
|
|
|
114
135
|
// ─── resetPendingResolve (test helper) ───────────────────────────────────────
|
|
@@ -120,6 +141,7 @@ export function resolveAgentEndCancelled(errorContext?: ErrorContext): void {
|
|
|
120
141
|
export function _resetPendingResolve(): void {
|
|
121
142
|
_currentResolve = null;
|
|
122
143
|
_sessionSwitchInFlight = false;
|
|
144
|
+
_pendingSwitchCancellation = null;
|
|
123
145
|
}
|
|
124
146
|
|
|
125
147
|
export function _hasPendingResolveForTest(): boolean {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// GSD-2 + src/resources/extensions/gsd/auto/run-unit.ts - Runs one GSD auto-mode unit from session creation through agent completion.
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* auto/run-unit.ts — Single unit execution: session create → prompt → await agent_end.
|
|
3
5
|
*
|
|
@@ -9,7 +11,12 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
9
11
|
import type { AutoSession } from "./session.js";
|
|
10
12
|
import { NEW_SESSION_TIMEOUT_MS } from "./session.js";
|
|
11
13
|
import type { UnitResult } from "./types.js";
|
|
12
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
_clearCurrentResolve,
|
|
16
|
+
_consumePendingSwitchCancellation,
|
|
17
|
+
_setCurrentResolve,
|
|
18
|
+
_setSessionSwitchInFlight,
|
|
19
|
+
} from "./resolve.js";
|
|
13
20
|
import {
|
|
14
21
|
getCurrentTurnGeneration,
|
|
15
22
|
runWithTurnGeneration,
|
|
@@ -17,6 +24,7 @@ import {
|
|
|
17
24
|
import { debugLog } from "../debug-logger.js";
|
|
18
25
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
19
26
|
import { resolveAutoSupervisorConfig } from "../preferences.js";
|
|
27
|
+
import { formatAutoUnitWorkingMessage } from "../working-output-messages.js";
|
|
20
28
|
|
|
21
29
|
// Tracks the latest session-switch attempt so a late timeout settlement from an
|
|
22
30
|
// older runUnit() call cannot clear the guard for a newer one.
|
|
@@ -94,6 +102,7 @@ export async function runUnit(
|
|
|
94
102
|
sessionResult = await Promise.race([sessionPromise, timeoutPromise]);
|
|
95
103
|
} catch (sessionErr) {
|
|
96
104
|
if (sessionTimeoutHandle) clearTimeout(sessionTimeoutHandle);
|
|
105
|
+
_consumePendingSwitchCancellation();
|
|
97
106
|
const msg =
|
|
98
107
|
sessionErr instanceof Error ? sessionErr.message : String(sessionErr);
|
|
99
108
|
debugLog("runUnit", {
|
|
@@ -107,17 +116,20 @@ export async function runUnit(
|
|
|
107
116
|
if (sessionTimeoutHandle) clearTimeout(sessionTimeoutHandle);
|
|
108
117
|
|
|
109
118
|
if (sessionResult.cancelled) {
|
|
119
|
+
_consumePendingSwitchCancellation();
|
|
110
120
|
debugLog("runUnit-session-timeout", { unitType, unitId });
|
|
111
121
|
return { status: "cancelled", errorContext: { message: "Session creation timed out", category: "timeout", isTransient: true } };
|
|
112
122
|
}
|
|
113
123
|
|
|
114
124
|
if (!s.active) {
|
|
125
|
+
_consumePendingSwitchCancellation();
|
|
115
126
|
return { status: "cancelled" };
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
if (s.currentUnitModel && typeof pi.setModel === "function") {
|
|
119
130
|
const restored = await pi.setModel(s.currentUnitModel, { persist: false });
|
|
120
131
|
if (!restored) {
|
|
132
|
+
_consumePendingSwitchCancellation();
|
|
121
133
|
const message =
|
|
122
134
|
`Failed to restore configured model ${s.currentUnitModel.provider}/${s.currentUnitModel.id} after session creation`;
|
|
123
135
|
ctx.ui.notify(
|
|
@@ -142,6 +154,14 @@ export async function runUnit(
|
|
|
142
154
|
const unitPromise = new Promise<UnitResult>((resolve) => {
|
|
143
155
|
_setCurrentResolve(resolve);
|
|
144
156
|
});
|
|
157
|
+
const pendingSwitchCancellation = _consumePendingSwitchCancellation();
|
|
158
|
+
if (pendingSwitchCancellation) {
|
|
159
|
+
_clearCurrentResolve();
|
|
160
|
+
return {
|
|
161
|
+
status: "cancelled",
|
|
162
|
+
...(pendingSwitchCancellation.errorContext ? { errorContext: pendingSwitchCancellation.errorContext } : {}),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
145
165
|
|
|
146
166
|
// ── Provider request-readiness pre-check (#4555) ──
|
|
147
167
|
// Verify the provider can accept requests before dispatching. If the token
|
|
@@ -184,30 +204,37 @@ export async function runUnit(
|
|
|
184
204
|
debugLog("runUnit", { phase: "send-message", unitType, unitId });
|
|
185
205
|
|
|
186
206
|
const requestDispatchedAt = Date.now();
|
|
187
|
-
|
|
188
|
-
{ customType: "gsd-auto", content: prompt, display: s.verbose },
|
|
189
|
-
{ triggerTurn: true },
|
|
190
|
-
);
|
|
207
|
+
ctx.ui.setWorkingMessage?.(formatAutoUnitWorkingMessage(unitType, unitId));
|
|
191
208
|
|
|
192
209
|
// ── Await agent_end with absolute timeout (H4 fix) ──
|
|
193
210
|
// If supervision fails to resolve unitPromise within 30s, treat as cancelled.
|
|
194
211
|
// Without this, a crashed agent that never emits agent_end hangs the loop (#3161).
|
|
195
|
-
debugLog("runUnit", { phase: "awaiting-agent-end", unitType, unitId });
|
|
196
212
|
const supervisor = resolveAutoSupervisorConfig();
|
|
197
213
|
const UNIT_HARD_TIMEOUT_MS = Math.max(
|
|
198
214
|
30_000,
|
|
199
215
|
((supervisor.hard_timeout_minutes ?? 30) * 60 * 1000) + 30_000,
|
|
200
216
|
);
|
|
201
217
|
let unitTimeoutHandle: ReturnType<typeof setTimeout> | undefined;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
218
|
+
let result: UnitResult;
|
|
219
|
+
try {
|
|
220
|
+
pi.sendMessage(
|
|
221
|
+
{ customType: "gsd-auto", content: prompt, display: s.verbose },
|
|
222
|
+
{ triggerTurn: true },
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
debugLog("runUnit", { phase: "awaiting-agent-end", unitType, unitId });
|
|
226
|
+
const timeoutResult = new Promise<UnitResult>((resolve) => {
|
|
227
|
+
unitTimeoutHandle = setTimeout(() => {
|
|
228
|
+
resolve({ status: "cancelled", errorContext: { message: "Unit hard timeout — supervision may have failed", category: "timeout", isTransient: true } });
|
|
229
|
+
}, UNIT_HARD_TIMEOUT_MS);
|
|
230
|
+
});
|
|
231
|
+
result = await runWithTurnGeneration(capturedTurnGen, () =>
|
|
232
|
+
Promise.race([unitPromise, timeoutResult]),
|
|
233
|
+
);
|
|
234
|
+
} finally {
|
|
235
|
+
if (unitTimeoutHandle) clearTimeout(unitTimeoutHandle);
|
|
236
|
+
ctx.ui.setWorkingMessage?.(undefined);
|
|
237
|
+
}
|
|
211
238
|
debugLog("runUnit", {
|
|
212
239
|
phase: "agent-end-received",
|
|
213
240
|
unitType,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// GSD-2 + src/resources/extensions/gsd/auto-dashboard.ts - Auto-mode progress widget rendering and dashboard helpers.
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Auto-mode Dashboard — progress widget rendering, elapsed time formatting,
|
|
3
5
|
* unit description helpers, and slice progress caching.
|
|
@@ -46,6 +48,7 @@ import {
|
|
|
46
48
|
import { logWarning } from "./workflow-logger.js";
|
|
47
49
|
import { formattedShortcutPair } from "./shortcut-defs.js";
|
|
48
50
|
import { homedir } from "node:os";
|
|
51
|
+
import { readUnitRuntimeRecord, type AutoUnitRuntimeRecord } from "./unit-runtime.js";
|
|
49
52
|
|
|
50
53
|
// ─── UAT Slice Extraction ─────────────────────────────────────────────────────
|
|
51
54
|
|
|
@@ -215,6 +218,36 @@ export function formatWidgetTokens(count: number): string {
|
|
|
215
218
|
return `${Math.round(count / 1000000)}M`;
|
|
216
219
|
}
|
|
217
220
|
|
|
221
|
+
export function formatRuntimeHealthSignal(
|
|
222
|
+
record: AutoUnitRuntimeRecord | null,
|
|
223
|
+
now = Date.now(),
|
|
224
|
+
): { level: "green" | "yellow"; summary: string; detail?: string } | null {
|
|
225
|
+
if (!record) return null;
|
|
226
|
+
const idleMs = Math.max(0, now - record.lastProgressAt);
|
|
227
|
+
const idleMinutes = Math.floor(idleMs / 60_000);
|
|
228
|
+
if ((record.recoveryAttempts ?? 0) > 0 || record.phase === "recovered" || record.lastProgressKind.includes("recovery")) {
|
|
229
|
+
return {
|
|
230
|
+
level: "yellow",
|
|
231
|
+
summary: "Recovering",
|
|
232
|
+
detail: `retry ${record.recoveryAttempts ?? 1} after ${record.lastRecoveryReason ?? "idle"} stall`,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (record.progressCount === 0 && idleMs >= 60_000) {
|
|
236
|
+
return {
|
|
237
|
+
level: "yellow",
|
|
238
|
+
summary: "Waiting on provider",
|
|
239
|
+
detail: `no output for ${idleMinutes}m`,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function shouldRenderRoadmapProgress(
|
|
246
|
+
progress: { total: number; activeSliceTasks?: { total: number } | null } | null,
|
|
247
|
+
): progress is { total: number; activeSliceTasks?: { total: number } | null } {
|
|
248
|
+
return !!progress && progress.total > 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
218
251
|
// ─── ETA Estimation ──────────────────────────────────────────────────────────
|
|
219
252
|
|
|
220
253
|
/**
|
|
@@ -622,6 +655,7 @@ export function updateProgressWidget(
|
|
|
622
655
|
let cachedLines: string[] | undefined;
|
|
623
656
|
let cachedWidth: number | undefined;
|
|
624
657
|
let cachedRtkLabel: string | null | undefined;
|
|
658
|
+
let cachedRuntimeRecord: AutoUnitRuntimeRecord | null = null;
|
|
625
659
|
|
|
626
660
|
const refreshRtkLabel = (): void => {
|
|
627
661
|
try {
|
|
@@ -634,7 +668,16 @@ export function updateProgressWidget(
|
|
|
634
668
|
}
|
|
635
669
|
};
|
|
636
670
|
|
|
671
|
+
const refreshRuntimeRecord = (): void => {
|
|
672
|
+
try {
|
|
673
|
+
cachedRuntimeRecord = readUnitRuntimeRecord(accessors.getBasePath(), unitType, unitId);
|
|
674
|
+
} catch {
|
|
675
|
+
cachedRuntimeRecord = null;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
|
|
637
679
|
refreshRtkLabel();
|
|
680
|
+
refreshRuntimeRecord();
|
|
638
681
|
|
|
639
682
|
const pulseTimer = setInterval(() => {
|
|
640
683
|
pulseBright = !pulseBright;
|
|
@@ -652,6 +695,7 @@ export function updateProgressWidget(
|
|
|
652
695
|
updateSliceProgressCache(accessors.getBasePath(), mid.id, slice?.id);
|
|
653
696
|
}
|
|
654
697
|
refreshRtkLabel();
|
|
698
|
+
refreshRuntimeRecord();
|
|
655
699
|
cachedLines = undefined;
|
|
656
700
|
} catch (err) { /* non-fatal */
|
|
657
701
|
logWarning("dashboard", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -685,13 +729,16 @@ export function updateProgressWidget(
|
|
|
685
729
|
|
|
686
730
|
// Health indicator in header
|
|
687
731
|
const score = computeProgressScore();
|
|
688
|
-
const
|
|
689
|
-
|
|
732
|
+
const runtimeSignal = formatRuntimeHealthSignal(cachedRuntimeRecord);
|
|
733
|
+
const healthLevel = runtimeSignal?.level ?? score.level;
|
|
734
|
+
const healthSummary = runtimeSignal?.summary ?? score.summary;
|
|
735
|
+
const healthColor = healthLevel === "green" ? "success"
|
|
736
|
+
: healthLevel === "yellow" ? "warning"
|
|
690
737
|
: "error";
|
|
691
|
-
const healthIcon =
|
|
692
|
-
:
|
|
738
|
+
const healthIcon = healthLevel === "green" ? GLYPH.statusActive
|
|
739
|
+
: healthLevel === "yellow" ? "!"
|
|
693
740
|
: "x";
|
|
694
|
-
const healthStr = ` ${theme.fg(healthColor, healthIcon)} ${theme.fg(healthColor,
|
|
741
|
+
const healthStr = ` ${theme.fg(healthColor, healthIcon)} ${theme.fg(healthColor, healthSummary)}`;
|
|
695
742
|
|
|
696
743
|
const headerLeft = `${pad}${dot} ${theme.fg("accent", theme.bold("GSD"))} ${theme.fg("success", modeTag)}${healthStr}`;
|
|
697
744
|
|
|
@@ -706,7 +753,9 @@ export function updateProgressWidget(
|
|
|
706
753
|
lines.push(rightAlign(headerLeft, headerRight, width));
|
|
707
754
|
|
|
708
755
|
// Show health signal details when degraded (yellow/red)
|
|
709
|
-
if (
|
|
756
|
+
if (runtimeSignal?.detail && widgetMode !== "min") {
|
|
757
|
+
lines.push(`${pad} ${theme.fg("dim", runtimeSignal.detail)}`);
|
|
758
|
+
} else if (score.level !== "green" && score.signals.length > 0 && widgetMode !== "min") {
|
|
710
759
|
// Show up to 3 most relevant signals in compact form
|
|
711
760
|
const topSignals = score.signals
|
|
712
761
|
.filter(s => s.kind === "negative")
|
|
@@ -785,7 +834,7 @@ export function updateProgressWidget(
|
|
|
785
834
|
|
|
786
835
|
// Progress bar
|
|
787
836
|
const roadmapSlices = mid ? getRoadmapSlicesSync() : null;
|
|
788
|
-
if (roadmapSlices) {
|
|
837
|
+
if (shouldRenderRoadmapProgress(roadmapSlices)) {
|
|
789
838
|
const { done, total, activeSliceTasks } = roadmapSlices;
|
|
790
839
|
const barWidth = Math.max(6, Math.min(18, Math.floor(width * 0.25)));
|
|
791
840
|
const pct = total > 0 ? done / total : 0;
|
|
@@ -853,7 +902,7 @@ export function updateProgressWidget(
|
|
|
853
902
|
|
|
854
903
|
const leftLines: string[] = [];
|
|
855
904
|
|
|
856
|
-
if (roadmapSlices) {
|
|
905
|
+
if (shouldRenderRoadmapProgress(roadmapSlices)) {
|
|
857
906
|
const { done, total, activeSliceTasks } = roadmapSlices;
|
|
858
907
|
const barWidth = Math.max(6, Math.min(18, Math.floor(leftColWidth * 0.4)));
|
|
859
908
|
const pct = total > 0 ? done / total : 0;
|
|
@@ -211,6 +211,23 @@ export function hasPendingDeepStage(prefs: GSDPreferences | undefined, basePath:
|
|
|
211
211
|
return gate.status === "pending" || gate.status === "blocked";
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
export function shouldRunDeepProjectSetup(
|
|
215
|
+
state: Pick<GSDState, "phase">,
|
|
216
|
+
prefs: GSDPreferences | undefined,
|
|
217
|
+
basePath: string,
|
|
218
|
+
options: { hasSurvivorBranch?: boolean } = {},
|
|
219
|
+
): boolean {
|
|
220
|
+
if (options.hasSurvivorBranch === true) return false;
|
|
221
|
+
if (
|
|
222
|
+
state.phase !== "pre-planning" &&
|
|
223
|
+
state.phase !== "needs-discussion" &&
|
|
224
|
+
state.phase !== "planning"
|
|
225
|
+
) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
return hasPendingDeepStage(prefs, basePath);
|
|
229
|
+
}
|
|
230
|
+
|
|
214
231
|
function missingSliceStop(mid: string, phase: string): DispatchAction {
|
|
215
232
|
return {
|
|
216
233
|
action: "stop",
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
44
44
|
import { syncStateToProjectRoot } from "./auto-worktree.js";
|
|
45
45
|
import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
46
|
-
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
46
|
+
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
|
|
47
47
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
48
48
|
import { consumeSignal } from "./session-status-io.js";
|
|
49
49
|
import {
|
|
@@ -852,22 +852,22 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
852
852
|
}
|
|
853
853
|
|
|
854
854
|
// Evidence cross-reference (execute-task only)
|
|
855
|
-
//
|
|
856
|
-
//
|
|
857
|
-
//
|
|
858
|
-
// we can still detect units that claimed success but ran no commands.
|
|
855
|
+
// Only compare against concrete command evidence persisted by the task
|
|
856
|
+
// completion tool. A prose Verify field can be satisfied later by the
|
|
857
|
+
// host verification gate, so it is not enough to accuse the unit.
|
|
859
858
|
if (safetyConfig.evidence_cross_reference && s.currentUnit.type === "execute-task") {
|
|
860
859
|
try {
|
|
861
860
|
const actual = getEvidence();
|
|
862
861
|
const bashCalls = actual.filter(e => e.kind === "bash");
|
|
863
|
-
// If the task is marked complete but zero bash commands were run,
|
|
864
|
-
// it's suspicious — the LLM may have fabricated results.
|
|
865
862
|
if (sMid && sSid && sTid && isDbAvailable()) {
|
|
866
863
|
const taskRow = getTask(sMid, sSid, sTid);
|
|
867
|
-
|
|
868
|
-
|
|
864
|
+
const claimedCommands = getVerificationEvidence(sMid, sSid, sTid)
|
|
865
|
+
.map((row) => row.command)
|
|
866
|
+
.filter((command): command is string => typeof command === "string" && command.trim().length > 0);
|
|
867
|
+
if (taskRow?.status === "complete" && claimedCommands.length > 0 && bashCalls.length === 0) {
|
|
868
|
+
logWarning("safety", "task claimed verification command evidence but no execution tool calls were recorded");
|
|
869
869
|
ctx.ui.notify(
|
|
870
|
-
`Safety: task ${sTid}
|
|
870
|
+
`Safety: task ${sTid} claimed command evidence but no execution tool calls were recorded`,
|
|
871
871
|
"warning",
|
|
872
872
|
);
|
|
873
873
|
}
|