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,56 @@
|
|
|
1
|
+
// GSD Extension — Notification Widget
|
|
2
|
+
// Always-on ambient widget rendered belowEditor showing unread count and
|
|
3
|
+
// the most recent notification message. Refreshes every 5 seconds.
|
|
4
|
+
// Widget key: "gsd-notifications", placement: "belowEditor"
|
|
5
|
+
import { getUnreadCount, readNotifications } from "./notification-store.js";
|
|
6
|
+
// ─── Pure rendering ──���────────────────────────���─────────────────────────
|
|
7
|
+
export function buildNotificationWidgetLines() {
|
|
8
|
+
const unread = getUnreadCount();
|
|
9
|
+
if (unread === 0)
|
|
10
|
+
return [];
|
|
11
|
+
const entries = readNotifications();
|
|
12
|
+
const latest = entries[0]; // newest-first
|
|
13
|
+
if (!latest)
|
|
14
|
+
return [];
|
|
15
|
+
const icon = latest.severity === "error" ? "✗" : latest.severity === "warning" ? "⚠" : "●";
|
|
16
|
+
const badge = `${unread} unread`;
|
|
17
|
+
const msgMax = 80;
|
|
18
|
+
const truncated = latest.message.length > msgMax
|
|
19
|
+
? latest.message.slice(0, msgMax - 1) + "…"
|
|
20
|
+
: latest.message;
|
|
21
|
+
return [` ${icon} [${badge}] ${truncated} (Ctrl+Alt+N to view)`];
|
|
22
|
+
}
|
|
23
|
+
// ─── Widget init ────────────────────────────────────────────────────────
|
|
24
|
+
const REFRESH_INTERVAL_MS = 5_000;
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the always-on notification widget (belowEditor).
|
|
27
|
+
* Call once from session_start after the notification store is initialized.
|
|
28
|
+
*/
|
|
29
|
+
export function initNotificationWidget(ctx) {
|
|
30
|
+
if (!ctx.hasUI)
|
|
31
|
+
return;
|
|
32
|
+
// String-array fallback for RPC mode
|
|
33
|
+
ctx.ui.setWidget("gsd-notifications", buildNotificationWidgetLines(), { placement: "belowEditor" });
|
|
34
|
+
// Factory-based widget for TUI mode
|
|
35
|
+
ctx.ui.setWidget("gsd-notifications", (_tui, _theme) => {
|
|
36
|
+
let cachedLines;
|
|
37
|
+
const refresh = () => {
|
|
38
|
+
cachedLines = undefined;
|
|
39
|
+
_tui.requestRender();
|
|
40
|
+
};
|
|
41
|
+
const refreshTimer = setInterval(refresh, REFRESH_INTERVAL_MS);
|
|
42
|
+
return {
|
|
43
|
+
render(_width) {
|
|
44
|
+
if (!cachedLines)
|
|
45
|
+
cachedLines = buildNotificationWidgetLines();
|
|
46
|
+
return cachedLines;
|
|
47
|
+
},
|
|
48
|
+
invalidate() {
|
|
49
|
+
cachedLines = undefined;
|
|
50
|
+
},
|
|
51
|
+
dispose() {
|
|
52
|
+
clearInterval(refreshTimer);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}, { placement: "belowEditor" });
|
|
56
|
+
}
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-Execution Checks — Validate task output after execution completes.
|
|
3
|
+
*
|
|
4
|
+
* Runs these checks against a completed task's output:
|
|
5
|
+
* 1. Import resolution — verify relative imports in key_files resolve to existing files
|
|
6
|
+
* 2. Cross-task signatures — detect hallucination cascades (function exists in task output
|
|
7
|
+
* but doesn't match prior tasks' actual code)
|
|
8
|
+
* 3. Pattern consistency — warn on async style drift, naming convention inconsistencies
|
|
9
|
+
*
|
|
10
|
+
* Design principles:
|
|
11
|
+
* - Pure functions taking (taskRow, priorTasks, basePath) for testability
|
|
12
|
+
* - Import checks are blocking failures; pattern checks are warnings
|
|
13
|
+
* - No AST parsers — uses regex heuristics
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
16
|
+
import { resolve, dirname, extname } from "node:path";
|
|
17
|
+
// ─── Import Resolution Check ─────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Extract relative import paths from TypeScript/JavaScript source code.
|
|
20
|
+
* Returns array of { importPath, lineNum } for relative imports.
|
|
21
|
+
*/
|
|
22
|
+
export function extractRelativeImports(source) {
|
|
23
|
+
const imports = [];
|
|
24
|
+
const lines = source.split("\n");
|
|
25
|
+
// Match:
|
|
26
|
+
// import ... from './path'
|
|
27
|
+
// import ... from "../path"
|
|
28
|
+
// import './path'
|
|
29
|
+
// require('./path')
|
|
30
|
+
// require("../path")
|
|
31
|
+
const importPattern = /(?:import\s+(?:.*?\s+from\s+)?|require\s*\(\s*)(['"])(\.\.?\/[^'"]+)\1/g;
|
|
32
|
+
// Track if we're inside a block comment
|
|
33
|
+
let inBlockComment = false;
|
|
34
|
+
for (let i = 0; i < lines.length; i++) {
|
|
35
|
+
const line = lines[i];
|
|
36
|
+
// Handle block comment boundaries
|
|
37
|
+
if (inBlockComment) {
|
|
38
|
+
if (line.includes("*/")) {
|
|
39
|
+
inBlockComment = false;
|
|
40
|
+
}
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
// Check for block comment start (that doesn't end on same line)
|
|
44
|
+
const blockStart = line.indexOf("/*");
|
|
45
|
+
const blockEnd = line.indexOf("*/");
|
|
46
|
+
if (blockStart !== -1 && (blockEnd === -1 || blockEnd < blockStart)) {
|
|
47
|
+
inBlockComment = true;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Skip single-line comments (// at start or after whitespace)
|
|
51
|
+
const trimmed = line.trimStart();
|
|
52
|
+
if (trimmed.startsWith("//")) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// Skip JSDoc-style lines (e.g., " * import ...")
|
|
56
|
+
if (trimmed.startsWith("*")) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
let match;
|
|
60
|
+
// Reset lastIndex for each line
|
|
61
|
+
importPattern.lastIndex = 0;
|
|
62
|
+
while ((match = importPattern.exec(line)) !== null) {
|
|
63
|
+
// Check if this match is after a // comment marker on the same line
|
|
64
|
+
const beforeMatch = line.substring(0, match.index);
|
|
65
|
+
if (beforeMatch.includes("//")) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
imports.push({
|
|
69
|
+
importPath: match[2],
|
|
70
|
+
lineNum: i + 1,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return imports;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Check if a relative import resolves to an existing file.
|
|
78
|
+
* Handles .ts, .tsx, .js, .jsx extensions and index files.
|
|
79
|
+
* Also handles TypeScript ESM convention where imports use .js but resolve to .ts.
|
|
80
|
+
*/
|
|
81
|
+
export function resolveImportPath(importPath, sourceFile, basePath) {
|
|
82
|
+
const sourceDir = dirname(resolve(basePath, sourceFile));
|
|
83
|
+
const extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
84
|
+
// Handle TypeScript ESM convention: .js imports resolve to .ts files
|
|
85
|
+
// e.g., import './types.js' -> ./types.ts
|
|
86
|
+
let normalizedPath = importPath;
|
|
87
|
+
if (importPath.endsWith(".js")) {
|
|
88
|
+
normalizedPath = importPath.slice(0, -3);
|
|
89
|
+
}
|
|
90
|
+
else if (importPath.endsWith(".jsx")) {
|
|
91
|
+
normalizedPath = importPath.slice(0, -4);
|
|
92
|
+
}
|
|
93
|
+
else if (importPath.endsWith(".mjs")) {
|
|
94
|
+
normalizedPath = importPath.slice(0, -4);
|
|
95
|
+
}
|
|
96
|
+
else if (importPath.endsWith(".cjs")) {
|
|
97
|
+
normalizedPath = importPath.slice(0, -4);
|
|
98
|
+
}
|
|
99
|
+
// Try the normalized path with common extensions first
|
|
100
|
+
for (const ext of extensions) {
|
|
101
|
+
const fullPath = resolve(sourceDir, normalizedPath + ext);
|
|
102
|
+
if (existsSync(fullPath)) {
|
|
103
|
+
return { exists: true, resolvedPath: fullPath };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Try as a directory with index file
|
|
107
|
+
for (const ext of extensions) {
|
|
108
|
+
const indexPath = resolve(sourceDir, normalizedPath, `index${ext}`);
|
|
109
|
+
if (existsSync(indexPath)) {
|
|
110
|
+
return { exists: true, resolvedPath: indexPath };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Check if path already has extension (for .json, etc.)
|
|
114
|
+
const hasExt = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".json"].some((ext) => importPath.endsWith(ext));
|
|
115
|
+
if (hasExt) {
|
|
116
|
+
const fullPath = resolve(sourceDir, importPath);
|
|
117
|
+
if (existsSync(fullPath)) {
|
|
118
|
+
return { exists: true, resolvedPath: fullPath };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { exists: false, resolvedPath: null };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Check that all relative imports in the task's key_files resolve to existing files.
|
|
125
|
+
* Reads modified files from task.key_files, extracts import statements via regex,
|
|
126
|
+
* verifies relative imports resolve to existing files.
|
|
127
|
+
*/
|
|
128
|
+
export function checkImportResolution(taskRow, _priorTasks, basePath) {
|
|
129
|
+
const results = [];
|
|
130
|
+
// Get files from key_files
|
|
131
|
+
const filesToCheck = taskRow.key_files.filter((f) => {
|
|
132
|
+
const ext = extname(f);
|
|
133
|
+
return [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext);
|
|
134
|
+
});
|
|
135
|
+
for (const file of filesToCheck) {
|
|
136
|
+
const absolutePath = resolve(basePath, file);
|
|
137
|
+
// Skip if file doesn't exist (might have been deleted or renamed)
|
|
138
|
+
if (!existsSync(absolutePath)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
let source;
|
|
142
|
+
try {
|
|
143
|
+
source = readFileSync(absolutePath, "utf-8");
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const imports = extractRelativeImports(source);
|
|
149
|
+
for (const { importPath, lineNum } of imports) {
|
|
150
|
+
const resolution = resolveImportPath(importPath, file, basePath);
|
|
151
|
+
if (!resolution.exists) {
|
|
152
|
+
results.push({
|
|
153
|
+
category: "import",
|
|
154
|
+
target: `${file}:${lineNum}`,
|
|
155
|
+
passed: false,
|
|
156
|
+
message: `Import '${importPath}' in ${file}:${lineNum} does not resolve to an existing file`,
|
|
157
|
+
blocking: true,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return results;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Extract function signatures from TypeScript/JavaScript source code.
|
|
166
|
+
*/
|
|
167
|
+
function extractFunctionSignatures(source, fileName) {
|
|
168
|
+
const signatures = [];
|
|
169
|
+
const lines = source.split("\n");
|
|
170
|
+
// Match function declarations and exports
|
|
171
|
+
// Patterns:
|
|
172
|
+
// function name(params): ReturnType
|
|
173
|
+
// export function name(params): ReturnType
|
|
174
|
+
// export async function name(params): Promise<ReturnType>
|
|
175
|
+
// const name = (params): ReturnType =>
|
|
176
|
+
// export const name = (params): ReturnType =>
|
|
177
|
+
const funcPattern = /(?:export\s+)?(?:async\s+)?(?:function\s+|const\s+)(\w+)(?:\s*=\s*)?\s*\(([^)]*)\)(?:\s*:\s*([^{=>\n]+))?/g;
|
|
178
|
+
for (let i = 0; i < lines.length; i++) {
|
|
179
|
+
const line = lines[i];
|
|
180
|
+
funcPattern.lastIndex = 0;
|
|
181
|
+
let match;
|
|
182
|
+
while ((match = funcPattern.exec(line)) !== null) {
|
|
183
|
+
const [, name, params, returnType] = match;
|
|
184
|
+
signatures.push({
|
|
185
|
+
name,
|
|
186
|
+
params: normalizeParams(params),
|
|
187
|
+
returnType: normalizeType(returnType || "void"),
|
|
188
|
+
file: fileName,
|
|
189
|
+
lineNum: i + 1,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return signatures;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Normalize parameter list for comparison.
|
|
197
|
+
*/
|
|
198
|
+
function normalizeParams(params) {
|
|
199
|
+
return params
|
|
200
|
+
.replace(/\/\*[\s\S]*?\*\//g, "") // Remove block comments
|
|
201
|
+
.replace(/\/\/[^\n]*/g, "") // Remove line comments
|
|
202
|
+
.replace(/\s*=\s*[^,)]+/g, "") // Remove default values
|
|
203
|
+
.replace(/\s+/g, " ") // Normalize whitespace
|
|
204
|
+
.trim();
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Normalize type for comparison.
|
|
208
|
+
*/
|
|
209
|
+
function normalizeType(type) {
|
|
210
|
+
return type.replace(/\s+/g, " ").trim();
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Compare function signatures in current task's output against prior tasks' key_files
|
|
214
|
+
* to catch hallucination cascades — when a task references functions that don't exist
|
|
215
|
+
* or have different signatures than what was actually created.
|
|
216
|
+
*/
|
|
217
|
+
export function checkCrossTaskSignatures(taskRow, priorTasks, basePath) {
|
|
218
|
+
const results = [];
|
|
219
|
+
// Build map of functions from prior tasks' key_files
|
|
220
|
+
const priorSignatures = new Map();
|
|
221
|
+
for (const task of priorTasks) {
|
|
222
|
+
for (const file of task.key_files) {
|
|
223
|
+
const ext = extname(file);
|
|
224
|
+
if (![".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext))
|
|
225
|
+
continue;
|
|
226
|
+
const absolutePath = resolve(basePath, file);
|
|
227
|
+
if (!existsSync(absolutePath))
|
|
228
|
+
continue;
|
|
229
|
+
try {
|
|
230
|
+
const source = readFileSync(absolutePath, "utf-8");
|
|
231
|
+
const sigs = extractFunctionSignatures(source, file);
|
|
232
|
+
for (const sig of sigs) {
|
|
233
|
+
const existing = priorSignatures.get(sig.name) || [];
|
|
234
|
+
existing.push(sig);
|
|
235
|
+
priorSignatures.set(sig.name, existing);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Skip unreadable files
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Extract function calls/references from current task's key_files
|
|
244
|
+
// and check they match prior definitions
|
|
245
|
+
for (const file of taskRow.key_files) {
|
|
246
|
+
const ext = extname(file);
|
|
247
|
+
if (![".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext))
|
|
248
|
+
continue;
|
|
249
|
+
const absolutePath = resolve(basePath, file);
|
|
250
|
+
if (!existsSync(absolutePath))
|
|
251
|
+
continue;
|
|
252
|
+
try {
|
|
253
|
+
const source = readFileSync(absolutePath, "utf-8");
|
|
254
|
+
const currentSigs = extractFunctionSignatures(source, file);
|
|
255
|
+
// Check each function in current task against prior definitions
|
|
256
|
+
for (const currentSig of currentSigs) {
|
|
257
|
+
const priorDefs = priorSignatures.get(currentSig.name);
|
|
258
|
+
// If this function was defined in a prior task, check for signature drift
|
|
259
|
+
if (priorDefs && priorDefs.length > 0) {
|
|
260
|
+
const priorDef = priorDefs[0]; // Use first definition
|
|
261
|
+
// Check parameter mismatch
|
|
262
|
+
if (currentSig.params !== priorDef.params) {
|
|
263
|
+
results.push({
|
|
264
|
+
category: "signature",
|
|
265
|
+
target: currentSig.name,
|
|
266
|
+
passed: false,
|
|
267
|
+
message: `Function '${currentSig.name}' in ${file}:${currentSig.lineNum} has parameters '${currentSig.params}' but prior definition in ${priorDef.file}:${priorDef.lineNum} has '${priorDef.params}'`,
|
|
268
|
+
blocking: false, // Warn only — may be intentional override
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
// Check return type mismatch
|
|
272
|
+
if (currentSig.returnType !== priorDef.returnType) {
|
|
273
|
+
results.push({
|
|
274
|
+
category: "signature",
|
|
275
|
+
target: currentSig.name,
|
|
276
|
+
passed: false,
|
|
277
|
+
message: `Function '${currentSig.name}' in ${file}:${currentSig.lineNum} returns '${currentSig.returnType}' but prior definition in ${priorDef.file}:${priorDef.lineNum} returns '${priorDef.returnType}'`,
|
|
278
|
+
blocking: false, // Warn only — may be intentional override
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
// Skip unreadable files
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return results;
|
|
289
|
+
}
|
|
290
|
+
// ─── Pattern Consistency Check ───────────────────────────────────────────────
|
|
291
|
+
/**
|
|
292
|
+
* Detect async style drift (mixing async/await with .then()) and
|
|
293
|
+
* naming convention inconsistencies within a task's key_files.
|
|
294
|
+
* Warn only — these are style issues, not correctness issues.
|
|
295
|
+
*/
|
|
296
|
+
export function checkPatternConsistency(taskRow, _priorTasks, basePath) {
|
|
297
|
+
const results = [];
|
|
298
|
+
for (const file of taskRow.key_files) {
|
|
299
|
+
const ext = extname(file);
|
|
300
|
+
if (![".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext))
|
|
301
|
+
continue;
|
|
302
|
+
const absolutePath = resolve(basePath, file);
|
|
303
|
+
if (!existsSync(absolutePath))
|
|
304
|
+
continue;
|
|
305
|
+
try {
|
|
306
|
+
const source = readFileSync(absolutePath, "utf-8");
|
|
307
|
+
// Check for async style drift
|
|
308
|
+
const asyncStyleResult = checkAsyncStyleDrift(source, file);
|
|
309
|
+
if (asyncStyleResult) {
|
|
310
|
+
results.push(asyncStyleResult);
|
|
311
|
+
}
|
|
312
|
+
// Check for naming convention inconsistencies
|
|
313
|
+
const namingResults = checkNamingConsistency(source, file);
|
|
314
|
+
results.push(...namingResults);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
// Skip unreadable files
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return results;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Detect async style drift within a single file.
|
|
324
|
+
* Returns a warning if both async/await AND .then() promise chaining are used.
|
|
325
|
+
*/
|
|
326
|
+
function checkAsyncStyleDrift(source, fileName) {
|
|
327
|
+
// Check for async/await usage
|
|
328
|
+
const hasAsyncAwait = /\basync\b[\s\S]*?\bawait\b/.test(source);
|
|
329
|
+
// Check for .then() promise chaining (excluding comments)
|
|
330
|
+
// Filter out common false positives like Array.prototype.then doesn't exist
|
|
331
|
+
const hasThenChaining = /\.\s*then\s*\(/.test(source);
|
|
332
|
+
// If both patterns are present, flag as style drift
|
|
333
|
+
if (hasAsyncAwait && hasThenChaining) {
|
|
334
|
+
return {
|
|
335
|
+
category: "pattern",
|
|
336
|
+
target: fileName,
|
|
337
|
+
passed: true, // Warning only
|
|
338
|
+
message: `File ${fileName} mixes async/await with .then() promise chaining — consider using consistent async style`,
|
|
339
|
+
blocking: false,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Check for naming convention inconsistencies within a file.
|
|
346
|
+
* Detects mixing of camelCase and snake_case for similar identifier types.
|
|
347
|
+
*/
|
|
348
|
+
function checkNamingConsistency(source, fileName) {
|
|
349
|
+
const results = [];
|
|
350
|
+
// Extract function names
|
|
351
|
+
const functionNames = [];
|
|
352
|
+
const funcPattern = /(?:function\s+|const\s+|let\s+|var\s+)(\w+)(?:\s*=\s*(?:async\s*)?\(|\s*\()/g;
|
|
353
|
+
let match;
|
|
354
|
+
while ((match = funcPattern.exec(source)) !== null) {
|
|
355
|
+
functionNames.push(match[1]);
|
|
356
|
+
}
|
|
357
|
+
// Check for mixed naming conventions in functions
|
|
358
|
+
const camelCaseFuncs = functionNames.filter((n) => /^[a-z][a-zA-Z0-9]*$/.test(n) && /[A-Z]/.test(n));
|
|
359
|
+
const snakeCaseFuncs = functionNames.filter((n) => /^[a-z][a-z0-9]*(_[a-z0-9]+)+$/.test(n));
|
|
360
|
+
if (camelCaseFuncs.length > 0 && snakeCaseFuncs.length > 0) {
|
|
361
|
+
results.push({
|
|
362
|
+
category: "pattern",
|
|
363
|
+
target: fileName,
|
|
364
|
+
passed: true, // Warning only
|
|
365
|
+
message: `File ${fileName} mixes camelCase (${camelCaseFuncs.slice(0, 2).join(", ")}) and snake_case (${snakeCaseFuncs.slice(0, 2).join(", ")}) function names`,
|
|
366
|
+
blocking: false,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return results;
|
|
370
|
+
}
|
|
371
|
+
// ─── Main Entry Point ────────────────────────────────────────────────────────
|
|
372
|
+
/**
|
|
373
|
+
* Run all post-execution checks against a completed task.
|
|
374
|
+
*
|
|
375
|
+
* @param taskRow - The completed task row
|
|
376
|
+
* @param priorTasks - Array of TaskRow from prior completed tasks in the slice
|
|
377
|
+
* @param basePath - Base path for resolving file references
|
|
378
|
+
* @returns PostExecutionResult with status, checks, and duration
|
|
379
|
+
*/
|
|
380
|
+
export function runPostExecutionChecks(taskRow, priorTasks, basePath) {
|
|
381
|
+
const startTime = Date.now();
|
|
382
|
+
const allChecks = [];
|
|
383
|
+
// Run all checks
|
|
384
|
+
const importChecks = checkImportResolution(taskRow, priorTasks, basePath);
|
|
385
|
+
const signatureChecks = checkCrossTaskSignatures(taskRow, priorTasks, basePath);
|
|
386
|
+
const patternChecks = checkPatternConsistency(taskRow, priorTasks, basePath);
|
|
387
|
+
allChecks.push(...importChecks, ...signatureChecks, ...patternChecks);
|
|
388
|
+
const durationMs = Date.now() - startTime;
|
|
389
|
+
// Determine overall status
|
|
390
|
+
const hasBlockingFailure = allChecks.some((c) => !c.passed && c.blocking);
|
|
391
|
+
const hasNonBlockingIssue = allChecks.some((c) => (!c.passed && !c.blocking) || (c.passed && c.category === "pattern"));
|
|
392
|
+
let status;
|
|
393
|
+
if (hasBlockingFailure) {
|
|
394
|
+
status = "fail";
|
|
395
|
+
}
|
|
396
|
+
else if (hasNonBlockingIssue) {
|
|
397
|
+
status = "warn";
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
status = "pass";
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
status,
|
|
404
|
+
checks: allChecks,
|
|
405
|
+
durationMs,
|
|
406
|
+
};
|
|
407
|
+
}
|