gsd-pi 2.50.0 → 2.51.0-dev.ae8f7cb
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 +2 -0
- package/dist/cli.js +26 -0
- package/dist/loader.js +4 -0
- 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 +3 -1
- 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/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 +81 -54
- 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-utils.js +20 -0
- package/dist/resources/extensions/gsd/auto.js +15 -5
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +16 -0
- 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 +589 -3
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -0
- package/dist/resources/extensions/gsd/files.js +5 -1
- package/dist/resources/extensions/gsd/guided-flow.js +10 -0
- package/dist/resources/extensions/gsd/init-wizard.js +9 -1
- 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-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 +3 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +11 -7
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
- package/dist/resources/extensions/gsd/provider-error-pause.js +8 -0
- 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 +10 -11
- 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 +17 -5
- package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
- package/dist/resources/extensions/gsd/templates/preferences.md +2 -0
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
- 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/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 +12 -11
- 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 +12 -11
- 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/5_KeZz1X0tXJK-d_4OhjB/_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.9ad5def014d90ce4.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-cfc9a116e6450a6b.js +1 -0
- package/dist/web/standalone/.next/static/css/de141508b083f922.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/package.json +1 -1
- package/packages/pi-ai/dist/types.d.ts +1 -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/types.ts +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 +10 -1
- 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/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/index.d.ts +2 -2
- 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/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/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/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/bash-executor.ts +10 -2
- 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/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/index.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -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/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 +3 -1
- 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/tests/partial-builder.test.ts +105 -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 +84 -51
- 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-utils.ts +25 -0
- package/src/resources/extensions/gsd/auto.ts +15 -5
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -0
- 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 +662 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -0
- package/src/resources/extensions/gsd/files.ts +6 -1
- package/src/resources/extensions/gsd/guided-flow.ts +11 -0
- package/src/resources/extensions/gsd/init-wizard.ts +9 -1
- 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-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 +3 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +11 -7
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
- package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
- 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 +10 -11
- 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 +16 -5
- package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
- package/src/resources/extensions/gsd/templates/preferences.md +2 -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/complete-milestone.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 +4 -3
- package/src/resources/extensions/gsd/tests/detection.test.ts +838 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
- package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +50 -0
- 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/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 +24 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
- 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/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 → 5_KeZz1X0tXJK-d_4OhjB}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import { validateTaskPlanContent, validateSlicePlanContent } from '../observability-validator.ts';
|
|
2
|
+
import { createTestContext } from './test-helpers.ts';
|
|
3
|
+
|
|
4
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
5
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
6
|
+
// validateTaskPlanContent — empty/missing Steps section
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
|
|
9
|
+
console.log('\n=== validateTaskPlanContent: empty Steps section ===');
|
|
10
|
+
{
|
|
11
|
+
const content = `# T01: Some Task
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Do something useful.
|
|
16
|
+
|
|
17
|
+
## Steps
|
|
18
|
+
|
|
19
|
+
## Verification
|
|
20
|
+
|
|
21
|
+
- Run the tests and confirm output.
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
25
|
+
const stepsIssues = issues.filter(i => i.ruleId === 'empty_steps_section');
|
|
26
|
+
assertTrue(stepsIssues.length >= 1, 'empty Steps section produces empty_steps_section issue');
|
|
27
|
+
if (stepsIssues.length > 0) {
|
|
28
|
+
assertEq(stepsIssues[0].severity, 'warning', 'empty_steps_section severity is warning');
|
|
29
|
+
assertEq(stepsIssues[0].scope, 'task-plan', 'empty_steps_section scope is task-plan');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log('\n=== validateTaskPlanContent: missing Steps section entirely ===');
|
|
34
|
+
{
|
|
35
|
+
const content = `# T01: Some Task
|
|
36
|
+
|
|
37
|
+
## Description
|
|
38
|
+
|
|
39
|
+
Do something useful.
|
|
40
|
+
|
|
41
|
+
## Verification
|
|
42
|
+
|
|
43
|
+
- Run the tests.
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
47
|
+
const stepsIssues = issues.filter(i => i.ruleId === 'empty_steps_section');
|
|
48
|
+
assertTrue(stepsIssues.length >= 1, 'missing Steps section produces empty_steps_section issue');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
52
|
+
// validateTaskPlanContent — placeholder-only Verification
|
|
53
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
54
|
+
|
|
55
|
+
console.log('\n=== validateTaskPlanContent: placeholder-only Verification ===');
|
|
56
|
+
{
|
|
57
|
+
const content = `# T01: Some Task
|
|
58
|
+
|
|
59
|
+
## Steps
|
|
60
|
+
|
|
61
|
+
1. Do the thing.
|
|
62
|
+
2. Do the other thing.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
|
|
66
|
+
- {{placeholder verification step}}
|
|
67
|
+
- {{another placeholder}}
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
71
|
+
const verifyIssues = issues.filter(i => i.ruleId === 'placeholder_verification');
|
|
72
|
+
assertTrue(verifyIssues.length >= 1, 'placeholder-only Verification produces placeholder_verification issue');
|
|
73
|
+
if (verifyIssues.length > 0) {
|
|
74
|
+
assertEq(verifyIssues[0].severity, 'warning', 'placeholder_verification severity is warning');
|
|
75
|
+
assertEq(verifyIssues[0].scope, 'task-plan', 'placeholder_verification scope is task-plan');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log('\n=== validateTaskPlanContent: Verification with only template text ===');
|
|
80
|
+
{
|
|
81
|
+
const content = `# T01: Some Task
|
|
82
|
+
|
|
83
|
+
## Steps
|
|
84
|
+
|
|
85
|
+
1. Do the thing.
|
|
86
|
+
|
|
87
|
+
## Verification
|
|
88
|
+
|
|
89
|
+
{{whatWasVerifiedAndHow — commands run, tests passed, behavior confirmed}}
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
93
|
+
const verifyIssues = issues.filter(i => i.ruleId === 'placeholder_verification');
|
|
94
|
+
assertTrue(verifyIssues.length >= 1, 'template-text-only Verification produces placeholder_verification issue');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
98
|
+
// validateSlicePlanContent — empty inline task entries
|
|
99
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
100
|
+
|
|
101
|
+
console.log('\n=== validateSlicePlanContent: empty inline task entries ===');
|
|
102
|
+
{
|
|
103
|
+
const content = `# S01: Some Slice
|
|
104
|
+
|
|
105
|
+
**Goal:** Build the thing.
|
|
106
|
+
**Demo:** It works.
|
|
107
|
+
|
|
108
|
+
## Tasks
|
|
109
|
+
|
|
110
|
+
- [ ] **T01: First Task** \`est:20m\`
|
|
111
|
+
|
|
112
|
+
- [ ] **T02: Second Task** \`est:15m\`
|
|
113
|
+
|
|
114
|
+
## Verification
|
|
115
|
+
|
|
116
|
+
- Run the tests.
|
|
117
|
+
`;
|
|
118
|
+
|
|
119
|
+
const issues = validateSlicePlanContent('S01-PLAN.md', content);
|
|
120
|
+
const emptyTaskIssues = issues.filter(i => i.ruleId === 'empty_task_entry');
|
|
121
|
+
assertTrue(emptyTaskIssues.length >= 1, 'task entries with no description produce empty_task_entry issue');
|
|
122
|
+
if (emptyTaskIssues.length > 0) {
|
|
123
|
+
assertEq(emptyTaskIssues[0].severity, 'warning', 'empty_task_entry severity is warning');
|
|
124
|
+
assertEq(emptyTaskIssues[0].scope, 'slice-plan', 'empty_task_entry scope is slice-plan');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
console.log('\n=== validateSlicePlanContent: task entries with content are fine ===');
|
|
129
|
+
{
|
|
130
|
+
const content = `# S01: Some Slice
|
|
131
|
+
|
|
132
|
+
**Goal:** Build the thing.
|
|
133
|
+
**Demo:** It works.
|
|
134
|
+
|
|
135
|
+
## Tasks
|
|
136
|
+
|
|
137
|
+
- [ ] **T01: First Task** \`est:20m\`
|
|
138
|
+
- Why: Because it matters.
|
|
139
|
+
- Files: \`src/index.ts\`
|
|
140
|
+
- Do: Implement the feature.
|
|
141
|
+
|
|
142
|
+
- [ ] **T02: Second Task** \`est:15m\`
|
|
143
|
+
- Why: Also important.
|
|
144
|
+
- Do: Add tests.
|
|
145
|
+
|
|
146
|
+
## Verification
|
|
147
|
+
|
|
148
|
+
- Run the tests.
|
|
149
|
+
`;
|
|
150
|
+
|
|
151
|
+
const issues = validateSlicePlanContent('S01-PLAN.md', content);
|
|
152
|
+
const emptyTaskIssues = issues.filter(i => i.ruleId === 'empty_task_entry');
|
|
153
|
+
assertEq(emptyTaskIssues.length, 0, 'task entries with description content produce no empty_task_entry issues');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
157
|
+
// validateTaskPlanContent — scope_estimate over threshold
|
|
158
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
159
|
+
|
|
160
|
+
console.log('\n=== validateTaskPlanContent: scope_estimate over threshold ===');
|
|
161
|
+
{
|
|
162
|
+
const content = `---
|
|
163
|
+
estimated_steps: 12
|
|
164
|
+
estimated_files: 15
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
# T01: Big Task
|
|
168
|
+
|
|
169
|
+
## Steps
|
|
170
|
+
|
|
171
|
+
1. Step one.
|
|
172
|
+
2. Step two.
|
|
173
|
+
3. Step three.
|
|
174
|
+
|
|
175
|
+
## Verification
|
|
176
|
+
|
|
177
|
+
- Check it works.
|
|
178
|
+
`;
|
|
179
|
+
|
|
180
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
181
|
+
const stepsOverIssues = issues.filter(i => i.ruleId === 'scope_estimate_steps_high');
|
|
182
|
+
const filesOverIssues = issues.filter(i => i.ruleId === 'scope_estimate_files_high');
|
|
183
|
+
assertTrue(stepsOverIssues.length >= 1, 'estimated_steps=12 (>=10) produces scope_estimate_steps_high issue');
|
|
184
|
+
assertTrue(filesOverIssues.length >= 1, 'estimated_files=15 (>=12) produces scope_estimate_files_high issue');
|
|
185
|
+
if (stepsOverIssues.length > 0) {
|
|
186
|
+
assertEq(stepsOverIssues[0].severity, 'warning', 'scope_estimate_steps_high severity is warning');
|
|
187
|
+
assertEq(stepsOverIssues[0].scope, 'task-plan', 'scope_estimate_steps_high scope is task-plan');
|
|
188
|
+
}
|
|
189
|
+
if (filesOverIssues.length > 0) {
|
|
190
|
+
assertEq(filesOverIssues[0].severity, 'warning', 'scope_estimate_files_high severity is warning');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
195
|
+
// validateTaskPlanContent — scope_estimate within limits
|
|
196
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
197
|
+
|
|
198
|
+
console.log('\n=== validateTaskPlanContent: scope_estimate within limits ===');
|
|
199
|
+
{
|
|
200
|
+
const content = `---
|
|
201
|
+
estimated_steps: 4
|
|
202
|
+
estimated_files: 6
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
# T01: Small Task
|
|
206
|
+
|
|
207
|
+
## Steps
|
|
208
|
+
|
|
209
|
+
1. Do the thing.
|
|
210
|
+
|
|
211
|
+
## Verification
|
|
212
|
+
|
|
213
|
+
- Verify it works.
|
|
214
|
+
`;
|
|
215
|
+
|
|
216
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
217
|
+
const scopeIssues = issues.filter(i =>
|
|
218
|
+
i.ruleId === 'scope_estimate_steps_high' || i.ruleId === 'scope_estimate_files_high'
|
|
219
|
+
);
|
|
220
|
+
assertEq(scopeIssues.length, 0, 'scope_estimate within limits produces no scope issues');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
224
|
+
// validateTaskPlanContent — missing scope_estimate (no warning)
|
|
225
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
226
|
+
|
|
227
|
+
console.log('\n=== validateTaskPlanContent: missing scope_estimate ===');
|
|
228
|
+
{
|
|
229
|
+
const content = `# T01: No Frontmatter Task
|
|
230
|
+
|
|
231
|
+
## Steps
|
|
232
|
+
|
|
233
|
+
1. Do the thing.
|
|
234
|
+
|
|
235
|
+
## Verification
|
|
236
|
+
|
|
237
|
+
- Verify it works.
|
|
238
|
+
`;
|
|
239
|
+
|
|
240
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
241
|
+
const scopeIssues = issues.filter(i =>
|
|
242
|
+
i.ruleId === 'scope_estimate_steps_high' || i.ruleId === 'scope_estimate_files_high'
|
|
243
|
+
);
|
|
244
|
+
assertEq(scopeIssues.length, 0, 'missing scope_estimate produces no scope issues');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
console.log('\n=== validateTaskPlanContent: frontmatter without scope keys ===');
|
|
248
|
+
{
|
|
249
|
+
const content = `---
|
|
250
|
+
id: T01
|
|
251
|
+
parent: S01
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
# T01: Task With Other Frontmatter
|
|
255
|
+
|
|
256
|
+
## Steps
|
|
257
|
+
|
|
258
|
+
1. Do the thing.
|
|
259
|
+
|
|
260
|
+
## Verification
|
|
261
|
+
|
|
262
|
+
- Verify it works.
|
|
263
|
+
`;
|
|
264
|
+
|
|
265
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
266
|
+
const scopeIssues = issues.filter(i =>
|
|
267
|
+
i.ruleId === 'scope_estimate_steps_high' || i.ruleId === 'scope_estimate_files_high'
|
|
268
|
+
);
|
|
269
|
+
assertEq(scopeIssues.length, 0, 'frontmatter without scope keys produces no scope issues');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
273
|
+
// Clean plans — no false positives
|
|
274
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
275
|
+
|
|
276
|
+
console.log('\n=== Clean task plan: no plan-quality issues ===');
|
|
277
|
+
{
|
|
278
|
+
const content = `---
|
|
279
|
+
estimated_steps: 5
|
|
280
|
+
estimated_files: 3
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
# T01: Well-Formed Task
|
|
284
|
+
|
|
285
|
+
## Description
|
|
286
|
+
|
|
287
|
+
A real task with real content.
|
|
288
|
+
|
|
289
|
+
## Steps
|
|
290
|
+
|
|
291
|
+
1. Read the input files.
|
|
292
|
+
2. Parse the configuration.
|
|
293
|
+
3. Transform the data.
|
|
294
|
+
4. Write the output.
|
|
295
|
+
5. Verify the results.
|
|
296
|
+
|
|
297
|
+
## Must-Haves
|
|
298
|
+
|
|
299
|
+
- [ ] Output file is valid JSON
|
|
300
|
+
- [ ] All input records are processed
|
|
301
|
+
|
|
302
|
+
## Verification
|
|
303
|
+
|
|
304
|
+
- Run \`node --test tests/transform.test.ts\` — all assertions pass
|
|
305
|
+
- Manually inspect output.json for correct structure
|
|
306
|
+
|
|
307
|
+
## Observability Impact
|
|
308
|
+
|
|
309
|
+
- Signals added/changed: structured error log on parse failure
|
|
310
|
+
- How a future agent inspects this: check stderr for JSON parse errors
|
|
311
|
+
- Failure state exposed: exit code 1 + error message on invalid input
|
|
312
|
+
`;
|
|
313
|
+
|
|
314
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
315
|
+
const planQualityIssues = issues.filter(i =>
|
|
316
|
+
i.ruleId === 'empty_steps_section' ||
|
|
317
|
+
i.ruleId === 'placeholder_verification' ||
|
|
318
|
+
i.ruleId === 'scope_estimate_steps_high' ||
|
|
319
|
+
i.ruleId === 'scope_estimate_files_high'
|
|
320
|
+
);
|
|
321
|
+
assertEq(planQualityIssues.length, 0, 'clean task plan produces no plan-quality issues');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
console.log('\n=== Clean slice plan: no plan-quality issues ===');
|
|
325
|
+
{
|
|
326
|
+
const content = `# S01: Well-Formed Slice
|
|
327
|
+
|
|
328
|
+
**Goal:** Build a complete feature.
|
|
329
|
+
**Demo:** Run the test suite and see all green.
|
|
330
|
+
|
|
331
|
+
## Tasks
|
|
332
|
+
|
|
333
|
+
- [ ] **T01: Create tests** \`est:20m\`
|
|
334
|
+
- Why: Tests define the contract before implementation.
|
|
335
|
+
- Files: \`tests/feature.test.ts\`
|
|
336
|
+
- Do: Write comprehensive test assertions.
|
|
337
|
+
- Verify: Test file runs without syntax errors.
|
|
338
|
+
|
|
339
|
+
- [ ] **T02: Implement feature** \`est:30m\`
|
|
340
|
+
- Why: Core implementation.
|
|
341
|
+
- Files: \`src/feature.ts\`
|
|
342
|
+
- Do: Build the feature to make tests pass.
|
|
343
|
+
- Verify: All tests pass.
|
|
344
|
+
|
|
345
|
+
## Verification
|
|
346
|
+
|
|
347
|
+
- \`node --test tests/feature.test.ts\` — all assertions pass
|
|
348
|
+
- Check error output for diagnostic messages
|
|
349
|
+
|
|
350
|
+
## Observability / Diagnostics
|
|
351
|
+
|
|
352
|
+
- Runtime signals: structured error objects with error codes
|
|
353
|
+
- Inspection surfaces: test output shows pass/fail counts
|
|
354
|
+
- Failure visibility: exit code 1 on failure with descriptive message
|
|
355
|
+
- Redaction constraints: none
|
|
356
|
+
`;
|
|
357
|
+
|
|
358
|
+
const issues = validateSlicePlanContent('S01-PLAN.md', content);
|
|
359
|
+
const planQualityIssues = issues.filter(i => i.ruleId === 'empty_task_entry');
|
|
360
|
+
assertEq(planQualityIssues.length, 0, 'clean slice plan produces no empty_task_entry issues');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
364
|
+
// validateTaskPlanContent — missing output file paths
|
|
365
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
366
|
+
|
|
367
|
+
console.log('\n=== validateTaskPlanContent: missing output file paths ===');
|
|
368
|
+
{
|
|
369
|
+
const content = `# T01: Some Task
|
|
370
|
+
|
|
371
|
+
## Description
|
|
372
|
+
|
|
373
|
+
Do something.
|
|
374
|
+
|
|
375
|
+
## Steps
|
|
376
|
+
|
|
377
|
+
1. Do the thing
|
|
378
|
+
|
|
379
|
+
## Verification
|
|
380
|
+
|
|
381
|
+
- Check it works
|
|
382
|
+
|
|
383
|
+
## Expected Output
|
|
384
|
+
|
|
385
|
+
This task produces the main output.
|
|
386
|
+
`;
|
|
387
|
+
|
|
388
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
389
|
+
const outputIssues = issues.filter(i => i.ruleId === 'missing_output_file_paths');
|
|
390
|
+
assertTrue(outputIssues.length >= 1, 'Expected Output without file paths triggers missing_output_file_paths');
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
console.log('\n=== validateTaskPlanContent: valid output file paths ===');
|
|
394
|
+
{
|
|
395
|
+
const content = `# T01: Some Task
|
|
396
|
+
|
|
397
|
+
## Description
|
|
398
|
+
|
|
399
|
+
Do something.
|
|
400
|
+
|
|
401
|
+
## Steps
|
|
402
|
+
|
|
403
|
+
1. Do the thing
|
|
404
|
+
|
|
405
|
+
## Verification
|
|
406
|
+
|
|
407
|
+
- Check it works
|
|
408
|
+
|
|
409
|
+
## Expected Output
|
|
410
|
+
|
|
411
|
+
- \`src/types.ts\` — New type definitions
|
|
412
|
+
`;
|
|
413
|
+
|
|
414
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
415
|
+
const outputIssues = issues.filter(i => i.ruleId === 'missing_output_file_paths');
|
|
416
|
+
assertEq(outputIssues.length, 0, 'Expected Output with file paths does not trigger warning');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
console.log('\n=== validateTaskPlanContent: missing input file paths (info severity) ===');
|
|
420
|
+
{
|
|
421
|
+
const content = `# T01: Some Task
|
|
422
|
+
|
|
423
|
+
## Description
|
|
424
|
+
|
|
425
|
+
Do something.
|
|
426
|
+
|
|
427
|
+
## Steps
|
|
428
|
+
|
|
429
|
+
1. Do the thing
|
|
430
|
+
|
|
431
|
+
## Verification
|
|
432
|
+
|
|
433
|
+
- Check it works
|
|
434
|
+
|
|
435
|
+
## Inputs
|
|
436
|
+
|
|
437
|
+
Prior task summary insights about the architecture.
|
|
438
|
+
|
|
439
|
+
## Expected Output
|
|
440
|
+
|
|
441
|
+
- \`src/output.ts\` — Output file
|
|
442
|
+
`;
|
|
443
|
+
|
|
444
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
445
|
+
const inputIssues = issues.filter(i => i.ruleId === 'missing_input_file_paths');
|
|
446
|
+
assertTrue(inputIssues.length >= 1, 'Inputs without file paths triggers missing_input_file_paths');
|
|
447
|
+
if (inputIssues.length > 0) {
|
|
448
|
+
assertEq(inputIssues[0].severity, 'info', 'missing_input_file_paths is info severity (not warning)');
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
console.log('\n=== validateTaskPlanContent: no Expected Output section at all ===');
|
|
453
|
+
{
|
|
454
|
+
const content = `# T01: Some Task
|
|
455
|
+
|
|
456
|
+
## Description
|
|
457
|
+
|
|
458
|
+
Do something.
|
|
459
|
+
|
|
460
|
+
## Steps
|
|
461
|
+
|
|
462
|
+
1. Do the thing
|
|
463
|
+
|
|
464
|
+
## Verification
|
|
465
|
+
|
|
466
|
+
- Check it works
|
|
467
|
+
`;
|
|
468
|
+
|
|
469
|
+
const issues = validateTaskPlanContent('T01-PLAN.md', content);
|
|
470
|
+
const outputIssues = issues.filter(i => i.ruleId === 'missing_output_file_paths');
|
|
471
|
+
assertTrue(outputIssues.length >= 1, 'Missing Expected Output section triggers missing_output_file_paths');
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
report();
|
|
@@ -377,3 +377,53 @@ test("unrecognized format warning is emitted at most once (#2373)", () => {
|
|
|
377
377
|
_resetParseWarningFlag();
|
|
378
378
|
}
|
|
379
379
|
});
|
|
380
|
+
|
|
381
|
+
// ── Experimental preferences ─────────────────────────────────────────────────
|
|
382
|
+
|
|
383
|
+
test("experimental.rtk: true is accepted and stored", () => {
|
|
384
|
+
const result = validatePreferences({ experimental: { rtk: true } });
|
|
385
|
+
assert.deepEqual(result.errors, []);
|
|
386
|
+
assert.equal(result.preferences.experimental?.rtk, true);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test("experimental.rtk: false is accepted and stored", () => {
|
|
390
|
+
const result = validatePreferences({ experimental: { rtk: false } });
|
|
391
|
+
assert.deepEqual(result.errors, []);
|
|
392
|
+
assert.equal(result.preferences.experimental?.rtk, false);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
test("experimental.rtk: non-boolean produces error", () => {
|
|
396
|
+
const result = validatePreferences({ experimental: { rtk: "yes" } } as unknown as GSDPreferences);
|
|
397
|
+
assert.ok(result.errors.some(e => e.includes("experimental.rtk")), `expected rtk error in: ${JSON.stringify(result.errors)}`);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
test("experimental: non-object produces error", () => {
|
|
401
|
+
const result = validatePreferences({ experimental: true } as unknown as GSDPreferences);
|
|
402
|
+
assert.ok(result.errors.some(e => e.includes("experimental must be an object")));
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
test("experimental: unknown key produces warning", () => {
|
|
406
|
+
const result = validatePreferences({ experimental: { rtk: true, future_flag: true } } as unknown as GSDPreferences);
|
|
407
|
+
assert.ok(result.warnings.some(w => w.includes("future_flag")), `expected unknown-key warning in: ${JSON.stringify(result.warnings)}`);
|
|
408
|
+
assert.equal(result.preferences.experimental?.rtk, true);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test("experimental: omitting rtk defaults to undefined (opt-in)", () => {
|
|
412
|
+
const result = validatePreferences({ version: 1 });
|
|
413
|
+
assert.equal(result.preferences.experimental, undefined);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test("experimental.rtk parses correctly from preferences markdown", () => {
|
|
417
|
+
const content = "---\nversion: 1\nexperimental:\n rtk: true\n---\n";
|
|
418
|
+
const prefs = parsePreferencesMarkdown(content);
|
|
419
|
+
assert.notEqual(prefs, null);
|
|
420
|
+
assert.equal(prefs!.experimental?.rtk, true);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("experimental.rtk defaults to off in new project preferences", () => {
|
|
424
|
+
// No experimental key → feature is disabled
|
|
425
|
+
const content = "---\nversion: 1\n---\n";
|
|
426
|
+
const prefs = parsePreferencesMarkdown(content);
|
|
427
|
+
assert.notEqual(prefs, null);
|
|
428
|
+
assert.equal(prefs!.experimental?.rtk, undefined);
|
|
429
|
+
});
|
|
@@ -292,4 +292,44 @@ test('E2E: depends_on inline format preserved after partial removal', () => {
|
|
|
292
292
|
}
|
|
293
293
|
});
|
|
294
294
|
|
|
295
|
+
test('E2E: DB-backed path respects queue order (#2556)', async () => {
|
|
296
|
+
// Regression test for #2556: getActiveMilestoneId and deriveStateFromDb
|
|
297
|
+
// used lexicographic sort instead of queue order, causing a deadlock when
|
|
298
|
+
// the dispatch guard (which respects queue order) blocked completion.
|
|
299
|
+
const base = createFixtureBase();
|
|
300
|
+
try {
|
|
301
|
+
const { openDatabase, closeDatabase, insertMilestone, isDbAvailable } = await import('../gsd-db.ts');
|
|
302
|
+
const dbPath = join(base, '.gsd', 'gsd.db');
|
|
303
|
+
|
|
304
|
+
// Create milestone directories (required for findMilestoneIds)
|
|
305
|
+
writeMilestoneDir(base, 'M006');
|
|
306
|
+
writeContext(base, 'M006', '', 'Earlier milestone');
|
|
307
|
+
writeMilestoneDir(base, 'M008');
|
|
308
|
+
writeContext(base, 'M008', '', 'Later milestone');
|
|
309
|
+
|
|
310
|
+
// Open DB and insert milestones
|
|
311
|
+
openDatabase(dbPath);
|
|
312
|
+
try {
|
|
313
|
+
insertMilestone({ id: 'M006', title: 'Earlier', status: 'active' });
|
|
314
|
+
insertMilestone({ id: 'M008', title: 'Later', status: 'active' });
|
|
315
|
+
|
|
316
|
+
// Set queue order: M008 should come FIRST (user reordered via /gsd queue)
|
|
317
|
+
saveQueueOrder(base, ['M008', 'M006']);
|
|
318
|
+
|
|
319
|
+
// deriveState should pick M008 (queue-first), not M006 (ID-first)
|
|
320
|
+
invalidateStateCache();
|
|
321
|
+
const state = await deriveState(base);
|
|
322
|
+
assert.equal(
|
|
323
|
+
state.activeMilestone?.id,
|
|
324
|
+
'M008',
|
|
325
|
+
'DB-backed deriveState must respect queue order — M008 is queued first',
|
|
326
|
+
);
|
|
327
|
+
} finally {
|
|
328
|
+
if (isDbAvailable()) closeDatabase();
|
|
329
|
+
}
|
|
330
|
+
} finally {
|
|
331
|
+
cleanup(base);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
295
335
|
});
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "../reactive-graph.ts";
|
|
16
16
|
import { validatePreferences } from "../preferences-validation.ts";
|
|
17
17
|
import type { ReactiveExecutionState } from "../types.ts";
|
|
18
|
+
import { parseUnitId } from "../unit-id.ts";
|
|
18
19
|
|
|
19
20
|
// ─── Preference Validation ────────────────────────────────────────────────
|
|
20
21
|
|
|
@@ -441,13 +442,12 @@ test("unitId batch encoding round-trips correctly", () => {
|
|
|
441
442
|
const unitId = `${mid}/${sid}/reactive+${selected.join(",")}`;
|
|
442
443
|
|
|
443
444
|
// Parse it back
|
|
444
|
-
const
|
|
445
|
-
assert.equal(
|
|
446
|
-
assert.equal(
|
|
447
|
-
const
|
|
448
|
-
const plusIdx = batchPart.indexOf("+");
|
|
445
|
+
const { milestone, slice, task: batchPart } = parseUnitId(unitId);
|
|
446
|
+
assert.equal(milestone, "M001");
|
|
447
|
+
assert.equal(slice, "S01");
|
|
448
|
+
const plusIdx = batchPart!.indexOf("+");
|
|
449
449
|
assert.ok(plusIdx > 0, "Should have + separator");
|
|
450
|
-
const batchIds = batchPart
|
|
450
|
+
const batchIds = batchPart!.slice(plusIdx + 1).split(",");
|
|
451
451
|
assert.deepEqual(batchIds, ["T02", "T03", "T05"]);
|
|
452
452
|
});
|
|
453
453
|
|