@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.97ef11e3
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 +10 -8
- package/dist/cli.js +5 -1
- package/dist/headless-events.d.ts +2 -1
- package/dist/headless-events.js +11 -3
- package/dist/headless-milestone-readiness.d.ts +29 -0
- package/dist/headless-milestone-readiness.js +161 -0
- package/dist/headless.js +27 -3
- package/dist/print-mode-exit.d.ts +12 -0
- package/dist/print-mode-exit.js +14 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +18 -49
- package/dist/resources/extensions/browser-tools/capture.js +2 -77
- package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
- package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
- package/dist/resources/extensions/gsd/auto/loop.js +24 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
- package/dist/resources/extensions/gsd/auto/unit-phase.js +37 -5
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
- package/dist/resources/extensions/gsd/auto-dispatch.js +76 -19
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +137 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -5
- package/dist/resources/extensions/gsd/auto-start.js +29 -9
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +40 -0
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +20 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
- package/dist/resources/extensions/gsd/command-feedback.js +16 -12
- package/dist/resources/extensions/gsd/commands-verdict.js +10 -9
- package/dist/resources/extensions/gsd/compat/compat-marker.js +98 -6
- package/dist/resources/extensions/gsd/constants.js +12 -13
- package/dist/resources/extensions/gsd/context-masker.js +97 -21
- package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +56 -18
- package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
- package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
- package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
- package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +24 -8
- package/dist/resources/extensions/gsd/error-classifier.js +12 -2
- package/dist/resources/extensions/gsd/exec-sandbox.js +1 -0
- package/dist/resources/extensions/gsd/flat-phase-migration.js +168 -21
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +262 -76
- package/dist/resources/extensions/gsd/guided-flow.js +40 -15
- package/dist/resources/extensions/gsd/markdown-renderer.js +20 -22
- package/dist/resources/extensions/gsd/md-importer.js +107 -20
- package/dist/resources/extensions/gsd/migrate/command.js +19 -162
- package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
- package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
- package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
- package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
- package/dist/resources/extensions/gsd/model-router.js +11 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
- package/dist/resources/extensions/gsd/paths.js +70 -16
- package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
- package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
- package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
- package/dist/resources/extensions/gsd/preferences-types.js +5 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
- package/dist/resources/extensions/gsd/preferences.js +17 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
- package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
- package/dist/resources/extensions/gsd/skill-activation.js +17 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +125 -15
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +17 -4
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +5 -2
- package/dist/resources/extensions/gsd/stop-notice.js +24 -1
- package/dist/resources/extensions/gsd/sync-lock.js +13 -7
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
- package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
- package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
- package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
- package/dist/resources/extensions/gsd/unit-registry.js +4 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
- package/dist/resources/extensions/gsd/workspace.js +2 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +26 -18
- package/dist/resources/extensions/mac-tools/index.js +31 -9
- package/dist/resources/extensions/shared/interview-ui.js +43 -6
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- 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 +1 -1
- 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_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_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_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_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_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_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_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_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_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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- 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_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_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_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_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_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_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_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_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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/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_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_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_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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- 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_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_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_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_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_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_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_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_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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +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_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_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_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_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_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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
- package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- 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/package.json +0 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +31 -3
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +13 -10
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -1
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +5 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/cloud-config.test.js +51 -1
- package/packages/daemon/dist/cloud-config.test.js.map +1 -1
- package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
- package/packages/daemon/dist/local-tool-executor.js +2 -0
- package/packages/daemon/dist/local-tool-executor.js.map +1 -1
- package/packages/daemon/package.json +6 -6
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +1 -0
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/README.md +9 -3
- package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/background-cli.test.js +248 -0
- package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cli.d.ts +5 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cli.js +266 -0
- package/packages/gsd-cloud/dist/cli.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.js +237 -0
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +33 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js +260 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.js +37 -0
- package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
- package/packages/gsd-cloud/dist/config.d.ts +17 -0
- package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/config.js +146 -0
- package/packages/gsd-cloud/dist/config.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.js +128 -0
- package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
- package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.js +11 -0
- package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.js +29 -0
- package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
- package/packages/gsd-cloud/dist/index.d.ts +7 -0
- package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/index.js +8 -0
- package/packages/gsd-cloud/dist/index.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
- package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
- package/packages/gsd-cloud/dist/logger.d.ts +25 -0
- package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/logger.js +72 -0
- package/packages/gsd-cloud/dist/logger.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.d.ts +27 -0
- package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.js +272 -0
- package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.test.js +97 -0
- package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
- package/packages/gsd-cloud/dist/types.d.ts +51 -0
- package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/types.js +9 -0
- package/packages/gsd-cloud/dist/types.js.map +1 -0
- package/packages/gsd-cloud/package.json +3 -3
- package/packages/mcp-server/README.md +15 -2
- package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
- package/packages/mcp-server/dist/cli-runner.js +119 -33
- package/packages/mcp-server/dist/cli-runner.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +5 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +64 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +136 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +124 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +25 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +103 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +18 -49
- package/src/resources/extensions/browser-tools/capture.ts +2 -86
- package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
- package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
- package/src/resources/extensions/gsd/auto/loop.ts +48 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
- package/src/resources/extensions/gsd/auto/unit-phase.ts +41 -5
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
- package/src/resources/extensions/gsd/auto-dispatch.ts +87 -19
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +156 -20
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-runtime-state.ts +12 -7
- package/src/resources/extensions/gsd/auto-start.ts +31 -8
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +56 -0
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +25 -8
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -12
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
- package/src/resources/extensions/gsd/command-feedback.ts +19 -12
- package/src/resources/extensions/gsd/commands-verdict.ts +16 -9
- package/src/resources/extensions/gsd/compat/compat-marker.ts +119 -8
- package/src/resources/extensions/gsd/constants.ts +14 -13
- package/src/resources/extensions/gsd/context-masker.ts +98 -2
- package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +58 -19
- package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
- package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
- package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
- package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +30 -7
- package/src/resources/extensions/gsd/error-classifier.ts +13 -2
- package/src/resources/extensions/gsd/exec-sandbox.ts +1 -0
- package/src/resources/extensions/gsd/flat-phase-migration.ts +174 -19
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +340 -85
- package/src/resources/extensions/gsd/guided-flow.ts +50 -14
- package/src/resources/extensions/gsd/markdown-renderer.ts +28 -30
- package/src/resources/extensions/gsd/md-importer.ts +114 -16
- package/src/resources/extensions/gsd/migrate/command.ts +21 -227
- package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
- package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
- package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
- package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
- package/src/resources/extensions/gsd/model-router.ts +12 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
- package/src/resources/extensions/gsd/paths.ts +77 -16
- package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
- package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
- package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
- package/src/resources/extensions/gsd/preferences.ts +25 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
- package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
- package/src/resources/extensions/gsd/skill-activation.ts +17 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +162 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +20 -4
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +4 -2
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
- package/src/resources/extensions/gsd/stop-notice.ts +29 -1
- package/src/resources/extensions/gsd/sync-lock.ts +14 -6
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
- package/src/resources/extensions/gsd/tests/db-engine-cjs-compat.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
- package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
- package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
- package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
- package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
- package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
- package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
- package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
- package/src/resources/extensions/gsd/types.ts +11 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
- package/src/resources/extensions/gsd/unit-registry.ts +4 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
- package/src/resources/extensions/gsd/workspace.ts +2 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -24
- package/src/resources/extensions/mac-tools/index.ts +52 -9
- package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
- package/src/resources/extensions/shared/interview-ui.ts +47 -8
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +29 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// GSD Extension - Migration guard tests (plan 026).
|
|
2
|
+
// Covers the newer-DB refusal in migrateSchema, whole-chain rollback atomicity
|
|
3
|
+
// via the _setMigrationFaultForTest seam, the legacy-data guard in initSchema,
|
|
4
|
+
// and getCurrentSchemaVersion's empty-table NULL handling.
|
|
5
|
+
|
|
6
|
+
import { describe, test } from 'node:test';
|
|
7
|
+
import assert from 'node:assert/strict';
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
openDatabase,
|
|
15
|
+
closeDatabase,
|
|
16
|
+
isDbAvailable,
|
|
17
|
+
SCHEMA_VERSION,
|
|
18
|
+
_setMigrationFaultForTest,
|
|
19
|
+
} from '../gsd-db.ts';
|
|
20
|
+
import { createDbAdapter } from '../db-adapter.ts';
|
|
21
|
+
import { getCurrentSchemaVersion } from '../db-schema-metadata.ts';
|
|
22
|
+
|
|
23
|
+
const _require = createRequire(import.meta.url);
|
|
24
|
+
|
|
25
|
+
function tempDbPath(): string {
|
|
26
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-migrate-guards-'));
|
|
27
|
+
return path.join(dir, 'gsd.db');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function cleanup(dbPath: string): void {
|
|
31
|
+
closeDatabase();
|
|
32
|
+
fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface RawDb {
|
|
36
|
+
exec(sql: string): void;
|
|
37
|
+
prepare(sql: string): { get(...args: unknown[]): Record<string, unknown> | undefined; all(...args: unknown[]): Array<Record<string, unknown>> };
|
|
38
|
+
close(): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function openRawSqliteForTest(dbPath: string): RawDb {
|
|
42
|
+
try {
|
|
43
|
+
const mod = _require('node:sqlite') as { DatabaseSync: new (path: string) => RawDb };
|
|
44
|
+
return new mod.DatabaseSync(dbPath);
|
|
45
|
+
} catch {
|
|
46
|
+
type SqliteCtor = new (path: string) => RawDb;
|
|
47
|
+
const mod = _require('better-sqlite3') as SqliteCtor | { default: SqliteCtor };
|
|
48
|
+
const DatabaseCtor: SqliteCtor = typeof mod === 'function' ? mod : mod.default;
|
|
49
|
+
return new DatabaseCtor(dbPath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function rawColumnNames(raw: RawDb, table: string): string[] {
|
|
54
|
+
return raw.prepare(`PRAGMA table_info(${table})`).all().map((r) => r['name'] as string);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function rawHasTable(raw: RawDb, table: string): boolean {
|
|
58
|
+
const row = raw.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(table);
|
|
59
|
+
return Boolean(row);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function rawMaxVersion(raw: RawDb): number | null {
|
|
63
|
+
const row = raw.prepare('SELECT MAX(version) as v FROM schema_version').get();
|
|
64
|
+
return (row?.['v'] as number | null) ?? null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
describe('db-engine migrate guards', () => {
|
|
68
|
+
test('getCurrentSchemaVersion returns 0 on an empty schema_version table', () => {
|
|
69
|
+
const sqlite = _require('node:sqlite') as { DatabaseSync: new (path: string) => unknown };
|
|
70
|
+
const adapter = createDbAdapter(new sqlite.DatabaseSync(':memory:'));
|
|
71
|
+
try {
|
|
72
|
+
adapter.exec('CREATE TABLE schema_version (version INTEGER NOT NULL, applied_at TEXT NOT NULL)');
|
|
73
|
+
assert.equal(getCurrentSchemaVersion(adapter), 0);
|
|
74
|
+
} finally {
|
|
75
|
+
adapter.close();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('refuses to open a DB whose schema is newer than this binary', () => {
|
|
80
|
+
const dbPath = tempDbPath();
|
|
81
|
+
try {
|
|
82
|
+
assert.ok(openDatabase(dbPath), 'fresh open should succeed');
|
|
83
|
+
closeDatabase();
|
|
84
|
+
|
|
85
|
+
const raw = openRawSqliteForTest(dbPath);
|
|
86
|
+
raw.exec(
|
|
87
|
+
`INSERT INTO schema_version (version, applied_at) VALUES (${SCHEMA_VERSION + 1}, '2026-01-01T00:00:00Z')`,
|
|
88
|
+
);
|
|
89
|
+
raw.close();
|
|
90
|
+
|
|
91
|
+
assert.throws(() => openDatabase(dbPath), /newer than/);
|
|
92
|
+
assert.equal(isDbAvailable(), false, 'no connection may stay open on refusal');
|
|
93
|
+
} finally {
|
|
94
|
+
cleanup(dbPath);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('a mid-migration failure rolls back to the starting schema version', () => {
|
|
99
|
+
const dbPath = tempDbPath();
|
|
100
|
+
try {
|
|
101
|
+
assert.ok(openDatabase(dbPath), 'fresh open should succeed');
|
|
102
|
+
closeDatabase();
|
|
103
|
+
|
|
104
|
+
// Rewind the DB to v(SCHEMA_VERSION-1): stamp the prior version and drop
|
|
105
|
+
// the objects the last migration adds, so the re-run has real work to redo.
|
|
106
|
+
const startVersion = SCHEMA_VERSION - 2;
|
|
107
|
+
const raw = openRawSqliteForTest(dbPath);
|
|
108
|
+
raw.exec('DELETE FROM schema_version');
|
|
109
|
+
raw.exec(`INSERT INTO schema_version (version, applied_at) VALUES (${startVersion}, '2026-01-01T00:00:00Z')`);
|
|
110
|
+
raw.exec('ALTER TABLE slices DROP COLUMN target_repositories');
|
|
111
|
+
raw.exec('ALTER TABLE tasks DROP COLUMN target_repositories');
|
|
112
|
+
raw.close();
|
|
113
|
+
|
|
114
|
+
_setMigrationFaultForTest(true);
|
|
115
|
+
try {
|
|
116
|
+
assert.throws(() => openDatabase(dbPath), /migration fault injected/);
|
|
117
|
+
} finally {
|
|
118
|
+
_setMigrationFaultForTest(false);
|
|
119
|
+
}
|
|
120
|
+
assert.equal(isDbAvailable(), false, 'no connection may stay open on migration failure');
|
|
121
|
+
|
|
122
|
+
const inspect = openRawSqliteForTest(dbPath);
|
|
123
|
+
try {
|
|
124
|
+
assert.equal(rawMaxVersion(inspect), startVersion, 'version must roll back to the starting version');
|
|
125
|
+
assert.ok(
|
|
126
|
+
!rawColumnNames(inspect, 'slices').includes('target_repositories'),
|
|
127
|
+
'column added by the failed migration must be rolled back',
|
|
128
|
+
);
|
|
129
|
+
} finally {
|
|
130
|
+
inspect.close();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The DB is intact — a clean re-open migrates to the current version.
|
|
134
|
+
assert.ok(openDatabase(dbPath), 're-open without the fault should succeed');
|
|
135
|
+
closeDatabase();
|
|
136
|
+
const after = openRawSqliteForTest(dbPath);
|
|
137
|
+
try {
|
|
138
|
+
assert.equal(rawMaxVersion(after), SCHEMA_VERSION);
|
|
139
|
+
assert.ok(rawColumnNames(after, 'slices').includes('target_repositories'));
|
|
140
|
+
assert.equal(rawHasTable(after, 'rework_briefs'), true);
|
|
141
|
+
assert.equal(rawHasTable(after, 'rework_brief_findings'), true);
|
|
142
|
+
} finally {
|
|
143
|
+
after.close();
|
|
144
|
+
}
|
|
145
|
+
} finally {
|
|
146
|
+
cleanup(dbPath);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('a DB with data but no version rows migrates from v1 instead of being stamped current', () => {
|
|
151
|
+
const dbPath = tempDbPath();
|
|
152
|
+
try {
|
|
153
|
+
assert.ok(openDatabase(dbPath), 'fresh open should succeed');
|
|
154
|
+
closeDatabase();
|
|
155
|
+
|
|
156
|
+
// Simulate a legacy DB: user data present, version table empty, and a
|
|
157
|
+
// migration-added column missing so we can observe the chain actually run.
|
|
158
|
+
const raw = openRawSqliteForTest(dbPath);
|
|
159
|
+
raw.exec("INSERT INTO milestones (id, title) VALUES ('M001', 'Legacy milestone')");
|
|
160
|
+
raw.exec('DELETE FROM schema_version');
|
|
161
|
+
raw.exec('ALTER TABLE milestones DROP COLUMN vision');
|
|
162
|
+
raw.close();
|
|
163
|
+
|
|
164
|
+
assert.ok(openDatabase(dbPath), 'legacy DB open should succeed');
|
|
165
|
+
closeDatabase();
|
|
166
|
+
|
|
167
|
+
const inspect = openRawSqliteForTest(dbPath);
|
|
168
|
+
try {
|
|
169
|
+
const versions = inspect.prepare('SELECT version FROM schema_version ORDER BY version').all()
|
|
170
|
+
.map((r) => r['version'] as number);
|
|
171
|
+
assert.equal(versions[0], 1, 'baseline v1 must be recorded, not a fresh-install stamp');
|
|
172
|
+
assert.equal(versions[versions.length - 1], SCHEMA_VERSION, 'migration chain must reach the current version');
|
|
173
|
+
assert.ok(
|
|
174
|
+
rawColumnNames(inspect, 'milestones').includes('vision'),
|
|
175
|
+
'migration-added column must be restored by the chain',
|
|
176
|
+
);
|
|
177
|
+
const row = inspect.prepare('SELECT count(*) as cnt FROM milestones').get();
|
|
178
|
+
assert.equal(row?.['cnt'], 1, 'existing data must survive');
|
|
179
|
+
} finally {
|
|
180
|
+
inspect.close();
|
|
181
|
+
}
|
|
182
|
+
} finally {
|
|
183
|
+
cleanup(dbPath);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Verifies GSD_ADVERTISE_TOOL_ALIASES gates alias registration on the native tool path (plan 035).
|
|
3
|
+
|
|
4
|
+
import { test } from 'node:test';
|
|
5
|
+
import assert from 'node:assert/strict';
|
|
6
|
+
import { registerDbTools } from '../bootstrap/db-tools.ts';
|
|
7
|
+
import { WORKFLOW_TOOL_ALIAS_NAMES, WORKFLOW_TOOL_CONTRACTS } from '../workflow-tool-surface.ts';
|
|
8
|
+
|
|
9
|
+
function makeMockPi() {
|
|
10
|
+
const tools: any[] = [];
|
|
11
|
+
return {
|
|
12
|
+
registerTool: (tool: any) => tools.push(tool),
|
|
13
|
+
tools,
|
|
14
|
+
} as any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function withEnv(name: string, value: string | undefined, fn: () => void): void {
|
|
18
|
+
const previous = process.env[name];
|
|
19
|
+
if (value === undefined) delete process.env[name];
|
|
20
|
+
else process.env[name] = value;
|
|
21
|
+
try {
|
|
22
|
+
fn();
|
|
23
|
+
} finally {
|
|
24
|
+
if (previous === undefined) delete process.env[name];
|
|
25
|
+
else process.env[name] = previous;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
test('default: only canonical names are registered, no aliases', () => {
|
|
30
|
+
withEnv('GSD_ADVERTISE_TOOL_ALIASES', undefined, () => {
|
|
31
|
+
const pi = makeMockPi();
|
|
32
|
+
registerDbTools(pi);
|
|
33
|
+
const names = new Set(pi.tools.map((tool: any) => tool.name));
|
|
34
|
+
|
|
35
|
+
for (const alias of WORKFLOW_TOOL_ALIAS_NAMES) {
|
|
36
|
+
assert.ok(!names.has(alias), `alias "${alias}" should not be registered by default`);
|
|
37
|
+
}
|
|
38
|
+
const registeredCanonical = WORKFLOW_TOOL_CONTRACTS
|
|
39
|
+
.map((tool) => tool.canonicalName)
|
|
40
|
+
.filter((name) => names.has(name));
|
|
41
|
+
assert.ok(registeredCanonical.length > 0, 'canonical tools should still be registered');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('GSD_ADVERTISE_TOOL_ALIASES=1: aliases are registered with the "(alias for ...)" description suffix', () => {
|
|
46
|
+
withEnv('GSD_ADVERTISE_TOOL_ALIASES', '1', () => {
|
|
47
|
+
const pi = makeMockPi();
|
|
48
|
+
registerDbTools(pi);
|
|
49
|
+
const toolByName = new Map<string, any>(pi.tools.map((tool: any) => [tool.name, tool]));
|
|
50
|
+
|
|
51
|
+
const registeredAliases = WORKFLOW_TOOL_ALIAS_NAMES.filter((alias) => toolByName.has(alias));
|
|
52
|
+
assert.ok(registeredAliases.length > 0, 'at least one alias should be registered when opted in');
|
|
53
|
+
|
|
54
|
+
for (const alias of registeredAliases) {
|
|
55
|
+
const aliasTool = toolByName.get(alias);
|
|
56
|
+
assert.ok(
|
|
57
|
+
aliasTool.description.includes('(alias for '),
|
|
58
|
+
`alias "${alias}" description should include "(alias for ...)"`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -7,6 +7,8 @@ import { join } from 'node:path';
|
|
|
7
7
|
import { tmpdir } from 'node:os';
|
|
8
8
|
|
|
9
9
|
import { deriveState, invalidateStateCache, _deriveStateImpl, deriveStateFromDb, isGhostMilestone } from '../state.ts';
|
|
10
|
+
import { readCachedDeriveState, writeCachedDeriveState } from '../state/derive/cache.ts';
|
|
11
|
+
import type { GSDState } from '../types.ts';
|
|
10
12
|
import {
|
|
11
13
|
openDatabase,
|
|
12
14
|
closeDatabase,
|
|
@@ -582,6 +584,33 @@ describe('derive-state-db', async () => {
|
|
|
582
584
|
}
|
|
583
585
|
});
|
|
584
586
|
|
|
587
|
+
// ─── Test 7b: lock flip must not serve a basePath-keyed cache hit ─────
|
|
588
|
+
// The derive cache is keyed on basePath only, but deriveStateFromDb filters
|
|
589
|
+
// by GSD_MILESTONE_LOCK. auto.ts's capture/restoreMilestoneLockEnv call
|
|
590
|
+
// invalidateStateCache() on every flip; this guards that the cache is
|
|
591
|
+
// genuinely lock-blind (so that invalidate call is load-bearing, not
|
|
592
|
+
// redundant) and that invalidation defeats the stale read.
|
|
593
|
+
test('derive-state-db: a milestone-lock flip needs explicit cache invalidation', () => {
|
|
594
|
+
const prevLock = process.env.GSD_MILESTONE_LOCK;
|
|
595
|
+
try {
|
|
596
|
+
const base = '/tmp/gsd-lock-flip-fixture';
|
|
597
|
+
const stateA = { phase: 'planning' } as unknown as GSDState;
|
|
598
|
+
process.env.GSD_MILESTONE_LOCK = 'M001';
|
|
599
|
+
writeCachedDeriveState(base, stateA);
|
|
600
|
+
|
|
601
|
+
// Lock flips but basePath is unchanged → the cache still hits.
|
|
602
|
+
process.env.GSD_MILESTONE_LOCK = 'M002';
|
|
603
|
+
assert.strictEqual(readCachedDeriveState(base), stateA, 'basePath-only cache ignores the lock flip');
|
|
604
|
+
|
|
605
|
+
// What the lock-env functions do on flip:
|
|
606
|
+
invalidateStateCache();
|
|
607
|
+
assert.strictEqual(readCachedDeriveState(base), null, 'invalidation defeats the stale-lock read');
|
|
608
|
+
} finally {
|
|
609
|
+
if (prevLock === undefined) delete process.env.GSD_MILESTONE_LOCK;
|
|
610
|
+
else process.env.GSD_MILESTONE_LOCK = prevLock;
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
|
|
585
614
|
// ═════════════════════════════════════════════════════════════════════════
|
|
586
615
|
// New: deriveStateFromDb() cross-validation tests
|
|
587
616
|
// ═════════════════════════════════════════════════════════════════════════
|
|
@@ -18,6 +18,7 @@ import test from "node:test";
|
|
|
18
18
|
import assert from "node:assert/strict";
|
|
19
19
|
|
|
20
20
|
import { registerHooks } from "../bootstrap/register-hooks.ts";
|
|
21
|
+
import { autoSession } from "../auto-runtime-state.ts";
|
|
21
22
|
import { classifyCommand } from "../safety/destructive-guard.ts";
|
|
22
23
|
import {
|
|
23
24
|
DESTRUCTIVE_CONFIRM_GATE_MARKER,
|
|
@@ -232,6 +233,38 @@ test("integration: real hooks block a force push, then allow it once after confi
|
|
|
232
233
|
assert.equal(thirdAttempt?.block, true, "second run of the same command re-blocks (one-shot)");
|
|
233
234
|
});
|
|
234
235
|
|
|
236
|
+
test("integration: auto-mode destructive block does not pause before confirmation can be asked", async (t) => {
|
|
237
|
+
const dir = "/tmp/gsd-destructive-confirm-int-auto-defer";
|
|
238
|
+
const notifications: string[] = [];
|
|
239
|
+
const ctx = {
|
|
240
|
+
cwd: dir,
|
|
241
|
+
isIdle: () => true,
|
|
242
|
+
sessionManager: { getSessionFile: () => null },
|
|
243
|
+
ui: { notify: (message: string) => notifications.push(message) },
|
|
244
|
+
} as any;
|
|
245
|
+
resetDestructiveConfirmation(dir);
|
|
246
|
+
autoSession.reset();
|
|
247
|
+
autoSession.active = true;
|
|
248
|
+
autoSession.basePath = dir;
|
|
249
|
+
t.after(() => {
|
|
250
|
+
resetDestructiveConfirmation(dir);
|
|
251
|
+
autoSession.reset();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
const { handlers, pi } = makeHookHarness();
|
|
255
|
+
registerHooks(pi, []);
|
|
256
|
+
|
|
257
|
+
const block = await runBashGuard(handlers, FORCE_PUSH, ctx);
|
|
258
|
+
|
|
259
|
+
assert.equal(block?.block, true, "real guard blocks the first destructive attempt");
|
|
260
|
+
assert.equal(autoSession.active, true, "auto-mode must remain active so ask_user_questions can run");
|
|
261
|
+
assert.deepEqual(
|
|
262
|
+
notifications.filter((message) => message.includes("Destructive-command confirmation")),
|
|
263
|
+
[],
|
|
264
|
+
"destructive confirmation pause must not fire from the bash tool_call hook",
|
|
265
|
+
);
|
|
266
|
+
});
|
|
267
|
+
|
|
235
268
|
test("integration: declining the confirm gate leaves the command blocked", async (t) => {
|
|
236
269
|
const dir = "/tmp/gsd-destructive-confirm-int-decline";
|
|
237
270
|
const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
|
|
@@ -29,6 +29,7 @@ test("destructive guard still detects direct and wrapper-prefixed recursive dele
|
|
|
29
29
|
"find . -exec rm -rf {} \\;",
|
|
30
30
|
"cat doomed.txt | xargs rm -rf /tmp/x",
|
|
31
31
|
'rm -rf "/tmp/my build"',
|
|
32
|
+
"rm --recursive build",
|
|
32
33
|
];
|
|
33
34
|
|
|
34
35
|
for (const command of destructiveCommands) {
|
|
@@ -39,6 +40,19 @@ test("destructive guard still detects direct and wrapper-prefixed recursive dele
|
|
|
39
40
|
}
|
|
40
41
|
});
|
|
41
42
|
|
|
43
|
+
test("destructive guard does not classify force-only rm as recursive delete", () => {
|
|
44
|
+
const nonRecursiveCommands = [
|
|
45
|
+
"rm -f single-file.md",
|
|
46
|
+
"rm -fv single-file.md",
|
|
47
|
+
"rm single-file.md -f",
|
|
48
|
+
"rm --force single-file.md",
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
for (const command of nonRecursiveCommands) {
|
|
52
|
+
assert.deepEqual(classifyCommand(command), { destructive: false, labels: [] }, command);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
42
56
|
test("destructive guard treats quoted interpreter payloads as literals", () => {
|
|
43
57
|
assert.deepEqual(classifyCommand('bash -c "rm -rf /"'), { destructive: false, labels: [] });
|
|
44
58
|
});
|
|
@@ -80,6 +80,43 @@ function makeDiscussCtx(notifications: Array<{ message: string; level?: string }
|
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
async function runDiscussTargetFixture(
|
|
84
|
+
target: string,
|
|
85
|
+
milestones: Array<{ id: string; title?: string; status?: string }>,
|
|
86
|
+
writeArtifacts?: (base: string) => void,
|
|
87
|
+
) {
|
|
88
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-discuss-target-"));
|
|
89
|
+
const notifications: Array<{ message: string; level?: string }> = [];
|
|
90
|
+
const harness = makeDiscussPi();
|
|
91
|
+
try {
|
|
92
|
+
mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
|
|
93
|
+
writeArtifacts?.(base);
|
|
94
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
95
|
+
assert.equal(openDatabase(dbPath), true);
|
|
96
|
+
for (const milestone of milestones) {
|
|
97
|
+
insertMilestone(milestone);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
await showDiscuss(
|
|
101
|
+
makeDiscussCtx(notifications) as any,
|
|
102
|
+
harness.pi as any,
|
|
103
|
+
base,
|
|
104
|
+
{ target },
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
notifications: [...notifications],
|
|
109
|
+
sent: [...harness.sent],
|
|
110
|
+
};
|
|
111
|
+
} finally {
|
|
112
|
+
harness.restore();
|
|
113
|
+
if (isDbAvailable()) closeDatabase();
|
|
114
|
+
invalidateStateCache();
|
|
115
|
+
clearGuidedUnitContext();
|
|
116
|
+
rmSync(base, { recursive: true, force: true });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
83
120
|
describe("discuss target normalization", () => {
|
|
84
121
|
test("canonicalizes milestone and slice casing", () => {
|
|
85
122
|
assert.equal(normalizeDiscussTarget("m014"), "M014");
|
|
@@ -90,6 +127,92 @@ describe("discuss target normalization", () => {
|
|
|
90
127
|
});
|
|
91
128
|
});
|
|
92
129
|
|
|
130
|
+
describe("showDiscuss targeted milestone guardrails (#1320)", () => {
|
|
131
|
+
test("missing, complete, and parked milestone targets get actionable messages", async () => {
|
|
132
|
+
const cases = [
|
|
133
|
+
{
|
|
134
|
+
target: "M006",
|
|
135
|
+
milestones: [{ id: "M005", title: "Current", status: "active" }],
|
|
136
|
+
level: "warning",
|
|
137
|
+
message: /Milestone M006 was not found in the roadmap\. Use \/gsd new-milestone to add it, or \/gsd status to see available milestones\./,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
target: "M006/S01",
|
|
141
|
+
milestones: [{ id: "M005", title: "Current", status: "active" }],
|
|
142
|
+
level: "warning",
|
|
143
|
+
message: /Milestone M006 was not found in the roadmap\. Use \/gsd new-milestone to add it, or \/gsd status to see available milestones\./,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
target: "M006",
|
|
147
|
+
milestones: [{ id: "M006", title: "Done", status: "complete" }],
|
|
148
|
+
level: "info",
|
|
149
|
+
message: /Milestone M006 is already complete\./,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
target: "M006/S01",
|
|
153
|
+
milestones: [{ id: "M006", title: "Done", status: "complete" }],
|
|
154
|
+
level: "info",
|
|
155
|
+
message: /Milestone M006 is already complete\./,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
target: "M006",
|
|
159
|
+
milestones: [{ id: "M006", title: "Deferred", status: "parked" }],
|
|
160
|
+
level: "warning",
|
|
161
|
+
message: /Milestone M006 is parked\. Run \/gsd unpark M006 to reactivate\./,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
target: "M006/S01",
|
|
165
|
+
milestones: [{ id: "M006", title: "Deferred", status: "parked" }],
|
|
166
|
+
level: "warning",
|
|
167
|
+
message: /Milestone M006 is parked\. Run \/gsd unpark M006 to reactivate\./,
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
for (const testCase of cases) {
|
|
172
|
+
const result = await runDiscussTargetFixture(testCase.target, testCase.milestones);
|
|
173
|
+
assert.equal(result.sent.length, 0, `${testCase.target} must not dispatch`);
|
|
174
|
+
assert.equal(result.notifications.length, 1, `${testCase.target} must emit one notification`);
|
|
175
|
+
assert.equal(result.notifications[0]?.level, testCase.level);
|
|
176
|
+
assert.match(result.notifications[0]?.message ?? "", testCase.message);
|
|
177
|
+
assert.doesNotMatch(result.notifications[0]?.message ?? "", /not discussable/i);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("bare milestone targets match unique-suffix milestone IDs", async () => {
|
|
182
|
+
const result = await runDiscussTargetFixture("M006", [
|
|
183
|
+
{ id: "M006-abc123", title: "Unique milestone", status: "active" },
|
|
184
|
+
]);
|
|
185
|
+
|
|
186
|
+
assert.equal(result.notifications.length, 0);
|
|
187
|
+
assert.equal(result.sent.length, 1, "bare ID must dispatch the suffixed milestone");
|
|
188
|
+
assert.match(String(result.sent[0]?.content), /M006-abc123|Unique milestone|guided-discuss-milestone/i);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("bare slice targets match unique-suffix milestone IDs", async () => {
|
|
192
|
+
const result = await runDiscussTargetFixture(
|
|
193
|
+
"M006/S01",
|
|
194
|
+
[{ id: "M006-abc123", title: "Unique milestone", status: "active" }],
|
|
195
|
+
(base) => {
|
|
196
|
+
mkdirSync(join(base, ".gsd", "milestones", "M006-abc123"), { recursive: true });
|
|
197
|
+
writeFileSync(
|
|
198
|
+
join(base, ".gsd", "milestones", "M006-abc123", "M006-abc123-ROADMAP.md"),
|
|
199
|
+
`# M006-abc123 Roadmap
|
|
200
|
+
|
|
201
|
+
## Slices
|
|
202
|
+
- [ ] **S01: Unique slice** \`risk:medium\` \`depends:[]\`
|
|
203
|
+
> After this: the suffixed milestone slice can be discussed
|
|
204
|
+
`,
|
|
205
|
+
"utf-8",
|
|
206
|
+
);
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
assert.equal(result.notifications.length, 0);
|
|
211
|
+
assert.equal(result.sent.length, 1, "bare ID slice target must dispatch through the suffixed milestone");
|
|
212
|
+
assert.match(String(result.sent[0]?.content), /M006-abc123|S01|Unique slice|guided-discuss-slice/i);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
93
216
|
describe("loadDiscussNormSlices roadmap fallback (#2892)", () => {
|
|
94
217
|
test("falls back to ROADMAP when DB has no slice rows", async () => {
|
|
95
218
|
const base = mkdtempSync(join(tmpdir(), "gsd-discuss-slices-"));
|
|
@@ -330,6 +330,56 @@ test("dispatch: session milestone mismatch stops before missing-task-plan recove
|
|
|
330
330
|
assert.match(result.reason, /context mid "M001" does not match session\.currentMilestoneId "M002"/);
|
|
331
331
|
});
|
|
332
332
|
|
|
333
|
+
test("dispatch: bare context milestone maps to suffixed active session milestone", async (t) => {
|
|
334
|
+
const tmp = mkdtempSync(join(tmpdir(), "gsd-suffixed-session-milestone-"));
|
|
335
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
336
|
+
|
|
337
|
+
const worktreeRoot = join(tmp, ".gsd", "worktrees", "M003-vaz73w");
|
|
338
|
+
scaffoldLegacyMilestoneContext(worktreeRoot, "M003-vaz73w");
|
|
339
|
+
scaffoldLegacySlicePlan(worktreeRoot, "M003-vaz73w", "S01");
|
|
340
|
+
scaffoldLegacyTaskPlan(worktreeRoot, "M003-vaz73w", "S01", "T02");
|
|
341
|
+
|
|
342
|
+
const ctx = makeContextFor(tmp, "M003", "S01", "T02", {
|
|
343
|
+
basePath: worktreeRoot,
|
|
344
|
+
originalBasePath: tmp,
|
|
345
|
+
currentMilestoneId: "M003-vaz73w",
|
|
346
|
+
});
|
|
347
|
+
const result = await resolveDispatch(ctx);
|
|
348
|
+
|
|
349
|
+
assert.equal(result.action, "dispatch");
|
|
350
|
+
assert.ok(result.action === "dispatch" && result.unitType === "execute-task",
|
|
351
|
+
`unitType should be execute-task, got: ${result.action === "dispatch" ? result.unitType : "(stop)"}`);
|
|
352
|
+
assert.ok(result.action === "dispatch" && result.unitId === "M003-vaz73w/S01/T02",
|
|
353
|
+
`unitId should use suffixed milestone, got: ${result.action === "dispatch" ? result.unitId : "(stop)"}`);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("dispatch: suffixed context milestone keeps suffix when scoped alias is bare", async (t) => {
|
|
357
|
+
// Inverse of the case above: dispatch context carries the suffixed id but the
|
|
358
|
+
// scoped alias (session.currentMilestoneId) is bare. resolveEffectiveDispatchMilestoneId
|
|
359
|
+
// must keep the suffixed id so slice/task artifacts resolve under the suffixed
|
|
360
|
+
// worktree layout (milestones/M003-xxxxxx/) rather than the bare milestones/M003/.
|
|
361
|
+
const tmp = mkdtempSync(join(tmpdir(), "gsd-suffixed-context-bare-scope-"));
|
|
362
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
363
|
+
|
|
364
|
+
const worktreeRoot = join(tmp, ".gsd", "worktrees", "M003-vaz73w");
|
|
365
|
+
scaffoldLegacyMilestoneContext(worktreeRoot, "M003-vaz73w");
|
|
366
|
+
scaffoldLegacySlicePlan(worktreeRoot, "M003-vaz73w", "S01");
|
|
367
|
+
scaffoldLegacyTaskPlan(worktreeRoot, "M003-vaz73w", "S01", "T02");
|
|
368
|
+
|
|
369
|
+
const ctx = makeContextFor(tmp, "M003-vaz73w", "S01", "T02", {
|
|
370
|
+
basePath: worktreeRoot,
|
|
371
|
+
originalBasePath: tmp,
|
|
372
|
+
currentMilestoneId: "M003",
|
|
373
|
+
});
|
|
374
|
+
const result = await resolveDispatch(ctx);
|
|
375
|
+
|
|
376
|
+
assert.equal(result.action, "dispatch");
|
|
377
|
+
assert.ok(result.action === "dispatch" && result.unitType === "execute-task",
|
|
378
|
+
`unitType should be execute-task, got: ${result.action === "dispatch" ? result.unitType : "(stop)"}`);
|
|
379
|
+
assert.ok(result.action === "dispatch" && result.unitId === "M003-vaz73w/S01/T02",
|
|
380
|
+
`unitId should keep suffixed milestone, got: ${result.action === "dispatch" ? result.unitId : "(stop)"}`);
|
|
381
|
+
});
|
|
382
|
+
|
|
333
383
|
test("dispatch: worktree path mismatch stops before planning a different milestone", async (t) => {
|
|
334
384
|
const tmp = mkdtempSync(join(tmpdir(), "gsd-worktree-path-milestone-mismatch-"));
|
|
335
385
|
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
@@ -146,6 +146,55 @@ test("dispatch-rule-coverage: pre-planning, no CONTEXT → discuss-milestone", a
|
|
|
146
146
|
);
|
|
147
147
|
});
|
|
148
148
|
|
|
149
|
+
test("dispatch-rule-coverage: pre-planning worktree sees project-root CONTEXT", async (t) => {
|
|
150
|
+
const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-wt-context-"));
|
|
151
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
152
|
+
|
|
153
|
+
const projectPhaseDir = join(tmp, ".gsd", "phases", "01-foundation");
|
|
154
|
+
mkdirSync(projectPhaseDir, { recursive: true });
|
|
155
|
+
writeFileSync(join(projectPhaseDir, "01-CONTEXT.md"), "# Context\n");
|
|
156
|
+
|
|
157
|
+
const worktree = join(tmp, ".gsd", "worktrees", "M001");
|
|
158
|
+
mkdirSync(join(worktree, ".gsd", "milestones", "M001"), { recursive: true });
|
|
159
|
+
writeFileSync(
|
|
160
|
+
join(worktree, ".gsd", "milestones", "M001", "M001-META.json"),
|
|
161
|
+
'{"branch":"milestone/M001"}',
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const rule = DISPATCH_RULES.find(
|
|
165
|
+
(candidate) => candidate.name === "pre-planning (no context) → discuss-milestone",
|
|
166
|
+
);
|
|
167
|
+
assert.ok(rule, "pre-planning missing-context rule should exist");
|
|
168
|
+
|
|
169
|
+
const result = await rule.match(makeCtx(worktree, makeState({ phase: "pre-planning" })));
|
|
170
|
+
assert.equal(result, null, "project-root CONTEXT must prevent a second discuss-milestone dispatch");
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("dispatch-rule-coverage: pre-planning worktree sees worktree-only CONTEXT", async (t) => {
|
|
174
|
+
// Mirror image of the project-root test: discuss-milestone mirrors CONTEXT into
|
|
175
|
+
// the worktree's own .gsd, and it may not yet exist at the project root (the
|
|
176
|
+
// worktree→root sync deliberately does not flow markdown projections back).
|
|
177
|
+
// A project-root-only check would miss it and re-fire discuss-milestone.
|
|
178
|
+
const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-wt-only-context-"));
|
|
179
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
180
|
+
|
|
181
|
+
// No CONTEXT at the project root — only the milestone dir exists there.
|
|
182
|
+
mkdirSync(join(tmp, ".gsd", "phases"), { recursive: true });
|
|
183
|
+
|
|
184
|
+
const worktree = join(tmp, ".gsd", "worktrees", "M001");
|
|
185
|
+
const worktreePhaseDir = join(worktree, ".gsd", "phases", "01-foundation");
|
|
186
|
+
mkdirSync(worktreePhaseDir, { recursive: true });
|
|
187
|
+
writeFileSync(join(worktreePhaseDir, "01-CONTEXT.md"), "# WT Context\n");
|
|
188
|
+
|
|
189
|
+
const rule = DISPATCH_RULES.find(
|
|
190
|
+
(candidate) => candidate.name === "pre-planning (no context) → discuss-milestone",
|
|
191
|
+
);
|
|
192
|
+
assert.ok(rule, "pre-planning missing-context rule should exist");
|
|
193
|
+
|
|
194
|
+
const result = await rule.match(makeCtx(worktree, makeState({ phase: "pre-planning" })));
|
|
195
|
+
assert.equal(result, null, "worktree-only CONTEXT must prevent a second discuss-milestone dispatch");
|
|
196
|
+
});
|
|
197
|
+
|
|
149
198
|
test("dispatch-rule-coverage: pre-planning, has CONTEXT, no RESEARCH → research-milestone", async (t) => {
|
|
150
199
|
const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-res-"));
|
|
151
200
|
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|