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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for #2203: rewrite-docs circuit breaker must persist
|
|
3
|
+
* across session restarts.
|
|
4
|
+
*
|
|
5
|
+
* The rewrite attempt counter was stored in-memory on the session object,
|
|
6
|
+
* resetting to 0 on every session restart. This allowed the rewrite-docs
|
|
7
|
+
* dispatch rule to fire indefinitely, never tripping the MAX_REWRITE_ATTEMPTS
|
|
8
|
+
* circuit breaker.
|
|
9
|
+
*
|
|
10
|
+
* The fix persists the counter to `.gsd/runtime/rewrite-count.json`.
|
|
11
|
+
*/
|
|
12
|
+
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
13
|
+
import assert from "node:assert/strict";
|
|
14
|
+
import { mkdirSync, existsSync, readFileSync, writeFileSync, rmSync, mkdtempSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
|
|
18
|
+
import { getRewriteCount, setRewriteCount } from "../auto-dispatch.ts";
|
|
19
|
+
|
|
20
|
+
describe("rewrite-docs circuit breaker persistence (#2203)", () => {
|
|
21
|
+
let tempBase: string;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
tempBase = mkdtempSync(join(tmpdir(), "gsd-rewrite-test-"));
|
|
25
|
+
// Create .gsd/ directory so gsdRoot resolves to it
|
|
26
|
+
mkdirSync(join(tempBase, ".gsd", "runtime"), { recursive: true });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
rmSync(tempBase, { recursive: true, force: true });
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("getRewriteCount returns 0 when no file exists", () => {
|
|
34
|
+
const count = getRewriteCount(tempBase);
|
|
35
|
+
assert.equal(count, 0);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("setRewriteCount writes and getRewriteCount reads back", () => {
|
|
39
|
+
setRewriteCount(tempBase, 2);
|
|
40
|
+
const count = getRewriteCount(tempBase);
|
|
41
|
+
assert.equal(count, 2);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("counter persists across simulated session restarts", () => {
|
|
45
|
+
// Session 1: increment to 1
|
|
46
|
+
setRewriteCount(tempBase, 1);
|
|
47
|
+
|
|
48
|
+
// "Session restart" — only the disk file survives, session object is gone
|
|
49
|
+
const countAfterRestart = getRewriteCount(tempBase);
|
|
50
|
+
assert.equal(countAfterRestart, 1, "counter should survive session restart");
|
|
51
|
+
|
|
52
|
+
// Session 2: increment to 2
|
|
53
|
+
setRewriteCount(tempBase, countAfterRestart + 1);
|
|
54
|
+
assert.equal(getRewriteCount(tempBase), 2);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("setRewriteCount(0) resets the counter", () => {
|
|
58
|
+
setRewriteCount(tempBase, 3);
|
|
59
|
+
assert.equal(getRewriteCount(tempBase), 3);
|
|
60
|
+
|
|
61
|
+
setRewriteCount(tempBase, 0);
|
|
62
|
+
assert.equal(getRewriteCount(tempBase), 0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("getRewriteCount handles corrupt JSON gracefully", () => {
|
|
66
|
+
const filePath = join(tempBase, ".gsd", "runtime", "rewrite-count.json");
|
|
67
|
+
// writeFileSync is imported at the top of this file
|
|
68
|
+
writeFileSync(filePath, "not json{{{");
|
|
69
|
+
const count = getRewriteCount(tempBase);
|
|
70
|
+
assert.equal(count, 0, "corrupt file should return 0");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("rewrite-count.json is written to .gsd/runtime/", () => {
|
|
74
|
+
setRewriteCount(tempBase, 1);
|
|
75
|
+
const filePath = join(tempBase, ".gsd", "runtime", "rewrite-count.json");
|
|
76
|
+
assert.ok(existsSync(filePath), "rewrite-count.json should exist");
|
|
77
|
+
|
|
78
|
+
const content = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
79
|
+
assert.equal(content.count, 1);
|
|
80
|
+
assert.ok(content.updatedAt, "should include timestamp");
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -460,4 +460,150 @@ test('(n) stale replay guard', async () => {
|
|
|
460
460
|
}
|
|
461
461
|
});
|
|
462
462
|
|
|
463
|
+
test('(q) verdict in ASSESSMENT file skips UAT dispatch (file-based path)', async () => {
|
|
464
|
+
// Regression test for #2644: run-uat prompt writes the verdict to
|
|
465
|
+
// S{sid}-ASSESSMENT.md (via gsd_summary_save artifact_type:"ASSESSMENT"),
|
|
466
|
+
// but checkNeedsRunUat only checked S{sid}-UAT.md — causing a stuck loop.
|
|
467
|
+
const base = createFixtureBase();
|
|
468
|
+
try {
|
|
469
|
+
const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
|
|
470
|
+
mkdirSync(roadmapDir, { recursive: true });
|
|
471
|
+
writeFileSync(
|
|
472
|
+
join(roadmapDir, 'M001-ROADMAP.md'),
|
|
473
|
+
[
|
|
474
|
+
'# M001: Test roadmap',
|
|
475
|
+
'',
|
|
476
|
+
'## Slices',
|
|
477
|
+
'',
|
|
478
|
+
'- [x] **S01: First slice** `risk:low` `depends:[]`',
|
|
479
|
+
'- [ ] **S02: Next slice** `risk:low` `depends:[S01]`',
|
|
480
|
+
'',
|
|
481
|
+
'## Boundary Map',
|
|
482
|
+
'',
|
|
483
|
+
].join('\n'),
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
// UAT spec file WITHOUT a verdict (the spec never gets one)
|
|
487
|
+
writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('artifact-driven'));
|
|
488
|
+
// ASSESSMENT file WITH a verdict (where run-uat actually writes it)
|
|
489
|
+
writeSliceFile(base, 'M001', 'S01', 'ASSESSMENT', '---\nverdict: PASS\n---\n# UAT Assessment\n');
|
|
490
|
+
|
|
491
|
+
const state = {
|
|
492
|
+
activeMilestone: { id: 'M001', title: 'Test roadmap' },
|
|
493
|
+
activeSlice: { id: 'S02', title: 'Next slice' },
|
|
494
|
+
activeTask: null,
|
|
495
|
+
phase: 'planning',
|
|
496
|
+
recentDecisions: [],
|
|
497
|
+
blockers: [],
|
|
498
|
+
nextAction: 'Plan S02',
|
|
499
|
+
registry: [],
|
|
500
|
+
} as const;
|
|
501
|
+
|
|
502
|
+
const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
|
|
503
|
+
assert.deepStrictEqual(
|
|
504
|
+
result,
|
|
505
|
+
null,
|
|
506
|
+
'verdict in ASSESSMENT file should prevent re-dispatch of run-uat',
|
|
507
|
+
);
|
|
508
|
+
} finally {
|
|
509
|
+
cleanup(base);
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
test('(r) no ASSESSMENT file still dispatches UAT (no false skip)', async () => {
|
|
514
|
+
// Guard: when there is no ASSESSMENT file at all, UAT should still dispatch
|
|
515
|
+
// normally. The ASSESSMENT check must not cause a false-negative skip.
|
|
516
|
+
const base = createFixtureBase();
|
|
517
|
+
try {
|
|
518
|
+
const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
|
|
519
|
+
mkdirSync(roadmapDir, { recursive: true });
|
|
520
|
+
writeFileSync(
|
|
521
|
+
join(roadmapDir, 'M001-ROADMAP.md'),
|
|
522
|
+
[
|
|
523
|
+
'# M001: Test roadmap',
|
|
524
|
+
'',
|
|
525
|
+
'## Slices',
|
|
526
|
+
'',
|
|
527
|
+
'- [x] **S01: First slice** `risk:low` `depends:[]`',
|
|
528
|
+
'- [ ] **S02: Next slice** `risk:low` `depends:[S01]`',
|
|
529
|
+
'',
|
|
530
|
+
'## Boundary Map',
|
|
531
|
+
'',
|
|
532
|
+
].join('\n'),
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
// UAT spec file WITHOUT a verdict, and NO ASSESSMENT file
|
|
536
|
+
writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('artifact-driven'));
|
|
537
|
+
|
|
538
|
+
const state = {
|
|
539
|
+
activeMilestone: { id: 'M001', title: 'Test roadmap' },
|
|
540
|
+
activeSlice: { id: 'S02', title: 'Next slice' },
|
|
541
|
+
activeTask: null,
|
|
542
|
+
phase: 'planning',
|
|
543
|
+
recentDecisions: [],
|
|
544
|
+
blockers: [],
|
|
545
|
+
nextAction: 'Plan S02',
|
|
546
|
+
registry: [],
|
|
547
|
+
} as const;
|
|
548
|
+
|
|
549
|
+
const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
|
|
550
|
+
assert.deepStrictEqual(
|
|
551
|
+
result,
|
|
552
|
+
{ sliceId: 'S01', uatType: 'artifact-driven' },
|
|
553
|
+
'without ASSESSMENT file, UAT still dispatches normally',
|
|
554
|
+
);
|
|
555
|
+
} finally {
|
|
556
|
+
cleanup(base);
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
test('(s) ASSESSMENT without verdict does not skip UAT dispatch', async () => {
|
|
561
|
+
// Guard: an ASSESSMENT file that exists but has no verdict line should
|
|
562
|
+
// NOT suppress UAT dispatch — only a file with an actual verdict should.
|
|
563
|
+
const base = createFixtureBase();
|
|
564
|
+
try {
|
|
565
|
+
const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
|
|
566
|
+
mkdirSync(roadmapDir, { recursive: true });
|
|
567
|
+
writeFileSync(
|
|
568
|
+
join(roadmapDir, 'M001-ROADMAP.md'),
|
|
569
|
+
[
|
|
570
|
+
'# M001: Test roadmap',
|
|
571
|
+
'',
|
|
572
|
+
'## Slices',
|
|
573
|
+
'',
|
|
574
|
+
'- [x] **S01: First slice** `risk:low` `depends:[]`',
|
|
575
|
+
'- [ ] **S02: Next slice** `risk:low` `depends:[S01]`',
|
|
576
|
+
'',
|
|
577
|
+
'## Boundary Map',
|
|
578
|
+
'',
|
|
579
|
+
].join('\n'),
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
// UAT spec WITHOUT verdict
|
|
583
|
+
writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('artifact-driven'));
|
|
584
|
+
// ASSESSMENT file WITHOUT verdict (partial/incomplete assessment)
|
|
585
|
+
writeSliceFile(base, 'M001', 'S01', 'ASSESSMENT', '# UAT Assessment\n\nStill running checks...\n');
|
|
586
|
+
|
|
587
|
+
const state = {
|
|
588
|
+
activeMilestone: { id: 'M001', title: 'Test roadmap' },
|
|
589
|
+
activeSlice: { id: 'S02', title: 'Next slice' },
|
|
590
|
+
activeTask: null,
|
|
591
|
+
phase: 'planning',
|
|
592
|
+
recentDecisions: [],
|
|
593
|
+
blockers: [],
|
|
594
|
+
nextAction: 'Plan S02',
|
|
595
|
+
registry: [],
|
|
596
|
+
} as const;
|
|
597
|
+
|
|
598
|
+
const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
|
|
599
|
+
assert.deepStrictEqual(
|
|
600
|
+
result,
|
|
601
|
+
{ sliceId: 'S01', uatType: 'artifact-driven' },
|
|
602
|
+
'ASSESSMENT without verdict should not suppress UAT dispatch',
|
|
603
|
+
);
|
|
604
|
+
} finally {
|
|
605
|
+
cleanup(base);
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
|
|
463
609
|
});
|
|
@@ -113,12 +113,12 @@ test("postUnitPostVerification pushes to sidecarQueue for hooks", () => {
|
|
|
113
113
|
assert.ok(triageSectionStart > -1, "auto-post-unit.ts must have a triage check section");
|
|
114
114
|
const hookSection = source.slice(hookSectionStart, triageSectionStart);
|
|
115
115
|
assert.ok(
|
|
116
|
-
hookSection.includes("s.sidecarQueue.push("),
|
|
117
|
-
"hook section must
|
|
116
|
+
hookSection.includes("enqueueSidecar(") || hookSection.includes("s.sidecarQueue.push("),
|
|
117
|
+
"hook section must enqueue to sidecarQueue (via enqueueSidecar or direct push)",
|
|
118
118
|
);
|
|
119
119
|
assert.ok(
|
|
120
|
-
hookSection.includes('
|
|
121
|
-
"hook sidecar item must
|
|
120
|
+
hookSection.includes('"hook"'),
|
|
121
|
+
"hook sidecar item must reference kind 'hook'",
|
|
122
122
|
);
|
|
123
123
|
});
|
|
124
124
|
|
|
@@ -132,12 +132,12 @@ test("postUnitPostVerification pushes to sidecarQueue for triage", () => {
|
|
|
132
132
|
assert.ok(quickTaskSectionStart > -1, "auto-post-unit.ts must have a quick-task dispatch section");
|
|
133
133
|
const triageSection = source.slice(triageSectionStart, quickTaskSectionStart);
|
|
134
134
|
assert.ok(
|
|
135
|
-
triageSection.includes("s.sidecarQueue.push("),
|
|
136
|
-
"triage section must
|
|
135
|
+
triageSection.includes("enqueueSidecar(") || triageSection.includes("s.sidecarQueue.push("),
|
|
136
|
+
"triage section must enqueue to sidecarQueue (via enqueueSidecar or direct push)",
|
|
137
137
|
);
|
|
138
138
|
assert.ok(
|
|
139
|
-
triageSection.includes('
|
|
140
|
-
"triage sidecar item must
|
|
139
|
+
triageSection.includes('"triage"'),
|
|
140
|
+
"triage sidecar item must reference kind 'triage'",
|
|
141
141
|
);
|
|
142
142
|
});
|
|
143
143
|
|
|
@@ -149,12 +149,12 @@ test("postUnitPostVerification pushes to sidecarQueue for quick-tasks", () => {
|
|
|
149
149
|
assert.ok(quickTaskSectionStart > -1, "auto-post-unit.ts must have a quick-task dispatch section");
|
|
150
150
|
const quickTaskSection = source.slice(quickTaskSectionStart);
|
|
151
151
|
assert.ok(
|
|
152
|
-
quickTaskSection.includes("s.sidecarQueue.push("),
|
|
153
|
-
"quick-task section must
|
|
152
|
+
quickTaskSection.includes("enqueueSidecar(") || quickTaskSection.includes("s.sidecarQueue.push("),
|
|
153
|
+
"quick-task section must enqueue to sidecarQueue (via enqueueSidecar or direct push)",
|
|
154
154
|
);
|
|
155
155
|
assert.ok(
|
|
156
|
-
quickTaskSection.includes('
|
|
157
|
-
"quick-task sidecar item must
|
|
156
|
+
quickTaskSection.includes('"quick-task"'),
|
|
157
|
+
"quick-task sidecar item must reference kind 'quick-task'",
|
|
158
158
|
);
|
|
159
159
|
});
|
|
160
160
|
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for GSD Skill Catalog — pack matching logic.
|
|
3
|
+
*
|
|
4
|
+
* Exercises matchPacksForProject() to verify that project signals
|
|
5
|
+
* correctly map to skill packs.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import test from "node:test";
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { PROJECT_FILES } from "../detection.ts";
|
|
11
|
+
import { GREENFIELD_STACKS, SKILL_CATALOG, matchPacksForProject } from "../skill-catalog.ts";
|
|
12
|
+
import type { ProjectSignals } from "../detection.ts";
|
|
13
|
+
|
|
14
|
+
function makeSignals(overrides: Partial<ProjectSignals> = {}): ProjectSignals {
|
|
15
|
+
return {
|
|
16
|
+
detectedFiles: [],
|
|
17
|
+
isGitRepo: false,
|
|
18
|
+
isMonorepo: false,
|
|
19
|
+
xcodePlatforms: [],
|
|
20
|
+
hasCI: false,
|
|
21
|
+
hasTests: false,
|
|
22
|
+
verificationCommands: [],
|
|
23
|
+
...overrides,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function packLabels(signals: ProjectSignals): string[] {
|
|
28
|
+
return matchPacksForProject(signals).map((p) => p.label);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ── matchAlways packs are always included ────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
test("matchPacksForProject: always includes matchAlways packs", () => {
|
|
34
|
+
const labels = packLabels(makeSignals());
|
|
35
|
+
assert.ok(labels.includes("Skill Discovery"), "should include Skill Discovery");
|
|
36
|
+
assert.ok(labels.includes("Skill Authoring"), "should include Skill Authoring");
|
|
37
|
+
assert.ok(labels.includes("Browser Automation"), "should include Browser Automation");
|
|
38
|
+
assert.ok(labels.includes("Document Handling"), "should include Document Handling");
|
|
39
|
+
assert.ok(labels.includes("Code Review & Quality"), "should include Code Review & Quality");
|
|
40
|
+
assert.ok(labels.includes("Git Advanced Workflows"), "should include Git Advanced Workflows");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// ── Language matching ────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
test("matchPacksForProject: Python language matches Python packs", () => {
|
|
46
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "python", detectedFiles: ["pyproject.toml"] }));
|
|
47
|
+
assert.ok(labels.includes("Python"), "should include Python");
|
|
48
|
+
assert.ok(labels.includes("Python Advanced"), "should include Python Advanced");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("matchPacksForProject: Rust language matches Rust packs", () => {
|
|
52
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "rust", detectedFiles: ["Cargo.toml"] }));
|
|
53
|
+
assert.ok(labels.includes("Rust"), "should include Rust");
|
|
54
|
+
assert.ok(labels.includes("Rust Async Patterns"), "should include Rust Async Patterns");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("matchPacksForProject: Go language matches Go packs", () => {
|
|
58
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "go", detectedFiles: ["go.mod"] }));
|
|
59
|
+
assert.ok(labels.includes("Go"), "should include Go");
|
|
60
|
+
assert.ok(labels.includes("Go Concurrency Patterns"), "should include Go Concurrency Patterns");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("matchPacksForProject: JS/TS matches web frontend packs", () => {
|
|
64
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "javascript/typescript", detectedFiles: ["package.json"] }));
|
|
65
|
+
assert.ok(labels.includes("React & Web Frontend"), "should include React");
|
|
66
|
+
assert.ok(labels.includes("TypeScript & JS Development"), "should include TS/JS Dev");
|
|
67
|
+
assert.ok(labels.includes("React State & Patterns"), "should include React State");
|
|
68
|
+
assert.ok(labels.includes("shadcn/ui"), "should include shadcn");
|
|
69
|
+
assert.ok(labels.includes("Frontend Design & UX"), "should include Frontend Design");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// ── File matching ────────────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
test("matchPacksForProject: angular.json triggers Angular packs", () => {
|
|
75
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["angular.json"] }));
|
|
76
|
+
assert.ok(labels.includes("Angular"), "should include Angular");
|
|
77
|
+
assert.ok(labels.includes("Angular Migration"), "should include Angular Migration");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("matchPacksForProject: next.config.ts triggers Next.js packs", () => {
|
|
81
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["next.config.ts"] }));
|
|
82
|
+
assert.ok(labels.includes("Next.js"), "should include Next.js");
|
|
83
|
+
assert.ok(labels.includes("Next.js App Router Patterns"), "should include Next.js App Router");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("matchPacksForProject: *.vue triggers Vue.js", () => {
|
|
87
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["*.vue"] }));
|
|
88
|
+
assert.ok(labels.includes("Vue.js"), "should include Vue.js");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("matchPacksForProject: Chart.yaml triggers Kubernetes", () => {
|
|
92
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["Chart.yaml"] }));
|
|
93
|
+
assert.ok(labels.includes("Kubernetes"), "should include Kubernetes");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("matchPacksForProject: hardhat.config.ts triggers Blockchain", () => {
|
|
97
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["hardhat.config.ts"] }));
|
|
98
|
+
assert.ok(labels.includes("Blockchain & Web3"), "should include Blockchain & Web3");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("matchPacksForProject: tailwind.config.ts triggers Tailwind CSS", () => {
|
|
102
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["tailwind.config.ts"] }));
|
|
103
|
+
assert.ok(labels.includes("Tailwind CSS"), "should include Tailwind CSS");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// ── Xcode platform matching ─────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
test("matchPacksForProject: iphoneos triggers iOS packs", () => {
|
|
109
|
+
const labels = packLabels(makeSignals({ xcodePlatforms: ["iphoneos"] }));
|
|
110
|
+
assert.ok(labels.includes("iOS App Frameworks"), "should include iOS App Frameworks");
|
|
111
|
+
assert.ok(labels.includes("iOS Data Frameworks"), "should include iOS Data Frameworks");
|
|
112
|
+
assert.ok(labels.includes("iOS AI & ML"), "should include iOS AI & ML");
|
|
113
|
+
assert.ok(labels.includes("iOS Engineering"), "should include iOS Engineering");
|
|
114
|
+
assert.ok(labels.includes("iOS Hardware"), "should include iOS Hardware");
|
|
115
|
+
assert.ok(labels.includes("iOS Platform"), "should include iOS Platform");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// ── Isolation checks — packs that should NOT match ──────────────────────────
|
|
119
|
+
|
|
120
|
+
test("matchPacksForProject: FastAPI does not match generic Python", () => {
|
|
121
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "python", detectedFiles: ["pyproject.toml"] }));
|
|
122
|
+
assert.ok(!labels.includes("FastAPI"), "FastAPI should NOT match generic Python projects");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("matchPacksForProject: FastAPI matches when dep:fastapi detected", () => {
|
|
126
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "python", detectedFiles: ["pyproject.toml", "dep:fastapi"] }));
|
|
127
|
+
assert.ok(labels.includes("FastAPI"), "FastAPI should match when dep:fastapi is in detectedFiles");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("matchPacksForProject: Spring Boot does not match via language alone", () => {
|
|
131
|
+
// Simulate Android project: has java/kotlin language but no root pom.xml/build.gradle
|
|
132
|
+
const labels = packLabels(makeSignals({ primaryLanguage: "java/kotlin", detectedFiles: ["app/build.gradle"] }));
|
|
133
|
+
assert.ok(!labels.includes("Java & Spring Boot"), "Spring Boot should NOT match via language alone");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("matchPacksForProject: Spring Boot matches only dep:spring-boot", () => {
|
|
137
|
+
const positive = packLabels(makeSignals({ detectedFiles: ["dep:spring-boot"] }));
|
|
138
|
+
assert.ok(positive.includes("Java & Spring Boot"), "should include Spring Boot pack when dependency marker exists");
|
|
139
|
+
|
|
140
|
+
const androidLike = packLabels(makeSignals({ detectedFiles: ["build.gradle", "app/build.gradle"], primaryLanguage: "java/kotlin" }));
|
|
141
|
+
assert.ok(!androidLike.includes("Java & Spring Boot"), "generic Gradle + Android markers should not imply Spring Boot");
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("matchPacksForProject: Unity does not include Godot", () => {
|
|
145
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["ProjectSettings/ProjectVersion.txt"] }));
|
|
146
|
+
assert.ok(labels.includes("Unity"), "should include Unity");
|
|
147
|
+
assert.ok(!labels.includes("Godot"), "should NOT include Godot");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("matchPacksForProject: Godot does not include Unity", () => {
|
|
151
|
+
const labels = packLabels(makeSignals({ detectedFiles: ["project.godot"] }));
|
|
152
|
+
assert.ok(labels.includes("Godot"), "should include Godot");
|
|
153
|
+
assert.ok(!labels.includes("Unity"), "should NOT include Unity");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("matchPacksForProject: .NET backend patterns match F# and solution markers", () => {
|
|
157
|
+
const fsprojLabels = packLabels(makeSignals({ detectedFiles: ["*.fsproj"], primaryLanguage: "fsharp" }));
|
|
158
|
+
assert.ok(fsprojLabels.includes(".NET Backend Patterns"), "should include generic .NET backend patterns for F# projects");
|
|
159
|
+
assert.ok(!fsprojLabels.includes(".NET & C#"), "should not include C#-specific pack for F# projects");
|
|
160
|
+
|
|
161
|
+
const slnLabels = packLabels(makeSignals({ detectedFiles: ["*.sln"], primaryLanguage: "dotnet" }));
|
|
162
|
+
assert.ok(slnLabels.includes(".NET Backend Patterns"), "should include generic .NET backend patterns for solution files");
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test("SKILL_CATALOG: every matchFiles entry is backed by detection", () => {
|
|
166
|
+
const knownMarkers = new Set<string>([
|
|
167
|
+
...PROJECT_FILES,
|
|
168
|
+
"*.sqlite",
|
|
169
|
+
"*.sql",
|
|
170
|
+
"*.csproj",
|
|
171
|
+
"*.fsproj",
|
|
172
|
+
"*.sln",
|
|
173
|
+
"*.vue",
|
|
174
|
+
"dep:fastapi",
|
|
175
|
+
"dep:spring-boot",
|
|
176
|
+
]);
|
|
177
|
+
|
|
178
|
+
for (const pack of SKILL_CATALOG) {
|
|
179
|
+
for (const marker of pack.matchFiles ?? []) {
|
|
180
|
+
assert.ok(knownMarkers.has(marker), `Unknown detection marker: ${marker} (pack: ${pack.label})`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("GREENFIELD_STACKS: every pack label resolves to SKILL_CATALOG", () => {
|
|
186
|
+
const labels = new Set(SKILL_CATALOG.map((pack) => pack.label));
|
|
187
|
+
|
|
188
|
+
for (const stack of GREENFIELD_STACKS) {
|
|
189
|
+
for (const packLabel of stack.packs) {
|
|
190
|
+
assert.ok(labels.has(packLabel), `Unknown pack label: ${packLabel} (stack: ${stack.id})`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
@@ -1,49 +1,84 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* terminated-transient.test.ts — Regression test for #2309.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* classifyError should treat 'terminated' errors (process killed,
|
|
5
5
|
* connection reset) as transient with auto-resume, not permanent.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import test from "node:test";
|
|
9
9
|
import assert from "node:assert/strict";
|
|
10
|
-
import {
|
|
10
|
+
import { classifyError, isTransient } from "../error-classifier.ts";
|
|
11
11
|
|
|
12
12
|
test("#2309: 'terminated' errors should be classified as transient", () => {
|
|
13
|
-
const result =
|
|
14
|
-
assert.equal(result
|
|
15
|
-
assert.equal(result.
|
|
16
|
-
assert.ok(result.
|
|
13
|
+
const result = classifyError("terminated");
|
|
14
|
+
assert.equal(isTransient(result), true, "'terminated' should be transient");
|
|
15
|
+
assert.equal(result.kind, "connection", "'terminated' matches connection");
|
|
16
|
+
assert.ok("retryAfterMs" in result && result.retryAfterMs > 0, "'terminated' should have a retry delay");
|
|
17
|
+
assert.equal("retryAfterMs" in result && result.retryAfterMs, 15_000, "'terminated' should use 15s backoff");
|
|
17
18
|
});
|
|
18
19
|
|
|
19
|
-
test("#2309: 'connection reset' errors should be classified as transient", () => {
|
|
20
|
-
const result =
|
|
21
|
-
assert.equal(result
|
|
20
|
+
test("#2309: 'connection reset by peer' errors should be classified as transient (network)", () => {
|
|
21
|
+
const result = classifyError("connection reset by peer");
|
|
22
|
+
assert.equal(isTransient(result), true, "'connection reset by peer' should be transient");
|
|
23
|
+
assert.equal(result.kind, "network", "'connection reset by peer' matches NETWORK_RE (connection.*reset) before CONNECTION_RE");
|
|
24
|
+
assert.equal("retryAfterMs" in result && result.retryAfterMs, 3_000, "network errors use 3s backoff");
|
|
22
25
|
});
|
|
23
26
|
|
|
24
27
|
test("#2309: 'other side closed' errors should be classified as transient", () => {
|
|
25
|
-
const result =
|
|
26
|
-
assert.equal(result
|
|
28
|
+
const result = classifyError("other side closed the connection");
|
|
29
|
+
assert.equal(isTransient(result), true, "'other side closed' should be transient");
|
|
30
|
+
assert.equal(result.kind, "connection", "'other side closed' matches CONNECTION_RE");
|
|
27
31
|
});
|
|
28
32
|
|
|
29
33
|
test("#2309: 'fetch failed' errors should be classified as transient", () => {
|
|
30
|
-
const result =
|
|
31
|
-
assert.equal(result
|
|
34
|
+
const result = classifyError("fetch failed: network error");
|
|
35
|
+
assert.equal(isTransient(result), true, "'fetch failed' should be transient");
|
|
36
|
+
assert.equal(result.kind, "network", "'fetch failed' matches NETWORK_RE");
|
|
37
|
+
assert.equal("retryAfterMs" in result && result.retryAfterMs, 3_000, "network errors use 3s backoff");
|
|
32
38
|
});
|
|
33
39
|
|
|
34
40
|
test("#2309: 'connection refused' errors should be classified as transient", () => {
|
|
35
|
-
const result =
|
|
36
|
-
assert.equal(result
|
|
41
|
+
const result = classifyError("ECONNREFUSED: connection refused");
|
|
42
|
+
assert.equal(isTransient(result), true, "'connection refused' should be transient");
|
|
43
|
+
assert.equal(result.kind, "network", "'ECONNREFUSED' matches NETWORK_RE (same-model retry)");
|
|
37
44
|
});
|
|
38
45
|
|
|
39
46
|
test("#2309: permanent errors are still permanent", () => {
|
|
40
|
-
const authResult =
|
|
41
|
-
assert.equal(authResult
|
|
42
|
-
assert.equal(authResult.
|
|
47
|
+
const authResult = classifyError("unauthorized: invalid API key");
|
|
48
|
+
assert.equal(isTransient(authResult), false, "auth errors should stay permanent");
|
|
49
|
+
assert.equal(authResult.kind, "permanent", "auth errors are permanent");
|
|
50
|
+
assert.equal("retryAfterMs" in authResult, false, "permanent errors have no retryAfterMs");
|
|
43
51
|
});
|
|
44
52
|
|
|
45
53
|
test("#2309: rate limits are still transient", () => {
|
|
46
|
-
const rlResult =
|
|
47
|
-
assert.equal(rlResult
|
|
48
|
-
assert.equal(rlResult.
|
|
54
|
+
const rlResult = classifyError("rate limit exceeded (429)");
|
|
55
|
+
assert.equal(isTransient(rlResult), true, "rate limits are still transient");
|
|
56
|
+
assert.equal(rlResult.kind, "rate-limit", "rate limits are flagged as rate-limit kind");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// --- #2572: stream-truncation JSON parse errors should be transient ---
|
|
60
|
+
|
|
61
|
+
test("#2572: 'Expected double-quoted property name' (truncated stream) is transient", () => {
|
|
62
|
+
const result = classifyError("Expected double-quoted property name in JSON at position 23 (line 1 column 24)");
|
|
63
|
+
assert.equal(isTransient(result), true, "truncated-stream JSON parse error should be transient");
|
|
64
|
+
assert.equal(result.kind, "stream", "JSON parse errors are stream kind");
|
|
65
|
+
assert.equal("retryAfterMs" in result && result.retryAfterMs, 15_000, "should use 15s backoff");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("#2572: 'Unexpected end of JSON input' (truncated stream) is transient", () => {
|
|
69
|
+
const result = classifyError("Unexpected end of JSON input");
|
|
70
|
+
assert.equal(isTransient(result), true, "'Unexpected end of JSON input' should be transient");
|
|
71
|
+
assert.equal(result.kind, "stream", "JSON parse errors are stream kind");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("#2572: 'Unexpected token' in JSON (truncated stream) is transient", () => {
|
|
75
|
+
const result = classifyError("Unexpected token < in JSON at position 0");
|
|
76
|
+
assert.equal(isTransient(result), true, "'Unexpected token in JSON' should be transient");
|
|
77
|
+
assert.equal(result.kind, "stream", "JSON parse errors are stream kind");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("#2572: 'SyntaxError' with JSON context (truncated stream) is transient", () => {
|
|
81
|
+
const result = classifyError("SyntaxError: JSON.parse: unexpected character at line 1 column 1");
|
|
82
|
+
assert.equal(isTransient(result), true, "'SyntaxError...JSON' should be transient");
|
|
83
|
+
assert.equal(result.kind, "stream", "JSON parse errors are stream kind");
|
|
49
84
|
});
|
|
@@ -63,13 +63,13 @@ test("show_token_cost defaults to undefined (disabled) when not set", () => {
|
|
|
63
63
|
assert.equal(preferences.show_token_cost, undefined);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
test("empty
|
|
66
|
+
test("empty PREFERENCES.md does not enable show_token_cost", () => {
|
|
67
67
|
const prefs = parsePreferencesMarkdown("---\nversion: 1\n---\n");
|
|
68
68
|
assert.ok(prefs);
|
|
69
69
|
assert.equal(prefs.show_token_cost, undefined);
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
test("
|
|
72
|
+
test("PREFERENCES.md with show_token_cost: true enables the preference", () => {
|
|
73
73
|
const prefs = parsePreferencesMarkdown("---\nshow_token_cost: true\n---\n");
|
|
74
74
|
assert.ok(prefs);
|
|
75
75
|
assert.equal(prefs.show_token_cost, true);
|
|
@@ -119,7 +119,7 @@ test("dispatch: triage dispatch keeps the loop in continue mode", () => {
|
|
|
119
119
|
postUnitSrc.indexOf("// ── Quick-task dispatch"),
|
|
120
120
|
);
|
|
121
121
|
assert.ok(
|
|
122
|
-
triageBlock.includes('return "continue"'),
|
|
122
|
+
triageBlock.includes('return "continue"') || triageBlock.includes("return enqueueSidecar("),
|
|
123
123
|
"triage dispatch should return 'continue' after enqueuing sidecar work",
|
|
124
124
|
);
|
|
125
125
|
});
|
|
@@ -320,7 +320,7 @@ test("dispatch: quick-task dispatch keeps the loop in continue mode", () => {
|
|
|
320
320
|
postUnitSrc.indexOf("if (s.stepMode)"),
|
|
321
321
|
);
|
|
322
322
|
assert.ok(
|
|
323
|
-
quickTaskSection.includes('return "continue"'),
|
|
323
|
+
quickTaskSection.includes('return "continue"') || quickTaskSection.includes("return enqueueSidecar("),
|
|
324
324
|
"quick-task dispatch should return 'continue' after enqueuing sidecar work",
|
|
325
325
|
);
|
|
326
326
|
});
|