@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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only planning specialists that controlled planning dispatch may use.
|
|
3
|
+
*
|
|
4
|
+
* Unit manifests and project preferences still declare per-unit subsets. This
|
|
5
|
+
* registry is the global safety classification checked by the write gate and
|
|
6
|
+
* preference validation before any configured planning allowlist takes effect.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const PLANNING_DISPATCH_AGENT_REGISTRY = {
|
|
10
|
+
mnemo: { readOnlySpecialist: true },
|
|
11
|
+
scout: { readOnlySpecialist: true },
|
|
12
|
+
planner: { readOnlySpecialist: true },
|
|
13
|
+
reviewer: { readOnlySpecialist: true },
|
|
14
|
+
security: { readOnlySpecialist: true },
|
|
15
|
+
tester: { readOnlySpecialist: true },
|
|
16
|
+
} as const satisfies Record<string, { readonly readOnlySpecialist: boolean }>;
|
|
17
|
+
|
|
18
|
+
export const ALLOWED_PLANNING_DISPATCH_AGENTS = new Set<string>(
|
|
19
|
+
Object.entries(PLANNING_DISPATCH_AGENT_REGISTRY)
|
|
20
|
+
.filter(([, metadata]) => metadata.readOnlySpecialist)
|
|
21
|
+
.map(([agentId]) => agentId),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export function isReadOnlyPlanningDispatchAgent(agentId: string): boolean {
|
|
25
|
+
const metadata = PLANNING_DISPATCH_AGENT_REGISTRY[agentId as keyof typeof PLANNING_DISPATCH_AGENT_REGISTRY];
|
|
26
|
+
return metadata?.readOnlySpecialist === true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function allowedPlanningDispatchAgentsList(): string {
|
|
30
|
+
return [...ALLOWED_PLANNING_DISPATCH_AGENTS].join(", ");
|
|
31
|
+
}
|
|
@@ -318,12 +318,12 @@ export function checkImportResolution(
|
|
|
318
318
|
const imports = extractRelativeImports(source);
|
|
319
319
|
|
|
320
320
|
for (const { importPath, lineNum } of imports) {
|
|
321
|
-
// Framework-generated
|
|
322
|
-
// checks
|
|
323
|
-
// block task completion on these imports.
|
|
321
|
+
// Framework/codegen-generated modules may not exist on disk during
|
|
322
|
+
// post-exec checks. Don't block task completion on these imports.
|
|
324
323
|
if (
|
|
325
324
|
/^\.{1,2}\/\+types\//.test(importPath) ||
|
|
326
|
-
/^(?:\.{1,2}\/)+(?:[^/]+\/)*\$types(?:$|\/)/.test(importPath)
|
|
325
|
+
/^(?:\.{1,2}\/)+(?:[^/]+\/)*\$types(?:$|\/)/.test(importPath) ||
|
|
326
|
+
/^(?:\.{1,2}\/)+(?:[^/]+\/)*_generated(?:$|\/)/.test(importPath)
|
|
327
327
|
) {
|
|
328
328
|
continue;
|
|
329
329
|
}
|
|
@@ -141,6 +141,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
|
|
|
141
141
|
"git",
|
|
142
142
|
"post_unit_hooks",
|
|
143
143
|
"pre_dispatch_hooks",
|
|
144
|
+
"planning_subagents",
|
|
144
145
|
"dynamic_routing",
|
|
145
146
|
"disabled_model_providers",
|
|
146
147
|
"uok",
|
|
@@ -217,6 +218,20 @@ export const KNOWN_UNIT_LABELS = [
|
|
|
217
218
|
] as const;
|
|
218
219
|
export type UnitLabel = (typeof KNOWN_UNIT_LABELS)[number];
|
|
219
220
|
|
|
221
|
+
export const CONFIGURABLE_PLANNING_SUBAGENT_UNITS = [
|
|
222
|
+
"plan-milestone",
|
|
223
|
+
"plan-slice",
|
|
224
|
+
] as const;
|
|
225
|
+
export type ConfigurablePlanningSubagentUnit = (typeof CONFIGURABLE_PLANNING_SUBAGENT_UNITS)[number];
|
|
226
|
+
|
|
227
|
+
export interface PlanningSubagentUnitConfig {
|
|
228
|
+
allowed?: string[];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export type PlanningSubagentsConfig = Partial<
|
|
232
|
+
Record<ConfigurablePlanningSubagentUnit, PlanningSubagentUnitConfig>
|
|
233
|
+
>;
|
|
234
|
+
|
|
220
235
|
|
|
221
236
|
export const SKILL_ACTIONS = new Set(["use", "prefer", "avoid"]);
|
|
222
237
|
|
|
@@ -476,6 +491,7 @@ export interface GSDPreferences {
|
|
|
476
491
|
git?: GitPreferences;
|
|
477
492
|
post_unit_hooks?: PostUnitHookConfig[];
|
|
478
493
|
pre_dispatch_hooks?: PreDispatchHookConfig[];
|
|
494
|
+
planning_subagents?: PlanningSubagentsConfig;
|
|
479
495
|
dynamic_routing?: DynamicRoutingConfig;
|
|
480
496
|
/** Provider IDs to exclude from /model and automatic model routing while leaving tool auth intact. */
|
|
481
497
|
disabled_model_providers?: string[];
|
|
@@ -17,6 +17,7 @@ import { getGateIdsForTurn } from "./gate-registry.js";
|
|
|
17
17
|
import {
|
|
18
18
|
KNOWN_PREFERENCE_KEYS,
|
|
19
19
|
KNOWN_UNIT_LABELS,
|
|
20
|
+
CONFIGURABLE_PLANNING_SUBAGENT_UNITS,
|
|
20
21
|
GSD_MODEL_PHASE_KEYS,
|
|
21
22
|
|
|
22
23
|
SKILL_ACTIONS,
|
|
@@ -26,6 +27,10 @@ import {
|
|
|
26
27
|
type GSDSkillRule,
|
|
27
28
|
type GSDThinkingLevel,
|
|
28
29
|
} from "./preferences-types.js";
|
|
30
|
+
import {
|
|
31
|
+
ALLOWED_PLANNING_DISPATCH_AGENTS,
|
|
32
|
+
allowedPlanningDispatchAgentsList,
|
|
33
|
+
} from "./planning-subagent-registry.js";
|
|
29
34
|
|
|
30
35
|
const VALID_TOKEN_PROFILES = new Set<TokenProfile>(["budget", "balanced", "quality", "burn-max"]);
|
|
31
36
|
const VALID_THINKING_LEVELS = new Set<GSDThinkingLevel>([
|
|
@@ -747,6 +752,63 @@ export function validatePreferences(preferences: GSDPreferences): {
|
|
|
747
752
|
}
|
|
748
753
|
}
|
|
749
754
|
|
|
755
|
+
// ─── Planning Subagents ─────────────────────────────────────────────────
|
|
756
|
+
if (preferences.planning_subagents !== undefined) {
|
|
757
|
+
if (
|
|
758
|
+
!preferences.planning_subagents ||
|
|
759
|
+
typeof preferences.planning_subagents !== "object" ||
|
|
760
|
+
Array.isArray(preferences.planning_subagents)
|
|
761
|
+
) {
|
|
762
|
+
errors.push("planning_subagents must be an object keyed by planning unit type");
|
|
763
|
+
} else {
|
|
764
|
+
const validUnits = new Set<string>(CONFIGURABLE_PLANNING_SUBAGENT_UNITS);
|
|
765
|
+
const validPlanningSubagents: NonNullable<GSDPreferences["planning_subagents"]> = {};
|
|
766
|
+
|
|
767
|
+
for (const [unitType, rawConfig] of Object.entries(preferences.planning_subagents as Record<string, unknown>)) {
|
|
768
|
+
if (!validUnits.has(unitType)) {
|
|
769
|
+
errors.push(
|
|
770
|
+
`planning_subagents unknown or unsupported unit "${unitType}" — supported units: ` +
|
|
771
|
+
`${CONFIGURABLE_PLANNING_SUBAGENT_UNITS.join(", ")}`,
|
|
772
|
+
);
|
|
773
|
+
continue;
|
|
774
|
+
}
|
|
775
|
+
if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
|
|
776
|
+
errors.push(`planning_subagents.${unitType} must be an object with an allowed array`);
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
const allowed = normalizeStringArray((rawConfig as Record<string, unknown>).allowed);
|
|
781
|
+
if (allowed.length === 0) {
|
|
782
|
+
errors.push(`planning_subagents.${unitType}.allowed must include at least one read-only planning specialist`);
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const sanitizedAllowed: string[] = [];
|
|
787
|
+
for (const agentId of allowed) {
|
|
788
|
+
if (!ALLOWED_PLANNING_DISPATCH_AGENTS.has(agentId)) {
|
|
789
|
+
errors.push(
|
|
790
|
+
`planning_subagents.${unitType}.allowed includes "${agentId}", which is not classified as a ` +
|
|
791
|
+
`read-only planning specialist. Allowed agents: ${allowedPlanningDispatchAgentsList()}`,
|
|
792
|
+
);
|
|
793
|
+
continue;
|
|
794
|
+
}
|
|
795
|
+
sanitizedAllowed.push(agentId);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
const dedupedAllowed = Array.from(new Set(sanitizedAllowed));
|
|
799
|
+
if (dedupedAllowed.length > 0) {
|
|
800
|
+
validPlanningSubagents[unitType as keyof NonNullable<GSDPreferences["planning_subagents"]>] = {
|
|
801
|
+
allowed: dedupedAllowed,
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
if (Object.keys(validPlanningSubagents).length > 0) {
|
|
807
|
+
validated.planning_subagents = validPlanningSubagents;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
750
812
|
// ─── Dynamic Routing ─────────────────────────────────────────────────
|
|
751
813
|
if (preferences.dynamic_routing !== undefined) {
|
|
752
814
|
if (typeof preferences.dynamic_routing === "object" && preferences.dynamic_routing !== null) {
|
|
@@ -817,6 +817,7 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
|
|
|
817
817
|
: undefined,
|
|
818
818
|
post_unit_hooks: mergePostUnitHooks(base.post_unit_hooks, override.post_unit_hooks),
|
|
819
819
|
pre_dispatch_hooks: mergePreDispatchHooks(base.pre_dispatch_hooks, override.pre_dispatch_hooks),
|
|
820
|
+
planning_subagents: mergePlanningSubagents(base.planning_subagents, override.planning_subagents),
|
|
820
821
|
dynamic_routing: (base.dynamic_routing || override.dynamic_routing)
|
|
821
822
|
? { ...(base.dynamic_routing ?? {}), ...(override.dynamic_routing ?? {}) } as DynamicRoutingConfig
|
|
822
823
|
: undefined,
|
|
@@ -943,6 +944,30 @@ function mergePreDispatchHooks(
|
|
|
943
944
|
return merged.length > 0 ? merged : undefined;
|
|
944
945
|
}
|
|
945
946
|
|
|
947
|
+
function mergePlanningSubagents(
|
|
948
|
+
base?: GSDPreferences["planning_subagents"],
|
|
949
|
+
override?: GSDPreferences["planning_subagents"],
|
|
950
|
+
): GSDPreferences["planning_subagents"] | undefined {
|
|
951
|
+
if (!base && !override) return undefined;
|
|
952
|
+
const merged: NonNullable<GSDPreferences["planning_subagents"]> = {};
|
|
953
|
+
const unitTypes = new Set([
|
|
954
|
+
...Object.keys(base ?? {}),
|
|
955
|
+
...Object.keys(override ?? {}),
|
|
956
|
+
]);
|
|
957
|
+
|
|
958
|
+
for (const unitType of unitTypes) {
|
|
959
|
+
const allowed = mergeStringLists(
|
|
960
|
+
base?.[unitType as keyof NonNullable<GSDPreferences["planning_subagents"]>]?.allowed,
|
|
961
|
+
override?.[unitType as keyof NonNullable<GSDPreferences["planning_subagents"]>]?.allowed,
|
|
962
|
+
);
|
|
963
|
+
if (allowed?.length) {
|
|
964
|
+
merged[unitType as keyof NonNullable<GSDPreferences["planning_subagents"]>] = { allowed };
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
969
|
+
}
|
|
970
|
+
|
|
946
971
|
// ─── System Prompt Rendering ──────────────────────────────────────────────────
|
|
947
972
|
|
|
948
973
|
export function renderPreferencesForSystemPrompt(
|
|
@@ -66,12 +66,12 @@ Then:
|
|
|
66
66
|
**Web apps:** when inlined Web App UAT guidance is present, follow it for Playwright scaffolding and browser-capable verification commands.
|
|
67
67
|
4. For non-trivial slices, plan observability / proof level / integration closure, threat surface, and requirement impact. Omit entirely for simple slices.
|
|
68
68
|
5. Decompose the slice into tasks that fit one context window each. Every task passed to `gsd_plan_slice` must use the exact keys `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. Put Why / Do / Done-when detail in `description`. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even for one path (for example, `"expectedOutput": ["src/index.ts"]`, never `"expectedOutput": "src/index.ts"`). `expectedOutput` is path-only: list only files the task creates or overwrites, and use `[]` for pure verification tasks. Never list GSD planning artifacts — anything under `.gsd/`, `.planning/`, or `.audits/`, or artifact names like `M001-CONTEXT.md` / `S01-PLAN.md` — in `inputs`, `files`, or `expectedOutput`: their content is preloaded as context, and they are written by workflow tools, not by tasks.
|
|
69
|
-
6. **Persist planning state through `gsd_plan_slice`.** Call it with the full payload. The tool writes to the DB and renders `{{outputPath}}`
|
|
69
|
+
6. **Persist planning state through `gsd_plan_slice`.** Call it with the full payload. The tool writes to the DB and renders `{{outputPath}}` with embedded task planning automatically. Do NOT rely on direct `PLAN.md` writes.
|
|
70
70
|
7. **Self-audit the plan.** If every task were completed exactly as written, the slice goal/demo should be true. Every must-have maps to a task. Inputs and Expected Output are backtick-wrapped file paths.
|
|
71
71
|
8. If refinement produced structural decisions that diverge from the sketch, call `gsd_decision_save` for each; the tool persists the decision and regenerates `.gsd/DECISIONS.md`.
|
|
72
72
|
9. {{commitInstruction}}
|
|
73
73
|
|
|
74
|
-
The slice
|
|
74
|
+
The slice plan path already exists. Do NOT mkdir.
|
|
75
75
|
|
|
76
76
|
**Autonomous execution:** Do not call `ask_user_questions` or `secure_env_collect`. Document assumptions in the plan.
|
|
77
77
|
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
* Provider Payload Policy - ordered shaping of provider request payloads.
|
|
3
3
|
*
|
|
4
4
|
* The order is intentional:
|
|
5
|
-
* 1.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* 1. superseded GSD context injections (memory/guided/forensics) are removed,
|
|
6
|
+
* keeping only the latest, for every mode,
|
|
7
|
+
* 2. observation budgeting masks old tool results in auto-mode,
|
|
8
|
+
* 3. display truncation caps tool-result text for every mode,
|
|
9
|
+
* 4. the protected Source Context Block is appended after truncation,
|
|
10
|
+
* 5. supported models receive the configured service tier.
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
import type { ContextManagementConfig } from "./preferences-types.js";
|
|
@@ -14,6 +16,8 @@ import type { ServiceTierSetting } from "./service-tier.js";
|
|
|
14
16
|
import {
|
|
15
17
|
createObservationMask,
|
|
16
18
|
createResponsesInputObservationMask,
|
|
19
|
+
filterSupersededContextInjections,
|
|
20
|
+
filterSupersededResponsesContextInjections,
|
|
17
21
|
truncateContextResultMessages,
|
|
18
22
|
truncateResponsesInputResultItems,
|
|
19
23
|
} from "./context-masker.js";
|
|
@@ -80,10 +84,20 @@ function applyContextManagement(
|
|
|
80
84
|
deps: ProviderPayloadPolicyDeps,
|
|
81
85
|
): void {
|
|
82
86
|
const config = deps.loadContextManagementConfig();
|
|
87
|
+
applyContextInjectionFilter(payload);
|
|
83
88
|
applyObservationBudget(payload, config, deps.isAutoActive());
|
|
84
89
|
applyDisplayTruncation(payload, config);
|
|
85
90
|
}
|
|
86
91
|
|
|
92
|
+
function applyContextInjectionFilter(payload: Record<string, unknown>): void {
|
|
93
|
+
if (Array.isArray(payload.messages)) {
|
|
94
|
+
payload.messages = filterSupersededContextInjections(payload.messages as MessagePayload);
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(payload.input)) {
|
|
97
|
+
payload.input = filterSupersededResponsesContextInjections(payload.input as ResponsesInputPayload);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
87
101
|
function applyObservationBudget(
|
|
88
102
|
payload: Record<string, unknown>,
|
|
89
103
|
config: ContextManagementConfig | undefined,
|
|
@@ -14,7 +14,7 @@ interface DestructivePattern {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const DESTRUCTIVE_PATTERNS: readonly DestructivePattern[] = [
|
|
17
|
-
{ pattern: /\brm\s+(
|
|
17
|
+
{ pattern: /\brm\s+((?:-(?!-)[^\s]*[rR][^\s]*|--recursive)\s+|.*\s+(?:-(?!-)[^\s]*[rR][^\s]*|--recursive)(?:\s|$))/, label: "recursive delete" },
|
|
18
18
|
{ pattern: /\bgit\s+push\s+.*--force/, label: "force push" },
|
|
19
19
|
{ pattern: /\bgit\s+push\s+-f\b/, label: "force push" },
|
|
20
20
|
{ pattern: /\bgit\s+reset\s+--hard/, label: "hard reset" },
|
|
@@ -232,7 +232,7 @@ export function recordToolCall(toolCallId: string, toolName: string, input: Reco
|
|
|
232
232
|
toolCallId,
|
|
233
233
|
// gsd_exec / gsd_uat_exec carry the script body in `script` (or `code`);
|
|
234
234
|
// bash-style tools use `command`/`cmd`; gsd_exec_search uses `query`.
|
|
235
|
-
command:
|
|
235
|
+
command: formatExecutionEvidenceCommand(toolName, input),
|
|
236
236
|
exitCode: -1,
|
|
237
237
|
outputSnippet: "",
|
|
238
238
|
timestamp: Date.now(),
|
|
@@ -254,6 +254,33 @@ export function recordToolCall(toolCallId: string, toolName: string, input: Reco
|
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
+
function pickString(input: Record<string, unknown>, ...keys: string[]): string {
|
|
258
|
+
for (const key of keys) {
|
|
259
|
+
const value = input[key];
|
|
260
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
261
|
+
}
|
|
262
|
+
return "";
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function canonicalExecutionToolLabel(toolName: string): string {
|
|
266
|
+
const normalized = toolName.trim().toLowerCase();
|
|
267
|
+
const mcpMatch = normalized.match(/^mcp__.+__(gsd_(?:uat_)?exec(?:_search)?)$/);
|
|
268
|
+
return mcpMatch?.[1] ?? normalized;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function formatExecutionEvidenceCommand(toolName: string, input: Record<string, unknown>): string {
|
|
272
|
+
const body = pickString(input, "command", "script", "cmd", "code", "query");
|
|
273
|
+
const tool = canonicalExecutionToolLabel(toolName);
|
|
274
|
+
const purpose = pickString(input, "purpose");
|
|
275
|
+
const runtime = pickString(input, "runtime").toLowerCase();
|
|
276
|
+
const label = purpose && (tool === "gsd_exec" || tool === "gsd_uat_exec")
|
|
277
|
+
? `${tool}${runtime ? ` ${runtime}` : ""}: ${purpose}`
|
|
278
|
+
: "";
|
|
279
|
+
|
|
280
|
+
if (label && body) return `${label}\n${body}`;
|
|
281
|
+
return body || label;
|
|
282
|
+
}
|
|
283
|
+
|
|
257
284
|
/**
|
|
258
285
|
* Record a tool execution result. Matches the entry by toolCallId (assigned
|
|
259
286
|
* at dispatch time) and fills in exit code + output. Prior versions matched
|
|
@@ -161,9 +161,18 @@ function findMatches(
|
|
|
161
161
|
): BashEvidence[] {
|
|
162
162
|
const normalized = claimedCommand.trim();
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
const exact = bashCalls.filter((b) => b.command.trim() === normalized);
|
|
165
|
+
|
|
166
|
+
// When an exact run exists, also consider wrapper-equivalent reruns (e.g.
|
|
167
|
+
// `cd ... && <command>`) so a newer pass is not shadowed by a stale exact
|
|
168
|
+
// failure. Do not merge arbitrary containing scripts: their exit code may
|
|
169
|
+
// belong to later work, not to the claimed verification command.
|
|
170
|
+
const scriptWrapped = bashCalls.filter((b) => {
|
|
171
|
+
const command = b.command.trim();
|
|
172
|
+
if (command.length === 0 || command === normalized) return false;
|
|
173
|
+
return isWrapperEquivalentCommand(command, normalized);
|
|
174
|
+
});
|
|
175
|
+
if (exact.length > 0) return [...exact, ...scriptWrapped];
|
|
167
176
|
|
|
168
177
|
// Substring match: claimed is contained in actual or actual in claimed.
|
|
169
178
|
// A claimed verification command typically appears verbatim inside a
|
|
@@ -171,7 +180,7 @@ function findMatches(
|
|
|
171
180
|
// script-containing-claim is the common direction. Blank-command entries
|
|
172
181
|
// must be excluded — `"x".includes("")` is true, so they'd match anything.
|
|
173
182
|
const substring = bashCalls.filter(
|
|
174
|
-
b => b.command.trim().length > 0 &&
|
|
183
|
+
(b) => b.command.trim().length > 0 &&
|
|
175
184
|
(b.command.includes(normalized) || normalized.includes(b.command)),
|
|
176
185
|
);
|
|
177
186
|
if (substring.length > 0) return substring;
|
|
@@ -199,6 +208,23 @@ function findMatches(
|
|
|
199
208
|
|
|
200
209
|
function latestMatch(matches: readonly BashEvidence[]): BashEvidence {
|
|
201
210
|
return matches.reduce((latest, match) => (
|
|
202
|
-
match.timestamp
|
|
211
|
+
match.timestamp >= latest.timestamp ? match : latest
|
|
203
212
|
));
|
|
204
213
|
}
|
|
214
|
+
|
|
215
|
+
/** True when `actual` is the same command with only shell wrapper noise. */
|
|
216
|
+
function isWrapperEquivalentCommand(actual: string, claimed: string): boolean {
|
|
217
|
+
const claimIndex = actual.lastIndexOf(claimed);
|
|
218
|
+
if (claimIndex < 0) return false;
|
|
219
|
+
|
|
220
|
+
const prefix = actual.slice(0, claimIndex).trim();
|
|
221
|
+
if (prefix.length > 0 && !/^cd\s+.+\s+&&$/.test(prefix)) return false;
|
|
222
|
+
|
|
223
|
+
const suffix = actual.slice(claimIndex + claimed.length).trim();
|
|
224
|
+
return suffix.length === 0 || isBenignWrapperSuffix(suffix);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function isBenignWrapperSuffix(suffix: string): boolean {
|
|
228
|
+
if (/^;\s*echo\s+["']?[A-Z_]*EXIT=\$\?["']?$/.test(suffix)) return true;
|
|
229
|
+
return /^(?:(?:\d?>>?|&>)\s*\S+|\d?>&\d)(?:\s+(?:(?:\d?>>?|&>)\s*\S+|\d?>&\d))*$/.test(suffix);
|
|
230
|
+
}
|
|
@@ -131,10 +131,23 @@ function resolvePreferredSkillNames(
|
|
|
131
131
|
* to prevent prompt injection via crafted directory names. */
|
|
132
132
|
const SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
133
133
|
|
|
134
|
-
function
|
|
134
|
+
function escapeXml(str: string): string {
|
|
135
|
+
return str
|
|
136
|
+
.replace(/&/g, "&")
|
|
137
|
+
.replace(/</g, "<")
|
|
138
|
+
.replace(/>/g, ">")
|
|
139
|
+
.replace(/"/g, """)
|
|
140
|
+
.replace(/'/g, "'");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function formatSkillActivationBlock(skillNames: string[], skillPaths: Map<string, string>): string {
|
|
135
144
|
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
136
145
|
if (safe.length === 0) return "";
|
|
137
|
-
const reads = safe.map(name =>
|
|
146
|
+
const reads = safe.map(name => {
|
|
147
|
+
const path = skillPaths.get(name);
|
|
148
|
+
if (path) return `Read the skill file at \`${escapeXml(path)}\``;
|
|
149
|
+
return `Find '${name}' in <available_skills>, copy its <location> value, and pass that exact path to read`;
|
|
150
|
+
}).join(". ");
|
|
138
151
|
return `<skill_activation>${reads}.</skill_activation>`;
|
|
139
152
|
}
|
|
140
153
|
|
|
@@ -203,6 +216,7 @@ export function buildSkillActivationBlock(params: {
|
|
|
203
216
|
const visibleSkills = loaded;
|
|
204
217
|
const manifestScopedSkills = filterSkillsByManifest(visibleSkills, params.unitType);
|
|
205
218
|
const installedNames = new Set(visibleSkills.map(skill => normalizeSkillReference(skill.name)));
|
|
219
|
+
const installedSkillPaths = new Map(visibleSkills.map(skill => [normalizeSkillReference(skill.name), skill.filePath]));
|
|
206
220
|
warnIfManifestHasMissingSkills(params.unitType, installedNames);
|
|
207
221
|
const avoided = new Set(resolvePreferenceSkillNames(prefs?.avoid_skills ?? [], params.base));
|
|
208
222
|
const matched = new Set<string>();
|
|
@@ -252,7 +266,7 @@ export function buildSkillActivationBlock(params: {
|
|
|
252
266
|
const ordered = [...matched]
|
|
253
267
|
.filter(name => installedNames.has(name) && !avoided.has(name))
|
|
254
268
|
.sort();
|
|
255
|
-
const activationBlock = formatSkillActivationBlock(ordered);
|
|
269
|
+
const activationBlock = formatSkillActivationBlock(ordered, installedSkillPaths);
|
|
256
270
|
|
|
257
271
|
// Omit recommendations when the system catalog is manifest-scoped for this
|
|
258
272
|
// unit — skill names are already listed in <available_skills>.
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
//
|
|
4
4
|
// gsd-pi's DB is canonical, but .gsd/*.md is the inter-tool contract. When
|
|
5
5
|
// gsd-core edits a projection file, this handler detects the sha drift vs the
|
|
6
|
-
// recorded baseline in .gsd/.compat.json and re-imports
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// recorded baseline in .gsd/.compat.json and re-imports from markdown with
|
|
7
|
+
// status authority scoped to the affected milestone ids. The next
|
|
8
|
+
// renderAllFromDb pass re-projects; the write-time invalidation hook then
|
|
9
|
+
// refreshes the marker entry, closing the loop.
|
|
9
10
|
|
|
10
11
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
12
|
import { join } from "node:path";
|
|
@@ -59,10 +60,11 @@ function detectExternalMarkdownEdit(
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/**
|
|
62
|
-
* Idempotent repair: re-import hierarchy
|
|
63
|
-
* markdown
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* Idempotent repair: re-import the hierarchy from markdown while allowing
|
|
64
|
+
* markdown status authority only for milestones named by the drifted file's
|
|
65
|
+
* marker entities, then update the marker entry so the next detect pass sees
|
|
66
|
+
* the file as expected. migrateHierarchyToDb is itself idempotent (upsert), so
|
|
67
|
+
* re-running this repair after a successful one is a no-op.
|
|
66
68
|
*/
|
|
67
69
|
async function repairExternalMarkdownEdit(
|
|
68
70
|
record: ExternalMarkdownEditDrift,
|
|
@@ -72,13 +74,28 @@ async function repairExternalMarkdownEdit(
|
|
|
72
74
|
// Dynamic imports break a module-init cycle: this handler ← registry ←
|
|
73
75
|
// state.ts ← guided-flow.ts ← md-importer.ts ← (this handler's old static
|
|
74
76
|
// import). Deferring to repair time keeps module load cycle-free.
|
|
75
|
-
const { migrateHierarchyToDb } = await import("../../md-importer.js");
|
|
77
|
+
const { migrateHierarchyToDb, milestoneIdsFromEntities } = await import("../../md-importer.js");
|
|
76
78
|
const { invalidateStateCache } = await import("../../state.js");
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
79
|
+
// #027: migrateHierarchyToDb walks the whole tree (a cheap upsert), so
|
|
80
|
+
// without scoping every projection rides along with markdown *status*
|
|
81
|
+
// authority. That lets an unrelated file that is stale from gsd-pi's own
|
|
82
|
+
// miss silently revert a reopened slice/milestone. Scope status authority to
|
|
83
|
+
// exactly the milestone(s) this drifted file projects.
|
|
84
|
+
//
|
|
85
|
+
// Step 1: the marker's `entities` are DB ids (`M001`, `M001/S01`,
|
|
86
|
+
// `M001/S01/T01`), so the milestone id is always the first `/`-segment —
|
|
87
|
+
// layout-independent (legacy `milestones/<MID>/…` and flat `phases/NN-slug/…`
|
|
88
|
+
// both resolve the same way), no projectionPath parsing needed. An empty set
|
|
89
|
+
// (no resolvable entities) preserves DB status everywhere: fail toward
|
|
90
|
+
// protecting the DB, not toward markdown authority.
|
|
91
|
+
const statusAuthoritativeMilestones = milestoneIdsFromEntities(record.entities);
|
|
92
|
+
if (statusAuthoritativeMilestones.size === 0) {
|
|
93
|
+
logWarning(
|
|
94
|
+
"reconcile",
|
|
95
|
+
`external-markdown-edit: no milestone scope resolved for ${record.projectionPath}; preserving DB status for all milestones`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
migrateHierarchyToDb(ctx.basePath, { statusAuthoritativeMilestones });
|
|
82
99
|
invalidateStateCache();
|
|
83
100
|
} catch (err) {
|
|
84
101
|
logWarning(
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
// Parallel to external-markdown-edit.ts. Detects sha drift between the compat
|
|
4
4
|
// marker's planning.projections/passthrough and current .planning/ files.
|
|
5
5
|
//
|
|
6
|
-
// Modeled files (projections): re-imported via parsePlanningDirectory → DB
|
|
6
|
+
// Modeled files (projections): re-imported via parsePlanningDirectory → DB,
|
|
7
|
+
// with markdown status authority scoped to their marker entity milestone ids.
|
|
7
8
|
// Passthrough files (un-modeled docs): sha refreshed, content untouched.
|
|
8
9
|
|
|
9
10
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -148,13 +149,25 @@ async function repairExternalPlanningEdit(
|
|
|
148
149
|
const { parsePlanningDirectory } = await import("../../migrate/parser.js");
|
|
149
150
|
const { transformToGSD } = await import("../../migrate/transformer.js");
|
|
150
151
|
const { writeGSDDirectory } = await import("../../migrate/writer.js");
|
|
151
|
-
const { migrateHierarchyToDb } = await import("../../md-importer.js");
|
|
152
|
+
const { migrateHierarchyToDb, milestoneIdsFromEntities } = await import("../../md-importer.js");
|
|
152
153
|
const { invalidateStateCache } = await import("../../state.js");
|
|
153
154
|
|
|
154
155
|
const parsed = await parsePlanningDirectory(join(ctx.basePath, ".planning"));
|
|
155
156
|
const gsdProject = transformToGSD(parsed);
|
|
156
157
|
await writeGSDDirectory(gsdProject, ctx.basePath);
|
|
157
|
-
|
|
158
|
+
// #027: scope status authority to the milestone(s) this drifted .planning/
|
|
159
|
+
// file projects (first `/`-segment of its DB entity ids), so a stale
|
|
160
|
+
// checkbox in an unrelated projection can't revert a reopened slice/milestone
|
|
161
|
+
// in the DB. Unseeded files carry no entities → empty set → preserve DB
|
|
162
|
+
// status everywhere (fail toward the DB, log the breadcrumb).
|
|
163
|
+
const statusAuthoritativeMilestones = milestoneIdsFromEntities(record.entities);
|
|
164
|
+
if (statusAuthoritativeMilestones.size === 0) {
|
|
165
|
+
logWarning(
|
|
166
|
+
"reconcile",
|
|
167
|
+
`external-planning-edit: no milestone scope resolved for ${record.projectionPath}; preserving DB status for all milestones`,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
migrateHierarchyToDb(ctx.basePath, { statusAuthoritativeMilestones });
|
|
158
171
|
invalidateStateCache();
|
|
159
172
|
} catch (err) {
|
|
160
173
|
logWarning(
|
|
@@ -49,14 +49,14 @@ export type DriftRecord =
|
|
|
49
49
|
projectionPath: string; // relative to basePath, e.g. "m1/plan.md"
|
|
50
50
|
expectedSha: string; // sha recorded in .compat.json
|
|
51
51
|
actualSha: string; // freshly computed from disk
|
|
52
|
-
entities: string[]; // DB entity ids to
|
|
52
|
+
entities: string[]; // DB entity ids used to scope status authority
|
|
53
53
|
}
|
|
54
54
|
| {
|
|
55
55
|
kind: "external-planning-edit";
|
|
56
56
|
projectionPath: string; // relative to .planning/, e.g. "phases/01-foo/01-01-PLAN.md"
|
|
57
57
|
expectedSha: string;
|
|
58
58
|
actualSha: string;
|
|
59
|
-
entities: string[];
|
|
59
|
+
entities: string[]; // DB entity ids used to scope status authority
|
|
60
60
|
passthrough: boolean; // true = content-only, no re-import, just refresh sha
|
|
61
61
|
};
|
|
62
62
|
|
|
@@ -66,10 +66,27 @@ export function isNonBlockingPauseNotice(message: string): boolean {
|
|
|
66
66
|
return message.includes("idempotent advance: unit already active");
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* A picker / next-action menu that could not render in a non-interactive
|
|
71
|
+
* (headless / RPC) session. Both wordings originate from the menu-unavailable
|
|
72
|
+
* helpers (`notifyCommandMenuUnavailable` and `notifyPickerCommandNeedsInteractiveMenu`
|
|
73
|
+
* in next-action-ui.ts / command-feedback.ts). Headless `auto`/`next` cannot
|
|
74
|
+
* answer such a menu, so the run has dead-ended and needs operator intervention.
|
|
75
|
+
* Classify it as blocked so the headless host exits 10 instead of idling
|
|
76
|
+
* forever waiting for a completion signal that never comes. (#1294)
|
|
77
|
+
*/
|
|
78
|
+
export function isInteractiveMenuUnavailableNotice(message: string): boolean {
|
|
79
|
+
return (
|
|
80
|
+
message.includes("menu could not be shown in this session") ||
|
|
81
|
+
message.includes("did not start:")
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
69
85
|
export function isBlockedNoticeMessage(message: string): boolean {
|
|
70
86
|
return (
|
|
71
87
|
message.includes("blocked:") ||
|
|
72
88
|
(isPauseNotice(message) && !isNonBlockingPauseNotice(message)) ||
|
|
73
|
-
isManualResolutionNotice(message)
|
|
89
|
+
isManualResolutionNotice(message) ||
|
|
90
|
+
isInteractiveMenuUnavailableNotice(message)
|
|
74
91
|
);
|
|
75
92
|
}
|
|
@@ -9,8 +9,10 @@ import { dirname, join } from "node:path";
|
|
|
9
9
|
const STALE_THRESHOLD_MS = 60_000; // 60 seconds
|
|
10
10
|
const DEFAULT_TIMEOUT_MS = 0; // fail fast; sync waits block the JS event loop
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const DEFAULT_LOCK_NAME = "sync.lock";
|
|
13
|
+
|
|
14
|
+
function lockFilePath(basePath: string, lockName: string = DEFAULT_LOCK_NAME): string {
|
|
15
|
+
return join(basePath, ".gsd", lockName);
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/** True if the given PID is alive in the current process namespace. */
|
|
@@ -74,8 +76,9 @@ function tryCreateLockFile(lp: string, payload: string): boolean {
|
|
|
74
76
|
export function acquireSyncLock(
|
|
75
77
|
basePath: string,
|
|
76
78
|
_timeoutMs: number = DEFAULT_TIMEOUT_MS,
|
|
79
|
+
lockName: string = DEFAULT_LOCK_NAME,
|
|
77
80
|
): { acquired: boolean } {
|
|
78
|
-
const lp = lockFilePath(basePath);
|
|
81
|
+
const lp = lockFilePath(basePath, lockName);
|
|
79
82
|
const lockData = JSON.stringify(
|
|
80
83
|
{ pid: process.pid, acquired_at: new Date().toISOString() },
|
|
81
84
|
null,
|
|
@@ -89,7 +92,12 @@ export function acquireSyncLock(
|
|
|
89
92
|
return { acquired: true };
|
|
90
93
|
}
|
|
91
94
|
} catch {
|
|
92
|
-
|
|
95
|
+
// tryCreateLockFile only throws for non-EEXIST errors — a persistently
|
|
96
|
+
// uncreatable lock path (dangling-symlink parent, ENOTDIR, read-only FS).
|
|
97
|
+
// Retrying would spin the loop forever with no progress condition,
|
|
98
|
+
// blocking the JS event loop. Fail open like a contended lock so callers
|
|
99
|
+
// proceed (racy but functional) instead of hanging.
|
|
100
|
+
return { acquired: false };
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
// File exists. Decide whether to steal (stale + owner dead) or skip.
|
|
@@ -131,8 +139,8 @@ export function acquireSyncLock(
|
|
|
131
139
|
/**
|
|
132
140
|
* Release the advisory sync lock. No-op if lock file does not exist.
|
|
133
141
|
*/
|
|
134
|
-
export function releaseSyncLock(basePath: string): void {
|
|
135
|
-
const lp = lockFilePath(basePath);
|
|
142
|
+
export function releaseSyncLock(basePath: string, lockName: string = DEFAULT_LOCK_NAME): void {
|
|
143
|
+
const lp = lockFilePath(basePath, lockName);
|
|
136
144
|
try {
|
|
137
145
|
if (existsSync(lp)) {
|
|
138
146
|
unlinkSync(lp);
|
|
@@ -92,6 +92,11 @@ remote_questions:
|
|
|
92
92
|
uat_dispatch:
|
|
93
93
|
post_unit_hooks: []
|
|
94
94
|
pre_dispatch_hooks: []
|
|
95
|
+
# planning_subagents:
|
|
96
|
+
# plan-milestone:
|
|
97
|
+
# allowed: [scout, planner, security]
|
|
98
|
+
# plan-slice:
|
|
99
|
+
# allowed: [scout, planner, reviewer, security]
|
|
95
100
|
# language:
|
|
96
101
|
# experimental:
|
|
97
102
|
# rtk: false
|