@opengsd/gsd-pi 1.1.1-dev.74e8dd1 → 1.1.1-dev.75048e7
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/dist/cli.js +3 -2
- package/dist/help-text.js +10 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
- package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
- package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/dist/resources/extensions/browser-tools/index.js +57 -9
- package/dist/resources/extensions/browser-tools/package.json +5 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +77 -13
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +21 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +63 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +3 -4
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -66
- package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
- package/dist/resources/extensions/gsd/auto.js +9 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +20 -14
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +28 -13
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +18 -29
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
- package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -1
- package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
- package/dist/resources/extensions/gsd/escalation.js +4 -4
- package/dist/resources/extensions/gsd/forensics.js +74 -2
- package/dist/resources/extensions/gsd/gsd-db.js +5 -2
- package/dist/resources/extensions/gsd/guided-flow.js +118 -175
- package/dist/resources/extensions/gsd/mcp-project-config.js +9 -76
- package/dist/resources/extensions/gsd/memory-store.js +4 -1
- package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
- package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
- package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +25 -21
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
- package/dist/resources/extensions/gsd/rule-registry.js +428 -52
- package/dist/resources/extensions/gsd/state.js +2 -2
- package/dist/resources/extensions/gsd/templates/plan.md +3 -1
- package/dist/resources/extensions/gsd/tool-contract.js +5 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +30 -7
- package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +132 -18
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
- package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
- package/dist/resources/extensions/gsd/verification-gate.js +72 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +3 -75
- package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
- package/dist/rtk.d.ts +7 -1
- package/dist/rtk.js +27 -11
- package/dist/update-check.d.ts +15 -1
- package/dist/update-check.js +87 -12
- package/dist/update-cmd.d.ts +1 -0
- package/dist/update-cmd.js +53 -2
- 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 +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- 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/package.json +4 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +32 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/index.d.ts +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +1 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
- package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
- package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
- package/packages/gsd-agent-core/package.json +6 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +20 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +23 -9
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +2 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +42 -3
- package/packages/pi-agent-core/dist/agent-loop.js.map +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/dist/harness/agent-harness.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +6 -1
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/api-registry.d.ts +2 -0
- package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/packages/pi-ai/dist/api-registry.js +23 -0
- package/packages/pi-ai/dist/api-registry.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +74 -23
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +82 -31
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/stream.js +6 -6
- package/packages/pi-ai/dist/stream.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
- package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
- package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/src/resources/extensions/browser-tools/index.ts +60 -9
- package/src/resources/extensions/browser-tools/package.json +5 -1
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +82 -14
- package/src/resources/extensions/gsd/auto-dispatch.ts +19 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +28 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +97 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +3 -3
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -74
- package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
- package/src/resources/extensions/gsd/auto.ts +12 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +20 -14
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +32 -13
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +50 -54
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
- package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -1
- package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
- package/src/resources/extensions/gsd/escalation.ts +4 -4
- package/src/resources/extensions/gsd/forensics.ts +99 -5
- package/src/resources/extensions/gsd/gsd-db.ts +5 -2
- package/src/resources/extensions/gsd/guided-flow.ts +214 -216
- package/src/resources/extensions/gsd/mcp-project-config.ts +13 -78
- package/src/resources/extensions/gsd/memory-store.ts +4 -1
- package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
- package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +25 -21
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
- package/src/resources/extensions/gsd/rule-registry.ts +558 -58
- package/src/resources/extensions/gsd/rule-types.ts +2 -0
- package/src/resources/extensions/gsd/state.ts +2 -2
- package/src/resources/extensions/gsd/templates/plan.md +3 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +105 -4
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -10
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +73 -1
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +410 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -0
- package/src/resources/extensions/gsd/tool-contract.ts +6 -0
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +63 -7
- package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +163 -20
- package/src/resources/extensions/gsd/types.ts +69 -5
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
- package/src/resources/extensions/gsd/verification-gate.ts +87 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +3 -75
- package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
- /package/dist/web/standalone/.next/static/{eRWf-RI9bzbrwEurm_3uI → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{eRWf-RI9bzbrwEurm_3uI → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Central Unit-to-tool contracts for phase-aware GSD tool surfaces.
|
|
3
|
+
|
|
4
|
+
export interface UnitToolSurfaceContract {
|
|
5
|
+
allowedGsdTools: readonly string[];
|
|
6
|
+
requiredWorkflowTools: readonly string[];
|
|
7
|
+
forbiddenGsdTools?: Readonly<Record<string, string>>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const RUN_UAT_WORKFLOW_TOOL_NAMES = [
|
|
11
|
+
"gsd_uat_exec",
|
|
12
|
+
"gsd_uat_result_save",
|
|
13
|
+
"gsd_resume",
|
|
14
|
+
"gsd_milestone_status",
|
|
15
|
+
"gsd_journal_query",
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
export const RUN_UAT_READ_ONLY_TOOL_NAMES = [
|
|
19
|
+
"find",
|
|
20
|
+
"glob",
|
|
21
|
+
"grep",
|
|
22
|
+
"ls",
|
|
23
|
+
"read",
|
|
24
|
+
] as const;
|
|
25
|
+
|
|
26
|
+
export const RUN_UAT_BROWSER_TOOL_NAMES = [
|
|
27
|
+
"browser_navigate",
|
|
28
|
+
"browser_click",
|
|
29
|
+
"browser_type",
|
|
30
|
+
"browser_fill_form",
|
|
31
|
+
"browser_click_ref",
|
|
32
|
+
"browser_fill_ref",
|
|
33
|
+
"browser_wait_for",
|
|
34
|
+
"browser_assert",
|
|
35
|
+
"browser_verify",
|
|
36
|
+
"browser_screenshot",
|
|
37
|
+
"browser_snapshot_refs",
|
|
38
|
+
"browser_find",
|
|
39
|
+
"browser_get_console_logs",
|
|
40
|
+
"browser_get_network_logs",
|
|
41
|
+
"browser_evaluate",
|
|
42
|
+
"browser_reload",
|
|
43
|
+
"browser_batch",
|
|
44
|
+
"browser_act",
|
|
45
|
+
] as const;
|
|
46
|
+
|
|
47
|
+
export const RUN_UAT_TOOL_PRESENTATION_PLAN_ID = "run-uat/default-v1";
|
|
48
|
+
|
|
49
|
+
export const UNIT_TOOL_CONTRACTS: Record<string, UnitToolSurfaceContract> = {
|
|
50
|
+
"research-milestone": {
|
|
51
|
+
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
52
|
+
requiredWorkflowTools: ["gsd_summary_save"],
|
|
53
|
+
},
|
|
54
|
+
"plan-milestone": {
|
|
55
|
+
allowedGsdTools: ["gsd_plan_milestone", "gsd_decision_save", "gsd_requirement_update"],
|
|
56
|
+
requiredWorkflowTools: ["gsd_plan_milestone"],
|
|
57
|
+
},
|
|
58
|
+
"discuss-milestone": {
|
|
59
|
+
allowedGsdTools: [
|
|
60
|
+
"gsd_summary_save",
|
|
61
|
+
"gsd_decision_save",
|
|
62
|
+
"gsd_requirement_save",
|
|
63
|
+
"gsd_requirement_update",
|
|
64
|
+
"gsd_plan_milestone",
|
|
65
|
+
"gsd_milestone_generate_id",
|
|
66
|
+
],
|
|
67
|
+
requiredWorkflowTools: [
|
|
68
|
+
"gsd_summary_save",
|
|
69
|
+
"gsd_requirement_save",
|
|
70
|
+
"gsd_requirement_update",
|
|
71
|
+
"gsd_plan_milestone",
|
|
72
|
+
"gsd_milestone_generate_id",
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
"discuss-slice": {
|
|
76
|
+
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
77
|
+
requiredWorkflowTools: ["gsd_summary_save"],
|
|
78
|
+
},
|
|
79
|
+
"validate-milestone": {
|
|
80
|
+
allowedGsdTools: ["gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
|
|
81
|
+
requiredWorkflowTools: ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap"],
|
|
82
|
+
},
|
|
83
|
+
"complete-milestone": {
|
|
84
|
+
allowedGsdTools: ["gsd_complete_milestone", "subagent"],
|
|
85
|
+
requiredWorkflowTools: ["gsd_milestone_status", "gsd_complete_milestone"],
|
|
86
|
+
},
|
|
87
|
+
"research-slice": {
|
|
88
|
+
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
89
|
+
requiredWorkflowTools: ["gsd_summary_save"],
|
|
90
|
+
},
|
|
91
|
+
"plan-slice": {
|
|
92
|
+
allowedGsdTools: ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
93
|
+
requiredWorkflowTools: ["gsd_plan_slice"],
|
|
94
|
+
},
|
|
95
|
+
"refine-slice": {
|
|
96
|
+
allowedGsdTools: ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
97
|
+
requiredWorkflowTools: [],
|
|
98
|
+
},
|
|
99
|
+
"replan-slice": {
|
|
100
|
+
allowedGsdTools: ["gsd_replan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
101
|
+
requiredWorkflowTools: ["gsd_replan_slice"],
|
|
102
|
+
},
|
|
103
|
+
"complete-slice": {
|
|
104
|
+
allowedGsdTools: [
|
|
105
|
+
"gsd_slice_complete",
|
|
106
|
+
"gsd_task_reopen",
|
|
107
|
+
"gsd_replan_slice",
|
|
108
|
+
"gsd_decision_save",
|
|
109
|
+
"gsd_requirement_update",
|
|
110
|
+
"subagent",
|
|
111
|
+
],
|
|
112
|
+
requiredWorkflowTools: ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice"],
|
|
113
|
+
forbiddenGsdTools: {
|
|
114
|
+
gsd_uat_result_save: "Run UAT owns persisted UAT Assessment.",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
"reassess-roadmap": {
|
|
118
|
+
allowedGsdTools: ["gsd_reassess_roadmap"],
|
|
119
|
+
requiredWorkflowTools: ["gsd_milestone_status", "gsd_reassess_roadmap"],
|
|
120
|
+
},
|
|
121
|
+
"execute-task": {
|
|
122
|
+
allowedGsdTools: ["gsd_task_complete", "gsd_decision_save"],
|
|
123
|
+
requiredWorkflowTools: ["gsd_task_complete"],
|
|
124
|
+
},
|
|
125
|
+
"execute-task-simple": {
|
|
126
|
+
allowedGsdTools: ["gsd_task_complete", "gsd_decision_save"],
|
|
127
|
+
requiredWorkflowTools: ["gsd_task_complete"],
|
|
128
|
+
},
|
|
129
|
+
"reactive-execute": {
|
|
130
|
+
allowedGsdTools: ["gsd_task_complete", "gsd_decision_save"],
|
|
131
|
+
requiredWorkflowTools: ["gsd_task_complete"],
|
|
132
|
+
},
|
|
133
|
+
"run-uat": {
|
|
134
|
+
allowedGsdTools: [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent"],
|
|
135
|
+
requiredWorkflowTools: [...RUN_UAT_WORKFLOW_TOOL_NAMES],
|
|
136
|
+
forbiddenGsdTools: {
|
|
137
|
+
gsd_exec: "Use gsd_uat_exec so acceptance evidence is typed as UAT-owned.",
|
|
138
|
+
gsd_save_gate_result: "gsd_uat_result_save owns the aggregate UAT gate.",
|
|
139
|
+
gsd_summary_save: "gsd_uat_result_save owns persisted UAT Assessment writes.",
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
"gate-evaluate": {
|
|
143
|
+
allowedGsdTools: ["gsd_save_gate_result"],
|
|
144
|
+
requiredWorkflowTools: ["gsd_save_gate_result"],
|
|
145
|
+
},
|
|
146
|
+
"rewrite-docs": {
|
|
147
|
+
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
148
|
+
requiredWorkflowTools: [],
|
|
149
|
+
},
|
|
150
|
+
"workflow-preferences": {
|
|
151
|
+
allowedGsdTools: ["gsd_summary_save"],
|
|
152
|
+
requiredWorkflowTools: [],
|
|
153
|
+
},
|
|
154
|
+
"discuss-project": {
|
|
155
|
+
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save", "gsd_requirement_save"],
|
|
156
|
+
requiredWorkflowTools: ["ask_user_questions", "gsd_summary_save"],
|
|
157
|
+
},
|
|
158
|
+
"discuss-requirements": {
|
|
159
|
+
allowedGsdTools: ["gsd_requirement_save", "gsd_summary_save"],
|
|
160
|
+
requiredWorkflowTools: ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"],
|
|
161
|
+
},
|
|
162
|
+
"research-decision": {
|
|
163
|
+
allowedGsdTools: ["gsd_summary_save"],
|
|
164
|
+
requiredWorkflowTools: ["ask_user_questions"],
|
|
165
|
+
},
|
|
166
|
+
"research-project": {
|
|
167
|
+
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
168
|
+
requiredWorkflowTools: [],
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export const AUTO_UNIT_SCOPED_TOOLS: Record<string, readonly string[]> = Object.fromEntries(
|
|
173
|
+
Object.entries(UNIT_TOOL_CONTRACTS).map(([unitType, contract]) => [unitType, contract.allowedGsdTools]),
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
export function getUnitToolSurfaceContract(unitType: string): UnitToolSurfaceContract | undefined {
|
|
177
|
+
return UNIT_TOOL_CONTRACTS[unitType];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function getRequiredWorkflowToolsForUnit(unitType: string): string[] {
|
|
181
|
+
return [...(UNIT_TOOL_CONTRACTS[unitType]?.requiredWorkflowTools ?? [])];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function getForbiddenGsdToolReason(unitType: string, toolName: string): string | undefined {
|
|
185
|
+
return UNIT_TOOL_CONTRACTS[unitType]?.forbiddenGsdTools?.[toolName];
|
|
186
|
+
}
|
|
@@ -7,9 +7,60 @@
|
|
|
7
7
|
|
|
8
8
|
import { extractUatType } from "./files.js";
|
|
9
9
|
import type { UatType } from "./files.js";
|
|
10
|
+
import { splitFrontmatter, parseFrontmatterMap } from "../shared/frontmatter.js";
|
|
11
|
+
import { parse as parseYaml } from "yaml";
|
|
12
|
+
|
|
13
|
+
function normalizeVerdict(value: unknown): string | undefined {
|
|
14
|
+
if (typeof value !== "string") return undefined;
|
|
15
|
+
let verdict = value.trim().toLowerCase();
|
|
16
|
+
if (!verdict) return undefined;
|
|
17
|
+
if (verdict === "passed") verdict = "pass";
|
|
18
|
+
return verdict;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getCaseInsensitive(obj: Record<string, unknown>, key: string): unknown {
|
|
22
|
+
const lowerKey = key.toLowerCase();
|
|
23
|
+
for (const [candidate, value] of Object.entries(obj)) {
|
|
24
|
+
if (candidate.toLowerCase() === lowerKey) return value;
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
10
28
|
|
|
11
29
|
// ── Verdict extraction ──────────────────────────────────────────────────
|
|
12
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Extract and normalize the frontmatter `verdict` value.
|
|
33
|
+
*
|
|
34
|
+
* Supports both top-level `verdict` and the hook outcome shape
|
|
35
|
+
* `outcome.verdict`. Returns `undefined` when frontmatter is absent or has no
|
|
36
|
+
* verdict field.
|
|
37
|
+
*/
|
|
38
|
+
export function extractFrontmatterVerdict(content: string): string | undefined {
|
|
39
|
+
const [frontmatterLines] = splitFrontmatter(content);
|
|
40
|
+
if (!frontmatterLines) return undefined;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const parsed = parseYaml(frontmatterLines.join("\n")) as unknown;
|
|
44
|
+
if (parsed && typeof parsed === "object") {
|
|
45
|
+
const root = parsed as Record<string, unknown>;
|
|
46
|
+
const topLevel = normalizeVerdict(getCaseInsensitive(root, "verdict"));
|
|
47
|
+
if (topLevel) return topLevel;
|
|
48
|
+
const outcome = getCaseInsensitive(root, "outcome");
|
|
49
|
+
if (outcome && typeof outcome === "object") {
|
|
50
|
+
const nested = normalizeVerdict(getCaseInsensitive(outcome as Record<string, unknown>, "verdict"));
|
|
51
|
+
if (nested) return nested;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
// Fall through to the permissive parser used by legacy frontmatter paths.
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const frontmatter = parseFrontmatterMap(frontmatterLines);
|
|
59
|
+
const topLevel = normalizeVerdict(getCaseInsensitive(frontmatter, "verdict"));
|
|
60
|
+
if (topLevel) return topLevel;
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
13
64
|
/**
|
|
14
65
|
* Extract and normalize the `verdict` value from YAML frontmatter.
|
|
15
66
|
*
|
|
@@ -21,24 +72,14 @@ import type { UatType } from "./files.js";
|
|
|
21
72
|
*/
|
|
22
73
|
export function extractVerdict(content: string): string | undefined {
|
|
23
74
|
// Primary: YAML frontmatter verdict (canonical format)
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
const verdictMatch = fmMatch[1].match(/verdict:\s*([\w-]+)/i);
|
|
27
|
-
if (verdictMatch) {
|
|
28
|
-
let v = verdictMatch[1].toLowerCase();
|
|
29
|
-
if (v === "passed") v = "pass";
|
|
30
|
-
return v;
|
|
31
|
-
}
|
|
32
|
-
return undefined;
|
|
33
|
-
}
|
|
75
|
+
const [frontmatterLines] = splitFrontmatter(content);
|
|
76
|
+
if (frontmatterLines) return extractFrontmatterVerdict(content);
|
|
34
77
|
|
|
35
78
|
// Fallback: detect verdict in markdown body (LLM manual writes, #2960).
|
|
36
79
|
// Matches patterns like: **Verdict:** PASS, **Verdict:** ✅ PASS, **Verdict** needs-remediation
|
|
37
80
|
const bodyMatch = content.match(/\*\*Verdict:?\*\*\s*(?:✅\s*)?(\w[\w-]*)/i);
|
|
38
81
|
if (bodyMatch) {
|
|
39
|
-
|
|
40
|
-
if (v === "passed") v = "pass";
|
|
41
|
-
return v;
|
|
82
|
+
return normalizeVerdict(bodyMatch[1]);
|
|
42
83
|
}
|
|
43
84
|
|
|
44
85
|
return undefined;
|
|
@@ -295,6 +295,90 @@ function hasUnsafeShellSyntax(cmd: string): boolean {
|
|
|
295
295
|
return false;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
+
function splitLeadingShellWords(cmd: string): string[] {
|
|
299
|
+
const words: string[] = [];
|
|
300
|
+
let current = "";
|
|
301
|
+
let inSingle = false;
|
|
302
|
+
let inDouble = false;
|
|
303
|
+
let escaped = false;
|
|
304
|
+
|
|
305
|
+
for (let i = 0; i < cmd.length; i += 1) {
|
|
306
|
+
const ch = cmd[i];
|
|
307
|
+
|
|
308
|
+
if (escaped) {
|
|
309
|
+
current += ch;
|
|
310
|
+
escaped = false;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (ch === "\\" && !inSingle) {
|
|
315
|
+
escaped = true;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (ch === "'" && !inDouble) {
|
|
320
|
+
inSingle = !inSingle;
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (ch === "\"" && !inSingle) {
|
|
325
|
+
inDouble = !inDouble;
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (!inSingle && !inDouble) {
|
|
330
|
+
if (/\s/.test(ch)) {
|
|
331
|
+
if (current) {
|
|
332
|
+
words.push(current);
|
|
333
|
+
current = "";
|
|
334
|
+
}
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if ([";", "|", "&", "<", ">"].includes(ch)) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
current += ch;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (current) {
|
|
347
|
+
words.push(current);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return words;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function isCountFlag(token: string): boolean {
|
|
354
|
+
return (
|
|
355
|
+
token === "--count" ||
|
|
356
|
+
token.startsWith("--count=") ||
|
|
357
|
+
token === "--count-matches" ||
|
|
358
|
+
token.startsWith("--count-matches=") ||
|
|
359
|
+
/^-[A-Za-z]*c[A-Za-z]*$/.test(token)
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function countSearchWarning(command: string, exitCode: number): string | null {
|
|
364
|
+
if (exitCode !== 1) return null;
|
|
365
|
+
|
|
366
|
+
const trimmed = command.trim();
|
|
367
|
+
if (trimmed.startsWith("!")) return null;
|
|
368
|
+
|
|
369
|
+
const [tool, ...args] = splitLeadingShellWords(trimmed);
|
|
370
|
+
if (tool !== "grep" && tool !== "rg") return null;
|
|
371
|
+
if (!args.some(isCountFlag)) return null;
|
|
372
|
+
|
|
373
|
+
return `verification-gate: warning: '${tool} -c' returns exit 1 when count=0; for absence checks use '! ${tool} -q ...' instead.`;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function appendStderrWarning(stderr: string, warning: string | null): string {
|
|
377
|
+
if (!warning) return stderr;
|
|
378
|
+
const trimmed = stderr.trimEnd();
|
|
379
|
+
return trimmed ? `${trimmed}\n${warning}` : warning;
|
|
380
|
+
}
|
|
381
|
+
|
|
298
382
|
/**
|
|
299
383
|
* Known executable first-tokens that are safe to run.
|
|
300
384
|
* Lowercase commands, common build/test tools, and npm/yarn/pnpm invocations.
|
|
@@ -486,11 +570,13 @@ export function runVerificationGate(options: RunVerificationGateOptions): Verifi
|
|
|
486
570
|
stderr = truncate(result.stderr, MAX_OUTPUT_BYTES);
|
|
487
571
|
}
|
|
488
572
|
|
|
573
|
+
const warning = countSearchWarning(command, exitCode);
|
|
574
|
+
|
|
489
575
|
checks.push({
|
|
490
576
|
command,
|
|
491
577
|
exitCode,
|
|
492
578
|
stdout: truncate(result.stdout, MAX_OUTPUT_BYTES),
|
|
493
|
-
stderr,
|
|
579
|
+
stderr: truncate(appendStderrWarning(stderr, warning), MAX_OUTPUT_BYTES),
|
|
494
580
|
durationMs,
|
|
495
581
|
});
|
|
496
582
|
}
|
|
@@ -2,7 +2,7 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync, realpathSync } from "node:fs";
|
|
3
3
|
import { dirname, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
-
import {
|
|
5
|
+
import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
|
|
6
6
|
|
|
7
7
|
type WorkflowExecutorsModule = typeof import("./tools/workflow-tool-executors.js");
|
|
8
8
|
|
|
@@ -414,83 +414,11 @@ export function buildWorkflowMcpServers(
|
|
|
414
414
|
}
|
|
415
415
|
|
|
416
416
|
export function getRequiredWorkflowToolsForGuidedUnit(unitType: string): string[] {
|
|
417
|
-
|
|
418
|
-
case "discuss-project":
|
|
419
|
-
return ["ask_user_questions", "gsd_summary_save"];
|
|
420
|
-
case "discuss-requirements":
|
|
421
|
-
return ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"];
|
|
422
|
-
case "research-decision":
|
|
423
|
-
return ["ask_user_questions"];
|
|
424
|
-
case "discuss-milestone":
|
|
425
|
-
return [
|
|
426
|
-
"gsd_summary_save",
|
|
427
|
-
"gsd_requirement_save",
|
|
428
|
-
"gsd_requirement_update",
|
|
429
|
-
"gsd_plan_milestone",
|
|
430
|
-
"gsd_milestone_generate_id",
|
|
431
|
-
];
|
|
432
|
-
case "discuss-slice":
|
|
433
|
-
return ["gsd_summary_save"];
|
|
434
|
-
case "research-milestone":
|
|
435
|
-
case "research-slice":
|
|
436
|
-
return ["gsd_summary_save"];
|
|
437
|
-
case "plan-milestone":
|
|
438
|
-
return ["gsd_plan_milestone"];
|
|
439
|
-
case "plan-slice":
|
|
440
|
-
return ["gsd_plan_slice"];
|
|
441
|
-
case "execute-task":
|
|
442
|
-
return ["gsd_task_complete"];
|
|
443
|
-
case "complete-slice":
|
|
444
|
-
return ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice"];
|
|
445
|
-
default:
|
|
446
|
-
return [];
|
|
447
|
-
}
|
|
417
|
+
return getRequiredWorkflowToolsForUnit(unitType);
|
|
448
418
|
}
|
|
449
419
|
|
|
450
420
|
export function getRequiredWorkflowToolsForAutoUnit(unitType: string): string[] {
|
|
451
|
-
|
|
452
|
-
case "discuss-project":
|
|
453
|
-
return ["ask_user_questions", "gsd_summary_save"];
|
|
454
|
-
case "discuss-requirements":
|
|
455
|
-
return ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"];
|
|
456
|
-
case "research-decision":
|
|
457
|
-
return ["ask_user_questions"];
|
|
458
|
-
case "discuss-milestone":
|
|
459
|
-
return [
|
|
460
|
-
"gsd_summary_save",
|
|
461
|
-
"gsd_requirement_save",
|
|
462
|
-
"gsd_requirement_update",
|
|
463
|
-
"gsd_plan_milestone",
|
|
464
|
-
"gsd_milestone_generate_id",
|
|
465
|
-
];
|
|
466
|
-
case "research-milestone":
|
|
467
|
-
case "research-slice":
|
|
468
|
-
return ["gsd_summary_save"];
|
|
469
|
-
case "run-uat":
|
|
470
|
-
return [...RUN_UAT_WORKFLOW_TOOL_NAMES];
|
|
471
|
-
case "plan-milestone":
|
|
472
|
-
return ["gsd_plan_milestone"];
|
|
473
|
-
case "plan-slice":
|
|
474
|
-
return ["gsd_plan_slice"];
|
|
475
|
-
case "execute-task":
|
|
476
|
-
case "execute-task-simple":
|
|
477
|
-
case "reactive-execute":
|
|
478
|
-
return ["gsd_task_complete"];
|
|
479
|
-
case "complete-slice":
|
|
480
|
-
return ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice"];
|
|
481
|
-
case "replan-slice":
|
|
482
|
-
return ["gsd_replan_slice"];
|
|
483
|
-
case "reassess-roadmap":
|
|
484
|
-
return ["gsd_milestone_status", "gsd_reassess_roadmap"];
|
|
485
|
-
case "gate-evaluate":
|
|
486
|
-
return ["gsd_save_gate_result"];
|
|
487
|
-
case "validate-milestone":
|
|
488
|
-
return ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap"];
|
|
489
|
-
case "complete-milestone":
|
|
490
|
-
return ["gsd_milestone_status", "gsd_complete_milestone"];
|
|
491
|
-
default:
|
|
492
|
-
return [];
|
|
493
|
-
}
|
|
421
|
+
return getRequiredWorkflowToolsForUnit(unitType);
|
|
494
422
|
}
|
|
495
423
|
|
|
496
424
|
export function usesWorkflowMcpTransport(
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { basename, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
export const GSD_BROWSER_MCP_SERVER_NAME = "gsd-browser";
|
|
9
|
+
|
|
10
|
+
export interface GsdBrowserMcpLaunchConfig {
|
|
11
|
+
serverName: string;
|
|
12
|
+
command: string;
|
|
13
|
+
args: string[];
|
|
14
|
+
cwd: string;
|
|
15
|
+
env?: Record<string, string>;
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
sessionName: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface GsdBrowserMcpLaunchOptions {
|
|
21
|
+
sessionName?: string;
|
|
22
|
+
sessionSuffix?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function parseJsonEnv<T>(env: NodeJS.ProcessEnv, name: string): T | undefined {
|
|
26
|
+
const raw = env[name];
|
|
27
|
+
if (!raw) return undefined;
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(raw) as T;
|
|
30
|
+
} catch {
|
|
31
|
+
throw new Error(`Invalid JSON in ${name}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function sanitizeSessionSegment(value: string): string {
|
|
36
|
+
return value
|
|
37
|
+
.replace(/[^a-zA-Z0-9._-]+/g, "-")
|
|
38
|
+
.replace(/^-+|-+$/g, "")
|
|
39
|
+
.slice(0, 40);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function compareSemverLocal(a: string, b: string): number {
|
|
43
|
+
const left = a.split(".").map(Number);
|
|
44
|
+
const right = b.split(".").map(Number);
|
|
45
|
+
for (let index = 0; index < Math.max(left.length, right.length); index++) {
|
|
46
|
+
const leftValue = left[index] || 0;
|
|
47
|
+
const rightValue = right[index] || 0;
|
|
48
|
+
if (leftValue > rightValue) return 1;
|
|
49
|
+
if (leftValue < rightValue) return -1;
|
|
50
|
+
}
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function parseGsdBrowserVersion(output: string): string | null {
|
|
55
|
+
return output.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveBundledGsdBrowserPackageVersion(): string | null {
|
|
59
|
+
try {
|
|
60
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
61
|
+
const packageJsonPath = requireFromHere.resolve("@opengsd/gsd-browser/package.json");
|
|
62
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as { version?: unknown };
|
|
63
|
+
return typeof pkg.version === "string" ? parseGsdBrowserVersion(pkg.version) : null;
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function resolvePathGsdBrowserVersion(env: NodeJS.ProcessEnv): string | null {
|
|
70
|
+
const explicit = env.GSD_BROWSER_PATH_VERSION?.trim();
|
|
71
|
+
if (explicit) return parseGsdBrowserVersion(explicit);
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
return parseGsdBrowserVersion(execFileSync("gsd-browser", ["--version"], {
|
|
75
|
+
encoding: "utf-8",
|
|
76
|
+
env,
|
|
77
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
78
|
+
timeout: 2000,
|
|
79
|
+
}));
|
|
80
|
+
} catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function shouldPreferPathGsdBrowser(env: NodeJS.ProcessEnv): boolean {
|
|
86
|
+
const pathVersion = resolvePathGsdBrowserVersion(env);
|
|
87
|
+
if (!pathVersion) return false;
|
|
88
|
+
|
|
89
|
+
const bundledVersion = resolveBundledGsdBrowserPackageVersion();
|
|
90
|
+
return !bundledVersion || compareSemverLocal(pathVersion, bundledVersion) > 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function resolveBundledGsdBrowserCliPath(env: NodeJS.ProcessEnv = process.env): string | null {
|
|
94
|
+
const explicit = env.GSD_BROWSER_CLI_PATH?.trim() || env.GSD_BROWSER_BIN_PATH?.trim();
|
|
95
|
+
if (explicit) return explicit;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
99
|
+
const packageJsonPath = requireFromHere.resolve("@opengsd/gsd-browser/package.json");
|
|
100
|
+
const candidate = resolve(packageJsonPath, "..", "bin", "gsd-browser");
|
|
101
|
+
if (existsSync(candidate)) return candidate;
|
|
102
|
+
} catch {
|
|
103
|
+
// Fall through to path candidates for source/dist layouts.
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const candidates = [
|
|
107
|
+
resolve(fileURLToPath(new URL("../../../../node_modules/@opengsd/gsd-browser/bin/gsd-browser", import.meta.url))),
|
|
108
|
+
resolve(fileURLToPath(new URL("../../../../node_modules/.bin/gsd-browser", import.meta.url))),
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
for (const candidate of candidates) {
|
|
112
|
+
if (existsSync(candidate)) return candidate;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function buildGsdBrowserSessionName(projectRoot: string, suffix?: string): string {
|
|
119
|
+
const resolvedProjectRoot = resolve(projectRoot);
|
|
120
|
+
const base = sanitizeSessionSegment(basename(resolvedProjectRoot)) || "project";
|
|
121
|
+
const hash = createHash("sha1").update(resolvedProjectRoot).digest("hex").slice(0, 8);
|
|
122
|
+
const cleanSuffix = suffix ? sanitizeSessionSegment(suffix) : "";
|
|
123
|
+
return cleanSuffix ? `gsd-${base}-${hash}-${cleanSuffix}` : `gsd-${base}-${hash}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function resolveGsdBrowserMcpLaunchConfig(
|
|
127
|
+
projectRoot: string,
|
|
128
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
129
|
+
options: GsdBrowserMcpLaunchOptions = {},
|
|
130
|
+
): GsdBrowserMcpLaunchConfig {
|
|
131
|
+
const resolvedProjectRoot = resolve(projectRoot);
|
|
132
|
+
const serverName = env.GSD_BROWSER_MCP_NAME?.trim() || GSD_BROWSER_MCP_SERVER_NAME;
|
|
133
|
+
const explicitArgs = parseJsonEnv<unknown>(env, "GSD_BROWSER_MCP_ARGS");
|
|
134
|
+
const explicitEnv = parseJsonEnv<Record<string, string>>(env, "GSD_BROWSER_MCP_ENV");
|
|
135
|
+
const explicitCommand = env.GSD_BROWSER_MCP_COMMAND?.trim();
|
|
136
|
+
const explicitCliPath = env.GSD_BROWSER_CLI_PATH?.trim() || env.GSD_BROWSER_BIN_PATH?.trim();
|
|
137
|
+
const preferPathCli = !explicitCommand && !explicitCliPath && shouldPreferPathGsdBrowser(env);
|
|
138
|
+
const bundledCliPath = !explicitCommand && !explicitCliPath && !preferPathCli
|
|
139
|
+
? resolveBundledGsdBrowserCliPath(env)
|
|
140
|
+
: null;
|
|
141
|
+
const sessionName =
|
|
142
|
+
options.sessionName?.trim() || buildGsdBrowserSessionName(resolvedProjectRoot, options.sessionSuffix);
|
|
143
|
+
const command =
|
|
144
|
+
explicitCommand
|
|
145
|
+
|| explicitCliPath
|
|
146
|
+
|| (preferPathCli ? "gsd-browser" : undefined)
|
|
147
|
+
|| (bundledCliPath ? process.execPath : undefined)
|
|
148
|
+
|| "gsd-browser";
|
|
149
|
+
const args = Array.isArray(explicitArgs) && explicitArgs.length > 0
|
|
150
|
+
? explicitArgs.map(String)
|
|
151
|
+
: [
|
|
152
|
+
...(bundledCliPath ? [bundledCliPath] : []),
|
|
153
|
+
"mcp",
|
|
154
|
+
"--session",
|
|
155
|
+
sessionName,
|
|
156
|
+
"--identity-scope",
|
|
157
|
+
"project",
|
|
158
|
+
"--identity-project",
|
|
159
|
+
resolvedProjectRoot,
|
|
160
|
+
];
|
|
161
|
+
const cwd = env.GSD_BROWSER_MCP_CWD?.trim() || resolvedProjectRoot;
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
serverName,
|
|
165
|
+
command,
|
|
166
|
+
args,
|
|
167
|
+
cwd,
|
|
168
|
+
...(explicitEnv ? { env: explicitEnv } : {}),
|
|
169
|
+
projectRoot: resolvedProjectRoot,
|
|
170
|
+
sessionName,
|
|
171
|
+
};
|
|
172
|
+
}
|