@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.b1abb545
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-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +84 -228
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +109 -11
- package/dist/resources/extensions/gsd/auto/phases.js +28 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
- package/dist/resources/extensions/gsd/auto-start.js +12 -23
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +21 -19
- package/dist/resources/extensions/gsd/auto.js +11 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +100 -138
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/gsd-db.js +12 -0
- package/dist/resources/extensions/gsd/guided-flow.js +34 -468
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +147 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- 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 +8 -8
- 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/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 +7 -7
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/package.json +2 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- 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 +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +2 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +8 -93
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +35 -120
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.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/extensions/ask-user-questions.ts +87 -24
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +108 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +240 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +125 -12
- package/src/resources/extensions/gsd/auto/phases.ts +35 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
- package/src/resources/extensions/gsd/auto-start.ts +17 -20
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree.ts +33 -26
- package/src/resources/extensions/gsd/auto.ts +15 -8
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +116 -151
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/gsd-db.ts +12 -0
- package/src/resources/extensions/gsd/guided-flow.ts +47 -558
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +173 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_ssgManifest.js +0 -0
|
@@ -7,11 +7,12 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
|
|
|
7
7
|
import { ALWAYS_PRESERVED_SHIM_TOOL_NAMES } from "@gsd/pi-ai";
|
|
8
8
|
import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
|
|
9
9
|
import { buildMilestoneFileName, clearPathCache, milestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
10
|
-
import { canonicalToolName, clearDiscussionFlowState,
|
|
10
|
+
import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isMilestoneDepthVerified, isQueuePhaseActive, markApprovalGateVerified, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
11
11
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
12
12
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
13
13
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
14
|
-
import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError, } from "../auto-runtime-state.js";
|
|
14
|
+
import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, isInteractiveElicitationInFlight, markToolEnd, markToolStart, recordAutoToolSurfaceSnapshot, recordToolInvocationError, } from "../auto-runtime-state.js";
|
|
15
|
+
import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
|
|
15
16
|
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
16
17
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
17
18
|
import { saveActivityLog } from "../activity-log.js";
|
|
@@ -22,16 +23,18 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
|
|
|
22
23
|
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
23
24
|
import { initNotificationStore } from "../notification-store.js";
|
|
24
25
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
26
|
+
import { notifyPreferenceDiagnostics } from "../preferences-diagnostics.js";
|
|
25
27
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
26
28
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
27
|
-
import { approvalGateIdForUnit, isExplicitApprovalResponse, shouldPauseForUserApprovalQuestion } from "../user-input-boundary.js";
|
|
29
|
+
import { approvalGateIdForUnit, isExplicitApprovalResponse, messageHasPendingAskUserQuestionsTool, shouldPauseForUserApprovalQuestion, } from "../user-input-boundary.js";
|
|
28
30
|
import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
|
|
29
31
|
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
30
32
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
31
|
-
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
33
|
+
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, canonicalWorkflowToolName, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
32
34
|
import { filterToolsForProvider } from "../model-router.js";
|
|
35
|
+
import { mcpToolMatchesBaseName } from "../mcp-tool-name.js";
|
|
33
36
|
import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
34
|
-
import {
|
|
37
|
+
import { supportsSourceObservationsForUnit } from "../source-observations.js";
|
|
35
38
|
let approvalQuestionAbortInFlight = false;
|
|
36
39
|
async function loadWelcomeScreenModule() {
|
|
37
40
|
const candidates = [];
|
|
@@ -165,15 +168,19 @@ function resolveScopedToolNames(activeToolNames, requestedToolNames) {
|
|
|
165
168
|
const resolved = new Set();
|
|
166
169
|
for (const requested of requestedToolNames) {
|
|
167
170
|
const scopedMatches = [];
|
|
171
|
+
const aliasFallbacks = [];
|
|
168
172
|
for (const activeName of activeToolNames) {
|
|
169
|
-
if (
|
|
170
|
-
continue;
|
|
171
|
-
const toolSeparator = activeName.indexOf("__", "mcp__".length);
|
|
172
|
-
if (toolSeparator < 0)
|
|
173
|
-
continue;
|
|
174
|
-
if (activeName.slice(toolSeparator + 2) === requested) {
|
|
173
|
+
if (mcpToolMatchesBaseName(activeName, requested)) {
|
|
175
174
|
scopedMatches.push(activeName);
|
|
176
175
|
}
|
|
176
|
+
else if (isWorkflowAliasTool(activeName) && canonicalWorkflowToolName(activeName) === requested) {
|
|
177
|
+
aliasFallbacks.push(activeName);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Only use alias as fallback when canonical is absent — not directly and not via MCP scoping.
|
|
181
|
+
// Prevents the alias from resurfacing alongside the canonical when both are in the active set.
|
|
182
|
+
if (!exact.has(requested) && scopedMatches.length === 0) {
|
|
183
|
+
scopedMatches.push(...aliasFallbacks);
|
|
177
184
|
}
|
|
178
185
|
if (requested.startsWith("browser_") && scopedMatches.length > 0) {
|
|
179
186
|
for (const match of scopedMatches)
|
|
@@ -214,7 +221,7 @@ export function buildRunUatGsdToolSet(activeToolNames, registeredToolNames = act
|
|
|
214
221
|
...RUN_UAT_BROWSER_TOOL_NAMES,
|
|
215
222
|
]);
|
|
216
223
|
const resolved = [...new Set(scoped)];
|
|
217
|
-
const unresolved = RUN_UAT_WORKFLOW_TOOL_NAMES.filter((tool) => !resolved.some((name) => name === tool || (name
|
|
224
|
+
const unresolved = RUN_UAT_WORKFLOW_TOOL_NAMES.filter((tool) => !resolved.some((name) => name === tool || mcpToolMatchesBaseName(name, tool)));
|
|
218
225
|
if (unresolved.length > 0) {
|
|
219
226
|
safetyLogWarning("bootstrap", `buildRunUatGsdToolSet: required run-uat workflow tool(s) not found in active/registered surface: ${unresolved.join(", ")}. Session may lack gsd-workflow MCP connection.`);
|
|
220
227
|
}
|
|
@@ -271,7 +278,17 @@ function applyMinimalGsdToolSurface(pi) {
|
|
|
271
278
|
return;
|
|
272
279
|
const dash = getAutoRuntimeSnapshot();
|
|
273
280
|
if (dash.active && dash.currentUnit) {
|
|
274
|
-
|
|
281
|
+
const currentToolNames = pi.getActiveTools();
|
|
282
|
+
const registeredToolNames = resolveRegisteredToolNames(pi, currentToolNames);
|
|
283
|
+
const scopedToolNames = buildMinimalAutoGsdToolSet(currentToolNames, dash.currentUnit.type, registeredToolNames);
|
|
284
|
+
recordAutoToolSurfaceSnapshot({
|
|
285
|
+
source: "runtime-scope",
|
|
286
|
+
unitType: dash.currentUnit.type,
|
|
287
|
+
modelFacingToolNames: scopedToolNames,
|
|
288
|
+
registeredToolNames,
|
|
289
|
+
scopedToolNames,
|
|
290
|
+
});
|
|
291
|
+
pi.setActiveTools(scopedToolNames);
|
|
275
292
|
return;
|
|
276
293
|
}
|
|
277
294
|
if (!isGeneralGsdToolScopingRequested())
|
|
@@ -286,6 +303,13 @@ export function scopeGsdWorkflowToolsForDispatch(pi, unitType) {
|
|
|
286
303
|
const scoped = unitType
|
|
287
304
|
? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
|
|
288
305
|
: buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
|
|
306
|
+
recordAutoToolSurfaceSnapshot({
|
|
307
|
+
source: "dispatch-scope",
|
|
308
|
+
unitType,
|
|
309
|
+
modelFacingToolNames: scoped,
|
|
310
|
+
registeredToolNames,
|
|
311
|
+
scopedToolNames: scoped,
|
|
312
|
+
});
|
|
289
313
|
const toolsChanged = !(scoped.length === current.length && scoped.every((name, index) => name === current[index]));
|
|
290
314
|
const canScopeSkills = unitHasSkillManifest(unitType) && pi.getVisibleSkills && pi.setVisibleSkills;
|
|
291
315
|
if (!toolsChanged && !canScopeSkills) {
|
|
@@ -540,6 +564,7 @@ function initSessionNotifications(ctx) {
|
|
|
540
564
|
initNotificationStore(resolveNotificationStoreBasePath(contextBasePath(ctx)));
|
|
541
565
|
installNotifyInterceptor(ctx);
|
|
542
566
|
initNotificationWidget(ctx);
|
|
567
|
+
notifyPreferenceDiagnostics(ctx, contextBasePath(ctx), { surface: "session-start" });
|
|
543
568
|
}
|
|
544
569
|
async function prepareWorkflowMcpForHookContext(ctx, basePath) {
|
|
545
570
|
// Skip MCP auto-prep when running inside an auto-worktree. The worktree
|
|
@@ -803,6 +828,20 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
803
828
|
pi.on("message_update", async (event, ctx) => {
|
|
804
829
|
if (approvalQuestionAbortInFlight)
|
|
805
830
|
return;
|
|
831
|
+
// If the model asked via ask_user_questions, that in-flight elicitation IS
|
|
832
|
+
// the human boundary. Arming the pause/gate here (and emitting the "waiting
|
|
833
|
+
// for your approval - pausing" notice) would tear it down and trigger the
|
|
834
|
+
// foreground self-cancel/re-ask loop. The marker is set only by the
|
|
835
|
+
// claude-code-cli SDK elicitation handler and is ungated, so it is true in
|
|
836
|
+
// foreground; under the native-TUI provider it is always false and this path
|
|
837
|
+
// runs unchanged (#cc-elicitation-self-cancel).
|
|
838
|
+
if (isInteractiveElicitationInFlight())
|
|
839
|
+
return;
|
|
840
|
+
// Prose with "?" can stream before the MCP tool/elicitation starts. When the
|
|
841
|
+
// structured ask_user_questions call is already in the partial message, the
|
|
842
|
+
// tool IS the human boundary — do not arm the text-based approval pause.
|
|
843
|
+
if (messageHasPendingAskUserQuestionsTool(event.message))
|
|
844
|
+
return;
|
|
806
845
|
const dash = getAutoRuntimeSnapshot();
|
|
807
846
|
if (dash.active)
|
|
808
847
|
return;
|
|
@@ -1071,77 +1110,32 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1071
1110
|
const basePath = contextBasePath(ctx);
|
|
1072
1111
|
const milestoneId = await getDiscussionMilestoneIdFor(basePath);
|
|
1073
1112
|
const details = event.details;
|
|
1074
|
-
// ── Discussion gate enforcement: handle gate question responses ──
|
|
1075
|
-
// If the result is cancelled or has no response, the pending gate stays active
|
|
1076
|
-
// so the model is blocked from non-read-only tools until it re-asks.
|
|
1077
|
-
// If the user responded at all (even "needs adjustment"), clear the pending gate
|
|
1078
|
-
// because the user engaged — the prompt handles the re-ask-after-adjustment flow.
|
|
1079
1113
|
const questions = event.input?.questions ?? [];
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
await maybePauseAutoForApprovalGate(ctx, pi, true, interrupted
|
|
1093
|
-
? "Depth confirmation was interrupted — pausing auto-mode until you respond."
|
|
1094
|
-
: "Depth confirmation is waiting for your answer — pausing auto-mode.");
|
|
1095
|
-
}
|
|
1096
|
-
return {
|
|
1097
|
-
content: [{
|
|
1098
|
-
type: "text",
|
|
1099
|
-
text: [
|
|
1100
|
-
`Waiting for depth confirmation on gate "${currentPendingGate}".`,
|
|
1101
|
-
interrupted
|
|
1102
|
-
? "The confirmation question was interrupted before a response was recorded."
|
|
1103
|
-
: "No user response was received for the confirmation question.",
|
|
1104
|
-
"Do not infer approval from earlier or prior messages.",
|
|
1105
|
-
"Do not proceed, write files, save artifacts, or call other tools.",
|
|
1106
|
-
`Re-call ask_user_questions with the same gate question id ("${currentPendingGate}") and wait for the user's response.`,
|
|
1107
|
-
].join(" "),
|
|
1108
|
-
}],
|
|
1109
|
-
};
|
|
1110
|
-
}
|
|
1111
|
-
else {
|
|
1112
|
-
const pendingQuestion = questions.find((question) => question?.id === currentPendingGate);
|
|
1113
|
-
if (pendingQuestion) {
|
|
1114
|
-
const answer = details.response?.answers?.[currentPendingGate];
|
|
1115
|
-
if (isDepthConfirmationAnswer(answer?.selected, pendingQuestion.options)) {
|
|
1116
|
-
markApprovalGateVerified(currentPendingGate, basePath);
|
|
1117
|
-
const milestoneIdFromGate = extractDepthVerificationMilestoneId(currentPendingGate);
|
|
1118
|
-
if (milestoneIdFromGate)
|
|
1119
|
-
markDepthVerified(milestoneIdFromGate, basePath);
|
|
1120
|
-
clearPendingGate(basePath);
|
|
1121
|
-
clearDeferredApprovalGate(basePath);
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1114
|
+
const gateResult = applyAskUserQuestionsGateResult({
|
|
1115
|
+
basePath,
|
|
1116
|
+
questions,
|
|
1117
|
+
details,
|
|
1118
|
+
fallbackMilestoneId: milestoneId,
|
|
1119
|
+
});
|
|
1120
|
+
if (gateResult.status === "waiting") {
|
|
1121
|
+
resetToolCallLoopGuard();
|
|
1122
|
+
if (ctx) {
|
|
1123
|
+
await maybePauseAutoForApprovalGate(ctx, pi, true, gateResult.interrupted
|
|
1124
|
+
? "Depth confirmation was interrupted — pausing auto-mode until you respond."
|
|
1125
|
+
: "Depth confirmation is waiting for your answer — pausing auto-mode.");
|
|
1124
1126
|
}
|
|
1127
|
+
return {
|
|
1128
|
+
content: [{
|
|
1129
|
+
type: "text",
|
|
1130
|
+
text: formatPendingAskUserQuestionsGateMessage(gateResult.pendingGateId, gateResult.interrupted),
|
|
1131
|
+
}],
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
if (gateResult.status === "verified") {
|
|
1135
|
+
clearDeferredApprovalGate(basePath);
|
|
1125
1136
|
}
|
|
1126
1137
|
if (details?.cancelled || !details?.response)
|
|
1127
1138
|
return;
|
|
1128
|
-
for (const question of questions) {
|
|
1129
|
-
if (typeof question.id === "string" && question.id.includes("depth_verification")) {
|
|
1130
|
-
// Only unlock the gate if the user selected the first option (confirmation).
|
|
1131
|
-
// Cross-references against the question's defined options to reject free-form "Other" text.
|
|
1132
|
-
const answer = details.response?.answers?.[question.id];
|
|
1133
|
-
const inferredMilestoneId = extractDepthVerificationMilestoneId(question.id) ?? milestoneId;
|
|
1134
|
-
if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
|
|
1135
|
-
if (currentPendingGate && question.id !== currentPendingGate)
|
|
1136
|
-
break;
|
|
1137
|
-
markApprovalGateVerified(question.id, basePath);
|
|
1138
|
-
markDepthVerified(inferredMilestoneId, basePath);
|
|
1139
|
-
clearPendingGate(basePath);
|
|
1140
|
-
clearDeferredApprovalGate(basePath);
|
|
1141
|
-
}
|
|
1142
|
-
break;
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
1139
|
if (!milestoneId)
|
|
1146
1140
|
return;
|
|
1147
1141
|
await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
|
|
@@ -1196,61 +1190,10 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1196
1190
|
const payload = event.payload;
|
|
1197
1191
|
if (!payload || typeof payload !== "object")
|
|
1198
1192
|
return;
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
const { createObservationMask, createResponsesInputObservationMask, truncateContextResultMessages, truncateResponsesInputResultItems, } = await import("../context-masker.js");
|
|
1204
|
-
const prefs = loadEffectiveGSDPreferences();
|
|
1205
|
-
const cmConfig = prefs?.preferences.context_management;
|
|
1206
|
-
// Observation masking: replace old tool results with placeholders.
|
|
1207
|
-
// Only active during auto-mode when context_management.observation_masking is enabled.
|
|
1208
|
-
if (isAutoActive() && cmConfig?.observation_masking !== false) {
|
|
1209
|
-
const keepTurns = cmConfig?.observation_mask_turns ?? 8;
|
|
1210
|
-
const messages = payload.messages;
|
|
1211
|
-
if (Array.isArray(messages)) {
|
|
1212
|
-
payload.messages = createObservationMask(keepTurns)(messages);
|
|
1213
|
-
}
|
|
1214
|
-
const input = payload.input;
|
|
1215
|
-
if (Array.isArray(input)) {
|
|
1216
|
-
payload.input = createResponsesInputObservationMask(keepTurns)(input);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
// Tool result truncation: cap individual tool result content length.
|
|
1220
|
-
// Applies in ALL modes (auto + interactive) to prevent context bloat.
|
|
1221
|
-
// In pi-ai format, toolResult messages have role: "toolResult" and content: TextContent[].
|
|
1222
|
-
// Creates new objects to avoid mutating shared conversation state.
|
|
1223
|
-
const maxChars = cmConfig?.tool_result_max_chars ?? 800;
|
|
1224
|
-
const msgs = payload.messages;
|
|
1225
|
-
if (Array.isArray(msgs)) {
|
|
1226
|
-
payload.messages = truncateContextResultMessages(msgs, maxChars);
|
|
1227
|
-
}
|
|
1228
|
-
const input = payload.input;
|
|
1229
|
-
if (Array.isArray(input)) {
|
|
1230
|
-
payload.input = truncateResponsesInputResultItems(input, maxChars);
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
catch { /* non-fatal */ }
|
|
1234
|
-
try {
|
|
1235
|
-
if (isAutoActive()) {
|
|
1236
|
-
const sourceContextBlock = getSourceObservationStore().renderActiveBlock();
|
|
1237
|
-
if (sourceContextBlock) {
|
|
1238
|
-
const nextPayload = injectSourceContextBlockIntoPayload(payload, sourceContextBlock);
|
|
1239
|
-
Object.assign(payload, nextPayload);
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
catch { /* non-fatal */ }
|
|
1244
|
-
// ── Service Tier ────────────────────────────────────────────────────
|
|
1245
|
-
const modelId = event.model?.id;
|
|
1246
|
-
if (!modelId)
|
|
1247
|
-
return payload;
|
|
1248
|
-
const { getEffectiveServiceTier, supportsServiceTier } = await import("../service-tier.js");
|
|
1249
|
-
const tier = getEffectiveServiceTier();
|
|
1250
|
-
if (!tier || !supportsServiceTier(modelId))
|
|
1251
|
-
return payload;
|
|
1252
|
-
payload.service_tier = tier;
|
|
1253
|
-
return payload;
|
|
1193
|
+
return applyProviderPayloadPolicy({
|
|
1194
|
+
payload,
|
|
1195
|
+
modelId: event.model?.id,
|
|
1196
|
+
});
|
|
1254
1197
|
});
|
|
1255
1198
|
// Capability-aware model routing hook (ADR-004)
|
|
1256
1199
|
// Extensions can override model selection by returning { modelId: "..." }
|
|
@@ -1282,16 +1225,35 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1282
1225
|
const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1283
1226
|
const compatibleRegisteredToolNames = filterToolsForProvider(registeredToolNames, event.selectedModelApi, event.selectedModelProvider).compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)));
|
|
1284
1227
|
const guidedUnit = getGuidedUnitContext();
|
|
1285
|
-
const
|
|
1228
|
+
const requestRegisteredToolNames = guidedUnit?.unitType === "run-uat"
|
|
1229
|
+
? compatibleRegisteredToolNames
|
|
1230
|
+
: registeredToolNames;
|
|
1231
|
+
const requestScoped = buildRequestScopedGsdToolSet(guidedUnit?.unitType === "run-uat" ? aliasFilteredCompatible : providerCompatible, event.requestCustomMessages, requestRegisteredToolNames, guidedUnit?.unitType);
|
|
1286
1232
|
if (requestScoped) {
|
|
1233
|
+
recordAutoToolSurfaceSnapshot({
|
|
1234
|
+
source: "provider-adjustment",
|
|
1235
|
+
unitType: guidedUnit?.unitType,
|
|
1236
|
+
modelFacingToolNames: requestScoped,
|
|
1237
|
+
registeredToolNames: requestRegisteredToolNames,
|
|
1238
|
+
scopedToolNames: requestScoped,
|
|
1239
|
+
});
|
|
1287
1240
|
return { toolNames: requestScoped };
|
|
1288
1241
|
}
|
|
1289
1242
|
const dash = getAutoRuntimeSnapshot();
|
|
1290
1243
|
if (dash.active && dash.currentUnit) {
|
|
1244
|
+
const registeredForUnit = dash.currentUnit.type === "run-uat"
|
|
1245
|
+
? compatibleRegisteredToolNames
|
|
1246
|
+
: resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1247
|
+
const scopedToolNames = buildMinimalAutoGsdToolSet(dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible, dash.currentUnit.type, registeredForUnit);
|
|
1248
|
+
recordAutoToolSurfaceSnapshot({
|
|
1249
|
+
source: "provider-adjustment",
|
|
1250
|
+
unitType: dash.currentUnit.type,
|
|
1251
|
+
modelFacingToolNames: scopedToolNames,
|
|
1252
|
+
registeredToolNames: registeredForUnit,
|
|
1253
|
+
scopedToolNames,
|
|
1254
|
+
});
|
|
1291
1255
|
return {
|
|
1292
|
-
toolNames:
|
|
1293
|
-
? compatibleRegisteredToolNames
|
|
1294
|
-
: resolveRegisteredToolNames(pi, event.activeToolNames)),
|
|
1256
|
+
toolNames: scopedToolNames,
|
|
1295
1257
|
};
|
|
1296
1258
|
}
|
|
1297
1259
|
if (isGeneralGsdToolScopingRequested()) {
|
|
@@ -3,6 +3,7 @@ import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkS
|
|
|
3
3
|
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { minimatch } from "minimatch";
|
|
5
5
|
import { GSD_PHASE_SCOPE_DISPLAY_REASON, shouldBlockAutoUnitToolCall } from "../auto-unit-tool-scope.js";
|
|
6
|
+
import { stripMcpToolPrefix } from "../mcp-tool-name.js";
|
|
6
7
|
import { getIsolationMode } from "../preferences.js";
|
|
7
8
|
import { compileSubagentPermissionContract } from "../unit-context-manifest.js";
|
|
8
9
|
import { logWarning } from "../workflow-logger.js";
|
|
@@ -102,10 +103,7 @@ const GATE_SAFE_TOOLS = new Set([
|
|
|
102
103
|
"ask_user_questions",
|
|
103
104
|
]);
|
|
104
105
|
export function canonicalToolName(toolName) {
|
|
105
|
-
|
|
106
|
-
return toolName;
|
|
107
|
-
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
108
|
-
return toolSeparator >= 0 ? toolName.slice(toolSeparator + 2) : toolName;
|
|
106
|
+
return stripMcpToolPrefix(toolName);
|
|
109
107
|
}
|
|
110
108
|
/**
|
|
111
109
|
* Persistence is ON by default (opt-out).
|
|
@@ -385,6 +383,67 @@ export function isDepthConfirmationAnswer(selected, options) {
|
|
|
385
383
|
// Returning false prevents any free-form string from unlocking the gate.
|
|
386
384
|
return false;
|
|
387
385
|
}
|
|
386
|
+
function findGateQuestion(questions, gateId) {
|
|
387
|
+
return questions.find((question) => question?.id === gateId);
|
|
388
|
+
}
|
|
389
|
+
function readSelectedGateAnswer(details, questionId) {
|
|
390
|
+
return details.response?.answers?.[questionId]?.selected;
|
|
391
|
+
}
|
|
392
|
+
function verifyAnsweredGate(basePath, question, fallbackMilestoneId) {
|
|
393
|
+
const gateId = typeof question.id === "string" ? question.id : "";
|
|
394
|
+
const milestoneId = extractDepthVerificationMilestoneId(gateId) ?? fallbackMilestoneId ?? null;
|
|
395
|
+
markApprovalGateVerified(gateId, basePath);
|
|
396
|
+
markDepthVerified(milestoneId, basePath);
|
|
397
|
+
clearPendingGate(basePath);
|
|
398
|
+
return { status: "verified", gateId, milestoneId };
|
|
399
|
+
}
|
|
400
|
+
export function applyAskUserQuestionsGateResult(options) {
|
|
401
|
+
const { basePath, questions, details, fallbackMilestoneId } = options;
|
|
402
|
+
const currentPendingGate = getPendingGate(basePath);
|
|
403
|
+
if (currentPendingGate) {
|
|
404
|
+
if (details.cancelled || !details.response) {
|
|
405
|
+
return {
|
|
406
|
+
status: "waiting",
|
|
407
|
+
pendingGateId: currentPendingGate,
|
|
408
|
+
interrupted: details.interrupted === true,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
const pendingQuestion = findGateQuestion(questions, currentPendingGate);
|
|
412
|
+
if (pendingQuestion) {
|
|
413
|
+
const selected = readSelectedGateAnswer(details, currentPendingGate);
|
|
414
|
+
if (isDepthConfirmationAnswer(selected, pendingQuestion.options)) {
|
|
415
|
+
return verifyAnsweredGate(basePath, pendingQuestion, fallbackMilestoneId);
|
|
416
|
+
}
|
|
417
|
+
return { status: "answered", gateId: currentPendingGate };
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (details.cancelled || !details.response)
|
|
421
|
+
return { status: "not-gate" };
|
|
422
|
+
for (const question of questions) {
|
|
423
|
+
if (typeof question.id !== "string" || !isGateQuestionId(question.id))
|
|
424
|
+
continue;
|
|
425
|
+
const selected = readSelectedGateAnswer(details, question.id);
|
|
426
|
+
if (!isDepthConfirmationAnswer(selected, question.options)) {
|
|
427
|
+
return { status: "answered", gateId: question.id };
|
|
428
|
+
}
|
|
429
|
+
if (currentPendingGate && question.id !== currentPendingGate) {
|
|
430
|
+
return { status: "answered", gateId: currentPendingGate };
|
|
431
|
+
}
|
|
432
|
+
return verifyAnsweredGate(basePath, question, fallbackMilestoneId);
|
|
433
|
+
}
|
|
434
|
+
return { status: "not-gate" };
|
|
435
|
+
}
|
|
436
|
+
export function formatPendingAskUserQuestionsGateMessage(pendingGateId, interrupted) {
|
|
437
|
+
return [
|
|
438
|
+
`Waiting for depth confirmation on gate "${pendingGateId}".`,
|
|
439
|
+
interrupted
|
|
440
|
+
? "The confirmation question was interrupted before a response was recorded."
|
|
441
|
+
: "No user response was received for the confirmation question.",
|
|
442
|
+
"Do not infer approval from earlier or prior messages.",
|
|
443
|
+
"Do not proceed, write files, save artifacts, or call other tools.",
|
|
444
|
+
`Re-call ask_user_questions with the same gate question id ("${pendingGateId}") and wait for the user's response.`,
|
|
445
|
+
].join(" ");
|
|
446
|
+
}
|
|
388
447
|
export function shouldBlockContextWrite(toolName, inputPath, milestoneId, _queuePhaseActive, basePath = process.cwd()) {
|
|
389
448
|
if (toolName !== "write")
|
|
390
449
|
return { block: false };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Shared DB-backed guard for milestone closeout finalization.
|
|
3
|
-
import {
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { getLatestAssessmentByScope, getMilestone, getMilestoneSlices, getPendingGates, getSliceTasks, isDbAvailable, } from "./gsd-db.js";
|
|
5
|
+
import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk, } from "./db-workspace.js";
|
|
4
6
|
import { isClosedStatus } from "./status-guards.js";
|
|
7
|
+
import { closeQualityGatesFromEvidence } from "./quality-gate-closure.js";
|
|
5
8
|
export const CLOSEOUT_CONSISTENCY_BLOCKED_REASON = "closeout-consistency-blocked";
|
|
6
9
|
function blocked(reason, message) {
|
|
7
10
|
return {
|
|
@@ -14,22 +17,30 @@ function blocked(reason, message) {
|
|
|
14
17
|
function isFileBackedDbPath(path) {
|
|
15
18
|
return Boolean(path && path !== ":memory:");
|
|
16
19
|
}
|
|
20
|
+
function artifactBasePathFromDb() {
|
|
21
|
+
const dbPath = getWorkflowDatabasePath();
|
|
22
|
+
if (!isFileBackedDbPath(dbPath))
|
|
23
|
+
return undefined;
|
|
24
|
+
return dirname(dirname(dbPath));
|
|
25
|
+
}
|
|
17
26
|
export function checkCloseoutConsistencyGate(milestoneId, options = {}) {
|
|
18
27
|
if (!isDbAvailable()) {
|
|
19
28
|
return blocked("db-unavailable", `Closeout consistency blocked for ${milestoneId}: canonical DB is unavailable.`);
|
|
20
29
|
}
|
|
21
|
-
if (options.refreshFromDisk && isFileBackedDbPath(
|
|
30
|
+
if (options.refreshFromDisk && isFileBackedDbPath(getWorkflowDatabasePath()) && !refreshWorkflowDatabaseFromDisk()) {
|
|
22
31
|
return blocked("db-refresh-failed", `Closeout consistency blocked for ${milestoneId}: canonical DB refresh failed.`);
|
|
23
32
|
}
|
|
24
33
|
const milestone = getMilestone(milestoneId);
|
|
25
34
|
if (!milestone) {
|
|
26
35
|
return blocked("milestone-missing", `Closeout consistency blocked for ${milestoneId}: milestone is missing from canonical DB.`);
|
|
27
36
|
}
|
|
28
|
-
if (!isClosedStatus(milestone.status)) {
|
|
37
|
+
if (!isClosedStatus(milestone.status) && !options.allowOpenMilestone) {
|
|
29
38
|
return blocked("milestone-open", `Closeout consistency blocked for ${milestoneId}: canonical DB milestone status is "${milestone.status}".`);
|
|
30
39
|
}
|
|
40
|
+
const validation = milestone.status === "skipped"
|
|
41
|
+
? null
|
|
42
|
+
: getLatestAssessmentByScope(milestoneId, "milestone-validation");
|
|
31
43
|
if (milestone.status !== "skipped") {
|
|
32
|
-
const validation = getLatestAssessmentByScope(milestoneId, "milestone-validation");
|
|
33
44
|
if (validation?.status !== "pass") {
|
|
34
45
|
return blocked("validation-not-pass", `Closeout consistency blocked for ${milestoneId}: latest milestone validation is "${validation?.status ?? "absent"}".`);
|
|
35
46
|
}
|
|
@@ -38,6 +49,12 @@ export function checkCloseoutConsistencyGate(milestoneId, options = {}) {
|
|
|
38
49
|
if (slices.length === 0 && milestone.status !== "skipped") {
|
|
39
50
|
return blocked("slice-missing", `Closeout consistency blocked for ${milestoneId}: no slices exist in canonical DB.`);
|
|
40
51
|
}
|
|
52
|
+
if (milestone.status !== "skipped") {
|
|
53
|
+
closeQualityGatesFromEvidence(milestoneId, {
|
|
54
|
+
artifactBasePath: options.artifactBasePath ?? artifactBasePathFromDb(),
|
|
55
|
+
milestoneValidationPassed: validation?.status === "pass",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
41
58
|
for (const slice of slices) {
|
|
42
59
|
if (!isClosedStatus(slice.status)) {
|
|
43
60
|
return blocked("slice-open", `Closeout consistency blocked for ${milestoneId}: slice ${slice.id} status is "${slice.status}".`);
|
|
@@ -330,15 +330,19 @@ export function ensureCodebaseMapFresh(basePath, options, ensureOptions) {
|
|
|
330
330
|
const ttlMs = ensureOptions?.ttlMs ?? DEFAULT_REFRESH_TTL_MS;
|
|
331
331
|
const force = ensureOptions?.force === true;
|
|
332
332
|
const now = Date.now();
|
|
333
|
+
// Enumerate files and compute fingerprint before the TTL check so that
|
|
334
|
+
// file changes are always detected, even within the TTL window.
|
|
335
|
+
const existing = readCodebaseMap(basePath);
|
|
336
|
+
const listed = enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
|
|
337
|
+
const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated);
|
|
338
|
+
// TTL short-circuit: only bypass regeneration when the fingerprint matches,
|
|
339
|
+
// confirming that no tracked files changed since the last check.
|
|
333
340
|
if (!force && ttlMs > 0) {
|
|
334
341
|
const cached = freshnessCache.get(cacheKey);
|
|
335
|
-
if (cached && now - cached.checkedAt < ttlMs) {
|
|
342
|
+
if (cached && now - cached.checkedAt < ttlMs && cached.result.fingerprint === fingerprint) {
|
|
336
343
|
return cached.result;
|
|
337
344
|
}
|
|
338
345
|
}
|
|
339
|
-
const existing = readCodebaseMap(basePath);
|
|
340
|
-
const listed = enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
|
|
341
|
-
const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated);
|
|
342
346
|
const cacheAndReturn = (result) => {
|
|
343
347
|
freshnessCache.set(cacheKey, { checkedAt: now, result });
|
|
344
348
|
return result;
|
|
@@ -3,6 +3,7 @@ import { resolve } from "node:path";
|
|
|
3
3
|
import { enableDebug } from "../../debug-logger.js";
|
|
4
4
|
import { isAutoActive, isAutoPaused, pauseAuto, startAutoDetached, stopAuto, stopAutoRemote } from "../../auto.js";
|
|
5
5
|
import { handleRate } from "../../commands-rate.js";
|
|
6
|
+
import { notifyPreferenceDiagnostics } from "../../preferences-diagnostics.js";
|
|
6
7
|
import { setSessionModelOverride } from "../../session-model-override.js";
|
|
7
8
|
import { guardRemoteSession, projectRoot } from "../context.js";
|
|
8
9
|
import { findMilestoneIds } from "../../milestone-id-utils.js";
|
|
@@ -82,6 +83,7 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
82
83
|
const basePath = projectRoot();
|
|
83
84
|
if (await hasUnresolvedCloseoutBlocker(ctx, basePath))
|
|
84
85
|
return true;
|
|
86
|
+
notifyPreferenceDiagnostics(ctx, basePath, { surface: "auto-preflight" });
|
|
85
87
|
// Validate the milestone target exists and is not already complete.
|
|
86
88
|
if (milestoneId) {
|
|
87
89
|
const allIds = findMilestoneIds(basePath);
|
|
@@ -109,6 +111,7 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
109
111
|
const basePath = projectRoot();
|
|
110
112
|
if (await hasUnresolvedCloseoutBlocker(ctx, basePath))
|
|
111
113
|
return true;
|
|
114
|
+
notifyPreferenceDiagnostics(ctx, basePath, { surface: "auto-preflight" });
|
|
112
115
|
// Validate the milestone target exists and is not already complete.
|
|
113
116
|
if (milestoneId) {
|
|
114
117
|
const allIds = findMilestoneIds(basePath);
|
|
@@ -19,6 +19,7 @@ import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
|
|
|
19
19
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
20
20
|
import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
|
|
21
21
|
import { loadPrompt } from "./prompt-loader.js";
|
|
22
|
+
import { buildClaudeRuntimeFloorAdvisory } from "../../shared/claude-runtime-floor.js";
|
|
22
23
|
import { isPnpmInstall } from "../../shared/package-manager-detection.js";
|
|
23
24
|
import { buildDoctorHealIssuePayload, buildDoctorHealSummary, buildWorkflowDispatchContent, } from "./workflow-protocol.js";
|
|
24
25
|
import { restoreGsdWorkflowTools, scopeGsdWorkflowToolsForDispatch, } from "./bootstrap/register-hooks.js";
|
|
@@ -52,6 +53,21 @@ function resolveInstallCommand(pkg) {
|
|
|
52
53
|
return `pnpm add -g ${pkg}`;
|
|
53
54
|
return `npm install -g ${pkg}`;
|
|
54
55
|
}
|
|
56
|
+
function notifyClaudeRuntimeFloorAdvisory(ctx) {
|
|
57
|
+
let advisory = null;
|
|
58
|
+
try {
|
|
59
|
+
advisory = buildClaudeRuntimeFloorAdvisory({
|
|
60
|
+
agentDir: join(gsdHome(), "agent"),
|
|
61
|
+
cwd: process.cwd(),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (advisory) {
|
|
68
|
+
ctx.ui.notify(advisory, "warning");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
55
71
|
async function fetchLatestVersionForCommand(registryUrl = UPDATE_REGISTRY_URL) {
|
|
56
72
|
const controller = new AbortController();
|
|
57
73
|
const timeout = setTimeout(() => controller.abort(), UPDATE_FETCH_TIMEOUT_MS);
|
|
@@ -458,6 +474,8 @@ export async function handleUpdate(ctx, args = "") {
|
|
|
458
474
|
}
|
|
459
475
|
if (current && compareSemverLocal(latest, current) <= 0) {
|
|
460
476
|
ctx.ui.notify(`Already up to date (${formatCommandVersion(current)}).`, "info");
|
|
477
|
+
if (!browserUpdate)
|
|
478
|
+
notifyClaudeRuntimeFloorAdvisory(ctx);
|
|
461
479
|
return;
|
|
462
480
|
}
|
|
463
481
|
ctx.ui.notify(`Updating: ${formatCommandVersion(current)} → v${latest}...`, "info");
|
|
@@ -472,6 +490,8 @@ export async function handleUpdate(ctx, args = "") {
|
|
|
472
490
|
? `Updated gsd-browser to v${latest}. Restart your GSD session to use the new browser automation version.` +
|
|
473
491
|
(pathReady ? "" : "\nNote: Ensure the npm global bin directory is on your PATH so MCP automation uses the updated binary.")
|
|
474
492
|
: `Updated to v${latest}. Restart your GSD session to use the new version.`, "info");
|
|
493
|
+
if (!browserUpdate)
|
|
494
|
+
notifyClaudeRuntimeFloorAdvisory(ctx);
|
|
475
495
|
}
|
|
476
496
|
catch {
|
|
477
497
|
ctx.ui.notify(`Update failed. Try manually: ${installCmd}`, "error");
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Contains: InspectData type, formatInspectOutput, handleInspect
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import { gsdRoot } from "./paths.js";
|
|
6
|
+
import { isWorkflowDatabaseOpen, openExistingWorkflowDatabase, } from "./db-workspace.js";
|
|
9
7
|
import { logWarning } from "./workflow-logger.js";
|
|
10
8
|
import { getErrorMessage } from "./error-utils.js";
|
|
11
9
|
export function formatInspectOutput(data) {
|
|
@@ -34,11 +32,9 @@ export function formatInspectOutput(data) {
|
|
|
34
32
|
}
|
|
35
33
|
export async function handleInspect(ctx) {
|
|
36
34
|
try {
|
|
37
|
-
const {
|
|
38
|
-
if (!
|
|
39
|
-
|
|
40
|
-
const dbPath = join(gsdDir, "gsd.db");
|
|
41
|
-
if (!existsSync(gsdDir) || !existsSync(dbPath) || !openDatabase(dbPath)) {
|
|
35
|
+
const { _getAdapter } = await import("./gsd-db.js");
|
|
36
|
+
if (!isWorkflowDatabaseOpen()) {
|
|
37
|
+
if (!openExistingWorkflowDatabase(process.cwd()).ok) {
|
|
42
38
|
ctx.ui.notify("No GSD database available. Run /gsd auto to create one.", "info");
|
|
43
39
|
return;
|
|
44
40
|
}
|