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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// GSD-2 worktree-isolation write gate (#5199).
|
|
2
|
+
//
|
|
3
|
+
// Regression coverage for shouldBlockWorktreeWrite — the helper that prevents
|
|
4
|
+
// the LLM from authoring code at the project root when `git.isolation: worktree`
|
|
5
|
+
// is configured but auto-mode (and its post-unit commit pipeline) hasn't run.
|
|
6
|
+
// Without this gate, writes silently orphan outside git history.
|
|
7
|
+
//
|
|
8
|
+
// Test setup creates a fresh temp project for each isolation case, writes a
|
|
9
|
+
// `.gsd/PREFERENCES.md` with `isolation: "worktree"`, and exercises the helper
|
|
10
|
+
// against the 9 scenarios listed in the issue. No source-grep tests — every
|
|
11
|
+
// assertion exercises the real predicate.
|
|
12
|
+
|
|
13
|
+
import { test, describe, beforeEach, afterEach } from "node:test";
|
|
14
|
+
import assert from "node:assert/strict";
|
|
15
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
|
|
19
|
+
import { shouldBlockWorktreeWrite } from "../bootstrap/write-gate.js";
|
|
20
|
+
import { invalidateAllCaches } from "../cache.js";
|
|
21
|
+
|
|
22
|
+
function makeProject(isolation: "none" | "worktree" | "branch" | null): string {
|
|
23
|
+
const root = mkdtempSync(join(tmpdir(), "wt-write-gate-"));
|
|
24
|
+
if (isolation !== null) {
|
|
25
|
+
mkdirSync(join(root, ".gsd"), { recursive: true });
|
|
26
|
+
writeFileSync(
|
|
27
|
+
join(root, ".gsd", "PREFERENCES.md"),
|
|
28
|
+
`---\ngit:\n isolation: "${isolation}"\n---\n`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
invalidateAllCaches();
|
|
32
|
+
return root;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const PLANNING_WRITE_TOOLS = ["write", "edit", "multi_edit", "notebook_edit"];
|
|
36
|
+
|
|
37
|
+
describe("shouldBlockWorktreeWrite (#5199)", () => {
|
|
38
|
+
let projectRoot: string;
|
|
39
|
+
let prevDisableEnv: string | undefined;
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
prevDisableEnv = process.env.GSD_DISABLE_WORKTREE_WRITE_GUARD;
|
|
43
|
+
delete process.env.GSD_DISABLE_WORKTREE_WRITE_GUARD;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
if (projectRoot) {
|
|
48
|
+
try { rmSync(projectRoot, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
49
|
+
}
|
|
50
|
+
if (prevDisableEnv === undefined) {
|
|
51
|
+
delete process.env.GSD_DISABLE_WORKTREE_WRITE_GUARD;
|
|
52
|
+
} else {
|
|
53
|
+
process.env.GSD_DISABLE_WORKTREE_WRITE_GUARD = prevDisableEnv;
|
|
54
|
+
}
|
|
55
|
+
invalidateAllCaches();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("Case 1: every PLANNING_WRITE_TOOLS variant writing to <root>/app.js is blocked", () => {
|
|
59
|
+
projectRoot = makeProject("worktree");
|
|
60
|
+
for (const tool of PLANNING_WRITE_TOOLS) {
|
|
61
|
+
const result = shouldBlockWorktreeWrite(
|
|
62
|
+
tool,
|
|
63
|
+
join(projectRoot, "app.js"),
|
|
64
|
+
projectRoot,
|
|
65
|
+
/* isAutoLive */ false,
|
|
66
|
+
/* unitType */ null,
|
|
67
|
+
);
|
|
68
|
+
assert.equal(result.block, true, `tool ${tool} should be blocked`);
|
|
69
|
+
assert.match(result.reason ?? "", /HARD BLOCK/);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("Case 2: write to <root>/.gsd/PROJECT.md is allowed", () => {
|
|
74
|
+
projectRoot = makeProject("worktree");
|
|
75
|
+
const result = shouldBlockWorktreeWrite(
|
|
76
|
+
"write",
|
|
77
|
+
join(projectRoot, ".gsd", "PROJECT.md"),
|
|
78
|
+
projectRoot,
|
|
79
|
+
false,
|
|
80
|
+
null,
|
|
81
|
+
);
|
|
82
|
+
assert.equal(result.block, false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("Case 3: write inside <root>/.gsd/worktrees/M001/ is allowed", () => {
|
|
86
|
+
projectRoot = makeProject("worktree");
|
|
87
|
+
const target = join(projectRoot, ".gsd", "worktrees", "M001", "src", "app.js");
|
|
88
|
+
const result = shouldBlockWorktreeWrite("edit", target, projectRoot, false, null);
|
|
89
|
+
assert.equal(result.block, false);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("Case 4: write to <root>/.gsd/worktrees-extra/M001/app.js (prefix trick) is blocked", () => {
|
|
93
|
+
projectRoot = makeProject("worktree");
|
|
94
|
+
const target = join(projectRoot, ".gsd", "worktrees-extra", "M001", "app.js");
|
|
95
|
+
const result = shouldBlockWorktreeWrite("write", target, projectRoot, false, null);
|
|
96
|
+
assert.equal(result.block, true);
|
|
97
|
+
assert.match(result.reason ?? "", /HARD BLOCK/);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("Case 5: isolation=none → allow", () => {
|
|
101
|
+
projectRoot = makeProject("none");
|
|
102
|
+
const result = shouldBlockWorktreeWrite(
|
|
103
|
+
"write",
|
|
104
|
+
join(projectRoot, "app.js"),
|
|
105
|
+
projectRoot,
|
|
106
|
+
false,
|
|
107
|
+
null,
|
|
108
|
+
);
|
|
109
|
+
assert.equal(result.block, false);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("Case 6: isolation=worktree, auto active, effectiveBasePath inside worktree → allow", () => {
|
|
113
|
+
projectRoot = makeProject("worktree");
|
|
114
|
+
const inside = join(projectRoot, ".gsd", "worktrees", "M001");
|
|
115
|
+
mkdirSync(inside, { recursive: true });
|
|
116
|
+
const result = shouldBlockWorktreeWrite(
|
|
117
|
+
"write",
|
|
118
|
+
join(inside, "src", "app.js"),
|
|
119
|
+
inside,
|
|
120
|
+
/* isAutoLive */ true,
|
|
121
|
+
null,
|
|
122
|
+
);
|
|
123
|
+
assert.equal(result.block, false);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("Case 7: isolation=worktree, auto active, effectiveBasePath is project root (cwd never flipped) → block", () => {
|
|
127
|
+
projectRoot = makeProject("worktree");
|
|
128
|
+
const result = shouldBlockWorktreeWrite(
|
|
129
|
+
"write",
|
|
130
|
+
join(projectRoot, "app.js"),
|
|
131
|
+
projectRoot,
|
|
132
|
+
/* isAutoLive */ true,
|
|
133
|
+
null,
|
|
134
|
+
);
|
|
135
|
+
assert.equal(result.block, true);
|
|
136
|
+
assert.match(result.reason ?? "", /HARD BLOCK/);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("Case 8: bootstrap unit type active → allow", () => {
|
|
140
|
+
projectRoot = makeProject("worktree");
|
|
141
|
+
for (const unitType of ["discuss-milestone", "plan-milestone", "init"]) {
|
|
142
|
+
const result = shouldBlockWorktreeWrite(
|
|
143
|
+
"write",
|
|
144
|
+
join(projectRoot, "app.js"),
|
|
145
|
+
projectRoot,
|
|
146
|
+
false,
|
|
147
|
+
unitType,
|
|
148
|
+
);
|
|
149
|
+
assert.equal(result.block, false, `unit ${unitType} should bypass the guard`);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test("Case 9: GSD_DISABLE_WORKTREE_WRITE_GUARD=1 → allow", () => {
|
|
154
|
+
projectRoot = makeProject("worktree");
|
|
155
|
+
process.env.GSD_DISABLE_WORKTREE_WRITE_GUARD = "1";
|
|
156
|
+
const result = shouldBlockWorktreeWrite(
|
|
157
|
+
"write",
|
|
158
|
+
join(projectRoot, "app.js"),
|
|
159
|
+
projectRoot,
|
|
160
|
+
false,
|
|
161
|
+
null,
|
|
162
|
+
);
|
|
163
|
+
assert.equal(result.block, false);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test("non-planning tools (read/grep/bash) pass through unconditionally", () => {
|
|
167
|
+
projectRoot = makeProject("worktree");
|
|
168
|
+
for (const tool of ["read", "grep", "bash", "ls"]) {
|
|
169
|
+
const result = shouldBlockWorktreeWrite(
|
|
170
|
+
tool,
|
|
171
|
+
join(projectRoot, "app.js"),
|
|
172
|
+
projectRoot,
|
|
173
|
+
false,
|
|
174
|
+
null,
|
|
175
|
+
);
|
|
176
|
+
assert.equal(result.block, false, `tool ${tool} must not be gated`);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Shared Context Mode tool result helpers.
|
|
3
|
+
|
|
4
|
+
export interface ToolExecutionResult {
|
|
5
|
+
content: Array<{ type: "text"; text: string }>;
|
|
6
|
+
details: Record<string, unknown>;
|
|
7
|
+
isError?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ContextModeToolName = "gsd_exec" | "gsd_exec_search" | "gsd_resume";
|
|
11
|
+
|
|
12
|
+
export function contextModeDisabledResult(operation: ContextModeToolName): ToolExecutionResult {
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text:
|
|
18
|
+
`${operation} is disabled by \`context_mode.enabled: false\` in preferences. ` +
|
|
19
|
+
"Remove that override or set it to true to re-enable Context Mode tools.",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
details: { operation, error: "context_mode_disabled" },
|
|
23
|
+
isError: true,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
// re-discover past runs without re-executing. Read-only; no DB writes.
|
|
5
5
|
|
|
6
6
|
import { searchExecHistory, type ExecSearchOptions } from "../exec-history.js";
|
|
7
|
+
import { isContextModeEnabled, type ContextModeConfig } from "../preferences-types.js";
|
|
8
|
+
import { contextModeDisabledResult, type ToolExecutionResult } from "./context-mode-tool-result.js";
|
|
7
9
|
|
|
8
10
|
export interface ExecSearchToolParams {
|
|
9
11
|
query?: string;
|
|
@@ -12,16 +14,14 @@ export interface ExecSearchToolParams {
|
|
|
12
14
|
limit?: number;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export interface ToolExecutionResult {
|
|
16
|
-
content: Array<{ type: "text"; text: string }>;
|
|
17
|
-
details: Record<string, unknown>;
|
|
18
|
-
isError?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
17
|
export function executeExecSearch(
|
|
22
18
|
params: ExecSearchToolParams,
|
|
23
|
-
opts: { baseDir: string },
|
|
19
|
+
opts: { baseDir: string; preferences?: { context_mode?: ContextModeConfig } | null },
|
|
24
20
|
): ToolExecutionResult {
|
|
21
|
+
if (!isContextModeEnabled(opts.preferences)) {
|
|
22
|
+
return contextModeDisabledResult("gsd_exec_search");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
25
|
const searchOpts: ExecSearchOptions = {
|
|
26
26
|
query: typeof params.query === "string" ? params.query : undefined,
|
|
27
27
|
runtime: params.runtime,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type ExecSandboxResult,
|
|
13
13
|
} from "../exec-sandbox.js";
|
|
14
14
|
import { isContextModeEnabled, type ContextModeConfig } from "../preferences-types.js";
|
|
15
|
+
import { contextModeDisabledResult, type ToolExecutionResult } from "./context-mode-tool-result.js";
|
|
15
16
|
|
|
16
17
|
export interface ExecToolParams {
|
|
17
18
|
runtime: ExecSandboxRequest["runtime"];
|
|
@@ -20,17 +21,12 @@ export interface ExecToolParams {
|
|
|
20
21
|
timeout_ms?: number;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
export interface ToolExecutionResult {
|
|
24
|
-
content: Array<{ type: "text"; text: string }>;
|
|
25
|
-
details: Record<string, unknown>;
|
|
26
|
-
isError?: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
24
|
export interface ExecToolDeps {
|
|
30
25
|
baseDir: string;
|
|
31
26
|
preferences: { context_mode?: ContextModeConfig } | null;
|
|
32
27
|
/** Optional override for testing. */
|
|
33
28
|
run?: (req: ExecSandboxRequest, opts: ExecSandboxOptions) => Promise<ExecSandboxResult>;
|
|
29
|
+
env?: NodeJS.ProcessEnv;
|
|
34
30
|
now?: () => Date;
|
|
35
31
|
generateId?: () => string;
|
|
36
32
|
}
|
|
@@ -77,21 +73,6 @@ function isEnabled(prefs: ExecToolDeps["preferences"]): boolean {
|
|
|
77
73
|
return isContextModeEnabled(prefs);
|
|
78
74
|
}
|
|
79
75
|
|
|
80
|
-
function disabledResult(): ToolExecutionResult {
|
|
81
|
-
return {
|
|
82
|
-
content: [
|
|
83
|
-
{
|
|
84
|
-
type: "text",
|
|
85
|
-
text:
|
|
86
|
-
"gsd_exec is disabled by `context_mode.enabled: false` in preferences. Remove that " +
|
|
87
|
-
"override (or set it to true) to re-enable sandboxed tool-output execution.",
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
details: { operation: "gsd_exec", error: "context_mode_disabled" },
|
|
91
|
-
isError: true,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
76
|
function paramError(message: string): ToolExecutionResult {
|
|
96
77
|
return {
|
|
97
78
|
content: [{ type: "text", text: `Error: ${message}` }],
|
|
@@ -104,7 +85,7 @@ export async function executeGsdExec(
|
|
|
104
85
|
params: ExecToolParams,
|
|
105
86
|
deps: ExecToolDeps,
|
|
106
87
|
): Promise<ToolExecutionResult> {
|
|
107
|
-
if (!isEnabled(deps.preferences)) return
|
|
88
|
+
if (!isEnabled(deps.preferences)) return contextModeDisabledResult("gsd_exec");
|
|
108
89
|
|
|
109
90
|
const runtime = params.runtime;
|
|
110
91
|
if (runtime !== "bash" && runtime !== "node" && runtime !== "python") {
|
|
@@ -121,7 +102,7 @@ export async function executeGsdExec(
|
|
|
121
102
|
const opts = buildExecOptions(
|
|
122
103
|
deps.baseDir,
|
|
123
104
|
deps.preferences?.context_mode,
|
|
124
|
-
{ now: deps.now, generateId: deps.generateId },
|
|
105
|
+
{ env: deps.env, now: deps.now, generateId: deps.generateId },
|
|
125
106
|
);
|
|
126
107
|
const run = deps.run ?? runExecSandbox;
|
|
127
108
|
|
|
@@ -308,6 +308,7 @@ function includeSupersededMemories(rankedActive: Memory[]): Memory[] {
|
|
|
308
308
|
scope: (row["scope"] as string) ?? "project",
|
|
309
309
|
tags,
|
|
310
310
|
structured_fields: structuredFields,
|
|
311
|
+
last_hit_at: (row["last_hit_at"] as string | null) ?? null,
|
|
311
312
|
};
|
|
312
313
|
});
|
|
313
314
|
} catch {
|
|
@@ -18,6 +18,7 @@ import { renderAllProjections } from "../workflow-projections.js";
|
|
|
18
18
|
import { writeManifest } from "../workflow-manifest.js";
|
|
19
19
|
import { appendEvent } from "../workflow-events.js";
|
|
20
20
|
import { logWarning } from "../workflow-logger.js";
|
|
21
|
+
import { validatePlanningPathScope } from "../planning-path-scope.js";
|
|
21
22
|
|
|
22
23
|
export interface PlanSliceTaskInput {
|
|
23
24
|
taskId: string;
|
|
@@ -141,6 +142,18 @@ export async function handlePlanSlice(
|
|
|
141
142
|
return { error: `validation failed: ${(err as Error).message}` };
|
|
142
143
|
}
|
|
143
144
|
|
|
145
|
+
const pathScopeError = validatePlanningPathScope(
|
|
146
|
+
basePath,
|
|
147
|
+
params.tasks.flatMap((task, index) => [
|
|
148
|
+
{ field: `tasks[${index}].files`, values: task.files },
|
|
149
|
+
{ field: `tasks[${index}].inputs`, values: task.inputs },
|
|
150
|
+
{ field: `tasks[${index}].expectedOutput`, values: task.expectedOutput },
|
|
151
|
+
]),
|
|
152
|
+
);
|
|
153
|
+
if (pathScopeError) {
|
|
154
|
+
return { error: `validation failed: ${pathScopeError}` };
|
|
155
|
+
}
|
|
156
|
+
|
|
144
157
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
145
158
|
// Guards must be inside the transaction so the state they check cannot
|
|
146
159
|
// change between the read and the write (#2723).
|
|
@@ -8,6 +8,7 @@ import { renderAllProjections } from "../workflow-projections.js";
|
|
|
8
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
9
9
|
import { appendEvent } from "../workflow-events.js";
|
|
10
10
|
import { logWarning } from "../workflow-logger.js";
|
|
11
|
+
import { validatePlanningPathScope } from "../planning-path-scope.js";
|
|
11
12
|
|
|
12
13
|
export interface PlanTaskParams {
|
|
13
14
|
milestoneId: string;
|
|
@@ -66,6 +67,15 @@ export async function handlePlanTask(
|
|
|
66
67
|
return { error: `validation failed: ${(err as Error).message}` };
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
const pathScopeError = validatePlanningPathScope(basePath, [
|
|
71
|
+
{ field: "files", values: params.files },
|
|
72
|
+
{ field: "inputs", values: params.inputs },
|
|
73
|
+
{ field: "expectedOutput", values: params.expectedOutput },
|
|
74
|
+
]);
|
|
75
|
+
if (pathScopeError) {
|
|
76
|
+
return { error: `validation failed: ${pathScopeError}` };
|
|
77
|
+
}
|
|
78
|
+
|
|
69
79
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
70
80
|
// Guards must be inside the transaction so the state they check cannot
|
|
71
81
|
// change between the read and the write (#2723).
|
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
// re-deriving project memory state.
|
|
4
4
|
|
|
5
5
|
import { readCompactionSnapshot } from "../compaction-snapshot.js";
|
|
6
|
+
import { isContextModeEnabled, type ContextModeConfig } from "../preferences-types.js";
|
|
7
|
+
import { contextModeDisabledResult, type ToolExecutionResult } from "./context-mode-tool-result.js";
|
|
6
8
|
|
|
7
9
|
export interface ResumeToolParams {
|
|
8
10
|
/** Ignored — reserved for future variant (e.g. dated snapshots). */
|
|
9
11
|
_variant?: string;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
export interface ToolExecutionResult {
|
|
13
|
-
content: Array<{ type: "text"; text: string }>;
|
|
14
|
-
details: Record<string, unknown>;
|
|
15
|
-
isError?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
14
|
export function executeResume(
|
|
19
15
|
_params: ResumeToolParams,
|
|
20
|
-
opts: { baseDir: string },
|
|
16
|
+
opts: { baseDir: string; preferences?: { context_mode?: ContextModeConfig } | null },
|
|
21
17
|
): ToolExecutionResult {
|
|
18
|
+
if (!isContextModeEnabled(opts.preferences)) {
|
|
19
|
+
return contextModeDisabledResult("gsd_resume");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
22
|
const snapshot = readCompactionSnapshot(opts.baseDir);
|
|
23
23
|
if (snapshot == null) {
|
|
24
24
|
return {
|
|
@@ -813,7 +813,7 @@ export async function executeMilestoneStatus(
|
|
|
813
813
|
|
|
814
814
|
return {
|
|
815
815
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
816
|
-
details: { operation: "milestone_status",
|
|
816
|
+
details: { operation: "milestone_status", ...result },
|
|
817
817
|
};
|
|
818
818
|
});
|
|
819
819
|
} catch (err) {
|
|
@@ -112,8 +112,22 @@ const CONTEXT_MODE_LANE_LABELS: Record<Exclude<ContextModePolicy, "none">, strin
|
|
|
112
112
|
docs: "documentation",
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
-
const
|
|
116
|
-
|
|
115
|
+
const CONTEXT_MODE_GUIDANCE_BY_LANE: Record<Exclude<ContextModePolicy, "none">, string> = {
|
|
116
|
+
interview:
|
|
117
|
+
"Use `gsd_resume` to restore prior discussion, `gsd_exec` for noisy discovery, and `gsd_exec_search` before repeating scans.",
|
|
118
|
+
research:
|
|
119
|
+
"Use `gsd_exec` for noisy research scans, `gsd_exec_search` before reruns, and `gsd_resume` to restore prior findings.",
|
|
120
|
+
planning:
|
|
121
|
+
"Use `gsd_resume` for planning continuity, `gsd_exec` for noisy checks, and `gsd_exec_search` before rerunning diagnostics.",
|
|
122
|
+
execution:
|
|
123
|
+
"Use `gsd_exec` for builds, tests, and diagnostics, `gsd_exec_search` before reruns, and `gsd_resume` after compaction or resume.",
|
|
124
|
+
verification:
|
|
125
|
+
"Use `gsd_exec` for verification commands, `gsd_exec_search` to reuse prior evidence, and `gsd_resume` after compaction or resume.",
|
|
126
|
+
orchestration:
|
|
127
|
+
"Use `gsd_resume` before resuming orchestration, `gsd_exec_search` to reuse prior runs, and `gsd_exec` for noisy coordination checks.",
|
|
128
|
+
docs:
|
|
129
|
+
"Use `gsd_resume` for prior context, `gsd_exec_search` for saved evidence, and `gsd_exec` for noisy doc validation commands.",
|
|
130
|
+
};
|
|
117
131
|
|
|
118
132
|
/**
|
|
119
133
|
* Render the Context Mode instruction lane for a unit type. Unknown unit
|
|
@@ -129,15 +143,16 @@ export function composeContextModeInstructions(
|
|
|
129
143
|
if (!manifest || manifest.contextMode === "none") return "";
|
|
130
144
|
|
|
131
145
|
const lane = CONTEXT_MODE_LANE_LABELS[manifest.contextMode];
|
|
146
|
+
const guidance = CONTEXT_MODE_GUIDANCE_BY_LANE[manifest.contextMode];
|
|
132
147
|
if (opts.renderMode === "nested") {
|
|
133
|
-
return `Context Mode (${lane} lane): ${
|
|
148
|
+
return `Context Mode (${lane} lane): ${guidance}`;
|
|
134
149
|
}
|
|
135
150
|
|
|
136
151
|
return [
|
|
137
152
|
"## Context Mode",
|
|
138
153
|
"",
|
|
139
154
|
`Lane: **${lane} lane**.`,
|
|
140
|
-
|
|
155
|
+
guidance,
|
|
141
156
|
].join("\n");
|
|
142
157
|
}
|
|
143
158
|
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
} from "./paths.js";
|
|
11
11
|
import { loadFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js";
|
|
12
12
|
import { parseUnitId } from "./unit-id.js";
|
|
13
|
+
import { getTask, isDbAvailable, refreshOpenDatabaseFromDisk } from "./gsd-db.js";
|
|
14
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
13
15
|
|
|
14
16
|
// Per-record advisory lock — prevents read-modify-write races between
|
|
15
17
|
// concurrent writers updating disjoint fields of the same runtime record.
|
|
@@ -67,17 +69,32 @@ export type UnitRuntimePhase =
|
|
|
67
69
|
| "wrapup-warning-sent"
|
|
68
70
|
| "timeout"
|
|
69
71
|
| "finalize-timeout"
|
|
72
|
+
| "crashed"
|
|
70
73
|
| "recovered"
|
|
71
74
|
| "finalized"
|
|
72
75
|
| "paused"
|
|
73
76
|
| "skipped";
|
|
74
77
|
|
|
78
|
+
export const IN_FLIGHT_RUNTIME_PHASES: ReadonlySet<UnitRuntimePhase> = new Set([
|
|
79
|
+
"dispatched",
|
|
80
|
+
"wrapup-warning-sent",
|
|
81
|
+
"timeout",
|
|
82
|
+
"finalize-timeout",
|
|
83
|
+
"crashed",
|
|
84
|
+
"paused",
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
export function isInFlightRuntimePhase(phase: UnitRuntimePhase): boolean {
|
|
88
|
+
return IN_FLIGHT_RUNTIME_PHASES.has(phase);
|
|
89
|
+
}
|
|
90
|
+
|
|
75
91
|
export interface ExecuteTaskRecoveryStatus {
|
|
76
92
|
planPath: string;
|
|
77
93
|
summaryPath: string;
|
|
78
94
|
summaryExists: boolean;
|
|
79
95
|
taskChecked: boolean;
|
|
80
96
|
nextActionAdvanced: boolean;
|
|
97
|
+
dbComplete: boolean;
|
|
81
98
|
mustHaveCount: number;
|
|
82
99
|
mustHavesMentionedInSummary: number;
|
|
83
100
|
}
|
|
@@ -199,6 +216,12 @@ export async function inspectExecuteTaskDurability(
|
|
|
199
216
|
const escapedTid = tid.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
200
217
|
const taskChecked = !!planContent && new RegExp(`^- \\[[xX]\\] \\*\\*${escapedTid}:`, "m").test(planContent);
|
|
201
218
|
const nextActionAdvanced = !new RegExp(`Execute ${tid}\\b`).test(stateContent);
|
|
219
|
+
let dbComplete = false;
|
|
220
|
+
if (isDbAvailable()) {
|
|
221
|
+
refreshOpenDatabaseFromDisk();
|
|
222
|
+
const task = getTask(mid, sid, tid);
|
|
223
|
+
dbComplete = !!task && isClosedStatus(task.status);
|
|
224
|
+
}
|
|
202
225
|
|
|
203
226
|
// Must-have coverage: load task plan and count mentions in summary
|
|
204
227
|
let mustHaveCount = 0;
|
|
@@ -225,12 +248,14 @@ export async function inspectExecuteTaskDurability(
|
|
|
225
248
|
summaryExists,
|
|
226
249
|
taskChecked,
|
|
227
250
|
nextActionAdvanced,
|
|
251
|
+
dbComplete,
|
|
228
252
|
mustHaveCount,
|
|
229
253
|
mustHavesMentionedInSummary,
|
|
230
254
|
};
|
|
231
255
|
}
|
|
232
256
|
|
|
233
257
|
export function formatExecuteTaskRecoveryStatus(status: ExecuteTaskRecoveryStatus): string {
|
|
258
|
+
if (status.dbComplete) return "DB task status is closed";
|
|
234
259
|
const missing = [] as string[];
|
|
235
260
|
if (!status.summaryExists) missing.push(`summary missing (${status.summaryPath})`);
|
|
236
261
|
if (!status.taskChecked) missing.push(`task checkbox unchecked in ${status.planPath}`);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// GSD-2 + src/resources/extensions/gsd/working-output-messages.ts - Formats and audits user-facing working-state messages.
|
|
2
|
+
|
|
3
|
+
export type WorkingOutputSurface =
|
|
4
|
+
| "loader"
|
|
5
|
+
| "dashboard"
|
|
6
|
+
| "status"
|
|
7
|
+
| "notification"
|
|
8
|
+
| "assistant"
|
|
9
|
+
| "tool";
|
|
10
|
+
|
|
11
|
+
export type WorkingHealthState =
|
|
12
|
+
| "healthy"
|
|
13
|
+
| "waiting"
|
|
14
|
+
| "recovering"
|
|
15
|
+
| "stalled"
|
|
16
|
+
| "provider-error"
|
|
17
|
+
| "timeout"
|
|
18
|
+
| "stopped";
|
|
19
|
+
|
|
20
|
+
export interface WorkingOutputContext {
|
|
21
|
+
unitType?: string;
|
|
22
|
+
unitId?: string;
|
|
23
|
+
health?: WorkingHealthState;
|
|
24
|
+
elapsedMs?: number;
|
|
25
|
+
recoveryAttempts?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface WorkingOutputMessage {
|
|
29
|
+
surface: WorkingOutputSurface;
|
|
30
|
+
message: string;
|
|
31
|
+
context?: WorkingOutputContext;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface WorkingOutputFinding {
|
|
35
|
+
code:
|
|
36
|
+
| "empty-message"
|
|
37
|
+
| "generic-working-message"
|
|
38
|
+
| "misleading-healthy-message"
|
|
39
|
+
| "fake-zero-progress"
|
|
40
|
+
| "missing-action";
|
|
41
|
+
severity: "error" | "warning";
|
|
42
|
+
detail: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const ACTION_RE = /\b(?:wait|pause|paused|retry|retrying|recover|recovering|resume|stop|stopped|run|press|type|configure|restart)\b/i;
|
|
46
|
+
|
|
47
|
+
export function formatAutoUnitWorkingMessage(unitType: string, unitId: string): string {
|
|
48
|
+
switch (unitType) {
|
|
49
|
+
case "research-milestone":
|
|
50
|
+
case "research-slice":
|
|
51
|
+
return `Researching ${unitId}: waiting for provider response`;
|
|
52
|
+
case "plan-milestone":
|
|
53
|
+
case "plan-slice":
|
|
54
|
+
return `Planning ${unitId}: waiting for provider response`;
|
|
55
|
+
case "execute-task":
|
|
56
|
+
return `Executing ${unitId}: waiting for provider response`;
|
|
57
|
+
case "complete-slice":
|
|
58
|
+
case "complete-milestone":
|
|
59
|
+
return `Completing ${unitId}: waiting for provider response`;
|
|
60
|
+
default:
|
|
61
|
+
return `${unitType} ${unitId}: waiting for provider response`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function evaluateWorkingOutputMessage(
|
|
66
|
+
item: WorkingOutputMessage,
|
|
67
|
+
): WorkingOutputFinding[] {
|
|
68
|
+
const findings: WorkingOutputFinding[] = [];
|
|
69
|
+
const message = item.message.trim();
|
|
70
|
+
const health = item.context?.health;
|
|
71
|
+
|
|
72
|
+
if (!message) {
|
|
73
|
+
findings.push({
|
|
74
|
+
code: "empty-message",
|
|
75
|
+
severity: "error",
|
|
76
|
+
detail: `${item.surface} message is empty`,
|
|
77
|
+
});
|
|
78
|
+
return findings;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (/^Working(?:\.\.\.)?(?:\s|\(|$)/i.test(message)) {
|
|
82
|
+
findings.push({
|
|
83
|
+
code: "generic-working-message",
|
|
84
|
+
severity: "warning",
|
|
85
|
+
detail: `${item.surface} message should say what work is running`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (/Progressing well/i.test(message) && health && health !== "healthy") {
|
|
90
|
+
findings.push({
|
|
91
|
+
code: "misleading-healthy-message",
|
|
92
|
+
severity: "error",
|
|
93
|
+
detail: `${item.surface} says progress is healthy while runtime health is ${health}`,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (/\b0\s*\/\s*0\s+slices\b/i.test(message)) {
|
|
98
|
+
findings.push({
|
|
99
|
+
code: "fake-zero-progress",
|
|
100
|
+
severity: "warning",
|
|
101
|
+
detail: `${item.surface} should hide roadmap progress before roadmap slices exist`,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if ((health === "stalled" || health === "provider-error" || health === "timeout") && !ACTION_RE.test(message)) {
|
|
106
|
+
findings.push({
|
|
107
|
+
code: "missing-action",
|
|
108
|
+
severity: "warning",
|
|
109
|
+
detail: `${item.surface} should give the user a next action for ${health}`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return findings;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function evaluateWorkingOutputMessages(
|
|
117
|
+
items: WorkingOutputMessage[],
|
|
118
|
+
): WorkingOutputFinding[] {
|
|
119
|
+
return items.flatMap(evaluateWorkingOutputMessage);
|
|
120
|
+
}
|