gsd-pi 2.66.1-dev.ed243f2 → 2.67.0-dev.43b0159
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/claude-cli-check.d.ts +8 -0
- package/dist/claude-cli-check.js +36 -0
- package/dist/cli.js +40 -0
- package/dist/onboarding.js +19 -2
- package/dist/resources/extensions/ask-user-questions.js +79 -11
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +4 -3
- package/dist/resources/extensions/claude-code-cli/readiness.js +63 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +10 -3
- package/dist/resources/extensions/gsd/auto/loop.js +13 -1
- package/dist/resources/extensions/gsd/auto/phases.js +22 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto/session.js +1 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +65 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +30 -28
- package/dist/resources/extensions/gsd/auto-model-selection.js +12 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +173 -25
- package/dist/resources/extensions/gsd/auto-recovery.js +11 -12
- package/dist/resources/extensions/gsd/auto.js +13 -1
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +18 -6
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +59 -5
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +8 -5
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +186 -14
- package/dist/resources/extensions/gsd/codebase-generator.js +4 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +2 -1
- package/dist/resources/extensions/gsd/commands/dispatcher.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +94 -4
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +49 -9
- package/dist/resources/extensions/gsd/context-store.js +134 -2
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -1
- package/dist/resources/extensions/gsd/detection.js +6 -0
- package/dist/resources/extensions/gsd/files.js +19 -2
- package/dist/resources/extensions/gsd/guided-flow.js +12 -8
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +2 -0
- package/dist/resources/extensions/gsd/parsers-legacy.js +3 -1
- package/dist/resources/extensions/gsd/preferences.js +6 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
- package/dist/resources/extensions/gsd/prompts/discuss.md +3 -3
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/dist/resources/extensions/gsd/prompts/rethink.md +6 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +11 -9
- package/dist/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +2 -1
- package/dist/resources/extensions/gsd/state.js +2 -1
- package/dist/resources/extensions/gsd/visualizer-overlay.js +27 -26
- package/dist/resources/extensions/gsd/workflow-reconcile.js +46 -7
- package/dist/resources/extensions/remote-questions/manager.js +8 -0
- package/dist/resources/extensions/shared/interview-ui.js +10 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- 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 +2 -2
- 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/settings-data/route.js +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 +17 -17
- 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 +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{6502.8874bcae249c02e1.js → 6502.b804e48b7919f55e.js} +3 -3
- package/dist/web/standalone/.next/static/chunks/{webpack-9fed74684e1c5bb1.js → webpack-65f0501b197d1c49.js} +1 -1
- package/package.json +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +4 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +11 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js +60 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.js +14 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +10 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +4 -3
- package/packages/pi-ai/src/utils/json-parse.ts +11 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +69 -1
- package/packages/pi-ai/src/utils/tests/json-parse.test.ts +17 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +13 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +58 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +58 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +4 -0
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +69 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +66 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +5 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +18 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +11 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +2 -2
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +13 -0
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +35 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/tui.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +43 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -0
- package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/packages/pi-tui/dist/autocomplete.js +9 -7
- package/packages/pi-tui/dist/autocomplete.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts +2 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js +54 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js.map +1 -0
- package/packages/pi-tui/dist/components/editor.d.ts +3 -1
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +14 -3
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +6 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +8 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +15 -0
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +43 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +50 -0
- package/packages/pi-tui/src/autocomplete.ts +9 -7
- package/packages/pi-tui/src/components/__tests__/editor.test.ts +64 -0
- package/packages/pi-tui/src/components/editor.ts +14 -3
- package/packages/pi-tui/src/stdin-buffer.ts +7 -0
- package/packages/pi-tui/src/tui.ts +9 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +103 -11
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +4 -3
- package/src/resources/extensions/claude-code-cli/readiness.ts +67 -12
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +12 -3
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +17 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +18 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -1
- package/src/resources/extensions/gsd/auto/loop.ts +14 -1
- package/src/resources/extensions/gsd/auto/phases.ts +27 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +14 -2
- package/src/resources/extensions/gsd/auto/session.ts +1 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +76 -16
- package/src/resources/extensions/gsd/auto-dispatch.ts +36 -35
- package/src/resources/extensions/gsd/auto-model-selection.ts +12 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +195 -25
- package/src/resources/extensions/gsd/auto-recovery.ts +15 -15
- package/src/resources/extensions/gsd/auto.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +27 -6
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +67 -6
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +11 -8
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +209 -16
- package/src/resources/extensions/gsd/codebase-generator.ts +4 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +2 -1
- package/src/resources/extensions/gsd/commands/dispatcher.ts +1 -2
- package/src/resources/extensions/gsd/commands/handlers/core.ts +113 -8
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +49 -11
- package/src/resources/extensions/gsd/context-store.ts +167 -2
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -1
- package/src/resources/extensions/gsd/detection.ts +6 -0
- package/src/resources/extensions/gsd/files.ts +21 -2
- package/src/resources/extensions/gsd/guided-flow.ts +15 -8
- package/src/resources/extensions/gsd/index.ts +6 -0
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +2 -0
- package/src/resources/extensions/gsd/parsers-legacy.ts +3 -1
- package/src/resources/extensions/gsd/preferences.ts +6 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
- package/src/resources/extensions/gsd/prompts/discuss.md +3 -3
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/rethink.md +6 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +11 -9
- package/src/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +4 -1
- package/src/resources/extensions/gsd/state.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +52 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +21 -7
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/decision-scope-cascade.test.ts +370 -0
- package/src/resources/extensions/gsd/tests/detection.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +53 -13
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/measurement.test.ts +531 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +71 -2
- package/src/resources/extensions/gsd/tests/parsers.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +26 -4
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +210 -35
- package/src/resources/extensions/gsd/visualizer-overlay.ts +31 -27
- package/src/resources/extensions/gsd/workflow-reconcile.ts +59 -8
- package/src/resources/extensions/remote-questions/manager.ts +9 -0
- package/src/resources/extensions/shared/interview-ui.ts +13 -0
- /package/dist/web/standalone/.next/static/{HAq0VE4k68rhRvJbQL1VW → CrKrzIIxk55witDF1eS0L}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{HAq0VE4k68rhRvJbQL1VW → CrKrzIIxk55witDF1eS0L}/_ssgManifest.js +0 -0
|
@@ -13,7 +13,7 @@ import { appendEvent } from "./workflow-events.js";
|
|
|
13
13
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
14
14
|
import { clearParseCache } from "./files.js";
|
|
15
15
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
16
|
-
import { isDbAvailable, getTask, getSlice, getSliceTasks, updateTaskStatus, updateSliceStatus } from "./gsd-db.js";
|
|
16
|
+
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus } from "./gsd-db.js";
|
|
17
17
|
import { isValidationTerminal } from "./state.js";
|
|
18
18
|
import { getErrorMessage } from "./error-utils.js";
|
|
19
19
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -248,8 +248,7 @@ export function verifyExpectedArtifact(
|
|
|
248
248
|
if (gateIds.length === 0) return true;
|
|
249
249
|
|
|
250
250
|
try {
|
|
251
|
-
const
|
|
252
|
-
const pending = getPending(mid, sid, "slice");
|
|
251
|
+
const pending = getPendingGates(mid, sid, "slice");
|
|
253
252
|
const pendingIds = new Set(pending.map((g: any) => g.gate_id));
|
|
254
253
|
// All dispatched gates must no longer be pending
|
|
255
254
|
for (const gid of gateIds) {
|
|
@@ -480,22 +479,23 @@ function abortAndResetMerge(
|
|
|
480
479
|
}
|
|
481
480
|
}
|
|
482
481
|
|
|
482
|
+
export type MergeReconcileResult = "clean" | "reconciled" | "blocked";
|
|
483
|
+
|
|
483
484
|
/**
|
|
484
485
|
* Detect leftover merge state from a prior session and reconcile it.
|
|
485
486
|
* If MERGE_HEAD or SQUASH_MSG exists, check whether conflicts are resolved.
|
|
486
|
-
* If resolved: finalize the commit. If
|
|
487
|
-
*
|
|
488
|
-
* Returns true if state was dirty and re-derivation is needed.
|
|
487
|
+
* If resolved: finalize the commit. If only .gsd conflicts remain: auto-resolve.
|
|
488
|
+
* If code conflicts remain: fail safe without modifying the worktree.
|
|
489
489
|
*/
|
|
490
490
|
export function reconcileMergeState(
|
|
491
491
|
basePath: string,
|
|
492
492
|
ctx: ExtensionContext,
|
|
493
|
-
):
|
|
493
|
+
): MergeReconcileResult {
|
|
494
494
|
const mergeHeadPath = join(basePath, ".git", "MERGE_HEAD");
|
|
495
495
|
const squashMsgPath = join(basePath, ".git", "SQUASH_MSG");
|
|
496
496
|
const hasMergeHead = existsSync(mergeHeadPath);
|
|
497
497
|
const hasSquashMsg = existsSync(squashMsgPath);
|
|
498
|
-
if (!hasMergeHead && !hasSquashMsg) return
|
|
498
|
+
if (!hasMergeHead && !hasSquashMsg) return "clean";
|
|
499
499
|
|
|
500
500
|
const conflictedFiles = nativeConflictFiles(basePath);
|
|
501
501
|
if (conflictedFiles.length === 0) {
|
|
@@ -511,7 +511,7 @@ export function reconcileMergeState(
|
|
|
511
511
|
} catch (err) {
|
|
512
512
|
const errorMessage = getErrorMessage(err);
|
|
513
513
|
ctx.ui.notify(`Failed to finalize leftover merge/squash commit: ${errorMessage}`, "error");
|
|
514
|
-
return
|
|
514
|
+
return "blocked";
|
|
515
515
|
}
|
|
516
516
|
} else {
|
|
517
517
|
// Still conflicted — try auto-resolving .gsd/ state file conflicts (#530)
|
|
@@ -551,15 +551,16 @@ export function reconcileMergeState(
|
|
|
551
551
|
);
|
|
552
552
|
}
|
|
553
553
|
} else {
|
|
554
|
-
// Code conflicts present —
|
|
555
|
-
|
|
554
|
+
// Code conflicts present — fail safe and preserve any manual resolution
|
|
555
|
+
// work instead of discarding it with merge --abort/reset --hard.
|
|
556
556
|
ctx.ui.notify(
|
|
557
|
-
"Detected leftover merge state with unresolved conflicts
|
|
558
|
-
"
|
|
557
|
+
"Detected leftover merge state with unresolved code conflicts. Auto-mode will pause without modifying the worktree so manual conflict resolution is preserved.",
|
|
558
|
+
"error",
|
|
559
559
|
);
|
|
560
|
+
return "blocked";
|
|
560
561
|
}
|
|
561
562
|
}
|
|
562
|
-
return
|
|
563
|
+
return "reconciled";
|
|
563
564
|
}
|
|
564
565
|
|
|
565
566
|
// ─── Loop Remediation ─────────────────────────────────────────────────────────
|
|
@@ -618,4 +619,3 @@ export function buildLoopRemediationSteps(
|
|
|
618
619
|
}
|
|
619
620
|
return null;
|
|
620
621
|
}
|
|
621
|
-
|
|
@@ -1205,7 +1205,18 @@ export async function startAuto(
|
|
|
1205
1205
|
s.active = true;
|
|
1206
1206
|
s.verbose = verboseMode;
|
|
1207
1207
|
s.stepMode = requestedStepMode;
|
|
1208
|
-
|
|
1208
|
+
// Preserve the original cmdCtx (ExtensionCommandContext with newSession)
|
|
1209
|
+
// when resuming from a provider-error pause. The resume callback receives
|
|
1210
|
+
// an ExtensionContext (from the agent_end hook) which lacks newSession —
|
|
1211
|
+
// using it would crash runUnit with "newSession is not a function".
|
|
1212
|
+
// Only override if the new ctx actually has newSession (user-initiated resume).
|
|
1213
|
+
if ("newSession" in ctx && typeof (ctx as any).newSession === "function") {
|
|
1214
|
+
s.cmdCtx = ctx;
|
|
1215
|
+
} else if (!s.cmdCtx) {
|
|
1216
|
+
// No saved cmdCtx — this shouldn't happen, but handle gracefully
|
|
1217
|
+
s.cmdCtx = ctx as ExtensionCommandContext;
|
|
1218
|
+
}
|
|
1219
|
+
// else: keep existing s.cmdCtx which has the real newSession
|
|
1209
1220
|
s.basePath = base;
|
|
1210
1221
|
setLogBasePath(base);
|
|
1211
1222
|
if (!s.autoStartTime || s.autoStartTime <= 0) s.autoStartTime = Date.now();
|
|
@@ -19,7 +19,17 @@ import {
|
|
|
19
19
|
|
|
20
20
|
const retryState = createRetryState();
|
|
21
21
|
const MAX_NETWORK_RETRIES = 2;
|
|
22
|
-
const MAX_TRANSIENT_AUTO_RESUMES =
|
|
22
|
+
const MAX_TRANSIENT_AUTO_RESUMES = 8;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Reset the module-level retry state so a resumed auto-session starts fresh.
|
|
26
|
+
* Called by provider-error-resume.ts before startAuto() — without this, the
|
|
27
|
+
* consecutiveTransientCount accumulates across pause/resume cycles and locks
|
|
28
|
+
* out auto-resume after MAX_TRANSIENT_AUTO_RESUMES total (not consecutive) errors.
|
|
29
|
+
*/
|
|
30
|
+
export function resetTransientRetryState(): void {
|
|
31
|
+
resetRetryState(retryState);
|
|
32
|
+
}
|
|
23
33
|
|
|
24
34
|
async function pauseTransientWithBackoff(
|
|
25
35
|
cls: ErrorClass,
|
|
@@ -114,6 +124,29 @@ export async function handleAgentEnd(
|
|
|
114
124
|
// ── 1. Classify using rawErrorMsg to avoid prose false-positives ────
|
|
115
125
|
const cls = classifyError(rawErrorMsg, explicitRetryAfterMs);
|
|
116
126
|
|
|
127
|
+
// ── 1b. Defer to Core RetryHandler for transient errors ─────────────
|
|
128
|
+
// The Core RetryHandler (agent-session.ts) processes retryable errors
|
|
129
|
+
// AFTER this extension handler, in the same _processAgentEvent() call.
|
|
130
|
+
// For transient errors (overloaded, rate limit, server), the Core will
|
|
131
|
+
// retry in-context — same session, same conversation — which is strictly
|
|
132
|
+
// better than our Layer 2 pause+resume (which creates a new session).
|
|
133
|
+
//
|
|
134
|
+
// If we react here AND the Core also retries, we race: pauseAuto tears
|
|
135
|
+
// down the session while agent.continue() starts a new turn.
|
|
136
|
+
//
|
|
137
|
+
// Solution: Do nothing for transient errors. The Core RetryHandler
|
|
138
|
+
// runs next in _processAgentEvent and will either:
|
|
139
|
+
// a) Retry successfully → new agent_end (success) → we see it next time
|
|
140
|
+
// b) Exhaust retries → the agent stays idle, autoLoop's unit timeout
|
|
141
|
+
// or stuck detection handles it
|
|
142
|
+
//
|
|
143
|
+
// We do NOT call resolveAgentEnd here — that would unblock autoLoop
|
|
144
|
+
// prematurely while the Core is still retrying in the same session.
|
|
145
|
+
// We do NOT call pauseAuto — that would tear down the session.
|
|
146
|
+
if (isTransient(cls)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
117
150
|
// Cap rate-limit backoff for CLI-style providers (openai-codex, google-gemini-cli)
|
|
118
151
|
// which use per-user quotas with shorter windows (#2922).
|
|
119
152
|
if (cls.kind === "rate-limit") {
|
|
@@ -7,6 +7,16 @@ import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
|
7
7
|
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
8
8
|
import { StringEnum } from "@gsd/pi-ai";
|
|
9
9
|
import { logError } from "../workflow-logger.js";
|
|
10
|
+
import { getErrorMessage } from "../error-utils.js";
|
|
11
|
+
import { shouldBlockContextArtifactSave } from "./write-gate.js";
|
|
12
|
+
|
|
13
|
+
const SUPPORTED_SUMMARY_ARTIFACT_TYPES = ["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT", "CONTEXT-DRAFT"] as const;
|
|
14
|
+
|
|
15
|
+
export function isSupportedSummaryArtifactType(
|
|
16
|
+
artifactType: string,
|
|
17
|
+
): artifactType is (typeof SUPPORTED_SUMMARY_ARTIFACT_TYPES)[number] {
|
|
18
|
+
return (SUPPORTED_SUMMARY_ARTIFACT_TYPES as readonly string[]).includes(artifactType);
|
|
19
|
+
}
|
|
10
20
|
|
|
11
21
|
/**
|
|
12
22
|
* Register an alias tool that shares the same execute function as its canonical counterpart.
|
|
@@ -283,13 +293,23 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
283
293
|
details: { operation: "save_summary", error: "db_unavailable" } as any,
|
|
284
294
|
};
|
|
285
295
|
}
|
|
286
|
-
|
|
287
|
-
if (!validTypes.includes(params.artifact_type)) {
|
|
296
|
+
if (!isSupportedSummaryArtifactType(params.artifact_type)) {
|
|
288
297
|
return {
|
|
289
|
-
content: [{ type: "text" as const, text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${
|
|
298
|
+
content: [{ type: "text" as const, text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${SUPPORTED_SUMMARY_ARTIFACT_TYPES.join(", ")}` }],
|
|
290
299
|
details: { operation: "save_summary", error: "invalid_artifact_type" } as any,
|
|
291
300
|
};
|
|
292
301
|
}
|
|
302
|
+
const contextGuard = shouldBlockContextArtifactSave(
|
|
303
|
+
params.artifact_type,
|
|
304
|
+
params.milestone_id ?? null,
|
|
305
|
+
params.slice_id ?? null,
|
|
306
|
+
);
|
|
307
|
+
if (contextGuard.block) {
|
|
308
|
+
return {
|
|
309
|
+
content: [{ type: "text" as const, text: `Error saving artifact: ${contextGuard.reason ?? "context write blocked"}` }],
|
|
310
|
+
details: { operation: "save_summary", error: "context_write_blocked" } as any,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
293
313
|
try {
|
|
294
314
|
let relativePath: string;
|
|
295
315
|
if (params.task_id && params.slice_id) {
|
|
@@ -333,16 +353,17 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
333
353
|
"Computes the file path from milestone/slice/task IDs automatically.",
|
|
334
354
|
promptSnippet: "Save a GSD artifact (summary/research/context/assessment) to DB and disk",
|
|
335
355
|
promptGuidelines: [
|
|
336
|
-
"Use gsd_summary_save to persist structured artifacts (SUMMARY, RESEARCH, CONTEXT, ASSESSMENT).",
|
|
356
|
+
"Use gsd_summary_save to persist structured artifacts (SUMMARY, RESEARCH, CONTEXT, ASSESSMENT, CONTEXT-DRAFT).",
|
|
337
357
|
"milestone_id is required. slice_id and task_id are optional — they determine the file path.",
|
|
338
358
|
"The tool computes the relative path automatically: milestones/M001/M001-SUMMARY.md, milestones/M001/slices/S01/S01-SUMMARY.md, etc.",
|
|
339
|
-
"artifact_type must be one of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT.",
|
|
359
|
+
"artifact_type must be one of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT, CONTEXT-DRAFT.",
|
|
360
|
+
"Use CONTEXT-DRAFT for incremental draft persistence; use CONTEXT for the final milestone context after depth verification.",
|
|
340
361
|
],
|
|
341
362
|
parameters: Type.Object({
|
|
342
363
|
milestone_id: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
343
364
|
slice_id: Type.Optional(Type.String({ description: "Slice ID (e.g. S01)" })),
|
|
344
365
|
task_id: Type.Optional(Type.String({ description: "Task ID (e.g. T01)" })),
|
|
345
|
-
artifact_type: Type.String({ description: "One of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT" }),
|
|
366
|
+
artifact_type: Type.String({ description: "One of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT, CONTEXT-DRAFT" }),
|
|
346
367
|
content: Type.String({ description: "The full markdown content of the artifact" }),
|
|
347
368
|
}),
|
|
348
369
|
execute: summarySaveExecute,
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
} from "@gsd/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
import { getAutoDashboardData, startAuto, type AutoDashboardData } from "../auto.js";
|
|
8
|
+
import { resetTransientRetryState } from "./agent-end-recovery.js";
|
|
8
9
|
|
|
9
10
|
type AutoResumeSnapshot = Pick<AutoDashboardData, "active" | "paused" | "stepMode" | "basePath">;
|
|
10
11
|
|
|
@@ -42,6 +43,11 @@ export async function resumeAutoAfterProviderDelay(
|
|
|
42
43
|
return "missing-base";
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
// Reset the transient retry counter before restarting — without this,
|
|
47
|
+
// consecutiveTransientCount accumulates across pause/resume cycles and
|
|
48
|
+
// permanently locks out auto-resume after MAX_TRANSIENT_AUTO_RESUMES errors.
|
|
49
|
+
resetTransientRetryState();
|
|
50
|
+
|
|
45
51
|
await deps.startAuto(
|
|
46
52
|
ctx as ExtensionCommandContext,
|
|
47
53
|
pi,
|
|
@@ -6,7 +6,7 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
|
|
|
6
6
|
import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
7
7
|
import { buildBeforeAgentStartResult } from "./system-context.js";
|
|
8
8
|
import { handleAgentEnd } from "./agent-end-recovery.js";
|
|
9
|
-
import { clearDiscussionFlowState,
|
|
9
|
+
import { clearDiscussionFlowState, isDepthConfirmationAnswer, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockQueueExecution, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
10
10
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
11
11
|
import { cleanupQuickBranch } from "../quick.js";
|
|
12
12
|
import { getDiscussionMilestoneId } from "../guided-flow.js";
|
|
@@ -24,6 +24,7 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
|
|
|
24
24
|
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
25
25
|
import { initNotificationStore } from "../notification-store.js";
|
|
26
26
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
27
|
+
import { initHealthWidget } from "../health-widget.js";
|
|
27
28
|
|
|
28
29
|
// Skip the welcome screen on the very first session_start — cli.ts already
|
|
29
30
|
// printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
|
|
@@ -39,6 +40,7 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
39
40
|
initNotificationStore(process.cwd());
|
|
40
41
|
installNotifyInterceptor(ctx);
|
|
41
42
|
initNotificationWidget(ctx);
|
|
43
|
+
initHealthWidget(ctx);
|
|
42
44
|
resetWriteGateState();
|
|
43
45
|
resetToolCallLoopGuard();
|
|
44
46
|
resetAskUserQuestionsCache();
|
|
@@ -162,12 +164,50 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
162
164
|
});
|
|
163
165
|
|
|
164
166
|
pi.on("tool_call", async (event) => {
|
|
167
|
+
const discussionBasePath = process.cwd();
|
|
165
168
|
// ── Loop guard: block repeated identical tool calls ──
|
|
166
169
|
const loopCheck = checkToolCallLoop(event.toolName, event.input as Record<string, unknown>);
|
|
167
170
|
if (loopCheck.block) {
|
|
168
171
|
return { block: true, reason: loopCheck.reason };
|
|
169
172
|
}
|
|
170
173
|
|
|
174
|
+
// ── Discussion gate enforcement: track pending gate questions ─────────
|
|
175
|
+
// Only gate-shaped ask_user_questions calls should block execution.
|
|
176
|
+
// The gate stays pending until the user selects the approval option.
|
|
177
|
+
if (event.toolName === "ask_user_questions") {
|
|
178
|
+
const milestoneId = getDiscussionMilestoneId(discussionBasePath);
|
|
179
|
+
const inDiscussion = milestoneId !== null || isQueuePhaseActive();
|
|
180
|
+
if (inDiscussion) {
|
|
181
|
+
const questions: any[] = (event.input as any)?.questions ?? [];
|
|
182
|
+
const questionId = questions.find((question) => typeof question?.id === "string" && isGateQuestionId(question.id))?.id;
|
|
183
|
+
if (typeof questionId === "string") {
|
|
184
|
+
setPendingGate(questionId);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ── Discussion gate enforcement: block tool calls while gate is pending ──
|
|
190
|
+
// If ask_user_questions was called with a gate ID but hasn't been confirmed,
|
|
191
|
+
// block all non-read-only tool calls to prevent the model from skipping gates.
|
|
192
|
+
if (getPendingGate()) {
|
|
193
|
+
const milestoneId = getDiscussionMilestoneId(discussionBasePath);
|
|
194
|
+
if (isToolCallEventType("bash", event)) {
|
|
195
|
+
const bashGuard = shouldBlockPendingGateBash(
|
|
196
|
+
event.input.command,
|
|
197
|
+
milestoneId,
|
|
198
|
+
isQueuePhaseActive(),
|
|
199
|
+
);
|
|
200
|
+
if (bashGuard.block) return bashGuard;
|
|
201
|
+
} else {
|
|
202
|
+
const gateGuard = shouldBlockPendingGate(
|
|
203
|
+
event.toolName,
|
|
204
|
+
milestoneId,
|
|
205
|
+
isQueuePhaseActive(),
|
|
206
|
+
);
|
|
207
|
+
if (gateGuard.block) return gateGuard;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
171
211
|
// ── Queue-mode execution guard (#2545): block source-code mutations ──
|
|
172
212
|
// When /gsd queue is active, the agent should only create milestones,
|
|
173
213
|
// not execute work. Block write/edit to non-.gsd/ paths and bash commands
|
|
@@ -210,8 +250,7 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
210
250
|
const result = shouldBlockContextWrite(
|
|
211
251
|
event.toolName,
|
|
212
252
|
event.input.path,
|
|
213
|
-
getDiscussionMilestoneId(),
|
|
214
|
-
isDepthVerified(),
|
|
253
|
+
getDiscussionMilestoneId(discussionBasePath),
|
|
215
254
|
isQueuePhaseActive(),
|
|
216
255
|
);
|
|
217
256
|
if (result.block) return result;
|
|
@@ -239,21 +278,43 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
239
278
|
|
|
240
279
|
pi.on("tool_result", async (event) => {
|
|
241
280
|
if (event.toolName !== "ask_user_questions") return;
|
|
242
|
-
const milestoneId = getDiscussionMilestoneId();
|
|
281
|
+
const milestoneId = getDiscussionMilestoneId(process.cwd());
|
|
243
282
|
const queueActive = isQueuePhaseActive();
|
|
244
283
|
if (!milestoneId && !queueActive) return;
|
|
245
284
|
|
|
246
285
|
const details = event.details as any;
|
|
247
|
-
if (details?.cancelled || !details?.response) return;
|
|
248
286
|
|
|
287
|
+
// ── Discussion gate enforcement: handle gate question responses ──
|
|
288
|
+
// If the result is cancelled or has no response, the pending gate stays active
|
|
289
|
+
// so the model is blocked from non-read-only tools until it re-asks.
|
|
290
|
+
// If the user responded at all (even "needs adjustment"), clear the pending gate
|
|
291
|
+
// because the user engaged — the prompt handles the re-ask-after-adjustment flow.
|
|
249
292
|
const questions: any[] = (event.input as any)?.questions ?? [];
|
|
293
|
+
const currentPendingGate = getPendingGate();
|
|
294
|
+
if (currentPendingGate) {
|
|
295
|
+
if (details?.cancelled || !details?.response) {
|
|
296
|
+
// Gate stays pending — model will be blocked from non-read-only tools
|
|
297
|
+
// until it re-asks and gets a valid response
|
|
298
|
+
} else {
|
|
299
|
+
const pendingQuestion = questions.find((question) => question?.id === currentPendingGate);
|
|
300
|
+
if (pendingQuestion) {
|
|
301
|
+
const answer = details.response?.answers?.[currentPendingGate];
|
|
302
|
+
if (isDepthConfirmationAnswer(answer?.selected, pendingQuestion.options)) {
|
|
303
|
+
clearPendingGate();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (details?.cancelled || !details?.response) return;
|
|
310
|
+
|
|
250
311
|
for (const question of questions) {
|
|
251
312
|
if (typeof question.id === "string" && question.id.includes("depth_verification")) {
|
|
252
313
|
// Only unlock the gate if the user selected the first option (confirmation).
|
|
253
314
|
// Cross-references against the question's defined options to reject free-form "Other" text.
|
|
254
315
|
const answer = details.response?.answers?.[question.id];
|
|
255
316
|
if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
|
|
256
|
-
markDepthVerified();
|
|
317
|
+
markDepthVerified(extractDepthVerificationMilestoneId(question.id) ?? milestoneId);
|
|
257
318
|
}
|
|
258
319
|
break;
|
|
259
320
|
}
|
|
@@ -7,18 +7,20 @@ import { Key } from "@gsd/pi-tui";
|
|
|
7
7
|
import { GSDDashboardOverlay } from "../dashboard-overlay.js";
|
|
8
8
|
import { GSDNotificationOverlay } from "../notification-overlay.js";
|
|
9
9
|
import { ParallelMonitorOverlay } from "../parallel-monitor-overlay.js";
|
|
10
|
+
import { projectRoot } from "../commands/context.js";
|
|
10
11
|
import { shortcutDesc } from "../../shared/mod.js";
|
|
11
12
|
|
|
12
13
|
export function registerShortcuts(pi: ExtensionAPI): void {
|
|
13
14
|
pi.registerShortcut(Key.ctrlAlt("g"), {
|
|
14
15
|
description: shortcutDesc("Open GSD dashboard", "/gsd status"),
|
|
15
16
|
handler: async (ctx) => {
|
|
16
|
-
|
|
17
|
+
const basePath = projectRoot();
|
|
18
|
+
if (!existsSync(join(basePath, ".gsd"))) {
|
|
17
19
|
ctx.ui.notify("No .gsd/ directory found. Run /gsd to start.", "info");
|
|
18
20
|
return;
|
|
19
21
|
}
|
|
20
|
-
await ctx.ui.custom<
|
|
21
|
-
(tui, theme, _kb, done) => new GSDDashboardOverlay(tui, theme, () => done()),
|
|
22
|
+
await ctx.ui.custom<boolean>(
|
|
23
|
+
(tui, theme, _kb, done) => new GSDDashboardOverlay(tui, theme, () => done(true)),
|
|
22
24
|
{
|
|
23
25
|
overlay: true,
|
|
24
26
|
overlayOptions: {
|
|
@@ -35,8 +37,8 @@ export function registerShortcuts(pi: ExtensionAPI): void {
|
|
|
35
37
|
pi.registerShortcut(Key.ctrlAlt("n"), {
|
|
36
38
|
description: shortcutDesc("Open notification history", "/gsd notifications"),
|
|
37
39
|
handler: async (ctx) => {
|
|
38
|
-
await ctx.ui.custom<
|
|
39
|
-
(tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done()),
|
|
40
|
+
await ctx.ui.custom<boolean>(
|
|
41
|
+
(tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done(true)),
|
|
40
42
|
{
|
|
41
43
|
overlay: true,
|
|
42
44
|
overlayOptions: {
|
|
@@ -54,13 +56,14 @@ export function registerShortcuts(pi: ExtensionAPI): void {
|
|
|
54
56
|
pi.registerShortcut(Key.ctrlAlt("p"), {
|
|
55
57
|
description: shortcutDesc("Open parallel worker monitor", "/gsd parallel watch"),
|
|
56
58
|
handler: async (ctx) => {
|
|
57
|
-
const
|
|
59
|
+
const basePath = projectRoot();
|
|
60
|
+
const parallelDir = join(basePath, ".gsd", "parallel");
|
|
58
61
|
if (!existsSync(parallelDir)) {
|
|
59
62
|
ctx.ui.notify("No parallel workers found. Run /gsd parallel start first.", "info");
|
|
60
63
|
return;
|
|
61
64
|
}
|
|
62
|
-
await ctx.ui.custom<
|
|
63
|
-
(tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done()),
|
|
65
|
+
await ctx.ui.custom<boolean>(
|
|
66
|
+
(tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done(true)),
|
|
64
67
|
{
|
|
65
68
|
overlay: true,
|
|
66
69
|
overlayOptions: {
|