gsd-pi 2.63.0 → 2.64.0-dev.05b8a94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -134
- package/dist/cli.js +48 -6
- package/dist/headless-query.js +11 -1
- package/dist/headless.js +3 -1
- package/dist/help-text.js +4 -1
- package/dist/onboarding.js +15 -8
- package/dist/resource-loader.js +18 -3
- 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/cmux/index.js +21 -12
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +27 -0
- package/dist/resources/extensions/gsd/auto/finalize-timeout.js +40 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -0
- package/dist/resources/extensions/gsd/auto/phases.js +157 -22
- package/dist/resources/extensions/gsd/auto/session.js +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +14 -8
- package/dist/resources/extensions/gsd/auto-model-selection.js +32 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +222 -11
- package/dist/resources/extensions/gsd/auto-prompts.js +25 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +15 -7
- package/dist/resources/extensions/gsd/auto-start.js +10 -21
- package/dist/resources/extensions/gsd/auto-timers.js +2 -1
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +17 -0
- package/dist/resources/extensions/gsd/auto-verification.js +138 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +13 -7
- package/dist/resources/extensions/gsd/auto.js +24 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +158 -75
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +13 -0
- package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +85 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +40 -1
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +15 -0
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +54 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +50 -2
- 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 +103 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +9 -4
- package/dist/resources/extensions/gsd/constants.js +42 -0
- package/dist/resources/extensions/gsd/db-writer.js +72 -4
- package/dist/resources/extensions/gsd/forensics.js +20 -4
- package/dist/resources/extensions/gsd/gsd-db.js +64 -17
- package/dist/resources/extensions/gsd/guided-flow.js +19 -0
- package/dist/resources/extensions/gsd/metrics.js +27 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +5 -3
- package/dist/resources/extensions/gsd/notification-overlay.js +224 -0
- package/dist/resources/extensions/gsd/notification-store.js +268 -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 +6 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +33 -0
- package/dist/resources/extensions/gsd/preferences.js +11 -2
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -0
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +4 -7
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
- package/dist/resources/extensions/gsd/roadmap-mutations.js +1 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +9 -5
- package/dist/resources/extensions/gsd/safety/content-validator.js +73 -0
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +34 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +109 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +83 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +71 -0
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +91 -0
- package/dist/resources/extensions/gsd/safety/safety-harness.js +64 -0
- package/dist/resources/extensions/gsd/slice-parallel-conflict.js +67 -0
- package/dist/resources/extensions/gsd/slice-parallel-eligibility.js +51 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +378 -0
- package/dist/resources/extensions/gsd/state.js +74 -14
- package/dist/resources/extensions/gsd/status-guards.js +11 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +17 -12
- package/dist/resources/extensions/gsd/tools/complete-slice.js +40 -26
- package/dist/resources/extensions/gsd/tools/complete-task.js +12 -12
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +33 -25
- package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -8
- package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +21 -5
- package/dist/resources/extensions/gsd/worktree-manager.js +82 -29
- package/dist/resources/extensions/gsd/worktree-resolver.js +4 -3
- package/dist/resources/extensions/mcp-client/auth.js +101 -0
- package/dist/resources/extensions/mcp-client/index.js +10 -1
- package/dist/resources/extensions/ollama/index.js +28 -22
- package/dist/resources/extensions/ollama/model-capabilities.js +37 -34
- package/dist/resources/extensions/ollama/ndjson-stream.js +54 -0
- package/dist/resources/extensions/ollama/ollama-chat-provider.js +380 -0
- package/dist/resources/extensions/ollama/ollama-client.js +23 -32
- package/dist/resources/extensions/ollama/ollama-discovery.js +2 -7
- package/dist/resources/extensions/ollama/ollama-tool.js +62 -0
- package/dist/resources/extensions/ollama/thinking-parser.js +104 -0
- package/dist/update-cmd.js +4 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -19
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +4 -4
- package/dist/web/standalone/.next/routes-manifest.json +6 -0
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +3 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -19
- package/dist/web/standalone/.next/server/chunks/6897.js +12 -0
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/Vbx2-SrSBOgta6576xj9m/_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/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts +8 -0
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +70 -3
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +317 -5
- package/packages/pi-agent-core/src/agent-loop.ts +90 -6
- package/packages/pi-ai/dist/types.d.ts +16 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/types.ts +18 -1
- 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/auth-storage.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +50 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +41 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +31 -4
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +28 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +12 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -3
- package/packages/pi-coding-agent/dist/core/model-resolver.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 +23 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +84 -57
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +9 -0
- package/packages/pi-coding-agent/dist/core/sdk.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/auth-storage.test.ts +53 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +66 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +39 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +34 -4
- package/packages/pi-coding-agent/src/core/extensions/provider-registration.test.ts +81 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +14 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -3
- 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 +94 -57
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -0
- 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/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/tui.d.ts +2 -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/components/loader.ts +27 -10
- package/packages/pi-tui/src/components/text.ts +1 -0
- package/packages/pi-tui/src/tui.ts +32 -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/cmux/index.ts +18 -12
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +27 -0
- package/src/resources/extensions/gsd/auto/finalize-timeout.ts +46 -0
- package/src/resources/extensions/gsd/auto/loop.ts +5 -0
- package/src/resources/extensions/gsd/auto/phases.ts +194 -33
- package/src/resources/extensions/gsd/auto/session.ts +14 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +16 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +36 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +263 -12
- package/src/resources/extensions/gsd/auto-prompts.ts +21 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +9 -8
- package/src/resources/extensions/gsd/auto-start.ts +11 -20
- package/src/resources/extensions/gsd/auto-timers.ts +2 -1
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-verification.ts +190 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +14 -6
- package/src/resources/extensions/gsd/auto.ts +26 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +172 -88
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +44 -1
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +19 -0
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +57 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +59 -2
- 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 +139 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +10 -4
- package/src/resources/extensions/gsd/constants.ts +44 -0
- package/src/resources/extensions/gsd/db-writer.ts +78 -4
- package/src/resources/extensions/gsd/forensics.ts +21 -5
- package/src/resources/extensions/gsd/gsd-db.ts +64 -17
- package/src/resources/extensions/gsd/guided-flow.ts +22 -0
- package/src/resources/extensions/gsd/metrics.ts +28 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +5 -3
- package/src/resources/extensions/gsd/notification-overlay.ts +267 -0
- package/src/resources/extensions/gsd/notification-store.ts +288 -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 +44 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +33 -0
- package/src/resources/extensions/gsd/preferences.ts +13 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -0
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +4 -7
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
- package/src/resources/extensions/gsd/roadmap-mutations.ts +1 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +10 -5
- package/src/resources/extensions/gsd/safety/content-validator.ts +98 -0
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +49 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +151 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +120 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +108 -0
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +106 -0
- package/src/resources/extensions/gsd/safety/safety-harness.ts +105 -0
- package/src/resources/extensions/gsd/slice-parallel-conflict.ts +86 -0
- package/src/resources/extensions/gsd/slice-parallel-eligibility.ts +73 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +477 -0
- package/src/resources/extensions/gsd/state.ts +67 -12
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +34 -13
- package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/cmux.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +247 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +109 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +13 -9
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/deferred-slice-dispatch.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +130 -0
- package/src/resources/extensions/gsd/tests/doctor-fix-flag.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/git-checkpoint.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/insert-slice-no-wipe.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +27 -7
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +116 -1
- package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +249 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +82 -18
- 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/preferences.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-eligibility.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +349 -0
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +35 -2
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +148 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +34 -20
- package/src/resources/extensions/gsd/tools/complete-slice.ts +41 -26
- package/src/resources/extensions/gsd/tools/complete-task.ts +12 -12
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +55 -30
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -8
- package/src/resources/extensions/gsd/types.ts +44 -22
- package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +15 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +23 -5
- package/src/resources/extensions/gsd/worktree-manager.ts +76 -28
- package/src/resources/extensions/gsd/worktree-resolver.ts +4 -3
- package/src/resources/extensions/mcp-client/auth.ts +149 -0
- package/src/resources/extensions/mcp-client/index.ts +16 -1
- package/src/resources/extensions/ollama/index.ts +26 -25
- package/src/resources/extensions/ollama/model-capabilities.ts +41 -34
- package/src/resources/extensions/ollama/ndjson-stream.ts +63 -0
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +20 -0
- package/src/resources/extensions/ollama/ollama-chat-provider.ts +459 -0
- package/src/resources/extensions/ollama/ollama-client.ts +30 -30
- package/src/resources/extensions/ollama/ollama-discovery.ts +5 -8
- package/src/resources/extensions/ollama/ollama-tool.ts +69 -0
- package/src/resources/extensions/ollama/tests/ollama-chat-provider-stream.test.ts +82 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -27
- package/src/resources/extensions/ollama/thinking-parser.ts +116 -0
- package/src/resources/extensions/ollama/types.ts +23 -0
- package/dist/web/standalone/.next/server/chunks/2229.js +0 -12
- package/dist/web/standalone/.next/static/5FLUBNdqolRyyehCyChPd/_buildManifest.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
- /package/dist/web/standalone/.next/static/{5FLUBNdqolRyyehCyChPd → Vbx2-SrSBOgta6576xj9m}/_ssgManifest.js +0 -0
|
@@ -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,24 @@ 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
|
+
},
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
34
53
|
pi.registerShortcut(Key.ctrlAlt("p"), {
|
|
35
54
|
description: shortcutDesc("Open parallel worker monitor", "/gsd parallel watch"),
|
|
36
55
|
handler: async (ctx) => {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input sanitization for gsd_complete_milestone parameters.
|
|
3
|
+
*
|
|
4
|
+
* The Claude SDK deserializes tool-call JSON before the handler runs.
|
|
5
|
+
* When an LLM (especially smaller models like haiku) generates large markdown
|
|
6
|
+
* parameters, the JSON can arrive with subtly wrong types — numbers where
|
|
7
|
+
* strings are expected, null where arrays belong, string "true" instead of
|
|
8
|
+
* boolean true, etc. This sanitizer normalizes all fields so
|
|
9
|
+
* handleCompleteMilestone never crashes on type mismatches.
|
|
10
|
+
*
|
|
11
|
+
* See: https://github.com/gsd-build/gsd-2/issues/3013
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { CompleteMilestoneParams } from "../tools/complete-milestone.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Coerce an unknown value to a trimmed string.
|
|
18
|
+
* Returns "" for null / undefined.
|
|
19
|
+
*/
|
|
20
|
+
function toStr(v: unknown): string {
|
|
21
|
+
if (v == null) return "";
|
|
22
|
+
return String(v).trim();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Coerce an unknown value to an array of trimmed, non-empty strings.
|
|
27
|
+
* - If already an array, filter/trim each element.
|
|
28
|
+
* - Otherwise return [].
|
|
29
|
+
*/
|
|
30
|
+
function toStrArray(v: unknown): string[] {
|
|
31
|
+
if (!Array.isArray(v)) return [];
|
|
32
|
+
return v
|
|
33
|
+
.map((item) => (item == null ? "" : String(item).trim()))
|
|
34
|
+
.filter((s) => s.length > 0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Sanitize raw params from the tool-call framework into well-typed
|
|
39
|
+
* CompleteMilestoneParams, tolerating type mismatches from LLM JSON quirks.
|
|
40
|
+
*/
|
|
41
|
+
export function sanitizeCompleteMilestoneParams(raw: Record<string, unknown>): CompleteMilestoneParams {
|
|
42
|
+
return {
|
|
43
|
+
milestoneId: toStr(raw.milestoneId),
|
|
44
|
+
title: toStr(raw.title),
|
|
45
|
+
oneLiner: toStr(raw.oneLiner),
|
|
46
|
+
narrative: toStr(raw.narrative),
|
|
47
|
+
successCriteriaResults: toStr(raw.successCriteriaResults),
|
|
48
|
+
definitionOfDoneResults: toStr(raw.definitionOfDoneResults),
|
|
49
|
+
requirementOutcomes: toStr(raw.requirementOutcomes),
|
|
50
|
+
keyDecisions: toStrArray(raw.keyDecisions),
|
|
51
|
+
keyFiles: toStrArray(raw.keyFiles),
|
|
52
|
+
lessonsLearned: toStrArray(raw.lessonsLearned),
|
|
53
|
+
followUps: toStr(raw.followUps),
|
|
54
|
+
deviations: toStr(raw.deviations),
|
|
55
|
+
verificationPassed: raw.verificationPassed === true || raw.verificationPassed === "true",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -6,9 +6,10 @@ import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
6
6
|
|
|
7
7
|
import { logWarning } from "../workflow-logger.js";
|
|
8
8
|
import { debugTime } from "../debug-logger.js";
|
|
9
|
-
import { loadPrompt } from "../prompt-loader.js";
|
|
9
|
+
import { loadPrompt, getTemplatesDir } from "../prompt-loader.js";
|
|
10
10
|
import { readForensicsMarker } from "../forensics.js";
|
|
11
11
|
import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffectiveGSDPreferences } from "../preferences.js";
|
|
12
|
+
import { resolveSkillReference } from "../preferences-skills.js";
|
|
12
13
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
13
14
|
import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
|
|
14
15
|
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
@@ -20,6 +21,31 @@ import { markCmuxPromptShown, shouldPromptToEnableCmux } from "../../cmux/index.
|
|
|
20
21
|
|
|
21
22
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Bundled skill triggers — resolved dynamically at runtime instead of
|
|
26
|
+
* hardcoding absolute paths in the system prompt template. Only skills
|
|
27
|
+
* that actually exist on disk are included in the table. (#3575)
|
|
28
|
+
*/
|
|
29
|
+
const BUNDLED_SKILL_TRIGGERS: Array<{ trigger: string; skill: string }> = [
|
|
30
|
+
{ trigger: "Frontend UI - web components, pages, landing pages, dashboards, React/HTML/CSS, styling", skill: "frontend-design" },
|
|
31
|
+
{ trigger: "macOS or iOS apps - SwiftUI, Xcode, App Store", skill: "swiftui" },
|
|
32
|
+
{ trigger: "Debugging - complex bugs, failing tests, root-cause investigation after standard approaches fail", skill: "debug-like-expert" },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
function buildBundledSkillsTable(): string {
|
|
36
|
+
const cwd = process.cwd();
|
|
37
|
+
const rows: string[] = [];
|
|
38
|
+
for (const { trigger, skill } of BUNDLED_SKILL_TRIGGERS) {
|
|
39
|
+
const resolution = resolveSkillReference(skill, cwd);
|
|
40
|
+
if (resolution.method === "unresolved") continue; // skill not installed — omit from prompt
|
|
41
|
+
rows.push(`| ${trigger} | \`${resolution.resolvedPath}\` |`);
|
|
42
|
+
}
|
|
43
|
+
if (rows.length === 0) {
|
|
44
|
+
return "*No bundled skills found. Install skills to `~/.agents/skills/` or `~/.claude/skills/`.*";
|
|
45
|
+
}
|
|
46
|
+
return `| Trigger | Skill to load |\n|---|---|\n${rows.join("\n")}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
23
49
|
function warnDeprecatedAgentInstructions(): void {
|
|
24
50
|
const paths = [
|
|
25
51
|
join(gsdHome, "agent-instructions.md"),
|
|
@@ -43,7 +69,10 @@ export async function buildBeforeAgentStartResult(
|
|
|
43
69
|
if (!existsSync(join(process.cwd(), ".gsd"))) return undefined;
|
|
44
70
|
|
|
45
71
|
const stopContextTimer = debugTime("context-inject");
|
|
46
|
-
const systemContent = loadPrompt("system"
|
|
72
|
+
const systemContent = loadPrompt("system", {
|
|
73
|
+
bundledSkillsTable: buildBundledSkillsTable(),
|
|
74
|
+
templatesDir: getTemplatesDir(),
|
|
75
|
+
});
|
|
47
76
|
const loadedPreferences = loadEffectiveGSDPreferences();
|
|
48
77
|
if (shouldPromptToEnableCmux(loadedPreferences?.preferences)) {
|
|
49
78
|
markCmuxPromptShown();
|
|
@@ -235,6 +264,13 @@ function buildWorktreeContextBlock(): string {
|
|
|
235
264
|
return "";
|
|
236
265
|
}
|
|
237
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
|
+
|
|
238
274
|
async function buildGuidedExecuteContextInjection(prompt: string, basePath: string): Promise<string | null> {
|
|
239
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);
|
|
240
276
|
if (executeMatch) {
|
|
@@ -251,6 +287,27 @@ async function buildGuidedExecuteContextInjection(prompt: string, basePath: stri
|
|
|
251
287
|
}
|
|
252
288
|
}
|
|
253
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
|
+
|
|
254
311
|
return null;
|
|
255
312
|
}
|
|
256
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,139 @@
|
|
|
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
|
+
},
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
return true;
|
|
112
|
+
} catch {
|
|
113
|
+
// Fall through to text output if overlay fails
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Text fallback (RPC/headless mode)
|
|
118
|
+
const unread = getUnreadCount();
|
|
119
|
+
const entries = readNotifications().slice(0, 10);
|
|
120
|
+
if (entries.length === 0) {
|
|
121
|
+
ctx.ui.notify("No notifications.", "info");
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const lines = entries.map((e) =>
|
|
126
|
+
`${severityIcon(e.severity)} [${formatTimestamp(e.ts)}] ${e.message}`,
|
|
127
|
+
);
|
|
128
|
+
const header = unread > 0 ? `${unread} unread — ` : "";
|
|
129
|
+
ctx.ui.notify(`${header}Recent notifications:\n${lines.join("\n")}`, "info");
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Unknown subcommand
|
|
134
|
+
ctx.ui.notify(
|
|
135
|
+
"Usage: /gsd notifications [clear|tail [N]|filter <severity>]",
|
|
136
|
+
"warning",
|
|
137
|
+
);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
@@ -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;
|
|
@@ -43,21 +43,27 @@ export function dispatchDoctorHeal(pi: ExtensionAPI, scope: string | undefined,
|
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
/** Parse doctor command args into structured flags and positionals (pure, no I/O). */
|
|
47
|
+
export function parseDoctorArgs(args: string) {
|
|
47
48
|
const trimmed = args.trim();
|
|
48
|
-
// Extract flags before positional parsing
|
|
49
49
|
const jsonMode = trimmed.includes("--json");
|
|
50
50
|
const dryRun = trimmed.includes("--dry-run");
|
|
51
|
+
const fixFlag = trimmed.includes("--fix");
|
|
51
52
|
const includeBuild = trimmed.includes("--build");
|
|
52
53
|
const includeTests = trimmed.includes("--test");
|
|
53
|
-
const stripped = trimmed.replace(/--json|--dry-run|--build|--test/g, "").trim();
|
|
54
|
+
const stripped = trimmed.replace(/--json|--dry-run|--build|--test|--fix/g, "").trim();
|
|
54
55
|
const parts = stripped ? stripped.split(/\s+/) : [];
|
|
55
56
|
const mode = parts[0] === "fix" || parts[0] === "heal" || parts[0] === "audit" ? parts[0] : "doctor";
|
|
56
57
|
const requestedScope = mode === "doctor" ? parts[0] : parts[1];
|
|
58
|
+
return { jsonMode, dryRun, fixFlag, includeBuild, includeTests, mode, requestedScope };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function handleDoctor(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {
|
|
62
|
+
const { jsonMode, dryRun, fixFlag, includeBuild, includeTests, mode, requestedScope } = parseDoctorArgs(args);
|
|
57
63
|
const scope = await selectDoctorScope(projectRoot(), requestedScope);
|
|
58
64
|
const effectiveScope = mode === "audit" ? requestedScope : scope;
|
|
59
65
|
const report = await runGSDDoctor(projectRoot(), {
|
|
60
|
-
fix: mode === "fix" || mode === "heal" || dryRun,
|
|
66
|
+
fix: mode === "fix" || mode === "heal" || dryRun || fixFlag,
|
|
61
67
|
dryRun,
|
|
62
68
|
scope: effectiveScope,
|
|
63
69
|
includeBuild,
|
|
@@ -19,3 +19,47 @@ export const DIR_CACHE_MAX = 200;
|
|
|
19
19
|
|
|
20
20
|
/** Max parse-cache entries before eviction. */
|
|
21
21
|
export const CACHE_MAX = 50;
|
|
22
|
+
|
|
23
|
+
// ─── Tool Scoping ─────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* GSD tools allowed during discuss flows (#2949).
|
|
27
|
+
*
|
|
28
|
+
* xAI/Grok (and potentially other providers with grammar-based constrained
|
|
29
|
+
* decoding) return "Grammar is too complex" (HTTP 400) when the combined
|
|
30
|
+
* tool schemas exceed their internal grammar limit. The full GSD tool set
|
|
31
|
+
* registers ~33 tools with deeply nested schemas; discuss flows only need
|
|
32
|
+
* a small subset.
|
|
33
|
+
*
|
|
34
|
+
* By scoping tools to this allowlist during discuss dispatches, the grammar
|
|
35
|
+
* sent to the provider stays well under provider limits.
|
|
36
|
+
*
|
|
37
|
+
* Included tools and why:
|
|
38
|
+
* - gsd_summary_save: writes CONTEXT.md artifacts (all discuss prompts)
|
|
39
|
+
* - gsd_save_summary: alias for above
|
|
40
|
+
* - gsd_decision_save: records decisions (discuss.md output phase)
|
|
41
|
+
* - gsd_save_decision: alias for above
|
|
42
|
+
* - gsd_plan_milestone: writes roadmap (discuss.md single/multi milestone)
|
|
43
|
+
* - gsd_milestone_plan: alias for above
|
|
44
|
+
* - gsd_milestone_generate_id: generates milestone IDs (discuss.md multi-milestone)
|
|
45
|
+
* - gsd_generate_milestone_id: alias for above
|
|
46
|
+
* - gsd_requirement_update: updates requirements during discuss
|
|
47
|
+
* - gsd_update_requirement: alias for above
|
|
48
|
+
*/
|
|
49
|
+
export const DISCUSS_TOOLS_ALLOWLIST: readonly string[] = [
|
|
50
|
+
// Context / summary writing
|
|
51
|
+
"gsd_summary_save",
|
|
52
|
+
"gsd_save_summary",
|
|
53
|
+
// Decision recording
|
|
54
|
+
"gsd_decision_save",
|
|
55
|
+
"gsd_save_decision",
|
|
56
|
+
// Milestone planning (needed for discuss.md output phase)
|
|
57
|
+
"gsd_plan_milestone",
|
|
58
|
+
"gsd_milestone_plan",
|
|
59
|
+
// Milestone ID generation (multi-milestone flow)
|
|
60
|
+
"gsd_milestone_generate_id",
|
|
61
|
+
"gsd_generate_milestone_id",
|
|
62
|
+
// Requirement updates
|
|
63
|
+
"gsd_requirement_update",
|
|
64
|
+
"gsd_update_requirement",
|
|
65
|
+
];
|
|
@@ -469,6 +469,23 @@ export async function saveDecisionToDb(
|
|
|
469
469
|
adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
|
|
470
470
|
throw diskErr;
|
|
471
471
|
}
|
|
472
|
+
// #2661: When a decision defers a slice, update the slice status in the DB
|
|
473
|
+
// so the dispatcher skips it. Without this, STATE.md and DECISIONS.md are
|
|
474
|
+
// in split-brain: the decision says "deferred" but the state still says
|
|
475
|
+
// "active", causing auto-mode to keep dispatching the deferred work.
|
|
476
|
+
try {
|
|
477
|
+
const sliceRef = extractDeferredSliceRef(fields);
|
|
478
|
+
if (sliceRef) {
|
|
479
|
+
db.updateSliceStatus(sliceRef.milestoneId, sliceRef.sliceId, 'deferred');
|
|
480
|
+
}
|
|
481
|
+
} catch (deferErr) {
|
|
482
|
+
// Non-fatal — log but don't fail the decision save
|
|
483
|
+
logError('manifest', 'failed to update deferred slice status', {
|
|
484
|
+
fn: 'saveDecisionToDb',
|
|
485
|
+
error: String((deferErr as Error).message),
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
|
|
472
489
|
// Invalidate file-read caches so deriveState() sees the updated markdown.
|
|
473
490
|
// Do NOT clear the artifacts table — we just wrote to it intentionally.
|
|
474
491
|
invalidateStateCache();
|
|
@@ -482,6 +499,39 @@ export async function saveDecisionToDb(
|
|
|
482
499
|
}
|
|
483
500
|
}
|
|
484
501
|
|
|
502
|
+
/**
|
|
503
|
+
* Extract a milestone/slice reference from a deferral decision.
|
|
504
|
+
*
|
|
505
|
+
* Detects deferrals by checking:
|
|
506
|
+
* - scope contains "defer" (e.g., "deferral", "defer")
|
|
507
|
+
* - choice or decision contains "defer" + an M###/S## pattern
|
|
508
|
+
*
|
|
509
|
+
* Returns { milestoneId, sliceId } if found, null otherwise.
|
|
510
|
+
*/
|
|
511
|
+
export function extractDeferredSliceRef(
|
|
512
|
+
fields: Pick<SaveDecisionFields, 'scope' | 'decision' | 'choice'>,
|
|
513
|
+
): { milestoneId: string; sliceId: string } | null {
|
|
514
|
+
const isDeferral =
|
|
515
|
+
/\bdefer(?:ral|red|ring|s)?\b/i.test(fields.scope) ||
|
|
516
|
+
/\bdefer(?:ral|red|ring|s)?\b/i.test(fields.choice) ||
|
|
517
|
+
/\bdefer(?:ral|red|ring|s)?\b/i.test(fields.decision);
|
|
518
|
+
|
|
519
|
+
if (!isDeferral) return null;
|
|
520
|
+
|
|
521
|
+
// Look for M###/S## pattern in choice first, then decision
|
|
522
|
+
const slicePattern = /\b(M\d{3,4})\/(S\d{2,3})\b/;
|
|
523
|
+
const choiceMatch = fields.choice.match(slicePattern);
|
|
524
|
+
if (choiceMatch) {
|
|
525
|
+
return { milestoneId: choiceMatch[1], sliceId: choiceMatch[2] };
|
|
526
|
+
}
|
|
527
|
+
const decisionMatch = fields.decision.match(slicePattern);
|
|
528
|
+
if (decisionMatch) {
|
|
529
|
+
return { milestoneId: decisionMatch[1], sliceId: decisionMatch[2] };
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
return null;
|
|
533
|
+
}
|
|
534
|
+
|
|
485
535
|
// ─── Update Requirement in DB + Regenerate Markdown ───────────────────────
|
|
486
536
|
|
|
487
537
|
/**
|
|
@@ -496,11 +546,35 @@ export async function updateRequirementInDb(
|
|
|
496
546
|
try {
|
|
497
547
|
const db = await import('./gsd-db.js');
|
|
498
548
|
|
|
499
|
-
|
|
549
|
+
let existing = db.getRequirementById(id);
|
|
550
|
+
|
|
551
|
+
// If requirement doesn't exist in DB, seed the entire requirements table
|
|
552
|
+
// from REQUIREMENTS.md first (#3346). This handles the standard workflow
|
|
553
|
+
// where requirements are authored in markdown during discussion but never
|
|
554
|
+
// imported into the database — making gsd_requirement_update always fail
|
|
555
|
+
// with "not_found" at milestone completion.
|
|
556
|
+
if (!existing) {
|
|
557
|
+
const reqFilePath = resolveGsdRootFile(basePath, 'REQUIREMENTS');
|
|
558
|
+
try {
|
|
559
|
+
const content = readFileSync(reqFilePath, 'utf-8');
|
|
560
|
+
const { parseRequirementsSections } = await import('./md-importer.js');
|
|
561
|
+
const parsed = parseRequirementsSections(content);
|
|
562
|
+
if (parsed.length > 0) {
|
|
563
|
+
logWarning('manifest', `Seeding ${parsed.length} requirements from REQUIREMENTS.md into DB (first update triggers import)`, { fn: 'updateRequirementInDb' });
|
|
564
|
+
for (const req of parsed) {
|
|
565
|
+
// Only seed if not already in DB (avoid overwriting concurrent inserts)
|
|
566
|
+
if (!db.getRequirementById(req.id)) {
|
|
567
|
+
db.upsertRequirement(req);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
// Re-check after seeding
|
|
571
|
+
existing = db.getRequirementById(id);
|
|
572
|
+
}
|
|
573
|
+
} catch {
|
|
574
|
+
// REQUIREMENTS.md missing or unparseable — fall through to skeleton
|
|
575
|
+
}
|
|
576
|
+
}
|
|
500
577
|
|
|
501
|
-
// If requirement doesn't exist in DB, create a skeleton and merge updates.
|
|
502
|
-
// This handles the case where requirements were written to REQUIREMENTS.md
|
|
503
|
-
// but never imported into the database (see #2919).
|
|
504
578
|
const base: Requirement = existing ?? {
|
|
505
579
|
id,
|
|
506
580
|
class: '',
|
|
@@ -38,7 +38,7 @@ import { ensurePreferencesFile, serializePreferencesToFrontmatter } from "./comm
|
|
|
38
38
|
|
|
39
39
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
40
40
|
|
|
41
|
-
interface ForensicAnomaly {
|
|
41
|
+
export interface ForensicAnomaly {
|
|
42
42
|
type: "stuck-loop" | "cost-spike" | "timeout" | "missing-artifact" | "crash" | "doctor-issue" | "error-trace" | "journal-stuck" | "journal-guard-block" | "journal-rapid-iterations" | "journal-worktree-failure";
|
|
43
43
|
severity: "info" | "warning" | "error";
|
|
44
44
|
unitType?: string;
|
|
@@ -640,13 +640,29 @@ function getDbCompletionCounts(): DbCompletionCounts | null {
|
|
|
640
640
|
|
|
641
641
|
// ─── Anomaly Detectors ───────────────────────────────────────────────────────
|
|
642
642
|
|
|
643
|
-
|
|
644
|
-
|
|
643
|
+
/**
|
|
644
|
+
* Detect units that were dispatched multiple times (stuck in a loop).
|
|
645
|
+
*
|
|
646
|
+
* Counts distinct dispatches by grouping on (type, id, startedAt) first to
|
|
647
|
+
* collapse idle-watchdog duplicate snapshots (#1943), then counts unique
|
|
648
|
+
* startedAt values per type/id to determine actual dispatch count.
|
|
649
|
+
*
|
|
650
|
+
* Exported for testability.
|
|
651
|
+
*/
|
|
652
|
+
export function detectStuckLoops(units: UnitMetrics[], anomalies: ForensicAnomaly[]): void {
|
|
653
|
+
// First, collect unique startedAt values per type/id key
|
|
654
|
+
const dispatchMap = new Map<string, Set<number>>();
|
|
645
655
|
for (const u of units) {
|
|
646
656
|
const key = `${u.type}/${u.id}`;
|
|
647
|
-
|
|
657
|
+
let starts = dispatchMap.get(key);
|
|
658
|
+
if (!starts) {
|
|
659
|
+
starts = new Set();
|
|
660
|
+
dispatchMap.set(key, starts);
|
|
661
|
+
}
|
|
662
|
+
starts.add(u.startedAt);
|
|
648
663
|
}
|
|
649
|
-
for (const [key,
|
|
664
|
+
for (const [key, starts] of dispatchMap) {
|
|
665
|
+
const count = starts.size;
|
|
650
666
|
if (count > 1) {
|
|
651
667
|
const [unitType, ...idParts] = key.split("/");
|
|
652
668
|
anomalies.push({
|