gsd-pi 2.49.0 → 2.50.0-dev.d210a87
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/headless-ui.js +12 -2
- package/dist/headless.js +29 -13
- 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/infra-errors.js +1 -0
- package/dist/resources/extensions/gsd/auto/phases.js +27 -12
- package/dist/resources/extensions/gsd/auto/resolve.js +2 -2
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -2
- package/dist/resources/extensions/gsd/auto/session.js +9 -0
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +8 -10
- package/dist/resources/extensions/gsd/auto-dashboard.js +28 -6
- package/dist/resources/extensions/gsd/auto-dispatch.js +113 -74
- package/dist/resources/extensions/gsd/auto-observability.js +54 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +53 -99
- package/dist/resources/extensions/gsd/auto-prompts.js +155 -17
- package/dist/resources/extensions/gsd/auto-recovery.js +79 -205
- package/dist/resources/extensions/gsd/auto-start.js +4 -31
- package/dist/resources/extensions/gsd/auto-timers.js +2 -2
- package/dist/resources/extensions/gsd/auto-utils.js +20 -0
- package/dist/resources/extensions/gsd/auto-verification.js +4 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +257 -113
- package/dist/resources/extensions/gsd/auto.js +22 -10
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +24 -1
- package/dist/resources/extensions/gsd/branch-patterns.js +13 -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/doctor-checks.js +5 -1234
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +168 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +28 -7
- package/dist/resources/extensions/gsd/doctor-git-checks.js +405 -0
- package/dist/resources/extensions/gsd/doctor-global-checks.js +74 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +600 -0
- package/dist/resources/extensions/gsd/doctor.js +9 -1
- package/dist/resources/extensions/gsd/extension-manifest.json +1 -1
- package/dist/resources/extensions/gsd/files.js +5 -1
- package/dist/resources/extensions/gsd/git-service.js +9 -10
- package/dist/resources/extensions/gsd/gsd-db.js +124 -1
- package/dist/resources/extensions/gsd/guided-flow-queue.js +10 -11
- 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/markdown-renderer.js +33 -5
- 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 +3 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +64 -0
- package/dist/resources/extensions/gsd/preferences.js +3 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +9 -8
- package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -13
- package/dist/resources/extensions/gsd/prompts/forensics.md +19 -8
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
- package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +8 -3
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- 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/repo-identity.js +29 -0
- package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +2 -2
- 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 +13 -14
- package/dist/resources/extensions/gsd/session-lock.js +67 -56
- 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 +51 -12
- package/dist/resources/extensions/gsd/templates/milestone-summary.md +8 -0
- package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
- package/dist/resources/extensions/gsd/templates/plan.md +16 -0
- package/dist/resources/extensions/gsd/templates/preferences.md +2 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +13 -0
- package/dist/resources/extensions/gsd/templates/slice-summary.md +9 -0
- package/dist/resources/extensions/gsd/templates/task-plan.md +24 -0
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -3
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
- package/dist/resources/extensions/gsd/verdict-parser.js +84 -0
- package/dist/resources/extensions/gsd/verification-gate.js +3 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +24 -0
- package/dist/resources/extensions/gsd/worktree.js +3 -2
- package/dist/resources/extensions/remote-questions/config.js +3 -5
- package/dist/resources/extensions/search-the-web/native-search.js +8 -3
- package/dist/resources/extensions/search-the-web/tool-search.js +19 -2
- package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
- package/dist/resources/extensions/shared/rtk.js +100 -0
- package/dist/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
- 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 +20 -19
- 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 +20 -19
- 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/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/.next/static/yJIyd5cXPNpmXTv18ZlyC/_buildManifest.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +39 -10
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +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/providers/openai-codex-responses.ts +39 -8
- 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/blob-store.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/blob-store.js +8 -3
- package/packages/pi-coding-agent/dist/core/blob-store.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.js +9 -2
- package/packages/pi-coding-agent/dist/core/discovery-cache.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/retry-handler.js +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.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 +13 -36
- 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/jsonl.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js.map +1 -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 +0 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.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/blob-store.ts +6 -3
- package/packages/pi-coding-agent/src/core/discovery-cache.ts +9 -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/retry-handler.ts +1 -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 +13 -36
- 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/jsonl.ts +6 -0
- package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +0 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
- 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/infra-errors.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +25 -12
- package/src/resources/extensions/gsd/auto/resolve.ts +3 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -2
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto/types.ts +13 -0
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +19 -21
- package/src/resources/extensions/gsd/auto-dashboard.ts +36 -5
- package/src/resources/extensions/gsd/auto-dispatch.ts +122 -71
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-observability.ts +72 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +73 -110
- package/src/resources/extensions/gsd/auto-prompts.ts +159 -17
- package/src/resources/extensions/gsd/auto-recovery.ts +80 -221
- package/src/resources/extensions/gsd/auto-start.ts +7 -27
- package/src/resources/extensions/gsd/auto-timers.ts +2 -2
- package/src/resources/extensions/gsd/auto-utils.ts +25 -0
- package/src/resources/extensions/gsd/auto-verification.ts +4 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +305 -108
- package/src/resources/extensions/gsd/auto.ts +26 -15
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +93 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -0
- package/src/resources/extensions/gsd/branch-patterns.ts +16 -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/doctor-checks.ts +5 -1291
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +182 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +30 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +415 -0
- package/src/resources/extensions/gsd/doctor-global-checks.ts +84 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +626 -0
- package/src/resources/extensions/gsd/doctor.ts +9 -1
- package/src/resources/extensions/gsd/extension-manifest.json +1 -1
- package/src/resources/extensions/gsd/files.ts +6 -1
- package/src/resources/extensions/gsd/git-service.ts +7 -15
- package/src/resources/extensions/gsd/gsd-db.ts +150 -2
- package/src/resources/extensions/gsd/guided-flow-queue.ts +11 -12
- 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/markdown-renderer.ts +37 -4
- 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 +25 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +63 -0
- package/src/resources/extensions/gsd/preferences.ts +3 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
- package/src/resources/extensions/gsd/prompts/complete-slice.md +9 -8
- package/src/resources/extensions/gsd/prompts/execute-task.md +16 -13
- package/src/resources/extensions/gsd/prompts/forensics.md +19 -8
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +8 -3
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- 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/repo-identity.ts +28 -0
- package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +2 -2
- 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 +13 -14
- package/src/resources/extensions/gsd/session-lock.ts +92 -64
- 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 +54 -10
- package/src/resources/extensions/gsd/templates/milestone-summary.md +8 -0
- package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
- package/src/resources/extensions/gsd/templates/plan.md +16 -0
- package/src/resources/extensions/gsd/templates/preferences.md +2 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +13 -0
- package/src/resources/extensions/gsd/templates/slice-summary.md +9 -0
- package/src/resources/extensions/gsd/templates/task-plan.md +24 -0
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +2 -2
- 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 +103 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +1 -81
- 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.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +9 -12
- 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/doctor-environment.test.ts +115 -1
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +65 -1
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +189 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
- 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/infra-error.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +39 -0
- 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/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/quality-gates.test.ts +347 -0
- package/src/resources/extensions/gsd/tests/queue-completed-milestone-perf.test.ts +155 -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/replan-slice.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +32 -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/roadmap-slices.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +166 -16
- package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +223 -0
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +44 -4
- 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/tool-naming.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +0 -16
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +204 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +16 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -3
- package/src/resources/extensions/gsd/types.ts +32 -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/verdict-parser.ts +95 -0
- package/src/resources/extensions/gsd/verification-gate.ts +3 -3
- package/src/resources/extensions/gsd/worktree-resolver.ts +31 -0
- package/src/resources/extensions/gsd/worktree.ts +3 -2
- package/src/resources/extensions/remote-questions/config.ts +3 -5
- package/src/resources/extensions/search-the-web/native-search.ts +8 -3
- package/src/resources/extensions/search-the-web/tool-search.ts +22 -2
- package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
- package/src/resources/extensions/shared/rtk.ts +120 -0
- package/src/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +0 -191
- package/dist/resources/extensions/gsd/resource-version.js +0 -97
- 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/chunks/4024.11ca5c01938e5948.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-0a4cd455ec4197d2.js +0 -1
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
- package/dist/web/standalone/.next/static/gj-y5hikmhS--NT8Web6M/_buildManifest.js +0 -1
- package/packages/pi-ai/pnpm-lock.yaml +0 -2022
- package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -234
- package/src/resources/extensions/gsd/resource-version.ts +0 -101
- /package/dist/web/standalone/.next/static/{gj-y5hikmhS--NT8Web6M → yJIyd5cXPNpmXTv18ZlyC}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { extractSection } from "../files.ts";
|
|
5
|
+
import { createTestContext } from "./test-helpers.ts";
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const templatesDir = join(__dirname, "..", "templates");
|
|
9
|
+
const promptsDir = join(__dirname, "..", "prompts");
|
|
10
|
+
|
|
11
|
+
const { assertTrue, report } = createTestContext();
|
|
12
|
+
|
|
13
|
+
function loadTemplate(name: string): string {
|
|
14
|
+
return readFileSync(join(templatesDir, `${name}.md`), "utf-8");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function loadPrompt(name: string): string {
|
|
18
|
+
return readFileSync(join(promptsDir, `${name}.md`), "utf-8");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
22
|
+
// Level 1: Templates contain quality gate headings
|
|
23
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
24
|
+
|
|
25
|
+
console.log("\n=== Level 1: Templates contain quality gate headings ===");
|
|
26
|
+
{
|
|
27
|
+
const plan = loadTemplate("plan");
|
|
28
|
+
assertTrue(plan.includes("## Threat Surface"), "plan.md contains ## Threat Surface");
|
|
29
|
+
assertTrue(plan.includes("## Requirement Impact"), "plan.md contains ## Requirement Impact");
|
|
30
|
+
|
|
31
|
+
const taskPlan = loadTemplate("task-plan");
|
|
32
|
+
assertTrue(taskPlan.includes("## Failure Modes"), "task-plan.md contains ## Failure Modes");
|
|
33
|
+
assertTrue(taskPlan.includes("## Load Profile"), "task-plan.md contains ## Load Profile");
|
|
34
|
+
assertTrue(taskPlan.includes("## Negative Tests"), "task-plan.md contains ## Negative Tests");
|
|
35
|
+
|
|
36
|
+
const sliceSummary = loadTemplate("slice-summary");
|
|
37
|
+
assertTrue(sliceSummary.includes("## Operational Readiness"), "slice-summary.md contains ## Operational Readiness");
|
|
38
|
+
|
|
39
|
+
const roadmap = loadTemplate("roadmap");
|
|
40
|
+
assertTrue(roadmap.includes("## Horizontal Checklist"), "roadmap.md contains ## Horizontal Checklist");
|
|
41
|
+
|
|
42
|
+
const milestoneSummary = loadTemplate("milestone-summary");
|
|
43
|
+
assertTrue(milestoneSummary.includes("## Decision Re-evaluation"), "milestone-summary.md contains ## Decision Re-evaluation");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
47
|
+
// Level 2: Prompts reference quality gates
|
|
48
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
49
|
+
|
|
50
|
+
console.log("\n=== Level 2: Prompts reference quality gates ===");
|
|
51
|
+
{
|
|
52
|
+
const planSlice = loadPrompt("plan-slice");
|
|
53
|
+
assertTrue(planSlice.includes("Threat Surface"), "plan-slice.md mentions Threat Surface");
|
|
54
|
+
assertTrue(planSlice.includes("Requirement Impact"), "plan-slice.md mentions Requirement Impact");
|
|
55
|
+
assertTrue(planSlice.toLowerCase().includes("quality gate"), "plan-slice.md mentions quality gate");
|
|
56
|
+
|
|
57
|
+
const guidedPlanSlice = loadPrompt("guided-plan-slice");
|
|
58
|
+
assertTrue(
|
|
59
|
+
guidedPlanSlice.includes("Threat Surface") || guidedPlanSlice.includes("Q3"),
|
|
60
|
+
"guided-plan-slice.md mentions Threat Surface or Q3"
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const executeTask = loadPrompt("execute-task");
|
|
64
|
+
assertTrue(executeTask.includes("Failure Modes"), "execute-task.md mentions Failure Modes");
|
|
65
|
+
assertTrue(executeTask.includes("Load Profile"), "execute-task.md mentions Load Profile");
|
|
66
|
+
assertTrue(executeTask.includes("Negative Tests"), "execute-task.md mentions Negative Tests");
|
|
67
|
+
|
|
68
|
+
const guidedExecuteTask = loadPrompt("guided-execute-task");
|
|
69
|
+
assertTrue(
|
|
70
|
+
guidedExecuteTask.includes("Failure Modes") || guidedExecuteTask.includes("Q5"),
|
|
71
|
+
"guided-execute-task.md mentions Failure Modes or Q5"
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const completeSlice = loadPrompt("complete-slice");
|
|
75
|
+
assertTrue(completeSlice.includes("Operational Readiness"), "complete-slice.md mentions Operational Readiness");
|
|
76
|
+
|
|
77
|
+
const guidedCompleteSlice = loadPrompt("guided-complete-slice");
|
|
78
|
+
assertTrue(
|
|
79
|
+
guidedCompleteSlice.includes("Operational Readiness") || guidedCompleteSlice.includes("Q8"),
|
|
80
|
+
"guided-complete-slice.md mentions Operational Readiness or Q8"
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const completeMilestone = loadPrompt("complete-milestone");
|
|
84
|
+
assertTrue(completeMilestone.includes("Horizontal Checklist"), "complete-milestone.md mentions Horizontal Checklist");
|
|
85
|
+
assertTrue(completeMilestone.includes("Decision Re-evaluation"), "complete-milestone.md mentions Decision Re-evaluation");
|
|
86
|
+
|
|
87
|
+
const planMilestone = loadPrompt("plan-milestone");
|
|
88
|
+
assertTrue(planMilestone.toLowerCase().includes("horizontal checklist"), "plan-milestone.md mentions horizontal checklist");
|
|
89
|
+
|
|
90
|
+
const guidedPlanMilestone = loadPrompt("guided-plan-milestone");
|
|
91
|
+
assertTrue(guidedPlanMilestone.includes("Horizontal Checklist"), "guided-plan-milestone.md mentions Horizontal Checklist");
|
|
92
|
+
|
|
93
|
+
const reassess = loadPrompt("reassess-roadmap");
|
|
94
|
+
assertTrue(reassess.includes("Threat Surface"), "reassess-roadmap.md mentions Threat Surface");
|
|
95
|
+
assertTrue(reassess.includes("Operational Readiness"), "reassess-roadmap.md mentions Operational Readiness");
|
|
96
|
+
assertTrue(reassess.includes("Horizontal Checklist"), "reassess-roadmap.md mentions Horizontal Checklist");
|
|
97
|
+
|
|
98
|
+
const replan = loadPrompt("replan-slice");
|
|
99
|
+
assertTrue(replan.includes("Threat Surface"), "replan-slice.md mentions Threat Surface");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
103
|
+
// Level 3: Parser backward compatibility — extractSection handles new headings
|
|
104
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
105
|
+
|
|
106
|
+
console.log("\n=== Level 3: extractSection backward compatibility ===");
|
|
107
|
+
{
|
|
108
|
+
// Old-style slice plan (no quality gate sections)
|
|
109
|
+
const oldPlan = `# S01: Auth Flow
|
|
110
|
+
|
|
111
|
+
**Goal:** Build login
|
|
112
|
+
**Demo:** User can log in
|
|
113
|
+
|
|
114
|
+
## Must-Haves
|
|
115
|
+
|
|
116
|
+
- Login form works
|
|
117
|
+
- Session persists
|
|
118
|
+
|
|
119
|
+
## Proof Level
|
|
120
|
+
|
|
121
|
+
- This slice proves: integration
|
|
122
|
+
|
|
123
|
+
## Tasks
|
|
124
|
+
|
|
125
|
+
- [ ] **T01: Build login** \`est:1h\`
|
|
126
|
+
`;
|
|
127
|
+
|
|
128
|
+
// New-style slice plan (with quality gate sections)
|
|
129
|
+
const newPlan = `# S01: Auth Flow
|
|
130
|
+
|
|
131
|
+
**Goal:** Build login
|
|
132
|
+
**Demo:** User can log in
|
|
133
|
+
|
|
134
|
+
## Must-Haves
|
|
135
|
+
|
|
136
|
+
- Login form works
|
|
137
|
+
- Session persists
|
|
138
|
+
|
|
139
|
+
## Threat Surface
|
|
140
|
+
|
|
141
|
+
- **Abuse**: Credential stuffing, brute force login attempts
|
|
142
|
+
- **Data exposure**: Session tokens in cookies, password in request body
|
|
143
|
+
- **Input trust**: Username/password from form input reaching DB query
|
|
144
|
+
|
|
145
|
+
## Requirement Impact
|
|
146
|
+
|
|
147
|
+
- **Requirements touched**: R001, R003
|
|
148
|
+
- **Re-verify**: Login flow, session management
|
|
149
|
+
- **Decisions revisited**: D002
|
|
150
|
+
|
|
151
|
+
## Proof Level
|
|
152
|
+
|
|
153
|
+
- This slice proves: integration
|
|
154
|
+
|
|
155
|
+
## Tasks
|
|
156
|
+
|
|
157
|
+
- [ ] **T01: Build login** \`est:1h\`
|
|
158
|
+
`;
|
|
159
|
+
|
|
160
|
+
// Old plan: quality gate sections return null (not found)
|
|
161
|
+
assertTrue(
|
|
162
|
+
extractSection(oldPlan, "Threat Surface") === null,
|
|
163
|
+
"extractSection returns null for Threat Surface on old plan"
|
|
164
|
+
);
|
|
165
|
+
assertTrue(
|
|
166
|
+
extractSection(oldPlan, "Requirement Impact") === null,
|
|
167
|
+
"extractSection returns null for Requirement Impact on old plan"
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Old plan: core sections still parse correctly
|
|
171
|
+
const oldMustHaves = extractSection(oldPlan, "Must-Haves");
|
|
172
|
+
assertTrue(
|
|
173
|
+
oldMustHaves !== null && oldMustHaves.includes("Login form works"),
|
|
174
|
+
"extractSection still parses Must-Haves on old plan"
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// New plan: quality gate sections are extracted
|
|
178
|
+
const threatSurface = extractSection(newPlan, "Threat Surface");
|
|
179
|
+
assertTrue(
|
|
180
|
+
threatSurface !== null && threatSurface.includes("Credential stuffing"),
|
|
181
|
+
"extractSection extracts Threat Surface content from new plan"
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const reqImpact = extractSection(newPlan, "Requirement Impact");
|
|
185
|
+
assertTrue(
|
|
186
|
+
reqImpact !== null && reqImpact.includes("R001"),
|
|
187
|
+
"extractSection extracts Requirement Impact content from new plan"
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
// New plan: core sections still parse correctly
|
|
191
|
+
const newMustHaves = extractSection(newPlan, "Must-Haves");
|
|
192
|
+
assertTrue(
|
|
193
|
+
newMustHaves !== null && newMustHaves.includes("Login form works"),
|
|
194
|
+
"extractSection still parses Must-Haves on new plan"
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Task plan: Failure Modes
|
|
198
|
+
const oldTaskPlan = `# T01: Build Login
|
|
199
|
+
|
|
200
|
+
## Description
|
|
201
|
+
|
|
202
|
+
Build the login endpoint.
|
|
203
|
+
|
|
204
|
+
## Steps
|
|
205
|
+
|
|
206
|
+
1. Create route
|
|
207
|
+
`;
|
|
208
|
+
|
|
209
|
+
const newTaskPlan = `# T01: Build Login
|
|
210
|
+
|
|
211
|
+
## Description
|
|
212
|
+
|
|
213
|
+
Build the login endpoint.
|
|
214
|
+
|
|
215
|
+
## Failure Modes
|
|
216
|
+
|
|
217
|
+
| Dependency | On error | On timeout | On malformed response |
|
|
218
|
+
|------------|----------|-----------|----------------------|
|
|
219
|
+
| Auth DB | Return 500 | 3s timeout, retry once | Reject, log warning |
|
|
220
|
+
|
|
221
|
+
## Steps
|
|
222
|
+
|
|
223
|
+
1. Create route
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
assertTrue(
|
|
227
|
+
extractSection(oldTaskPlan, "Failure Modes") === null,
|
|
228
|
+
"extractSection returns null for Failure Modes on old task plan"
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const failureModes = extractSection(newTaskPlan, "Failure Modes");
|
|
232
|
+
assertTrue(
|
|
233
|
+
failureModes !== null && failureModes.includes("Auth DB"),
|
|
234
|
+
"extractSection extracts Failure Modes content from new task plan"
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// Slice summary: Operational Readiness
|
|
238
|
+
const oldSummary = `# S01: Auth Flow
|
|
239
|
+
|
|
240
|
+
**Built login with session management**
|
|
241
|
+
|
|
242
|
+
## Verification
|
|
243
|
+
|
|
244
|
+
All tests pass.
|
|
245
|
+
|
|
246
|
+
## Deviations
|
|
247
|
+
|
|
248
|
+
None.
|
|
249
|
+
`;
|
|
250
|
+
|
|
251
|
+
const newSummary = `# S01: Auth Flow
|
|
252
|
+
|
|
253
|
+
**Built login with session management**
|
|
254
|
+
|
|
255
|
+
## Verification
|
|
256
|
+
|
|
257
|
+
All tests pass.
|
|
258
|
+
|
|
259
|
+
## Operational Readiness
|
|
260
|
+
|
|
261
|
+
- **Health signal**: /health endpoint returns 200 with session count
|
|
262
|
+
- **Failure signal**: Auth error rate > 5% triggers alert
|
|
263
|
+
- **Recovery**: Stateless — restart clears nothing
|
|
264
|
+
- **Monitoring gaps**: None
|
|
265
|
+
|
|
266
|
+
## Deviations
|
|
267
|
+
|
|
268
|
+
None.
|
|
269
|
+
`;
|
|
270
|
+
|
|
271
|
+
assertTrue(
|
|
272
|
+
extractSection(oldSummary, "Operational Readiness") === null,
|
|
273
|
+
"extractSection returns null for Operational Readiness on old summary"
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const opReadiness = extractSection(newSummary, "Operational Readiness");
|
|
277
|
+
assertTrue(
|
|
278
|
+
opReadiness !== null && opReadiness.includes("/health endpoint"),
|
|
279
|
+
"extractSection extracts Operational Readiness content from new summary"
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
284
|
+
// Level 4: Template section ordering is correct
|
|
285
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
286
|
+
|
|
287
|
+
console.log("\n=== Level 4: Template section ordering ===");
|
|
288
|
+
{
|
|
289
|
+
const plan = loadTemplate("plan");
|
|
290
|
+
const mustHavesIdx = plan.indexOf("## Must-Haves");
|
|
291
|
+
const threatIdx = plan.indexOf("## Threat Surface");
|
|
292
|
+
const proofIdx = plan.indexOf("## Proof Level");
|
|
293
|
+
assertTrue(
|
|
294
|
+
mustHavesIdx < threatIdx && threatIdx < proofIdx,
|
|
295
|
+
"plan.md: Threat Surface is between Must-Haves and Proof Level"
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const reqImpactIdx = plan.indexOf("## Requirement Impact");
|
|
299
|
+
assertTrue(
|
|
300
|
+
threatIdx < reqImpactIdx && reqImpactIdx < proofIdx,
|
|
301
|
+
"plan.md: Requirement Impact is between Threat Surface and Proof Level"
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
const taskPlan = loadTemplate("task-plan");
|
|
305
|
+
const descIdx = taskPlan.indexOf("## Description");
|
|
306
|
+
const failIdx = taskPlan.indexOf("## Failure Modes");
|
|
307
|
+
const stepsIdx = taskPlan.indexOf("## Steps");
|
|
308
|
+
assertTrue(
|
|
309
|
+
descIdx < failIdx && failIdx < stepsIdx,
|
|
310
|
+
"task-plan.md: Failure Modes is between Description and Steps"
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
const loadIdx = taskPlan.indexOf("## Load Profile");
|
|
314
|
+
const negIdx = taskPlan.indexOf("## Negative Tests");
|
|
315
|
+
assertTrue(
|
|
316
|
+
failIdx < loadIdx && loadIdx < negIdx && negIdx < stepsIdx,
|
|
317
|
+
"task-plan.md: Failure Modes < Load Profile < Negative Tests < Steps"
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
const sliceSummary = loadTemplate("slice-summary");
|
|
321
|
+
const reqInvalidIdx = sliceSummary.indexOf("## Requirements Invalidated");
|
|
322
|
+
const opIdx = sliceSummary.indexOf("## Operational Readiness");
|
|
323
|
+
const devIdx = sliceSummary.indexOf("## Deviations");
|
|
324
|
+
assertTrue(
|
|
325
|
+
reqInvalidIdx < opIdx && opIdx < devIdx,
|
|
326
|
+
"slice-summary.md: Operational Readiness is between Requirements Invalidated and Deviations"
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
const roadmap = loadTemplate("roadmap");
|
|
330
|
+
const horizIdx = roadmap.indexOf("## Horizontal Checklist");
|
|
331
|
+
const boundaryIdx = roadmap.indexOf("## Boundary Map");
|
|
332
|
+
assertTrue(
|
|
333
|
+
horizIdx > 0 && horizIdx < boundaryIdx,
|
|
334
|
+
"roadmap.md: Horizontal Checklist is before Boundary Map"
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
const milestoneSummary = loadTemplate("milestone-summary");
|
|
338
|
+
const reqChangesIdx = milestoneSummary.indexOf("## Requirement Changes");
|
|
339
|
+
const decRevalIdx = milestoneSummary.indexOf("## Decision Re-evaluation");
|
|
340
|
+
const fwdIntelIdx = milestoneSummary.indexOf("## Forward Intelligence");
|
|
341
|
+
assertTrue(
|
|
342
|
+
reqChangesIdx < decRevalIdx && decRevalIdx < fwdIntelIdx,
|
|
343
|
+
"milestone-summary.md: Decision Re-evaluation is between Requirement Changes and Forward Intelligence"
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
report();
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for #2379: /gsd queue fails with 429 rate limit on projects
|
|
3
|
+
* with many completed milestones.
|
|
4
|
+
*
|
|
5
|
+
* The bug: buildExistingMilestonesContext iterates over ALL milestones
|
|
6
|
+
* (including completed ones) and calls loadFile for CONTEXT, SUMMARY,
|
|
7
|
+
* CONTEXT-DRAFT, and ROADMAP files on each — causing excessive I/O that
|
|
8
|
+
* triggers rate limits on large projects.
|
|
9
|
+
*
|
|
10
|
+
* The fix: completed milestones should emit a short summary line without
|
|
11
|
+
* loading their heavy artifact files (CONTEXT.md, SUMMARY.md, etc.).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
|
|
18
|
+
import { buildExistingMilestonesContext } from "../guided-flow-queue.ts";
|
|
19
|
+
import type { GSDState, MilestoneRegistryEntry } from "../types.ts";
|
|
20
|
+
import { createTestContext } from "./test-helpers.ts";
|
|
21
|
+
|
|
22
|
+
const { assertTrue, assertEq, report } = createTestContext();
|
|
23
|
+
|
|
24
|
+
// ─── Fixture: project with many completed milestones ─────────────────────
|
|
25
|
+
|
|
26
|
+
const tmpBase = mkdtempSync(join(tmpdir(), "gsd-queue-perf-"));
|
|
27
|
+
const gsd = join(tmpBase, ".gsd");
|
|
28
|
+
mkdirSync(join(gsd, "milestones"), { recursive: true });
|
|
29
|
+
|
|
30
|
+
const COMPLETED_COUNT = 25;
|
|
31
|
+
const ACTIVE_COUNT = 1;
|
|
32
|
+
const PENDING_COUNT = 2;
|
|
33
|
+
|
|
34
|
+
const allMilestoneIds: string[] = [];
|
|
35
|
+
const registry: MilestoneRegistryEntry[] = [];
|
|
36
|
+
|
|
37
|
+
// Create 25 completed milestones with CONTEXT.md and SUMMARY.md files
|
|
38
|
+
for (let i = 1; i <= COMPLETED_COUNT; i++) {
|
|
39
|
+
const mid = `M${String(i).padStart(3, "0")}`;
|
|
40
|
+
allMilestoneIds.push(mid);
|
|
41
|
+
registry.push({ id: mid, title: `Completed milestone ${i}`, status: "complete" });
|
|
42
|
+
mkdirSync(join(gsd, "milestones", mid), { recursive: true });
|
|
43
|
+
writeFileSync(
|
|
44
|
+
join(gsd, "milestones", mid, `${mid}-CONTEXT.md`),
|
|
45
|
+
`# ${mid}: Completed milestone ${i}\n\nThis is a large context document for ${mid}.\n${"Lorem ipsum dolor sit amet. ".repeat(50)}\n`,
|
|
46
|
+
);
|
|
47
|
+
writeFileSync(
|
|
48
|
+
join(gsd, "milestones", mid, `${mid}-SUMMARY.md`),
|
|
49
|
+
`# ${mid} Summary\n\nDelivered feature ${i} successfully.\n`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Create 1 active milestone
|
|
54
|
+
{
|
|
55
|
+
const mid = `M${String(COMPLETED_COUNT + 1).padStart(3, "0")}`;
|
|
56
|
+
allMilestoneIds.push(mid);
|
|
57
|
+
registry.push({ id: mid, title: "Active milestone", status: "active" });
|
|
58
|
+
mkdirSync(join(gsd, "milestones", mid), { recursive: true });
|
|
59
|
+
writeFileSync(
|
|
60
|
+
join(gsd, "milestones", mid, `${mid}-CONTEXT.md`),
|
|
61
|
+
`# ${mid}: Active milestone\n\nCurrently in progress.\n`,
|
|
62
|
+
);
|
|
63
|
+
writeFileSync(
|
|
64
|
+
join(gsd, "milestones", mid, `${mid}-ROADMAP.md`),
|
|
65
|
+
`# ${mid} Roadmap\n\nSlices planned.\n`,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Create 2 pending milestones
|
|
70
|
+
for (let i = 0; i < PENDING_COUNT; i++) {
|
|
71
|
+
const mid = `M${String(COMPLETED_COUNT + ACTIVE_COUNT + 1 + i).padStart(3, "0")}`;
|
|
72
|
+
allMilestoneIds.push(mid);
|
|
73
|
+
registry.push({ id: mid, title: `Pending milestone ${i + 1}`, status: "pending" });
|
|
74
|
+
mkdirSync(join(gsd, "milestones", mid), { recursive: true });
|
|
75
|
+
writeFileSync(
|
|
76
|
+
join(gsd, "milestones", mid, `${mid}-CONTEXT.md`),
|
|
77
|
+
`# ${mid}: Pending milestone ${i + 1}\n\nQueued work.\n`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const state: GSDState = {
|
|
82
|
+
activeMilestone: { id: `M${String(COMPLETED_COUNT + 1).padStart(3, "0")}`, title: "Active milestone" },
|
|
83
|
+
activeSlice: null,
|
|
84
|
+
activeTask: null,
|
|
85
|
+
phase: "executing",
|
|
86
|
+
recentDecisions: [],
|
|
87
|
+
blockers: [],
|
|
88
|
+
nextAction: "",
|
|
89
|
+
registry,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// ─── Test: completed milestones should NOT have their files loaded ────────
|
|
93
|
+
|
|
94
|
+
console.log("\n=== Queue completed milestone performance (#2379) ===");
|
|
95
|
+
|
|
96
|
+
const context = await buildExistingMilestonesContext(tmpBase, allMilestoneIds, state);
|
|
97
|
+
|
|
98
|
+
// Active and pending milestones SHOULD have full context loaded
|
|
99
|
+
const activeMid = `M${String(COMPLETED_COUNT + 1).padStart(3, "0")}`;
|
|
100
|
+
assertTrue(
|
|
101
|
+
context.includes("Currently in progress"),
|
|
102
|
+
"Active milestone context content should be loaded",
|
|
103
|
+
);
|
|
104
|
+
assertTrue(
|
|
105
|
+
context.includes("Slices planned"),
|
|
106
|
+
"Active milestone roadmap should be loaded",
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
for (let i = 0; i < PENDING_COUNT; i++) {
|
|
110
|
+
const mid = `M${String(COMPLETED_COUNT + ACTIVE_COUNT + 1 + i).padStart(3, "0")}`;
|
|
111
|
+
assertTrue(
|
|
112
|
+
context.includes(`Pending milestone ${i + 1}`),
|
|
113
|
+
`Pending milestone ${mid} context should be loaded`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Completed milestones should NOT have their CONTEXT.md body or SUMMARY.md
|
|
118
|
+
// content loaded — only a status line
|
|
119
|
+
for (let i = 1; i <= COMPLETED_COUNT; i++) {
|
|
120
|
+
const mid = `M${String(i).padStart(3, "0")}`;
|
|
121
|
+
|
|
122
|
+
// Should still mention the milestone ID and status
|
|
123
|
+
assertTrue(
|
|
124
|
+
context.includes(mid),
|
|
125
|
+
`Completed milestone ${mid} should still be referenced`,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Should NOT contain the heavy context body text
|
|
129
|
+
assertTrue(
|
|
130
|
+
!context.includes(`This is a large context document for ${mid}`),
|
|
131
|
+
`Completed milestone ${mid} should NOT have its full CONTEXT.md body loaded`,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Should NOT contain the summary body
|
|
135
|
+
assertTrue(
|
|
136
|
+
!context.includes(`Delivered feature ${i} successfully`),
|
|
137
|
+
`Completed milestone ${mid} should NOT have its SUMMARY.md body loaded`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ─── Test: the overall context should be reasonable in size ──────────────
|
|
142
|
+
|
|
143
|
+
// With 25 completed milestones NOT loading files, the context should be
|
|
144
|
+
// significantly smaller than if all files were loaded
|
|
145
|
+
const contextLines = context.split("\n").length;
|
|
146
|
+
assertTrue(
|
|
147
|
+
contextLines < 200,
|
|
148
|
+
`Context should be concise (got ${contextLines} lines); completed milestones should not inflate it`,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// ─── Cleanup ──────────────────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
rmSync(tmpBase, { recursive: true, force: true });
|
|
154
|
+
|
|
155
|
+
report();
|
|
@@ -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
|
|
|
@@ -503,7 +503,8 @@ console.log('\n=== doctor: no blocker → no blocker_discovered_no_replan issue
|
|
|
503
503
|
// Artifact Resolution: resolveExpectedArtifactPath for replan-slice (#858)
|
|
504
504
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
505
505
|
|
|
506
|
-
import { resolveExpectedArtifactPath
|
|
506
|
+
import { resolveExpectedArtifactPath } from '../auto-artifact-paths.ts';
|
|
507
|
+
import { verifyExpectedArtifact } from '../auto-recovery.ts';
|
|
507
508
|
|
|
508
509
|
|
|
509
510
|
describe('replan-slice', () => {
|
|
@@ -184,6 +184,38 @@ test('subdirectory of parent repo gets unique identity after git init (#1639)',
|
|
|
184
184
|
rmSync(parentRepo, { recursive: true, force: true });
|
|
185
185
|
});
|
|
186
186
|
|
|
187
|
+
test('ensureGsdSymlink from subdirectory does not create .gsd in subdir when git-root .gsd exists (#2380)', () => {
|
|
188
|
+
const repo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-subdir-symlink-")));
|
|
189
|
+
run("git init -b main", repo);
|
|
190
|
+
run('git config user.name "Pi Test"', repo);
|
|
191
|
+
run('git config user.email "pi@example.com"', repo);
|
|
192
|
+
run('git remote add origin git@github.com:example/subdir-test.git', repo);
|
|
193
|
+
writeFileSync(join(repo, "README.md"), "# Subdir Test\n", "utf-8");
|
|
194
|
+
run("git add README.md", repo);
|
|
195
|
+
run('git commit -m "init"', repo);
|
|
196
|
+
|
|
197
|
+
// Set up .gsd symlink at the git root (normal project initialisation)
|
|
198
|
+
ensureGsdSymlink(repo);
|
|
199
|
+
assert.ok(existsSync(join(repo, ".gsd")), "root .gsd exists after ensureGsdSymlink");
|
|
200
|
+
assert.ok(lstatSync(join(repo, ".gsd")).isSymbolicLink(), "root .gsd is a symlink");
|
|
201
|
+
|
|
202
|
+
// Create a subdirectory and call ensureGsdSymlink from there
|
|
203
|
+
const subdir = join(repo, "src", "lib");
|
|
204
|
+
mkdirSync(subdir, { recursive: true });
|
|
205
|
+
ensureGsdSymlink(subdir);
|
|
206
|
+
|
|
207
|
+
// ensureGsdSymlink should NOT create a .gsd in the subdirectory
|
|
208
|
+
// because the git root already has a valid .gsd symlink.
|
|
209
|
+
assert.ok(!existsSync(join(subdir, ".gsd")), "no .gsd created in subdirectory when git-root .gsd exists (#2380)");
|
|
210
|
+
assert.ok(!existsSync(join(repo, "src", ".gsd")), "no .gsd created in intermediate directory");
|
|
211
|
+
|
|
212
|
+
// The root .gsd should still be intact
|
|
213
|
+
assert.ok(existsSync(join(repo, ".gsd")), "root .gsd still exists");
|
|
214
|
+
assert.ok(lstatSync(join(repo, ".gsd")).isSymbolicLink(), "root .gsd is still a symlink");
|
|
215
|
+
|
|
216
|
+
rmSync(repo, { recursive: true, force: true });
|
|
217
|
+
});
|
|
218
|
+
|
|
187
219
|
test('validateProjectId rejects invalid values', () => {
|
|
188
220
|
for (const invalid of ["has spaces", "path/traversal", "dot..dot", "back\\slash"]) {
|
|
189
221
|
assert.ok(!validateProjectId(invalid), `validateProjectId rejects invalid value: "${invalid}"`);
|