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
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
|
-
import {
|
|
13
|
-
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
/** Industry-standard skills.sh global skills directory */
|
|
14
|
+
const SKILLS_DIR = join(homedir(), ".agents", "skills");
|
|
14
15
|
/** Snapshot of skill names at auto-mode start */
|
|
15
16
|
let baselineSkills = null;
|
|
16
17
|
/**
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { existsSync } from "node:fs";
|
|
16
16
|
import { join } from "node:path";
|
|
17
|
-
import {
|
|
17
|
+
import { homedir } from "node:os";
|
|
18
18
|
import { formatCost, formatTokenCount, loadLedgerFromDisk } from "./metrics.js";
|
|
19
19
|
import { detectStaleSkills } from "./skill-telemetry.js";
|
|
20
20
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
@@ -141,7 +141,7 @@ export function formatSkillDetail(basePath, skillName) {
|
|
|
141
141
|
lines.push(` ${date} ${u.id.padEnd(20)} ${formatTokenCount(u.tokens.total).padStart(8)} tokens ${formatCost(u.cost)}`);
|
|
142
142
|
}
|
|
143
143
|
// Check for SKILL.md existence
|
|
144
|
-
const skillPath = join(
|
|
144
|
+
const skillPath = join(homedir(), ".agents", "skills", skillName, "SKILL.md");
|
|
145
145
|
if (existsSync(skillPath)) {
|
|
146
146
|
const stat = require("node:fs").statSync(skillPath);
|
|
147
147
|
lines.push("");
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { existsSync, readdirSync } from "node:fs";
|
|
14
14
|
import { join } from "node:path";
|
|
15
|
-
import {
|
|
15
|
+
import { homedir } from "node:os";
|
|
16
16
|
// ─── In-memory state ──────────────────────────────────────────────────────────
|
|
17
17
|
/** Skills available in the system prompt for the current unit */
|
|
18
18
|
let availableSkills = [];
|
|
@@ -24,8 +24,14 @@ const activelyLoadedSkills = new Set();
|
|
|
24
24
|
* Called before each unit starts.
|
|
25
25
|
*/
|
|
26
26
|
export function captureAvailableSkills() {
|
|
27
|
-
const skillsDir = join(
|
|
28
|
-
|
|
27
|
+
const skillsDir = join(homedir(), ".agents", "skills");
|
|
28
|
+
const legacyDir = join(homedir(), ".gsd", "agent", "skills");
|
|
29
|
+
const names = listSkillNames(skillsDir);
|
|
30
|
+
// Include skills still in the legacy directory only if migration hasn't completed
|
|
31
|
+
const legacyMigrated = existsSync(join(legacyDir, ".migrated-to-agents"));
|
|
32
|
+
const legacyNames = legacyMigrated ? [] : listSkillNames(legacyDir);
|
|
33
|
+
const all = new Set([...names, ...legacyNames]);
|
|
34
|
+
availableSkills = [...all];
|
|
29
35
|
activelyLoadedSkills.clear();
|
|
30
36
|
}
|
|
31
37
|
/**
|
|
@@ -85,8 +91,12 @@ export function detectStaleSkills(units, thresholdDays) {
|
|
|
85
91
|
const cutoff = Date.now() - (thresholdDays * 24 * 60 * 60 * 1000);
|
|
86
92
|
const stale = [];
|
|
87
93
|
// Check all installed skills, not just those with usage data
|
|
88
|
-
const skillsDir = join(
|
|
89
|
-
const
|
|
94
|
+
const skillsDir = join(homedir(), ".agents", "skills");
|
|
95
|
+
const legacyDir = join(homedir(), ".gsd", "agent", "skills");
|
|
96
|
+
const legacyMigrated = existsSync(join(legacyDir, ".migrated-to-agents"));
|
|
97
|
+
const legacyNames = legacyMigrated ? [] : listSkillNames(legacyDir);
|
|
98
|
+
const installedSet = new Set([...listSkillNames(skillsDir), ...legacyNames]);
|
|
99
|
+
const installed = [...installedSet];
|
|
90
100
|
for (const skill of installed) {
|
|
91
101
|
const lastTs = lastUsed.get(skill);
|
|
92
102
|
if (lastTs === undefined || lastTs < cutoff) {
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
import { parseRoadmap, parsePlan, } from './parsers-legacy.js';
|
|
5
5
|
import { parseSummary, loadFile, parseRequirementCounts, parseContextDependsOn, } from './files.js';
|
|
6
6
|
import { resolveMilestoneFile, resolveSlicePath, resolveSliceFile, resolveTaskFile, resolveTasksDir, resolveGsdRootFile, gsdRoot, } from './paths.js';
|
|
7
|
-
import {
|
|
7
|
+
import { findMilestoneIds } from './milestone-ids.js';
|
|
8
|
+
import { loadQueueOrder, sortByQueueOrder } from './queue-order.js';
|
|
8
9
|
import { nativeBatchParseGsdFiles } from './native-parser-bridge.js';
|
|
9
10
|
import { join, resolve } from 'path';
|
|
10
11
|
import { existsSync, readdirSync } from 'node:fs';
|
|
@@ -84,8 +85,14 @@ export async function getActiveMilestoneId(basePath) {
|
|
|
84
85
|
if (isDbAvailable()) {
|
|
85
86
|
const allMilestones = getAllMilestones();
|
|
86
87
|
if (allMilestones.length > 0) {
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
// Respect queue-order.json so /gsd queue reordering is honored (#2556).
|
|
89
|
+
// Without this, the DB path uses lexicographic sort while the dispatch
|
|
90
|
+
// guard uses queue order — causing a deadlock.
|
|
91
|
+
const customOrder = loadQueueOrder(basePath);
|
|
92
|
+
const sortedIds = sortByQueueOrder(allMilestones.map(m => m.id), customOrder);
|
|
93
|
+
const byId = new Map(allMilestones.map(m => [m.id, m]));
|
|
94
|
+
for (const id of sortedIds) {
|
|
95
|
+
const m = byId.get(id);
|
|
89
96
|
if (m.status === "complete" || m.status === "done" || m.status === "parked")
|
|
90
97
|
continue;
|
|
91
98
|
return m.id;
|
|
@@ -137,7 +144,23 @@ export async function deriveState(basePath) {
|
|
|
137
144
|
let result;
|
|
138
145
|
// Dual-path: try DB-backed derivation first when hierarchy tables are populated
|
|
139
146
|
if (isDbAvailable()) {
|
|
140
|
-
|
|
147
|
+
let dbMilestones = getAllMilestones();
|
|
148
|
+
// Disk→DB reconciliation (#2631): when the milestones table is empty
|
|
149
|
+
// (e.g. failed initial migration per #2529), the reconciliation code
|
|
150
|
+
// inside deriveStateFromDb is unreachable. Populate from disk here so
|
|
151
|
+
// the DB path activates correctly.
|
|
152
|
+
if (dbMilestones.length === 0) {
|
|
153
|
+
const diskIds = findMilestoneIds(basePath);
|
|
154
|
+
let synced = false;
|
|
155
|
+
for (const diskId of diskIds) {
|
|
156
|
+
if (!isGhostMilestone(basePath, diskId)) {
|
|
157
|
+
insertMilestone({ id: diskId, status: 'active' });
|
|
158
|
+
synced = true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (synced)
|
|
162
|
+
dbMilestones = getAllMilestones();
|
|
163
|
+
}
|
|
141
164
|
if (dbMilestones.length > 0) {
|
|
142
165
|
const stopDbTimer = debugTime("derive-state-db");
|
|
143
166
|
result = await deriveStateFromDb(basePath);
|
|
@@ -233,8 +256,13 @@ export async function deriveStateFromDb(basePath) {
|
|
|
233
256
|
});
|
|
234
257
|
}
|
|
235
258
|
}
|
|
236
|
-
// Re-sort so milestones
|
|
237
|
-
|
|
259
|
+
// Re-sort so milestones follow queue order (same as dispatch guard) (#2556)
|
|
260
|
+
const customOrder = loadQueueOrder(basePath);
|
|
261
|
+
const sortedIds = sortByQueueOrder(allMilestones.map(m => m.id), customOrder);
|
|
262
|
+
const byId = new Map(allMilestones.map(m => [m.id, m]));
|
|
263
|
+
allMilestones.length = 0;
|
|
264
|
+
for (const id of sortedIds)
|
|
265
|
+
allMilestones.push(byId.get(id));
|
|
238
266
|
// Parallel worker isolation: when locked, filter to just the locked milestone
|
|
239
267
|
const milestoneLock = process.env.GSD_MILESTONE_LOCK;
|
|
240
268
|
const milestones = milestoneLock
|
|
@@ -453,7 +481,10 @@ export async function deriveStateFromDb(basePath) {
|
|
|
453
481
|
};
|
|
454
482
|
}
|
|
455
483
|
// ── All slices done → validating/completing ─────────────────────────
|
|
456
|
-
|
|
484
|
+
// Guard: [].every() === true (vacuous truth). Without the length check,
|
|
485
|
+
// an empty slice array causes a premature phase transition to
|
|
486
|
+
// validating-milestone. See: https://github.com/gsd-build/gsd-2/issues/2667
|
|
487
|
+
const allSlicesDone = activeMilestoneSlices.length > 0 && activeMilestoneSlices.every(s => isStatusDone(s.status));
|
|
457
488
|
if (allSlicesDone) {
|
|
458
489
|
const validationFile = resolveMilestoneFile(basePath, activeMilestone.id, "VALIDATION");
|
|
459
490
|
const validationContent = validationFile ? await loadFile(validationFile) : null;
|
|
@@ -35,6 +35,18 @@ validated_at: {{date}}
|
|
|
35
35
|
|
|
36
36
|
- **{{requirementId}}**: {{status}} — {{disposition: covered by remediation slice / acceptable gap / needs attention}}
|
|
37
37
|
|
|
38
|
+
## Verification Class Compliance
|
|
39
|
+
|
|
40
|
+
<!-- If verification classes were defined during planning, document whether each
|
|
41
|
+
was addressed. Use N/A for classes that were empty or "none" in planning. -->
|
|
42
|
+
|
|
43
|
+
| Class | Planned | Evidence | Status |
|
|
44
|
+
|-------|---------|----------|--------|
|
|
45
|
+
| Contract | {{planned_or_none}} | {{evidence_or_none}} | {{MET / NOT MET / N/A}} |
|
|
46
|
+
| Integration | {{planned_or_none}} | {{evidence_or_none}} | {{MET / NOT MET / N/A}} |
|
|
47
|
+
| Operational | {{planned_or_none}} | {{evidence_or_none}} | {{MET / NOT MET / N/A}} |
|
|
48
|
+
| UAT | {{planned_or_none}} | {{evidence_or_none}} | {{MET / NOT MET / N/A}} |
|
|
49
|
+
|
|
38
50
|
## Remediation Slices
|
|
39
51
|
|
|
40
52
|
<!-- New slices appended to the roadmap to address auto-remediable gaps.
|
|
@@ -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 };
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { mkdirSync } from "node:fs";
|
|
10
|
-
import { transaction, getMilestone, getMilestoneSlices, getSliceTasks,
|
|
10
|
+
import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, updateMilestoneStatus, } from "../gsd-db.js";
|
|
11
11
|
import { resolveMilestonePath, clearPathCache } from "../paths.js";
|
|
12
12
|
import { saveFile, clearParseCache } from "../files.js";
|
|
13
13
|
import { invalidateStateCache } from "../state.js";
|
|
@@ -116,11 +116,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
// All guards passed — perform write
|
|
119
|
-
|
|
120
|
-
adapter.prepare(`UPDATE milestones SET status = 'complete', completed_at = :completed_at WHERE id = :mid`).run({
|
|
121
|
-
":completed_at": completedAt,
|
|
122
|
-
":mid": params.milestoneId,
|
|
123
|
-
});
|
|
119
|
+
updateMilestoneStatus(params.milestoneId, 'complete', completedAt);
|
|
124
120
|
});
|
|
125
121
|
if (guardError) {
|
|
126
122
|
return { error: guardError };
|
|
@@ -144,10 +140,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
144
140
|
catch (renderErr) {
|
|
145
141
|
// Disk render failed — roll back DB status so state stays consistent
|
|
146
142
|
process.stderr.write(`gsd-db: complete_milestone — disk render failed, rolling back DB status: ${renderErr.message}\n`);
|
|
147
|
-
|
|
148
|
-
if (rollbackAdapter) {
|
|
149
|
-
rollbackAdapter.prepare(`UPDATE milestones SET status = 'active', completed_at = NULL WHERE id = :mid`).run({ ":mid": params.milestoneId });
|
|
150
|
-
}
|
|
143
|
+
updateMilestoneStatus(params.milestoneId, 'active', null);
|
|
151
144
|
invalidateStateCache();
|
|
152
145
|
return { error: `disk render failed: ${renderErr.message}` };
|
|
153
146
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { mkdirSync } from "node:fs";
|
|
11
|
-
import { transaction, insertMilestone, insertSlice, getSlice, getSliceTasks, getMilestone, updateSliceStatus,
|
|
11
|
+
import { transaction, insertMilestone, insertSlice, getSlice, getSliceTasks, getMilestone, updateSliceStatus, setSliceSummaryMd, } from "../gsd-db.js";
|
|
12
12
|
import { resolveSlicePath, clearPathCache } from "../paths.js";
|
|
13
13
|
import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
|
|
14
14
|
import { saveFile, clearParseCache } from "../files.js";
|
|
@@ -240,26 +240,12 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
240
240
|
catch (renderErr) {
|
|
241
241
|
// Disk render failed — roll back DB status so state stays consistent
|
|
242
242
|
process.stderr.write(`gsd-db: complete_slice — disk render failed, rolling back DB status: ${renderErr.message}\n`);
|
|
243
|
-
|
|
244
|
-
if (rollbackAdapter) {
|
|
245
|
-
rollbackAdapter.prepare(`UPDATE slices SET status = 'pending' WHERE milestone_id = :mid AND id = :sid`).run({
|
|
246
|
-
":mid": params.milestoneId,
|
|
247
|
-
":sid": params.sliceId,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
243
|
+
updateSliceStatus(params.milestoneId, params.sliceId, 'pending');
|
|
250
244
|
invalidateStateCache();
|
|
251
245
|
return { error: `disk render failed: ${renderErr.message}` };
|
|
252
246
|
}
|
|
253
247
|
// Store rendered markdown in DB for D004 recovery
|
|
254
|
-
|
|
255
|
-
if (adapter) {
|
|
256
|
-
adapter.prepare(`UPDATE slices SET full_summary_md = :summary_md, full_uat_md = :uat_md WHERE milestone_id = :mid AND id = :sid`).run({
|
|
257
|
-
":summary_md": summaryMd,
|
|
258
|
-
":uat_md": uatMd,
|
|
259
|
-
":mid": params.milestoneId,
|
|
260
|
-
":sid": params.sliceId,
|
|
261
|
-
});
|
|
262
|
-
}
|
|
248
|
+
setSliceSummaryMd(params.milestoneId, params.sliceId, summaryMd, uatMd);
|
|
263
249
|
// Invalidate all caches
|
|
264
250
|
invalidateStateCache();
|
|
265
251
|
clearPathCache();
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { mkdirSync } from "node:fs";
|
|
11
|
-
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask,
|
|
11
|
+
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, setTaskSummaryMd, deleteVerificationEvidence, } from "../gsd-db.js";
|
|
12
12
|
import { resolveSliceFile, resolveTasksDir, clearPathCache } from "../paths.js";
|
|
13
13
|
import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
|
|
14
14
|
import { saveFile, clearParseCache } from "../files.js";
|
|
@@ -202,27 +202,16 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
202
202
|
catch (renderErr) {
|
|
203
203
|
// Disk render failed — roll back DB status so state stays consistent
|
|
204
204
|
process.stderr.write(`gsd-db: complete_task — disk render failed, rolling back DB status: ${renderErr.message}\n`);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
":tid": params.taskId,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
205
|
+
// Delete orphaned verification_evidence rows first (FK constraint
|
|
206
|
+
// references tasks, so evidence must go before status change).
|
|
207
|
+
// Without this, retries accumulate duplicate evidence rows (#2724).
|
|
208
|
+
deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
|
|
209
|
+
updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, 'pending');
|
|
213
210
|
invalidateStateCache();
|
|
214
211
|
return { error: `disk render failed: ${renderErr.message}` };
|
|
215
212
|
}
|
|
216
213
|
// Store rendered markdown in DB for D004 recovery
|
|
217
|
-
|
|
218
|
-
if (adapter) {
|
|
219
|
-
adapter.prepare(`UPDATE tasks SET full_summary_md = :md WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`).run({
|
|
220
|
-
":md": summaryMd,
|
|
221
|
-
":mid": params.milestoneId,
|
|
222
|
-
":sid": params.sliceId,
|
|
223
|
-
":tid": params.taskId,
|
|
224
|
-
});
|
|
225
|
-
}
|
|
214
|
+
setTaskSummaryMd(params.milestoneId, params.sliceId, params.taskId, summaryMd);
|
|
226
215
|
// Invalidate all caches
|
|
227
216
|
invalidateStateCache();
|
|
228
217
|
clearPathCache();
|
|
@@ -145,25 +145,31 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
145
145
|
catch (err) {
|
|
146
146
|
return { error: `validation failed: ${err.message}` };
|
|
147
147
|
}
|
|
148
|
-
// ──
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
// Validate depends_on: all dependencies must exist and be complete
|
|
154
|
-
if (params.dependsOn && params.dependsOn.length > 0) {
|
|
155
|
-
for (const depId of params.dependsOn) {
|
|
156
|
-
const dep = getMilestone(depId);
|
|
157
|
-
if (!dep) {
|
|
158
|
-
return { error: `depends_on references unknown milestone: ${depId}` };
|
|
159
|
-
}
|
|
160
|
-
if (dep.status !== "complete" && dep.status !== "done") {
|
|
161
|
-
return { error: `depends_on milestone ${depId} is not yet complete (status: ${dep.status})` };
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
148
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
149
|
+
// Guards must be inside the transaction so the state they check cannot
|
|
150
|
+
// change between the read and the write (#2723).
|
|
151
|
+
let guardError = null;
|
|
165
152
|
try {
|
|
166
153
|
transaction(() => {
|
|
154
|
+
const existingMilestone = getMilestone(params.milestoneId);
|
|
155
|
+
if (existingMilestone && (existingMilestone.status === "complete" || existingMilestone.status === "done")) {
|
|
156
|
+
guardError = `cannot re-plan milestone ${params.milestoneId}: it is already complete`;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Validate depends_on: all dependencies must exist and be complete
|
|
160
|
+
if (params.dependsOn && params.dependsOn.length > 0) {
|
|
161
|
+
for (const depId of params.dependsOn) {
|
|
162
|
+
const dep = getMilestone(depId);
|
|
163
|
+
if (!dep) {
|
|
164
|
+
guardError = `depends_on references unknown milestone: ${depId}`;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (dep.status !== "complete" && dep.status !== "done") {
|
|
168
|
+
guardError = `depends_on milestone ${depId} is not yet complete (status: ${dep.status})`;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
167
173
|
insertMilestone({
|
|
168
174
|
id: params.milestoneId,
|
|
169
175
|
title: params.title,
|
|
@@ -206,6 +212,9 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
206
212
|
catch (err) {
|
|
207
213
|
return { error: `db write failed: ${err.message}` };
|
|
208
214
|
}
|
|
215
|
+
if (guardError) {
|
|
216
|
+
return { error: guardError };
|
|
217
|
+
}
|
|
209
218
|
let roadmapPath;
|
|
210
219
|
try {
|
|
211
220
|
const renderResult = await renderRoadmapFromDb(basePath, params.milestoneId);
|
|
@@ -102,22 +102,30 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
102
102
|
catch (err) {
|
|
103
103
|
return { error: `validation failed: ${err.message}` };
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (parentMilestone.status === "complete" || parentMilestone.status === "done") {
|
|
110
|
-
return { error: `cannot plan slice in a closed milestone: ${params.milestoneId} (status: ${parentMilestone.status})` };
|
|
111
|
-
}
|
|
112
|
-
const parentSlice = getSlice(params.milestoneId, params.sliceId);
|
|
113
|
-
if (!parentSlice) {
|
|
114
|
-
return { error: `missing parent slice: ${params.milestoneId}/${params.sliceId}` };
|
|
115
|
-
}
|
|
116
|
-
if (parentSlice.status === "complete" || parentSlice.status === "done") {
|
|
117
|
-
return { error: `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first` };
|
|
118
|
-
}
|
|
105
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
106
|
+
// Guards must be inside the transaction so the state they check cannot
|
|
107
|
+
// change between the read and the write (#2723).
|
|
108
|
+
let guardError = null;
|
|
119
109
|
try {
|
|
120
110
|
transaction(() => {
|
|
111
|
+
const parentMilestone = getMilestone(params.milestoneId);
|
|
112
|
+
if (!parentMilestone) {
|
|
113
|
+
guardError = `milestone not found: ${params.milestoneId}`;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (parentMilestone.status === "complete" || parentMilestone.status === "done") {
|
|
117
|
+
guardError = `cannot plan slice in a closed milestone: ${params.milestoneId} (status: ${parentMilestone.status})`;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const parentSlice = getSlice(params.milestoneId, params.sliceId);
|
|
121
|
+
if (!parentSlice) {
|
|
122
|
+
guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (parentSlice.status === "complete" || parentSlice.status === "done") {
|
|
126
|
+
guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
121
129
|
upsertSlicePlanning(params.milestoneId, params.sliceId, {
|
|
122
130
|
goal: params.goal,
|
|
123
131
|
successCriteria: params.successCriteria,
|
|
@@ -163,6 +171,9 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
163
171
|
catch (err) {
|
|
164
172
|
return { error: `db write failed: ${err.message}` };
|
|
165
173
|
}
|
|
174
|
+
if (guardError) {
|
|
175
|
+
return { error: guardError };
|
|
176
|
+
}
|
|
166
177
|
try {
|
|
167
178
|
const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
168
179
|
invalidateStateCache();
|
|
@@ -50,19 +50,26 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
50
50
|
catch (err) {
|
|
51
51
|
return { error: `validation failed: ${err.message}` };
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (parentSlice.status === "complete" || parentSlice.status === "done") {
|
|
58
|
-
return { error: `cannot plan task in a closed slice: ${params.sliceId} (status: ${parentSlice.status})` };
|
|
59
|
-
}
|
|
60
|
-
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
61
|
-
if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
|
|
62
|
-
return { error: `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first` };
|
|
63
|
-
}
|
|
53
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
54
|
+
// Guards must be inside the transaction so the state they check cannot
|
|
55
|
+
// change between the read and the write (#2723).
|
|
56
|
+
let guardError = null;
|
|
64
57
|
try {
|
|
65
58
|
transaction(() => {
|
|
59
|
+
const parentSlice = getSlice(params.milestoneId, params.sliceId);
|
|
60
|
+
if (!parentSlice) {
|
|
61
|
+
guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (parentSlice.status === "complete" || parentSlice.status === "done") {
|
|
65
|
+
guardError = `cannot plan task in a closed slice: ${params.sliceId} (status: ${parentSlice.status})`;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
69
|
+
if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
|
|
70
|
+
guardError = `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first`;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
66
73
|
if (!existingTask) {
|
|
67
74
|
insertTask({
|
|
68
75
|
id: params.taskId,
|
|
@@ -88,6 +95,9 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
88
95
|
catch (err) {
|
|
89
96
|
return { error: `db write failed: ${err.message}` };
|
|
90
97
|
}
|
|
98
|
+
if (guardError) {
|
|
99
|
+
return { error: guardError };
|
|
100
|
+
}
|
|
91
101
|
try {
|
|
92
102
|
const renderResult = await renderTaskPlanFromDb(basePath, params.milestoneId, params.sliceId, params.taskId);
|
|
93
103
|
invalidateStateCache();
|
|
@@ -61,48 +61,55 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
61
61
|
catch (err) {
|
|
62
62
|
return { error: `validation failed: ${err.message}` };
|
|
63
63
|
}
|
|
64
|
-
// ── Verify milestone exists and is active ────────────────────────
|
|
65
|
-
const milestone = getMilestone(params.milestoneId);
|
|
66
|
-
if (!milestone) {
|
|
67
|
-
return { error: `milestone not found: ${params.milestoneId}` };
|
|
68
|
-
}
|
|
69
|
-
if (milestone.status === "complete" || milestone.status === "done") {
|
|
70
|
-
return { error: `cannot reassess a closed milestone: ${params.milestoneId} (status: ${milestone.status})` };
|
|
71
|
-
}
|
|
72
|
-
// ── Verify completedSliceId is actually complete ──────────────────
|
|
73
|
-
const completedSlice = getSlice(params.milestoneId, params.completedSliceId);
|
|
74
|
-
if (!completedSlice) {
|
|
75
|
-
return { error: `completedSliceId not found: ${params.milestoneId}/${params.completedSliceId}` };
|
|
76
|
-
}
|
|
77
|
-
if (completedSlice.status !== "complete" && completedSlice.status !== "done") {
|
|
78
|
-
return { error: `completedSliceId ${params.completedSliceId} is not complete (status: ${completedSlice.status}) — reassess can only be called after a slice finishes` };
|
|
79
|
-
}
|
|
80
|
-
// ── Structural enforcement ────────────────────────────────────────
|
|
81
|
-
const existingSlices = getMilestoneSlices(params.milestoneId);
|
|
82
|
-
const completedSliceIds = new Set();
|
|
83
|
-
for (const slice of existingSlices) {
|
|
84
|
-
if (slice.status === "complete" || slice.status === "done") {
|
|
85
|
-
completedSliceIds.add(slice.id);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Reject modifications to completed slices
|
|
89
|
-
for (const modifiedSlice of params.sliceChanges.modified) {
|
|
90
|
-
if (completedSliceIds.has(modifiedSlice.sliceId)) {
|
|
91
|
-
return { error: `cannot modify completed slice ${modifiedSlice.sliceId}` };
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// Reject removal of completed slices
|
|
95
|
-
for (const removedId of params.sliceChanges.removed) {
|
|
96
|
-
if (completedSliceIds.has(removedId)) {
|
|
97
|
-
return { error: `cannot remove completed slice ${removedId}` };
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
64
|
// ── Compute assessment artifact path ──────────────────────────────
|
|
101
65
|
// Assessment lives in the completed slice's directory
|
|
102
66
|
const assessmentRelPath = join(".gsd", "milestones", params.milestoneId, "slices", params.completedSliceId, `${params.completedSliceId}-ASSESSMENT.md`);
|
|
103
|
-
// ──
|
|
67
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
68
|
+
// Guards must be inside the transaction so the state they check cannot
|
|
69
|
+
// change between the read and the write (#2723).
|
|
70
|
+
let guardError = null;
|
|
104
71
|
try {
|
|
105
72
|
transaction(() => {
|
|
73
|
+
// Verify milestone exists and is active
|
|
74
|
+
const milestone = getMilestone(params.milestoneId);
|
|
75
|
+
if (!milestone) {
|
|
76
|
+
guardError = `milestone not found: ${params.milestoneId}`;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (milestone.status === "complete" || milestone.status === "done") {
|
|
80
|
+
guardError = `cannot reassess a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Verify completedSliceId is actually complete
|
|
84
|
+
const completedSlice = getSlice(params.milestoneId, params.completedSliceId);
|
|
85
|
+
if (!completedSlice) {
|
|
86
|
+
guardError = `completedSliceId not found: ${params.milestoneId}/${params.completedSliceId}`;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (completedSlice.status !== "complete" && completedSlice.status !== "done") {
|
|
90
|
+
guardError = `completedSliceId ${params.completedSliceId} is not complete (status: ${completedSlice.status}) — reassess can only be called after a slice finishes`;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Structural enforcement — reject modifications/removal of completed slices
|
|
94
|
+
const existingSlices = getMilestoneSlices(params.milestoneId);
|
|
95
|
+
const completedSliceIds = new Set();
|
|
96
|
+
for (const slice of existingSlices) {
|
|
97
|
+
if (slice.status === "complete" || slice.status === "done") {
|
|
98
|
+
completedSliceIds.add(slice.id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const modifiedSlice of params.sliceChanges.modified) {
|
|
102
|
+
if (completedSliceIds.has(modifiedSlice.sliceId)) {
|
|
103
|
+
guardError = `cannot modify completed slice ${modifiedSlice.sliceId}`;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const removedId of params.sliceChanges.removed) {
|
|
108
|
+
if (completedSliceIds.has(removedId)) {
|
|
109
|
+
guardError = `cannot remove completed slice ${removedId}`;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
106
113
|
// Record assessment
|
|
107
114
|
insertAssessment({
|
|
108
115
|
path: assessmentRelPath,
|
|
@@ -142,6 +149,9 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
142
149
|
catch (err) {
|
|
143
150
|
return { error: `db write failed: ${err.message}` };
|
|
144
151
|
}
|
|
152
|
+
if (guardError) {
|
|
153
|
+
return { error: guardError };
|
|
154
|
+
}
|
|
145
155
|
// ── Render artifacts ──────────────────────────────────────────────
|
|
146
156
|
try {
|
|
147
157
|
const roadmapResult = await renderRoadmapFromDb(basePath, params.milestoneId);
|