@opengsd/gsd-pi 1.2.0-dev.5457a158 → 1.2.0-dev.822c9439
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/headless-events.js +7 -5
- package/dist/mcp-server.js +2 -1
- package/dist/resource-loader.d.ts +9 -5
- package/dist/resource-loader.js +114 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +3 -2
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
- package/dist/resources/extensions/gsd/auto/phases.js +49 -6
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
- package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
- package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
- package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
- package/dist/resources/extensions/gsd/auto-start.js +12 -12
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
- package/dist/resources/extensions/gsd/auto-verification.js +23 -30
- package/dist/resources/extensions/gsd/auto-worktree.js +14 -1
- package/dist/resources/extensions/gsd/auto.js +37 -1
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +172 -59
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
- package/dist/resources/extensions/gsd/commands/context.js +16 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
- package/dist/resources/extensions/gsd/consent-question.js +353 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
- package/dist/resources/extensions/gsd/db/queries.js +26 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
- package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +2 -1
- package/dist/resources/extensions/gsd/guidance.js +60 -0
- package/dist/resources/extensions/gsd/guided-flow.js +6 -3
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/preferences-models.js +2 -2
- package/dist/resources/extensions/gsd/projection-flush.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -1
- package/dist/resources/extensions/gsd/state.js +5 -0
- package/dist/resources/extensions/gsd/tool-contract.js +14 -3
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
- package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
- package/dist/resources/extensions/gsd/unit-registry.js +7 -20
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
- package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
- package/dist/resources/extensions/gsd/workflow-events.js +6 -18
- package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
- package/dist/resources/extensions/gsd/worktree.js +8 -1
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
- package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
- package/dist/resources/shared/package-manager-detection.js +1 -1
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/SKILL.md +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-check.d.ts +2 -0
- package/dist/update-check.js +24 -1
- package/dist/update-cmd.js +20 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- 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/react-loadable-manifest.json +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.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/api/update/route.js.nft.json +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 +11 -11
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -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 +7 -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 +8 -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-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +10 -5
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +4 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +99 -38
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +239 -153
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +256 -145
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +12 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +12 -3
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- 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 +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +3 -2
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
- package/src/resources/extensions/gsd/auto/phases.ts +65 -26
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
- package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
- package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
- package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
- package/src/resources/extensions/gsd/auto-start.ts +12 -14
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
- package/src/resources/extensions/gsd/auto-verification.ts +26 -28
- package/src/resources/extensions/gsd/auto-worktree.ts +14 -1
- package/src/resources/extensions/gsd/auto.ts +44 -1
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +211 -59
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
- package/src/resources/extensions/gsd/consent-question.ts +431 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
- package/src/resources/extensions/gsd/db/queries.ts +37 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +4 -3
- package/src/resources/extensions/gsd/guidance.ts +78 -0
- package/src/resources/extensions/gsd/guided-flow.ts +21 -26
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/preferences-models.ts +2 -1
- package/src/resources/extensions/gsd/projection-flush.ts +20 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/session-lock.ts +1 -1
- package/src/resources/extensions/gsd/state.ts +5 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +7 -11
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +20 -58
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
- package/src/resources/extensions/gsd/tool-contract.ts +38 -3
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
- package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
- package/src/resources/extensions/gsd/unit-registry.ts +7 -20
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
- package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
- package/src/resources/extensions/gsd/workflow-events.ts +12 -20
- package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
- package/src/resources/extensions/gsd/worktree.ts +7 -1
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
- package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
- package/src/resources/shared/package-manager-detection.ts +1 -1
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/SKILL.md +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- package/src/resources/skills/gsd-browser/SKILL.md +0 -41
- /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_ssgManifest.js +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
|
-
// File Purpose: Web-app detection and
|
|
2
|
+
// File Purpose: Web-app detection and browser-UAT guidance for planning and slice closeout.
|
|
3
3
|
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
|
|
7
|
+
import { resolveAmbientBrowserEngineResolution, type BrowserEngineResolution } from "../browser-tools/engine/selection.js";
|
|
7
8
|
import { detectWebApp } from "../browser-tools/web-app-detect.js";
|
|
9
|
+
import { UAT_MODE_POLICIES, type UatType } from "./uat-policy.js";
|
|
8
10
|
|
|
9
11
|
export { detectWebApp };
|
|
10
12
|
|
|
@@ -47,24 +49,61 @@ export function findPlaywrightTestScript(projectRoot: string): string | null {
|
|
|
47
49
|
return null;
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
function describeBrowserToolBacking(engineResolution: BrowserEngineResolution): string {
|
|
53
|
+
switch (engineResolution.engine) {
|
|
54
|
+
case "gsd-browser":
|
|
55
|
+
return "This project looks browser-facing. GSD exposes `browser_*` tools backed by the managed gsd-browser engine for run-uat.";
|
|
56
|
+
case "legacy":
|
|
57
|
+
return "This project looks browser-facing. GSD exposes Playwright-backed `browser_*` tools for run-uat.";
|
|
58
|
+
case "off":
|
|
59
|
+
return "This project looks browser-facing, but Pi browser tools are disabled (GSD_BROWSER_ENGINE=off) — prefer `runtime-executable` UAT with automated browser test commands.";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// One bullet per recommended UAT mode; `mode` keys into UAT_MODE_POLICIES so
|
|
64
|
+
// modes that require browser tools drop out of the guidance when the resolved
|
|
65
|
+
// engine provides none (mixed/live-runtime share one bullet and one policy bit).
|
|
66
|
+
const UAT_MODE_GUIDANCE: ReadonlyArray<{ mode: UatType; bullet: string }> = [
|
|
67
|
+
{
|
|
68
|
+
mode: "browser-executable",
|
|
69
|
+
bullet: "- `browser-executable` — navigate to `http://localhost:…`, click, screenshot, assert via `browser_*` tools during run-uat",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
mode: "runtime-executable",
|
|
73
|
+
bullet: "- `runtime-executable` — run an automated browser test command via `gsd_uat_exec` (for example `npx playwright test`)",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
mode: "mixed",
|
|
77
|
+
bullet: "- `mixed` / `live-runtime` — combine runtime startup checks with interactive browser verification",
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
|
|
50
81
|
/**
|
|
51
82
|
* Markdown block injected into plan/complete-slice prompts when the project
|
|
52
|
-
* looks browser-facing. Returns null for CLI/library-only repos.
|
|
83
|
+
* looks browser-facing. Returns null for CLI/library-only repos. Guidance is
|
|
84
|
+
* composed from the resolved Browser Automation Engine so prompts never claim
|
|
85
|
+
* an engine the runtime is not using; `engineResolution` is injectable for
|
|
86
|
+
* tests and defaults to the ambient resolution.
|
|
53
87
|
*/
|
|
54
|
-
export function buildWebAppUatGuidanceBlock(
|
|
88
|
+
export function buildWebAppUatGuidanceBlock(
|
|
89
|
+
projectRoot: string,
|
|
90
|
+
engineResolution?: BrowserEngineResolution,
|
|
91
|
+
): string | null {
|
|
55
92
|
if (!detectWebApp(projectRoot)) return null;
|
|
56
93
|
|
|
94
|
+
const resolvedEngine = engineResolution ?? resolveAmbientBrowserEngineResolution(projectRoot);
|
|
95
|
+
const browserToolsAvailable = resolvedEngine.engine !== "off";
|
|
57
96
|
const playwrightScript = findPlaywrightTestScript(projectRoot);
|
|
58
97
|
const hasPlaywright = hasPlaywrightTestDependency(projectRoot) || playwrightScript !== null;
|
|
59
98
|
const lines = [
|
|
60
99
|
"### Web App UAT (detected)",
|
|
61
100
|
"",
|
|
62
|
-
|
|
101
|
+
describeBrowserToolBacking(resolvedEngine),
|
|
63
102
|
"",
|
|
64
103
|
"**UAT modes (pick one per slice — do not use `artifact-driven` for browser steps):**",
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
104
|
+
...UAT_MODE_GUIDANCE
|
|
105
|
+
.filter(({ mode }) => browserToolsAvailable || !UAT_MODE_POLICIES[mode].browserTools)
|
|
106
|
+
.map(({ bullet }) => bullet),
|
|
68
107
|
"",
|
|
69
108
|
"**Planning / closeout rules:**",
|
|
70
109
|
"- Preconditions must name the dev-server command and URL (for example `npm run dev` → `http://localhost:3000`)",
|
|
@@ -93,8 +132,12 @@ export function buildWebAppUatGuidanceBlock(projectRoot: string): string | null
|
|
|
93
132
|
"**Playwright scaffolding (first UI slice):** no `playwright` / `@playwright/test` dependency yet.",
|
|
94
133
|
"- Add a planning task that installs Playwright, adds `playwright.config.ts`, and creates a minimal smoke spec (for example `e2e/smoke.spec.ts`)",
|
|
95
134
|
"- Task `verify` should run `npx playwright test` (or the focused spec) with a safe, simple command",
|
|
96
|
-
"- Until specs exist, use `browser-executable` UAT with localhost preconditions and interactive `browser_*` checks at slice closeout",
|
|
97
135
|
);
|
|
136
|
+
if (browserToolsAvailable) {
|
|
137
|
+
lines.push(
|
|
138
|
+
"- Until specs exist, use `browser-executable` UAT with localhost preconditions and interactive `browser_*` checks at slice closeout",
|
|
139
|
+
);
|
|
140
|
+
}
|
|
98
141
|
}
|
|
99
142
|
|
|
100
143
|
return lines.join("\n");
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
|
|
5
|
+
import { atomicWriteSync } from "./atomic-write.js";
|
|
6
|
+
import { resolveGsdPathContract } from "./paths.js";
|
|
7
|
+
import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
|
|
8
|
+
import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
|
|
9
|
+
import { normalizeWorkflowEventCommand } from "./workflow-event-vocabulary.js";
|
|
10
|
+
import type { WorkflowEvent } from "./workflow-events.js";
|
|
11
|
+
|
|
12
|
+
export const WORKFLOW_EVENT_LOG_FILENAME = "event-log.jsonl";
|
|
13
|
+
|
|
14
|
+
export interface WorkflowEventLedgerLocation {
|
|
15
|
+
projectRoot: string;
|
|
16
|
+
workRoot: string;
|
|
17
|
+
projectGsd: string;
|
|
18
|
+
worktreeGsd: string | null;
|
|
19
|
+
projectLogPath: string;
|
|
20
|
+
worktreeLogPath: string | null;
|
|
21
|
+
isWorktree: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type WorkflowEventInput = Omit<WorkflowEvent, "hash" | "session_id"> & {
|
|
25
|
+
actor_name?: string;
|
|
26
|
+
trigger_reason?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function resolveWorkflowEventLedgerLocation(
|
|
30
|
+
basePath: string,
|
|
31
|
+
originalProjectRoot?: string | null,
|
|
32
|
+
): WorkflowEventLedgerLocation {
|
|
33
|
+
const contract = resolveGsdPathContract(basePath, originalProjectRoot);
|
|
34
|
+
return {
|
|
35
|
+
projectRoot: contract.projectRoot,
|
|
36
|
+
workRoot: contract.workRoot,
|
|
37
|
+
projectGsd: contract.projectGsd,
|
|
38
|
+
worktreeGsd: contract.worktreeGsd,
|
|
39
|
+
projectLogPath: join(contract.projectGsd, WORKFLOW_EVENT_LOG_FILENAME),
|
|
40
|
+
worktreeLogPath: contract.worktreeGsd
|
|
41
|
+
? join(contract.worktreeGsd, WORKFLOW_EVENT_LOG_FILENAME)
|
|
42
|
+
: null,
|
|
43
|
+
isWorktree: contract.isWorktree,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function workflowEventLogPath(basePath: string): string {
|
|
48
|
+
return resolveWorkflowEventLedgerLocation(basePath).projectLogPath;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function workflowEventArchivePath(basePath: string, milestoneId: string): string {
|
|
52
|
+
const location = resolveWorkflowEventLedgerLocation(basePath);
|
|
53
|
+
return join(location.projectGsd, `event-log-${milestoneId}.jsonl.archived`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function readWorktreeEventLogPath(worktreeBasePath: string): string {
|
|
57
|
+
const location = resolveWorkflowEventLedgerLocation(worktreeBasePath);
|
|
58
|
+
return location.worktreeLogPath ?? location.projectLogPath;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function buildWorkflowEvent(event: WorkflowEventInput, sessionId: string): WorkflowEvent {
|
|
62
|
+
const hash = createHash("sha256")
|
|
63
|
+
.update(JSON.stringify({ cmd: event.cmd, params: event.params }))
|
|
64
|
+
.digest("hex")
|
|
65
|
+
.slice(0, 16);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
v: 2,
|
|
69
|
+
...event,
|
|
70
|
+
hash,
|
|
71
|
+
session_id: sessionId,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function appendWorkflowEvent(
|
|
76
|
+
basePath: string,
|
|
77
|
+
event: WorkflowEventInput,
|
|
78
|
+
sessionId: string,
|
|
79
|
+
): WorkflowEvent {
|
|
80
|
+
const fullEvent = buildWorkflowEvent(event, sessionId);
|
|
81
|
+
const location = resolveWorkflowEventLedgerLocation(basePath);
|
|
82
|
+
|
|
83
|
+
mkdirSync(location.projectGsd, { recursive: true });
|
|
84
|
+
appendFileSync(location.projectLogPath, `${JSON.stringify(fullEvent)}\n`, "utf-8");
|
|
85
|
+
emitWorkflowEventAudit(location.projectRoot, fullEvent);
|
|
86
|
+
return fullEvent;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function writeWorkflowEventLog(basePath: string, events: readonly WorkflowEvent[]): void {
|
|
90
|
+
const location = resolveWorkflowEventLedgerLocation(basePath);
|
|
91
|
+
mkdirSync(location.projectGsd, { recursive: true });
|
|
92
|
+
const content = events.map((event) => JSON.stringify(event)).join("\n") + (events.length > 0 ? "\n" : "");
|
|
93
|
+
atomicWriteSync(location.projectLogPath, content);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function writeWorktreeEventLog(
|
|
97
|
+
worktreeBasePath: string,
|
|
98
|
+
events: readonly WorkflowEvent[],
|
|
99
|
+
): void {
|
|
100
|
+
const location = resolveWorkflowEventLedgerLocation(worktreeBasePath);
|
|
101
|
+
const logPath = location.worktreeLogPath ?? location.projectLogPath;
|
|
102
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
103
|
+
const content = events.map((event) => JSON.stringify(event)).join("\n") + (events.length > 0 ? "\n" : "");
|
|
104
|
+
atomicWriteSync(logPath, content);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function emitWorkflowEventAudit(basePath: string, event: WorkflowEvent): void {
|
|
108
|
+
if (!isUnifiedAuditEnabled()) return;
|
|
109
|
+
try {
|
|
110
|
+
const normalized = normalizeWorkflowEventCommand(event.cmd) ?? "unknown";
|
|
111
|
+
emitUokAuditEvent(
|
|
112
|
+
basePath,
|
|
113
|
+
buildAuditEnvelope({
|
|
114
|
+
traceId: event.session_id,
|
|
115
|
+
category: "orchestration",
|
|
116
|
+
type: `workflow-event-${normalized}`,
|
|
117
|
+
payload: {
|
|
118
|
+
cmd: event.cmd,
|
|
119
|
+
params: event.params,
|
|
120
|
+
actor: event.actor,
|
|
121
|
+
actorName: event.actor_name,
|
|
122
|
+
triggerReason: event.trigger_reason,
|
|
123
|
+
eventTs: event.ts,
|
|
124
|
+
hash: event.hash,
|
|
125
|
+
},
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
} catch {
|
|
129
|
+
// Best-effort: audit projection must never block the workflow event ledger.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { WorkflowEvent } from "./workflow-events.js";
|
|
2
|
+
|
|
3
|
+
export interface WorkflowEventEntityKey {
|
|
4
|
+
type: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function normalizeWorkflowEventCommand(cmd: unknown): string | null {
|
|
9
|
+
return typeof cmd === "string" ? cmd.replace(/-/g, "_") : null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Workflow progress events are keyed by the domain entity they mutate.
|
|
14
|
+
* Keep command aliases and conflict identity in this module so replay,
|
|
15
|
+
* conflict detection, and tests do not each grow their own vocabulary.
|
|
16
|
+
*/
|
|
17
|
+
export function workflowEventEntityKey(event: WorkflowEvent): WorkflowEventEntityKey | null {
|
|
18
|
+
const p = event.params;
|
|
19
|
+
const cmd = normalizeWorkflowEventCommand(event.cmd);
|
|
20
|
+
if (!cmd) return null;
|
|
21
|
+
|
|
22
|
+
switch (cmd) {
|
|
23
|
+
case "complete_task":
|
|
24
|
+
case "start_task":
|
|
25
|
+
case "skip_task":
|
|
26
|
+
case "report_blocker":
|
|
27
|
+
case "record_verification":
|
|
28
|
+
case "plan_task":
|
|
29
|
+
return typeof p["taskId"] === "string"
|
|
30
|
+
? { type: "task", id: p["taskId"] }
|
|
31
|
+
: null;
|
|
32
|
+
|
|
33
|
+
case "complete_slice":
|
|
34
|
+
case "replan_slice":
|
|
35
|
+
return typeof p["sliceId"] === "string"
|
|
36
|
+
? { type: "slice", id: p["sliceId"] }
|
|
37
|
+
: null;
|
|
38
|
+
|
|
39
|
+
case "plan_slice":
|
|
40
|
+
return typeof p["sliceId"] === "string"
|
|
41
|
+
? { type: "slice_plan", id: p["sliceId"] }
|
|
42
|
+
: null;
|
|
43
|
+
|
|
44
|
+
case "complete_milestone":
|
|
45
|
+
case "plan_milestone":
|
|
46
|
+
return typeof p["milestoneId"] === "string"
|
|
47
|
+
? { type: "milestone", id: p["milestoneId"] }
|
|
48
|
+
: null;
|
|
49
|
+
|
|
50
|
+
case "save_decision":
|
|
51
|
+
if (typeof p["scope"] === "string" && typeof p["decision"] === "string") {
|
|
52
|
+
return { type: "decision", id: `${p["scope"]}:${p["decision"]}` };
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
|
|
56
|
+
default:
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { join } from "node:path";
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
4
3
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
5
4
|
import { withFileLockSync } from "./file-lock.js";
|
|
5
|
+
import {
|
|
6
|
+
appendWorkflowEvent,
|
|
7
|
+
workflowEventArchivePath,
|
|
8
|
+
workflowEventLogPath,
|
|
9
|
+
type WorkflowEventInput,
|
|
10
|
+
} from "./workflow-event-ledger.js";
|
|
6
11
|
import { logWarning } from "./workflow-logger.js";
|
|
7
12
|
|
|
8
13
|
// ─── Session ID ───────────────────────────────────────────────────────────
|
|
@@ -40,22 +45,9 @@ export interface WorkflowEvent {
|
|
|
40
45
|
*/
|
|
41
46
|
export function appendEvent(
|
|
42
47
|
basePath: string,
|
|
43
|
-
event:
|
|
48
|
+
event: WorkflowEventInput,
|
|
44
49
|
): void {
|
|
45
|
-
|
|
46
|
-
.update(JSON.stringify({ cmd: event.cmd, params: event.params }))
|
|
47
|
-
.digest("hex")
|
|
48
|
-
.slice(0, 16);
|
|
49
|
-
|
|
50
|
-
const fullEvent: WorkflowEvent = {
|
|
51
|
-
v: 2,
|
|
52
|
-
...event,
|
|
53
|
-
hash,
|
|
54
|
-
session_id: ENGINE_SESSION_ID,
|
|
55
|
-
};
|
|
56
|
-
const dir = join(basePath, ".gsd");
|
|
57
|
-
mkdirSync(dir, { recursive: true });
|
|
58
|
-
appendFileSync(join(dir, "event-log.jsonl"), JSON.stringify(fullEvent) + "\n", "utf-8");
|
|
50
|
+
appendWorkflowEvent(basePath, event, ENGINE_SESSION_ID);
|
|
59
51
|
}
|
|
60
52
|
|
|
61
53
|
// ─── readEvents ──────────────────────────────────────────────────────────
|
|
@@ -125,8 +117,8 @@ export function compactMilestoneEvents(
|
|
|
125
117
|
basePath: string,
|
|
126
118
|
milestoneId: string,
|
|
127
119
|
): { archived: number } {
|
|
128
|
-
const logPath =
|
|
129
|
-
const archivePath =
|
|
120
|
+
const logPath = workflowEventLogPath(basePath);
|
|
121
|
+
const archivePath = workflowEventArchivePath(basePath, milestoneId);
|
|
130
122
|
|
|
131
123
|
return withFileLockSync(logPath, () => {
|
|
132
124
|
const allEvents = readEvents(logPath);
|
|
@@ -3,6 +3,16 @@ import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
|
3
3
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
4
4
|
import { readEvents, findForkPoint, getSessionId } from "./workflow-events.js";
|
|
5
5
|
import type { WorkflowEvent } from "./workflow-events.js";
|
|
6
|
+
import {
|
|
7
|
+
normalizeWorkflowEventCommand,
|
|
8
|
+
workflowEventEntityKey,
|
|
9
|
+
} from "./workflow-event-vocabulary.js";
|
|
10
|
+
import {
|
|
11
|
+
readWorktreeEventLogPath,
|
|
12
|
+
workflowEventLogPath,
|
|
13
|
+
writeWorkflowEventLog,
|
|
14
|
+
writeWorktreeEventLog,
|
|
15
|
+
} from "./workflow-event-ledger.js";
|
|
6
16
|
import {
|
|
7
17
|
transaction,
|
|
8
18
|
updateTaskStatus,
|
|
@@ -82,14 +92,11 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
82
92
|
transaction(() => {
|
|
83
93
|
for (const event of events) {
|
|
84
94
|
const p = event.params;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// Type guard: malformed event lines with non-string cmd are skipped.
|
|
88
|
-
if (typeof event.cmd !== "string") {
|
|
95
|
+
const cmd = normalizeWorkflowEventCommand(event.cmd);
|
|
96
|
+
if (!cmd) {
|
|
89
97
|
logWarning("reconcile", `Event with non-string cmd skipped: ${JSON.stringify(event.cmd)}`);
|
|
90
98
|
continue;
|
|
91
99
|
}
|
|
92
|
-
const cmd = event.cmd.replace(/-/g, "_");
|
|
93
100
|
switch (cmd) {
|
|
94
101
|
case "complete_task": {
|
|
95
102
|
const milestoneId = p["milestoneId"] as string;
|
|
@@ -235,48 +242,7 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
235
242
|
export function extractEntityKey(
|
|
236
243
|
event: WorkflowEvent,
|
|
237
244
|
): { type: string; id: string } | null {
|
|
238
|
-
|
|
239
|
-
// Normalize cmd format: accept both hyphens and underscores
|
|
240
|
-
if (typeof event.cmd !== "string") return null;
|
|
241
|
-
const cmd = event.cmd.replace(/-/g, "_");
|
|
242
|
-
|
|
243
|
-
switch (cmd) {
|
|
244
|
-
case "complete_task":
|
|
245
|
-
case "start_task":
|
|
246
|
-
case "skip_task":
|
|
247
|
-
case "report_blocker":
|
|
248
|
-
case "record_verification":
|
|
249
|
-
case "plan_task":
|
|
250
|
-
return typeof p["taskId"] === "string"
|
|
251
|
-
? { type: "task", id: p["taskId"] }
|
|
252
|
-
: null;
|
|
253
|
-
|
|
254
|
-
case "complete_slice":
|
|
255
|
-
case "replan_slice":
|
|
256
|
-
return typeof p["sliceId"] === "string"
|
|
257
|
-
? { type: "slice", id: p["sliceId"] }
|
|
258
|
-
: null;
|
|
259
|
-
|
|
260
|
-
case "plan_slice":
|
|
261
|
-
return typeof p["sliceId"] === "string"
|
|
262
|
-
? { type: "slice_plan", id: p["sliceId"] }
|
|
263
|
-
: null;
|
|
264
|
-
|
|
265
|
-
case "complete_milestone":
|
|
266
|
-
case "plan_milestone":
|
|
267
|
-
return typeof p["milestoneId"] === "string"
|
|
268
|
-
? { type: "milestone", id: p["milestoneId"] }
|
|
269
|
-
: null;
|
|
270
|
-
|
|
271
|
-
case "save_decision":
|
|
272
|
-
if (typeof p["scope"] === "string" && typeof p["decision"] === "string") {
|
|
273
|
-
return { type: "decision", id: `${p["scope"]}:${p["decision"]}` };
|
|
274
|
-
}
|
|
275
|
-
return null;
|
|
276
|
-
|
|
277
|
-
default:
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
245
|
+
return workflowEventEntityKey(event);
|
|
280
246
|
}
|
|
281
247
|
|
|
282
248
|
// ─── detectConflicts ──────────────────────────────────────────────────────────
|
|
@@ -360,13 +326,6 @@ function rewriteDivergedEventsForEntity(
|
|
|
360
326
|
return rewritten;
|
|
361
327
|
}
|
|
362
328
|
|
|
363
|
-
function writeEventLog(basePath: string, events: WorkflowEvent[]): void {
|
|
364
|
-
const dir = join(basePath, ".gsd");
|
|
365
|
-
mkdirSync(dir, { recursive: true });
|
|
366
|
-
const content = events.map((e) => JSON.stringify(e)).join("\n") + (events.length > 0 ? "\n" : "");
|
|
367
|
-
atomicWriteSync(join(dir, "event-log.jsonl"), content);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
329
|
// ─── writeConflictsFile ───────────────────────────────────────────────────────
|
|
371
330
|
|
|
372
331
|
/**
|
|
@@ -450,12 +409,18 @@ function _reconcileWorktreeLogsInner(
|
|
|
450
409
|
worktreeBasePath: string,
|
|
451
410
|
): ReconcileResult {
|
|
452
411
|
// Step 1: Read both logs
|
|
453
|
-
const mainLogPath =
|
|
454
|
-
const wtLogPath =
|
|
412
|
+
const mainLogPath = workflowEventLogPath(mainBasePath);
|
|
413
|
+
const wtLogPath = readWorktreeEventLogPath(worktreeBasePath);
|
|
455
414
|
|
|
456
415
|
const mainEvents = readEvents(mainLogPath);
|
|
457
416
|
const wtEvents = readEvents(wtLogPath);
|
|
458
417
|
|
|
418
|
+
// Canonical worktree appends are already durable in the project ledger.
|
|
419
|
+
// Empty/missing worktree shards are legacy-only absence, not divergence.
|
|
420
|
+
if (wtEvents.length === 0) {
|
|
421
|
+
return { autoMerged: 0, conflicts: [] };
|
|
422
|
+
}
|
|
423
|
+
|
|
459
424
|
// Step 2: Find fork point
|
|
460
425
|
const forkPoint = findForkPoint(mainEvents, wtEvents);
|
|
461
426
|
|
|
@@ -495,9 +460,7 @@ function _reconcileWorktreeLogsInner(
|
|
|
495
460
|
|
|
496
461
|
const baseEvents = mainEvents.slice(0, forkPoint + 1);
|
|
497
462
|
const mergedLog = baseEvents.concat(merged);
|
|
498
|
-
|
|
499
|
-
mkdirSync(join(mainBasePath, ".gsd"), { recursive: true });
|
|
500
|
-
atomicWriteSync(join(mainBasePath, ".gsd", "event-log.jsonl"), logContent);
|
|
463
|
+
writeWorkflowEventLog(mainBasePath, mergedLog);
|
|
501
464
|
|
|
502
465
|
// Step 8: Replay into DB (wrapped in a transaction by replayEvents)
|
|
503
466
|
openWorkflowDatabasePath(resolveGsdPathContract(mainBasePath).projectDb);
|
|
@@ -636,8 +599,8 @@ export function resolveConflict(
|
|
|
636
599
|
const conflict = conflicts[idx]!;
|
|
637
600
|
const eventsToReplay = pick === "main" ? conflict.mainSideEvents : conflict.worktreeSideEvents;
|
|
638
601
|
|
|
639
|
-
const mainLogPath =
|
|
640
|
-
const wtLogPath =
|
|
602
|
+
const mainLogPath = workflowEventLogPath(basePath);
|
|
603
|
+
const wtLogPath = readWorktreeEventLogPath(worktreeBasePath);
|
|
641
604
|
const mainEvents = readEvents(mainLogPath);
|
|
642
605
|
const wtEvents = readEvents(wtLogPath);
|
|
643
606
|
const forkPoint = findForkPoint(mainEvents, wtEvents);
|
|
@@ -652,7 +615,11 @@ export function resolveConflict(
|
|
|
652
615
|
|
|
653
616
|
const targetBasePath = pick === "main" ? worktreeBasePath : basePath;
|
|
654
617
|
const targetBaseEvents = pick === "main" ? wtBaseEvents : mainBaseEvents;
|
|
655
|
-
|
|
618
|
+
if (pick === "main") {
|
|
619
|
+
writeWorktreeEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
|
|
620
|
+
} else {
|
|
621
|
+
writeWorkflowEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
|
|
622
|
+
}
|
|
656
623
|
|
|
657
624
|
// Replay resolved events through the DB (updates DB state)
|
|
658
625
|
openWorkflowDatabasePath(resolveGsdPathContract(basePath).projectDb);
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
// callers — production wiring previously injected them via deps; the seam
|
|
48
48
|
// added type churn without enabling test variation.
|
|
49
49
|
import { loadEffectiveGSDPreferences, getIsolationMode } from "./preferences.js";
|
|
50
|
+
import { isolationDegradedFallbackGuidance, worktreeCreationFailedGuidance } from "./guidance.js";
|
|
50
51
|
import { invalidateAllCaches } from "./cache.js";
|
|
51
52
|
import { resolveMilestoneFile } from "./paths.js";
|
|
52
53
|
import { getMilestone, insertMilestone, isDbAvailable, updateMilestoneStatus } from "./gsd-db.js";
|
|
@@ -693,10 +694,7 @@ export function _enterMilestoneCore(
|
|
|
693
694
|
s.basePath = basePath;
|
|
694
695
|
rebuildGitService(s, deps);
|
|
695
696
|
invalidateAllCaches();
|
|
696
|
-
ctx.notify(
|
|
697
|
-
`Worktree isolation is degraded. Fell back to branch milestone/${milestoneId}.`,
|
|
698
|
-
"warning",
|
|
699
|
-
);
|
|
697
|
+
ctx.notify(isolationDegradedFallbackGuidance(milestoneId), "warning");
|
|
700
698
|
return { ok: true, mode: "branch", path: basePath };
|
|
701
699
|
} catch (err) {
|
|
702
700
|
debugLog("WorktreeLifecycle", {
|
|
@@ -883,10 +881,7 @@ export function _enterMilestoneCore(
|
|
|
883
881
|
eventType: "worktree-create-failed",
|
|
884
882
|
data: { milestoneId, error: msg, fallback: "project-root" },
|
|
885
883
|
});
|
|
886
|
-
ctx.notify(
|
|
887
|
-
`Auto-worktree creation for ${milestoneId} failed: ${msg}. Continuing in project root.`,
|
|
888
|
-
"warning",
|
|
889
|
-
);
|
|
884
|
+
ctx.notify(worktreeCreationFailedGuidance(milestoneId, msg), "warning");
|
|
890
885
|
// Degrade isolation for the rest of this session so mergeAndExit
|
|
891
886
|
// doesn't try to merge a nonexistent worktree branch (#2483)
|
|
892
887
|
s.isolationDegraded = true;
|
|
@@ -656,7 +656,12 @@ export function removeWorktree(
|
|
|
656
656
|
const resolvedPathSafe = isInsideWorktreesDir(basePath, resolvedWtPath);
|
|
657
657
|
|
|
658
658
|
// If we're inside the worktree, move out first — git can't remove an in-use directory
|
|
659
|
-
|
|
659
|
+
let cwd: string;
|
|
660
|
+
try {
|
|
661
|
+
cwd = process.cwd();
|
|
662
|
+
} catch {
|
|
663
|
+
cwd = basePath;
|
|
664
|
+
}
|
|
660
665
|
const resolvedCwd = existsSync(cwd) ? realpathSync(cwd) : cwd;
|
|
661
666
|
if (resolvedCwd === resolvedWtPath || resolvedCwd.startsWith(resolvedWtPath + sep)) {
|
|
662
667
|
process.chdir(basePath);
|
|
@@ -224,7 +224,13 @@ export function resolveGitHeadPath(dir: string): string | null {
|
|
|
224
224
|
*/
|
|
225
225
|
export function nudgeGitBranchCache(previousCwd: string): void {
|
|
226
226
|
const now = new Date();
|
|
227
|
-
|
|
227
|
+
let currentCwd: string | null = null;
|
|
228
|
+
try {
|
|
229
|
+
currentCwd = process.cwd();
|
|
230
|
+
} catch {
|
|
231
|
+
currentCwd = null;
|
|
232
|
+
}
|
|
233
|
+
for (const dir of [previousCwd, currentCwd].filter((dir): dir is string => Boolean(dir))) {
|
|
228
234
|
try {
|
|
229
235
|
const headPath = resolveGitHeadPath(dir);
|
|
230
236
|
if (headPath) utimesSync(headPath, now, now);
|
|
@@ -243,9 +243,11 @@ export function registerNativeSearchHooks(pi: NativeSearchPI): { getIsAnthropic:
|
|
|
243
243
|
// Anthropic-only tool never leaks into OpenAI Responses requests.
|
|
244
244
|
isAnthropic = isAnthropicProvider && payloadLooksAnthropic !== false;
|
|
245
245
|
} else {
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
|
|
246
|
+
// No authoritative provider info available (no event.model, no model_select).
|
|
247
|
+
// Do NOT inject native web_search — guessing on model name alone causes 400
|
|
248
|
+
// "unsupported_value" errors when the actual provider (copilot, openrouter,
|
|
249
|
+
// proxy, etc.) doesn't expose the server-side search tool (#648).
|
|
250
|
+
isAnthropic = false;
|
|
249
251
|
}
|
|
250
252
|
if (!isAnthropic) return;
|
|
251
253
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Browser Automation Contract — the single source for the canonical
|
|
3
|
+
// Pi-facing browser tool vocabulary. Engine adapters (legacy Playwright, managed
|
|
4
|
+
// gsd-browser), UAT policy, dispatch preflight, and evidence detection all derive
|
|
5
|
+
// their browser tool knowledge from this module instead of re-listing names.
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Canonical `browser_*` tool names of the Browser Automation Contract.
|
|
9
|
+
*
|
|
10
|
+
* These are the product-level names Units see regardless of which Browser
|
|
11
|
+
* Automation Engine serves them (ADR-024). Adding a capability here is the
|
|
12
|
+
* one-line vocabulary change; the engine adapters and presentation surfaces
|
|
13
|
+
* are typed against this list, so missing coverage fails typecheck.
|
|
14
|
+
*/
|
|
15
|
+
export const BROWSER_CONTRACT_TOOL_NAMES = [
|
|
16
|
+
"browser_navigate",
|
|
17
|
+
"browser_click",
|
|
18
|
+
"browser_type",
|
|
19
|
+
"browser_fill_form",
|
|
20
|
+
"browser_click_ref",
|
|
21
|
+
"browser_fill_ref",
|
|
22
|
+
"browser_wait_for",
|
|
23
|
+
"browser_assert",
|
|
24
|
+
"browser_verify",
|
|
25
|
+
"browser_screenshot",
|
|
26
|
+
"browser_snapshot_refs",
|
|
27
|
+
"browser_find",
|
|
28
|
+
"browser_get_console_logs",
|
|
29
|
+
"browser_get_network_logs",
|
|
30
|
+
"browser_evaluate",
|
|
31
|
+
"browser_reload",
|
|
32
|
+
"browser_batch",
|
|
33
|
+
"browser_act",
|
|
34
|
+
] as const;
|
|
35
|
+
|
|
36
|
+
export type BrowserContractToolName = (typeof BROWSER_CONTRACT_TOOL_NAMES)[number];
|
|
37
|
+
|
|
38
|
+
const BROWSER_CONTRACT_TOOL_NAME_SET: ReadonlySet<string> = new Set(BROWSER_CONTRACT_TOOL_NAMES);
|
|
39
|
+
|
|
40
|
+
export function isBrowserContractToolName(name: string): name is BrowserContractToolName {
|
|
41
|
+
return BROWSER_CONTRACT_TOOL_NAME_SET.has(name);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Whether a canonical (non-MCP-prefixed) tool name belongs to the browser tool
|
|
46
|
+
* family. Broader than the contract list on purpose: an External MCP Client or
|
|
47
|
+
* host integration may supply additional `browser_*` tools that still satisfy
|
|
48
|
+
* browser-backed UAT.
|
|
49
|
+
*/
|
|
50
|
+
export function hasBrowserContractPrefix(canonicalToolName: string): boolean {
|
|
51
|
+
return canonicalToolName.startsWith("browser_");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Contract tool names whose appearance in prose marks browser-backed UAT
|
|
56
|
+
* activity (requirement or evidence language). Consumed by the
|
|
57
|
+
* browser-evidence regexes so textual detection stays derived from the
|
|
58
|
+
* contract vocabulary.
|
|
59
|
+
*/
|
|
60
|
+
export const BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES = [
|
|
61
|
+
"browser_assert",
|
|
62
|
+
"browser_batch",
|
|
63
|
+
"browser_find",
|
|
64
|
+
"browser_verify",
|
|
65
|
+
"browser_snapshot_refs",
|
|
66
|
+
] as const satisfies readonly BrowserContractToolName[];
|