@opengsd/gsd-pi 1.2.0-dev.84c56d87 → 1.2.0-dev.8e6112e9
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-model-override.d.ts +15 -0
- package/dist/cli-model-override.js +21 -0
- package/dist/cli.js +1 -18
- package/dist/headless-events.js +7 -5
- package/dist/loader.js +6 -4
- package/dist/mcp-server.js +2 -1
- package/dist/register-agent-bundles.d.ts +11 -2
- package/dist/register-agent-bundles.js +18 -4
- package/dist/resource-loader.d.ts +10 -5
- package/dist/resource-loader.js +121 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/ask-user-questions.js +3 -2
- 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/claude-code-cli/stream-adapter.js +447 -215
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
- 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 +120 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
- package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
- package/dist/resources/extensions/gsd/auto/loop.js +7 -1
- package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +174 -69
- package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
- package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
- package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
- package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
- package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
- package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
- package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
- package/dist/resources/extensions/gsd/auto-start.js +35 -15
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
- package/dist/resources/extensions/gsd/auto-verification.js +23 -30
- package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
- package/dist/resources/extensions/gsd/auto.js +52 -2
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +60 -13
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +145 -50
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/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/commands-mcp-status.js +2 -2
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
- package/dist/resources/extensions/gsd/consent-question.js +353 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
- package/dist/resources/extensions/gsd/db/engine.js +5 -3
- package/dist/resources/extensions/gsd/db/queries.js +56 -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 +256 -125
- package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +11 -8
- package/dist/resources/extensions/gsd/guidance.js +60 -0
- package/dist/resources/extensions/gsd/guided-flow.js +93 -4
- package/dist/resources/extensions/gsd/health-widget.js +87 -28
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
- package/dist/resources/extensions/gsd/memory-relations.js +1 -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/milestone-settlement.js +2 -2
- package/dist/resources/extensions/gsd/notifications.js +12 -7
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/preferences-models.js +2 -2
- package/dist/resources/extensions/gsd/projection-flush.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -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/prompts/workflow-start.md +2 -1
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -1
- package/dist/resources/extensions/gsd/skill-activation.js +3 -6
- package/dist/resources/extensions/gsd/state.js +11 -2
- 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 +83 -31
- 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 +65 -2
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
- package/dist/resources/extensions/gsd/uat-policy.js +40 -15
- package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
- package/dist/resources/extensions/gsd/unit-registry.js +34 -4
- 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/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-mcp-auto-prep.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
- package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
- package/dist/resources/extensions/gsd/worktree.js +8 -1
- package/dist/resources/extensions/mcp-client/manager.js +6 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +45 -3
- 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/skill-structure.md +1 -0
- package/dist/runtime-checks.d.ts +10 -0
- package/dist/runtime-checks.js +27 -0
- 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 +6 -6
- 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 +6 -6
- 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/node_modules/postcss/lib/container.js +26 -18
- package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
- package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
- package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
- package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
- package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
- package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
- package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
- package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
- package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
- package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
- package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
- package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
- package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
- package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
- package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
- package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
- package/dist/web/standalone/node_modules/postcss/package.json +48 -48
- package/package.json +3 -3
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +6 -4
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -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 +55 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.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-mode.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.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/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.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/README.md +12 -3
- package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
- package/packages/mcp-server/dist/cli-runner.js +137 -0
- package/packages/mcp-server/dist/cli-runner.js.map +1 -0
- package/packages/mcp-server/dist/cli.js +2 -53
- 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/pid-registry.d.ts +46 -0
- package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
- package/packages/mcp-server/dist/pid-registry.js +452 -0
- package/packages/mcp-server/dist/pid-registry.js.map +1 -0
- package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
- package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
- package/packages/mcp-server/dist/probe-mode.js +10 -0
- package/packages/mcp-server/dist/probe-mode.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/stdio-watchdog.d.ts +8 -0
- package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
- package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
- package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +161 -81
- 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/agent-loop.js +43 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +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 +419 -221
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +460 -261
- 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/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.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/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
- package/packages/pi-coding-agent/dist/theme/theme.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/index.d.ts +1 -1
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +1 -1
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
- package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal-image.js +54 -2
- package/packages/pi-tui/dist/terminal-image.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +8 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +63 -18
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +110 -36
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +45 -17
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/ask-user-questions.ts +7 -2
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +309 -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 +168 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
- package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
- package/src/resources/extensions/gsd/auto/loop.ts +7 -1
- package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +193 -71
- package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
- package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
- package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
- package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
- package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
- package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
- package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
- package/src/resources/extensions/gsd/auto-start.ts +36 -18
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
- package/src/resources/extensions/gsd/auto-verification.ts +26 -28
- package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
- package/src/resources/extensions/gsd/auto.ts +64 -2
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +79 -12
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +163 -55
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/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/commands-mcp-status.ts +2 -2
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
- package/src/resources/extensions/gsd/consent-question.ts +431 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
- package/src/resources/extensions/gsd/db/engine.ts +5 -3
- package/src/resources/extensions/gsd/db/queries.ts +66 -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 +267 -142
- package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +13 -10
- package/src/resources/extensions/gsd/guidance.ts +78 -0
- package/src/resources/extensions/gsd/guided-flow.ts +145 -24
- package/src/resources/extensions/gsd/health-widget.ts +91 -27
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
- package/src/resources/extensions/gsd/memory-relations.ts +1 -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/milestone-settlement.ts +2 -2
- package/src/resources/extensions/gsd/notifications.ts +13 -6
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/preferences-models.ts +2 -1
- package/src/resources/extensions/gsd/projection-flush.ts +20 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +9 -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/prompts/workflow-start.md +2 -1
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/session-lock.ts +1 -1
- package/src/resources/extensions/gsd/skill-activation.ts +3 -6
- package/src/resources/extensions/gsd/state.ts +12 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +273 -37
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
- 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/auto-unit-closeout.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
- 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 +12 -11
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
- 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 +328 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
- 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/engine-interfaces-contract.test.ts +117 -91
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -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/gsd-command-home.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
- 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/parallel-skill-prompt-integration.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +45 -2
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
- 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 +88 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
- 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 +126 -19
- 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 +90 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
- package/src/resources/extensions/gsd/uat-policy.ts +60 -15
- package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
- package/src/resources/extensions/gsd/unit-registry.ts +34 -4
- 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/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-mcp-auto-prep.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
- package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
- package/src/resources/extensions/gsd/worktree.ts +7 -1
- package/src/resources/extensions/mcp-client/manager.ts +7 -1
- package/src/resources/extensions/shared/gsd-browser-cli.ts +54 -3
- 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/skill-structure.md +1 -0
- 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/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_ssgManifest.js +0 -0
|
@@ -6,7 +6,8 @@ import { tmpdir } from "node:os";
|
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
8
|
|
|
9
|
-
import { runDispatch
|
|
9
|
+
import { runDispatch } from "../auto/dispatch.ts";
|
|
10
|
+
import { runPreDispatch } from "../auto/pre-dispatch.ts";
|
|
10
11
|
import { AutoSession } from "../auto/session.ts";
|
|
11
12
|
import { resolveUnitSupervisionTimeouts } from "../auto-timers.ts";
|
|
12
13
|
import { bootstrapAutoSession } from "../auto-start.ts";
|
|
@@ -15,7 +16,7 @@ import { resolveDispatch, setResearchProjectPromptBuilderForTest } from "../auto
|
|
|
15
16
|
import { resolveExpectedArtifactPath, verifyExpectedArtifact, writeBlockerPlaceholder } from "../auto-recovery.ts";
|
|
16
17
|
import { finalizeProjectResearchTimeout } from "../project-research-policy.ts";
|
|
17
18
|
import { resetRegistry } from "../rule-registry.ts";
|
|
18
|
-
import { approvalGateIdForUnit, isAwaitingUserInput, isExplicitApprovalResponse,
|
|
19
|
+
import { approvalGateIdForUnit, isAwaitingUserInput, isExplicitApprovalResponse, shouldPauseForQuestion } from "../consent-question.ts";
|
|
19
20
|
import {
|
|
20
21
|
clearPendingAutoStart,
|
|
21
22
|
checkDeepProjectSetupAfterTurn,
|
|
@@ -1402,7 +1403,7 @@ test("deep project setup: user-quoted remote question failure does not pause aut
|
|
|
1402
1403
|
];
|
|
1403
1404
|
|
|
1404
1405
|
assert.equal(isAwaitingUserInput(messages), false);
|
|
1405
|
-
assert.equal(
|
|
1406
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1406
1407
|
});
|
|
1407
1408
|
|
|
1408
1409
|
test("deep project setup: plain-text approval wait is treated as waiting for user input", () => {
|
|
@@ -1426,7 +1427,7 @@ test("deep project setup: opening interview question does not trigger approval a
|
|
|
1426
1427
|
];
|
|
1427
1428
|
|
|
1428
1429
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1429
|
-
assert.equal(
|
|
1430
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1430
1431
|
});
|
|
1431
1432
|
|
|
1432
1433
|
test("deep project setup: grounding interview question with requirements context does not trigger approval abort", () => {
|
|
@@ -1441,7 +1442,7 @@ test("deep project setup: grounding interview question with requirements context
|
|
|
1441
1442
|
];
|
|
1442
1443
|
|
|
1443
1444
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1444
|
-
assert.equal(
|
|
1445
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1445
1446
|
});
|
|
1446
1447
|
|
|
1447
1448
|
test("deep project setup: persistence and anti-goals interview prompt does not trigger approval abort", () => {
|
|
@@ -1460,7 +1461,7 @@ test("deep project setup: persistence and anti-goals interview prompt does not t
|
|
|
1460
1461
|
];
|
|
1461
1462
|
|
|
1462
1463
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1463
|
-
assert.equal(
|
|
1464
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1464
1465
|
});
|
|
1465
1466
|
|
|
1466
1467
|
test("deep project setup: discovery questions before writing PROJECT do not trigger approval abort", () => {
|
|
@@ -1479,7 +1480,7 @@ test("deep project setup: discovery questions before writing PROJECT do not trig
|
|
|
1479
1480
|
];
|
|
1480
1481
|
|
|
1481
1482
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1482
|
-
assert.equal(
|
|
1483
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1483
1484
|
});
|
|
1484
1485
|
|
|
1485
1486
|
test("deep project setup: discovery question mentioning write intent does not trigger approval abort", () => {
|
|
@@ -1491,7 +1492,7 @@ test("deep project setup: discovery question mentioning write intent does not tr
|
|
|
1491
1492
|
];
|
|
1492
1493
|
|
|
1493
1494
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1494
|
-
assert.equal(
|
|
1495
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1495
1496
|
});
|
|
1496
1497
|
|
|
1497
1498
|
test("deep project setup: scope discovery question mentioning add does not trigger approval abort", () => {
|
|
@@ -1503,7 +1504,7 @@ test("deep project setup: scope discovery question mentioning add does not trigg
|
|
|
1503
1504
|
];
|
|
1504
1505
|
|
|
1505
1506
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1506
|
-
assert.equal(
|
|
1507
|
+
assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
|
|
1507
1508
|
});
|
|
1508
1509
|
|
|
1509
1510
|
test("deep project setup: requirements preview question from screenshot is treated as waiting", () => {
|
|
@@ -1523,12 +1524,12 @@ test("deep project setup: requirements preview question from screenshot is treat
|
|
|
1523
1524
|
];
|
|
1524
1525
|
|
|
1525
1526
|
assert.equal(isAwaitingUserInput(messages), true);
|
|
1526
|
-
assert.equal(
|
|
1527
|
+
assert.equal(shouldPauseForQuestion("discuss-requirements", messages), true);
|
|
1527
1528
|
});
|
|
1528
1529
|
|
|
1529
1530
|
test("deep project setup: research decision question triggers approval boundary pause", () => {
|
|
1530
1531
|
assert.equal(
|
|
1531
|
-
|
|
1532
|
+
shouldPauseForQuestion("research-decision", [
|
|
1532
1533
|
{
|
|
1533
1534
|
role: "assistant",
|
|
1534
1535
|
content: "Run domain research now? (y/n)",
|
|
@@ -569,6 +569,42 @@ describe('derive-state-helpers', () => {
|
|
|
569
569
|
}
|
|
570
570
|
});
|
|
571
571
|
|
|
572
|
+
// ─── Batch slice query: multi-milestone slices loaded in one query ─────
|
|
573
|
+
test('buildRegistryAndFindActive: batched slice query preserves ordering across milestones', async () => {
|
|
574
|
+
const base = createFixtureBase();
|
|
575
|
+
try {
|
|
576
|
+
// M001 is complete so the loop advances past it.
|
|
577
|
+
writeFile(base, 'milestones/M001/M001-ROADMAP.md', ROADMAP_CONTENT);
|
|
578
|
+
writeFile(base, 'milestones/M001/M001-SUMMARY.md', '# M001 Summary\n\nDone.');
|
|
579
|
+
// M002 is a queued shell milestone with no context and no slices — should be deferred.
|
|
580
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M002'), { recursive: true });
|
|
581
|
+
// M003 is the real active milestone with slices in non-trivial sequence order.
|
|
582
|
+
writeFile(base, 'milestones/M003/M003-CONTEXT.md', '# M003: Real\n\nReal milestone.');
|
|
583
|
+
|
|
584
|
+
openDatabase(':memory:');
|
|
585
|
+
insertMilestone({ id: 'M001', title: 'Complete', status: 'complete' });
|
|
586
|
+
insertMilestone({ id: 'M002', title: 'Shell', status: 'queued' });
|
|
587
|
+
insertMilestone({ id: 'M003', title: 'Real', status: 'active' });
|
|
588
|
+
// Slices intentionally inserted with out-of-order sequences to prove ordering.
|
|
589
|
+
insertSlice({ id: 'S01', milestoneId: 'M001', title: 'M1 Second', status: 'complete', risk: 'low', depends: [], sequence: 2 });
|
|
590
|
+
insertSlice({ id: 'S02', milestoneId: 'M001', title: 'M1 First', status: 'complete', risk: 'low', depends: [], sequence: 1 });
|
|
591
|
+
insertSlice({ id: 'S03', milestoneId: 'M003', title: 'M3 Second', status: 'active', risk: 'low', depends: [], sequence: 5 });
|
|
592
|
+
insertSlice({ id: 'S04', milestoneId: 'M003', title: 'M3 First', status: 'active', risk: 'low', depends: [], sequence: 3 });
|
|
593
|
+
|
|
594
|
+
invalidateStateCache();
|
|
595
|
+
const state = await deriveStateFromDb(base);
|
|
596
|
+
|
|
597
|
+
assert.equal(state.activeMilestone?.id, 'M003', 'batched: M003 is active after complete M001 and shell M002');
|
|
598
|
+
assert.equal(state.activeSlice?.id, 'S04', 'batched: first slice by sequence is active');
|
|
599
|
+
assert.equal(state.registry.find(e => e.id === 'M001')?.status, 'complete', 'batched: M001 complete');
|
|
600
|
+
assert.equal(state.registry.find(e => e.id === 'M002')?.status, 'pending', 'batched: shell M002 deferred to pending');
|
|
601
|
+
assert.equal(state.registry.find(e => e.id === 'M003')?.status, 'active', 'batched: M003 active');
|
|
602
|
+
} finally {
|
|
603
|
+
closeDatabase();
|
|
604
|
+
cleanup(base);
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
|
|
572
608
|
// ─── Deferred queued shell: shell milestone deferred, real one promoted ──
|
|
573
609
|
test('buildRegistryAndFindActive: queued shell deferred, later real milestone becomes active (#3470)', async () => {
|
|
574
610
|
const base = createFixtureBase();
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the destructive-command confirmation escape hatch.
|
|
3
|
+
*
|
|
4
|
+
* Regression target: the destructive-guard hard block had no confirmation
|
|
5
|
+
* path. Re-issuing a force push after confirming via ask_user_questions hit
|
|
6
|
+
* the identical HARD BLOCK every time — an unwinnable loop. These tests pin
|
|
7
|
+
* the block → confirm → allow-once flow and its safety invariants.
|
|
8
|
+
*
|
|
9
|
+
* Two layers of coverage:
|
|
10
|
+
* 1. Unit — the confirmation-token module in isolation (block/confirm/consume
|
|
11
|
+
* and every safety invariant).
|
|
12
|
+
* 2. Integration — the real registerHooks() bash tool_call guard +
|
|
13
|
+
* ask_user_questions tool_result handler driven end-to-end, proving the
|
|
14
|
+
* loop is escapable through the actual wiring, not just the helper module.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import test from "node:test";
|
|
18
|
+
import assert from "node:assert/strict";
|
|
19
|
+
|
|
20
|
+
import { registerHooks } from "../bootstrap/register-hooks.ts";
|
|
21
|
+
import { classifyCommand } from "../safety/destructive-guard.ts";
|
|
22
|
+
import {
|
|
23
|
+
DESTRUCTIVE_CONFIRM_GATE_MARKER,
|
|
24
|
+
confirmDestructiveCommand,
|
|
25
|
+
consumeDestructiveConfirmation,
|
|
26
|
+
isDestructiveConfirmGateId,
|
|
27
|
+
normalizeDestructiveCommand,
|
|
28
|
+
peekPendingDestructiveCommand,
|
|
29
|
+
requestDestructiveConfirmation,
|
|
30
|
+
resetDestructiveConfirmation,
|
|
31
|
+
} from "../safety/destructive-confirmation.ts";
|
|
32
|
+
|
|
33
|
+
const BASE = "/tmp/gsd-destructive-confirm-test";
|
|
34
|
+
const FORCE_PUSH = "git push --force-with-lease origin feature/PO-566-chart-supply-chain";
|
|
35
|
+
|
|
36
|
+
function blocked(command: string, basePath: string): boolean {
|
|
37
|
+
// Mirror the guard's decision: a classified-destructive command is blocked
|
|
38
|
+
// unless a matching confirmation token is consumed in this same check.
|
|
39
|
+
if (!classifyCommand(command).destructive) return false;
|
|
40
|
+
return !consumeDestructiveConfirmation(command, basePath);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
test("repro: destructive command loops forever without confirmation", () => {
|
|
44
|
+
resetDestructiveConfirmation(BASE);
|
|
45
|
+
// Every attempt blocks — this is the bug the escape hatch fixes.
|
|
46
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "first attempt blocks");
|
|
47
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "retry still blocks");
|
|
48
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "and again — unwinnable loop");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("block then confirm then retry allows the exact command once", () => {
|
|
52
|
+
resetDestructiveConfirmation(BASE);
|
|
53
|
+
|
|
54
|
+
// 1. Guard blocks and records the pending command.
|
|
55
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "initial attempt blocks");
|
|
56
|
+
requestDestructiveConfirmation(FORCE_PUSH, BASE);
|
|
57
|
+
assert.equal(peekPendingDestructiveCommand(BASE), normalizeDestructiveCommand(FORCE_PUSH));
|
|
58
|
+
|
|
59
|
+
// 2. User confirms via ask_user_questions affirmative answer.
|
|
60
|
+
const confirmed = confirmDestructiveCommand(BASE);
|
|
61
|
+
assert.equal(confirmed, normalizeDestructiveCommand(FORCE_PUSH));
|
|
62
|
+
|
|
63
|
+
// 3. Retry in the same turn now passes.
|
|
64
|
+
assert.equal(blocked(FORCE_PUSH, BASE), false, "confirmed command passes once");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("confirmation is one-shot — a second destructive command re-blocks", () => {
|
|
68
|
+
resetDestructiveConfirmation(BASE);
|
|
69
|
+
|
|
70
|
+
requestDestructiveConfirmation(FORCE_PUSH, BASE);
|
|
71
|
+
confirmDestructiveCommand(BASE);
|
|
72
|
+
assert.equal(blocked(FORCE_PUSH, BASE), false, "first run consumes the token");
|
|
73
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "identical second run re-blocks");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("confirmation is command-bound — a different command is not approved", () => {
|
|
77
|
+
resetDestructiveConfirmation(BASE);
|
|
78
|
+
|
|
79
|
+
requestDestructiveConfirmation(FORCE_PUSH, BASE);
|
|
80
|
+
confirmDestructiveCommand(BASE);
|
|
81
|
+
|
|
82
|
+
// A different destructive command must not ride the force-push confirmation.
|
|
83
|
+
assert.equal(blocked("rm -rf node_modules", BASE), true, "unrelated destructive cmd re-blocks");
|
|
84
|
+
// The original token is still intact for its exact command.
|
|
85
|
+
assert.equal(blocked(FORCE_PUSH, BASE), false, "original confirmed command still passes once");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("cosmetic whitespace reformatting still matches the confirmed token", () => {
|
|
89
|
+
resetDestructiveConfirmation(BASE);
|
|
90
|
+
|
|
91
|
+
requestDestructiveConfirmation("git push --force origin main", BASE);
|
|
92
|
+
confirmDestructiveCommand(BASE);
|
|
93
|
+
assert.equal(blocked("git push --force origin main", BASE), false, "whitespace-normalized match passes");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("requesting a new confirmation invalidates a stale confirmed token", () => {
|
|
97
|
+
resetDestructiveConfirmation(BASE);
|
|
98
|
+
|
|
99
|
+
requestDestructiveConfirmation(FORCE_PUSH, BASE);
|
|
100
|
+
confirmDestructiveCommand(BASE);
|
|
101
|
+
// New block for a different command before the first was consumed.
|
|
102
|
+
requestDestructiveConfirmation("git reset --hard HEAD~3", BASE);
|
|
103
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "old confirmation no longer valid after new request");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("confirm with nothing pending returns null and approves nothing", () => {
|
|
107
|
+
resetDestructiveConfirmation(BASE);
|
|
108
|
+
assert.equal(confirmDestructiveCommand(BASE), null, "no pending command -> null");
|
|
109
|
+
assert.equal(blocked(FORCE_PUSH, BASE), true, "no spurious approval");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("tokens are isolated per basePath", () => {
|
|
113
|
+
const a = "/tmp/gsd-confirm-ws-a";
|
|
114
|
+
const b = "/tmp/gsd-confirm-ws-b";
|
|
115
|
+
resetDestructiveConfirmation(a);
|
|
116
|
+
resetDestructiveConfirmation(b);
|
|
117
|
+
|
|
118
|
+
requestDestructiveConfirmation(FORCE_PUSH, a);
|
|
119
|
+
confirmDestructiveCommand(a);
|
|
120
|
+
|
|
121
|
+
assert.equal(blocked(FORCE_PUSH, b), true, "workspace B is unaffected by workspace A's confirmation");
|
|
122
|
+
assert.equal(blocked(FORCE_PUSH, a), false, "workspace A still passes once");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("gate id marker detection", () => {
|
|
126
|
+
assert.equal(isDestructiveConfirmGateId(`${DESTRUCTIVE_CONFIRM_GATE_MARKER}_push`), true);
|
|
127
|
+
assert.equal(isDestructiveConfirmGateId("depth_verification_M001"), false);
|
|
128
|
+
assert.equal(isDestructiveConfirmGateId(undefined), false);
|
|
129
|
+
assert.equal(isDestructiveConfirmGateId(123), false);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("non-destructive commands are never gated regardless of token state", () => {
|
|
133
|
+
resetDestructiveConfirmation(BASE);
|
|
134
|
+
assert.equal(blocked("git status", BASE), false);
|
|
135
|
+
assert.equal(blocked("ls -la", BASE), false);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// ─── Integration: real registerHooks() wiring, driven end-to-end ────────────
|
|
139
|
+
// The unit tests above exercise the token module directly. These drive the
|
|
140
|
+
// actual registered bash tool_call guard and ask_user_questions tool_result
|
|
141
|
+
// handler, proving the loop the user hit is escapable through the real hooks —
|
|
142
|
+
// not just the helper. Mirrors the harness in
|
|
143
|
+
// register-hooks-depth-verification.test.ts.
|
|
144
|
+
|
|
145
|
+
type Handler = (event: any, ctx?: any) => Promise<any> | any;
|
|
146
|
+
|
|
147
|
+
function makeHookHarness(): {
|
|
148
|
+
handlers: Map<string, Handler[]>;
|
|
149
|
+
pi: any;
|
|
150
|
+
} {
|
|
151
|
+
const handlers = new Map<string, Handler[]>();
|
|
152
|
+
const pi = {
|
|
153
|
+
on(event: string, handler: Handler) {
|
|
154
|
+
const existing = handlers.get(event) ?? [];
|
|
155
|
+
existing.push(handler);
|
|
156
|
+
handlers.set(event, existing);
|
|
157
|
+
},
|
|
158
|
+
} as any;
|
|
159
|
+
return { handlers, pi };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Run every bash tool_call guard and return the first block result, if any. */
|
|
163
|
+
async function runBashGuard(
|
|
164
|
+
handlers: Map<string, Handler[]>,
|
|
165
|
+
command: string,
|
|
166
|
+
ctx: any,
|
|
167
|
+
): Promise<{ block?: boolean; reason?: string } | undefined> {
|
|
168
|
+
let block: { block?: boolean; reason?: string } | undefined;
|
|
169
|
+
for (const handler of handlers.get("tool_call") ?? []) {
|
|
170
|
+
const result = await handler(
|
|
171
|
+
{ toolCallId: "bash-1", toolName: "bash", input: { command } },
|
|
172
|
+
ctx,
|
|
173
|
+
);
|
|
174
|
+
if (result?.block) block = result;
|
|
175
|
+
}
|
|
176
|
+
return block;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Deliver an affirmative ask_user_questions answer for a destructive gate. */
|
|
180
|
+
async function answerConfirmGate(
|
|
181
|
+
handlers: Map<string, Handler[]>,
|
|
182
|
+
questionId: string,
|
|
183
|
+
ctx: any,
|
|
184
|
+
): Promise<void> {
|
|
185
|
+
const questions = [
|
|
186
|
+
{
|
|
187
|
+
id: questionId,
|
|
188
|
+
question: "Run this destructive command?",
|
|
189
|
+
options: [{ label: "Yes, run it (Recommended)" }, { label: "No, cancel" }],
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
for (const handler of handlers.get("tool_result") ?? []) {
|
|
193
|
+
await handler(
|
|
194
|
+
{
|
|
195
|
+
toolName: "ask_user_questions",
|
|
196
|
+
input: { questions },
|
|
197
|
+
details: {
|
|
198
|
+
response: { answers: { [questionId]: { selected: "Yes, run it (Recommended)" } } },
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
ctx,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
test("integration: real hooks block a force push, then allow it once after confirmation", async (t) => {
|
|
207
|
+
const dir = "/tmp/gsd-destructive-confirm-int-allow";
|
|
208
|
+
const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
|
|
209
|
+
resetDestructiveConfirmation(dir);
|
|
210
|
+
t.after(() => resetDestructiveConfirmation(dir));
|
|
211
|
+
|
|
212
|
+
const { handlers, pi } = makeHookHarness();
|
|
213
|
+
registerHooks(pi, []);
|
|
214
|
+
|
|
215
|
+
// 1. First attempt is hard-blocked by the real guard, with instructions that
|
|
216
|
+
// name the destructive_confirm gate.
|
|
217
|
+
const firstBlock = await runBashGuard(handlers, FORCE_PUSH, ctx);
|
|
218
|
+
assert.equal(firstBlock?.block, true, "real guard blocks the first attempt");
|
|
219
|
+
assert.match(firstBlock?.reason ?? "", /HARD BLOCK: destructive Bash command/);
|
|
220
|
+
assert.match(firstBlock?.reason ?? "", /force push/);
|
|
221
|
+
assert.match(firstBlock?.reason ?? "", /destructive_confirm/);
|
|
222
|
+
|
|
223
|
+
// 2. User answers an affirmative destructive_confirm gate.
|
|
224
|
+
await answerConfirmGate(handlers, "destructive_confirm_force_push", ctx);
|
|
225
|
+
|
|
226
|
+
// 3. Re-issuing the exact command in the same turn now runs once (no block).
|
|
227
|
+
const secondAttempt = await runBashGuard(handlers, FORCE_PUSH, ctx);
|
|
228
|
+
assert.equal(secondAttempt, undefined, "confirmed command passes the real guard once");
|
|
229
|
+
|
|
230
|
+
// 4. One-shot: an immediate identical third attempt re-blocks.
|
|
231
|
+
const thirdAttempt = await runBashGuard(handlers, FORCE_PUSH, ctx);
|
|
232
|
+
assert.equal(thirdAttempt?.block, true, "second run of the same command re-blocks (one-shot)");
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test("integration: declining the confirm gate leaves the command blocked", async (t) => {
|
|
236
|
+
const dir = "/tmp/gsd-destructive-confirm-int-decline";
|
|
237
|
+
const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
|
|
238
|
+
resetDestructiveConfirmation(dir);
|
|
239
|
+
t.after(() => resetDestructiveConfirmation(dir));
|
|
240
|
+
|
|
241
|
+
const { handlers, pi } = makeHookHarness();
|
|
242
|
+
registerHooks(pi, []);
|
|
243
|
+
|
|
244
|
+
assert.equal((await runBashGuard(handlers, FORCE_PUSH, ctx))?.block, true, "first attempt blocks");
|
|
245
|
+
|
|
246
|
+
// Decline: the non-affirmative (non-first) option must NOT promote a token.
|
|
247
|
+
const questions = [
|
|
248
|
+
{
|
|
249
|
+
id: "destructive_confirm_force_push",
|
|
250
|
+
question: "Run this destructive command?",
|
|
251
|
+
options: [{ label: "Yes, run it (Recommended)" }, { label: "No, cancel" }],
|
|
252
|
+
},
|
|
253
|
+
];
|
|
254
|
+
for (const handler of handlers.get("tool_result") ?? []) {
|
|
255
|
+
await handler(
|
|
256
|
+
{
|
|
257
|
+
toolName: "ask_user_questions",
|
|
258
|
+
input: { questions },
|
|
259
|
+
details: {
|
|
260
|
+
response: { answers: { "destructive_confirm_force_push": { selected: "No, cancel" } } },
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
ctx,
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
assert.equal(
|
|
268
|
+
(await runBashGuard(handlers, FORCE_PUSH, ctx))?.block,
|
|
269
|
+
true,
|
|
270
|
+
"declined command stays blocked",
|
|
271
|
+
);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test("integration: a confirm token does not leak to a different destructive command", async (t) => {
|
|
275
|
+
const dir = "/tmp/gsd-destructive-confirm-int-bound";
|
|
276
|
+
const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
|
|
277
|
+
resetDestructiveConfirmation(dir);
|
|
278
|
+
t.after(() => resetDestructiveConfirmation(dir));
|
|
279
|
+
|
|
280
|
+
const { handlers, pi } = makeHookHarness();
|
|
281
|
+
registerHooks(pi, []);
|
|
282
|
+
|
|
283
|
+
await runBashGuard(handlers, FORCE_PUSH, ctx);
|
|
284
|
+
await answerConfirmGate(handlers, "destructive_confirm_force_push", ctx);
|
|
285
|
+
|
|
286
|
+
// A different destructive command must not ride the force-push confirmation.
|
|
287
|
+
// In the real guard, blocking this command also records it as pending, which
|
|
288
|
+
// invalidates the stale force-push token (stale-token safety invariant) — so
|
|
289
|
+
// the original confirmation is consumed/cleared, not left dangling.
|
|
290
|
+
assert.equal(
|
|
291
|
+
(await runBashGuard(handlers, "rm -rf build", ctx))?.block,
|
|
292
|
+
true,
|
|
293
|
+
"unrelated destructive command is still blocked",
|
|
294
|
+
);
|
|
295
|
+
// Because the unrelated block invalidated the stale token, the original
|
|
296
|
+
// force-push now re-blocks too: a confirmation never survives an intervening
|
|
297
|
+
// destructive command. This is stricter (safer) than per-command isolation.
|
|
298
|
+
assert.equal(
|
|
299
|
+
(await runBashGuard(handlers, FORCE_PUSH, ctx))?.block,
|
|
300
|
+
true,
|
|
301
|
+
"force-push token was invalidated by the intervening destructive block",
|
|
302
|
+
);
|
|
303
|
+
});
|
|
@@ -39,7 +39,11 @@ function makeDiscussPi() {
|
|
|
39
39
|
tmp,
|
|
40
40
|
pi: {
|
|
41
41
|
getActiveTools: () => ["gsd_summary_save", "bash"],
|
|
42
|
+
emitAdjustToolSet: async () => undefined,
|
|
43
|
+
emitBeforeModelSelect: async () => undefined,
|
|
44
|
+
setModel: async () => true,
|
|
42
45
|
setActiveTools: () => {},
|
|
46
|
+
setThinkingLevel: () => {},
|
|
43
47
|
sendMessage: (message: { content?: unknown }) => {
|
|
44
48
|
sent.push(message);
|
|
45
49
|
},
|
|
@@ -53,6 +57,7 @@ function makeDiscussPi() {
|
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
function makeDiscussCtx(notifications: Array<{ message: string; level?: string }> = []) {
|
|
60
|
+
const model = { provider: "anthropic", id: "claude-sonnet-4-6", api: "anthropic-messages" };
|
|
56
61
|
return {
|
|
57
62
|
hasUI: true,
|
|
58
63
|
sessionManager: {
|
|
@@ -65,8 +70,13 @@ function makeDiscussCtx(notifications: Array<{ message: string; level?: string }
|
|
|
65
70
|
setStatus: () => {},
|
|
66
71
|
},
|
|
67
72
|
waitForIdle: async () => {},
|
|
68
|
-
model
|
|
69
|
-
modelRegistry: {
|
|
73
|
+
model,
|
|
74
|
+
modelRegistry: {
|
|
75
|
+
getAvailable: () => [model],
|
|
76
|
+
getAll: () => [model],
|
|
77
|
+
getProviderAuthMode: () => "apiKey",
|
|
78
|
+
isProviderRequestReady: () => true,
|
|
79
|
+
},
|
|
70
80
|
};
|
|
71
81
|
}
|
|
72
82
|
|