gsd-pi 2.64.0 → 2.65.0-dev.5c8557b
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/dist/headless.js +3 -1
- package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
- package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +5 -5
- package/dist/resources/extensions/gsd/auto-post-unit.js +98 -1
- package/dist/resources/extensions/gsd/auto-verification.js +138 -1
- package/dist/resources/extensions/gsd/auto.js +5 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +24 -13
- package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +8 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +16 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +20 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +104 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/notification-overlay.js +256 -0
- package/dist/resources/extensions/gsd/notification-store.js +273 -0
- package/dist/resources/extensions/gsd/notification-widget.js +56 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +464 -0
- package/dist/resources/extensions/gsd/preferences-types.js +4 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +33 -0
- package/dist/resources/extensions/gsd/preferences.js +4 -0
- package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -15
- 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/required-server-files.json +4 -4
- package/dist/web/standalone/.next/routes-manifest.json +6 -0
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +3 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -15
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/qq3YfHPfyqvh3DIMVmsRH/_buildManifest.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +26 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +100 -4
- package/packages/pi-agent-core/src/agent-loop.ts +43 -12
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -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 +8 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -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 +36 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +5 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +9 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +33 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +66 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -0
- package/packages/pi-tui/dist/components/loader.d.ts +4 -2
- package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/loader.js +27 -9
- package/packages/pi-tui/dist/components/loader.js.map +1 -1
- package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/text.js +2 -0
- package/packages/pi-tui/dist/components/text.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +12 -1
- package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +4 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +35 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +82 -0
- package/packages/pi-tui/src/components/loader.ts +27 -10
- package/packages/pi-tui/src/components/text.ts +1 -0
- package/packages/pi-tui/src/overlay-layout.ts +13 -1
- package/packages/pi-tui/src/tui.ts +34 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
- package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +5 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +122 -0
- package/src/resources/extensions/gsd/auto-verification.ts +190 -2
- package/src/resources/extensions/gsd/auto.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +25 -13
- package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +8 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +20 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +28 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +140 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/notification-overlay.ts +295 -0
- package/src/resources/extensions/gsd/notification-store.ts +293 -0
- package/src/resources/extensions/gsd/notification-widget.ts +68 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +573 -0
- package/src/resources/extensions/gsd/preferences-types.ts +28 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +33 -0
- package/src/resources/extensions/gsd/preferences.ts +4 -0
- package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +282 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +999 -0
- package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
- package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +13 -0
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/eebXKteM9EaWyseHKTjqp/_buildManifest.js +0 -1
- /package/dist/web/standalone/.next/static/{eebXKteM9EaWyseHKTjqp → qq3YfHPfyqvh3DIMVmsRH}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pre-execution-pause-wiring.test.ts — Integration tests for pre-execution check → pauseAuto wiring.
|
|
3
|
+
*
|
|
4
|
+
* Tests that verify the control flow from pre-execution checks through to pauseAuto:
|
|
5
|
+
* 1. When runPreExecutionChecks returns status: "fail" with blocking: true, pauseAuto is called
|
|
6
|
+
* 2. When enhanced_verification_strict: true and status: "warn", pauseAuto is also called
|
|
7
|
+
*
|
|
8
|
+
* These are integration-level tests that exercise the actual postUnitPostVerification function
|
|
9
|
+
* with controlled mocks for external dependencies.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, test, mock, beforeEach, afterEach } from "node:test";
|
|
13
|
+
import assert from "node:assert/strict";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import { mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
|
|
18
|
+
import { postUnitPostVerification, type PostUnitContext } from "../auto-post-unit.ts";
|
|
19
|
+
import { AutoSession } from "../auto/session.ts";
|
|
20
|
+
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask } from "../gsd-db.ts";
|
|
21
|
+
import { invalidateAllCaches } from "../cache.ts";
|
|
22
|
+
import { _clearGsdRootCache } from "../paths.ts";
|
|
23
|
+
|
|
24
|
+
// ─── Test Fixtures ───────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
let tempDir: string;
|
|
27
|
+
let dbPath: string;
|
|
28
|
+
let originalCwd: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a minimal mock ExtensionContext.
|
|
32
|
+
*/
|
|
33
|
+
function makeMockCtx() {
|
|
34
|
+
return {
|
|
35
|
+
ui: {
|
|
36
|
+
notify: mock.fn(),
|
|
37
|
+
setStatus: () => {},
|
|
38
|
+
setWidget: () => {},
|
|
39
|
+
setFooter: () => {},
|
|
40
|
+
},
|
|
41
|
+
model: { id: "test-model" },
|
|
42
|
+
} as any;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a minimal mock ExtensionAPI.
|
|
47
|
+
*/
|
|
48
|
+
function makeMockPi() {
|
|
49
|
+
return {
|
|
50
|
+
sendMessage: mock.fn(),
|
|
51
|
+
setModel: mock.fn(async () => true),
|
|
52
|
+
} as any;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a minimal AutoSession for testing.
|
|
57
|
+
*/
|
|
58
|
+
function makeMockSession(basePath: string, currentUnit?: { type: string; id: string }): AutoSession {
|
|
59
|
+
const s = new AutoSession();
|
|
60
|
+
s.basePath = basePath;
|
|
61
|
+
s.active = true;
|
|
62
|
+
if (currentUnit) {
|
|
63
|
+
s.currentUnit = {
|
|
64
|
+
type: currentUnit.type,
|
|
65
|
+
id: currentUnit.id,
|
|
66
|
+
startedAt: Date.now(),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return s;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create a PostUnitContext with a mockable pauseAuto.
|
|
74
|
+
*/
|
|
75
|
+
function makePostUnitContext(
|
|
76
|
+
s: AutoSession,
|
|
77
|
+
ctx: ReturnType<typeof makeMockCtx>,
|
|
78
|
+
pi: ReturnType<typeof makeMockPi>,
|
|
79
|
+
pauseAutoMock: ReturnType<typeof mock.fn>,
|
|
80
|
+
): PostUnitContext {
|
|
81
|
+
return {
|
|
82
|
+
s,
|
|
83
|
+
ctx,
|
|
84
|
+
pi,
|
|
85
|
+
buildSnapshotOpts: () => ({}),
|
|
86
|
+
lockBase: () => tempDir,
|
|
87
|
+
stopAuto: mock.fn(async () => {}) as unknown as PostUnitContext["stopAuto"],
|
|
88
|
+
pauseAuto: pauseAutoMock as unknown as PostUnitContext["pauseAuto"],
|
|
89
|
+
updateProgressWidget: () => {},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Set up a temp directory with GSD structure and DB.
|
|
95
|
+
* Also changes cwd so preferences loading finds the right PREFERENCES.md.
|
|
96
|
+
*/
|
|
97
|
+
function setupTestEnvironment(): void {
|
|
98
|
+
// Save original cwd so we can restore it
|
|
99
|
+
originalCwd = process.cwd();
|
|
100
|
+
|
|
101
|
+
tempDir = join(tmpdir(), `pre-exec-pause-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
102
|
+
mkdirSync(tempDir, { recursive: true });
|
|
103
|
+
|
|
104
|
+
// Create .gsd directory structure
|
|
105
|
+
const gsdDir = join(tempDir, ".gsd");
|
|
106
|
+
mkdirSync(gsdDir, { recursive: true });
|
|
107
|
+
|
|
108
|
+
// Create milestones directory structure
|
|
109
|
+
const milestonesDir = join(gsdDir, "milestones", "M001", "slices", "S01", "tasks");
|
|
110
|
+
mkdirSync(milestonesDir, { recursive: true });
|
|
111
|
+
|
|
112
|
+
// Change cwd so loadEffectiveGSDPreferences finds our PREFERENCES.md
|
|
113
|
+
process.chdir(tempDir);
|
|
114
|
+
|
|
115
|
+
// Clear gsdRoot cache so it finds the new .gsd directory
|
|
116
|
+
_clearGsdRootCache();
|
|
117
|
+
|
|
118
|
+
// Initialize DB
|
|
119
|
+
dbPath = join(gsdDir, "gsd.db");
|
|
120
|
+
openDatabase(dbPath);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Clean up test environment.
|
|
125
|
+
*/
|
|
126
|
+
function cleanupTestEnvironment(): void {
|
|
127
|
+
// Restore original cwd before cleanup
|
|
128
|
+
try {
|
|
129
|
+
process.chdir(originalCwd);
|
|
130
|
+
} catch {
|
|
131
|
+
// Ignore if original cwd doesn't exist
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
closeDatabase();
|
|
136
|
+
} catch {
|
|
137
|
+
// Ignore close errors
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
141
|
+
} catch {
|
|
142
|
+
// Ignore cleanup errors
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Create a PREFERENCES.md file with specified preferences.
|
|
148
|
+
* Uses YAML frontmatter format (---\nkey: value\n---).
|
|
149
|
+
* Also invalidates caches so the preferences are re-read.
|
|
150
|
+
*/
|
|
151
|
+
function writePreferences(prefs: Record<string, unknown>): void {
|
|
152
|
+
const yamlLines = Object.entries(prefs).map(([k, v]) => `${k}: ${JSON.stringify(v)}`);
|
|
153
|
+
const prefsContent = `---
|
|
154
|
+
${yamlLines.join("\n")}
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
# GSD Preferences
|
|
158
|
+
`;
|
|
159
|
+
writeFileSync(join(tempDir, ".gsd", "PREFERENCES.md"), prefsContent);
|
|
160
|
+
// Invalidate caches so the new preferences file is found
|
|
161
|
+
invalidateAllCaches();
|
|
162
|
+
_clearGsdRootCache();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Create tasks in DB that will cause pre-execution checks to fail.
|
|
167
|
+
* A task that references a non-existent file will produce a blocking failure.
|
|
168
|
+
*/
|
|
169
|
+
function createFailingTasks(): void {
|
|
170
|
+
// Insert milestone first
|
|
171
|
+
insertMilestone({ id: "M001" });
|
|
172
|
+
|
|
173
|
+
// Insert slice
|
|
174
|
+
insertSlice({
|
|
175
|
+
id: "S01",
|
|
176
|
+
milestoneId: "M001",
|
|
177
|
+
title: "Test Slice",
|
|
178
|
+
risk: "low",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Create a task that references a file that doesn't exist
|
|
182
|
+
// This will cause checkFilePathConsistency to produce a blocking failure
|
|
183
|
+
insertTask({
|
|
184
|
+
id: "T01",
|
|
185
|
+
sliceId: "S01",
|
|
186
|
+
milestoneId: "M001",
|
|
187
|
+
title: "Task with missing file",
|
|
188
|
+
status: "pending",
|
|
189
|
+
planning: {
|
|
190
|
+
description: "This task references a non-existent file",
|
|
191
|
+
estimate: "1h",
|
|
192
|
+
files: ["nonexistent-file-that-does-not-exist.ts"],
|
|
193
|
+
verify: "npm test",
|
|
194
|
+
inputs: [],
|
|
195
|
+
expectedOutput: [],
|
|
196
|
+
observabilityImpact: "",
|
|
197
|
+
},
|
|
198
|
+
sequence: 0,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Create tasks in DB that will produce only warnings (non-blocking issues).
|
|
204
|
+
* Interface contract mismatches produce warnings, not blocking failures.
|
|
205
|
+
*/
|
|
206
|
+
function createWarningOnlyTasks(): void {
|
|
207
|
+
// Insert milestone first
|
|
208
|
+
insertMilestone({ id: "M001" });
|
|
209
|
+
|
|
210
|
+
// Insert slice
|
|
211
|
+
insertSlice({
|
|
212
|
+
id: "S01",
|
|
213
|
+
milestoneId: "M001",
|
|
214
|
+
title: "Test Slice",
|
|
215
|
+
risk: "low",
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Create tasks with interface contract mismatch (produces warn, not fail)
|
|
219
|
+
insertTask({
|
|
220
|
+
id: "T01",
|
|
221
|
+
sliceId: "S01",
|
|
222
|
+
milestoneId: "M001",
|
|
223
|
+
title: "Task 1 with function signature",
|
|
224
|
+
status: "pending",
|
|
225
|
+
planning: {
|
|
226
|
+
description: `
|
|
227
|
+
\`\`\`typescript
|
|
228
|
+
function processData(input: string): boolean
|
|
229
|
+
\`\`\`
|
|
230
|
+
`.trim(),
|
|
231
|
+
estimate: "1h",
|
|
232
|
+
files: [],
|
|
233
|
+
verify: "npm test",
|
|
234
|
+
inputs: [],
|
|
235
|
+
expectedOutput: [],
|
|
236
|
+
observabilityImpact: "",
|
|
237
|
+
},
|
|
238
|
+
sequence: 0,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
insertTask({
|
|
242
|
+
id: "T02",
|
|
243
|
+
sliceId: "S01",
|
|
244
|
+
milestoneId: "M001",
|
|
245
|
+
title: "Task 2 with mismatched signature",
|
|
246
|
+
status: "pending",
|
|
247
|
+
planning: {
|
|
248
|
+
description: `
|
|
249
|
+
\`\`\`typescript
|
|
250
|
+
function processData(input: number): string
|
|
251
|
+
\`\`\`
|
|
252
|
+
`.trim(),
|
|
253
|
+
estimate: "1h",
|
|
254
|
+
files: [],
|
|
255
|
+
verify: "npm test",
|
|
256
|
+
inputs: [],
|
|
257
|
+
expectedOutput: [],
|
|
258
|
+
observabilityImpact: "",
|
|
259
|
+
},
|
|
260
|
+
sequence: 1,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ─── Tests ───────────────────────────────────────────────────────────────────
|
|
265
|
+
|
|
266
|
+
describe("Pre-execution checks → pauseAuto wiring", () => {
|
|
267
|
+
beforeEach(() => {
|
|
268
|
+
setupTestEnvironment();
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
afterEach(() => {
|
|
272
|
+
cleanupTestEnvironment();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("pauseAuto is called when pre-execution checks return status: fail with blocking: true", async () => {
|
|
276
|
+
// Set up tasks that will cause a blocking failure
|
|
277
|
+
createFailingTasks();
|
|
278
|
+
|
|
279
|
+
// Create mocks
|
|
280
|
+
const ctx = makeMockCtx();
|
|
281
|
+
const pi = makeMockPi();
|
|
282
|
+
const pauseAutoMock = mock.fn(async () => {});
|
|
283
|
+
const s = makeMockSession(tempDir, { type: "plan-slice", id: "M001/S01" });
|
|
284
|
+
const pctx = makePostUnitContext(s, ctx, pi, pauseAutoMock);
|
|
285
|
+
|
|
286
|
+
// Call postUnitPostVerification
|
|
287
|
+
const result = await postUnitPostVerification(pctx);
|
|
288
|
+
|
|
289
|
+
// Verify pauseAuto was called
|
|
290
|
+
assert.equal(
|
|
291
|
+
pauseAutoMock.mock.callCount(),
|
|
292
|
+
1,
|
|
293
|
+
"pauseAuto should be called exactly once when pre-execution checks fail with blocking issues"
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
// Verify return value is "stopped"
|
|
297
|
+
assert.equal(
|
|
298
|
+
result,
|
|
299
|
+
"stopped",
|
|
300
|
+
"postUnitPostVerification should return 'stopped' when pre-execution checks fail"
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
// Verify UI was notified of the failure
|
|
304
|
+
const notifyCalls = ctx.ui.notify.mock.calls;
|
|
305
|
+
const errorNotify = notifyCalls.find(
|
|
306
|
+
(call: { arguments: unknown[] }) =>
|
|
307
|
+
call.arguments[1] === "error" &&
|
|
308
|
+
String(call.arguments[0]).includes("Pre-execution checks failed")
|
|
309
|
+
);
|
|
310
|
+
assert.ok(errorNotify, "Should show error notification about pre-execution check failure");
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
test("pauseAuto is called when enhanced_verification_strict: true and pre-execution returns warn", async () => {
|
|
314
|
+
// Write preferences with strict mode enabled
|
|
315
|
+
writePreferences({
|
|
316
|
+
enhanced_verification: true,
|
|
317
|
+
enhanced_verification_pre: true,
|
|
318
|
+
enhanced_verification_strict: true,
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Set up tasks that will produce only warnings (interface contract mismatch)
|
|
322
|
+
createWarningOnlyTasks();
|
|
323
|
+
|
|
324
|
+
// Create mocks
|
|
325
|
+
const ctx = makeMockCtx();
|
|
326
|
+
const pi = makeMockPi();
|
|
327
|
+
const pauseAutoMock = mock.fn(async () => {});
|
|
328
|
+
const s = makeMockSession(tempDir, { type: "plan-slice", id: "M001/S01" });
|
|
329
|
+
const pctx = makePostUnitContext(s, ctx, pi, pauseAutoMock);
|
|
330
|
+
|
|
331
|
+
// Call postUnitPostVerification
|
|
332
|
+
const result = await postUnitPostVerification(pctx);
|
|
333
|
+
|
|
334
|
+
// Verify pauseAuto was called (strict mode promotes warnings to blocking)
|
|
335
|
+
assert.equal(
|
|
336
|
+
pauseAutoMock.mock.callCount(),
|
|
337
|
+
1,
|
|
338
|
+
"pauseAuto should be called when strict mode is enabled and pre-execution returns warn"
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
// Verify return value is "stopped"
|
|
342
|
+
assert.equal(
|
|
343
|
+
result,
|
|
344
|
+
"stopped",
|
|
345
|
+
"postUnitPostVerification should return 'stopped' when strict mode treats warnings as blocking"
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
// Verify UI was notified of the warning
|
|
349
|
+
const notifyCalls = ctx.ui.notify.mock.calls;
|
|
350
|
+
const warnNotify = notifyCalls.find(
|
|
351
|
+
(call: { arguments: unknown[] }) =>
|
|
352
|
+
call.arguments[1] === "warning" &&
|
|
353
|
+
String(call.arguments[0]).includes("Pre-execution checks passed with warnings")
|
|
354
|
+
);
|
|
355
|
+
assert.ok(warnNotify, "Should show warning notification about pre-execution check warnings");
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test("pauseAuto is NOT called when enhanced_verification_strict: false and pre-execution returns warn", async () => {
|
|
359
|
+
// Write preferences with strict mode disabled (default behavior)
|
|
360
|
+
writePreferences({
|
|
361
|
+
enhanced_verification: true,
|
|
362
|
+
enhanced_verification_pre: true,
|
|
363
|
+
enhanced_verification_strict: false,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Set up tasks that will produce only warnings
|
|
367
|
+
createWarningOnlyTasks();
|
|
368
|
+
|
|
369
|
+
// Create mocks
|
|
370
|
+
const ctx = makeMockCtx();
|
|
371
|
+
const pi = makeMockPi();
|
|
372
|
+
const pauseAutoMock = mock.fn(async () => {});
|
|
373
|
+
const s = makeMockSession(tempDir, { type: "plan-slice", id: "M001/S01" });
|
|
374
|
+
const pctx = makePostUnitContext(s, ctx, pi, pauseAutoMock);
|
|
375
|
+
|
|
376
|
+
// Call postUnitPostVerification
|
|
377
|
+
const result = await postUnitPostVerification(pctx);
|
|
378
|
+
|
|
379
|
+
// Verify pauseAuto was NOT called (warnings don't block in non-strict mode)
|
|
380
|
+
assert.equal(
|
|
381
|
+
pauseAutoMock.mock.callCount(),
|
|
382
|
+
0,
|
|
383
|
+
"pauseAuto should NOT be called when strict mode is disabled and only warnings exist"
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
// Verify return value is "continue" (not "stopped")
|
|
387
|
+
assert.equal(
|
|
388
|
+
result,
|
|
389
|
+
"continue",
|
|
390
|
+
"postUnitPostVerification should return 'continue' when warnings don't block in non-strict mode"
|
|
391
|
+
);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
test("pre-execution checks are skipped when unit type is not plan-slice", async () => {
|
|
395
|
+
// Set up tasks that would fail if checked
|
|
396
|
+
createFailingTasks();
|
|
397
|
+
|
|
398
|
+
// Create mocks with execute-task unit (not plan-slice)
|
|
399
|
+
const ctx = makeMockCtx();
|
|
400
|
+
const pi = makeMockPi();
|
|
401
|
+
const pauseAutoMock = mock.fn(async () => {});
|
|
402
|
+
const s = makeMockSession(tempDir, { type: "execute-task", id: "M001/S01/T01" });
|
|
403
|
+
const pctx = makePostUnitContext(s, ctx, pi, pauseAutoMock);
|
|
404
|
+
|
|
405
|
+
// Call postUnitPostVerification
|
|
406
|
+
const result = await postUnitPostVerification(pctx);
|
|
407
|
+
|
|
408
|
+
// Verify pauseAuto was NOT called (pre-execution checks only run for plan-slice)
|
|
409
|
+
assert.equal(
|
|
410
|
+
pauseAutoMock.mock.callCount(),
|
|
411
|
+
0,
|
|
412
|
+
"pauseAuto should NOT be called for non-plan-slice unit types"
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
// Verify return value is "continue"
|
|
416
|
+
assert.equal(
|
|
417
|
+
result,
|
|
418
|
+
"continue",
|
|
419
|
+
"postUnitPostVerification should return 'continue' for non-plan-slice unit types"
|
|
420
|
+
);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("pre-execution checks are skipped when enhanced_verification_pre: false", async () => {
|
|
424
|
+
// Write preferences with pre-execution checks disabled
|
|
425
|
+
writePreferences({
|
|
426
|
+
enhanced_verification: true,
|
|
427
|
+
enhanced_verification_pre: false,
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// Set up tasks that would fail if checked
|
|
431
|
+
createFailingTasks();
|
|
432
|
+
|
|
433
|
+
// Create mocks
|
|
434
|
+
const ctx = makeMockCtx();
|
|
435
|
+
const pi = makeMockPi();
|
|
436
|
+
const pauseAutoMock = mock.fn(async () => {});
|
|
437
|
+
const s = makeMockSession(tempDir, { type: "plan-slice", id: "M001/S01" });
|
|
438
|
+
const pctx = makePostUnitContext(s, ctx, pi, pauseAutoMock);
|
|
439
|
+
|
|
440
|
+
// Call postUnitPostVerification
|
|
441
|
+
const result = await postUnitPostVerification(pctx);
|
|
442
|
+
|
|
443
|
+
// Verify pauseAuto was NOT called (pre-execution checks disabled)
|
|
444
|
+
assert.equal(
|
|
445
|
+
pauseAutoMock.mock.callCount(),
|
|
446
|
+
0,
|
|
447
|
+
"pauseAuto should NOT be called when enhanced_verification_pre is disabled"
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
// Verify return value is "continue"
|
|
451
|
+
assert.equal(
|
|
452
|
+
result,
|
|
453
|
+
"continue",
|
|
454
|
+
"postUnitPostVerification should return 'continue' when pre-execution checks are disabled"
|
|
455
|
+
);
|
|
456
|
+
});
|
|
457
|
+
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// GSD-2 — Regression test for #3615: unstructured "continue" must inject task context
|
|
2
|
+
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bug #3615: When a user types "continue" (or any bare text) to resume
|
|
6
|
+
* an in-progress session, buildGuidedExecuteContextInjection() only
|
|
7
|
+
* matched two hardcoded regex patterns (auto-dispatch and guided-resume).
|
|
8
|
+
* The function returned null for any other input, so no task context was
|
|
9
|
+
* injected — causing the agent to rebuild everything from scratch and
|
|
10
|
+
* burn ~86k tokens.
|
|
11
|
+
*
|
|
12
|
+
* This test verifies:
|
|
13
|
+
* 1. Structural: the fallback exists with phase + intent guards
|
|
14
|
+
* 2. Behavioral: RESUME_INTENT_PATTERNS matches expected prompts and
|
|
15
|
+
* rejects non-resume prompts (control, help, diagnostic, etc.)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { describe, test } from "node:test";
|
|
19
|
+
import assert from "node:assert/strict";
|
|
20
|
+
import { readFileSync } from "node:fs";
|
|
21
|
+
import { join, dirname } from "node:path";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
|
|
24
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
const systemContextSource = readFileSync(
|
|
26
|
+
join(__dirname, "..", "bootstrap", "system-context.ts"),
|
|
27
|
+
"utf-8",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// ── Structural tests ────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
describe("#3615 — structural: fallback exists with correct guards", () => {
|
|
33
|
+
const fnStart = systemContextSource.indexOf("async function buildGuidedExecuteContextInjection(");
|
|
34
|
+
assert.ok(fnStart >= 0, "should find buildGuidedExecuteContextInjection");
|
|
35
|
+
const fnEnd = systemContextSource.indexOf("\nasync function ", fnStart + 1);
|
|
36
|
+
const fnBody = fnEnd >= 0
|
|
37
|
+
? systemContextSource.slice(fnStart, fnEnd)
|
|
38
|
+
: systemContextSource.slice(fnStart);
|
|
39
|
+
|
|
40
|
+
test("has a deriveState fallback after the two regex branches", () => {
|
|
41
|
+
const deriveStateCalls = fnBody.match(/deriveState\(basePath\)/g);
|
|
42
|
+
assert.ok(
|
|
43
|
+
deriveStateCalls && deriveStateCalls.length >= 2,
|
|
44
|
+
`expected >=2 deriveState(basePath) calls, got ${deriveStateCalls?.length ?? 0}`,
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("fallback is phase-gated to executing only", () => {
|
|
49
|
+
const afterFallback = fnBody.indexOf("// Fallback:");
|
|
50
|
+
assert.ok(afterFallback >= 0, "should have a fallback comment");
|
|
51
|
+
const fallbackSection = fnBody.slice(afterFallback);
|
|
52
|
+
assert.ok(
|
|
53
|
+
fallbackSection.includes('state.phase === "executing"'),
|
|
54
|
+
'fallback must be gated on state.phase === "executing"',
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("fallback is intent-gated via RESUME_INTENT_PATTERNS", () => {
|
|
59
|
+
const afterFallback = fnBody.indexOf("// Fallback:");
|
|
60
|
+
const fallbackSection = fnBody.slice(afterFallback);
|
|
61
|
+
assert.ok(
|
|
62
|
+
fallbackSection.includes("RESUME_INTENT_PATTERNS"),
|
|
63
|
+
"fallback must check RESUME_INTENT_PATTERNS before deriveState",
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("fallback calls buildTaskExecutionContextInjection with derived state", () => {
|
|
68
|
+
const afterFallback = fnBody.indexOf("// Fallback:");
|
|
69
|
+
const fallbackSection = fnBody.slice(afterFallback);
|
|
70
|
+
assert.ok(
|
|
71
|
+
fallbackSection.includes("buildTaskExecutionContextInjection") &&
|
|
72
|
+
fallbackSection.includes("state.activeMilestone.id") &&
|
|
73
|
+
fallbackSection.includes("state.activeSlice.id") &&
|
|
74
|
+
fallbackSection.includes("state.activeTask.id"),
|
|
75
|
+
"fallback must call buildTaskExecutionContextInjection with state-derived IDs",
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("only one return null at the end", () => {
|
|
80
|
+
const returnNulls = fnBody.match(/return null;/g);
|
|
81
|
+
assert.ok(
|
|
82
|
+
returnNulls && returnNulls.length === 1,
|
|
83
|
+
`expected exactly 1 'return null' (at end after fallback), got ${returnNulls?.length ?? 0}`,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// ── Behavioral tests: RESUME_INTENT_PATTERNS ────────────────────────
|
|
89
|
+
|
|
90
|
+
describe("#3615 — behavioral: RESUME_INTENT_PATTERNS matches resume prompts", () => {
|
|
91
|
+
// Extract the regex from source so the test stays in sync
|
|
92
|
+
const patternMatch = systemContextSource.match(/const RESUME_INTENT_PATTERNS\s*=\s*\/(.+)\/;/);
|
|
93
|
+
assert.ok(patternMatch, "should find RESUME_INTENT_PATTERNS definition");
|
|
94
|
+
const pattern = new RegExp(patternMatch[1]);
|
|
95
|
+
|
|
96
|
+
// Helper: normalize prompt the same way the production code does
|
|
97
|
+
const normalize = (s: string) => s.trim().toLowerCase().replace(/[.!?,]+$/g, "");
|
|
98
|
+
|
|
99
|
+
const shouldMatch = [
|
|
100
|
+
"continue",
|
|
101
|
+
"Continue",
|
|
102
|
+
"CONTINUE",
|
|
103
|
+
"continue.",
|
|
104
|
+
"continue!",
|
|
105
|
+
"resume",
|
|
106
|
+
"ok",
|
|
107
|
+
"OK",
|
|
108
|
+
"Ok!",
|
|
109
|
+
"go",
|
|
110
|
+
"go ahead",
|
|
111
|
+
"Go ahead.",
|
|
112
|
+
"proceed",
|
|
113
|
+
"keep going",
|
|
114
|
+
"carry on",
|
|
115
|
+
"next",
|
|
116
|
+
"yes",
|
|
117
|
+
"yeah",
|
|
118
|
+
"yep",
|
|
119
|
+
"sure",
|
|
120
|
+
"do it",
|
|
121
|
+
"let's go",
|
|
122
|
+
"pick up where you left off",
|
|
123
|
+
" continue ", // whitespace padded
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const shouldNotMatch = [
|
|
127
|
+
"help",
|
|
128
|
+
"status",
|
|
129
|
+
"/gsd auto",
|
|
130
|
+
"/gsd stats",
|
|
131
|
+
"what's the plan?",
|
|
132
|
+
"show me the logs",
|
|
133
|
+
"abort",
|
|
134
|
+
"stop",
|
|
135
|
+
"cancel",
|
|
136
|
+
"replan this slice",
|
|
137
|
+
"I think we should change the approach",
|
|
138
|
+
"can you explain what you just did?",
|
|
139
|
+
"run the tests",
|
|
140
|
+
"check the build",
|
|
141
|
+
"Execute the next task: T01",
|
|
142
|
+
"what files were changed",
|
|
143
|
+
"",
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
for (const prompt of shouldMatch) {
|
|
147
|
+
test(`matches resume prompt: "${prompt}"`, () => {
|
|
148
|
+
assert.ok(
|
|
149
|
+
pattern.test(normalize(prompt)),
|
|
150
|
+
`expected RESUME_INTENT_PATTERNS to match "${prompt}" (normalized: "${normalize(prompt)}")`,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
for (const prompt of shouldNotMatch) {
|
|
156
|
+
test(`rejects non-resume prompt: "${prompt}"`, () => {
|
|
157
|
+
assert.ok(
|
|
158
|
+
!pattern.test(normalize(prompt)),
|
|
159
|
+
`expected RESUME_INTENT_PATTERNS to NOT match "${prompt}" (normalized: "${normalize(prompt)}")`,
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
});
|
|
@@ -52,6 +52,32 @@ export interface BrowserEvidenceJSON {
|
|
|
52
52
|
duration: number;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
export interface PreExecutionCheckJSON {
|
|
56
|
+
/** Check category: package, file, tool, endpoint, schema */
|
|
57
|
+
category: "package" | "file" | "tool" | "endpoint" | "schema";
|
|
58
|
+
/** What was checked (e.g., package name, file path) */
|
|
59
|
+
target: string;
|
|
60
|
+
/** Whether the check passed */
|
|
61
|
+
passed: boolean;
|
|
62
|
+
/** Human-readable message explaining the result */
|
|
63
|
+
message: string;
|
|
64
|
+
/** Whether this failure should block execution (only meaningful when passed=false) */
|
|
65
|
+
blocking?: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface PostExecutionCheckJSON {
|
|
69
|
+
/** Check category: import, signature, pattern */
|
|
70
|
+
category: "import" | "signature" | "pattern";
|
|
71
|
+
/** What was checked (e.g., file:line, function name) */
|
|
72
|
+
target: string;
|
|
73
|
+
/** Whether the check passed */
|
|
74
|
+
passed: boolean;
|
|
75
|
+
/** Human-readable message explaining the result */
|
|
76
|
+
message: string;
|
|
77
|
+
/** Whether this failure should block completion (only meaningful when passed=false) */
|
|
78
|
+
blocking?: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
55
81
|
export interface EvidenceJSON {
|
|
56
82
|
schemaVersion: 1;
|
|
57
83
|
taskId: string;
|
|
@@ -65,6 +91,10 @@ export interface EvidenceJSON {
|
|
|
65
91
|
runtimeErrors?: RuntimeErrorJSON[];
|
|
66
92
|
auditWarnings?: AuditWarningJSON[];
|
|
67
93
|
browser?: BrowserEvidenceJSON;
|
|
94
|
+
/** Pre-execution checks run before task execution (package existence, file refs, etc.) */
|
|
95
|
+
preExecutionChecks?: PreExecutionCheckJSON[];
|
|
96
|
+
/** Post-execution checks run after task completion (import resolution, signature drift, pattern consistency) */
|
|
97
|
+
postExecutionChecks?: PostExecutionCheckJSON[];
|
|
68
98
|
}
|
|
69
99
|
|
|
70
100
|
/**
|
|
@@ -124,6 +154,44 @@ export function writeVerificationJSON(
|
|
|
124
154
|
writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
|
|
125
155
|
}
|
|
126
156
|
|
|
157
|
+
// ─── Pre-Execution Evidence ──────────────────────────────────────────────────
|
|
158
|
+
|
|
159
|
+
export interface PreExecutionEvidenceJSON {
|
|
160
|
+
schemaVersion: 1;
|
|
161
|
+
milestoneId: string;
|
|
162
|
+
sliceId: string;
|
|
163
|
+
timestamp: number;
|
|
164
|
+
status: "pass" | "warn" | "fail";
|
|
165
|
+
durationMs: number;
|
|
166
|
+
checks: PreExecutionCheckJSON[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Write pre-execution check results to a PRE-EXEC-VERIFY.json artifact
|
|
171
|
+
* in the slice directory.
|
|
172
|
+
*/
|
|
173
|
+
export function writePreExecutionEvidence(
|
|
174
|
+
result: { status: "pass" | "warn" | "fail"; checks: PreExecutionCheckJSON[]; durationMs: number },
|
|
175
|
+
sliceDir: string,
|
|
176
|
+
milestoneId: string,
|
|
177
|
+
sliceId: string,
|
|
178
|
+
): void {
|
|
179
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
180
|
+
|
|
181
|
+
const evidence: PreExecutionEvidenceJSON = {
|
|
182
|
+
schemaVersion: 1,
|
|
183
|
+
milestoneId,
|
|
184
|
+
sliceId,
|
|
185
|
+
timestamp: Date.now(),
|
|
186
|
+
status: result.status,
|
|
187
|
+
durationMs: result.durationMs,
|
|
188
|
+
checks: result.checks,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const filePath = join(sliceDir, `${sliceId}-PRE-EXEC-VERIFY.json`);
|
|
192
|
+
writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
|
|
193
|
+
}
|
|
194
|
+
|
|
127
195
|
// ─── Markdown Evidence Table ─────────────────────────────────────────────────
|
|
128
196
|
|
|
129
197
|
/**
|