@opengsd/gsd-pi 1.2.0-dev.b1abb545 → 1.2.0-dev.d6c5343c
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-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.js +2 -14
- 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/bg-shell/utilities.js +5 -2
- 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/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
- 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 +94 -48
- package/dist/resources/extensions/gsd/auto/phases.js +8 -3
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +40 -57
- package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +31 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +24 -26
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +9 -28
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
- package/dist/resources/extensions/gsd/auto.js +8 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- 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/captures.js +5 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/consent-question.js +337 -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 +4 -12
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +398 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -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/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +171 -2048
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +51 -5
- 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/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
- package/dist/resources/extensions/gsd/milestone-closeout.js +13 -23
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +37 -24
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/preferences.js +14 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.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/run-uat.md +6 -4
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +6 -20
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +44 -53
- package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +28 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
- 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 +96 -5
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- 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/gsd-browser/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/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/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +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/api/visualizer/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 +8 -8
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- 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/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/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -11
- 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/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.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 +8 -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 +6 -3
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +46 -21
- 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/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/models.generated.d.ts +192 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +166 -0
- package/packages/pi-ai/dist/models.generated.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/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.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/bg-shell/utilities.ts +5 -2
- 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 +29 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
- 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-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +109 -51
- package/src/resources/extensions/gsd/auto/phases.ts +12 -3
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -32
- package/src/resources/extensions/gsd/auto-dispatch.ts +38 -52
- package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +37 -13
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +24 -29
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +8 -26
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
- package/src/resources/extensions/gsd/auto.ts +20 -24
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- 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/captures.ts +5 -16
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/consent-question.ts +416 -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 +3 -9
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +490 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -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/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +173 -2373
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +50 -5
- 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/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
- package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
- package/src/resources/extensions/gsd/milestone-closeout.ts +13 -23
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +42 -22
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/preferences.ts +18 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.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/run-uat.md +6 -4
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +9 -21
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +101 -26
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- 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/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +336 -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/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/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/evidence-xref-gsd-exec.test.ts +157 -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/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- 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/migration-auto-check.test.ts +85 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- 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 +139 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +43 -68
- package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +29 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
- 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 +119 -5
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- 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/gsd-browser/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- 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/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → jmTLg6xZmAuq_LIqKOxrH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → jmTLg6xZmAuq_LIqKOxrH}/_ssgManifest.js +0 -0
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
STATE_TRANSITION_MATRIX,
|
|
6
6
|
findTransition,
|
|
7
7
|
validateTransitionMatrix,
|
|
8
|
+
isLegalEdge,
|
|
9
|
+
IllegalPhaseTransitionError,
|
|
8
10
|
} from "../state-transition-matrix.ts";
|
|
9
11
|
|
|
10
12
|
test("state transition matrix covers required swarm hardening events", () => {
|
|
@@ -42,3 +44,37 @@ test("state transition matrix entries all have guard and reason codes", () => {
|
|
|
42
44
|
assert.ok(entry.reasonCode.length > 0, `${entry.event} must include reason code`);
|
|
43
45
|
}
|
|
44
46
|
});
|
|
47
|
+
|
|
48
|
+
// ─── ADR-030: Phase Transition Invariant ───────────────────────────────────
|
|
49
|
+
|
|
50
|
+
test("isLegalEdge treats a self-edge as trivially legal", () => {
|
|
51
|
+
assert.equal(isLegalEdge("executing", "executing"), true);
|
|
52
|
+
assert.equal(isLegalEdge("planning", "planning"), true);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("isLegalEdge accepts edges enumerated in the matrix", () => {
|
|
56
|
+
assert.equal(isLegalEdge("planning", "executing"), true);
|
|
57
|
+
assert.equal(isLegalEdge("executing", "summarizing"), true);
|
|
58
|
+
assert.equal(isLegalEdge("summarizing", "validating-milestone"), true);
|
|
59
|
+
assert.equal(isLegalEdge("completing-milestone", "complete"), true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("isLegalEdge honors the * wildcard rows (any -> blocked, any -> executing)", () => {
|
|
63
|
+
assert.equal(isLegalEdge("planning", "blocked"), true);
|
|
64
|
+
assert.equal(isLegalEdge("summarizing", "executing"), true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("isLegalEdge rejects an edge no matrix entry permits", () => {
|
|
68
|
+
// executing -> complete skips validation — exactly the illegal jump the
|
|
69
|
+
// invariant exists to catch.
|
|
70
|
+
assert.equal(isLegalEdge("executing", "complete"), false);
|
|
71
|
+
assert.equal(isLegalEdge("planning", "summarizing"), false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("IllegalPhaseTransitionError carries both endpoints and a descriptive message", () => {
|
|
75
|
+
const err = new IllegalPhaseTransitionError("executing", "complete");
|
|
76
|
+
assert.equal(err.from, "executing");
|
|
77
|
+
assert.equal(err.to, "complete");
|
|
78
|
+
assert.equal(err.name, "IllegalPhaseTransitionError");
|
|
79
|
+
assert.match(err.message, /executing -> complete/);
|
|
80
|
+
});
|
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
isDeferredStatus,
|
|
10
10
|
isInactiveStatus,
|
|
11
11
|
isSkippedForDispatch,
|
|
12
|
+
toStatus,
|
|
13
|
+
RAW_CLOSED_STATUSES,
|
|
12
14
|
} from '../status-guards.ts';
|
|
15
|
+
import { TERMINAL_STATUS_SQL } from '../db/sql-constants.ts';
|
|
13
16
|
|
|
14
17
|
test('isClosedStatus: "complete" returns true', () => {
|
|
15
18
|
assert.equal(isClosedStatus('complete'), true);
|
|
@@ -95,3 +98,38 @@ test('isSkippedForDispatch does NOT skip pending/active/planned', () => {
|
|
|
95
98
|
assert.equal(isSkippedForDispatch(s), false, `${s} should block dispatch ordering`);
|
|
96
99
|
}
|
|
97
100
|
});
|
|
101
|
+
|
|
102
|
+
// ─── ADR-030: canonical Status vocabulary + normalization ──────────────────
|
|
103
|
+
|
|
104
|
+
test('toStatus passes canonical values through unchanged', () => {
|
|
105
|
+
for (const s of ['pending', 'queued', 'active', 'parked', 'in_progress', 'blocked', 'complete', 'skipped', 'deferred']) {
|
|
106
|
+
assert.equal(toStatus(s), s, `${s} is canonical and should be returned verbatim`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('toStatus maps known aliases to canonical', () => {
|
|
111
|
+
assert.equal(toStatus('done'), 'complete');
|
|
112
|
+
assert.equal(toStatus('closed'), 'complete');
|
|
113
|
+
assert.equal(toStatus('planned'), 'pending');
|
|
114
|
+
assert.equal(toStatus('in-progress'), 'in_progress');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('toStatus trims surrounding whitespace before matching', () => {
|
|
118
|
+
assert.equal(toStatus(' complete '), 'complete');
|
|
119
|
+
assert.equal(toStatus(' done '), 'complete');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('toStatus quarantines unknown values verbatim (tolerant read, no throw)', () => {
|
|
123
|
+
assert.equal(toStatus('weird-legacy-value'), 'weird-legacy-value');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('RAW_CLOSED_STATUSES is the single source: every member is closed', () => {
|
|
127
|
+
for (const s of RAW_CLOSED_STATUSES) {
|
|
128
|
+
assert.equal(isClosedStatus(s), true, `${s} is in RAW_CLOSED_STATUSES so must be closed`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('TERMINAL_STATUS_SQL is derived from RAW_CLOSED_STATUSES and renders identically', () => {
|
|
133
|
+
assert.equal(TERMINAL_STATUS_SQL, "'complete', 'done', 'skipped', 'closed'");
|
|
134
|
+
assert.equal(TERMINAL_STATUS_SQL, RAW_CLOSED_STATUSES.map((s) => `'${s}'`).join(', '));
|
|
135
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// GSD Extension — Stop Notice module tests
|
|
2
|
+
// Locks the emitter↔detector round-trip: every notice the formatters produce
|
|
3
|
+
// must be recognized by the classifiers the headless host uses for exit codes.
|
|
4
|
+
|
|
5
|
+
import { describe, test } from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
formatStopNoticePrefix,
|
|
10
|
+
isBlockedStopReason,
|
|
11
|
+
stopNoticeDisplayReason,
|
|
12
|
+
stopNoticeKind,
|
|
13
|
+
isTerminalNotice,
|
|
14
|
+
isPauseNotice,
|
|
15
|
+
isBlockedNoticeMessage,
|
|
16
|
+
isManualResolutionNotice,
|
|
17
|
+
PAUSED_NOTICE_PREFIXES,
|
|
18
|
+
TERMINAL_NOTICE_PREFIXES,
|
|
19
|
+
} from "../stop-notice.js";
|
|
20
|
+
|
|
21
|
+
describe("stop notice formatting", () => {
|
|
22
|
+
test("plain stop has no reason suffix", () => {
|
|
23
|
+
assert.equal(formatStopNoticePrefix(), "Auto-mode stopped");
|
|
24
|
+
assert.equal(formatStopNoticePrefix(null), "Auto-mode stopped");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("reason is appended after an em-dash", () => {
|
|
28
|
+
assert.equal(formatStopNoticePrefix("user request"), "Auto-mode stopped — user request");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("Blocked: marker switches the prefix and is stripped from display", () => {
|
|
32
|
+
assert.equal(formatStopNoticePrefix("Blocked: validation gate"), "Auto-mode blocked — validation gate");
|
|
33
|
+
assert.equal(stopNoticeKind("Blocked: x"), "blocked");
|
|
34
|
+
assert.equal(stopNoticeKind("stop"), "stopped");
|
|
35
|
+
assert.ok(isBlockedStopReason("blocked: lowercase too"));
|
|
36
|
+
assert.equal(stopNoticeDisplayReason("Blocked: spaced "), "spaced");
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("emitter↔detector round-trip", () => {
|
|
41
|
+
test("formatted stop notices classify as terminal", () => {
|
|
42
|
+
for (const reason of [undefined, "user request"]) {
|
|
43
|
+
const message = formatStopNoticePrefix(reason).toLowerCase();
|
|
44
|
+
assert.ok(isTerminalNotice(message), `not terminal: ${message}`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("pause prefixes classify as pause and as blocked (operator intervention)", () => {
|
|
49
|
+
for (const prefix of PAUSED_NOTICE_PREFIXES) {
|
|
50
|
+
assert.ok(isPauseNotice(`${prefix}: provider error`));
|
|
51
|
+
assert.ok(isBlockedNoticeMessage(`${prefix}: provider error`));
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("idempotent-advance pauses are non-blocking", () => {
|
|
56
|
+
assert.equal(isBlockedNoticeMessage("auto-mode paused (idempotent advance: unit already active)"), false);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("manual-resolution notices classify as blocked", () => {
|
|
60
|
+
const message = "merge conflict — resolve manually and re-run /gsd auto";
|
|
61
|
+
assert.ok(isManualResolutionNotice(message));
|
|
62
|
+
assert.ok(isBlockedNoticeMessage(message));
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("terminal prefixes cover the known stop vocabulary", () => {
|
|
66
|
+
for (const message of ["auto-mode stopped.", "auto-mode complete", "auto-mode idle", "no active milestone"]) {
|
|
67
|
+
assert.ok(TERMINAL_NOTICE_PREFIXES.some((prefix) => message.startsWith(prefix)), message);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -10,6 +10,7 @@ import { DISCUSS_TOOLS_ALLOWLIST } from "../constants.ts";
|
|
|
10
10
|
import { buildMinimalAutoGsdToolSet, buildMinimalGsdToolSet, buildMinimalGsdWorkflowToolSet, buildRequestScopedGsdToolSet, MINIMAL_AUTO_BASE_TOOL_NAMES, MINIMAL_GSD_TOOL_NAMES, requestHasGsdCustomType, restoreGsdWorkflowTools, scopeGsdWorkflowToolsForDispatch } from "../bootstrap/register-hooks.ts";
|
|
11
11
|
import { filterToolsForProvider } from "../model-router.ts";
|
|
12
12
|
import { applyUnitSkillVisibility } from "../skill-scope.ts";
|
|
13
|
+
import { drainLogs } from "../workflow-logger.ts";
|
|
13
14
|
|
|
14
15
|
test("buildMinimalGsdToolSet preserves non-GSD tools and replaces broad GSD surface", () => {
|
|
15
16
|
const result = buildMinimalGsdToolSet([
|
|
@@ -17,6 +18,7 @@ test("buildMinimalGsdToolSet preserves non-GSD tools and replaces broad GSD surf
|
|
|
17
18
|
"read",
|
|
18
19
|
"browser_open",
|
|
19
20
|
"gsd_plan_milestone",
|
|
21
|
+
"gsd_plan_slice",
|
|
20
22
|
"gsd_task_complete",
|
|
21
23
|
"gsd_exec",
|
|
22
24
|
"gsd_exec_search",
|
|
@@ -103,6 +105,40 @@ test("buildMinimalAutoGsdToolSet keeps unit-specific completion tools without al
|
|
|
103
105
|
assert.ok(!result.includes("gsd_complete_slice"));
|
|
104
106
|
});
|
|
105
107
|
|
|
108
|
+
test("buildMinimalAutoGsdToolSet warns when plan-milestone required tools are unresolved", () => {
|
|
109
|
+
drainLogs();
|
|
110
|
+
const result = buildMinimalAutoGsdToolSet(
|
|
111
|
+
[
|
|
112
|
+
"ask_user_questions",
|
|
113
|
+
"bash",
|
|
114
|
+
"read",
|
|
115
|
+
"gsd_milestone_status",
|
|
116
|
+
"gsd_plan_milestone",
|
|
117
|
+
],
|
|
118
|
+
"plan-milestone",
|
|
119
|
+
[
|
|
120
|
+
"ask_user_questions",
|
|
121
|
+
"bash",
|
|
122
|
+
"read",
|
|
123
|
+
"gsd_milestone_status",
|
|
124
|
+
"gsd_plan_milestone",
|
|
125
|
+
],
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
assert.ok(result.includes("gsd_plan_milestone"));
|
|
129
|
+
assert.ok(!result.includes("gsd_plan_slice"));
|
|
130
|
+
|
|
131
|
+
const logs = drainLogs();
|
|
132
|
+
assert.ok(
|
|
133
|
+
logs.some((entry) =>
|
|
134
|
+
entry.component === "bootstrap" &&
|
|
135
|
+
entry.message.includes("buildMinimalAutoGsdToolSet(plan-milestone)") &&
|
|
136
|
+
entry.message.includes("gsd_plan_slice")
|
|
137
|
+
),
|
|
138
|
+
`expected missing gsd_plan_slice bootstrap warning, got ${JSON.stringify(logs)}`,
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
106
142
|
test("buildMinimalAutoGsdToolSet scopes run-uat to UAT-specific and read-only tools", () => {
|
|
107
143
|
const active = ["ask_user_questions", "bash", "read", "edit", "write", "gsd_summary_save"];
|
|
108
144
|
const registered = [
|
|
@@ -613,6 +649,46 @@ test("buildMinimalAutoGsdToolSet resolves MCP-scoped gsd_memory_query and gsd_ca
|
|
|
613
649
|
);
|
|
614
650
|
});
|
|
615
651
|
|
|
652
|
+
// ── Regression #627: auto-mode cannot run plan-milestone because gsd_plan_slice is missing ──
|
|
653
|
+
// gsd_plan_slice is in AUTO_UNIT_SCOPED_TOOLS["plan-milestone"] (via unit-tool-contracts).
|
|
654
|
+
// buildMinimalAutoGsdToolSet must expose it when unitType is "plan-milestone".
|
|
655
|
+
|
|
656
|
+
test("buildMinimalAutoGsdToolSet includes gsd_plan_slice for plan-milestone (regression #627)", () => {
|
|
657
|
+
const result = buildMinimalAutoGsdToolSet([
|
|
658
|
+
"bash",
|
|
659
|
+
"read",
|
|
660
|
+
"gsd_plan_milestone",
|
|
661
|
+
"gsd_plan_slice",
|
|
662
|
+
"gsd_milestone_status",
|
|
663
|
+
"gsd_checkpoint_db",
|
|
664
|
+
"memory_query",
|
|
665
|
+
"capture_thought",
|
|
666
|
+
], "plan-milestone");
|
|
667
|
+
|
|
668
|
+
assert.ok(
|
|
669
|
+
result.includes("gsd_plan_slice"),
|
|
670
|
+
"gsd_plan_slice must be included in plan-milestone auto-mode tool set",
|
|
671
|
+
);
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
test("buildMinimalAutoGsdToolSet resolves MCP-scoped gsd_plan_slice for plan-milestone when subprocess only registers prefixed variant (regression #627)", () => {
|
|
675
|
+
const result = buildMinimalAutoGsdToolSet([
|
|
676
|
+
"bash",
|
|
677
|
+
"read",
|
|
678
|
+
"mcp__gsd-workflow__gsd_plan_milestone",
|
|
679
|
+
"mcp__gsd-workflow__gsd_plan_slice",
|
|
680
|
+
"mcp__gsd-workflow__gsd_milestone_status",
|
|
681
|
+
"mcp__gsd-workflow__gsd_checkpoint_db",
|
|
682
|
+
"mcp__gsd-workflow__memory_query",
|
|
683
|
+
"mcp__gsd-workflow__capture_thought",
|
|
684
|
+
], "plan-milestone");
|
|
685
|
+
|
|
686
|
+
assert.ok(
|
|
687
|
+
result.includes("mcp__gsd-workflow__gsd_plan_slice"),
|
|
688
|
+
"mcp__gsd-workflow__gsd_plan_slice must be included when only the MCP-scoped variant is available",
|
|
689
|
+
);
|
|
690
|
+
});
|
|
691
|
+
|
|
616
692
|
test("applyUnitSkillVisibility sets manifest or clears for wildcard", () => {
|
|
617
693
|
const calls: Array<string[] | undefined> = [];
|
|
618
694
|
applyUnitSkillVisibility({
|
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
isDeterministicPolicyError,
|
|
49
49
|
isPendingUserApprovalGateError,
|
|
50
50
|
isToolInvocationError,
|
|
51
|
+
isToolUnavailableError,
|
|
51
52
|
isQueuedUserMessageSkip,
|
|
52
53
|
} from "../auto-tool-tracking.ts";
|
|
53
54
|
import {
|
|
@@ -121,6 +122,13 @@ describe("#2883: isToolInvocationError classification", () => {
|
|
|
121
122
|
assert.equal(isToolInvocationError("No such tool available: mcp__gsd-workflow__memory_query"), true);
|
|
122
123
|
});
|
|
123
124
|
|
|
125
|
+
test("isToolUnavailableError singles out the startup-race error as transient", () => {
|
|
126
|
+
assert.equal(isToolUnavailableError("No such tool available: mcp__gsd-workflow__gsd_uat_exec"), true);
|
|
127
|
+
assert.equal(isToolUnavailableError("Validation failed for tool gsd_complete_slice"), false);
|
|
128
|
+
assert.equal(isToolUnavailableError("Unexpected end of JSON input"), false);
|
|
129
|
+
assert.equal(isToolUnavailableError(""), false);
|
|
130
|
+
});
|
|
131
|
+
|
|
124
132
|
test("detects ESM export-link errors", () => {
|
|
125
133
|
assert.equal(
|
|
126
134
|
isToolInvocationError("The requested module '../paths.js' does not provide an export named 'gsdProjectionRoot'"),
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Contract coverage for the Tool Surface Readiness gate and its recovery classification.
|
|
3
|
+
|
|
4
|
+
import { describe, test } from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
|
|
7
|
+
import { getToolSurfaceReadinessError } from "../tool-surface-readiness.ts";
|
|
8
|
+
import { isToolUnavailableError } from "../auto-tool-tracking.ts";
|
|
9
|
+
import { classifyError, isTransient } from "../error-classifier.ts";
|
|
10
|
+
import { toMcpToolName } from "../mcp-tool-name.ts";
|
|
11
|
+
import { classifyFailure } from "../recovery-classification.ts";
|
|
12
|
+
|
|
13
|
+
const SERVER = "gsd-workflow";
|
|
14
|
+
|
|
15
|
+
function prefixed(tool: string): string {
|
|
16
|
+
return toMcpToolName(SERVER, tool);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const RUN_UAT_TOOLS = [
|
|
20
|
+
"gsd_uat_exec",
|
|
21
|
+
"gsd_uat_result_save",
|
|
22
|
+
"gsd_resume",
|
|
23
|
+
"gsd_milestone_status",
|
|
24
|
+
"gsd_journal_query",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
describe("getToolSurfaceReadinessError", () => {
|
|
28
|
+
test("returns null when no unit type or no workflow server is in play", () => {
|
|
29
|
+
const observation = { tools: [], mcpServers: [] };
|
|
30
|
+
assert.equal(
|
|
31
|
+
getToolSurfaceReadinessError({ unitType: undefined, workflowServerName: SERVER, observation }),
|
|
32
|
+
null,
|
|
33
|
+
);
|
|
34
|
+
assert.equal(
|
|
35
|
+
getToolSurfaceReadinessError({ unitType: "run-uat", workflowServerName: undefined, observation }),
|
|
36
|
+
null,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("returns null for units with no required workflow tools", () => {
|
|
41
|
+
const error = getToolSurfaceReadinessError({
|
|
42
|
+
unitType: "rewrite-docs",
|
|
43
|
+
workflowServerName: SERVER,
|
|
44
|
+
observation: { tools: [], mcpServers: [{ name: SERVER, status: "failed" }] },
|
|
45
|
+
});
|
|
46
|
+
assert.equal(error, null);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("returns an error when the expected workflow server is absent from the init surface", () => {
|
|
50
|
+
const error = getToolSurfaceReadinessError({
|
|
51
|
+
unitType: "run-uat",
|
|
52
|
+
workflowServerName: SERVER,
|
|
53
|
+
observation: { tools: ["read", "bash"], mcpServers: [{ name: "other-server", status: "connected" }] },
|
|
54
|
+
});
|
|
55
|
+
assert.ok(error, "expected a readiness error when the workflow server is absent");
|
|
56
|
+
assert.match(error, /workflow tool surface not ready for run-uat/);
|
|
57
|
+
assert.match(error, /absent from the init surface/);
|
|
58
|
+
assert.match(error, /gsd_uat_exec/);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("passes a still-connecting (pending) server through instead of aborting", () => {
|
|
62
|
+
// The SDK reports still-connecting servers as "pending" at init — the
|
|
63
|
+
// common healthy session. A genuine miss after pass-through is caught
|
|
64
|
+
// in-session ("No such tool available" → tool-unavailable → retry).
|
|
65
|
+
const error = getToolSurfaceReadinessError({
|
|
66
|
+
unitType: "plan-slice",
|
|
67
|
+
workflowServerName: SERVER,
|
|
68
|
+
observation: { tools: ["read", "bash"], mcpServers: [{ name: SERVER, status: "pending" }] },
|
|
69
|
+
});
|
|
70
|
+
assert.equal(error, null);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("returns null when all required tools are registered under the MCP prefix", () => {
|
|
74
|
+
const error = getToolSurfaceReadinessError({
|
|
75
|
+
unitType: "run-uat",
|
|
76
|
+
workflowServerName: SERVER,
|
|
77
|
+
observation: {
|
|
78
|
+
tools: ["read", ...RUN_UAT_TOOLS.map(prefixed)],
|
|
79
|
+
mcpServers: [{ name: SERVER, status: "connected" }],
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
assert.equal(error, null);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("reports the failed server and the missing tools when the surface never registered", () => {
|
|
86
|
+
const error = getToolSurfaceReadinessError({
|
|
87
|
+
unitType: "run-uat",
|
|
88
|
+
workflowServerName: SERVER,
|
|
89
|
+
observation: { tools: ["read", "bash"], mcpServers: [{ name: SERVER, status: "failed" }] },
|
|
90
|
+
});
|
|
91
|
+
assert.ok(error, "expected a readiness error");
|
|
92
|
+
assert.match(error, /workflow tool surface not ready for run-uat/);
|
|
93
|
+
assert.match(error, /status is "failed"/);
|
|
94
|
+
assert.match(error, /gsd_uat_exec/);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("aborts on needs-auth (terminal — cannot self-heal)", () => {
|
|
98
|
+
const error = getToolSurfaceReadinessError({
|
|
99
|
+
unitType: "run-uat",
|
|
100
|
+
workflowServerName: SERVER,
|
|
101
|
+
observation: { tools: ["read", "bash"], mcpServers: [{ name: SERVER, status: "needs-auth" }] },
|
|
102
|
+
});
|
|
103
|
+
assert.ok(error, "expected a readiness error for needs-auth");
|
|
104
|
+
assert.match(error, /status is "needs-auth"/);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("aborts on disabled (terminal — cannot self-heal)", () => {
|
|
108
|
+
const error = getToolSurfaceReadinessError({
|
|
109
|
+
unitType: "run-uat",
|
|
110
|
+
workflowServerName: SERVER,
|
|
111
|
+
observation: { tools: ["read", "bash"], mcpServers: [{ name: SERVER, status: "disabled" }] },
|
|
112
|
+
});
|
|
113
|
+
assert.ok(error, "expected a readiness error for disabled");
|
|
114
|
+
assert.match(error, /status is "disabled"/);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("reports partially-registered surfaces even when the server says connected", () => {
|
|
118
|
+
const error = getToolSurfaceReadinessError({
|
|
119
|
+
unitType: "run-uat",
|
|
120
|
+
workflowServerName: SERVER,
|
|
121
|
+
observation: {
|
|
122
|
+
tools: [prefixed("gsd_uat_exec")],
|
|
123
|
+
mcpServers: [{ name: SERVER, status: "connected" }],
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
assert.ok(error, "expected a readiness error");
|
|
127
|
+
assert.match(error, /connected but has not registered/);
|
|
128
|
+
assert.match(error, /gsd_uat_result_save/);
|
|
129
|
+
assert.doesNotMatch(error, /gsd_uat_exec,/);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("readiness error classification contract", () => {
|
|
134
|
+
const readinessError = getToolSurfaceReadinessError({
|
|
135
|
+
unitType: "run-uat",
|
|
136
|
+
workflowServerName: SERVER,
|
|
137
|
+
observation: { tools: [], mcpServers: [{ name: SERVER, status: "failed" }] },
|
|
138
|
+
})!;
|
|
139
|
+
|
|
140
|
+
test("auto-tool-tracking treats the readiness error as tool-unavailable", () => {
|
|
141
|
+
assert.equal(isToolUnavailableError(readinessError), true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("error-classifier treats the readiness error as transient", () => {
|
|
145
|
+
const cls = classifyError(`Claude Code error: ${readinessError}`);
|
|
146
|
+
assert.equal(isTransient(cls), true);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("Recovery Classification maps the readiness error to tool-unavailable → retry", () => {
|
|
150
|
+
const recovery = classifyFailure({ error: new Error(readinessError), unitType: "run-uat", unitId: "M001" });
|
|
151
|
+
assert.equal(recovery.failureKind, "tool-unavailable");
|
|
152
|
+
assert.equal(recovery.action, "retry");
|
|
153
|
+
assert.equal(recovery.exitReason, "tool-unavailable");
|
|
154
|
+
});
|
|
155
|
+
});
|
|
@@ -3,9 +3,9 @@ import assert from "node:assert/strict";
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
classifyUatContent,
|
|
6
|
+
classifyUatContentForRun,
|
|
6
7
|
getDeclaredUatType,
|
|
7
8
|
getUatBrowserToolSupportError,
|
|
8
|
-
hasUatBrowserToolSurface,
|
|
9
9
|
isPartialEligibleUatType,
|
|
10
10
|
resolveEffectiveUatType,
|
|
11
11
|
shouldDispatchUatForContent,
|
|
@@ -13,12 +13,104 @@ import {
|
|
|
13
13
|
uatTypeIncludesBrowser,
|
|
14
14
|
validateUatModePolicy,
|
|
15
15
|
} from "../uat-policy.ts";
|
|
16
|
+
import {
|
|
17
|
+
assertBrowserAutomationContractAvailable,
|
|
18
|
+
assertBrowserAutomationContractMissing,
|
|
19
|
+
assertBrowserBackedUatCanDispatch,
|
|
20
|
+
BROWSER_AUTOMATION_CONTRACT_TOOLS,
|
|
21
|
+
} from "./browser-automation-contract-fixture.ts";
|
|
16
22
|
|
|
17
23
|
describe("uat-policy", () => {
|
|
18
24
|
it("defaults missing UAT mode to artifact-driven", () => {
|
|
19
25
|
assert.equal(getDeclaredUatType("# UAT\n\nCheck generated files."), "artifact-driven");
|
|
20
26
|
});
|
|
21
27
|
|
|
28
|
+
it("parses a bare keyword under ## UAT Type (M006/S01 agent format drift)", () => {
|
|
29
|
+
const content = [
|
|
30
|
+
"# S01 UAT",
|
|
31
|
+
"",
|
|
32
|
+
"## UAT Type",
|
|
33
|
+
"browser-executable",
|
|
34
|
+
"",
|
|
35
|
+
"## Preconditions",
|
|
36
|
+
"- Run `node tests/browser/search-uat.mjs` (it starts its own server on an ephemeral port; do not start serve-static separately).",
|
|
37
|
+
].join("\n");
|
|
38
|
+
assert.equal(getDeclaredUatType(content), "browser-executable");
|
|
39
|
+
assert.equal(shouldEscalateArtifactUatToBrowser(content), false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("promotes browser-executable UAT when slice context names test:uat but UAT only documents test:server (M007/S01)", () => {
|
|
43
|
+
const uatFile = [
|
|
44
|
+
"# S01 UAT",
|
|
45
|
+
"",
|
|
46
|
+
"## UAT Type",
|
|
47
|
+
"- UAT mode: browser-executable",
|
|
48
|
+
"",
|
|
49
|
+
"## Preconditions",
|
|
50
|
+
"- Start the dev/local verification server with `npm run test:server`.",
|
|
51
|
+
"- Open the app at the localhost URL printed by the server.",
|
|
52
|
+
].join("\n");
|
|
53
|
+
const sliceContext = [
|
|
54
|
+
"Fresh slice-level verification ran via `gsd_exec` with `npm run test:uat` and passed.",
|
|
55
|
+
"The run produced PASS with browser diagnostics consoleErrors=0.",
|
|
56
|
+
].join("\n");
|
|
57
|
+
|
|
58
|
+
assert.equal(classifyUatContentForRun(uatFile, sliceContext).effectiveType, "runtime-executable");
|
|
59
|
+
assert.equal(classifyUatContentForRun(uatFile).effectiveType, "browser-executable");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("promotes browser-executable UAT to runtime-executable when a self-contained harness is named (M006/S01)", () => {
|
|
63
|
+
const content = [
|
|
64
|
+
"# S01 UAT",
|
|
65
|
+
"",
|
|
66
|
+
"## UAT Type",
|
|
67
|
+
"- UAT mode: browser-executable",
|
|
68
|
+
"",
|
|
69
|
+
"## Preconditions",
|
|
70
|
+
"- Start the local app server with `npm run start`.",
|
|
71
|
+
"- Open the app at `http://127.0.0.1:4173`.",
|
|
72
|
+
"",
|
|
73
|
+
"## Evidence",
|
|
74
|
+
"- Fresh closeout verification command: `node --check app.js && node --check tests/browser/search-uat.mjs && npm run test:uat`",
|
|
75
|
+
].join("\n");
|
|
76
|
+
|
|
77
|
+
assert.equal(resolveEffectiveUatType(content), "runtime-executable");
|
|
78
|
+
assert.deepEqual(classifyUatContent(content), {
|
|
79
|
+
declaredType: "browser-executable",
|
|
80
|
+
modeDeclared: true,
|
|
81
|
+
effectiveType: "runtime-executable",
|
|
82
|
+
browserRequired: false,
|
|
83
|
+
shouldDispatchByDefault: true,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("parses a UAT mode line case-insensitively with bold markers", () => {
|
|
88
|
+
const content = [
|
|
89
|
+
"## UAT Type",
|
|
90
|
+
"- **UAT Mode:** Runtime-Executable (npx playwright test)",
|
|
91
|
+
].join("\n");
|
|
92
|
+
assert.equal(getDeclaredUatType(content), "runtime-executable");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("does not parse prose in the section as a mode declaration", () => {
|
|
96
|
+
const content = [
|
|
97
|
+
"## UAT Type",
|
|
98
|
+
"- Why this mode is sufficient: static checks cover the schema.",
|
|
99
|
+
].join("\n");
|
|
100
|
+
assert.equal(getDeclaredUatType(content), "artifact-driven");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("treats an explicit UAT mode line with an unrecognised value as undeclared", () => {
|
|
104
|
+
const content = [
|
|
105
|
+
"## UAT Type",
|
|
106
|
+
"- UAT mode: manual-spot-check",
|
|
107
|
+
"- browser-executable would also work",
|
|
108
|
+
].join("\n");
|
|
109
|
+
// The explicit declaration wins (and fails to parse) — the stray keyword
|
|
110
|
+
// bullet below it must not be promoted to the declared mode.
|
|
111
|
+
assert.equal(getDeclaredUatType(content), "artifact-driven");
|
|
112
|
+
});
|
|
113
|
+
|
|
22
114
|
it("escalates artifact-driven UAT to browser-executable when the spec requires browser work", () => {
|
|
23
115
|
const content = [
|
|
24
116
|
"## UAT Type",
|
|
@@ -33,6 +125,7 @@ describe("uat-policy", () => {
|
|
|
33
125
|
assert.equal(shouldDispatchUatForContent(content, undefined), true);
|
|
34
126
|
assert.deepEqual(classifyUatContent(content), {
|
|
35
127
|
declaredType: "artifact-driven",
|
|
128
|
+
modeDeclared: true,
|
|
36
129
|
effectiveType: "browser-executable",
|
|
37
130
|
browserRequired: true,
|
|
38
131
|
shouldDispatchByDefault: true,
|
|
@@ -63,14 +156,14 @@ describe("uat-policy", () => {
|
|
|
63
156
|
}
|
|
64
157
|
});
|
|
65
158
|
|
|
66
|
-
it("detects
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
159
|
+
it("detects Browser Automation Contract capability across adapters", () => {
|
|
160
|
+
assertBrowserAutomationContractAvailable(BROWSER_AUTOMATION_CONTRACT_TOOLS.piProvider);
|
|
161
|
+
assertBrowserAutomationContractAvailable(BROWSER_AUTOMATION_CONTRACT_TOOLS.externalMcpClient);
|
|
162
|
+
assertBrowserAutomationContractAvailable(BROWSER_AUTOMATION_CONTRACT_TOOLS.externalMcpWildcard);
|
|
163
|
+
assertBrowserAutomationContractAvailable(BROWSER_AUTOMATION_CONTRACT_TOOLS.otherBrowserMcp);
|
|
164
|
+
assertBrowserAutomationContractMissing(BROWSER_AUTOMATION_CONTRACT_TOOLS.workflowOnly);
|
|
165
|
+
assertBrowserAutomationContractMissing(BROWSER_AUTOMATION_CONTRACT_TOOLS.withoutBrowser);
|
|
166
|
+
assertBrowserAutomationContractMissing(undefined);
|
|
74
167
|
});
|
|
75
168
|
|
|
76
169
|
it("reports missing browser tools only for browser-backed UAT with a known tool snapshot", () => {
|
|
@@ -92,26 +185,16 @@ describe("uat-policy", () => {
|
|
|
92
185
|
}),
|
|
93
186
|
null,
|
|
94
187
|
);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
105
|
-
assert.equal(
|
|
106
|
-
getUatBrowserToolSupportError({
|
|
107
|
-
uatType: "human-experience",
|
|
108
|
-
activeTools: ["read", "gsd_uat_exec"],
|
|
109
|
-
registeredTools: ["mcp__gsd-browser__*"],
|
|
110
|
-
milestoneId: "M001",
|
|
111
|
-
sliceId: "S01",
|
|
112
|
-
}),
|
|
113
|
-
null,
|
|
114
|
-
);
|
|
188
|
+
assertBrowserBackedUatCanDispatch({
|
|
189
|
+
uatType: "human-experience",
|
|
190
|
+
activeTools: BROWSER_AUTOMATION_CONTRACT_TOOLS.withoutBrowser,
|
|
191
|
+
registeredTools: BROWSER_AUTOMATION_CONTRACT_TOOLS.piProvider,
|
|
192
|
+
});
|
|
193
|
+
assertBrowserBackedUatCanDispatch({
|
|
194
|
+
uatType: "human-experience",
|
|
195
|
+
activeTools: BROWSER_AUTOMATION_CONTRACT_TOOLS.withoutBrowser,
|
|
196
|
+
registeredTools: BROWSER_AUTOMATION_CONTRACT_TOOLS.externalMcpWildcard,
|
|
197
|
+
});
|
|
115
198
|
|
|
116
199
|
const error = getUatBrowserToolSupportError({
|
|
117
200
|
uatType: "browser-executable",
|