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
|
@@ -74,7 +74,7 @@ function parseTableSlices(section) {
|
|
|
74
74
|
// Determine completion status from any cell containing [x], "Done", or "Complete"
|
|
75
75
|
const fullRow = line.toLowerCase();
|
|
76
76
|
const done = /\[x\]/i.test(line) ||
|
|
77
|
-
/[
|
|
77
|
+
/[✅☑✓✔]/.test(line) ||
|
|
78
78
|
/\bdone\b/.test(fullRow) ||
|
|
79
79
|
/\bcomplete(?:d)?\b/.test(fullRow);
|
|
80
80
|
// Extract risk from any cell containing risk keywords
|
|
@@ -214,10 +214,10 @@ function parseProseSliceHeaders(content) {
|
|
|
214
214
|
// numeric prefixes (e.g., "1.", "(1)"), bracketed IDs (e.g., "[S01]"),
|
|
215
215
|
// optional checkmark completion marker, and optional leading indentation.
|
|
216
216
|
// Separator after the ID is flexible: colon, dash, em/en dash, dot, or just whitespace.
|
|
217
|
-
const headerPattern = /^\s*#{1,4}\s+\*{0,2}(
|
|
217
|
+
const headerPattern = /^\s*#{1,4}\s+\*{0,2}(?:[\u2713\u2705]\s+)?(?:\d+[.)]\s+)?(?:\(\d+\)\s+)?(?:Slice\s+)?\[?(S\d+)\]?\*{0,2}[:\s.\u2014\u2013-]*\s*(.+)/gm;
|
|
218
218
|
let match;
|
|
219
219
|
// Check for checkmark before the slice ID (e.g., "## checkmark S01: Title")
|
|
220
|
-
const prefixCheckPattern = /^\s*#{1,4}\s+\*{0,2}\u2713\s+/;
|
|
220
|
+
const prefixCheckPattern = /^\s*#{1,4}\s+\*{0,2}[\u2713\u2705]\s+/;
|
|
221
221
|
while ((match = headerPattern.exec(content)) !== null) {
|
|
222
222
|
const id = match[1];
|
|
223
223
|
let title = match[2].trim().replace(/\*{1,2}$/g, "").trim(); // strip trailing bold markers
|
|
@@ -229,9 +229,13 @@ function parseProseSliceHeaders(content) {
|
|
|
229
229
|
// 3. (Complete) suffix: "## S01: Title (Complete)"
|
|
230
230
|
const line = match[0];
|
|
231
231
|
let done = prefixCheckPattern.test(line);
|
|
232
|
-
if (!done &&
|
|
232
|
+
if (!done && /^[\u2713\u2705]/.test(title)) {
|
|
233
233
|
done = true;
|
|
234
|
-
title = title.replace(
|
|
234
|
+
title = title.replace(/^[\u2713\u2705]\s*/, "");
|
|
235
|
+
}
|
|
236
|
+
if (!done && /[\u2705]\s*$/.test(title)) {
|
|
237
|
+
done = true;
|
|
238
|
+
title = title.replace(/\s*[\u2705]\s*$/, "");
|
|
235
239
|
}
|
|
236
240
|
if (!done && /\(Complete\)\s*$/i.test(title)) {
|
|
237
241
|
done = true;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight content validator for auto-mode safety harness.
|
|
3
|
+
* Validates that high-value unit outputs contain minimum expected content.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
+
import { logWarning } from "../workflow-logger.js";
|
|
9
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Validate content quality for a completed unit.
|
|
12
|
+
* Returns an array of violations. Empty array = content looks acceptable.
|
|
13
|
+
*
|
|
14
|
+
* @param unitType - The type of unit that completed (e.g. "plan-slice")
|
|
15
|
+
* @param artifactPath - Absolute path to the primary artifact file
|
|
16
|
+
*/
|
|
17
|
+
export function validateContent(unitType, artifactPath) {
|
|
18
|
+
if (!artifactPath || !existsSync(artifactPath))
|
|
19
|
+
return [];
|
|
20
|
+
const validator = VALIDATORS[unitType];
|
|
21
|
+
if (!validator)
|
|
22
|
+
return [];
|
|
23
|
+
try {
|
|
24
|
+
const content = readFileSync(artifactPath, "utf-8");
|
|
25
|
+
return validator(content);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
logWarning("safety", `content validation read failed: ${e.message}`);
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const VALIDATORS = {
|
|
33
|
+
"plan-slice": validatePlanSlice,
|
|
34
|
+
"plan-milestone": validatePlanMilestone,
|
|
35
|
+
};
|
|
36
|
+
function validatePlanSlice(content) {
|
|
37
|
+
const violations = [];
|
|
38
|
+
// Must have at least 2 task entries (checkbox pattern)
|
|
39
|
+
const taskCount = (content.match(/- \[[ x]\] \*\*T\d+/g) || []).length;
|
|
40
|
+
if (taskCount < 2) {
|
|
41
|
+
violations.push({
|
|
42
|
+
severity: "warning",
|
|
43
|
+
reason: `Slice plan has only ${taskCount} task(s) — expected at least 2`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Should have a Files Likely Touched section
|
|
47
|
+
if (!content.includes("## Files Likely Touched") && !content.includes("## Files")) {
|
|
48
|
+
violations.push({
|
|
49
|
+
severity: "warning",
|
|
50
|
+
reason: "Slice plan missing 'Files Likely Touched' section",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// Should have a verification section
|
|
54
|
+
if (!content.includes("Verify") && !content.includes("verify")) {
|
|
55
|
+
violations.push({
|
|
56
|
+
severity: "warning",
|
|
57
|
+
reason: "Slice plan has no verification instructions",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return violations;
|
|
61
|
+
}
|
|
62
|
+
function validatePlanMilestone(content) {
|
|
63
|
+
const violations = [];
|
|
64
|
+
// Must have at least 1 slice entry
|
|
65
|
+
const sliceCount = (content.match(/##\s+S\d+/g) || []).length;
|
|
66
|
+
if (sliceCount < 1) {
|
|
67
|
+
violations.push({
|
|
68
|
+
severity: "warning",
|
|
69
|
+
reason: `Milestone roadmap has ${sliceCount} slice(s) — expected at least 1`,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return violations;
|
|
73
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destructive command classifier for auto-mode safety harness.
|
|
3
|
+
* Classifies bash commands and warns on potentially destructive operations.
|
|
4
|
+
* Does NOT block — only classifies for logging/notification.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
7
|
+
*/
|
|
8
|
+
const DESTRUCTIVE_PATTERNS = [
|
|
9
|
+
{ pattern: /\brm\s+(-[^\s]*[rfRF][^\s]*\s+|.*\s+-[^\s]*[rfRF])/, label: "recursive delete" },
|
|
10
|
+
{ pattern: /\bgit\s+push\s+.*--force/, label: "force push" },
|
|
11
|
+
{ pattern: /\bgit\s+push\s+-f\b/, label: "force push" },
|
|
12
|
+
{ pattern: /\bgit\s+reset\s+--hard/, label: "hard reset" },
|
|
13
|
+
{ pattern: /\bgit\s+clean\s+-[^\s]*[fdxFDX]/, label: "git clean" },
|
|
14
|
+
{ pattern: /\bgit\s+checkout\s+--\s+\./, label: "discard all changes" },
|
|
15
|
+
{ pattern: /\bdrop\s+(database|table|index)\b/i, label: "SQL drop" },
|
|
16
|
+
{ pattern: /\btruncate\s+table\b/i, label: "SQL truncate" },
|
|
17
|
+
{ pattern: /\bchmod\s+777\b/, label: "world-writable permissions" },
|
|
18
|
+
{ pattern: /\bcurl\s.*\|\s*(bash|sh|zsh)\b/, label: "pipe to shell" },
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Classify a bash command for destructive operations.
|
|
22
|
+
* Returns the list of matched destructive pattern labels.
|
|
23
|
+
*/
|
|
24
|
+
export function classifyCommand(command) {
|
|
25
|
+
const labels = [];
|
|
26
|
+
for (const { pattern, label } of DESTRUCTIVE_PATTERNS) {
|
|
27
|
+
if (pattern.test(command)) {
|
|
28
|
+
// Deduplicate labels (e.g., two force-push patterns)
|
|
29
|
+
if (!labels.includes(label))
|
|
30
|
+
labels.push(label);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { destructive: labels.length > 0, labels };
|
|
34
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real-time tool call evidence collector for auto-mode safety harness.
|
|
3
|
+
* Tracks every bash command, file write, and file edit during a unit execution.
|
|
4
|
+
* Evidence is compared against LLM completion claims in evidence-cross-ref.ts.
|
|
5
|
+
*
|
|
6
|
+
* Follows the same module-level Map pattern as auto-tool-tracking.ts.
|
|
7
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
8
|
+
*/
|
|
9
|
+
// ─── Module State ───────────────────────────────────────────────────────────
|
|
10
|
+
let unitEvidence = [];
|
|
11
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
12
|
+
/** Reset all evidence for a new unit. Call at unit start. */
|
|
13
|
+
export function resetEvidence() {
|
|
14
|
+
unitEvidence = [];
|
|
15
|
+
}
|
|
16
|
+
/** Get a read-only view of all evidence collected for the current unit. */
|
|
17
|
+
export function getEvidence() {
|
|
18
|
+
return unitEvidence;
|
|
19
|
+
}
|
|
20
|
+
/** Get only bash evidence entries. */
|
|
21
|
+
export function getBashEvidence() {
|
|
22
|
+
return unitEvidence.filter((e) => e.kind === "bash");
|
|
23
|
+
}
|
|
24
|
+
/** Get all file paths touched (write + edit). */
|
|
25
|
+
export function getFilePaths() {
|
|
26
|
+
return unitEvidence
|
|
27
|
+
.filter((e) => e.kind === "write" || e.kind === "edit")
|
|
28
|
+
.map(e => e.path);
|
|
29
|
+
}
|
|
30
|
+
// ─── Recording (called from register-hooks.ts) ─────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* Record a tool call at dispatch time (before execution).
|
|
33
|
+
* Exit codes and output are filled in by recordToolResult after execution.
|
|
34
|
+
*/
|
|
35
|
+
export function recordToolCall(toolName, input) {
|
|
36
|
+
if (toolName === "bash" || toolName === "Bash") {
|
|
37
|
+
unitEvidence.push({
|
|
38
|
+
kind: "bash",
|
|
39
|
+
toolCallId: "",
|
|
40
|
+
command: String(input.command ?? ""),
|
|
41
|
+
exitCode: -1,
|
|
42
|
+
outputSnippet: "",
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else if (toolName === "write" || toolName === "Write") {
|
|
47
|
+
unitEvidence.push({
|
|
48
|
+
kind: "write",
|
|
49
|
+
toolCallId: "",
|
|
50
|
+
path: String(input.file_path ?? input.path ?? ""),
|
|
51
|
+
timestamp: Date.now(),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else if (toolName === "edit" || toolName === "Edit") {
|
|
55
|
+
unitEvidence.push({
|
|
56
|
+
kind: "edit",
|
|
57
|
+
toolCallId: "",
|
|
58
|
+
path: String(input.file_path ?? input.path ?? ""),
|
|
59
|
+
timestamp: Date.now(),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Record a tool execution result. Matches the most recent unresolved entry
|
|
65
|
+
* of the same kind and fills in the toolCallId, exit code, and output.
|
|
66
|
+
*/
|
|
67
|
+
export function recordToolResult(toolCallId, toolName, result, isError) {
|
|
68
|
+
const normalizedName = toolName.toLowerCase();
|
|
69
|
+
if (normalizedName === "bash") {
|
|
70
|
+
const entry = findLastUnresolved("bash");
|
|
71
|
+
if (entry) {
|
|
72
|
+
entry.toolCallId = toolCallId;
|
|
73
|
+
const text = extractResultText(result);
|
|
74
|
+
entry.outputSnippet = text.slice(0, 500);
|
|
75
|
+
const exitMatch = text.match(/Command exited with code (\d+)/);
|
|
76
|
+
entry.exitCode = exitMatch ? Number(exitMatch[1]) : (isError ? 1 : 0);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (normalizedName === "write" || normalizedName === "edit") {
|
|
80
|
+
const entry = findLastUnresolved(normalizedName);
|
|
81
|
+
if (entry) {
|
|
82
|
+
entry.toolCallId = toolCallId;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ─── Internals ──────────────────────────────────────────────────────────────
|
|
87
|
+
function findLastUnresolved(kind) {
|
|
88
|
+
for (let i = unitEvidence.length - 1; i >= 0; i--) {
|
|
89
|
+
if (unitEvidence[i].kind === kind && unitEvidence[i].toolCallId === "") {
|
|
90
|
+
return unitEvidence[i];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
function extractResultText(result) {
|
|
96
|
+
if (typeof result === "string")
|
|
97
|
+
return result;
|
|
98
|
+
if (result && typeof result === "object") {
|
|
99
|
+
const r = result;
|
|
100
|
+
if (Array.isArray(r.content)) {
|
|
101
|
+
const textBlock = r.content.find((c) => typeof c === "object" && c !== null && c.type === "text");
|
|
102
|
+
if (textBlock && typeof textBlock.text === "string")
|
|
103
|
+
return textBlock.text;
|
|
104
|
+
}
|
|
105
|
+
if (typeof r.text === "string")
|
|
106
|
+
return r.text;
|
|
107
|
+
}
|
|
108
|
+
return String(result ?? "");
|
|
109
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence cross-reference for auto-mode safety harness.
|
|
3
|
+
* Compares the LLM's claimed verification evidence (command + exitCode)
|
|
4
|
+
* against actual bash tool calls recorded by the evidence collector.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
7
|
+
*/
|
|
8
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Cross-reference claimed verification evidence against actual bash tool calls.
|
|
11
|
+
*
|
|
12
|
+
* Returns an array of mismatches. Empty array = all claims verified.
|
|
13
|
+
* Skips entries that were coerced from strings (already flagged by db-tools.ts).
|
|
14
|
+
*/
|
|
15
|
+
export function crossReferenceEvidence(claimedEvidence, actualEvidence) {
|
|
16
|
+
const bashCalls = actualEvidence.filter((e) => e.kind === "bash");
|
|
17
|
+
const mismatches = [];
|
|
18
|
+
for (const claimed of claimedEvidence) {
|
|
19
|
+
// Skip coerced entries — they're already flagged with exitCode: -1
|
|
20
|
+
// and verdict: "unknown (coerced from string)" by db-tools.ts
|
|
21
|
+
if (claimed.verdict?.includes("coerced from string"))
|
|
22
|
+
continue;
|
|
23
|
+
if (claimed.exitCode === -1)
|
|
24
|
+
continue;
|
|
25
|
+
// Skip entries with empty or generic commands
|
|
26
|
+
if (!claimed.command || claimed.command.length < 3)
|
|
27
|
+
continue;
|
|
28
|
+
// Find matching bash call by command substring match
|
|
29
|
+
const match = findBestMatch(claimed.command, bashCalls);
|
|
30
|
+
if (!match) {
|
|
31
|
+
mismatches.push({
|
|
32
|
+
severity: "warning",
|
|
33
|
+
claimed,
|
|
34
|
+
actual: null,
|
|
35
|
+
reason: `No bash tool call found matching "${claimed.command.slice(0, 80)}"`,
|
|
36
|
+
});
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// Exit code mismatch: LLM claims success but actual command failed
|
|
40
|
+
if (claimed.exitCode === 0 && match.exitCode !== 0) {
|
|
41
|
+
mismatches.push({
|
|
42
|
+
severity: "error",
|
|
43
|
+
claimed,
|
|
44
|
+
actual: match,
|
|
45
|
+
reason: `Claimed exitCode=0 but actual exitCode=${match.exitCode}`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return mismatches;
|
|
50
|
+
}
|
|
51
|
+
// ─── Internals ──────────────────────────────────────────────────────────────
|
|
52
|
+
/**
|
|
53
|
+
* Find the best matching bash evidence entry for a claimed command.
|
|
54
|
+
* Uses substring matching — the claimed command may be a shortened version
|
|
55
|
+
* of the actual command, or vice versa.
|
|
56
|
+
*/
|
|
57
|
+
function findBestMatch(claimedCommand, bashCalls) {
|
|
58
|
+
const normalized = claimedCommand.trim();
|
|
59
|
+
// Exact match first
|
|
60
|
+
const exact = bashCalls.find(b => b.command.trim() === normalized);
|
|
61
|
+
if (exact)
|
|
62
|
+
return exact;
|
|
63
|
+
// Substring match: claimed is contained in actual or actual in claimed
|
|
64
|
+
const substring = bashCalls.find(b => b.command.includes(normalized) || normalized.includes(b.command));
|
|
65
|
+
if (substring)
|
|
66
|
+
return substring;
|
|
67
|
+
// Token match: split on whitespace and check significant overlap
|
|
68
|
+
const claimedTokens = normalized.split(/\s+/).filter(t => t.length > 2);
|
|
69
|
+
if (claimedTokens.length === 0)
|
|
70
|
+
return null;
|
|
71
|
+
let bestMatch = null;
|
|
72
|
+
let bestScore = 0;
|
|
73
|
+
for (const call of bashCalls) {
|
|
74
|
+
const callTokens = new Set(call.command.split(/\s+/));
|
|
75
|
+
const matchCount = claimedTokens.filter(t => callTokens.has(t)).length;
|
|
76
|
+
const score = matchCount / claimedTokens.length;
|
|
77
|
+
if (score > bestScore && score >= 0.5) {
|
|
78
|
+
bestScore = score;
|
|
79
|
+
bestMatch = call;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return bestMatch;
|
|
83
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-unit file change validator for auto-mode safety harness.
|
|
3
|
+
* Compares actual git diff against the task plan's expected output files.
|
|
4
|
+
*
|
|
5
|
+
* Uses tasks.expected_output (DB column, populated from per-task ## Expected Output)
|
|
6
|
+
* and tasks.files (from slice PLAN.md - Files: subline) as the expected set.
|
|
7
|
+
* Compares against git diff HEAD~1 --name-only after auto-commit.
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
10
|
+
*/
|
|
11
|
+
import { execFileSync } from "node:child_process";
|
|
12
|
+
import { logWarning } from "../workflow-logger.js";
|
|
13
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* Validate file changes after auto-commit for an execute-task unit.
|
|
16
|
+
* Returns null if task data is unavailable or DB is not loaded.
|
|
17
|
+
*
|
|
18
|
+
* @param basePath - Working directory (worktree or project root)
|
|
19
|
+
* @param expectedOutput - JSON array from tasks.expected_output DB column
|
|
20
|
+
* @param plannedFiles - JSON array from tasks.files DB column
|
|
21
|
+
*/
|
|
22
|
+
export function validateFileChanges(basePath, expectedOutput, plannedFiles) {
|
|
23
|
+
const allExpected = new Set([...expectedOutput, ...plannedFiles]);
|
|
24
|
+
// If no expected files were planned, skip validation
|
|
25
|
+
if (allExpected.size === 0)
|
|
26
|
+
return null;
|
|
27
|
+
// Get actual changed files from last commit
|
|
28
|
+
const actualFiles = getChangedFilesFromLastCommit(basePath);
|
|
29
|
+
if (!actualFiles)
|
|
30
|
+
return null;
|
|
31
|
+
// Filter out .gsd/ internal files — only validate project source files
|
|
32
|
+
const projectFiles = actualFiles.filter(f => !f.startsWith(".gsd/") && !f.startsWith(".gsd\\"));
|
|
33
|
+
// Normalize expected paths (strip leading ./ or /)
|
|
34
|
+
const normalizedExpected = new Set([...allExpected].map(f => f.replace(/^\.\//, "").replace(/^\//, "")));
|
|
35
|
+
// Compute symmetric difference
|
|
36
|
+
const unexpectedFiles = projectFiles.filter(f => !normalizedExpected.has(f));
|
|
37
|
+
const missingFiles = [...normalizedExpected].filter(f => !projectFiles.includes(f));
|
|
38
|
+
const violations = [];
|
|
39
|
+
for (const f of unexpectedFiles) {
|
|
40
|
+
violations.push({
|
|
41
|
+
severity: "warning",
|
|
42
|
+
file: f,
|
|
43
|
+
reason: "Modified but not in task plan's expected output",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
for (const f of missingFiles) {
|
|
47
|
+
violations.push({
|
|
48
|
+
severity: "info",
|
|
49
|
+
file: f,
|
|
50
|
+
reason: "Listed in task plan but not modified",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
expectedFiles: [...normalizedExpected],
|
|
55
|
+
actualFiles: projectFiles,
|
|
56
|
+
unexpectedFiles,
|
|
57
|
+
missingFiles,
|
|
58
|
+
violations,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// ─── Internals ──────────────────────────────────────────────────────────────
|
|
62
|
+
function getChangedFilesFromLastCommit(basePath) {
|
|
63
|
+
try {
|
|
64
|
+
const result = execFileSync("git", ["diff", "--name-only", "HEAD~1", "HEAD"], { cwd: basePath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
65
|
+
return result ? result.split("\n").filter(Boolean) : [];
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
logWarning("safety", `git diff failed in file-change-validator: ${e.message}`);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-unit git checkpoint and rollback for auto-mode safety harness.
|
|
3
|
+
* Uses the existing refs/gsd/ namespace (already pruned by doctor).
|
|
4
|
+
*
|
|
5
|
+
* Creates a lightweight ref at HEAD before unit execution. On failure,
|
|
6
|
+
* the ref can be used to rollback the branch to the pre-unit state.
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import { logWarning } from "../workflow-logger.js";
|
|
12
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
13
|
+
const CHECKPOINT_PREFIX = "refs/gsd/checkpoints/";
|
|
14
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Create a checkpoint ref at the current HEAD for the given unit.
|
|
17
|
+
* Returns the SHA of HEAD, or null if the operation fails.
|
|
18
|
+
*/
|
|
19
|
+
export function createCheckpoint(basePath, unitId) {
|
|
20
|
+
try {
|
|
21
|
+
const sha = execFileSync("git", ["rev-parse", "HEAD"], {
|
|
22
|
+
cwd: basePath,
|
|
23
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
24
|
+
encoding: "utf-8",
|
|
25
|
+
}).trim();
|
|
26
|
+
if (!sha || sha.length < 7)
|
|
27
|
+
return null;
|
|
28
|
+
// Sanitize unitId for use in ref path (replace / with -)
|
|
29
|
+
const safeUnitId = unitId.replace(/\//g, "-");
|
|
30
|
+
execFileSync("git", ["update-ref", `${CHECKPOINT_PREFIX}${safeUnitId}`, sha], {
|
|
31
|
+
cwd: basePath,
|
|
32
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
33
|
+
});
|
|
34
|
+
return sha;
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
logWarning("safety", `checkpoint creation failed: ${e.message}`);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Rollback the current branch to a checkpoint SHA.
|
|
43
|
+
* Returns true on success, false on failure.
|
|
44
|
+
*
|
|
45
|
+
* WARNING: This is a destructive operation — it discards all changes
|
|
46
|
+
* since the checkpoint. Only call when the user has opted in via
|
|
47
|
+
* safety_harness.auto_rollback or an explicit manual trigger.
|
|
48
|
+
*/
|
|
49
|
+
export function rollbackToCheckpoint(basePath, unitId, sha) {
|
|
50
|
+
try {
|
|
51
|
+
// Get current branch name
|
|
52
|
+
const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
53
|
+
cwd: basePath,
|
|
54
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
55
|
+
encoding: "utf-8",
|
|
56
|
+
}).trim();
|
|
57
|
+
if (!branch || branch === "HEAD") {
|
|
58
|
+
logWarning("safety", "rollback: detached HEAD state, cannot rollback");
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
// Reset branch pointer and working tree to checkpoint SHA in one step.
|
|
62
|
+
// Using `git reset --hard <sha>` works on the currently checked-out branch
|
|
63
|
+
// (unlike `git branch -f` which is rejected for checked-out branches).
|
|
64
|
+
execFileSync("git", ["reset", "--hard", sha], {
|
|
65
|
+
cwd: basePath,
|
|
66
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
67
|
+
});
|
|
68
|
+
// Cleanup checkpoint ref
|
|
69
|
+
cleanupCheckpoint(basePath, unitId);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
logWarning("safety", `rollback failed: ${e.message}`);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Remove a checkpoint ref after successful unit completion.
|
|
79
|
+
*/
|
|
80
|
+
export function cleanupCheckpoint(basePath, unitId) {
|
|
81
|
+
try {
|
|
82
|
+
const safeUnitId = unitId.replace(/\//g, "-");
|
|
83
|
+
execFileSync("git", ["update-ref", "-d", `${CHECKPOINT_PREFIX}${safeUnitId}`], {
|
|
84
|
+
cwd: basePath,
|
|
85
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Non-fatal — ref may already have been cleaned up
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safety Harness — central module for LLM damage control during auto-mode.
|
|
3
|
+
* Provides types, preference resolution, and orchestration for all safety components.
|
|
4
|
+
*
|
|
5
|
+
* Components:
|
|
6
|
+
* - evidence-collector.ts: Real-time tool call tracking
|
|
7
|
+
* - destructive-guard.ts: Bash command classification
|
|
8
|
+
* - file-change-validator.ts: Post-unit git diff vs plan
|
|
9
|
+
* - evidence-cross-ref.ts: Claimed vs actual verification evidence
|
|
10
|
+
* - git-checkpoint.ts: Pre-unit checkpoints + rollback
|
|
11
|
+
* - content-validator.ts: Output quality validation
|
|
12
|
+
*
|
|
13
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
14
|
+
*/
|
|
15
|
+
// ─── Defaults ───────────────────────────────────────────────────────────────
|
|
16
|
+
const DEFAULTS = {
|
|
17
|
+
enabled: true,
|
|
18
|
+
evidence_collection: true,
|
|
19
|
+
file_change_validation: true,
|
|
20
|
+
evidence_cross_reference: true,
|
|
21
|
+
destructive_command_warnings: true,
|
|
22
|
+
content_validation: true,
|
|
23
|
+
checkpoints: true,
|
|
24
|
+
auto_rollback: false,
|
|
25
|
+
timeout_scale_cap: 6,
|
|
26
|
+
};
|
|
27
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
28
|
+
/**
|
|
29
|
+
* Resolve safety harness configuration from raw preferences.
|
|
30
|
+
* Missing fields fall back to defaults.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveSafetyHarnessConfig(raw) {
|
|
33
|
+
if (!raw)
|
|
34
|
+
return { ...DEFAULTS };
|
|
35
|
+
return {
|
|
36
|
+
enabled: typeof raw.enabled === "boolean" ? raw.enabled : DEFAULTS.enabled,
|
|
37
|
+
evidence_collection: typeof raw.evidence_collection === "boolean" ? raw.evidence_collection : DEFAULTS.evidence_collection,
|
|
38
|
+
file_change_validation: typeof raw.file_change_validation === "boolean" ? raw.file_change_validation : DEFAULTS.file_change_validation,
|
|
39
|
+
evidence_cross_reference: typeof raw.evidence_cross_reference === "boolean" ? raw.evidence_cross_reference : DEFAULTS.evidence_cross_reference,
|
|
40
|
+
destructive_command_warnings: typeof raw.destructive_command_warnings === "boolean" ? raw.destructive_command_warnings : DEFAULTS.destructive_command_warnings,
|
|
41
|
+
content_validation: typeof raw.content_validation === "boolean" ? raw.content_validation : DEFAULTS.content_validation,
|
|
42
|
+
checkpoints: typeof raw.checkpoints === "boolean" ? raw.checkpoints : DEFAULTS.checkpoints,
|
|
43
|
+
auto_rollback: typeof raw.auto_rollback === "boolean" ? raw.auto_rollback : DEFAULTS.auto_rollback,
|
|
44
|
+
timeout_scale_cap: typeof raw.timeout_scale_cap === "number" ? raw.timeout_scale_cap : DEFAULTS.timeout_scale_cap,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if the safety harness is enabled.
|
|
49
|
+
* Used as a fast gate at hook registration and phase integration points.
|
|
50
|
+
*/
|
|
51
|
+
export function isHarnessEnabled(raw) {
|
|
52
|
+
if (!raw)
|
|
53
|
+
return DEFAULTS.enabled;
|
|
54
|
+
if (typeof raw.enabled === "boolean")
|
|
55
|
+
return raw.enabled;
|
|
56
|
+
return DEFAULTS.enabled;
|
|
57
|
+
}
|
|
58
|
+
// ─── Re-exports ─────────────────────────────────────────────────────────────
|
|
59
|
+
export { resetEvidence, getEvidence, getBashEvidence, getFilePaths, recordToolCall, recordToolResult, } from "./evidence-collector.js";
|
|
60
|
+
export { classifyCommand } from "./destructive-guard.js";
|
|
61
|
+
export { validateFileChanges } from "./file-change-validator.js";
|
|
62
|
+
export { crossReferenceEvidence } from "./evidence-cross-ref.js";
|
|
63
|
+
export { createCheckpoint, rollbackToCheckpoint, cleanupCheckpoint } from "./git-checkpoint.js";
|
|
64
|
+
export { validateContent } from "./content-validator.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD Slice Parallel Conflict Detection — File overlap analysis between slices.
|
|
3
|
+
*
|
|
4
|
+
* Reads PLAN.md for each slice and extracts file paths mentioned in task
|
|
5
|
+
* descriptions. If two slices share more than 5 file paths, they are considered
|
|
6
|
+
* conflicting and should not run in parallel.
|
|
7
|
+
*
|
|
8
|
+
* Conservative by default: missing PLAN = block parallel execution.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
// ─── File Path Extraction ─────────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Extract file paths from a PLAN.md content string.
|
|
15
|
+
* Matches common patterns like `src/...`, `lib/...`, paths with extensions.
|
|
16
|
+
*/
|
|
17
|
+
function extractFilePaths(content) {
|
|
18
|
+
const paths = new Set();
|
|
19
|
+
// Match file-like patterns: word/word paths with extensions, or src/lib/etc prefixed paths
|
|
20
|
+
const patterns = [
|
|
21
|
+
// Paths like src/foo/bar.ts, lib/utils.js, etc.
|
|
22
|
+
/(?:src|lib|test|tests|app|pkg|cmd|internal|components|pages|api|utils|config|scripts|dist|build)\/[\w./-]+\.\w+/g,
|
|
23
|
+
// Generic path with at least one slash and extension
|
|
24
|
+
/(?<!\w)[\w-]+\/[\w./-]+\.\w{1,5}(?!\w)/g,
|
|
25
|
+
];
|
|
26
|
+
for (const pattern of patterns) {
|
|
27
|
+
const matches = content.matchAll(pattern);
|
|
28
|
+
for (const match of matches) {
|
|
29
|
+
paths.add(match[0]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return paths;
|
|
33
|
+
}
|
|
34
|
+
// ─── Conflict Detection ──────────────────────────────────────────────────────
|
|
35
|
+
/**
|
|
36
|
+
* Check if two slices have file conflicts that would block parallel execution.
|
|
37
|
+
*
|
|
38
|
+
* @param basePath Project root path.
|
|
39
|
+
* @param mid Milestone ID.
|
|
40
|
+
* @param sliceA First slice ID.
|
|
41
|
+
* @param sliceB Second slice ID.
|
|
42
|
+
* @returns true if parallel is unsafe (>5 shared files or missing plan).
|
|
43
|
+
*/
|
|
44
|
+
export function hasFileConflict(basePath, mid, sliceA, sliceB) {
|
|
45
|
+
const planPathA = join(basePath, ".gsd", "milestones", mid, sliceA, "PLAN.md");
|
|
46
|
+
const planPathB = join(basePath, ".gsd", "milestones", mid, sliceB, "PLAN.md");
|
|
47
|
+
// Conservative: missing PLAN = block
|
|
48
|
+
if (!existsSync(planPathA) || !existsSync(planPathB)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
const contentA = readFileSync(planPathA, "utf-8");
|
|
52
|
+
const contentB = readFileSync(planPathB, "utf-8");
|
|
53
|
+
const filesA = extractFilePaths(contentA);
|
|
54
|
+
const filesB = extractFilePaths(contentB);
|
|
55
|
+
// If either has no files extracted, no conflict detectable → allow
|
|
56
|
+
if (filesA.size === 0 || filesB.size === 0) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// Count shared files
|
|
60
|
+
let sharedCount = 0;
|
|
61
|
+
for (const file of filesA) {
|
|
62
|
+
if (filesB.has(file)) {
|
|
63
|
+
sharedCount++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return sharedCount > 5;
|
|
67
|
+
}
|