@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.5c1a3ff2
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 +25 -2
- 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-artifact-paths.js +16 -10
- package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +125 -18
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -5
- 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/compat/compat-marker.js +19 -2
- 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 +51 -16
- 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 +3 -6
- package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +187 -45
- package/dist/resources/extensions/gsd/guided-flow.js +38 -13
- package/dist/resources/extensions/gsd/markdown-renderer.js +17 -13
- 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 +55 -11
- 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/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 +27 -13
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
- package/dist/resources/extensions/gsd/stop-notice.js +15 -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 +6 -0
- package/dist/resources/extensions/mac-tools/index.js +31 -9
- 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 +8 -8
- 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 +8 -8
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- 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 +12 -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/dist/cli.d.ts +5 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cli.js +160 -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 +231 -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 +35 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js +258 -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/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/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 +119 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +107 -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-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-artifact-paths.ts +16 -9
- package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +142 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -10
- 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/compat/compat-marker.ts +21 -4
- 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 +53 -17
- 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 +3 -5
- package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +255 -52
- package/src/resources/extensions/gsd/guided-flow.ts +48 -12
- package/src/resources/extensions/gsd/markdown-renderer.ts +25 -21
- 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 +62 -11
- 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/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 +30 -13
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
- package/src/resources/extensions/gsd/stop-notice.ts +18 -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-recovery.test.ts +39 -0
- 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/compat-marker.test.ts +104 -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-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/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/external-edit-scoped-import.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -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 +66 -0
- 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/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/stop-notice.test.ts +17 -0
- 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/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/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/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 +12 -0
- 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/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 → 6YWV7VAPg-jqjfPswrKZb}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_ssgManifest.js +0 -0
|
@@ -58,6 +58,7 @@ function registerAlias(pi: ExtensionAPI, toolDef: any, aliasName: string, canoni
|
|
|
58
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- toolDef shape matches ToolDefinition but varies by schema
|
|
59
59
|
function registerWorkflowTool(pi: ExtensionAPI, toolDef: any): void {
|
|
60
60
|
pi.registerTool(toolDef);
|
|
61
|
+
if (process.env.GSD_ADVERTISE_TOOL_ALIASES !== "1") return; // canonical-only model surface (see plan 035)
|
|
61
62
|
for (const alias of aliasesForWorkflowTool(toolDef.name)) {
|
|
62
63
|
registerAlias(pi, toolDef, alias, toolDef.name);
|
|
63
64
|
}
|
|
@@ -771,12 +772,12 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
771
772
|
name: "gsd_plan_task",
|
|
772
773
|
label: "Plan Task",
|
|
773
774
|
description:
|
|
774
|
-
"Write task planning state to the GSD database, render
|
|
775
|
-
promptSnippet: "Plan a task via DB write +
|
|
775
|
+
"Write task planning state to the GSD database, render the slice PLAN from DB, and clear caches after a successful render.",
|
|
776
|
+
promptSnippet: "Plan a task via DB write + slice PLAN render + cache invalidation",
|
|
776
777
|
promptGuidelines: [
|
|
777
|
-
"Use gsd_plan_task for task planning instead of writing
|
|
778
|
+
"Use gsd_plan_task for task planning instead of writing task PLAN files directly.",
|
|
778
779
|
"Keep parameters flat and provide the full task planning payload.",
|
|
779
|
-
"The tool validates input, requires an existing parent slice, writes task planning data, renders the
|
|
780
|
+
"The tool validates input, requires an existing parent slice, writes task planning data, renders the slice PLAN file from DB, and clears both state and parse caches after success.",
|
|
780
781
|
"Use the canonical name gsd_plan_task; gsd_task_plan is only an alias.",
|
|
781
782
|
],
|
|
782
783
|
parameters: Type.Object({
|
|
@@ -860,6 +861,15 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
860
861
|
}),
|
|
861
862
|
{ description: "Array of verification evidence entries (structured objects only)" },
|
|
862
863
|
)),
|
|
864
|
+
reworkResolution: Type.Optional(Type.Array(
|
|
865
|
+
Type.Object({
|
|
866
|
+
findingId: Type.String({ description: "Rework finding ID being resolved (e.g. F1)" }),
|
|
867
|
+
status: StringEnum(["resolved", "deferred-with-override"], { description: "Resolution status for this finding" }),
|
|
868
|
+
evidence: Type.String({ description: "Concrete evidence that the required fix was completed" }),
|
|
869
|
+
decisionRef: Type.Optional(Type.String({ description: "Decision reference required for deferred-with-override findings" })),
|
|
870
|
+
}),
|
|
871
|
+
{ description: "Resolution evidence for structured rework findings linked to this task" },
|
|
872
|
+
)),
|
|
863
873
|
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
864
874
|
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
865
875
|
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered (e.g. 'task verified after retry')" })),
|
|
@@ -1180,6 +1190,84 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1180
1190
|
|
|
1181
1191
|
registerWorkflowTool(pi, replanSliceTool);
|
|
1182
1192
|
|
|
1193
|
+
// ─── gsd_replan_task ───────────────────────────────────────────────────
|
|
1194
|
+
|
|
1195
|
+
const replanTaskExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1196
|
+
const { executeReplanTask } = await loadWorkflowExecutors();
|
|
1197
|
+
return executeReplanTask(params, resolveWorkflowToolBasePath(_ctx, params));
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
const replanTaskTool = {
|
|
1201
|
+
name: "gsd_replan_task",
|
|
1202
|
+
label: "Replan Task",
|
|
1203
|
+
description:
|
|
1204
|
+
"Update one pending task's planning contract after rework without touching sibling tasks. " +
|
|
1205
|
+
"Completed tasks are structurally protected. Re-renders the task/slice PLAN projection and records replan history.",
|
|
1206
|
+
promptSnippet: "Replan one pending GSD task after rework",
|
|
1207
|
+
promptGuidelines: [
|
|
1208
|
+
"Use gsd_replan_task when a reopened pending task needs its title, description, files, verify, inputs, or expectedOutput updated for rework.",
|
|
1209
|
+
"The task must already exist and be pending; completed tasks are rejected.",
|
|
1210
|
+
"Set reworkBriefRef when a structured rework brief triggered the task replan.",
|
|
1211
|
+
],
|
|
1212
|
+
parameters: Type.Object({
|
|
1213
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
1214
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
1215
|
+
taskId: Type.String({ description: "Task ID (e.g. T01)" }),
|
|
1216
|
+
title: Type.String({ description: "Updated task title" }),
|
|
1217
|
+
description: Type.String({ description: "Updated task description incorporating rework scope" }),
|
|
1218
|
+
estimate: Type.String({ description: "Updated task estimate string" }),
|
|
1219
|
+
files: Type.Array(Type.String(), { description: "Updated files likely touched" }),
|
|
1220
|
+
verify: Type.String({ description: "Updated verification command or block" }),
|
|
1221
|
+
inputs: Type.Array(Type.String(), { description: "Updated input files or references" }),
|
|
1222
|
+
expectedOutput: Type.Array(Type.String(), { description: "Updated files this task creates or overwrites" }),
|
|
1223
|
+
reworkBriefRef: Type.Optional(Type.String({ description: "Rework brief ID/reference that triggered this task replan" })),
|
|
1224
|
+
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail" })),
|
|
1225
|
+
triggerReason: Type.Optional(Type.String({ description: "Caller-provided reason this action was triggered" })),
|
|
1226
|
+
}),
|
|
1227
|
+
execute: replanTaskExecute,
|
|
1228
|
+
};
|
|
1229
|
+
|
|
1230
|
+
registerWorkflowTool(pi, replanTaskTool);
|
|
1231
|
+
|
|
1232
|
+
// ─── gsd_rework_brief_save ─────────────────────────────────────────────
|
|
1233
|
+
|
|
1234
|
+
const reworkBriefSaveExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1235
|
+
const { executeReworkBriefSave } = await loadWorkflowExecutors();
|
|
1236
|
+
return executeReworkBriefSave(params, resolveWorkflowToolBasePath(_ctx, params));
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
const reworkBriefSaveTool = {
|
|
1240
|
+
name: "gsd_rework_brief_save",
|
|
1241
|
+
label: "Save Rework Brief",
|
|
1242
|
+
description:
|
|
1243
|
+
"Persist a structured rework brief for a task. Blocking findings are enforced by gsd_task_complete until resolved with evidence.",
|
|
1244
|
+
promptSnippet: "Persist structured task rework findings",
|
|
1245
|
+
promptGuidelines: [
|
|
1246
|
+
"Use gsd_rework_brief_save when post-unit checks produce task rework findings.",
|
|
1247
|
+
"Use severity 'blocking' for findings that must be resolved before gsd_task_complete succeeds.",
|
|
1248
|
+
"Each finding needs a stable findingId, requiredFix, and verificationCommands.",
|
|
1249
|
+
],
|
|
1250
|
+
parameters: Type.Object({
|
|
1251
|
+
briefId: Type.Optional(Type.String({ description: "Stable brief ID; omitted defaults to RB-<milestone>-<slice>-<task>" })),
|
|
1252
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
1253
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
1254
|
+
taskId: Type.String({ description: "Task ID (e.g. T01)" }),
|
|
1255
|
+
findings: Type.Array(Type.Object({
|
|
1256
|
+
findingId: Type.String({ description: "Stable finding ID (e.g. F1)" }),
|
|
1257
|
+
severity: StringEnum(["blocking", "advisory"], { description: "Whether this finding blocks task completion" }),
|
|
1258
|
+
description: Type.String({ description: "What was found" }),
|
|
1259
|
+
requiredFix: Type.String({ description: "What must change" }),
|
|
1260
|
+
verificationCommands: Type.Array(Type.String(), { description: "Commands that must pass after the fix" }),
|
|
1261
|
+
status: Type.Optional(StringEnum(["pending", "resolved", "deferred-with-override"], { description: "Finding status; defaults to pending" })),
|
|
1262
|
+
evidence: Type.Optional(Type.String({ description: "Resolution evidence when already resolved" })),
|
|
1263
|
+
decisionRef: Type.Optional(Type.String({ description: "Decision reference for deferred-with-override" })),
|
|
1264
|
+
}), { description: "Structured rework findings for this task" }),
|
|
1265
|
+
}),
|
|
1266
|
+
execute: reworkBriefSaveExecute,
|
|
1267
|
+
};
|
|
1268
|
+
|
|
1269
|
+
registerWorkflowTool(pi, reworkBriefSaveTool);
|
|
1270
|
+
|
|
1183
1271
|
// ─── gsd_reassess_roadmap (gsd_roadmap_reassess alias) ─────────────────
|
|
1184
1272
|
|
|
1185
1273
|
const reassessRoadmapExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
@@ -51,7 +51,9 @@ import {
|
|
|
51
51
|
confirmDestructiveCommand,
|
|
52
52
|
consumeDestructiveConfirmation,
|
|
53
53
|
isDestructiveConfirmGateId,
|
|
54
|
+
peekPendingDestructiveCommand,
|
|
54
55
|
requestDestructiveConfirmation,
|
|
56
|
+
resetDestructiveConfirmation,
|
|
55
57
|
} from "../safety/destructive-confirmation.js";
|
|
56
58
|
import { logWarning as safetyLogWarning, setStderrLoggingEnabled } from "../workflow-logger.js";
|
|
57
59
|
import { isUnitCloseoutTool, runInteractiveUnitCloseout } from "../unit-closeout.js";
|
|
@@ -59,6 +61,7 @@ import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
|
59
61
|
import { initNotificationStore } from "../notification-store.js";
|
|
60
62
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
61
63
|
import { notifyPreferenceDiagnostics } from "../preferences-diagnostics.js";
|
|
64
|
+
import { resolveEffectivePlanningToolsPolicy } from "../planning-subagent-policy.js";
|
|
62
65
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
63
66
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
64
67
|
import {
|
|
@@ -187,6 +190,7 @@ function suppressWelcomeHeader(ctx: ExtensionContext): void {
|
|
|
187
190
|
* are bounded — cleared on activation, session boundaries, and verification.
|
|
188
191
|
*/
|
|
189
192
|
const deferredApprovalGates = new Map<string, string>();
|
|
193
|
+
const deferredDestructiveConfirmationPauses = new Set<string>();
|
|
190
194
|
|
|
191
195
|
export const MINIMAL_GSD_TOOL_NAMES = [
|
|
192
196
|
"gsd_exec",
|
|
@@ -618,6 +622,23 @@ function clearDeferredApprovalGate(basePath?: string): void {
|
|
|
618
622
|
}
|
|
619
623
|
}
|
|
620
624
|
|
|
625
|
+
function deferDestructiveConfirmationPause(basePath: string): void {
|
|
626
|
+
deferredDestructiveConfirmationPauses.add(basePath);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function clearDeferredDestructiveConfirmationPause(basePath?: string): void {
|
|
630
|
+
if (!basePath) {
|
|
631
|
+
deferredDestructiveConfirmationPauses.clear();
|
|
632
|
+
} else {
|
|
633
|
+
deferredDestructiveConfirmationPauses.delete(basePath);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function isDestructiveConfirmationBlocking(basePath: string): boolean {
|
|
638
|
+
return deferredDestructiveConfirmationPauses.has(basePath)
|
|
639
|
+
&& Boolean(peekPendingDestructiveCommand(basePath));
|
|
640
|
+
}
|
|
641
|
+
|
|
621
642
|
function deferApprovalGate(gateId: string, basePath: string): void {
|
|
622
643
|
// Verified-on-disk wins (same adapter policy as activation/re-arm): if the
|
|
623
644
|
// workflow MCP child already verified this gate, deferring would block
|
|
@@ -1015,6 +1036,7 @@ export function registerHooks(
|
|
|
1015
1036
|
await applyToolCallLoopGuardConfig(basePath);
|
|
1016
1037
|
approvalQuestionAbortInFlight = false;
|
|
1017
1038
|
clearDeferredApprovalGate();
|
|
1039
|
+
clearDeferredDestructiveConfirmationPause();
|
|
1018
1040
|
await resetAskUserQuestionsTurnCache();
|
|
1019
1041
|
await syncServiceTierStatus(ctx);
|
|
1020
1042
|
await applyDisabledModelProviderPolicy(ctx);
|
|
@@ -1106,6 +1128,7 @@ export function registerHooks(
|
|
|
1106
1128
|
resetToolCallLoopGuard();
|
|
1107
1129
|
await applyToolCallLoopGuardConfig(basePath);
|
|
1108
1130
|
clearDeferredApprovalGate();
|
|
1131
|
+
clearDeferredDestructiveConfirmationPause();
|
|
1109
1132
|
await resetAskUserQuestionsTurnCache();
|
|
1110
1133
|
clearDiscussionFlowState(basePath);
|
|
1111
1134
|
// /clear or /new destroys the conversation holding a discuss interview, so
|
|
@@ -1157,6 +1180,7 @@ export function registerHooks(
|
|
|
1157
1180
|
}
|
|
1158
1181
|
}
|
|
1159
1182
|
clearDeferredApprovalGate(beforeAgentBasePath);
|
|
1183
|
+
clearDeferredDestructiveConfirmationPause(beforeAgentBasePath);
|
|
1160
1184
|
|
|
1161
1185
|
// session_start can fire before the active provider has settled. By
|
|
1162
1186
|
// before_agent_start, Claude Code CLI sessions should get the same
|
|
@@ -1244,12 +1268,20 @@ export function registerHooks(
|
|
|
1244
1268
|
await handleAgentEnd(pi, event, ctx);
|
|
1245
1269
|
} finally {
|
|
1246
1270
|
activateDeferredApprovalGate(agentEndBasePath);
|
|
1271
|
+
const destructiveConfirmationBlocking = isDestructiveConfirmationBlocking(agentEndBasePath);
|
|
1272
|
+
clearDeferredDestructiveConfirmationPause(agentEndBasePath);
|
|
1247
1273
|
await maybePauseAutoForApprovalGate(
|
|
1248
1274
|
ctx,
|
|
1249
1275
|
pi,
|
|
1250
1276
|
isApprovalGateBlocking(agentEndBasePath),
|
|
1251
1277
|
"Depth confirmation is waiting for your answer — pausing auto-mode.",
|
|
1252
1278
|
);
|
|
1279
|
+
await maybePauseAutoForApprovalGate(
|
|
1280
|
+
ctx,
|
|
1281
|
+
pi,
|
|
1282
|
+
destructiveConfirmationBlocking,
|
|
1283
|
+
"Destructive-command confirmation is waiting for your answer — pausing auto-mode.",
|
|
1284
|
+
);
|
|
1253
1285
|
}
|
|
1254
1286
|
});
|
|
1255
1287
|
|
|
@@ -1559,6 +1591,7 @@ export function registerHooks(
|
|
|
1559
1591
|
const activeUnitType = dash.currentUnit?.type ?? guidedUnit?.unitType;
|
|
1560
1592
|
if (activeUnitType) {
|
|
1561
1593
|
const manifest = resolveManifest(activeUnitType);
|
|
1594
|
+
const planningBasePath = dash.basePath || guidedUnit?.basePath || discussionBasePath;
|
|
1562
1595
|
let planningInput = "";
|
|
1563
1596
|
let agentClasses: string[] | undefined;
|
|
1564
1597
|
if (isToolCallEventType("write", event)) {
|
|
@@ -1574,9 +1607,9 @@ export function registerHooks(
|
|
|
1574
1607
|
const planningGuard = shouldBlockPlanningUnit(
|
|
1575
1608
|
event.toolName,
|
|
1576
1609
|
planningInput,
|
|
1577
|
-
|
|
1610
|
+
planningBasePath,
|
|
1578
1611
|
activeUnitType,
|
|
1579
|
-
manifest?.tools,
|
|
1612
|
+
resolveEffectivePlanningToolsPolicy(activeUnitType, manifest?.tools, planningBasePath),
|
|
1580
1613
|
agentClasses,
|
|
1581
1614
|
(event as { input?: unknown }).input,
|
|
1582
1615
|
dash.currentUnit?.id,
|
|
@@ -1685,6 +1718,7 @@ export function registerHooks(
|
|
|
1685
1718
|
// Record the command as pending so an affirmative answer to a
|
|
1686
1719
|
// destructive_confirm gate (handled in tool_result) can confirm it.
|
|
1687
1720
|
requestDestructiveConfirmation(command, guardBasePath);
|
|
1721
|
+
deferDestructiveConfirmationPause(guardBasePath);
|
|
1688
1722
|
const reason = [
|
|
1689
1723
|
"HARD BLOCK: destructive Bash command requires explicit human confirmation.",
|
|
1690
1724
|
`Detected: ${classification.labels.join(", ")}`,
|
|
@@ -1695,14 +1729,6 @@ export function registerHooks(
|
|
|
1695
1729
|
safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
|
|
1696
1730
|
command: String(command).slice(0, 200),
|
|
1697
1731
|
});
|
|
1698
|
-
if (ctx) {
|
|
1699
|
-
await maybePauseAutoForApprovalGate(
|
|
1700
|
-
ctx,
|
|
1701
|
-
pi,
|
|
1702
|
-
isAutoActive(),
|
|
1703
|
-
"Destructive-command confirmation is waiting for your answer — pausing auto-mode.",
|
|
1704
|
-
);
|
|
1705
|
-
}
|
|
1706
1732
|
return { block: true, reason };
|
|
1707
1733
|
}
|
|
1708
1734
|
}
|
|
@@ -1884,7 +1910,10 @@ export function registerHooks(
|
|
|
1884
1910
|
const answer = details.response?.answers?.[question.id];
|
|
1885
1911
|
if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
|
|
1886
1912
|
confirmDestructiveCommand(basePath);
|
|
1913
|
+
} else {
|
|
1914
|
+
resetDestructiveConfirmation(basePath);
|
|
1887
1915
|
}
|
|
1916
|
+
clearDeferredDestructiveConfirmationPause(basePath);
|
|
1888
1917
|
break;
|
|
1889
1918
|
}
|
|
1890
1919
|
}
|
|
@@ -21,6 +21,14 @@ import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile,
|
|
|
21
21
|
import { toPosixPath } from "../../shared/mod.js";
|
|
22
22
|
import { autoEnableCmuxPreferences } from "../commands-cmux.js";
|
|
23
23
|
import { gsdHome } from "../gsd-home.js";
|
|
24
|
+
import { GSD_CONTEXT_MESSAGE_SENTINEL } from "../constants.js";
|
|
25
|
+
|
|
26
|
+
// Single source of truth lives in ../constants.js; re-exported here because
|
|
27
|
+
// buildContextMessage() stamps this marker on every context injection and the
|
|
28
|
+
// provider payload policy (filterSupersededContextInjections in
|
|
29
|
+
// context-masker.ts) matches it to dedupe. Adding a new context customType?
|
|
30
|
+
// Ensure buildContextMessage still prepends this sentinel.
|
|
31
|
+
export { GSD_CONTEXT_MESSAGE_SENTINEL };
|
|
24
32
|
|
|
25
33
|
const DEFAULT_CONTEXT_MESSAGE_MAX_CHARS = 4_000;
|
|
26
34
|
const DEFAULT_KNOWLEDGE_MAX_CHARS = 12_000;
|
|
@@ -448,14 +456,14 @@ export function buildContextMessage(opts: {
|
|
|
448
456
|
const memoryContent = markMemoryContextSupplied(opts.memoryBlock.trim());
|
|
449
457
|
if (opts.injection) {
|
|
450
458
|
const content = limitContextMessageContent(
|
|
451
|
-
memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection
|
|
459
|
+
`${GSD_CONTEXT_MESSAGE_SENTINEL}\n${memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection}`,
|
|
452
460
|
contextCharLimit,
|
|
453
461
|
);
|
|
454
462
|
return { customType: "gsd-guided-context", content, display: false as const };
|
|
455
463
|
}
|
|
456
464
|
if (opts.forensicsInjection) {
|
|
457
465
|
const content = limitContextMessageContent(
|
|
458
|
-
memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection
|
|
466
|
+
`${GSD_CONTEXT_MESSAGE_SENTINEL}\n${memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection}`,
|
|
459
467
|
contextCharLimit,
|
|
460
468
|
);
|
|
461
469
|
return { customType: "gsd-forensics", content, display: false as const };
|
|
@@ -463,7 +471,7 @@ export function buildContextMessage(opts: {
|
|
|
463
471
|
if (memoryContent) {
|
|
464
472
|
return {
|
|
465
473
|
customType: "gsd-memory",
|
|
466
|
-
content: limitContextMessageContent(memoryContent
|
|
474
|
+
content: limitContextMessageContent(`${GSD_CONTEXT_MESSAGE_SENTINEL}\n${memoryContent}`, contextCharLimit),
|
|
467
475
|
display: false as const,
|
|
468
476
|
};
|
|
469
477
|
}
|
|
@@ -9,7 +9,12 @@ import { canonicalToolName } from "../engine-hook-contract.js";
|
|
|
9
9
|
import { loadJsonFileOrNull } from "../json-persistence.js";
|
|
10
10
|
import { getIsolationMode } from "../preferences.js";
|
|
11
11
|
import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
|
|
12
|
+
import {
|
|
13
|
+
allowedPlanningDispatchAgentsList,
|
|
14
|
+
isReadOnlyPlanningDispatchAgent,
|
|
15
|
+
} from "../planning-subagent-registry.js";
|
|
12
16
|
import { logWarning } from "../workflow-logger.js";
|
|
17
|
+
import { acquireSyncLock, releaseSyncLock } from "../sync-lock.js";
|
|
13
18
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
14
19
|
import { worktreesDirs } from "../worktree-placement.js";
|
|
15
20
|
import { bashReferencesProjectRootOutsideWorktree } from "../worktree-shell-guard.js";
|
|
@@ -364,12 +369,63 @@ export function refreshWriteGateStateFromDisk(basePath: string): WriteGateSnapsh
|
|
|
364
369
|
return currentWriteGateSnapshot(basePath);
|
|
365
370
|
}
|
|
366
371
|
|
|
372
|
+
const WRITE_GATE_LOCK_NAME = "write-gate.lock";
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Test-only seam: fires once inside the held cross-process lock (after acquire,
|
|
376
|
+
* before the read-merge-write body) with the resolved lock root. Lets a
|
|
377
|
+
* regression test observe that a concurrent process is genuinely locked out of
|
|
378
|
+
* the critical section. Production leaves it null. Follows the repo's
|
|
379
|
+
* `_setGhAvailableForTest` naming convention.
|
|
380
|
+
*/
|
|
381
|
+
let interleaveHookForTest: ((lockRoot: string) => void) | null = null;
|
|
382
|
+
export function _setWriteGateInterleaveHookForTest(fn: ((lockRoot: string) => void) | null): void {
|
|
383
|
+
interleaveHookForTest = fn;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Serialize the read-merge-write critical section across the two processes
|
|
388
|
+
* that share the snapshot file (extension host + workflow MCP child). Atomic
|
|
389
|
+
* rename prevents torn files but not lost updates: without this lock the host
|
|
390
|
+
* can read the snapshot, the child can arm a gate and persist, then the host's
|
|
391
|
+
* later persist overwrites `pendingGateId`/`activeQueuePhase` (last-writer-wins
|
|
392
|
+
* fields) and silently drops the armed HARD-BLOCK gate.
|
|
393
|
+
*
|
|
394
|
+
* Fail-OPEN by contract: if a live peer holds the lock we proceed WITHOUT it —
|
|
395
|
+
* exactly the racy-but-functional behavior that shipped before this lock — and
|
|
396
|
+
* log once. The lock shrinks the race window to ~zero; it must never block,
|
|
397
|
+
* throw, or refuse a gate mutation. The lock is skipped entirely when snapshot
|
|
398
|
+
* persistence is off (no disk file, no cross-process seam).
|
|
399
|
+
*/
|
|
400
|
+
function withWriteGateLock<T>(basePath: string, fn: () => T): T {
|
|
401
|
+
if (!shouldPersistWriteGateSnapshot()) return fn();
|
|
402
|
+
const lockRoot = resolveWriteGateSnapshotRoot(basePath);
|
|
403
|
+
// Materialize `.gsd/` (including a dangling external-state symlink target)
|
|
404
|
+
// before locking. acquireSyncLock's own mkdir does NOT follow a symlink to
|
|
405
|
+
// create its target, so without this the O_EXCL open lands on a missing
|
|
406
|
+
// parent and the lock silently fails open — leaving the seam unserialized
|
|
407
|
+
// for exactly the external-state projects that need it. This is the same
|
|
408
|
+
// directory the persist path ensures anyway.
|
|
409
|
+
try { ensureWriteGateSnapshotDirectory(basePath); } catch { /* best-effort; acquire fails-open below */ }
|
|
410
|
+
const { acquired } = acquireSyncLock(lockRoot, 0, WRITE_GATE_LOCK_NAME);
|
|
411
|
+
if (!acquired) {
|
|
412
|
+
logWarning("intercept", "write-gate: proceeding without cross-process lock (held by live peer)", { lockRoot });
|
|
413
|
+
return fn();
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
interleaveHookForTest?.(lockRoot);
|
|
417
|
+
return fn();
|
|
418
|
+
} finally {
|
|
419
|
+
releaseSyncLock(lockRoot, WRITE_GATE_LOCK_NAME);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
367
423
|
/**
|
|
368
424
|
* Read-modify-write primitive for gate mutations. Reconciles the disk
|
|
369
425
|
* snapshot into memory (union merge), applies the mutation on top, then
|
|
370
|
-
* persists
|
|
371
|
-
*
|
|
372
|
-
*
|
|
426
|
+
* persists — all under the cross-process lock (withWriteGateLock). The whole
|
|
427
|
+
* sequence is synchronous, so the reconcile read doubles as the pre-persist
|
|
428
|
+
* merge of concurrent writes; there is no version field.
|
|
373
429
|
*
|
|
374
430
|
* The mutate callback sees the already-reconciled state, so policy checks
|
|
375
431
|
* (e.g. host setPending's verified-on-disk-wins guard) can live inside it
|
|
@@ -385,21 +441,23 @@ function mutateWriteGateState(
|
|
|
385
441
|
opts?: { writer?: WriteGateWriter; reconcile?: boolean },
|
|
386
442
|
): boolean {
|
|
387
443
|
const state = getWriteGateState(basePath);
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
444
|
+
return withWriteGateLock(basePath, () => {
|
|
445
|
+
if (shouldPersistWriteGateSnapshot() && (opts?.reconcile ?? true)) {
|
|
446
|
+
const disk = readDiskSnapshot(basePath);
|
|
447
|
+
if (disk) {
|
|
448
|
+
mergeSnapshotIntoState(state, disk);
|
|
449
|
+
} else {
|
|
450
|
+
// Missing OR unparseable on disk: treat as a full reset. Keeping
|
|
451
|
+
// stale in-memory state across a corrupt snapshot would persist it
|
|
452
|
+
// back on this very mutation and defeat the documented
|
|
453
|
+
// "delete the file to clear the HARD BLOCK gate" escape hatch.
|
|
454
|
+
replaceStateFromSnapshot(state, EMPTY_SNAPSHOT);
|
|
455
|
+
}
|
|
398
456
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
457
|
+
if (mutate(state) === false) return false;
|
|
458
|
+
persistWriteGateSnapshot(basePath, opts?.writer ?? defaultWriteGateWriter());
|
|
459
|
+
return true;
|
|
460
|
+
});
|
|
403
461
|
}
|
|
404
462
|
|
|
405
463
|
export function isDepthVerified(basePath: string = process.cwd()): boolean {
|
|
@@ -643,13 +701,15 @@ export const childWriteGateAdapter: WriteGateStateAdapter = {
|
|
|
643
701
|
|
|
644
702
|
function childMutate(basePath: string, mutate: (state: InMemoryWriteGateState) => void): void {
|
|
645
703
|
const state = getWriteGateState(basePath);
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
704
|
+
withWriteGateLock(basePath, () => {
|
|
705
|
+
if (shouldPersistWriteGateSnapshot()) {
|
|
706
|
+
// Always-fresh: disk is the only truth for the child; discard any
|
|
707
|
+
// cross-turn in-memory residue before mutating.
|
|
708
|
+
replaceStateFromSnapshot(state, readDiskSnapshot(basePath) ?? EMPTY_SNAPSHOT);
|
|
709
|
+
}
|
|
710
|
+
mutate(state);
|
|
711
|
+
persistWriteGateSnapshot(basePath, "child");
|
|
712
|
+
});
|
|
653
713
|
}
|
|
654
714
|
|
|
655
715
|
/**
|
|
@@ -1135,36 +1195,10 @@ export function shouldBlockQueueExecutionInSnapshot(
|
|
|
1135
1195
|
const PLANNING_WRITE_TOOLS = new Set(["write", "edit", "multi_edit", "notebook_edit"]);
|
|
1136
1196
|
const PLANNING_SUBAGENT_TOOLS = new Set(["subagent", "task"]);
|
|
1137
1197
|
|
|
1138
|
-
|
|
1139
|
-
* Canonical registry for agents that planning-dispatch may consider. Unit
|
|
1140
|
-
* manifests still declare per-unit subsets via ToolsPolicy.allowedSubagents.
|
|
1141
|
-
*/
|
|
1142
|
-
const PLANNING_DISPATCH_AGENT_REGISTRY = {
|
|
1143
|
-
mnemo: { readOnlySpecialist: true },
|
|
1144
|
-
scout: { readOnlySpecialist: true },
|
|
1145
|
-
planner: { readOnlySpecialist: true },
|
|
1146
|
-
reviewer: { readOnlySpecialist: true },
|
|
1147
|
-
security: { readOnlySpecialist: true },
|
|
1148
|
-
tester: { readOnlySpecialist: true },
|
|
1149
|
-
} as const satisfies Record<string, { readonly readOnlySpecialist: boolean }>;
|
|
1150
|
-
|
|
1151
|
-
export const ALLOWED_PLANNING_DISPATCH_AGENTS = new Set<string>(
|
|
1152
|
-
Object.entries(PLANNING_DISPATCH_AGENT_REGISTRY)
|
|
1153
|
-
.filter(([, metadata]) => metadata.readOnlySpecialist)
|
|
1154
|
-
.map(([agentId]) => agentId),
|
|
1155
|
-
);
|
|
1198
|
+
export { ALLOWED_PLANNING_DISPATCH_AGENTS } from "../planning-subagent-registry.js";
|
|
1156
1199
|
|
|
1157
1200
|
let warnedMissingControlledDispatchAgentClasses = false;
|
|
1158
1201
|
|
|
1159
|
-
function isReadOnlySpecialist(agentId: string): boolean {
|
|
1160
|
-
const metadata = PLANNING_DISPATCH_AGENT_REGISTRY[agentId as keyof typeof PLANNING_DISPATCH_AGENT_REGISTRY];
|
|
1161
|
-
return metadata?.readOnlySpecialist === true;
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
function allowedPlanningDispatchAgentsList(): string {
|
|
1165
|
-
return [...ALLOWED_PLANNING_DISPATCH_AGENTS].join(", ");
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
1202
|
function allowsControlledSubagentDispatch(
|
|
1169
1203
|
policy: ToolsPolicy,
|
|
1170
1204
|
): policy is ToolsPolicy & { readonly allowedSubagents: readonly string[] } {
|
|
@@ -1337,7 +1371,7 @@ export function shouldBlockPlanningUnit(
|
|
|
1337
1371
|
if (requested.length === 0) {
|
|
1338
1372
|
return { block: false };
|
|
1339
1373
|
}
|
|
1340
|
-
const globallyDisallowed = requested.find(a => !
|
|
1374
|
+
const globallyDisallowed = requested.find(a => !isReadOnlyPlanningDispatchAgent(a));
|
|
1341
1375
|
if (globallyDisallowed) {
|
|
1342
1376
|
return planningBlock(
|
|
1343
1377
|
unitType,
|
|
@@ -1350,7 +1384,7 @@ export function shouldBlockPlanningUnit(
|
|
|
1350
1384
|
return planningBlock(
|
|
1351
1385
|
unitType,
|
|
1352
1386
|
policy.mode,
|
|
1353
|
-
`subagent dispatch of "${disallowedByPolicy}" not permitted by ToolsPolicy.allowedSubagents; permitted agents for this unit: ${allowedSubagents.join(", ")}`,
|
|
1387
|
+
`subagent dispatch of "${disallowedByPolicy}" not permitted by unit allowlist (ToolsPolicy.allowedSubagents/planning_subagents); permitted agents for this unit: ${allowedSubagents.join(", ")}`,
|
|
1354
1388
|
);
|
|
1355
1389
|
}
|
|
1356
1390
|
return { block: false };
|
|
@@ -96,22 +96,29 @@ export function notifyDiscussNeedsInteractiveMenu(
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Hub picker for /gsd queue (reorder vs add) is unavailable.
|
|
101
|
+
*
|
|
102
|
+
* Unlike the other picker-guidance notices, /gsd queue does NOT dead-end here:
|
|
103
|
+
* the caller falls through to the add-work flow, which runs headlessly. So this
|
|
104
|
+
* notice must avoid the "did not start:" picker-failure phrasing — the headless
|
|
105
|
+
* host classifies that as a blocked dead-end (see stop-notice.ts / #1294) and
|
|
106
|
+
* would exit 10 before the add-work run starts.
|
|
107
|
+
*/
|
|
100
108
|
export function notifyQueueHubNeedsInteractiveMenu(
|
|
101
109
|
ctx: ExtensionCommandContext,
|
|
102
110
|
reason: string,
|
|
103
111
|
): void {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
112
|
+
ctx.ui.notify(
|
|
113
|
+
[
|
|
114
|
+
`/gsd queue reorder menu needs an interactive session (${reason}).`,
|
|
115
|
+
"Continuing headless with the add-work flow.",
|
|
116
|
+
"",
|
|
117
|
+
" • /gsd queue — run from the GSD TUI to reorder pending milestones",
|
|
118
|
+
" • /gsd status — see milestone order and phase",
|
|
119
|
+
].join("\n"),
|
|
120
|
+
"warning",
|
|
121
|
+
);
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
/** /gsd, /gsd new-milestone, /gsd new-project wizard menus. */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { existsSync, readFileSync, renameSync, unlinkSync, writeFileSync, mkdirSync } from "node:fs";
|
|
10
|
-
import { dirname, join } from "node:path";
|
|
10
|
+
import { dirname, join, isAbsolute, normalize } from "node:path";
|
|
11
11
|
|
|
12
12
|
/** Current marker schema version. Bump on breaking format changes + migrate. */
|
|
13
13
|
export const COMPAT_MARKER_SCHEMA = 2;
|
|
@@ -34,8 +34,10 @@ export interface PlanningMarker {
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Per-file projection entry. `sha` is a normalized-content SHA-256; `entities`
|
|
37
|
-
* is the list of DB entity ids (milestone/slice/task) that the file projects
|
|
38
|
-
*
|
|
37
|
+
* is the list of DB entity ids (milestone/slice/task) that the file projects.
|
|
38
|
+
* External-edit repair derives milestone ids from this list so markdown status
|
|
39
|
+
* authority is limited to the drifted projection's milestone scope while the
|
|
40
|
+
* importer still walks the whole tree.
|
|
39
41
|
*/
|
|
40
42
|
export interface ProjectionEntry {
|
|
41
43
|
sha: string;
|
|
@@ -220,9 +222,24 @@ function isValidProjectionEntry(x: unknown): x is ProjectionEntry {
|
|
|
220
222
|
return true;
|
|
221
223
|
}
|
|
222
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Projection-map keys are repo-relative paths under .gsd/ or .planning/.
|
|
227
|
+
* The marker is repo-controlled content, so a key must never escape its
|
|
228
|
+
* root: reject absolute paths, drive letters, backslashes, and any
|
|
229
|
+
* normalized form that starts with "..". Mirrors the write-side guard in
|
|
230
|
+
* db-writer.ts.
|
|
231
|
+
*/
|
|
232
|
+
function isSafeProjectionKey(key: string): boolean {
|
|
233
|
+
if (key.length === 0 || key.includes("\\") || key.includes("\0")) return false;
|
|
234
|
+
if (isAbsolute(key) || /^[A-Za-z]:/.test(key)) return false;
|
|
235
|
+
const norm = normalize(key);
|
|
236
|
+
return norm !== ".." && !norm.startsWith("../") && !isAbsolute(norm);
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
function isValidProjectionMap(x: unknown): boolean {
|
|
224
240
|
if (typeof x !== "object" || x === null) return false;
|
|
225
|
-
for (const v of Object.
|
|
241
|
+
for (const [k, v] of Object.entries(x as Record<string, unknown>)) {
|
|
242
|
+
if (!isSafeProjectionKey(k)) return false;
|
|
226
243
|
if (!isValidProjectionEntry(v)) return false;
|
|
227
244
|
}
|
|
228
245
|
return true;
|
|
@@ -31,36 +31,37 @@ export const CACHE_MAX = 50;
|
|
|
31
31
|
* By scoping tools to this allowlist during discuss dispatches, the grammar
|
|
32
32
|
* sent to the provider stays well under provider limits.
|
|
33
33
|
*
|
|
34
|
-
* Included tools and why
|
|
34
|
+
* Included tools and why (canonical names only — aliases are no longer
|
|
35
|
+
* advertised to models by default, see plan 035):
|
|
35
36
|
* - gsd_summary_save: writes CONTEXT.md artifacts (all discuss prompts)
|
|
36
|
-
* - gsd_save_summary: alias for above
|
|
37
37
|
* - gsd_decision_save: records decisions (discuss.md output phase)
|
|
38
|
-
* - gsd_save_decision: alias for above
|
|
39
38
|
* - gsd_plan_milestone: writes roadmap (discuss.md single/multi milestone)
|
|
40
|
-
* - gsd_milestone_plan: alias for above
|
|
41
39
|
* - gsd_milestone_generate_id: generates milestone IDs (discuss.md multi-milestone)
|
|
42
|
-
* - gsd_generate_milestone_id: alias for above
|
|
43
40
|
* - gsd_requirement_save: creates requirements during discuss
|
|
44
|
-
* - gsd_save_requirement: alias for above
|
|
45
41
|
* - gsd_requirement_update: updates requirements during discuss
|
|
46
|
-
* - gsd_update_requirement: alias for above
|
|
47
42
|
*/
|
|
48
43
|
export const DISCUSS_TOOLS_ALLOWLIST: readonly string[] = [
|
|
49
44
|
// Context / summary writing
|
|
50
45
|
"gsd_summary_save",
|
|
51
|
-
"gsd_save_summary",
|
|
52
46
|
// Decision recording
|
|
53
47
|
"gsd_decision_save",
|
|
54
|
-
"gsd_save_decision",
|
|
55
48
|
// Milestone planning (needed for discuss.md output phase)
|
|
56
49
|
"gsd_plan_milestone",
|
|
57
|
-
"gsd_milestone_plan",
|
|
58
50
|
// Milestone ID generation (multi-milestone flow)
|
|
59
51
|
"gsd_milestone_generate_id",
|
|
60
|
-
"gsd_generate_milestone_id",
|
|
61
52
|
// Requirement updates
|
|
62
53
|
"gsd_requirement_save",
|
|
63
|
-
"gsd_save_requirement",
|
|
64
54
|
"gsd_requirement_update",
|
|
65
|
-
"gsd_update_requirement",
|
|
66
55
|
];
|
|
56
|
+
|
|
57
|
+
// ─── Context Injection ────────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Leading marker stamped on every buildContextMessage() output
|
|
61
|
+
* (bootstrap/system-context.ts). Single source of truth for the producer and
|
|
62
|
+
* the consumer: the provider payload policy (filterSupersededContextInjections
|
|
63
|
+
* in context-masker.ts) matches this prefix to find and dedupe injected
|
|
64
|
+
* memory/guided/forensics messages after convertToLlm strips their customType.
|
|
65
|
+
* Both sides import it from here — do not inline the literal in either module.
|
|
66
|
+
*/
|
|
67
|
+
export const GSD_CONTEXT_MESSAGE_SENTINEL = "[GSD Context Injection]";
|