@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.9ad8ae33
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/mcp-server.js +2 -1
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.d.ts +10 -5
- package/dist/resource-loader.js +123 -20
- 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 +3 -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 +30 -4
- 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 +35 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +41 -18
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +23 -30
- package/dist/resources/extensions/gsd/auto-worktree.js +44 -91
- package/dist/resources/extensions/gsd/auto.js +41 -14
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
- 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 +212 -48
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
- 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 +4 -6
- 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 +12 -15
- package/dist/resources/extensions/gsd/db/queries.js +26 -0
- package/dist/resources/extensions/gsd/db-writer.js +8 -17
- 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-environment.js +2 -6
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
- 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/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +2 -1
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +23 -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 +4 -1
- 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/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +27 -0
- 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/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 +2 -2
- 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 +2 -2
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- 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/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 +37 -94
- 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 +6 -20
- package/dist/resources/extensions/gsd/stop-notice.js +57 -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/tool-surface-readiness.js +56 -0
- 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 +9 -7
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
- 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-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/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/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
- 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-root.js +11 -0
- package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
- 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 +13 -13
- 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 +13 -13
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- 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/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -15
- package/package.json +2 -2
- 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 +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 +9 -1
- 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 +26 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +116 -39
- 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 +35 -125
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +46 -120
- 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/bg-shell/utilities.ts +3 -0
- 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 +34 -4
- 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 +40 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +42 -21
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +26 -28
- package/src/resources/extensions/gsd/auto-worktree.ts +44 -94
- package/src/resources/extensions/gsd/auto.ts +52 -16
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
- 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 +251 -47
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
- 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 +4 -6
- 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 +13 -11
- package/src/resources/extensions/gsd/db/queries.ts +37 -0
- package/src/resources/extensions/gsd/db-writer.ts +11 -19
- 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-environment.ts +2 -7
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
- 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/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +4 -3
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +37 -28
- 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 +4 -1
- 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/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +33 -0
- 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/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 +2 -2
- 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 +2 -2
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- 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/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 +42 -96
- 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 +9 -21
- package/src/resources/extensions/gsd/stop-notice.ts +75 -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/auto-start-orphan-bootstrap.test.ts +236 -0
- 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/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -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 +351 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
- 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 +148 -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 +53 -11
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -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/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 +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/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/register-hooks-depth-verification.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- 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-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/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-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/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-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
- 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/tool-surface-readiness.ts +76 -0
- 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 +8 -7
- package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
- 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-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/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/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
- 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-root.ts +12 -0
- package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
- 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/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
|
@@ -118,6 +118,51 @@ function makeRepoWithMultipleStrandedMilestones(): string {
|
|
|
118
118
|
return base;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
function makeRepoWithOnlySiblingStrandedAndLockedActive(): string {
|
|
122
|
+
// Locked milestone (M002) is the active row but has NO stranded
|
|
123
|
+
// milestone branch. A sibling milestone (M001) has a stranded branch.
|
|
124
|
+
// A parallel worker locked to M002 must skip the sibling's stranded
|
|
125
|
+
// action entirely — neither block on it nor adopt it.
|
|
126
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-locked-no-stranded-bootstrap-"));
|
|
127
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
128
|
+
mkdirSync(join(base, ".gsd", "milestones", "M002"), { recursive: true });
|
|
129
|
+
// M002 has CONTEXT so bootstrap's pre-planning gate doesn't route to
|
|
130
|
+
// showSmartEntry and the test reaches the post-lock session-init path.
|
|
131
|
+
writeFileSync(
|
|
132
|
+
join(base, ".gsd", "milestones", "M002", "M002-CONTEXT.md"),
|
|
133
|
+
"# M002 context\n",
|
|
134
|
+
);
|
|
135
|
+
writeFileSync(
|
|
136
|
+
join(base, ".gsd", "PREFERENCES.md"),
|
|
137
|
+
"---\ngit:\n isolation: \"none\"\n---\n",
|
|
138
|
+
);
|
|
139
|
+
runGit(base, ["init"]);
|
|
140
|
+
runGit(base, ["config", "user.email", "test@test.com"]);
|
|
141
|
+
runGit(base, ["config", "user.name", "Test"]);
|
|
142
|
+
writeFileSync(join(base, "README.md"), "# test\n");
|
|
143
|
+
runGit(base, ["add", "-A"]);
|
|
144
|
+
runGit(base, ["commit", "-m", "init"]);
|
|
145
|
+
runGit(base, ["branch", "-M", "main"]);
|
|
146
|
+
|
|
147
|
+
// Sibling M001 has stranded work on milestone/M001.
|
|
148
|
+
runGit(base, ["checkout", "-b", "milestone/M001"]);
|
|
149
|
+
writeFileSync(join(base, "m001.txt"), "sibling stranded work\n");
|
|
150
|
+
runGit(base, ["add", "-A"]);
|
|
151
|
+
runGit(base, ["commit", "-m", "feat: M001 in progress"]);
|
|
152
|
+
runGit(base, ["checkout", "main"]);
|
|
153
|
+
|
|
154
|
+
// M002 has no stranded branch at all.
|
|
155
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
156
|
+
// Both milestones are open so the stranded audit produces a blocking
|
|
157
|
+
// action for the sibling (M001). M002 is the lock target and active
|
|
158
|
+
// row; getActiveMilestoneId honors the lock regardless of M001 order.
|
|
159
|
+
insertMilestone({ id: "M001", title: "Sibling milestone", status: "pending" });
|
|
160
|
+
insertMilestone({ id: "M002", title: "Locked milestone", status: "active" });
|
|
161
|
+
closeDatabase();
|
|
162
|
+
|
|
163
|
+
return base;
|
|
164
|
+
}
|
|
165
|
+
|
|
121
166
|
function makeRepoWithActiveMismatchAndStrandedTarget(): string {
|
|
122
167
|
const base = mkdtempSync(join(tmpdir(), "gsd-targeted-stranded-bootstrap-"));
|
|
123
168
|
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
@@ -455,6 +500,197 @@ test("bootstrap blocks active stranded recovery when another open milestone also
|
|
|
455
500
|
}
|
|
456
501
|
});
|
|
457
502
|
|
|
503
|
+
test("parallel worker recovers its locked stranded milestone despite stranded siblings", async () => {
|
|
504
|
+
const base = makeRepoWithMultipleStrandedMilestones();
|
|
505
|
+
const previousCwd = process.cwd();
|
|
506
|
+
const previousLock = process.env.GSD_MILESTONE_LOCK;
|
|
507
|
+
const previousWorker = process.env.GSD_PARALLEL_WORKER;
|
|
508
|
+
const s = new AutoSession();
|
|
509
|
+
const adoptCalls: Array<{ milestoneId: string; mode: string }> = [];
|
|
510
|
+
const notifications: Array<{ message: string; level?: string }> = [];
|
|
511
|
+
|
|
512
|
+
try {
|
|
513
|
+
process.env.GSD_PARALLEL_WORKER = "1";
|
|
514
|
+
process.env.GSD_MILESTONE_LOCK = "M002";
|
|
515
|
+
|
|
516
|
+
const ready = await bootstrapAutoSession(
|
|
517
|
+
s,
|
|
518
|
+
makeCtx(notifications) as any,
|
|
519
|
+
{
|
|
520
|
+
getThinkingLevel: () => "medium",
|
|
521
|
+
getActiveTools: () => [],
|
|
522
|
+
events: { emit: () => {} },
|
|
523
|
+
} as any,
|
|
524
|
+
base,
|
|
525
|
+
false,
|
|
526
|
+
false,
|
|
527
|
+
{
|
|
528
|
+
shouldUseWorktreeIsolation: () => false,
|
|
529
|
+
registerSigtermHandler: () => {},
|
|
530
|
+
registerAutoWorkerForSession: () => {},
|
|
531
|
+
lockBase: () => base,
|
|
532
|
+
buildLifecycle: () => ({
|
|
533
|
+
adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
|
|
534
|
+
s.basePath = sessionBase;
|
|
535
|
+
if (originalBase !== undefined) {
|
|
536
|
+
s.originalBasePath = originalBase;
|
|
537
|
+
} else if (!s.originalBasePath) {
|
|
538
|
+
s.originalBasePath = sessionBase;
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
enterMilestone: () => ({ ok: true, mode: "none", path: base }),
|
|
542
|
+
adoptStrandedMilestone: (
|
|
543
|
+
milestoneId: string,
|
|
544
|
+
sessionBase: string,
|
|
545
|
+
_ctx: unknown,
|
|
546
|
+
opts: { mode: "worktree" | "branch" },
|
|
547
|
+
) => {
|
|
548
|
+
adoptCalls.push({ milestoneId, mode: opts.mode });
|
|
549
|
+
s.basePath = sessionBase;
|
|
550
|
+
s.originalBasePath = sessionBase;
|
|
551
|
+
s.strandedRecoveryIsolationMode = opts.mode;
|
|
552
|
+
return { ok: true, mode: opts.mode, path: sessionBase };
|
|
553
|
+
},
|
|
554
|
+
adoptOrphanWorktree: <T extends { merged: boolean }>(
|
|
555
|
+
_mid: string,
|
|
556
|
+
_base: string,
|
|
557
|
+
run: () => T,
|
|
558
|
+
): T => run(),
|
|
559
|
+
}) as any,
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
classification: "none",
|
|
563
|
+
lock: null,
|
|
564
|
+
pausedSession: null,
|
|
565
|
+
state: null,
|
|
566
|
+
recovery: null,
|
|
567
|
+
recoveryPrompt: null,
|
|
568
|
+
recoveryToolCallCount: 0,
|
|
569
|
+
artifactSatisfied: false,
|
|
570
|
+
hasResumableDiskState: false,
|
|
571
|
+
isBootstrapCrash: false,
|
|
572
|
+
},
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
const messages = notifications.map((entry) => entry.message).join("\n");
|
|
576
|
+
assert.equal(ready, true);
|
|
577
|
+
assert.deepEqual(adoptCalls, [{ milestoneId: "M002", mode: "branch" }]);
|
|
578
|
+
assert.equal(s.currentMilestoneId, "M002");
|
|
579
|
+
assert.match(messages, /Resuming saved milestone work for M002/);
|
|
580
|
+
assert.doesNotMatch(messages, /blocks auto-mode before M002/);
|
|
581
|
+
assert.doesNotMatch(messages, /\/gsd auto M001/);
|
|
582
|
+
} finally {
|
|
583
|
+
if (previousLock === undefined) delete process.env.GSD_MILESTONE_LOCK;
|
|
584
|
+
else process.env.GSD_MILESTONE_LOCK = previousLock;
|
|
585
|
+
if (previousWorker === undefined) delete process.env.GSD_PARALLEL_WORKER;
|
|
586
|
+
else process.env.GSD_PARALLEL_WORKER = previousWorker;
|
|
587
|
+
try {
|
|
588
|
+
closeDatabase();
|
|
589
|
+
} catch {}
|
|
590
|
+
process.chdir(previousCwd);
|
|
591
|
+
rmSync(base, { recursive: true, force: true });
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
test("locked worker with no own stranded action does not adopt sibling stranded action", async () => {
|
|
596
|
+
const base = makeRepoWithOnlySiblingStrandedAndLockedActive();
|
|
597
|
+
const previousCwd = process.cwd();
|
|
598
|
+
const previousLock = process.env.GSD_MILESTONE_LOCK;
|
|
599
|
+
const previousWorker = process.env.GSD_PARALLEL_WORKER;
|
|
600
|
+
const s = new AutoSession();
|
|
601
|
+
const adoptCalls: Array<{ milestoneId: string; mode: string }> = [];
|
|
602
|
+
const enterCalls: string[] = [];
|
|
603
|
+
const notifications: Array<{ message: string; level?: string }> = [];
|
|
604
|
+
|
|
605
|
+
try {
|
|
606
|
+
process.env.GSD_PARALLEL_WORKER = "1";
|
|
607
|
+
process.env.GSD_MILESTONE_LOCK = "M002";
|
|
608
|
+
|
|
609
|
+
const ready = await bootstrapAutoSession(
|
|
610
|
+
s,
|
|
611
|
+
makeCtx(notifications) as any,
|
|
612
|
+
{
|
|
613
|
+
getThinkingLevel: () => "medium",
|
|
614
|
+
getActiveTools: () => [],
|
|
615
|
+
events: { emit: () => {} },
|
|
616
|
+
} as any,
|
|
617
|
+
base,
|
|
618
|
+
false,
|
|
619
|
+
false,
|
|
620
|
+
{
|
|
621
|
+
shouldUseWorktreeIsolation: () => false,
|
|
622
|
+
registerSigtermHandler: () => {},
|
|
623
|
+
registerAutoWorkerForSession: () => {},
|
|
624
|
+
lockBase: () => base,
|
|
625
|
+
buildLifecycle: () => ({
|
|
626
|
+
adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
|
|
627
|
+
s.basePath = sessionBase;
|
|
628
|
+
if (originalBase !== undefined) {
|
|
629
|
+
s.originalBasePath = originalBase;
|
|
630
|
+
} else if (!s.originalBasePath) {
|
|
631
|
+
s.originalBasePath = sessionBase;
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
enterMilestone: (mid: string) => {
|
|
635
|
+
enterCalls.push(mid);
|
|
636
|
+
return { ok: true, mode: "none", path: base };
|
|
637
|
+
},
|
|
638
|
+
adoptStrandedMilestone: (
|
|
639
|
+
milestoneId: string,
|
|
640
|
+
sessionBase: string,
|
|
641
|
+
_ctx: unknown,
|
|
642
|
+
opts: { mode: "worktree" | "branch" },
|
|
643
|
+
) => {
|
|
644
|
+
adoptCalls.push({ milestoneId, mode: opts.mode });
|
|
645
|
+
s.basePath = sessionBase;
|
|
646
|
+
s.originalBasePath = sessionBase;
|
|
647
|
+
s.strandedRecoveryIsolationMode = opts.mode;
|
|
648
|
+
return { ok: true, mode: opts.mode, path: sessionBase };
|
|
649
|
+
},
|
|
650
|
+
adoptOrphanWorktree: <T extends { merged: boolean }>(
|
|
651
|
+
_mid: string,
|
|
652
|
+
_base: string,
|
|
653
|
+
run: () => T,
|
|
654
|
+
): T => run(),
|
|
655
|
+
}) as any,
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
classification: "none",
|
|
659
|
+
lock: null,
|
|
660
|
+
pausedSession: null,
|
|
661
|
+
state: null,
|
|
662
|
+
recovery: null,
|
|
663
|
+
recoveryPrompt: null,
|
|
664
|
+
recoveryToolCallCount: 0,
|
|
665
|
+
artifactSatisfied: false,
|
|
666
|
+
hasResumableDiskState: false,
|
|
667
|
+
isBootstrapCrash: false,
|
|
668
|
+
},
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
const messages = notifications.map((entry) => entry.message).join("\n");
|
|
672
|
+
assert.equal(ready, true);
|
|
673
|
+
// Must not adopt M001 (the sibling stranded action) — the locked
|
|
674
|
+
// worker has no stranded action of its own, so adoption should not
|
|
675
|
+
// run at all. enterMilestone for M002 is also gated off by
|
|
676
|
+
// isolation=none with no stranded recoveryMode (#742 regression).
|
|
677
|
+
assert.deepEqual(adoptCalls, []);
|
|
678
|
+
assert.equal(s.currentMilestoneId, "M002");
|
|
679
|
+
assert.doesNotMatch(messages, /Resuming saved milestone work for M001/);
|
|
680
|
+
assert.doesNotMatch(messages, /blocks auto-mode before M002/);
|
|
681
|
+
} finally {
|
|
682
|
+
if (previousLock === undefined) delete process.env.GSD_MILESTONE_LOCK;
|
|
683
|
+
else process.env.GSD_MILESTONE_LOCK = previousLock;
|
|
684
|
+
if (previousWorker === undefined) delete process.env.GSD_PARALLEL_WORKER;
|
|
685
|
+
else process.env.GSD_PARALLEL_WORKER = previousWorker;
|
|
686
|
+
try {
|
|
687
|
+
closeDatabase();
|
|
688
|
+
} catch {}
|
|
689
|
+
process.chdir(previousCwd);
|
|
690
|
+
rmSync(base, { recursive: true, force: true });
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
|
|
458
694
|
test("bootstrap honors explicit solo milestone lock when recovering stranded target worktree", async () => {
|
|
459
695
|
const base = makeRepoWithActiveMismatchAndStrandedTarget();
|
|
460
696
|
const previousCwd = process.cwd();
|
|
@@ -8,7 +8,10 @@ import { join } from "node:path";
|
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
blockModel,
|
|
11
|
+
blockModelUntil,
|
|
12
|
+
clearTemporaryModelBlocksForTest,
|
|
11
13
|
isModelBlocked,
|
|
14
|
+
isModelTemporarilyUnavailable,
|
|
12
15
|
loadBlockedModels,
|
|
13
16
|
} from "../blocked-models.ts";
|
|
14
17
|
|
|
@@ -96,3 +99,19 @@ test("blocked-models: file created under .gsd/runtime/", () => {
|
|
|
96
99
|
rmSync(base, { recursive: true, force: true });
|
|
97
100
|
}
|
|
98
101
|
});
|
|
102
|
+
|
|
103
|
+
test("blocked-models: temporary rate-limit blocks expire without persisting", () => {
|
|
104
|
+
const base = mkBase();
|
|
105
|
+
try {
|
|
106
|
+
clearTemporaryModelBlocksForTest();
|
|
107
|
+
blockModelUntil(base, "openai-codex", "gpt-5.5", Date.now() + 60_000, "session limit");
|
|
108
|
+
assert.equal(isModelTemporarilyUnavailable(base, "openai-codex", "gpt-5.5"), true);
|
|
109
|
+
assert.equal(loadBlockedModels(base).length, 0, "rate-limit windows must not persist as account blocks");
|
|
110
|
+
|
|
111
|
+
blockModelUntil(base, "openai-codex", "gpt-5.5", Date.now() - 1, "expired");
|
|
112
|
+
assert.equal(isModelTemporarilyUnavailable(base, "openai-codex", "gpt-5.5"), false);
|
|
113
|
+
} finally {
|
|
114
|
+
clearTemporaryModelBlocksForTest();
|
|
115
|
+
rmSync(base, { recursive: true, force: true });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getUatBrowserToolSupportError,
|
|
5
|
+
hasUatBrowserToolSurface,
|
|
6
|
+
type UatType,
|
|
7
|
+
} from "../uat-policy.ts";
|
|
8
|
+
|
|
9
|
+
export const BROWSER_AUTOMATION_CONTRACT_TOOLS = {
|
|
10
|
+
piProvider: ["read", "browser_navigate"],
|
|
11
|
+
externalMcpClient: ["read", "mcp__gsd-browser__browser_navigate"],
|
|
12
|
+
externalMcpWildcard: ["read", "mcp__gsd-browser__*"],
|
|
13
|
+
otherBrowserMcp: ["read", "mcp__browser-uat__*"],
|
|
14
|
+
workflowOnly: ["read", "mcp__gsd-workflow__*"],
|
|
15
|
+
withoutBrowser: ["read", "gsd_uat_exec"],
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
export function assertBrowserAutomationContractAvailable(tools: readonly string[]): void {
|
|
19
|
+
assert.equal(hasUatBrowserToolSurface(tools), true, `${tools.join(", ")} should satisfy the Browser Automation Contract`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function assertBrowserAutomationContractMissing(tools: readonly string[] | undefined): void {
|
|
23
|
+
assert.equal(hasUatBrowserToolSurface(tools), false, `${tools?.join(", ") ?? "undefined"} should not satisfy the Browser Automation Contract`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function assertBrowserBackedUatCanDispatch(options: {
|
|
27
|
+
uatType: UatType;
|
|
28
|
+
activeTools: readonly string[] | undefined;
|
|
29
|
+
registeredTools?: readonly string[];
|
|
30
|
+
}): void {
|
|
31
|
+
assert.equal(
|
|
32
|
+
getUatBrowserToolSupportError({
|
|
33
|
+
...options,
|
|
34
|
+
milestoneId: "M001",
|
|
35
|
+
sliceId: "S01",
|
|
36
|
+
}),
|
|
37
|
+
null,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
BROWSER_CONTRACT_TOOL_NAMES,
|
|
6
|
+
BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES,
|
|
7
|
+
hasBrowserContractPrefix,
|
|
8
|
+
isBrowserContractToolName,
|
|
9
|
+
} from "../../shared/browser-contract.ts";
|
|
10
|
+
import { isUatBrowserToolName } from "../uat-policy.ts";
|
|
11
|
+
import { BROWSER_REQUIREMENT_RE, BROWSER_RUNTIME_RE } from "../browser-evidence.ts";
|
|
12
|
+
|
|
13
|
+
// Note: RUN_UAT_BROWSER_TOOL_NAMES and MANAGED_GSD_BROWSER_TOOL_NAMES are
|
|
14
|
+
// reference-equal aliases of BROWSER_CONTRACT_TOOL_NAMES, and the managed
|
|
15
|
+
// adapter's spec table is Record-keyed by BrowserContractToolName — both
|
|
16
|
+
// derivations are pinned by the type system, not by runtime assertions here.
|
|
17
|
+
describe("Browser Automation Contract parity", () => {
|
|
18
|
+
it("every contract name satisfies the UAT browser-tool predicate, bare and MCP-prefixed", () => {
|
|
19
|
+
for (const name of BROWSER_CONTRACT_TOOL_NAMES) {
|
|
20
|
+
assert.equal(isUatBrowserToolName(name), true, name);
|
|
21
|
+
assert.equal(isUatBrowserToolName(`mcp__gsd-browser__${name}`), true, `mcp__gsd-browser__${name}`);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("contract names are canonical browser_* names with no duplicates", () => {
|
|
26
|
+
assert.equal(new Set(BROWSER_CONTRACT_TOOL_NAMES).size, BROWSER_CONTRACT_TOOL_NAMES.length);
|
|
27
|
+
for (const name of BROWSER_CONTRACT_TOOL_NAMES) {
|
|
28
|
+
assert.equal(hasBrowserContractPrefix(name), true, name);
|
|
29
|
+
assert.equal(isBrowserContractToolName(name), true, name);
|
|
30
|
+
}
|
|
31
|
+
assert.equal(isBrowserContractToolName("browser_not_a_real_tool"), false);
|
|
32
|
+
assert.equal(hasBrowserContractPrefix("gsd_uat_exec"), false);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("evidence-signal names stay a subset of the contract and drive the detection regexes", () => {
|
|
36
|
+
for (const name of BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES) {
|
|
37
|
+
assert.equal(isBrowserContractToolName(name), true, name);
|
|
38
|
+
// Identifier-shaped names keep the regex splice in browser-evidence.ts escape-free.
|
|
39
|
+
assert.match(name, /^browser_[a-z_]+$/);
|
|
40
|
+
assert.match(`Verified via ${name} call`, BROWSER_REQUIREMENT_RE);
|
|
41
|
+
assert.match(`Verified via ${name} call`, BROWSER_RUNTIME_RE);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
prepareBrowserDaemonForUat,
|
|
6
|
+
shouldWarmBrowserDaemonForUat,
|
|
7
|
+
} from "../browser-daemon-auto-prep.ts";
|
|
8
|
+
import { commitBrowserEngineResolution } from "../../browser-tools/engine/selection.ts";
|
|
9
|
+
import { resolveGsdBrowserCliAvailability } from "../../shared/gsd-browser-cli.ts";
|
|
10
|
+
|
|
11
|
+
const GSD_BROWSER_ENGINE = { GSD_BROWSER_ENGINE: "gsd-browser" } as const;
|
|
12
|
+
|
|
13
|
+
test("shouldWarmBrowserDaemonForUat skips artifact-driven UAT", () => {
|
|
14
|
+
assert.equal(
|
|
15
|
+
shouldWarmBrowserDaemonForUat({
|
|
16
|
+
uatType: "artifact-driven",
|
|
17
|
+
sessionProvider: "claude-code",
|
|
18
|
+
projectRoot: "/tmp/project",
|
|
19
|
+
}),
|
|
20
|
+
false,
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("shouldWarmBrowserDaemonForUat enables Claude Code browser UAT when gsd-browser is available", (t) => {
|
|
25
|
+
const availability = resolveGsdBrowserCliAvailability();
|
|
26
|
+
if (!availability.available) {
|
|
27
|
+
t.skip("bundled gsd-browser CLI unavailable");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
assert.equal(
|
|
31
|
+
shouldWarmBrowserDaemonForUat({
|
|
32
|
+
uatType: "browser-executable",
|
|
33
|
+
sessionProvider: "claude-code",
|
|
34
|
+
sessionAuthMode: "externalCli",
|
|
35
|
+
projectRoot: "/tmp/project",
|
|
36
|
+
env: GSD_BROWSER_ENGINE,
|
|
37
|
+
}),
|
|
38
|
+
true,
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("shouldWarmBrowserDaemonForUat enables warm-up for Claude Code oauth/apiKey when engine is gsd-browser", (t) => {
|
|
43
|
+
const availability = resolveGsdBrowserCliAvailability();
|
|
44
|
+
if (!availability.available) {
|
|
45
|
+
t.skip("bundled gsd-browser CLI unavailable");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const sessionAuthMode of ["oauth", "apiKey"] as const) {
|
|
49
|
+
assert.equal(
|
|
50
|
+
shouldWarmBrowserDaemonForUat({
|
|
51
|
+
uatType: "browser-executable",
|
|
52
|
+
sessionProvider: "claude-code",
|
|
53
|
+
sessionAuthMode,
|
|
54
|
+
sessionBaseUrl: "https://api.anthropic.com",
|
|
55
|
+
projectRoot: "/tmp/project",
|
|
56
|
+
env: GSD_BROWSER_ENGINE,
|
|
57
|
+
}),
|
|
58
|
+
true,
|
|
59
|
+
`expected warm-up for sessionAuthMode=${sessionAuthMode}`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("shouldWarmBrowserDaemonForUat skips legacy Playwright engine for Claude Code", () => {
|
|
65
|
+
assert.equal(
|
|
66
|
+
shouldWarmBrowserDaemonForUat({
|
|
67
|
+
uatType: "browser-executable",
|
|
68
|
+
sessionProvider: "claude-code",
|
|
69
|
+
sessionAuthMode: "oauth",
|
|
70
|
+
projectRoot: "/tmp/project",
|
|
71
|
+
env: { GSD_BROWSER_ENGINE: "legacy" },
|
|
72
|
+
}),
|
|
73
|
+
false,
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("shouldWarmBrowserDaemonForUat uses session-committed ambient engine for non-Claude providers", () => {
|
|
78
|
+
const projectRoot = "/tmp/ambient-engine-project";
|
|
79
|
+
commitBrowserEngineResolution(projectRoot, {
|
|
80
|
+
engine: "legacy",
|
|
81
|
+
source: "probe",
|
|
82
|
+
reason: "gsd-browser daemon connect failed (test); using legacy Playwright",
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
assert.equal(
|
|
86
|
+
shouldWarmBrowserDaemonForUat({
|
|
87
|
+
uatType: "browser-executable",
|
|
88
|
+
sessionProvider: "openai",
|
|
89
|
+
projectRoot,
|
|
90
|
+
}),
|
|
91
|
+
false,
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("shouldWarmBrowserDaemonForUat skips when browser MCP is disabled", () => {
|
|
96
|
+
assert.equal(
|
|
97
|
+
shouldWarmBrowserDaemonForUat({
|
|
98
|
+
uatType: "browser-executable",
|
|
99
|
+
sessionProvider: "claude-code",
|
|
100
|
+
projectRoot: "/tmp/project",
|
|
101
|
+
env: { GSD_BROWSER_MCP_ENABLED: "0" },
|
|
102
|
+
}),
|
|
103
|
+
false,
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("shouldWarmBrowserDaemonForUat skips when warm-up is disabled", () => {
|
|
108
|
+
assert.equal(
|
|
109
|
+
shouldWarmBrowserDaemonForUat({
|
|
110
|
+
uatType: "browser-executable",
|
|
111
|
+
sessionProvider: "claude-code",
|
|
112
|
+
projectRoot: "/tmp/project",
|
|
113
|
+
env: { GSD_BROWSER_WARMUP: "0" },
|
|
114
|
+
}),
|
|
115
|
+
false,
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("prepareBrowserDaemonForUat returns null when warm-up is not required", () => {
|
|
120
|
+
assert.equal(
|
|
121
|
+
prepareBrowserDaemonForUat({
|
|
122
|
+
uatType: "artifact-driven",
|
|
123
|
+
sessionProvider: "claude-code",
|
|
124
|
+
sessionAuthMode: "externalCli",
|
|
125
|
+
projectRoot: "/tmp/example-project",
|
|
126
|
+
}),
|
|
127
|
+
null,
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("prepareBrowserDaemonForUat returns actionable error when daemon start fails", () => {
|
|
132
|
+
const error = prepareBrowserDaemonForUat({
|
|
133
|
+
uatType: "browser-executable",
|
|
134
|
+
sessionProvider: "claude-code",
|
|
135
|
+
sessionAuthMode: "externalCli",
|
|
136
|
+
projectRoot: "/tmp/example-project",
|
|
137
|
+
env: {
|
|
138
|
+
...GSD_BROWSER_ENGINE,
|
|
139
|
+
GSD_BROWSER_MCP_COMMAND: "/definitely/missing/gsd-browser",
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
assert.match(error ?? "", /gsd-browser daemon failed to start/i);
|
|
144
|
+
});
|
|
@@ -5,7 +5,7 @@ import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSy
|
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
|
|
8
|
-
import { checkoutBranchWithStashGuard } from "../
|
|
8
|
+
import { checkoutBranchWithStashGuard } from "../worktree-git-recovery.ts";
|
|
9
9
|
|
|
10
10
|
function git(args: string[], cwd: string): string {
|
|
11
11
|
return execFileSync("git", args, {
|
|
@@ -159,4 +159,69 @@ describe("checkoutBranchWithStashGuard", () => {
|
|
|
159
159
|
const stashList = git(["stash", "list"], repo).trim();
|
|
160
160
|
assert.equal(stashList, "");
|
|
161
161
|
});
|
|
162
|
+
|
|
163
|
+
test("auto-resolves combined non-.gsd untracked collision and .gsd index conflict", (t) => {
|
|
164
|
+
// Regression for: gate checked nonGsdUnmerged.length === 0 but ignored
|
|
165
|
+
// .gsd/ index conflicts, so a failed pop with both an untracked non-.gsd/
|
|
166
|
+
// collision AND a .gsd/ tracked conflict would drop the stash while leaving
|
|
167
|
+
// .gsd/ index unmerged entries unresolved.
|
|
168
|
+
const repo = createRepo(t);
|
|
169
|
+
// Add .gsd/DECISIONS.md to base so both branches diverge from it
|
|
170
|
+
writeFileSync(join(repo, ".gsd", "DECISIONS.md"), "base\n");
|
|
171
|
+
git(["add", ".gsd/DECISIONS.md"], repo);
|
|
172
|
+
git(["commit", "-m", "add decisions"], repo);
|
|
173
|
+
|
|
174
|
+
git(["checkout", "-b", "milestone/M003"], repo);
|
|
175
|
+
// Branch has its own version of DECISIONS.md (non-JSONL .gsd/ file)
|
|
176
|
+
writeFileSync(join(repo, ".gsd", "DECISIONS.md"), "target-version\n");
|
|
177
|
+
mkdirSync(join(repo, ".harness"), { recursive: true });
|
|
178
|
+
writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"dark\"}\n");
|
|
179
|
+
git(["add", ".gsd/DECISIONS.md", ".harness/settings.json"], repo);
|
|
180
|
+
git(["commit", "-m", "branch state"], repo);
|
|
181
|
+
git(["checkout", "main"], repo);
|
|
182
|
+
|
|
183
|
+
// On main: tracked .gsd/ change (creates unmerged index entry on pop) +
|
|
184
|
+
// untracked harness file (triggers "already exists, no checkout").
|
|
185
|
+
writeFileSync(join(repo, ".gsd", "DECISIONS.md"), "local-version\n");
|
|
186
|
+
mkdirSync(join(repo, ".harness"), { recursive: true });
|
|
187
|
+
writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"light\"}\n");
|
|
188
|
+
|
|
189
|
+
checkoutBranchWithStashGuard(repo, "milestone/M003", "test-combined-gsd-conflict");
|
|
190
|
+
|
|
191
|
+
const branch = git(["branch", "--show-current"], repo).trim();
|
|
192
|
+
assert.equal(branch, "milestone/M003");
|
|
193
|
+
const decisions = readFileSync(join(repo, ".gsd", "DECISIONS.md"), "utf8");
|
|
194
|
+
assert.equal(decisions, "target-version\n");
|
|
195
|
+
assert.doesNotMatch(decisions, /<<<<<<<|=======|>>>>>>>/);
|
|
196
|
+
const status = git(["status", "--porcelain"], repo).trim();
|
|
197
|
+
assert.equal(status, "");
|
|
198
|
+
const stashList = git(["stash", "list"], repo).trim();
|
|
199
|
+
assert.equal(stashList, "");
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("auto-resolves non-.gsd untracked restore collisions (e.g. harness config outside .gsd/)", (t) => {
|
|
203
|
+
const repo = createRepo(t);
|
|
204
|
+
// Target branch has a harness config file committed; source (main) has it untracked.
|
|
205
|
+
// Use a path not affected by global gitignore rules (unlike .claude/settings.local.json).
|
|
206
|
+
git(["checkout", "-b", "milestone/M001"], repo);
|
|
207
|
+
mkdirSync(join(repo, ".harness"), { recursive: true });
|
|
208
|
+
writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"dark\"}\n");
|
|
209
|
+
git(["add", ".harness/settings.json"], repo);
|
|
210
|
+
git(["commit", "-m", "add harness settings"], repo);
|
|
211
|
+
git(["checkout", "main"], repo);
|
|
212
|
+
|
|
213
|
+
mkdirSync(join(repo, ".harness"), { recursive: true });
|
|
214
|
+
writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"light\"}\n");
|
|
215
|
+
|
|
216
|
+
checkoutBranchWithStashGuard(repo, "milestone/M001", "test-non-gsd-untracked-collision");
|
|
217
|
+
|
|
218
|
+
const branch = git(["branch", "--show-current"], repo).trim();
|
|
219
|
+
assert.equal(branch, "milestone/M001");
|
|
220
|
+
const wtContent = readFileSync(join(repo, ".harness", "settings.json"), "utf8");
|
|
221
|
+
assert.equal(wtContent, "{\"theme\":\"dark\"}\n");
|
|
222
|
+
const status = git(["status", "--porcelain"], repo).trim();
|
|
223
|
+
assert.equal(status, "");
|
|
224
|
+
const stashList = git(["stash", "list"], repo).trim();
|
|
225
|
+
assert.equal(stashList, "");
|
|
226
|
+
});
|
|
162
227
|
});
|
|
@@ -74,6 +74,28 @@ describe("clear stale pending auto-start (#3667)", () => {
|
|
|
74
74
|
);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
+
test("guided-flow recovers a finished-but-unconsumed discussion instead of dead-ending", () => {
|
|
78
|
+
// CONTEXT exists + no live turn means the discussion completed but the
|
|
79
|
+
// agent_end handoff never consumed the entry (e.g. an external-engine
|
|
80
|
+
// post-hoc gate re-arm wiped the depth verification after the save).
|
|
81
|
+
// Without recovery, every /gsd prints "Discussion already in progress"
|
|
82
|
+
// forever: the stale heuristic requires CONTEXT to be absent and
|
|
83
|
+
// discussPlanComplete requires a ROADMAP that planning never produced.
|
|
84
|
+
const source = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
|
|
85
|
+
assert.ok(
|
|
86
|
+
source.includes("milestoneHasContext && !isAgentTurnInFlight(ctx)"),
|
|
87
|
+
"pending-entry guard must have a recovery branch for CONTEXT-present, no-turn-in-flight entries",
|
|
88
|
+
);
|
|
89
|
+
assert.ok(
|
|
90
|
+
source.includes("extractDepthVerificationMilestoneId(pendingGateId) === entry.milestoneId"),
|
|
91
|
+
"recovery must only clear a pending gate belonging to the entry's own milestone",
|
|
92
|
+
);
|
|
93
|
+
assert.ok(
|
|
94
|
+
source.includes("if (checkAutoStartAfterDiscuss(basePath)) return;"),
|
|
95
|
+
"recovery must re-run the discuss→auto handoff after clearing the stale gate",
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
77
99
|
test("guided-flow does not treat a live discuss turn as a stale pending entry", () => {
|
|
78
100
|
const source = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
|
|
79
101
|
assert.ok(
|
|
@@ -472,18 +472,19 @@ test("auto-dispatch needs-attention pause message references /gsd verdict", asyn
|
|
|
472
472
|
}
|
|
473
473
|
});
|
|
474
474
|
|
|
475
|
-
test("
|
|
475
|
+
test("guidance.ts needs-remediation blocker messages reference /gsd verdict", async () => {
|
|
476
476
|
// We don't need to invoke deriveState — just assert the substring is in the
|
|
477
|
-
// source. The blocker strings are constructed
|
|
478
|
-
// verbatim, so a static check is sufficient and avoids
|
|
479
|
-
|
|
480
|
-
|
|
477
|
+
// source. The blocker strings are constructed in the guidance catalog and
|
|
478
|
+
// shipped to the user verbatim, so a static check is sufficient and avoids
|
|
479
|
+
// fragile DB setup.
|
|
480
|
+
const guidanceSource = readFileSync(
|
|
481
|
+
new URL("../guidance.ts", import.meta.url).pathname,
|
|
481
482
|
"utf-8",
|
|
482
483
|
);
|
|
483
|
-
const occurrences =
|
|
484
|
+
const occurrences = guidanceSource.match(/`\/gsd verdict /g) ?? [];
|
|
484
485
|
assert.ok(
|
|
485
486
|
occurrences.length >= 2,
|
|
486
|
-
`expected at least 2 references to /gsd verdict in
|
|
487
|
+
`expected at least 2 references to /gsd verdict in guidance.ts blockers, found ${occurrences.length}`,
|
|
487
488
|
);
|
|
488
489
|
});
|
|
489
490
|
|