@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
|
@@ -2,12 +2,14 @@
|
|
|
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
|
-
import { createObservationMask, createResponsesInputObservationMask, truncateContextResultMessages, truncateResponsesInputResultItems, } from "./context-masker.js";
|
|
12
|
+
import { createObservationMask, createResponsesInputObservationMask, filterSupersededContextInjections, filterSupersededResponsesContextInjections, truncateContextResultMessages, truncateResponsesInputResultItems, } from "./context-masker.js";
|
|
11
13
|
import { getSourceObservationStore, isAutoActive } from "./auto-runtime-state.js";
|
|
12
14
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
13
15
|
import { getEffectiveServiceTier, supportsServiceTier } from "./service-tier.js";
|
|
@@ -42,9 +44,18 @@ export function applyProviderPayloadPolicy({ payload, modelId, deps: overrides,
|
|
|
42
44
|
}
|
|
43
45
|
function applyContextManagement(payload, deps) {
|
|
44
46
|
const config = deps.loadContextManagementConfig();
|
|
47
|
+
applyContextInjectionFilter(payload);
|
|
45
48
|
applyObservationBudget(payload, config, deps.isAutoActive());
|
|
46
49
|
applyDisplayTruncation(payload, config);
|
|
47
50
|
}
|
|
51
|
+
function applyContextInjectionFilter(payload) {
|
|
52
|
+
if (Array.isArray(payload.messages)) {
|
|
53
|
+
payload.messages = filterSupersededContextInjections(payload.messages);
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(payload.input)) {
|
|
56
|
+
payload.input = filterSupersededResponsesContextInjections(payload.input);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
48
59
|
function applyObservationBudget(payload, config, autoActive) {
|
|
49
60
|
if (!autoActive || config?.observation_masking === false)
|
|
50
61
|
return;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
7
7
|
*/
|
|
8
8
|
const DESTRUCTIVE_PATTERNS = [
|
|
9
|
-
{ pattern: /\brm\s+(
|
|
9
|
+
{ pattern: /\brm\s+((?:-(?!-)[^\s]*[rR][^\s]*|--recursive)\s+|.*\s+(?:-(?!-)[^\s]*[rR][^\s]*|--recursive)(?:\s|$))/, label: "recursive delete" },
|
|
10
10
|
{ pattern: /\bgit\s+push\s+.*--force/, label: "force push" },
|
|
11
11
|
{ pattern: /\bgit\s+push\s+-f\b/, label: "force push" },
|
|
12
12
|
{ pattern: /\bgit\s+reset\s+--hard/, label: "hard reset" },
|
|
@@ -173,7 +173,7 @@ export function recordToolCall(toolCallId, toolName, input) {
|
|
|
173
173
|
toolCallId,
|
|
174
174
|
// gsd_exec / gsd_uat_exec carry the script body in `script` (or `code`);
|
|
175
175
|
// bash-style tools use `command`/`cmd`; gsd_exec_search uses `query`.
|
|
176
|
-
command:
|
|
176
|
+
command: formatExecutionEvidenceCommand(toolName, input),
|
|
177
177
|
exitCode: -1,
|
|
178
178
|
outputSnippet: "",
|
|
179
179
|
timestamp: Date.now(),
|
|
@@ -196,6 +196,31 @@ export function recordToolCall(toolCallId, toolName, input) {
|
|
|
196
196
|
});
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
+
function pickString(input, ...keys) {
|
|
200
|
+
for (const key of keys) {
|
|
201
|
+
const value = input[key];
|
|
202
|
+
if (typeof value === "string" && value.trim().length > 0)
|
|
203
|
+
return value.trim();
|
|
204
|
+
}
|
|
205
|
+
return "";
|
|
206
|
+
}
|
|
207
|
+
function canonicalExecutionToolLabel(toolName) {
|
|
208
|
+
const normalized = toolName.trim().toLowerCase();
|
|
209
|
+
const mcpMatch = normalized.match(/^mcp__.+__(gsd_(?:uat_)?exec(?:_search)?)$/);
|
|
210
|
+
return mcpMatch?.[1] ?? normalized;
|
|
211
|
+
}
|
|
212
|
+
function formatExecutionEvidenceCommand(toolName, input) {
|
|
213
|
+
const body = pickString(input, "command", "script", "cmd", "code", "query");
|
|
214
|
+
const tool = canonicalExecutionToolLabel(toolName);
|
|
215
|
+
const purpose = pickString(input, "purpose");
|
|
216
|
+
const runtime = pickString(input, "runtime").toLowerCase();
|
|
217
|
+
const label = purpose && (tool === "gsd_exec" || tool === "gsd_uat_exec")
|
|
218
|
+
? `${tool}${runtime ? ` ${runtime}` : ""}: ${purpose}`
|
|
219
|
+
: "";
|
|
220
|
+
if (label && body)
|
|
221
|
+
return `${label}\n${body}`;
|
|
222
|
+
return body || label;
|
|
223
|
+
}
|
|
199
224
|
/**
|
|
200
225
|
* Record a tool execution result. Matches the entry by toolCallId (assigned
|
|
201
226
|
* at dispatch time) and fills in exit code + output. Prior versions matched
|
|
@@ -118,16 +118,25 @@ function latestClaimBatch(claimedEvidence) {
|
|
|
118
118
|
*/
|
|
119
119
|
function findMatches(claimedCommand, bashCalls) {
|
|
120
120
|
const normalized = claimedCommand.trim();
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
const exact = bashCalls.filter((b) => b.command.trim() === normalized);
|
|
122
|
+
// When an exact run exists, also consider wrapper-equivalent reruns (e.g.
|
|
123
|
+
// `cd ... && <command>`) so a newer pass is not shadowed by a stale exact
|
|
124
|
+
// failure. Do not merge arbitrary containing scripts: their exit code may
|
|
125
|
+
// belong to later work, not to the claimed verification command.
|
|
126
|
+
const scriptWrapped = bashCalls.filter((b) => {
|
|
127
|
+
const command = b.command.trim();
|
|
128
|
+
if (command.length === 0 || command === normalized)
|
|
129
|
+
return false;
|
|
130
|
+
return isWrapperEquivalentCommand(command, normalized);
|
|
131
|
+
});
|
|
123
132
|
if (exact.length > 0)
|
|
124
|
-
return exact;
|
|
133
|
+
return [...exact, ...scriptWrapped];
|
|
125
134
|
// Substring match: claimed is contained in actual or actual in claimed.
|
|
126
135
|
// A claimed verification command typically appears verbatim inside a
|
|
127
136
|
// larger gsd_exec script body (cd prefix, multi-line scripts), so
|
|
128
137
|
// script-containing-claim is the common direction. Blank-command entries
|
|
129
138
|
// must be excluded — `"x".includes("")` is true, so they'd match anything.
|
|
130
|
-
const substring = bashCalls.filter(b => b.command.trim().length > 0 &&
|
|
139
|
+
const substring = bashCalls.filter((b) => b.command.trim().length > 0 &&
|
|
131
140
|
(b.command.includes(normalized) || normalized.includes(b.command)));
|
|
132
141
|
if (substring.length > 0)
|
|
133
142
|
return substring;
|
|
@@ -150,5 +159,21 @@ function findMatches(claimedCommand, bashCalls) {
|
|
|
150
159
|
.map((match) => match.call);
|
|
151
160
|
}
|
|
152
161
|
function latestMatch(matches) {
|
|
153
|
-
return matches.reduce((latest, match) => (match.timestamp
|
|
162
|
+
return matches.reduce((latest, match) => (match.timestamp >= latest.timestamp ? match : latest));
|
|
163
|
+
}
|
|
164
|
+
/** True when `actual` is the same command with only shell wrapper noise. */
|
|
165
|
+
function isWrapperEquivalentCommand(actual, claimed) {
|
|
166
|
+
const claimIndex = actual.lastIndexOf(claimed);
|
|
167
|
+
if (claimIndex < 0)
|
|
168
|
+
return false;
|
|
169
|
+
const prefix = actual.slice(0, claimIndex).trim();
|
|
170
|
+
if (prefix.length > 0 && !/^cd\s+.+\s+&&$/.test(prefix))
|
|
171
|
+
return false;
|
|
172
|
+
const suffix = actual.slice(claimIndex + claimed.length).trim();
|
|
173
|
+
return suffix.length === 0 || isBenignWrapperSuffix(suffix);
|
|
174
|
+
}
|
|
175
|
+
function isBenignWrapperSuffix(suffix) {
|
|
176
|
+
if (/^;\s*echo\s+["']?[A-Z_]*EXIT=\$\?["']?$/.test(suffix))
|
|
177
|
+
return true;
|
|
178
|
+
return /^(?:(?:\d?>>?|&>)\s*\S+|\d?>&\d)(?:\s+(?:(?:\d?>>?|&>)\s*\S+|\d?>&\d))*$/.test(suffix);
|
|
154
179
|
}
|
|
@@ -104,11 +104,24 @@ function resolvePreferredSkillNames(prefs, visibleSkills, contextTokens, base) {
|
|
|
104
104
|
/** Skill names must be lowercase alphanumeric with hyphens — reject anything else
|
|
105
105
|
* to prevent prompt injection via crafted directory names. */
|
|
106
106
|
const SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
107
|
-
function
|
|
107
|
+
function escapeXml(str) {
|
|
108
|
+
return str
|
|
109
|
+
.replace(/&/g, "&")
|
|
110
|
+
.replace(/</g, "<")
|
|
111
|
+
.replace(/>/g, ">")
|
|
112
|
+
.replace(/"/g, """)
|
|
113
|
+
.replace(/'/g, "'");
|
|
114
|
+
}
|
|
115
|
+
function formatSkillActivationBlock(skillNames, skillPaths) {
|
|
108
116
|
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
109
117
|
if (safe.length === 0)
|
|
110
118
|
return "";
|
|
111
|
-
const reads = safe.map(name =>
|
|
119
|
+
const reads = safe.map(name => {
|
|
120
|
+
const path = skillPaths.get(name);
|
|
121
|
+
if (path)
|
|
122
|
+
return `Read the skill file at \`${escapeXml(path)}\``;
|
|
123
|
+
return `Find '${name}' in <available_skills>, copy its <location> value, and pass that exact path to read`;
|
|
124
|
+
}).join(". ");
|
|
112
125
|
return `<skill_activation>${reads}.</skill_activation>`;
|
|
113
126
|
}
|
|
114
127
|
/**
|
|
@@ -149,6 +162,7 @@ export function buildSkillActivationBlock(params) {
|
|
|
149
162
|
const visibleSkills = loaded;
|
|
150
163
|
const manifestScopedSkills = filterSkillsByManifest(visibleSkills, params.unitType);
|
|
151
164
|
const installedNames = new Set(visibleSkills.map(skill => normalizeSkillReference(skill.name)));
|
|
165
|
+
const installedSkillPaths = new Map(visibleSkills.map(skill => [normalizeSkillReference(skill.name), skill.filePath]));
|
|
152
166
|
warnIfManifestHasMissingSkills(params.unitType, installedNames);
|
|
153
167
|
const avoided = new Set(resolvePreferenceSkillNames(prefs?.avoid_skills ?? [], params.base));
|
|
154
168
|
const matched = new Set();
|
|
@@ -196,7 +210,7 @@ export function buildSkillActivationBlock(params) {
|
|
|
196
210
|
const ordered = [...matched]
|
|
197
211
|
.filter(name => installedNames.has(name) && !avoided.has(name))
|
|
198
212
|
.sort();
|
|
199
|
-
const activationBlock = formatSkillActivationBlock(ordered);
|
|
213
|
+
const activationBlock = formatSkillActivationBlock(ordered, installedSkillPaths);
|
|
200
214
|
// Omit recommendations when the system catalog is manifest-scoped for this
|
|
201
215
|
// unit — skill names are already listed in <available_skills>.
|
|
202
216
|
let recommendationsBlock = "";
|
|
@@ -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
|
import { existsSync, readFileSync } from "node:fs";
|
|
10
11
|
import { join } from "node:path";
|
|
11
12
|
import { computeProjectionSha, readCompatMarker, writeCompatMarker, } from "../../compat/compat-marker.js";
|
|
@@ -43,23 +44,36 @@ function detectExternalMarkdownEdit(_state, ctx) {
|
|
|
43
44
|
return records;
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
|
-
* Idempotent repair: re-import hierarchy
|
|
47
|
-
* markdown
|
|
48
|
-
*
|
|
49
|
-
*
|
|
47
|
+
* Idempotent repair: re-import the hierarchy from markdown while allowing
|
|
48
|
+
* markdown status authority only for milestones named by the drifted file's
|
|
49
|
+
* marker entities, then update the marker entry so the next detect pass sees
|
|
50
|
+
* the file as expected. migrateHierarchyToDb is itself idempotent (upsert), so
|
|
51
|
+
* re-running this repair after a successful one is a no-op.
|
|
50
52
|
*/
|
|
51
53
|
async function repairExternalMarkdownEdit(record, ctx) {
|
|
52
54
|
try {
|
|
53
55
|
// Dynamic imports break a module-init cycle: this handler ← registry ←
|
|
54
56
|
// state.ts ← guided-flow.ts ← md-importer.ts ← (this handler's old static
|
|
55
57
|
// import). Deferring to repair time keeps module load cycle-free.
|
|
56
|
-
const { migrateHierarchyToDb } = await import("../../md-importer.js");
|
|
58
|
+
const { migrateHierarchyToDb, milestoneIdsFromEntities } = await import("../../md-importer.js");
|
|
57
59
|
const { invalidateStateCache } = await import("../../state.js");
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
|
|
60
|
+
// #027: migrateHierarchyToDb walks the whole tree (a cheap upsert), so
|
|
61
|
+
// without scoping every projection rides along with markdown *status*
|
|
62
|
+
// authority. That lets an unrelated file that is stale from gsd-pi's own
|
|
63
|
+
// miss silently revert a reopened slice/milestone. Scope status authority to
|
|
64
|
+
// exactly the milestone(s) this drifted file projects.
|
|
65
|
+
//
|
|
66
|
+
// Step 1: the marker's `entities` are DB ids (`M001`, `M001/S01`,
|
|
67
|
+
// `M001/S01/T01`), so the milestone id is always the first `/`-segment —
|
|
68
|
+
// layout-independent (legacy `milestones/<MID>/…` and flat `phases/NN-slug/…`
|
|
69
|
+
// both resolve the same way), no projectionPath parsing needed. An empty set
|
|
70
|
+
// (no resolvable entities) preserves DB status everywhere: fail toward
|
|
71
|
+
// protecting the DB, not toward markdown authority.
|
|
72
|
+
const statusAuthoritativeMilestones = milestoneIdsFromEntities(record.entities);
|
|
73
|
+
if (statusAuthoritativeMilestones.size === 0) {
|
|
74
|
+
logWarning("reconcile", `external-markdown-edit: no milestone scope resolved for ${record.projectionPath}; preserving DB status for all milestones`);
|
|
75
|
+
}
|
|
76
|
+
migrateHierarchyToDb(ctx.basePath, { statusAuthoritativeMilestones });
|
|
63
77
|
invalidateStateCache();
|
|
64
78
|
}
|
|
65
79
|
catch (err) {
|
|
@@ -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
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
10
|
import { join } from "node:path";
|
|
@@ -115,12 +116,21 @@ async function repairExternalPlanningEdit(record, ctx) {
|
|
|
115
116
|
const { parsePlanningDirectory } = await import("../../migrate/parser.js");
|
|
116
117
|
const { transformToGSD } = await import("../../migrate/transformer.js");
|
|
117
118
|
const { writeGSDDirectory } = await import("../../migrate/writer.js");
|
|
118
|
-
const { migrateHierarchyToDb } = await import("../../md-importer.js");
|
|
119
|
+
const { migrateHierarchyToDb, milestoneIdsFromEntities } = await import("../../md-importer.js");
|
|
119
120
|
const { invalidateStateCache } = await import("../../state.js");
|
|
120
121
|
const parsed = await parsePlanningDirectory(join(ctx.basePath, ".planning"));
|
|
121
122
|
const gsdProject = transformToGSD(parsed);
|
|
122
123
|
await writeGSDDirectory(gsdProject, ctx.basePath);
|
|
123
|
-
|
|
124
|
+
// #027: scope status authority to the milestone(s) this drifted .planning/
|
|
125
|
+
// file projects (first `/`-segment of its DB entity ids), so a stale
|
|
126
|
+
// checkbox in an unrelated projection can't revert a reopened slice/milestone
|
|
127
|
+
// in the DB. Unseeded files carry no entities → empty set → preserve DB
|
|
128
|
+
// status everywhere (fail toward the DB, log the breadcrumb).
|
|
129
|
+
const statusAuthoritativeMilestones = milestoneIdsFromEntities(record.entities);
|
|
130
|
+
if (statusAuthoritativeMilestones.size === 0) {
|
|
131
|
+
logWarning("reconcile", `external-planning-edit: no milestone scope resolved for ${record.projectionPath}; preserving DB status for all milestones`);
|
|
132
|
+
}
|
|
133
|
+
migrateHierarchyToDb(ctx.basePath, { statusAuthoritativeMilestones });
|
|
124
134
|
invalidateStateCache();
|
|
125
135
|
}
|
|
126
136
|
catch (err) {
|
|
@@ -50,8 +50,22 @@ export function isTerminalNotice(message) {
|
|
|
50
50
|
export function isNonBlockingPauseNotice(message) {
|
|
51
51
|
return message.includes("idempotent advance: unit already active");
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* A picker / next-action menu that could not render in a non-interactive
|
|
55
|
+
* (headless / RPC) session. Both wordings originate from the menu-unavailable
|
|
56
|
+
* helpers (`notifyCommandMenuUnavailable` and `notifyPickerCommandNeedsInteractiveMenu`
|
|
57
|
+
* in next-action-ui.ts / command-feedback.ts). Headless `auto`/`next` cannot
|
|
58
|
+
* answer such a menu, so the run has dead-ended and needs operator intervention.
|
|
59
|
+
* Classify it as blocked so the headless host exits 10 instead of idling
|
|
60
|
+
* forever waiting for a completion signal that never comes. (#1294)
|
|
61
|
+
*/
|
|
62
|
+
export function isInteractiveMenuUnavailableNotice(message) {
|
|
63
|
+
return (message.includes("menu could not be shown in this session") ||
|
|
64
|
+
message.includes("did not start:"));
|
|
65
|
+
}
|
|
53
66
|
export function isBlockedNoticeMessage(message) {
|
|
54
67
|
return (message.includes("blocked:") ||
|
|
55
68
|
(isPauseNotice(message) && !isNonBlockingPauseNotice(message)) ||
|
|
56
|
-
isManualResolutionNotice(message)
|
|
69
|
+
isManualResolutionNotice(message) ||
|
|
70
|
+
isInteractiveMenuUnavailableNotice(message));
|
|
57
71
|
}
|
|
@@ -6,8 +6,9 @@ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, statSync, unl
|
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
const STALE_THRESHOLD_MS = 60_000; // 60 seconds
|
|
8
8
|
const DEFAULT_TIMEOUT_MS = 0; // fail fast; sync waits block the JS event loop
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const DEFAULT_LOCK_NAME = "sync.lock";
|
|
10
|
+
function lockFilePath(basePath, lockName = DEFAULT_LOCK_NAME) {
|
|
11
|
+
return join(basePath, ".gsd", lockName);
|
|
11
12
|
}
|
|
12
13
|
/** True if the given PID is alive in the current process namespace. */
|
|
13
14
|
function isPidAlive(pid) {
|
|
@@ -71,8 +72,8 @@ function tryCreateLockFile(lp, payload) {
|
|
|
71
72
|
* I/O, and UI work on Node's single JS thread. The timeout argument remains
|
|
72
73
|
* accepted for compatibility but is intentionally not used for sync waiting.
|
|
73
74
|
*/
|
|
74
|
-
export function acquireSyncLock(basePath, _timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
75
|
-
const lp = lockFilePath(basePath);
|
|
75
|
+
export function acquireSyncLock(basePath, _timeoutMs = DEFAULT_TIMEOUT_MS, lockName = DEFAULT_LOCK_NAME) {
|
|
76
|
+
const lp = lockFilePath(basePath, lockName);
|
|
76
77
|
const lockData = JSON.stringify({ pid: process.pid, acquired_at: new Date().toISOString() }, null, 2);
|
|
77
78
|
while (true) {
|
|
78
79
|
// First try the fast path: atomic create. No check-then-write race.
|
|
@@ -82,7 +83,12 @@ export function acquireSyncLock(basePath, _timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
catch {
|
|
85
|
-
|
|
86
|
+
// tryCreateLockFile only throws for non-EEXIST errors — a persistently
|
|
87
|
+
// uncreatable lock path (dangling-symlink parent, ENOTDIR, read-only FS).
|
|
88
|
+
// Retrying would spin the loop forever with no progress condition,
|
|
89
|
+
// blocking the JS event loop. Fail open like a contended lock so callers
|
|
90
|
+
// proceed (racy but functional) instead of hanging.
|
|
91
|
+
return { acquired: false };
|
|
86
92
|
}
|
|
87
93
|
// File exists. Decide whether to steal (stale + owner dead) or skip.
|
|
88
94
|
let canSteal = false;
|
|
@@ -125,8 +131,8 @@ export function acquireSyncLock(basePath, _timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
|
125
131
|
/**
|
|
126
132
|
* Release the advisory sync lock. No-op if lock file does not exist.
|
|
127
133
|
*/
|
|
128
|
-
export function releaseSyncLock(basePath) {
|
|
129
|
-
const lp = lockFilePath(basePath);
|
|
134
|
+
export function releaseSyncLock(basePath, lockName = DEFAULT_LOCK_NAME) {
|
|
135
|
+
const lp = lockFilePath(basePath, lockName);
|
|
130
136
|
try {
|
|
131
137
|
if (existsSync(lp)) {
|
|
132
138
|
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
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import { existsSync, unlinkSync } from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { isClosedStatus } from "../status-guards.js";
|
|
15
|
-
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, deleteVerificationEvidence, saveGateResult, getPendingGatesForTurn, } from "../gsd-db.js";
|
|
15
|
+
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, deleteVerificationEvidence, saveGateResult, getPendingGatesForTurn, getUnresolvedBlockingReworkFindingsForTask, getBlockingReworkFindingsForTask, applyReworkResolutions, } from "../gsd-db.js";
|
|
16
16
|
import { getWorkflowDatabasePath, ensureWorkflowDbAtPath } from "../db-workspace.js";
|
|
17
17
|
import { getGatesForTurn } from "../gate-registry.js";
|
|
18
|
-
import { gsdProjectionRoot, clearPathCache, resolveMilestonePath, resolveSlicePath } from "../paths.js";
|
|
18
|
+
import { buildFlatTaskFileName, buildTaskFileName, gsdProjectionRoot, clearPathCache, legacyMilestonesDir, resolveMilestonePath, resolveSlicePath, } from "../paths.js";
|
|
19
19
|
import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
|
|
20
20
|
import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
|
|
21
21
|
import { saveFile, clearParseCache } from "../files.js";
|
|
@@ -34,13 +34,20 @@ function taskSummaryPath(basePath, milestoneId, sliceId, taskId) {
|
|
|
34
34
|
// a legacy layout and breaks all subsequent path resolution for the session.
|
|
35
35
|
const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
|
|
36
36
|
const phaseDir = resolveMilestonePath(basePath, milestoneId);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
const legacyBase = legacyMilestonesDir(basePath);
|
|
38
|
+
const isLegacy = phaseDir
|
|
39
|
+
? phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\")
|
|
40
|
+
: false;
|
|
41
|
+
if (isLegacy && phaseDir) {
|
|
42
|
+
// Legacy layout: the slice has its own slices/SID/ subdir → tasks/ subdir.
|
|
43
|
+
const legacySlicePath = slicePath && slicePath !== phaseDir
|
|
44
|
+
? slicePath
|
|
45
|
+
: join(phaseDir, "slices", sliceId);
|
|
46
|
+
return join(legacySlicePath, "tasks", buildTaskFileName(taskId, "SUMMARY"));
|
|
40
47
|
}
|
|
41
48
|
if (phaseDir) {
|
|
42
49
|
// Flat-phase: task summaries go in the phase dir (no tasks/ subdir)
|
|
43
|
-
return join(phaseDir,
|
|
50
|
+
return join(phaseDir, buildFlatTaskFileName(sliceId, taskId, "SUMMARY"));
|
|
44
51
|
}
|
|
45
52
|
// Fallback: legacy hardcoded path (milestone/slice dir not on disk yet)
|
|
46
53
|
return join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks", `${taskId}-SUMMARY.md`);
|
|
@@ -107,6 +114,44 @@ export function normalizeListParam(value) {
|
|
|
107
114
|
* Build a TaskRow-shaped object from CompleteTaskParams so the unified
|
|
108
115
|
* renderSummaryContent() can be used at completion time (#2720).
|
|
109
116
|
*/
|
|
117
|
+
function normalizeReworkResolution(params) {
|
|
118
|
+
return (params.reworkResolution ?? []).map((resolution) => ({
|
|
119
|
+
milestoneId: params.milestoneId,
|
|
120
|
+
sliceId: params.sliceId,
|
|
121
|
+
taskId: params.taskId,
|
|
122
|
+
findingId: resolution.findingId,
|
|
123
|
+
status: resolution.status,
|
|
124
|
+
evidence: resolution.evidence,
|
|
125
|
+
decisionRef: resolution.decisionRef,
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
function unresolvedReworkError(missingFindingIds) {
|
|
129
|
+
const plural = missingFindingIds.length === 1 ? "finding" : "findings";
|
|
130
|
+
return `unresolved blocking rework ${plural}: ${missingFindingIds.join(", ")} — provide reworkResolution entries with status resolved and evidence, or status deferred-with-override with evidence and decisionRef, before completing the task`;
|
|
131
|
+
}
|
|
132
|
+
function satisfiesBlockingReworkFinding(resolution) {
|
|
133
|
+
if (resolution.evidence.trim().length === 0)
|
|
134
|
+
return false;
|
|
135
|
+
if (resolution.status === "resolved")
|
|
136
|
+
return true;
|
|
137
|
+
return (resolution.decisionRef ?? "").trim().length > 0;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Restore rework findings to their pre-completion state.
|
|
141
|
+
*
|
|
142
|
+
* The completion transaction flips blocking findings to resolved/
|
|
143
|
+
* deferred-with-override via applyReworkResolutions. When a later projection
|
|
144
|
+
* or escalation write fails and we compensate by reverting the task to
|
|
145
|
+
* `pending`, we must also revert those findings. Otherwise a retry sees no
|
|
146
|
+
* unresolved blocking findings (getUnresolvedBlockingReworkFindingsForTask
|
|
147
|
+
* only returns `pending` rows) and completes the task with the blocking gate
|
|
148
|
+
* silently skipped.
|
|
149
|
+
*/
|
|
150
|
+
function revertAppliedReworkResolutions(snapshot) {
|
|
151
|
+
if (snapshot.length === 0)
|
|
152
|
+
return;
|
|
153
|
+
applyReworkResolutions(snapshot);
|
|
154
|
+
}
|
|
110
155
|
function paramsToTaskRow(params, completedAt) {
|
|
111
156
|
return {
|
|
112
157
|
milestone_id: params.milestoneId,
|
|
@@ -182,6 +227,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
182
227
|
let guardError = null;
|
|
183
228
|
let summaryMd = "";
|
|
184
229
|
let repairTaskSummaryRow = null;
|
|
230
|
+
let appliedReworkSnapshot = [];
|
|
185
231
|
const rollbackDbPath = getWorkflowDatabasePath();
|
|
186
232
|
// ── ADR-011 Phase 2: validate escalation payload BEFORE any side effects ─
|
|
187
233
|
// Building the artifact runs the full shape validation (2-4 options, unique
|
|
@@ -192,6 +238,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
192
238
|
// no escalation recorded, and the loop would silently advance past it.
|
|
193
239
|
// The filesystem write happens later (after side effects) because that's
|
|
194
240
|
// the cheapest ordering and validation is where 99% of failures live.
|
|
241
|
+
const reworkResolutions = normalizeReworkResolution(params);
|
|
195
242
|
let validatedEscalationArtifact = null;
|
|
196
243
|
let escalationWriteEnabled = false;
|
|
197
244
|
if (params.escalation) {
|
|
@@ -231,6 +278,17 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
231
278
|
return;
|
|
232
279
|
}
|
|
233
280
|
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
281
|
+
const unresolvedRework = getUnresolvedBlockingReworkFindingsForTask(params.milestoneId, params.sliceId, params.taskId);
|
|
282
|
+
const resolvedFindingIds = new Set(reworkResolutions
|
|
283
|
+
.filter(satisfiesBlockingReworkFinding)
|
|
284
|
+
.map((resolution) => resolution.findingId));
|
|
285
|
+
const missingFindingIds = unresolvedRework
|
|
286
|
+
.filter((finding) => !resolvedFindingIds.has(finding.finding_id))
|
|
287
|
+
.map((finding) => finding.finding_id);
|
|
288
|
+
if (missingFindingIds.length > 0) {
|
|
289
|
+
guardError = unresolvedReworkError(missingFindingIds);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
234
292
|
if (existingTask && isClosedStatus(existingTask.status)) {
|
|
235
293
|
// Stale-turn path: a timed-out turn that was superseded by recovery
|
|
236
294
|
// can still reach this code when its LLM call eventually returns and
|
|
@@ -278,6 +336,33 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
278
336
|
keyDecisions: params.keyDecisions ?? [],
|
|
279
337
|
fullSummaryMd: summaryMd,
|
|
280
338
|
});
|
|
339
|
+
// Only persist resolutions that actually satisfy the evidence
|
|
340
|
+
// requirement. The guard above admits a finding as long as ONE satisfying
|
|
341
|
+
// entry exists, but applyReworkResolutions writes by findingId and lets the
|
|
342
|
+
// last entry win. Persisting every entry would let a later non-satisfying
|
|
343
|
+
// duplicate (empty evidence, or deferred-with-override without decisionRef)
|
|
344
|
+
// overwrite a valid resolution and leave the finding non-pending without
|
|
345
|
+
// acceptable evidence. Filtering with the same predicate the guard uses
|
|
346
|
+
// keeps the applied set and the gate consistent.
|
|
347
|
+
const resolutionsToApply = reworkResolutions.filter(satisfiesBlockingReworkFinding);
|
|
348
|
+
if (resolutionsToApply.length > 0) {
|
|
349
|
+
// Snapshot the pre-resolution state of the findings we're about to
|
|
350
|
+
// change so a compensating rollback can restore them exactly (see
|
|
351
|
+
// revertAppliedReworkResolutions).
|
|
352
|
+
const resolvedFindingIdsForSnapshot = new Set(resolutionsToApply.map((r) => r.findingId));
|
|
353
|
+
appliedReworkSnapshot = getBlockingReworkFindingsForTask(params.milestoneId, params.sliceId, params.taskId)
|
|
354
|
+
.filter((finding) => resolvedFindingIdsForSnapshot.has(finding.finding_id))
|
|
355
|
+
.map((finding) => ({
|
|
356
|
+
milestoneId: params.milestoneId,
|
|
357
|
+
sliceId: params.sliceId,
|
|
358
|
+
taskId: params.taskId,
|
|
359
|
+
findingId: finding.finding_id,
|
|
360
|
+
status: finding.status,
|
|
361
|
+
evidence: finding.evidence,
|
|
362
|
+
decisionRef: finding.decision_ref,
|
|
363
|
+
}));
|
|
364
|
+
applyReworkResolutions(resolutionsToApply);
|
|
365
|
+
}
|
|
281
366
|
for (const evidence of (params.verificationEvidence ?? [])) {
|
|
282
367
|
insertVerificationEvidence({
|
|
283
368
|
taskId: params.taskId,
|
|
@@ -340,6 +425,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
340
425
|
ensureWorkflowDbAtPath(rollbackDbPath);
|
|
341
426
|
deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
|
|
342
427
|
updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, "pending");
|
|
428
|
+
revertAppliedReworkResolutions(appliedReworkSnapshot);
|
|
343
429
|
invalidateStateCache();
|
|
344
430
|
rollbackSucceeded = true;
|
|
345
431
|
}
|
|
@@ -430,6 +516,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
430
516
|
try {
|
|
431
517
|
deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
|
|
432
518
|
updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, 'pending');
|
|
519
|
+
revertAppliedReworkResolutions(appliedReworkSnapshot);
|
|
433
520
|
invalidateStateCache();
|
|
434
521
|
logWarning("tool", `complete-task rolled back DB completion for ${params.milestoneId}/${params.sliceId}/${params.taskId} after escalation write failure; SUMMARY.md left on disk for retry.`);
|
|
435
522
|
}
|
|
@@ -447,6 +534,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
447
534
|
try {
|
|
448
535
|
deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
|
|
449
536
|
updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, 'pending');
|
|
537
|
+
revertAppliedReworkResolutions(appliedReworkSnapshot);
|
|
450
538
|
invalidateStateCache();
|
|
451
539
|
logWarning("tool", `complete-task rolled back DB completion for ${params.milestoneId}/${params.sliceId}/${params.taskId} because hard-blocker escalation handling is disabled; SUMMARY.md left on disk for retry.`);
|
|
452
540
|
}
|
|
@@ -5,7 +5,7 @@ import { getGateIdsForTurn } from "../gate-registry.js";
|
|
|
5
5
|
import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning, insertGateRow, setSliceSketchFlag } from "../gsd-db.js";
|
|
6
6
|
import { invalidateStateCache } from "../state.js";
|
|
7
7
|
import { renderTaskPlanFromDb, renderPlanFromDb } from "../markdown-renderer.js";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveMilestonePath, resolveSlicePath } from "../paths.js";
|
|
9
9
|
import { flushWorkflowProjections } from "../projection-flush.js";
|
|
10
10
|
import { writeManifest } from "../workflow-manifest.js";
|
|
11
11
|
import { appendEvent } from "../workflow-events.js";
|
|
@@ -193,21 +193,19 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
193
193
|
return { error: guardError };
|
|
194
194
|
}
|
|
195
195
|
try {
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// Guard: resolveTasksDir is null in flat-phase (no tasks/ subdir exists).
|
|
196
|
+
const milestonePath = resolveMilestonePath(basePath, params.milestoneId);
|
|
197
|
+
const slicePath = resolveSlicePath(basePath, params.milestoneId, params.sliceId);
|
|
198
|
+
const isLegacySliceLayout = Boolean(milestonePath && slicePath && slicePath !== milestonePath);
|
|
199
|
+
let renderedPath;
|
|
201
200
|
let slicePlanSynced = false;
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
206
|
-
slicePlanSynced = true;
|
|
207
|
-
}
|
|
201
|
+
if (isLegacySliceLayout) {
|
|
202
|
+
const renderResult = await renderTaskPlanFromDb(basePath, params.milestoneId, params.sliceId, params.taskId);
|
|
203
|
+
renderedPath = renderResult.taskPlanPath;
|
|
208
204
|
}
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
else {
|
|
206
|
+
const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
207
|
+
renderedPath = renderResult.planPath;
|
|
208
|
+
slicePlanSynced = true;
|
|
211
209
|
}
|
|
212
210
|
if (slicePlanSynced) {
|
|
213
211
|
setSliceSketchFlag(params.milestoneId, params.sliceId, false);
|
|
@@ -234,7 +232,7 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
234
232
|
milestoneId: params.milestoneId,
|
|
235
233
|
sliceId: params.sliceId,
|
|
236
234
|
taskId: params.taskId,
|
|
237
|
-
taskPlanPath:
|
|
235
|
+
taskPlanPath: renderedPath,
|
|
238
236
|
};
|
|
239
237
|
}
|
|
240
238
|
catch (err) {
|