gsd-pi 2.50.0 → 2.51.0-dev.7d435fe
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 +6 -4
- package/dist/cli.js +26 -0
- package/dist/headless-events.d.ts +18 -0
- package/dist/headless-events.js +36 -0
- package/dist/headless-types.d.ts +28 -0
- package/dist/headless-types.js +7 -0
- package/dist/headless.d.ts +8 -3
- package/dist/headless.js +47 -16
- package/dist/help-text.js +16 -5
- package/dist/loader.js +4 -0
- package/dist/onboarding.js +5 -4
- package/dist/remote-questions-config.js +1 -1
- package/dist/resource-loader.d.ts +4 -1
- package/dist/resource-loader.js +138 -3
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +32 -18
- package/dist/resources/extensions/bg-shell/interaction.js +3 -1
- package/dist/resources/extensions/bg-shell/process-manager.js +4 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +5 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
- package/dist/resources/extensions/gsd/auto/phases.js +16 -1
- package/dist/resources/extensions/gsd/auto/session.js +5 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +22 -3
- package/dist/resources/extensions/gsd/auto-dispatch.js +98 -53
- package/dist/resources/extensions/gsd/auto-observability.js +54 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +37 -76
- package/dist/resources/extensions/gsd/auto-prompts.js +57 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +21 -25
- package/dist/resources/extensions/gsd/auto-start.js +2 -0
- package/dist/resources/extensions/gsd/auto-timers.js +24 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
- package/dist/resources/extensions/gsd/auto-utils.js +20 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
- package/dist/resources/extensions/gsd/auto.js +19 -7
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +95 -69
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -1
- package/dist/resources/extensions/gsd/claude-import.js +60 -9
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
- package/dist/resources/extensions/gsd/commands-config.js +10 -5
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
- package/dist/resources/extensions/gsd/crash-recovery.js +6 -2
- package/dist/resources/extensions/gsd/custom-execution-policy.js +3 -2
- package/dist/resources/extensions/gsd/custom-verification.js +3 -1
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -2
- package/dist/resources/extensions/gsd/dashboard-overlay.js +4 -0
- package/dist/resources/extensions/gsd/detection.js +595 -9
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +18 -3
- package/dist/resources/extensions/gsd/error-classifier.js +105 -0
- package/dist/resources/extensions/gsd/files.js +5 -1
- package/dist/resources/extensions/gsd/gitignore.js +7 -7
- package/dist/resources/extensions/gsd/gsd-db.js +298 -45
- package/dist/resources/extensions/gsd/guided-flow.js +10 -0
- package/dist/resources/extensions/gsd/init-wizard.js +11 -3
- package/dist/resources/extensions/gsd/key-manager.js +7 -16
- package/dist/resources/extensions/gsd/memory-store.js +28 -13
- package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
- package/dist/resources/extensions/gsd/model-router.js +25 -0
- package/dist/resources/extensions/gsd/notifications.js +23 -0
- package/dist/resources/extensions/gsd/observability-validator.js +422 -0
- package/dist/resources/extensions/gsd/preferences-models.js +1 -13
- package/dist/resources/extensions/gsd/preferences-skills.js +11 -5
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +25 -0
- package/dist/resources/extensions/gsd/preferences.js +16 -13
- package/dist/resources/extensions/gsd/prompts/forensics.md +11 -7
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
- package/dist/resources/extensions/gsd/provider-error-pause.js +0 -36
- package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
- package/dist/resources/extensions/gsd/rtk-status.js +43 -0
- package/dist/resources/extensions/gsd/rule-registry.js +11 -12
- package/dist/resources/extensions/gsd/service-tier.js +13 -2
- package/dist/resources/extensions/gsd/session-forensics.js +7 -3
- package/dist/resources/extensions/gsd/skill-catalog.js +1026 -0
- package/dist/resources/extensions/gsd/skill-discovery.js +3 -2
- package/dist/resources/extensions/gsd/skill-health.js +2 -2
- package/dist/resources/extensions/gsd/skill-telemetry.js +15 -5
- package/dist/resources/extensions/gsd/state.js +38 -7
- package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
- package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -10
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -17
- package/dist/resources/extensions/gsd/tools/complete-task.js +7 -18
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +26 -17
- package/dist/resources/extensions/gsd/tools/plan-slice.js +25 -14
- package/dist/resources/extensions/gsd/tools/plan-task.js +21 -11
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +47 -37
- package/dist/resources/extensions/gsd/tools/replan-slice.js +49 -38
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
- package/dist/resources/extensions/gsd/verification-gate.js +3 -1
- package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
- package/dist/resources/extensions/remote-questions/config.js +1 -1
- package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
- package/dist/resources/extensions/search-the-web/native-search.js +1 -1
- package/dist/resources/extensions/search-the-web/provider.js +1 -1
- package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
- package/dist/resources/extensions/shared/rtk.js +100 -0
- package/dist/rtk.d.ts +52 -0
- package/dist/rtk.js +332 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- 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.js.nft.json +1 -1
- 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.js.nft.json +1 -1
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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 +2 -2
- 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.js.nft.json +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.js.nft.json +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 +3 -0
- package/dist/web/standalone/.next/server/app/api/experimental/route.js.nft.json +1 -0
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -0
- 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/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.js.nft.json +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 -26
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +1 -1
- 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.js.nft.json +1 -1
- 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.js.nft.json +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.js.nft.json +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 +5 -5
- 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 +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
- package/dist/web/standalone/.next/server/chunks/2229.js +12 -0
- package/dist/web/standalone/.next/server/chunks/2331.js +25 -0
- package/dist/web/standalone/.next/server/chunks/{741.js → 4741.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +2 -0
- package/dist/web/standalone/.next/server/chunks/7471.js +13 -0
- 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-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- 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/server/webpack-runtime.js +1 -1
- package/dist/web/standalone/.next/static/RqOU-jOv9uZ1Q03P6L6nn/_buildManifest.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{485.243af25f0cdf50d6.js → 2008.817d0885545aaea9.js} +6 -6
- package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.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-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.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-b950e4e384cc62b3.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-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.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-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/webpack-024d82be84800e52.js +1 -0
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +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/wizard.js +4 -1
- package/package.json +2 -2
- package/packages/pi-ai/dist/models.d.ts +14 -3
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.js +53 -10
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +102 -1
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +31 -0
- 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/models.test.ts +114 -1
- package/packages/pi-ai/src/models.ts +70 -13
- package/packages/pi-ai/src/types.ts +32 -1
- package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
- package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/cli/args.js +3 -0
- package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +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 +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/bash-executor.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/bash-executor.js +15 -2
- package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +13 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +19 -1
- 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/extensions/wrapper.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/wrapper.js +8 -0
- package/packages/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +8 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +11 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +30 -8
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +3 -3
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +5 -3
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +3 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- 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 +6 -4
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +5 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/cli/args.ts +4 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/bash-executor.ts +15 -3
- package/packages/pi-coding-agent/src/core/extensions/index.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +18 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +21 -0
- package/packages/pi-coding-agent/src/core/extensions/wrapper.ts +9 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
- package/packages/pi-coding-agent/src/core/package-manager.ts +10 -1
- package/packages/pi-coding-agent/src/core/skills.ts +35 -10
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
- package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
- package/packages/pi-coding-agent/src/index.ts +7 -0
- package/packages/pi-coding-agent/src/main.ts +5 -3
- package/packages/pi-coding-agent/src/modes/index.ts +8 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +6 -4
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +2 -1
- package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
- package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
- package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
- package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +2 -1
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/postinstall.js +163 -6
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +25 -12
- package/src/resources/extensions/bg-shell/interaction.ts +3 -1
- package/src/resources/extensions/bg-shell/process-manager.ts +4 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +5 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +105 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
- package/src/resources/extensions/gsd/auto/phases.ts +15 -1
- package/src/resources/extensions/gsd/auto/session.ts +6 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +31 -3
- package/src/resources/extensions/gsd/auto-dispatch.ts +102 -50
- package/src/resources/extensions/gsd/auto-observability.ts +72 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +56 -83
- package/src/resources/extensions/gsd/auto-prompts.ts +48 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +19 -26
- package/src/resources/extensions/gsd/auto-start.ts +2 -0
- package/src/resources/extensions/gsd/auto-timers.ts +25 -1
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
- package/src/resources/extensions/gsd/auto-utils.ts +25 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
- package/src/resources/extensions/gsd/auto.ts +20 -7
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +115 -72
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -1
- package/src/resources/extensions/gsd/claude-import.ts +58 -9
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
- package/src/resources/extensions/gsd/commands-config.ts +11 -5
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
- package/src/resources/extensions/gsd/crash-recovery.ts +6 -2
- package/src/resources/extensions/gsd/custom-execution-policy.ts +3 -2
- package/src/resources/extensions/gsd/custom-verification.ts +3 -1
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -2
- package/src/resources/extensions/gsd/dashboard-overlay.ts +7 -0
- package/src/resources/extensions/gsd/detection.ts +668 -9
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +18 -3
- package/src/resources/extensions/gsd/error-classifier.ts +139 -0
- package/src/resources/extensions/gsd/files.ts +6 -1
- package/src/resources/extensions/gsd/gitignore.ts +7 -7
- package/src/resources/extensions/gsd/gsd-db.ts +355 -63
- package/src/resources/extensions/gsd/guided-flow.ts +11 -0
- package/src/resources/extensions/gsd/init-wizard.ts +11 -3
- package/src/resources/extensions/gsd/key-manager.ts +7 -16
- package/src/resources/extensions/gsd/memory-store.ts +29 -18
- package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
- package/src/resources/extensions/gsd/model-router.ts +25 -0
- package/src/resources/extensions/gsd/notifications.ts +23 -0
- package/src/resources/extensions/gsd/observability-validator.ts +456 -0
- package/src/resources/extensions/gsd/preferences-models.ts +1 -13
- package/src/resources/extensions/gsd/preferences-skills.ts +11 -5
- package/src/resources/extensions/gsd/preferences-types.ts +20 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +26 -0
- package/src/resources/extensions/gsd/preferences.ts +15 -13
- package/src/resources/extensions/gsd/prompts/forensics.md +11 -7
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
- package/src/resources/extensions/gsd/provider-error-pause.ts +0 -48
- package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
- package/src/resources/extensions/gsd/rtk-status.ts +53 -0
- package/src/resources/extensions/gsd/rule-registry.ts +11 -12
- package/src/resources/extensions/gsd/service-tier.ts +14 -2
- package/src/resources/extensions/gsd/session-forensics.ts +7 -3
- package/src/resources/extensions/gsd/skill-catalog.ts +1085 -0
- package/src/resources/extensions/gsd/skill-discovery.ts +3 -2
- package/src/resources/extensions/gsd/skill-health.ts +2 -2
- package/src/resources/extensions/gsd/skill-telemetry.ts +15 -5
- package/src/resources/extensions/gsd/state.ts +38 -7
- package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
- package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/custom-verification.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +39 -10
- package/src/resources/extensions/gsd/tests/detection.test.ts +839 -1
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +51 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +161 -0
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
- package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +56 -21
- package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -14
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -21
- package/src/resources/extensions/gsd/tools/complete-task.ts +9 -22
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +28 -18
- package/src/resources/extensions/gsd/tools/plan-slice.ts +28 -16
- package/src/resources/extensions/gsd/tools/plan-task.ts +24 -12
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +54 -42
- package/src/resources/extensions/gsd/tools/replan-slice.ts +53 -40
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
- package/src/resources/extensions/gsd/types.ts +2 -0
- package/src/resources/extensions/gsd/undo.ts +8 -7
- package/src/resources/extensions/gsd/unit-runtime.ts +2 -1
- package/src/resources/extensions/gsd/verification-gate.ts +3 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
- package/src/resources/extensions/remote-questions/config.ts +1 -1
- package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
- package/src/resources/extensions/search-the-web/native-search.ts +1 -1
- package/src/resources/extensions/search-the-web/provider.ts +1 -1
- package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
- package/src/resources/extensions/shared/rtk.ts +120 -0
- package/dist/web/standalone/.next/server/chunks/229.js +0 -12
- package/dist/web/standalone/.next/server/chunks/441.js +0 -2
- package/dist/web/standalone/.next/server/chunks/471.js +0 -13
- package/dist/web/standalone/.next/static/MQOhBnkC_TLtNn_JvZWDj/_buildManifest.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4024.7c75ac378de0f2b5.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.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-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.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-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +0 -1
- package/dist/web/standalone/.next/static/chunks/webpack-2473ce2c3879fff4.js +0 -1
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
- package/packages/pi-ai/pnpm-lock.yaml +0 -2022
- package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
- /package/dist/web/standalone/.next/static/{MQOhBnkC_TLtNn_JvZWDj → RqOU-jOv9uZ1Q03P6L6nn}/_ssgManifest.js +0 -0
|
@@ -7,17 +7,28 @@ const require = createRequire(import.meta.url);
|
|
|
7
7
|
const ROOT = new URL("../../../../../", import.meta.url);
|
|
8
8
|
|
|
9
9
|
export function resolve(specifier, context, nextResolve) {
|
|
10
|
-
// 1.
|
|
10
|
+
// 1. Redirect all workspace package bare imports to source.
|
|
11
|
+
// CI portability runs don't build any packages/ dist artifacts, so every
|
|
12
|
+
// @gsd/* specifier (including transitive ones pulled in by pi-coding-agent
|
|
13
|
+
// source itself) must resolve to the TypeScript source entrypoint.
|
|
11
14
|
if (specifier === "../../packages/pi-coding-agent/src/index.js") {
|
|
12
|
-
specifier = new URL("packages/pi-coding-agent/
|
|
15
|
+
specifier = new URL("packages/pi-coding-agent/src/index.ts", ROOT).href;
|
|
16
|
+
} else if (specifier === "@gsd/pi-coding-agent") {
|
|
17
|
+
specifier = new URL("packages/pi-coding-agent/src/index.ts", ROOT).href;
|
|
13
18
|
} else if (specifier === "@gsd/pi-ai/oauth") {
|
|
14
|
-
specifier = new URL("packages/pi-ai/
|
|
19
|
+
specifier = new URL("packages/pi-ai/src/utils/oauth/index.ts", ROOT).href;
|
|
15
20
|
} else if (specifier === "@gsd/pi-ai") {
|
|
16
|
-
specifier = new URL("packages/pi-ai/
|
|
21
|
+
specifier = new URL("packages/pi-ai/src/index.ts", ROOT).href;
|
|
17
22
|
} else if (specifier === "@gsd/pi-agent-core") {
|
|
18
|
-
specifier = new URL("packages/pi-agent-core/
|
|
23
|
+
specifier = new URL("packages/pi-agent-core/src/index.ts", ROOT).href;
|
|
19
24
|
} else if (specifier === "@gsd/pi-tui") {
|
|
20
|
-
specifier = new URL("packages/pi-tui/
|
|
25
|
+
specifier = new URL("packages/pi-tui/src/index.ts", ROOT).href;
|
|
26
|
+
} else if (specifier === "@gsd/native") {
|
|
27
|
+
specifier = new URL("packages/native/src/index.ts", ROOT).href;
|
|
28
|
+
} else if (specifier.startsWith("@gsd/native/")) {
|
|
29
|
+
// Sub-path imports like @gsd/native/fd, @gsd/native/text, etc.
|
|
30
|
+
const subpath = specifier.slice("@gsd/native/".length);
|
|
31
|
+
specifier = new URL(`packages/native/src/${subpath}/index.ts`, ROOT).href;
|
|
21
32
|
}
|
|
22
33
|
// 2. Redirect packages/*/dist/ → packages/*/src/ with .js→.ts for strip-types
|
|
23
34
|
// Also handles local imports — skip rewrite for dist/ paths that are real compiled artifacts.
|
|
@@ -54,9 +65,15 @@ export function resolve(specifier, context, nextResolve) {
|
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
export function load(url, context, nextLoad) {
|
|
57
|
-
// Node's --experimental-strip-types handles .ts but not .tsx
|
|
58
|
-
//
|
|
59
|
-
|
|
68
|
+
// Node's --experimental-strip-types handles plain .ts but not .tsx and not
|
|
69
|
+
// all TypeScript syntax used by workspace packages (parameter properties,
|
|
70
|
+
// decorators, etc.). Transpile all workspace package source files and .tsx
|
|
71
|
+
// files through TypeScript's transpileModule to avoid those crashes.
|
|
72
|
+
const shouldTranspileWithTypeScript =
|
|
73
|
+
url.endsWith('.tsx') ||
|
|
74
|
+
(url.endsWith('.ts') && url.includes('/packages/') && url.includes('/src/'));
|
|
75
|
+
|
|
76
|
+
if (shouldTranspileWithTypeScript) {
|
|
60
77
|
const ts = require('typescript');
|
|
61
78
|
const source = readFileSync(fileURLToPath(url), 'utf-8');
|
|
62
79
|
const { outputText } = ts.transpileModule(source, {
|
|
@@ -66,6 +83,8 @@ export function load(url, context, nextLoad) {
|
|
|
66
83
|
module: ts.ModuleKind.ESNext,
|
|
67
84
|
target: ts.ScriptTarget.ESNext,
|
|
68
85
|
esModuleInterop: true,
|
|
86
|
+
experimentalDecorators: true,
|
|
87
|
+
emitDecoratorMetadata: true,
|
|
69
88
|
},
|
|
70
89
|
});
|
|
71
90
|
return { format: 'module', source: outputText, shortCircuit: true };
|
|
@@ -64,11 +64,11 @@ _None_
|
|
|
64
64
|
return dir;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
/** Write a .gsd/
|
|
67
|
+
/** Write a .gsd/PREFERENCES.md with the given git isolation mode. */
|
|
68
68
|
function writePreferencesFile(dir: string, isolation: "none" | "worktree" | "branch"): void {
|
|
69
69
|
const gsdDir = join(dir, ".gsd");
|
|
70
70
|
mkdirSync(gsdDir, { recursive: true });
|
|
71
|
-
writeFileSync(join(gsdDir, "
|
|
71
|
+
writeFileSync(join(gsdDir, "PREFERENCES.md"), `---\ngit:\n isolation: "${isolation}"\n---\n`);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/** Create a repo with an in-progress milestone. */
|
|
@@ -302,7 +302,7 @@ describe('doctor-git', async () => {
|
|
|
302
302
|
// ─── Test 7: none-mode skips orphaned worktree check ───────────────
|
|
303
303
|
// NOTE: loadEffectiveGSDPreferences() resolves PROJECT_PREFERENCES_PATH
|
|
304
304
|
// at module load time from process.cwd(). We write the prefs file to
|
|
305
|
-
// the test runner's cwd .gsd/
|
|
305
|
+
// the test runner's cwd .gsd/PREFERENCES.md and clean up afterwards.
|
|
306
306
|
if (process.platform !== "win32") {
|
|
307
307
|
test('none-mode skips orphaned worktree', async () => {
|
|
308
308
|
const dir = createRepoWithCompletedMilestone();
|
|
@@ -409,7 +409,7 @@ describe('doctor-git', async () => {
|
|
|
409
409
|
cleanups.push(dir);
|
|
410
410
|
|
|
411
411
|
run("git branch trunk", dir);
|
|
412
|
-
writeFileSync(join(dir, ".gsd", "
|
|
412
|
+
writeFileSync(join(dir, ".gsd", "PREFERENCES.md"), `---\ngit:\n isolation: "worktree"\n main_branch: "trunk"\n---\n`);
|
|
413
413
|
|
|
414
414
|
const metaPath = join(dir, ".gsd", "milestones", "M001", "M001-META.json");
|
|
415
415
|
writeFileSync(metaPath, JSON.stringify({ integrationBranch: "feat/does-not-exist" }, null, 2));
|
|
@@ -297,7 +297,7 @@ describe('doctor-proactive', async () => {
|
|
|
297
297
|
cleanups.push(dir);
|
|
298
298
|
|
|
299
299
|
run("git branch trunk", dir);
|
|
300
|
-
writeFileSync(join(dir, ".gsd", "
|
|
300
|
+
writeFileSync(join(dir, ".gsd", "PREFERENCES.md"), `---\ngit:\n main_branch: "trunk"\n---\n`);
|
|
301
301
|
const metaPath = join(dir, ".gsd", "milestones", "M001", "M001-META.json");
|
|
302
302
|
writeFileSync(metaPath, JSON.stringify({ integrationBranch: "feature/missing" }, null, 2));
|
|
303
303
|
|
|
@@ -419,7 +419,7 @@ test("runProviderChecks uses provider-qualified anthropic-vertex model IDs", ()
|
|
|
419
419
|
const repo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-providers-vertex-prefix-repo-")));
|
|
420
420
|
mkdirSync(join(repo, ".gsd"), { recursive: true });
|
|
421
421
|
writeFileSync(
|
|
422
|
-
join(repo, ".gsd", "
|
|
422
|
+
join(repo, ".gsd", "PREFERENCES.md"),
|
|
423
423
|
[
|
|
424
424
|
"---",
|
|
425
425
|
"models:",
|
|
@@ -454,7 +454,7 @@ test("runProviderChecks uses object provider field for anthropic-vertex models",
|
|
|
454
454
|
const repo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-providers-vertex-provider-repo-")));
|
|
455
455
|
mkdirSync(join(repo, ".gsd"), { recursive: true });
|
|
456
456
|
writeFileSync(
|
|
457
|
-
join(repo, ".gsd", "
|
|
457
|
+
join(repo, ".gsd", "PREFERENCES.md"),
|
|
458
458
|
[
|
|
459
459
|
"---",
|
|
460
460
|
"models:",
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join, dirname } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { AutoSession } from "../auto/session.ts";
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
|
|
10
|
+
describe("double mergeAndExit guard (#2645)", () => {
|
|
11
|
+
test("phases.ts sets milestoneMergedInPhases after mergeAndExit in milestone-complete path", () => {
|
|
12
|
+
// Source audit: the "complete" phase path must set the guard flag
|
|
13
|
+
// after calling mergeAndExit so that stopAuto skips the second merge.
|
|
14
|
+
const phasesSrc = readFileSync(
|
|
15
|
+
join(__dirname, "..", "auto", "phases.ts"),
|
|
16
|
+
"utf-8",
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
// Find the "complete" phase block
|
|
20
|
+
const completeIdx = phasesSrc.indexOf('state.phase === "complete"');
|
|
21
|
+
assert.ok(completeIdx > 0, "phases.ts should have a 'complete' phase check");
|
|
22
|
+
|
|
23
|
+
const afterComplete = phasesSrc.slice(completeIdx, completeIdx + 600);
|
|
24
|
+
const mergeIdx = afterComplete.indexOf("deps.resolver.mergeAndExit");
|
|
25
|
+
const flagIdx = afterComplete.indexOf("s.milestoneMergedInPhases = true");
|
|
26
|
+
|
|
27
|
+
assert.ok(mergeIdx > 0, "complete path should call mergeAndExit");
|
|
28
|
+
assert.ok(flagIdx > 0, "complete path should set milestoneMergedInPhases");
|
|
29
|
+
assert.ok(
|
|
30
|
+
flagIdx > mergeIdx,
|
|
31
|
+
"milestoneMergedInPhases must be set AFTER mergeAndExit (not before)",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("phases.ts sets milestoneMergedInPhases after mergeAndExit in all-milestones-complete path", () => {
|
|
36
|
+
const phasesSrc = readFileSync(
|
|
37
|
+
join(__dirname, "..", "auto", "phases.ts"),
|
|
38
|
+
"utf-8",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// The "all milestones complete" block checks incomplete.length === 0
|
|
42
|
+
const allCompleteIdx = phasesSrc.indexOf("incomplete.length === 0");
|
|
43
|
+
assert.ok(allCompleteIdx > 0, "phases.ts should have an all-milestones-complete check");
|
|
44
|
+
|
|
45
|
+
const afterAllComplete = phasesSrc.slice(allCompleteIdx, allCompleteIdx + 600);
|
|
46
|
+
const mergeIdx = afterAllComplete.indexOf("deps.resolver.mergeAndExit");
|
|
47
|
+
const flagIdx = afterAllComplete.indexOf("s.milestoneMergedInPhases = true");
|
|
48
|
+
|
|
49
|
+
assert.ok(mergeIdx > 0, "all-complete path should call mergeAndExit");
|
|
50
|
+
assert.ok(flagIdx > 0, "all-complete path should set milestoneMergedInPhases");
|
|
51
|
+
assert.ok(
|
|
52
|
+
flagIdx > mergeIdx,
|
|
53
|
+
"milestoneMergedInPhases must be set AFTER mergeAndExit (not before)",
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("stopAuto checks milestoneMergedInPhases before calling mergeAndExit", () => {
|
|
58
|
+
const autoSrc = readFileSync(
|
|
59
|
+
join(__dirname, "..", "auto.ts"),
|
|
60
|
+
"utf-8",
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// The Step 4 worktree exit block must check the guard flag
|
|
64
|
+
const step4Idx = autoSrc.indexOf("Step 4: Auto-worktree exit");
|
|
65
|
+
assert.ok(step4Idx > 0, "auto.ts should have Step 4 worktree exit");
|
|
66
|
+
|
|
67
|
+
const step4Block = autoSrc.slice(step4Idx, step4Idx + 600);
|
|
68
|
+
assert.ok(
|
|
69
|
+
step4Block.includes("milestoneMergedInPhases"),
|
|
70
|
+
"stopAuto Step 4 must check milestoneMergedInPhases before merging",
|
|
71
|
+
);
|
|
72
|
+
assert.ok(
|
|
73
|
+
step4Block.includes("!s.milestoneMergedInPhases"),
|
|
74
|
+
"stopAuto should skip merge when milestoneMergedInPhases is true",
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("AutoSession.milestoneMergedInPhases defaults to false", () => {
|
|
79
|
+
const session = new AutoSession();
|
|
80
|
+
assert.equal(
|
|
81
|
+
session.milestoneMergedInPhases,
|
|
82
|
+
false,
|
|
83
|
+
"new session should have milestoneMergedInPhases = false",
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("AutoSession.reset() clears milestoneMergedInPhases", () => {
|
|
88
|
+
const session = new AutoSession();
|
|
89
|
+
session.milestoneMergedInPhases = true;
|
|
90
|
+
session.reset();
|
|
91
|
+
assert.equal(
|
|
92
|
+
session.milestoneMergedInPhases,
|
|
93
|
+
false,
|
|
94
|
+
"reset() should clear milestoneMergedInPhases back to false",
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for #2631: deriveState disk→DB reconciliation must
|
|
3
|
+
* run even when the milestones table starts empty.
|
|
4
|
+
*
|
|
5
|
+
* When getAllMilestones() returns [] (e.g. after a failed initial migration),
|
|
6
|
+
* the reconciliation code inside deriveStateFromDb was unreachable because
|
|
7
|
+
* deriveState only called it when dbMilestones.length > 0. The fix moves
|
|
8
|
+
* disk→DB sync into deriveState itself, before the length check.
|
|
9
|
+
*/
|
|
10
|
+
import { test } from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
|
|
16
|
+
import { deriveState, invalidateStateCache } from "../state.ts";
|
|
17
|
+
import {
|
|
18
|
+
openDatabase,
|
|
19
|
+
closeDatabase,
|
|
20
|
+
getAllMilestones,
|
|
21
|
+
} from "../gsd-db.ts";
|
|
22
|
+
|
|
23
|
+
test("deriveState populates empty DB from disk milestones (#2631)", async () => {
|
|
24
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-empty-db-"));
|
|
25
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// Create a milestone on disk with a CONTEXT file (not a ghost)
|
|
29
|
+
writeFileSync(
|
|
30
|
+
join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
|
|
31
|
+
"# M001: Test Milestone\n\nSome context about this milestone.",
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Open DB — milestones table is empty (simulating failed migration)
|
|
35
|
+
openDatabase(":memory:");
|
|
36
|
+
const before = getAllMilestones();
|
|
37
|
+
assert.equal(before.length, 0, "DB should start with 0 milestones");
|
|
38
|
+
|
|
39
|
+
// deriveState should reconcile disk → DB
|
|
40
|
+
invalidateStateCache();
|
|
41
|
+
const state = await deriveState(base);
|
|
42
|
+
|
|
43
|
+
// After deriveState, the DB should now have the disk milestone
|
|
44
|
+
const after = getAllMilestones();
|
|
45
|
+
assert.ok(after.length > 0, "DB should have milestones after reconciliation");
|
|
46
|
+
assert.equal(after[0]!.id, "M001", "reconciled milestone should be M001");
|
|
47
|
+
|
|
48
|
+
// State should reflect the milestone (not "No milestones found")
|
|
49
|
+
assert.ok(
|
|
50
|
+
state.activeMilestone !== null,
|
|
51
|
+
"activeMilestone should not be null after reconciliation",
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
closeDatabase();
|
|
55
|
+
} finally {
|
|
56
|
+
closeDatabase();
|
|
57
|
+
rmSync(base, { recursive: true, force: true });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("deriveState does NOT insert ghost milestones into DB (#2631 guard)", async () => {
|
|
62
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-empty-db-"));
|
|
63
|
+
// Create a ghost milestone directory (empty — no CONTEXT, no ROADMAP)
|
|
64
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
openDatabase(":memory:");
|
|
68
|
+
invalidateStateCache();
|
|
69
|
+
await deriveState(base);
|
|
70
|
+
|
|
71
|
+
const milestones = getAllMilestones();
|
|
72
|
+
assert.equal(milestones.length, 0, "ghost milestone should NOT be inserted");
|
|
73
|
+
|
|
74
|
+
closeDatabase();
|
|
75
|
+
} finally {
|
|
76
|
+
closeDatabase();
|
|
77
|
+
rmSync(base, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
});
|
|
@@ -1142,7 +1142,7 @@ describe('git-service', async () => {
|
|
|
1142
1142
|
mkdirSync(join(repo, ".gsd", "runtime"), { recursive: true });
|
|
1143
1143
|
mkdirSync(join(repo, ".gsd", "activity"), { recursive: true });
|
|
1144
1144
|
writeFileSync(join(repo, ".gsd", "milestones", "M001", "ROADMAP.md"), "# Roadmap");
|
|
1145
|
-
writeFileSync(join(repo, ".gsd", "
|
|
1145
|
+
writeFileSync(join(repo, ".gsd", "PREFERENCES.md"), "---\nversion: 1\n---");
|
|
1146
1146
|
writeFileSync(join(repo, ".gsd", "STATE.md"), "# State");
|
|
1147
1147
|
writeFileSync(join(repo, ".gsd", "runtime", "units.json"), "{}");
|
|
1148
1148
|
writeFileSync(join(repo, ".gsd", "activity", "log.jsonl"), "{}");
|
|
@@ -64,7 +64,7 @@ describe('gsd-db', () => {
|
|
|
64
64
|
// Check schema_version table
|
|
65
65
|
const adapter = _getAdapter()!;
|
|
66
66
|
const version = adapter.prepare('SELECT MAX(version) as version FROM schema_version').get();
|
|
67
|
-
assert.deepStrictEqual(version?.['version'],
|
|
67
|
+
assert.deepStrictEqual(version?.['version'], 14, 'schema version should be 14');
|
|
68
68
|
|
|
69
69
|
// Check tables exist by querying them
|
|
70
70
|
const dRows = adapter.prepare('SELECT count(*) as cnt FROM decisions').get();
|
|
@@ -294,3 +294,66 @@ test('verifyExpectedArtifact: hook types always return true', () => {
|
|
|
294
294
|
}
|
|
295
295
|
});
|
|
296
296
|
|
|
297
|
+
|
|
298
|
+
test('writeBlockerPlaceholder: updates DB task status for execute-task (#2531)', async () => {
|
|
299
|
+
const base = createFixtureBase();
|
|
300
|
+
try {
|
|
301
|
+
const { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getTask, isDbAvailable } =
|
|
302
|
+
await import("../gsd-db.ts");
|
|
303
|
+
|
|
304
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
305
|
+
// Create the tasks directory (required for artifact path resolution)
|
|
306
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
307
|
+
|
|
308
|
+
openDatabase(dbPath);
|
|
309
|
+
try {
|
|
310
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
311
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "active" });
|
|
312
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Task", status: "pending" });
|
|
313
|
+
|
|
314
|
+
// Before fix: writeBlockerPlaceholder wrote the file but left DB as "pending"
|
|
315
|
+
writeBlockerPlaceholder("execute-task", "M001/S01/T01", base, "idle recovery exhausted");
|
|
316
|
+
|
|
317
|
+
const task = getTask("M001", "S01", "T01");
|
|
318
|
+
assert.equal(task?.status, "complete",
|
|
319
|
+
"writeBlockerPlaceholder must update DB task status to 'complete' so verifyExpectedArtifact passes");
|
|
320
|
+
|
|
321
|
+
// Verify the full chain works: verifyExpectedArtifact should return true
|
|
322
|
+
const verified = verifyExpectedArtifact("execute-task", "M001/S01/T01", base);
|
|
323
|
+
assert.equal(verified, true,
|
|
324
|
+
"verifyExpectedArtifact should pass after writeBlockerPlaceholder updates DB status");
|
|
325
|
+
} finally {
|
|
326
|
+
if (isDbAvailable()) closeDatabase();
|
|
327
|
+
}
|
|
328
|
+
} finally {
|
|
329
|
+
cleanup(base);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test('writeBlockerPlaceholder: does NOT update DB for non-execute-task types', async () => {
|
|
334
|
+
const base = createFixtureBase();
|
|
335
|
+
try {
|
|
336
|
+
const { openDatabase, closeDatabase, insertMilestone, insertSlice, getSlice, isDbAvailable } =
|
|
337
|
+
await import("../gsd-db.ts");
|
|
338
|
+
|
|
339
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
340
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
341
|
+
|
|
342
|
+
openDatabase(dbPath);
|
|
343
|
+
try {
|
|
344
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
345
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "active" });
|
|
346
|
+
|
|
347
|
+
// research-slice is NOT execute-task — DB should NOT be updated
|
|
348
|
+
writeBlockerPlaceholder("research-slice", "M001/S01", base, "idle recovery exhausted");
|
|
349
|
+
|
|
350
|
+
const slice = getSlice("M001", "S01");
|
|
351
|
+
assert.equal(slice?.status, "active",
|
|
352
|
+
"writeBlockerPlaceholder should not change DB status for non-execute-task types");
|
|
353
|
+
} finally {
|
|
354
|
+
if (isDbAvailable()) closeDatabase();
|
|
355
|
+
}
|
|
356
|
+
} finally {
|
|
357
|
+
cleanup(base);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for #2527: idle watchdog stalled-tool detection.
|
|
3
|
+
*
|
|
4
|
+
* Bug 1: When a tool is stalled longer than idle_timeout, the watchdog
|
|
5
|
+
* notifies but falls through to detectWorkingTreeActivity(), which
|
|
6
|
+
* resets lastProgressAt if files were modified earlier. Recovery is
|
|
7
|
+
* never called — the session burns tokens indefinitely.
|
|
8
|
+
*
|
|
9
|
+
* Bug 2: After async recoverTimedOutUnit(), pauseAuto/stopAuto may set
|
|
10
|
+
* s.currentUnit = null, but the next line accesses .startedAt — crash.
|
|
11
|
+
*
|
|
12
|
+
* These tests verify the auto-timers.ts source contains the structural
|
|
13
|
+
* fixes: the stalledToolDetected flag, clearInFlightTools() call, the
|
|
14
|
+
* filesystem-check guard, and the null guard after recovery.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { test, describe } from "node:test";
|
|
20
|
+
import assert from "node:assert/strict";
|
|
21
|
+
|
|
22
|
+
const TIMERS_SRC = readFileSync(
|
|
23
|
+
join(import.meta.dirname, "..", "auto-timers.ts"),
|
|
24
|
+
"utf-8",
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// ═══ Bug 1: stalledToolDetected flag prevents filesystem-activity override ═══
|
|
28
|
+
|
|
29
|
+
describe("#2527 Bug 1: stalled tool should not be overridden by filesystem activity", () => {
|
|
30
|
+
test("auto-timers.ts imports clearInFlightTools", () => {
|
|
31
|
+
assert.ok(
|
|
32
|
+
TIMERS_SRC.includes("clearInFlightTools"),
|
|
33
|
+
"clearInFlightTools must be imported from auto-tool-tracking",
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("auto-timers.ts declares stalledToolDetected flag", () => {
|
|
38
|
+
assert.ok(
|
|
39
|
+
TIMERS_SRC.includes("stalledToolDetected"),
|
|
40
|
+
"stalledToolDetected flag must exist in idle watchdog",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("stalled tool sets flag to true", () => {
|
|
45
|
+
// The flag must be set before the filesystem check
|
|
46
|
+
const flagSet = TIMERS_SRC.indexOf("stalledToolDetected = true");
|
|
47
|
+
assert.ok(flagSet > -1, "stalledToolDetected must be set to true when tool is stalled");
|
|
48
|
+
|
|
49
|
+
const notify = TIMERS_SRC.indexOf("Stalled tool detected:");
|
|
50
|
+
assert.ok(flagSet < notify, "flag must be set before the stall notification");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("stalled tool calls clearInFlightTools", () => {
|
|
54
|
+
// clearInFlightTools() must be called when tool is stalled, so subsequent
|
|
55
|
+
// watchdog ticks don't re-detect the same stale entries
|
|
56
|
+
const clearCall = TIMERS_SRC.indexOf("clearInFlightTools()");
|
|
57
|
+
assert.ok(clearCall > -1, "clearInFlightTools() must be called when tool is stalled");
|
|
58
|
+
|
|
59
|
+
const flagSet = TIMERS_SRC.indexOf("stalledToolDetected = true");
|
|
60
|
+
assert.ok(
|
|
61
|
+
Math.abs(clearCall - flagSet) < 200,
|
|
62
|
+
"clearInFlightTools() should be near stalledToolDetected = true",
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("filesystem-activity check is guarded by stalledToolDetected", () => {
|
|
67
|
+
// The detectWorkingTreeActivity check must be skipped when stalledToolDetected is true
|
|
68
|
+
assert.ok(
|
|
69
|
+
TIMERS_SRC.includes("!stalledToolDetected && detectWorkingTreeActivity"),
|
|
70
|
+
"detectWorkingTreeActivity must be guarded by !stalledToolDetected",
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("control flow: stalled tool → skip filesystem check → reach recovery", () => {
|
|
75
|
+
// Verify the structural ordering: flag declaration → stall block → guarded fs check → recovery
|
|
76
|
+
const flagDecl = TIMERS_SRC.indexOf("let stalledToolDetected = false");
|
|
77
|
+
const stallBlock = TIMERS_SRC.indexOf("stalledToolDetected = true");
|
|
78
|
+
const fsGuard = TIMERS_SRC.indexOf("!stalledToolDetected && detectWorkingTreeActivity");
|
|
79
|
+
const recovery = TIMERS_SRC.indexOf("recoverTimedOutUnit(ctx, pi, unitType, unitId, \"idle\"");
|
|
80
|
+
|
|
81
|
+
assert.ok(flagDecl > -1, "flag declaration must exist");
|
|
82
|
+
assert.ok(flagDecl < stallBlock, "flag declared before stall block");
|
|
83
|
+
assert.ok(stallBlock < fsGuard, "stall block before filesystem guard");
|
|
84
|
+
assert.ok(fsGuard < recovery, "filesystem guard before recovery call");
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// ═══ Bug 2: null guard after async recoverTimedOutUnit ═══════════════════════
|
|
89
|
+
|
|
90
|
+
describe("#2527 Bug 2: null guard after async recovery prevents crash", () => {
|
|
91
|
+
test("idle watchdog has null guard after recoverTimedOutUnit", () => {
|
|
92
|
+
// Find the idle recovery call
|
|
93
|
+
const idleRecovery = TIMERS_SRC.indexOf(
|
|
94
|
+
'recoverTimedOutUnit(ctx, pi, unitType, unitId, "idle"',
|
|
95
|
+
);
|
|
96
|
+
assert.ok(idleRecovery > -1, "idle recovery call must exist");
|
|
97
|
+
|
|
98
|
+
// The null guard must appear between the recovery call and the next
|
|
99
|
+
// writeUnitRuntimeRecord that accesses s.currentUnit.startedAt
|
|
100
|
+
const afterRecovery = TIMERS_SRC.slice(idleRecovery, idleRecovery + 400);
|
|
101
|
+
assert.ok(
|
|
102
|
+
afterRecovery.includes("if (!s.currentUnit) return"),
|
|
103
|
+
"null guard for s.currentUnit must exist after idle recoverTimedOutUnit",
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("null guard is between recovery and writeUnitRuntimeRecord", () => {
|
|
108
|
+
const idleRecovery = TIMERS_SRC.indexOf(
|
|
109
|
+
'recoverTimedOutUnit(ctx, pi, unitType, unitId, "idle"',
|
|
110
|
+
);
|
|
111
|
+
const afterRecovery = TIMERS_SRC.slice(idleRecovery);
|
|
112
|
+
|
|
113
|
+
const recoveredReturn = afterRecovery.indexOf('if (recovery === "recovered") return');
|
|
114
|
+
const nullGuard = afterRecovery.indexOf("if (!s.currentUnit) return");
|
|
115
|
+
const writeRecord = afterRecovery.indexOf("writeUnitRuntimeRecord(s.basePath");
|
|
116
|
+
|
|
117
|
+
assert.ok(recoveredReturn > -1, "recovered return must exist");
|
|
118
|
+
assert.ok(nullGuard > -1, "null guard must exist");
|
|
119
|
+
assert.ok(writeRecord > -1, "writeUnitRuntimeRecord must exist after recovery");
|
|
120
|
+
assert.ok(
|
|
121
|
+
recoveredReturn < nullGuard && nullGuard < writeRecord,
|
|
122
|
+
"order must be: recovered-return → null-guard → writeUnitRuntimeRecord",
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -123,7 +123,7 @@ test("init-wizard: v2 .gsd/ preferences detected", (t) => {
|
|
|
123
123
|
const dir = makeTempDir("prefs-detect");
|
|
124
124
|
try {
|
|
125
125
|
mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
|
|
126
|
-
writeFileSync(join(dir, ".gsd", "
|
|
126
|
+
writeFileSync(join(dir, ".gsd", "PREFERENCES.md"), "---\nversion: 1\nmode: solo\n---\n", "utf-8");
|
|
127
127
|
|
|
128
128
|
const detection = detectProjectState(dir);
|
|
129
129
|
assert.ok(detection.v2);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for #2676: idle watchdog must exempt user-interactive tools
|
|
3
|
+
* (ask_user_questions, secure_env_collect) from stall detection.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, test, beforeEach } from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import {
|
|
8
|
+
markToolStart,
|
|
9
|
+
markToolEnd,
|
|
10
|
+
hasInteractiveToolInFlight,
|
|
11
|
+
getInFlightToolCount,
|
|
12
|
+
getOldestInFlightToolStart,
|
|
13
|
+
getOldestInFlightToolAgeMs,
|
|
14
|
+
clearInFlightTools,
|
|
15
|
+
} from "../auto-tool-tracking.ts";
|
|
16
|
+
|
|
17
|
+
// These tests call the tracking module directly (bypassing the auto.ts
|
|
18
|
+
// wrapper which guards on s.active) so we always pass isActive=true.
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
clearInFlightTools();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("hasInteractiveToolInFlight", () => {
|
|
25
|
+
test("returns false when no tools are in-flight", () => {
|
|
26
|
+
assert.equal(hasInteractiveToolInFlight(), false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("returns false when only non-interactive tools are in-flight", () => {
|
|
30
|
+
markToolStart("call-1", true, "bash");
|
|
31
|
+
markToolStart("call-2", true, "read");
|
|
32
|
+
assert.equal(hasInteractiveToolInFlight(), false);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("returns true when ask_user_questions is in-flight", () => {
|
|
36
|
+
markToolStart("call-1", true, "bash");
|
|
37
|
+
markToolStart("call-2", true, "ask_user_questions");
|
|
38
|
+
assert.equal(hasInteractiveToolInFlight(), true);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("returns true when secure_env_collect is in-flight", () => {
|
|
42
|
+
markToolStart("call-1", true, "secure_env_collect");
|
|
43
|
+
assert.equal(hasInteractiveToolInFlight(), true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("returns false after interactive tool completes", () => {
|
|
47
|
+
markToolStart("call-1", true, "ask_user_questions");
|
|
48
|
+
assert.equal(hasInteractiveToolInFlight(), true);
|
|
49
|
+
markToolEnd("call-1");
|
|
50
|
+
assert.equal(hasInteractiveToolInFlight(), false);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("returns true if one of multiple tools is interactive", () => {
|
|
54
|
+
markToolStart("call-1", true, "bash");
|
|
55
|
+
markToolStart("call-2", true, "edit");
|
|
56
|
+
markToolStart("call-3", true, "ask_user_questions");
|
|
57
|
+
markToolStart("call-4", true, "write");
|
|
58
|
+
assert.equal(hasInteractiveToolInFlight(), true);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("toolName tracking in markToolStart", () => {
|
|
63
|
+
test("defaults toolName to 'unknown' when not provided", () => {
|
|
64
|
+
markToolStart("call-1", true);
|
|
65
|
+
// unknown tool should not be treated as interactive
|
|
66
|
+
assert.equal(hasInteractiveToolInFlight(), false);
|
|
67
|
+
assert.equal(getInFlightToolCount(), 1);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("no-ops when isActive is false", () => {
|
|
71
|
+
markToolStart("call-1", false, "ask_user_questions");
|
|
72
|
+
assert.equal(getInFlightToolCount(), 0);
|
|
73
|
+
assert.equal(hasInteractiveToolInFlight(), false);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("existing tracking behavior preserved with toolName", () => {
|
|
78
|
+
test("getInFlightToolCount tracks correctly", () => {
|
|
79
|
+
assert.equal(getInFlightToolCount(), 0);
|
|
80
|
+
markToolStart("call-1", true, "bash");
|
|
81
|
+
assert.equal(getInFlightToolCount(), 1);
|
|
82
|
+
markToolStart("call-2", true, "ask_user_questions");
|
|
83
|
+
assert.equal(getInFlightToolCount(), 2);
|
|
84
|
+
markToolEnd("call-1");
|
|
85
|
+
assert.equal(getInFlightToolCount(), 1);
|
|
86
|
+
markToolEnd("call-2");
|
|
87
|
+
assert.equal(getInFlightToolCount(), 0);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("getOldestInFlightToolStart returns correct timestamp", () => {
|
|
91
|
+
assert.equal(getOldestInFlightToolStart(), undefined);
|
|
92
|
+
const before = Date.now();
|
|
93
|
+
markToolStart("call-1", true, "bash");
|
|
94
|
+
const after = Date.now();
|
|
95
|
+
const oldest = getOldestInFlightToolStart();
|
|
96
|
+
assert.ok(oldest !== undefined);
|
|
97
|
+
assert.ok(oldest! >= before && oldest! <= after);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("getOldestInFlightToolAgeMs returns 0 with no tools", () => {
|
|
101
|
+
assert.equal(getOldestInFlightToolAgeMs(), 0);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("getOldestInFlightToolAgeMs returns positive value with tools", () => {
|
|
105
|
+
markToolStart("call-1", true, "read");
|
|
106
|
+
const age = getOldestInFlightToolAgeMs();
|
|
107
|
+
assert.ok(age >= 0, `age should be non-negative, got ${age}`);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("clearInFlightTools resets all state", () => {
|
|
111
|
+
markToolStart("call-1", true, "ask_user_questions");
|
|
112
|
+
markToolStart("call-2", true, "bash");
|
|
113
|
+
assert.equal(getInFlightToolCount(), 2);
|
|
114
|
+
assert.equal(hasInteractiveToolInFlight(), true);
|
|
115
|
+
clearInFlightTools();
|
|
116
|
+
assert.equal(getInFlightToolCount(), 0);
|
|
117
|
+
assert.equal(hasInteractiveToolInFlight(), false);
|
|
118
|
+
});
|
|
119
|
+
});
|