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
|
@@ -895,6 +895,7 @@ export async function pauseAuto(
|
|
|
895
895
|
sessionFile: s.pausedSessionFile,
|
|
896
896
|
activeEngineId: s.activeEngineId,
|
|
897
897
|
activeRunDir: s.activeRunDir,
|
|
898
|
+
autoStartTime: s.autoStartTime,
|
|
898
899
|
};
|
|
899
900
|
const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
|
|
900
901
|
mkdirSync(runtimeDir, { recursive: true });
|
|
@@ -1137,6 +1138,7 @@ export async function startAuto(
|
|
|
1137
1138
|
s.activeRunDir = meta.activeRunDir ?? null;
|
|
1138
1139
|
s.originalBasePath = meta.originalBasePath || base;
|
|
1139
1140
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
1141
|
+
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
1140
1142
|
s.paused = true;
|
|
1141
1143
|
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
|
1142
1144
|
logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
@@ -1162,6 +1164,7 @@ export async function startAuto(
|
|
|
1162
1164
|
s.currentMilestoneId = meta.milestoneId;
|
|
1163
1165
|
s.originalBasePath = meta.originalBasePath || base;
|
|
1164
1166
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
1167
|
+
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
1165
1168
|
s.paused = true;
|
|
1166
1169
|
// Clean up the persisted file — we're consuming it
|
|
1167
1170
|
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
|
@@ -1194,6 +1197,7 @@ export async function startAuto(
|
|
|
1194
1197
|
s.cmdCtx = ctx;
|
|
1195
1198
|
s.basePath = base;
|
|
1196
1199
|
setLogBasePath(base);
|
|
1200
|
+
if (!s.autoStartTime || s.autoStartTime <= 0) s.autoStartTime = Date.now();
|
|
1197
1201
|
s.unitDispatchCount.clear();
|
|
1198
1202
|
s.unitLifetimeDispatches.clear();
|
|
1199
1203
|
if (!getLedger()) initMetrics(base);
|
|
@@ -804,27 +804,39 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
804
804
|
return m ? [m[1].trim(), m[2].trim()] : [s.trim(), ""];
|
|
805
805
|
};
|
|
806
806
|
const coerced = { ...params };
|
|
807
|
-
|
|
807
|
+
// Coerce simple string-array fields: LLMs sometimes pass a plain string
|
|
808
|
+
// instead of a single-element array (#3585).
|
|
809
|
+
const wrapArray = (v: any): any[] =>
|
|
810
|
+
v == null ? [] : Array.isArray(v) ? v : [v];
|
|
811
|
+
coerced.provides = wrapArray(params.provides);
|
|
812
|
+
coerced.keyFiles = wrapArray(params.keyFiles);
|
|
813
|
+
coerced.keyDecisions = wrapArray(params.keyDecisions);
|
|
814
|
+
coerced.patternsEstablished = wrapArray(params.patternsEstablished);
|
|
815
|
+
coerced.observabilitySurfaces = wrapArray(params.observabilitySurfaces);
|
|
816
|
+
coerced.requirementsSurfaced = wrapArray(params.requirementsSurfaced);
|
|
817
|
+
coerced.drillDownPaths = wrapArray(params.drillDownPaths);
|
|
818
|
+
coerced.affects = wrapArray(params.affects);
|
|
819
|
+
coerced.filesModified = wrapArray(params.filesModified).map((f: any) => {
|
|
808
820
|
if (typeof f !== "string") return f;
|
|
809
821
|
const [path, description] = splitPair(f);
|
|
810
822
|
return { path, description };
|
|
811
823
|
});
|
|
812
|
-
coerced.requires = (params.requires
|
|
824
|
+
coerced.requires = wrapArray(params.requires).map((r: any) => {
|
|
813
825
|
if (typeof r !== "string") return r;
|
|
814
826
|
const [slice, provides] = splitPair(r);
|
|
815
827
|
return { slice, provides };
|
|
816
828
|
});
|
|
817
|
-
coerced.requirementsAdvanced = (params.requirementsAdvanced
|
|
829
|
+
coerced.requirementsAdvanced = wrapArray(params.requirementsAdvanced).map((r: any) => {
|
|
818
830
|
if (typeof r !== "string") return r;
|
|
819
831
|
const [id, how] = splitPair(r);
|
|
820
832
|
return { id, how };
|
|
821
833
|
});
|
|
822
|
-
coerced.requirementsValidated = (params.requirementsValidated
|
|
834
|
+
coerced.requirementsValidated = wrapArray(params.requirementsValidated).map((r: any) => {
|
|
823
835
|
if (typeof r !== "string") return r;
|
|
824
836
|
const [id, proof] = splitPair(r);
|
|
825
837
|
return { id, proof };
|
|
826
838
|
});
|
|
827
|
-
coerced.requirementsInvalidated = (params.requirementsInvalidated
|
|
839
|
+
coerced.requirementsInvalidated = wrapArray(params.requirementsInvalidated).map((r: any) => {
|
|
828
840
|
if (typeof r !== "string") return r;
|
|
829
841
|
const [id, what] = splitPair(r);
|
|
830
842
|
return { id, what };
|
|
@@ -884,14 +896,14 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
884
896
|
deviations: Type.Optional(Type.String({ description: "Deviations from the slice plan, or 'None.'" })),
|
|
885
897
|
knownLimitations: Type.Optional(Type.String({ description: "Known limitations or gaps, or 'None.'" })),
|
|
886
898
|
followUps: Type.Optional(Type.String({ description: "Follow-up work discovered during execution, or 'None.'" })),
|
|
887
|
-
keyFiles: Type.Optional(Type.Array(Type.String(), { description: "Key files created or modified" })),
|
|
888
|
-
keyDecisions: Type.Optional(Type.Array(Type.String(), { description: "Key decisions made during this slice" })),
|
|
889
|
-
patternsEstablished: Type.Optional(Type.Array(Type.String(), { description: "Patterns established by this slice" })),
|
|
890
|
-
observabilitySurfaces: Type.Optional(Type.Array(Type.String(), { description: "Observability surfaces added" })),
|
|
891
|
-
provides: Type.Optional(Type.Array(Type.String(), { description: "What this slice provides to downstream slices" })),
|
|
892
|
-
requirementsSurfaced: Type.Optional(Type.Array(Type.String(), { description: "New requirements surfaced" })),
|
|
893
|
-
drillDownPaths: Type.Optional(Type.Array(Type.String(), { description: "Paths to task summaries for drill-down" })),
|
|
894
|
-
affects: Type.Optional(Type.Array(Type.String(), { description: "Downstream slices affected" })),
|
|
899
|
+
keyFiles: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "Key files created or modified" })),
|
|
900
|
+
keyDecisions: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "Key decisions made during this slice" })),
|
|
901
|
+
patternsEstablished: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "Patterns established by this slice" })),
|
|
902
|
+
observabilitySurfaces: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "Observability surfaces added" })),
|
|
903
|
+
provides: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "What this slice provides to downstream slices" })),
|
|
904
|
+
requirementsSurfaced: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "New requirements surfaced" })),
|
|
905
|
+
drillDownPaths: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "Paths to task summaries for drill-down" })),
|
|
906
|
+
affects: Type.Optional(Type.Union([Type.Array(Type.String()), Type.String()], { description: "Downstream slices affected" })),
|
|
895
907
|
requirementsAdvanced: Type.Optional(Type.Array(
|
|
896
908
|
Type.Union([
|
|
897
909
|
Type.Object({
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// GSD Extension — Notify Interceptor
|
|
2
|
+
// Wraps ctx.ui.notify() in-place to persist every notification through the
|
|
3
|
+
// notification store. Uses a WeakSet to prevent double-wrapping and handle
|
|
4
|
+
// UI context replacement on /reload gracefully.
|
|
5
|
+
|
|
6
|
+
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
7
|
+
|
|
8
|
+
import { appendNotification, type NotifySeverity } from "../notification-store.js";
|
|
9
|
+
|
|
10
|
+
// Track which ui context objects have been wrapped to prevent double-install.
|
|
11
|
+
// WeakSet allows GC to collect replaced uiContext instances after /reload.
|
|
12
|
+
const _wrappedContexts = new WeakSet<object>();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Install the notify interceptor on a context's UI object.
|
|
16
|
+
* Mutates ctx.ui.notify in place — the original is called after persistence.
|
|
17
|
+
* Safe to call multiple times; no-ops if already installed on the same ui object.
|
|
18
|
+
*/
|
|
19
|
+
export function installNotifyInterceptor(ctx: ExtensionContext): void {
|
|
20
|
+
if (_wrappedContexts.has(ctx.ui)) return;
|
|
21
|
+
|
|
22
|
+
const originalNotify = ctx.ui.notify.bind(ctx.ui);
|
|
23
|
+
|
|
24
|
+
(ctx.ui as any).notify = (message: string, type?: "info" | "warning" | "error" | "success"): void => {
|
|
25
|
+
try {
|
|
26
|
+
appendNotification(message, (type ?? "info") as NotifySeverity, "notify");
|
|
27
|
+
} catch {
|
|
28
|
+
// Non-fatal — never let persistence break the UI
|
|
29
|
+
}
|
|
30
|
+
originalNotify(message, type);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
_wrappedContexts.add(ctx.ui);
|
|
34
|
+
}
|
|
@@ -21,6 +21,9 @@ import { resetAskUserQuestionsCache } from "../../ask-user-questions.js";
|
|
|
21
21
|
import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult } from "../safety/evidence-collector.js";
|
|
22
22
|
import { classifyCommand } from "../safety/destructive-guard.js";
|
|
23
23
|
import { logWarning as safetyLogWarning } from "../workflow-logger.js";
|
|
24
|
+
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
25
|
+
import { initNotificationStore } from "../notification-store.js";
|
|
26
|
+
import { initNotificationWidget } from "../notification-widget.js";
|
|
24
27
|
|
|
25
28
|
// Skip the welcome screen on the very first session_start — cli.ts already
|
|
26
29
|
// printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
|
|
@@ -33,6 +36,9 @@ async function syncServiceTierStatus(ctx: ExtensionContext): Promise<void> {
|
|
|
33
36
|
|
|
34
37
|
export function registerHooks(pi: ExtensionAPI): void {
|
|
35
38
|
pi.on("session_start", async (_event, ctx) => {
|
|
39
|
+
initNotificationStore(process.cwd());
|
|
40
|
+
installNotifyInterceptor(ctx);
|
|
41
|
+
initNotificationWidget(ctx);
|
|
36
42
|
resetWriteGateState();
|
|
37
43
|
resetToolCallLoopGuard();
|
|
38
44
|
resetAskUserQuestionsCache();
|
|
@@ -70,6 +76,8 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
70
76
|
});
|
|
71
77
|
|
|
72
78
|
pi.on("session_switch", async (_event, ctx) => {
|
|
79
|
+
initNotificationStore(process.cwd());
|
|
80
|
+
installNotifyInterceptor(ctx);
|
|
73
81
|
resetWriteGateState();
|
|
74
82
|
resetToolCallLoopGuard();
|
|
75
83
|
resetAskUserQuestionsCache();
|
|
@@ -5,6 +5,7 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
|
5
5
|
import { Key } from "@gsd/pi-tui";
|
|
6
6
|
|
|
7
7
|
import { GSDDashboardOverlay } from "../dashboard-overlay.js";
|
|
8
|
+
import { GSDNotificationOverlay } from "../notification-overlay.js";
|
|
8
9
|
import { ParallelMonitorOverlay } from "../parallel-monitor-overlay.js";
|
|
9
10
|
import { shortcutDesc } from "../../shared/mod.js";
|
|
10
11
|
|
|
@@ -31,6 +32,25 @@ export function registerShortcuts(pi: ExtensionAPI): void {
|
|
|
31
32
|
},
|
|
32
33
|
});
|
|
33
34
|
|
|
35
|
+
pi.registerShortcut(Key.ctrlAlt("n"), {
|
|
36
|
+
description: shortcutDesc("Open notification history", "/gsd notifications"),
|
|
37
|
+
handler: async (ctx) => {
|
|
38
|
+
await ctx.ui.custom<void>(
|
|
39
|
+
(tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done()),
|
|
40
|
+
{
|
|
41
|
+
overlay: true,
|
|
42
|
+
overlayOptions: {
|
|
43
|
+
width: "80%",
|
|
44
|
+
minWidth: 60,
|
|
45
|
+
maxHeight: "88%",
|
|
46
|
+
anchor: "center",
|
|
47
|
+
backdrop: true,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
34
54
|
pi.registerShortcut(Key.ctrlAlt("p"), {
|
|
35
55
|
description: shortcutDesc("Open parallel worker monitor", "/gsd parallel watch"),
|
|
36
56
|
handler: async (ctx) => {
|
|
@@ -264,6 +264,13 @@ function buildWorktreeContextBlock(): string {
|
|
|
264
264
|
return "";
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Low-entropy resume intent patterns — short phrases a user types to
|
|
269
|
+
* continue work after a pause, rate limit, or context reset (#3615).
|
|
270
|
+
* Tested against the trimmed, lowercased prompt with trailing punctuation stripped.
|
|
271
|
+
*/
|
|
272
|
+
const RESUME_INTENT_PATTERNS = /^(continue|resume|ok|go|go ahead|proceed|keep going|carry on|next|yes|yeah|yep|sure|do it|let's go|pick up where you left off)$/;
|
|
273
|
+
|
|
267
274
|
async function buildGuidedExecuteContextInjection(prompt: string, basePath: string): Promise<string | null> {
|
|
268
275
|
const executeMatch = prompt.match(/Execute the next task:\s+(T\d+)\s+\("([^"]+)"\)\s+in slice\s+(S\d+)\s+of milestone\s+(M\d+(?:-[a-z0-9]{6})?)/i);
|
|
269
276
|
if (executeMatch) {
|
|
@@ -280,6 +287,27 @@ async function buildGuidedExecuteContextInjection(prompt: string, basePath: stri
|
|
|
280
287
|
}
|
|
281
288
|
}
|
|
282
289
|
|
|
290
|
+
// Fallback: low-entropy resume prompt (e.g., "continue", "ok", "go ahead")
|
|
291
|
+
// during an active executing task — inject task context so the agent
|
|
292
|
+
// doesn't rebuild from scratch (#3615).
|
|
293
|
+
// Intent-gated: only fire for short, resume-like prompts to avoid hijacking
|
|
294
|
+
// control/help/diagnostic prompts with unrelated execution context.
|
|
295
|
+
// Phase-gated: only fire during "executing" to avoid misrouting during
|
|
296
|
+
// replanning, gate evaluation, or other non-execution phases.
|
|
297
|
+
const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
|
|
298
|
+
if (RESUME_INTENT_PATTERNS.test(trimmed)) {
|
|
299
|
+
const state = await deriveState(basePath);
|
|
300
|
+
if (state.phase === "executing" && state.activeTask && state.activeMilestone && state.activeSlice) {
|
|
301
|
+
return buildTaskExecutionContextInjection(
|
|
302
|
+
basePath,
|
|
303
|
+
state.activeMilestone.id,
|
|
304
|
+
state.activeSlice.id,
|
|
305
|
+
state.activeTask.id,
|
|
306
|
+
state.activeTask.title,
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
283
311
|
return null;
|
|
284
312
|
}
|
|
285
313
|
|
|
@@ -15,7 +15,7 @@ export interface GsdCommandDefinition {
|
|
|
15
15
|
type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
|
|
16
16
|
|
|
17
17
|
export const GSD_COMMAND_DESCRIPTION =
|
|
18
|
-
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast|mcp|rethink|codebase";
|
|
18
|
+
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast|mcp|rethink|codebase|notifications";
|
|
19
19
|
|
|
20
20
|
export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
21
21
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
@@ -48,6 +48,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
|
48
48
|
{ cmd: "hooks", desc: "Show configured post-unit and pre-dispatch hooks" },
|
|
49
49
|
{ cmd: "run-hook", desc: "Manually trigger a specific hook" },
|
|
50
50
|
{ cmd: "skill-health", desc: "Skill lifecycle dashboard" },
|
|
51
|
+
{ cmd: "notifications", desc: "View, filter, and clear persistent notification history" },
|
|
51
52
|
{ cmd: "doctor", desc: "Runtime health checks with auto-fix" },
|
|
52
53
|
{ cmd: "logs", desc: "Browse activity logs, debug logs, and metrics" },
|
|
53
54
|
{ cmd: "forensics", desc: "Examine execution logs" },
|
|
@@ -110,6 +111,11 @@ const NESTED_COMPLETIONS: CompletionMap = {
|
|
|
110
111
|
{ cmd: "keys", desc: "Manage API keys" },
|
|
111
112
|
{ cmd: "prefs", desc: "Configure global preferences" },
|
|
112
113
|
],
|
|
114
|
+
notifications: [
|
|
115
|
+
{ cmd: "clear", desc: "Clear all notifications" },
|
|
116
|
+
{ cmd: "tail", desc: "Show last N notifications (default: 20)" },
|
|
117
|
+
{ cmd: "filter", desc: "Filter by severity (error|warning|info|success)" },
|
|
118
|
+
],
|
|
113
119
|
logs: [
|
|
114
120
|
{ cmd: "debug", desc: "List or view debug log files" },
|
|
115
121
|
{ cmd: "tail", desc: "Show last N activity log summaries" },
|
|
@@ -29,6 +29,7 @@ export function showHelp(ctx: ExtensionCommandContext): void {
|
|
|
29
29
|
" /gsd queue Show queued/dispatched units and execution order",
|
|
30
30
|
" /gsd history View execution history [--cost] [--phase] [--model] [N]",
|
|
31
31
|
" /gsd changelog Show categorized release notes [version]",
|
|
32
|
+
" /gsd notifications View persistent notification history [clear|tail|filter] (Ctrl+Alt+N)",
|
|
32
33
|
"",
|
|
33
34
|
"COURSE CORRECTION",
|
|
34
35
|
" /gsd steer <desc> Apply user override to active work",
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// GSD Extension — /gsd notifications Command Handler
|
|
2
|
+
// View, filter, and clear the persistent notification history.
|
|
3
|
+
|
|
4
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
readNotifications,
|
|
8
|
+
clearNotifications,
|
|
9
|
+
getUnreadCount,
|
|
10
|
+
suppressPersistence,
|
|
11
|
+
unsuppressPersistence,
|
|
12
|
+
type NotifySeverity,
|
|
13
|
+
} from "../../notification-store.js";
|
|
14
|
+
import { GSDNotificationOverlay } from "../../notification-overlay.js";
|
|
15
|
+
|
|
16
|
+
function severityIcon(severity: NotifySeverity): string {
|
|
17
|
+
switch (severity) {
|
|
18
|
+
case "error": return "✗";
|
|
19
|
+
case "warning": return "⚠";
|
|
20
|
+
case "success": return "✓";
|
|
21
|
+
case "info":
|
|
22
|
+
default: return "●";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function formatTimestamp(ts: string): string {
|
|
27
|
+
try {
|
|
28
|
+
const d = new Date(ts);
|
|
29
|
+
return d.toLocaleString("en-US", { hour12: false, month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
|
30
|
+
} catch {
|
|
31
|
+
return ts.slice(0, 19);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function handleNotificationsCommand(
|
|
36
|
+
args: string,
|
|
37
|
+
ctx: ExtensionCommandContext,
|
|
38
|
+
pi: ExtensionAPI,
|
|
39
|
+
): Promise<boolean> {
|
|
40
|
+
// /gsd notifications clear
|
|
41
|
+
if (args === "clear") {
|
|
42
|
+
clearNotifications();
|
|
43
|
+
// Suppress persistence so the confirmation toast doesn't re-populate the store
|
|
44
|
+
suppressPersistence();
|
|
45
|
+
try {
|
|
46
|
+
ctx.ui.notify("All notifications cleared.", "success");
|
|
47
|
+
} finally {
|
|
48
|
+
unsuppressPersistence();
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// /gsd notifications tail [N]
|
|
54
|
+
if (args === "tail" || args.startsWith("tail ")) {
|
|
55
|
+
const countStr = args.replace(/^tail\s*/, "").trim();
|
|
56
|
+
const count = countStr ? parseInt(countStr, 10) : 20;
|
|
57
|
+
const n = isNaN(count) || count < 1 ? 20 : Math.min(count, 100);
|
|
58
|
+
const entries = readNotifications().slice(0, n);
|
|
59
|
+
|
|
60
|
+
if (entries.length === 0) {
|
|
61
|
+
ctx.ui.notify("No notifications.", "info");
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const lines = entries.map((e) =>
|
|
66
|
+
`${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`,
|
|
67
|
+
);
|
|
68
|
+
ctx.ui.notify(`Last ${entries.length} notification(s):\n${lines.join("\n")}`, "info");
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// /gsd notifications filter <severity>
|
|
73
|
+
if (args.startsWith("filter ")) {
|
|
74
|
+
const severity = args.replace(/^filter\s+/, "").trim().toLowerCase();
|
|
75
|
+
if (!["error", "warning", "info", "success"].includes(severity)) {
|
|
76
|
+
ctx.ui.notify("Usage: /gsd notifications filter <error|warning|info|success>", "warning");
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const entries = readNotifications().filter((e) => e.severity === severity);
|
|
80
|
+
|
|
81
|
+
if (entries.length === 0) {
|
|
82
|
+
ctx.ui.notify(`No ${severity} notifications.`, "info");
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const lines = entries.slice(0, 20).map((e) =>
|
|
87
|
+
`${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`,
|
|
88
|
+
);
|
|
89
|
+
const suffix = entries.length > 20 ? `\n... and ${entries.length - 20} more` : "";
|
|
90
|
+
ctx.ui.notify(`${severity} notifications (${entries.length}):\n${lines.join("\n")}${suffix}`, "info");
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// /gsd notifications (no args) — open overlay in TUI, or print summary
|
|
95
|
+
if (args === "" || args === "status") {
|
|
96
|
+
// Try overlay first (TUI mode)
|
|
97
|
+
if (ctx.hasUI) {
|
|
98
|
+
try {
|
|
99
|
+
await ctx.ui.custom<void>(
|
|
100
|
+
(tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done()),
|
|
101
|
+
{
|
|
102
|
+
overlay: true,
|
|
103
|
+
overlayOptions: {
|
|
104
|
+
width: "80%",
|
|
105
|
+
minWidth: 60,
|
|
106
|
+
maxHeight: "88%",
|
|
107
|
+
anchor: "center",
|
|
108
|
+
backdrop: true,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
return true;
|
|
113
|
+
} catch {
|
|
114
|
+
// Fall through to text output if overlay fails
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Text fallback (RPC/headless mode)
|
|
119
|
+
const unread = getUnreadCount();
|
|
120
|
+
const entries = readNotifications().slice(0, 10);
|
|
121
|
+
if (entries.length === 0) {
|
|
122
|
+
ctx.ui.notify("No notifications.", "info");
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const lines = entries.map((e) =>
|
|
127
|
+
`${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`,
|
|
128
|
+
);
|
|
129
|
+
const header = unread > 0 ? `${unread} unread — ` : "";
|
|
130
|
+
ctx.ui.notify(`${header}Recent notifications:\n${lines.join("\n")}`, "info");
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Unknown subcommand
|
|
135
|
+
ctx.ui.notify(
|
|
136
|
+
"Usage: /gsd notifications [clear|tail [N]|filter <severity>]",
|
|
137
|
+
"warning",
|
|
138
|
+
);
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
@@ -178,6 +178,11 @@ Examples:
|
|
|
178
178
|
await dispatchDirectPhase(ctx, pi, phase, projectRoot());
|
|
179
179
|
return true;
|
|
180
180
|
}
|
|
181
|
+
if (trimmed === "notifications" || trimmed.startsWith("notifications ")) {
|
|
182
|
+
const { handleNotificationsCommand } = await import("./notifications-handler.js");
|
|
183
|
+
await handleNotificationsCommand(trimmed.replace(/^notifications\s*/, "").trim(), ctx, pi);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
181
186
|
if (trimmed === "inspect") {
|
|
182
187
|
await handleInspect(ctx);
|
|
183
188
|
return true;
|