gsd-pi 2.64.0 → 2.65.0
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 +7 -6
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/routes-manifest.json +6 -0
- 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.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/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/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 +7 -6
- package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
- 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/MRM3OSYIAa4HMDqVGQ9nt/_buildManifest.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
- 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/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/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/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/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/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 → MRM3OSYIAa4HMDqVGQ9nt}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-Execution Checks — Validate task plans before execution begins.
|
|
3
|
+
*
|
|
4
|
+
* Runs these checks against a slice's task plan:
|
|
5
|
+
* 1. Package existence — npm view calls in parallel with timeout
|
|
6
|
+
* 2. File path consistency — verify files exist or are in prior expected_output
|
|
7
|
+
* 3. Task ordering — detect impossible ordering (task reads file created later)
|
|
8
|
+
* 4. Interface contracts — detect contradictory function signatures (warn only)
|
|
9
|
+
*
|
|
10
|
+
* Design principles:
|
|
11
|
+
* - Pure functions taking (tasks: TaskRow[], basePath: string) for testability
|
|
12
|
+
* - Network failures warn, don't fail (R012 conservative design)
|
|
13
|
+
* - Total execution <2s target (R013)
|
|
14
|
+
* - No AST parsers — interface parsing is heuristic (regex on code blocks)
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync } from "node:fs";
|
|
17
|
+
import { spawn } from "node:child_process";
|
|
18
|
+
import { resolve } from "node:path";
|
|
19
|
+
// ─── Package Existence Check ─────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Extract npm package names from task descriptions.
|
|
22
|
+
* Looks for:
|
|
23
|
+
* - `npm install <pkg>` patterns
|
|
24
|
+
* - Code blocks with `require('<pkg>')` or `import ... from '<pkg>'`
|
|
25
|
+
* - Explicit mentions like "uses lodash" or "package: axios"
|
|
26
|
+
*/
|
|
27
|
+
export function extractPackageReferences(description) {
|
|
28
|
+
const packages = new Set();
|
|
29
|
+
// Common words that aren't package names but might appear after install
|
|
30
|
+
const stopwords = new Set([
|
|
31
|
+
"then", "and", "the", "to", "a", "an", "in", "for", "with", "from", "or",
|
|
32
|
+
"npm", "yarn", "pnpm", "i", // Don't capture the command itself
|
|
33
|
+
]);
|
|
34
|
+
// npm install <pkg> patterns (handles npm i, npm add, yarn add, pnpm add)
|
|
35
|
+
// Use a global pattern to find all install commands, then parse following tokens
|
|
36
|
+
const installCmdPattern = /(?:npm\s+(?:install|i|add)|yarn\s+add|pnpm\s+add)\s+/g;
|
|
37
|
+
let cmdMatch;
|
|
38
|
+
while ((cmdMatch = installCmdPattern.exec(description)) !== null) {
|
|
39
|
+
// Start after the install command
|
|
40
|
+
const afterCmd = description.slice(cmdMatch.index + cmdMatch[0].length);
|
|
41
|
+
// Match package-like tokens (alphanumeric, @, /, -, _) until we hit
|
|
42
|
+
// something that's not a package (non-token char after whitespace)
|
|
43
|
+
const tokenPattern = /^([@a-zA-Z][a-zA-Z0-9@/_-]*)(?:\s+|$)/;
|
|
44
|
+
let remaining = afterCmd;
|
|
45
|
+
while (remaining.length > 0) {
|
|
46
|
+
// Skip any flags like -D, --save-dev
|
|
47
|
+
const flagMatch = remaining.match(/^(-[a-zA-Z-]+)\s*/);
|
|
48
|
+
if (flagMatch) {
|
|
49
|
+
remaining = remaining.slice(flagMatch[0].length);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
// Try to match a package name
|
|
53
|
+
const pkgMatch = remaining.match(tokenPattern);
|
|
54
|
+
if (pkgMatch) {
|
|
55
|
+
const token = pkgMatch[1];
|
|
56
|
+
// Skip stopwords - they indicate end of package list
|
|
57
|
+
if (stopwords.has(token.toLowerCase())) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
packages.add(normalizePackageName(token));
|
|
61
|
+
remaining = remaining.slice(pkgMatch[0].length);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Not a package name, stop parsing this install command
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// require('pkg') or import from 'pkg' in code blocks
|
|
70
|
+
const importPattern = /(?:require\s*\(\s*['"]|from\s+['"])([a-zA-Z0-9@/_-]+)['"\)]/g;
|
|
71
|
+
let importMatch;
|
|
72
|
+
while ((importMatch = importPattern.exec(description)) !== null) {
|
|
73
|
+
// Skip relative imports and node builtins
|
|
74
|
+
const pkg = importMatch[1];
|
|
75
|
+
if (!pkg.startsWith(".") && !pkg.startsWith("node:")) {
|
|
76
|
+
packages.add(normalizePackageName(pkg));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return Array.from(packages);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Normalize package name to registry-checkable form.
|
|
83
|
+
* Handles scoped packages (@org/pkg) and subpaths (pkg/subpath → pkg).
|
|
84
|
+
*/
|
|
85
|
+
function normalizePackageName(raw) {
|
|
86
|
+
// Scoped package: @org/pkg or @org/pkg/subpath
|
|
87
|
+
if (raw.startsWith("@")) {
|
|
88
|
+
const parts = raw.split("/");
|
|
89
|
+
return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : raw;
|
|
90
|
+
}
|
|
91
|
+
// Regular package: pkg or pkg/subpath
|
|
92
|
+
return raw.split("/")[0];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if a package exists on npm registry.
|
|
96
|
+
* Returns null on success, error message on failure.
|
|
97
|
+
* Times out after timeoutMs (default 5000ms).
|
|
98
|
+
*/
|
|
99
|
+
async function checkPackageOnNpm(packageName, timeoutMs = 5000) {
|
|
100
|
+
return new Promise((resolve) => {
|
|
101
|
+
const child = spawn("npm", ["view", packageName, "name"], {
|
|
102
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
103
|
+
timeout: timeoutMs,
|
|
104
|
+
});
|
|
105
|
+
let stdout = "";
|
|
106
|
+
let stderr = "";
|
|
107
|
+
child.stdout.on("data", (data) => {
|
|
108
|
+
stdout += data.toString();
|
|
109
|
+
});
|
|
110
|
+
child.stderr.on("data", (data) => {
|
|
111
|
+
stderr += data.toString();
|
|
112
|
+
});
|
|
113
|
+
const timer = setTimeout(() => {
|
|
114
|
+
child.kill("SIGTERM");
|
|
115
|
+
resolve({ exists: false, error: `Timeout after ${timeoutMs}ms` });
|
|
116
|
+
}, timeoutMs);
|
|
117
|
+
child.on("close", (code) => {
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
if (code === 0 && stdout.trim()) {
|
|
120
|
+
resolve({ exists: true });
|
|
121
|
+
}
|
|
122
|
+
else if (stderr.includes("404") || stderr.includes("not found")) {
|
|
123
|
+
resolve({ exists: false, error: `Package not found: ${packageName}` });
|
|
124
|
+
}
|
|
125
|
+
else if (code !== 0) {
|
|
126
|
+
// Network error or other issue — warn, don't fail
|
|
127
|
+
resolve({ exists: true, error: `npm view failed (code ${code}): ${stderr.slice(0, 100)}` });
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
resolve({ exists: true });
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
child.on("error", (err) => {
|
|
134
|
+
clearTimeout(timer);
|
|
135
|
+
resolve({ exists: true, error: `npm spawn error: ${err.message}` });
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check all package references in tasks for existence on npm.
|
|
141
|
+
* Runs checks in parallel with a 5s timeout per package.
|
|
142
|
+
* Network failures warn but don't fail (R012 conservative design).
|
|
143
|
+
*/
|
|
144
|
+
export async function checkPackageExistence(tasks, _basePath) {
|
|
145
|
+
const results = [];
|
|
146
|
+
const packagesToCheck = new Set();
|
|
147
|
+
// Collect all package references from task descriptions
|
|
148
|
+
for (const task of tasks) {
|
|
149
|
+
const packages = extractPackageReferences(task.description);
|
|
150
|
+
for (const pkg of packages) {
|
|
151
|
+
packagesToCheck.add(pkg);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (packagesToCheck.size === 0) {
|
|
155
|
+
return results;
|
|
156
|
+
}
|
|
157
|
+
// Check packages in parallel
|
|
158
|
+
const checkPromises = Array.from(packagesToCheck).map(async (pkg) => {
|
|
159
|
+
const result = await checkPackageOnNpm(pkg);
|
|
160
|
+
return { pkg, result };
|
|
161
|
+
});
|
|
162
|
+
const checkResults = await Promise.all(checkPromises);
|
|
163
|
+
for (const { pkg, result } of checkResults) {
|
|
164
|
+
if (!result.exists && !result.error?.includes("Timeout") && !result.error?.includes("spawn error")) {
|
|
165
|
+
// Package genuinely doesn't exist — blocking failure
|
|
166
|
+
results.push({
|
|
167
|
+
category: "package",
|
|
168
|
+
target: pkg,
|
|
169
|
+
passed: false,
|
|
170
|
+
message: result.error || `Package '${pkg}' not found on npm`,
|
|
171
|
+
blocking: true,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else if (result.error) {
|
|
175
|
+
// Network issue or timeout — warn but don't block
|
|
176
|
+
results.push({
|
|
177
|
+
category: "package",
|
|
178
|
+
target: pkg,
|
|
179
|
+
passed: true,
|
|
180
|
+
message: `Warning: ${result.error}`,
|
|
181
|
+
blocking: false,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// Silent success for existing packages — no need to report
|
|
185
|
+
}
|
|
186
|
+
return results;
|
|
187
|
+
}
|
|
188
|
+
// ─── File Path Consistency Check ─────────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* Normalize a file path for consistent comparison.
|
|
191
|
+
* - Strips leading ./
|
|
192
|
+
* - Normalizes path separators to forward slashes
|
|
193
|
+
* - Resolves redundant segments (e.g., foo/../bar → bar)
|
|
194
|
+
*
|
|
195
|
+
* This ensures that "./src/a.ts", "src/a.ts", and "src//a.ts" all compare equal.
|
|
196
|
+
*/
|
|
197
|
+
export function normalizeFilePath(filePath) {
|
|
198
|
+
if (!filePath)
|
|
199
|
+
return filePath;
|
|
200
|
+
// Normalize path separators to forward slashes
|
|
201
|
+
let normalized = filePath.replace(/\\/g, "/");
|
|
202
|
+
// Remove leading ./
|
|
203
|
+
while (normalized.startsWith("./")) {
|
|
204
|
+
normalized = normalized.slice(2);
|
|
205
|
+
}
|
|
206
|
+
// Remove duplicate slashes
|
|
207
|
+
normalized = normalized.replace(/\/+/g, "/");
|
|
208
|
+
// Remove trailing slash unless it's the root
|
|
209
|
+
if (normalized.length > 1 && normalized.endsWith("/")) {
|
|
210
|
+
normalized = normalized.slice(0, -1);
|
|
211
|
+
}
|
|
212
|
+
return normalized;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Build a set of files that will be created by tasks up to (but not including) taskIndex.
|
|
216
|
+
* All paths are normalized for consistent comparison.
|
|
217
|
+
*/
|
|
218
|
+
function getExpectedOutputsUpTo(tasks, taskIndex) {
|
|
219
|
+
const outputs = new Set();
|
|
220
|
+
for (let i = 0; i < taskIndex; i++) {
|
|
221
|
+
for (const file of tasks[i].expected_output) {
|
|
222
|
+
outputs.add(normalizeFilePath(file));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return outputs;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Check that all files referenced in task.files and task.inputs either:
|
|
229
|
+
* 1. Exist on disk, OR
|
|
230
|
+
* 2. Are in a prior task's expected_output
|
|
231
|
+
*
|
|
232
|
+
* All paths are normalized before comparison to ensure ./src/a.ts matches src/a.ts.
|
|
233
|
+
*/
|
|
234
|
+
export function checkFilePathConsistency(tasks, basePath) {
|
|
235
|
+
const results = [];
|
|
236
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
237
|
+
const task = tasks[i];
|
|
238
|
+
const priorOutputs = getExpectedOutputsUpTo(tasks, i);
|
|
239
|
+
const filesToCheck = [...task.files, ...task.inputs];
|
|
240
|
+
for (const file of filesToCheck) {
|
|
241
|
+
// Skip empty strings
|
|
242
|
+
if (!file.trim())
|
|
243
|
+
continue;
|
|
244
|
+
// Normalize path for consistent comparison
|
|
245
|
+
const normalizedFile = normalizeFilePath(file);
|
|
246
|
+
// Check if file exists on disk
|
|
247
|
+
const absolutePath = resolve(basePath, normalizedFile);
|
|
248
|
+
const existsOnDisk = existsSync(absolutePath);
|
|
249
|
+
// Check if file is in prior expected outputs (priorOutputs already normalized)
|
|
250
|
+
const inPriorOutputs = priorOutputs.has(normalizedFile);
|
|
251
|
+
if (!existsOnDisk && !inPriorOutputs) {
|
|
252
|
+
results.push({
|
|
253
|
+
category: "file",
|
|
254
|
+
target: file,
|
|
255
|
+
passed: false,
|
|
256
|
+
message: `Task ${task.id} references '${file}' which doesn't exist and isn't created by prior tasks`,
|
|
257
|
+
blocking: true,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return results;
|
|
263
|
+
}
|
|
264
|
+
// ─── Task Ordering Check ─────────────────────────────────────────────────────
|
|
265
|
+
/**
|
|
266
|
+
* Detect impossible task ordering: task N reads a file that task N+M creates.
|
|
267
|
+
* This is a fatal error — the plan has an impossible dependency.
|
|
268
|
+
*
|
|
269
|
+
* All paths are normalized before comparison to ensure ./src/a.ts matches src/a.ts.
|
|
270
|
+
*/
|
|
271
|
+
export function checkTaskOrdering(tasks, _basePath) {
|
|
272
|
+
const results = [];
|
|
273
|
+
// Build map: normalized file → task index that creates it
|
|
274
|
+
const fileCreators = new Map();
|
|
275
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
276
|
+
const task = tasks[i];
|
|
277
|
+
for (const file of task.expected_output) {
|
|
278
|
+
const normalizedFile = normalizeFilePath(file);
|
|
279
|
+
if (!fileCreators.has(normalizedFile)) {
|
|
280
|
+
fileCreators.set(normalizedFile, { taskId: task.id, index: i, originalPath: file });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Check each task's inputs against file creators
|
|
285
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
286
|
+
const task = tasks[i];
|
|
287
|
+
const filesToCheck = [...task.files, ...task.inputs];
|
|
288
|
+
for (const file of filesToCheck) {
|
|
289
|
+
const normalizedFile = normalizeFilePath(file);
|
|
290
|
+
const creator = fileCreators.get(normalizedFile);
|
|
291
|
+
if (creator && creator.index > i) {
|
|
292
|
+
// Task reads file that is created later — impossible ordering
|
|
293
|
+
results.push({
|
|
294
|
+
category: "file",
|
|
295
|
+
target: file,
|
|
296
|
+
passed: false,
|
|
297
|
+
message: `Task ${task.id} reads '${file}' but it's created by task ${creator.taskId} (sequence violation)`,
|
|
298
|
+
blocking: true,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return results;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Extract function signatures from code blocks in task description.
|
|
307
|
+
* Uses heuristic regex — not an AST parser.
|
|
308
|
+
*/
|
|
309
|
+
function extractFunctionSignatures(description, taskId) {
|
|
310
|
+
const signatures = [];
|
|
311
|
+
// Match code blocks (```...```)
|
|
312
|
+
const codeBlockPattern = /```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/g;
|
|
313
|
+
let blockMatch;
|
|
314
|
+
while ((blockMatch = codeBlockPattern.exec(description)) !== null) {
|
|
315
|
+
const codeBlock = blockMatch[1];
|
|
316
|
+
// Match function declarations and exports
|
|
317
|
+
// Patterns:
|
|
318
|
+
// function name(params): ReturnType
|
|
319
|
+
// export function name(params): ReturnType
|
|
320
|
+
// export async function name(params): Promise<ReturnType>
|
|
321
|
+
// const name = (params): ReturnType =>
|
|
322
|
+
// export const name = (params): ReturnType =>
|
|
323
|
+
const funcPattern = /(?:export\s+)?(?:async\s+)?(?:function\s+|const\s+)(\w+)(?:\s*=\s*)?\s*\(([^)]*)\)(?:\s*:\s*([^{=>\n]+))?/g;
|
|
324
|
+
let funcMatch;
|
|
325
|
+
while ((funcMatch = funcPattern.exec(codeBlock)) !== null) {
|
|
326
|
+
const [raw, name, params, returnType] = funcMatch;
|
|
327
|
+
signatures.push({
|
|
328
|
+
name,
|
|
329
|
+
params: normalizeParams(params),
|
|
330
|
+
returnType: normalizeType(returnType || "void"),
|
|
331
|
+
taskId,
|
|
332
|
+
raw: raw.trim(),
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
// Match interface method signatures
|
|
336
|
+
// Pattern: methodName(params): ReturnType;
|
|
337
|
+
const methodPattern = /^\s*(\w+)\s*\(([^)]*)\)\s*:\s*([^;]+);/gm;
|
|
338
|
+
let methodMatch;
|
|
339
|
+
while ((methodMatch = methodPattern.exec(codeBlock)) !== null) {
|
|
340
|
+
const [raw, name, params, returnType] = methodMatch;
|
|
341
|
+
signatures.push({
|
|
342
|
+
name,
|
|
343
|
+
params: normalizeParams(params),
|
|
344
|
+
returnType: normalizeType(returnType),
|
|
345
|
+
taskId,
|
|
346
|
+
raw: raw.trim(),
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return signatures;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Normalize parameter list for comparison.
|
|
354
|
+
* Removes whitespace, comments, and default values.
|
|
355
|
+
*/
|
|
356
|
+
function normalizeParams(params) {
|
|
357
|
+
return params
|
|
358
|
+
.replace(/\/\*[\s\S]*?\*\//g, "") // Remove block comments
|
|
359
|
+
.replace(/\/\/[^\n]*/g, "") // Remove line comments
|
|
360
|
+
.replace(/\s*=\s*[^,)]+/g, "") // Remove default values
|
|
361
|
+
.replace(/\s+/g, " ") // Normalize whitespace
|
|
362
|
+
.trim();
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Normalize type for comparison.
|
|
366
|
+
*/
|
|
367
|
+
function normalizeType(type) {
|
|
368
|
+
return type
|
|
369
|
+
.replace(/\s+/g, " ")
|
|
370
|
+
.trim();
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Check for contradictory function signatures across tasks.
|
|
374
|
+
* Same function name with different signatures is a warning (not blocking).
|
|
375
|
+
*/
|
|
376
|
+
export function checkInterfaceContracts(tasks, _basePath) {
|
|
377
|
+
const results = [];
|
|
378
|
+
// Collect all signatures
|
|
379
|
+
const allSignatures = [];
|
|
380
|
+
for (const task of tasks) {
|
|
381
|
+
const sigs = extractFunctionSignatures(task.description, task.id);
|
|
382
|
+
allSignatures.push(...sigs);
|
|
383
|
+
}
|
|
384
|
+
// Group by function name
|
|
385
|
+
const byName = new Map();
|
|
386
|
+
for (const sig of allSignatures) {
|
|
387
|
+
const existing = byName.get(sig.name) || [];
|
|
388
|
+
existing.push(sig);
|
|
389
|
+
byName.set(sig.name, existing);
|
|
390
|
+
}
|
|
391
|
+
// Check for contradictions
|
|
392
|
+
for (const [name, sigs] of byName) {
|
|
393
|
+
if (sigs.length < 2)
|
|
394
|
+
continue;
|
|
395
|
+
// Compare signatures
|
|
396
|
+
const first = sigs[0];
|
|
397
|
+
for (let i = 1; i < sigs.length; i++) {
|
|
398
|
+
const current = sigs[i];
|
|
399
|
+
// Check parameter mismatch
|
|
400
|
+
if (first.params !== current.params) {
|
|
401
|
+
results.push({
|
|
402
|
+
category: "schema",
|
|
403
|
+
target: name,
|
|
404
|
+
passed: true, // Warning only, not blocking
|
|
405
|
+
message: `Function '${name}' has different parameters: '${first.params}' (${first.taskId}) vs '${current.params}' (${current.taskId})`,
|
|
406
|
+
blocking: false,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
// Check return type mismatch
|
|
410
|
+
if (first.returnType !== current.returnType) {
|
|
411
|
+
results.push({
|
|
412
|
+
category: "schema",
|
|
413
|
+
target: name,
|
|
414
|
+
passed: true, // Warning only, not blocking
|
|
415
|
+
message: `Function '${name}' has different return types: '${first.returnType}' (${first.taskId}) vs '${current.returnType}' (${current.taskId})`,
|
|
416
|
+
blocking: false,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return results;
|
|
422
|
+
}
|
|
423
|
+
// ─── Main Entry Point ────────────────────────────────────────────────────────
|
|
424
|
+
/**
|
|
425
|
+
* Run all pre-execution checks against a slice's task plan.
|
|
426
|
+
*
|
|
427
|
+
* @param tasks - Array of TaskRow from the slice
|
|
428
|
+
* @param basePath - Base path for resolving file references
|
|
429
|
+
* @returns PreExecutionResult with status, checks, and duration
|
|
430
|
+
*/
|
|
431
|
+
export async function runPreExecutionChecks(tasks, basePath) {
|
|
432
|
+
const startTime = Date.now();
|
|
433
|
+
const allChecks = [];
|
|
434
|
+
// Run sync checks first
|
|
435
|
+
const fileChecks = checkFilePathConsistency(tasks, basePath);
|
|
436
|
+
const orderingChecks = checkTaskOrdering(tasks, basePath);
|
|
437
|
+
const contractChecks = checkInterfaceContracts(tasks, basePath);
|
|
438
|
+
allChecks.push(...fileChecks, ...orderingChecks, ...contractChecks);
|
|
439
|
+
// Run async package checks
|
|
440
|
+
const packageChecks = await checkPackageExistence(tasks, basePath);
|
|
441
|
+
allChecks.push(...packageChecks);
|
|
442
|
+
const durationMs = Date.now() - startTime;
|
|
443
|
+
// Determine overall status
|
|
444
|
+
const hasBlockingFailure = allChecks.some((c) => !c.passed && c.blocking);
|
|
445
|
+
const hasNonBlockingFailure = allChecks.some((c) => !c.passed && !c.blocking);
|
|
446
|
+
// Interface contract checks pass but still report warnings via message
|
|
447
|
+
const hasInterfaceWarning = allChecks.some((c) => c.category === "schema" && c.message && !c.message.startsWith("Warning:"));
|
|
448
|
+
const hasNetworkWarning = allChecks.some((c) => c.passed && c.message?.startsWith("Warning:"));
|
|
449
|
+
let status;
|
|
450
|
+
if (hasBlockingFailure) {
|
|
451
|
+
status = "fail";
|
|
452
|
+
}
|
|
453
|
+
else if (hasNonBlockingFailure || hasInterfaceWarning || hasNetworkWarning) {
|
|
454
|
+
status = "warn";
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
status = "pass";
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
status,
|
|
461
|
+
checks: allChecks,
|
|
462
|
+
durationMs,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
@@ -76,6 +76,10 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
|
|
|
76
76
|
"codebase",
|
|
77
77
|
"slice_parallel",
|
|
78
78
|
"safety_harness",
|
|
79
|
+
"enhanced_verification",
|
|
80
|
+
"enhanced_verification_pre",
|
|
81
|
+
"enhanced_verification_post",
|
|
82
|
+
"enhanced_verification_strict",
|
|
79
83
|
]);
|
|
80
84
|
/** Canonical list of all dispatch unit types. */
|
|
81
85
|
export const KNOWN_UNIT_TYPES = [
|
|
@@ -939,5 +939,38 @@ export function validatePreferences(preferences) {
|
|
|
939
939
|
errors.push("codebase must be an object");
|
|
940
940
|
}
|
|
941
941
|
}
|
|
942
|
+
// ─── Enhanced Verification ──────────────────────────────────────────────────
|
|
943
|
+
if (preferences.enhanced_verification !== undefined) {
|
|
944
|
+
if (typeof preferences.enhanced_verification === "boolean") {
|
|
945
|
+
validated.enhanced_verification = preferences.enhanced_verification;
|
|
946
|
+
}
|
|
947
|
+
else {
|
|
948
|
+
errors.push("enhanced_verification must be a boolean");
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
if (preferences.enhanced_verification_pre !== undefined) {
|
|
952
|
+
if (typeof preferences.enhanced_verification_pre === "boolean") {
|
|
953
|
+
validated.enhanced_verification_pre = preferences.enhanced_verification_pre;
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
errors.push("enhanced_verification_pre must be a boolean");
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
if (preferences.enhanced_verification_post !== undefined) {
|
|
960
|
+
if (typeof preferences.enhanced_verification_post === "boolean") {
|
|
961
|
+
validated.enhanced_verification_post = preferences.enhanced_verification_post;
|
|
962
|
+
}
|
|
963
|
+
else {
|
|
964
|
+
errors.push("enhanced_verification_post must be a boolean");
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
if (preferences.enhanced_verification_strict !== undefined) {
|
|
968
|
+
if (typeof preferences.enhanced_verification_strict === "boolean") {
|
|
969
|
+
validated.enhanced_verification_strict = preferences.enhanced_verification_strict;
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
errors.push("enhanced_verification_strict must be a boolean");
|
|
973
|
+
}
|
|
974
|
+
}
|
|
942
975
|
return { preferences: validated, errors, warnings };
|
|
943
976
|
}
|
|
@@ -282,6 +282,10 @@ function mergePreferences(base, override) {
|
|
|
282
282
|
verification_commands: mergeStringLists(base.verification_commands, override.verification_commands),
|
|
283
283
|
verification_auto_fix: override.verification_auto_fix ?? base.verification_auto_fix,
|
|
284
284
|
verification_max_retries: override.verification_max_retries ?? base.verification_max_retries,
|
|
285
|
+
enhanced_verification: override.enhanced_verification ?? base.enhanced_verification,
|
|
286
|
+
enhanced_verification_pre: override.enhanced_verification_pre ?? base.enhanced_verification_pre,
|
|
287
|
+
enhanced_verification_post: override.enhanced_verification_post ?? base.enhanced_verification_post,
|
|
288
|
+
enhanced_verification_strict: override.enhanced_verification_strict ?? base.enhanced_verification_strict,
|
|
285
289
|
search_provider: override.search_provider ?? base.search_provider,
|
|
286
290
|
context_selection: override.context_selection ?? base.context_selection,
|
|
287
291
|
auto_visualize: override.auto_visualize ?? base.auto_visualize,
|
|
@@ -55,6 +55,24 @@ export function writeVerificationJSON(result, tasksDir, taskId, unitId, retryAtt
|
|
|
55
55
|
const filePath = join(tasksDir, `${taskId}-VERIFY.json`);
|
|
56
56
|
writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Write pre-execution check results to a PRE-EXEC-VERIFY.json artifact
|
|
60
|
+
* in the slice directory.
|
|
61
|
+
*/
|
|
62
|
+
export function writePreExecutionEvidence(result, sliceDir, milestoneId, sliceId) {
|
|
63
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
64
|
+
const evidence = {
|
|
65
|
+
schemaVersion: 1,
|
|
66
|
+
milestoneId,
|
|
67
|
+
sliceId,
|
|
68
|
+
timestamp: Date.now(),
|
|
69
|
+
status: result.status,
|
|
70
|
+
durationMs: result.durationMs,
|
|
71
|
+
checks: result.checks,
|
|
72
|
+
};
|
|
73
|
+
const filePath = join(sliceDir, `${sliceId}-PRE-EXEC-VERIFY.json`);
|
|
74
|
+
writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
|
|
75
|
+
}
|
|
58
76
|
// ─── Markdown Evidence Table ─────────────────────────────────────────────────
|
|
59
77
|
/**
|
|
60
78
|
* Format duration in milliseconds as seconds with 1 decimal place.
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// Node process.
|
|
18
18
|
import { appendFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
|
|
19
19
|
import { join } from "node:path";
|
|
20
|
+
import { appendNotification } from "./notification-store.js";
|
|
20
21
|
// ─── Buffer & Persistent Audit ──────────────────────────────────────────
|
|
21
22
|
const MAX_BUFFER = 100;
|
|
22
23
|
let _buffer = [];
|
|
@@ -179,6 +180,13 @@ function _push(severity, component, message, context) {
|
|
|
179
180
|
const prefix = severity === "error" ? "ERROR" : "WARN";
|
|
180
181
|
const ctxStr = context ? ` ${JSON.stringify(context)}` : "";
|
|
181
182
|
process.stderr.write(`[gsd:${component}] ${prefix}: ${message}${ctxStr}\n`);
|
|
183
|
+
// Persist to notification store (both warnings and errors)
|
|
184
|
+
try {
|
|
185
|
+
appendNotification(`[${component}] ${message}`, severity === "error" ? "error" : "warning", "workflow-logger");
|
|
186
|
+
}
|
|
187
|
+
catch (notifErr) {
|
|
188
|
+
process.stderr.write(`[gsd:workflow-logger] notification-store append failed: ${notifErr.message}\n`);
|
|
189
|
+
}
|
|
182
190
|
// Buffer for auto-loop to drain
|
|
183
191
|
_buffer.push(entry);
|
|
184
192
|
if (_buffer.length > MAX_BUFFER) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
MRM3OSYIAa4HMDqVGQ9nt
|
|
@@ -5,29 +5,30 @@
|
|
|
5
5
|
"/api/boot/route": "/api/boot",
|
|
6
6
|
"/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
|
|
7
7
|
"/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
|
|
8
|
+
"/api/cleanup/route": "/api/cleanup",
|
|
8
9
|
"/api/dev-mode/route": "/api/dev-mode",
|
|
9
10
|
"/api/doctor/route": "/api/doctor",
|
|
10
11
|
"/api/captures/route": "/api/captures",
|
|
11
|
-
"/api/browse-directories/route": "/api/browse-directories",
|
|
12
12
|
"/api/export-data/route": "/api/export-data",
|
|
13
|
-
"/api/
|
|
13
|
+
"/api/browse-directories/route": "/api/browse-directories",
|
|
14
14
|
"/api/forensics/route": "/api/forensics",
|
|
15
|
+
"/api/git/route": "/api/git",
|
|
15
16
|
"/api/history/route": "/api/history",
|
|
16
17
|
"/api/hooks/route": "/api/hooks",
|
|
17
|
-
"/api/git/route": "/api/git",
|
|
18
18
|
"/api/inspect/route": "/api/inspect",
|
|
19
19
|
"/api/knowledge/route": "/api/knowledge",
|
|
20
20
|
"/api/experimental/route": "/api/experimental",
|
|
21
21
|
"/api/live-state/route": "/api/live-state",
|
|
22
|
+
"/api/notifications/route": "/api/notifications",
|
|
22
23
|
"/api/preferences/route": "/api/preferences",
|
|
23
24
|
"/api/recovery/route": "/api/recovery",
|
|
24
25
|
"/api/onboarding/route": "/api/onboarding",
|
|
25
26
|
"/api/projects/route": "/api/projects",
|
|
26
27
|
"/api/session/browser/route": "/api/session/browser",
|
|
27
|
-
"/api/session/command/route": "/api/session/command",
|
|
28
28
|
"/api/session/events/route": "/api/session/events",
|
|
29
|
-
"/api/settings-data/route": "/api/settings-data",
|
|
30
29
|
"/api/session/manage/route": "/api/session/manage",
|
|
30
|
+
"/api/settings-data/route": "/api/settings-data",
|
|
31
|
+
"/api/session/command/route": "/api/session/command",
|
|
31
32
|
"/api/shutdown/route": "/api/shutdown",
|
|
32
33
|
"/api/skill-health/route": "/api/skill-health",
|
|
33
34
|
"/api/steer/route": "/api/steer",
|
|
@@ -36,8 +37,8 @@
|
|
|
36
37
|
"/api/terminal/resize/route": "/api/terminal/resize",
|
|
37
38
|
"/api/switch-root/route": "/api/switch-root",
|
|
38
39
|
"/api/terminal/sessions/route": "/api/terminal/sessions",
|
|
39
|
-
"/api/terminal/stream/route": "/api/terminal/stream",
|
|
40
40
|
"/api/terminal/upload/route": "/api/terminal/upload",
|
|
41
|
+
"/api/terminal/stream/route": "/api/terminal/stream",
|
|
41
42
|
"/api/undo/route": "/api/undo",
|
|
42
43
|
"/api/visualizer/route": "/api/visualizer",
|
|
43
44
|
"/api/update/route": "/api/update",
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
7
|
+
"static/MRM3OSYIAa4HMDqVGQ9nt/_buildManifest.js",
|
|
8
|
+
"static/MRM3OSYIAa4HMDqVGQ9nt/_ssgManifest.js"
|
|
9
9
|
],
|
|
10
10
|
"rootMainFiles": [
|
|
11
11
|
"static/chunks/webpack-a1c1e452c6b32d04.js",
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"dynamicRoutes": {},
|
|
79
79
|
"notFoundRoutes": [],
|
|
80
80
|
"preview": {
|
|
81
|
-
"previewModeId": "
|
|
82
|
-
"previewModeSigningKey": "
|
|
83
|
-
"previewModeEncryptionKey": "
|
|
81
|
+
"previewModeId": "bb1a193e6c1bf4abd4a9d63cdf8655b7",
|
|
82
|
+
"previewModeSigningKey": "ca5e2b71c749274a2c0a666756ffb23c45fc42b15d3d6d88453fff2c7153813c",
|
|
83
|
+
"previewModeEncryptionKey": "8ab4799711ced11dba484f001c1fb80246ebf723c020e899c9dbccc68dbde139"
|
|
84
84
|
}
|
|
85
85
|
}
|