@opengsd/gsd-pi 1.2.0-dev.4c756166 → 1.2.0-dev.6ccd27b3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-model-override.d.ts +15 -0
- package/dist/cli-model-override.js +21 -0
- package/dist/cli-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +2 -19
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/loader.js +6 -4
- package/dist/mcp-server.js +2 -1
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/register-agent-bundles.d.ts +11 -2
- package/dist/register-agent-bundles.js +18 -4
- package/dist/resource-loader.d.ts +10 -5
- package/dist/resource-loader.js +123 -20
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/ask-user-questions.js +3 -2
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +5 -2
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +464 -200
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +120 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
- package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
- package/dist/resources/extensions/gsd/auto/loop.js +7 -1
- package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +207 -73
- package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
- package/dist/resources/extensions/gsd/auto/phases.js +17 -2324
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
- package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
- package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
- package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
- package/dist/resources/extensions/gsd/auto-post-unit.js +43 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +47 -29
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +23 -30
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +50 -354
- package/dist/resources/extensions/gsd/auto.js +49 -22
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +69 -19
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +5 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/commands/context.js +16 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
- package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
- package/dist/resources/extensions/gsd/consent-question.js +353 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +428 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/db-writer.js +8 -17
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
- package/dist/resources/extensions/gsd/doctor-environment.js +261 -136
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +6 -21
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +172 -2048
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +144 -9
- package/dist/resources/extensions/gsd/health-widget.js +87 -28
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
- package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
- package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/notifications.js +12 -7
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +37 -24
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/preferences.js +14 -0
- package/dist/resources/extensions/gsd/projection-flush.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -5
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
- package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -1
- package/dist/resources/extensions/gsd/skill-activation.js +3 -6
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +12 -22
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-contract.js +14 -3
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +108 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +46 -55
- package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
- package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +13 -31
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +16 -35
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +367 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
- package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
- package/dist/resources/extensions/gsd/workflow-events.js +6 -18
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
- package/dist/resources/extensions/gsd/worktree-manager.js +52 -29
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +28 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +36 -31
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
- package/dist/resources/extensions/gsd/worktree.js +8 -1
- package/dist/resources/extensions/mcp-client/manager.js +6 -1
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
- package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
- package/dist/resources/shared/package-manager-detection.js +1 -1
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/SKILL.md +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/runtime-checks.d.ts +10 -0
- package/dist/runtime-checks.js +27 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-check.d.ts +2 -0
- package/dist/update-check.js +24 -1
- package/dist/update-cmd.js +20 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -11
- package/package.json +3 -3
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +6 -4
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +55 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/README.md +12 -3
- package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
- package/packages/mcp-server/dist/cli-runner.js +137 -0
- package/packages/mcp-server/dist/cli-runner.js.map +1 -0
- package/packages/mcp-server/dist/cli.js +2 -50
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
- package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
- package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
- package/packages/mcp-server/dist/pid-registry.js +452 -0
- package/packages/mcp-server/dist/pid-registry.js.map +1 -0
- package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
- package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
- package/packages/mcp-server/dist/probe-mode.js +10 -0
- package/packages/mcp-server/dist/probe-mode.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +4 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
- package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
- package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
- package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +207 -102
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +43 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +158 -17
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +132 -17
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +12 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +12 -3
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
- package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/index.d.ts +1 -1
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +1 -1
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
- package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal-image.js +54 -2
- package/packages/pi-tui/dist/terminal-image.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +8 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +72 -18
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +110 -36
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +45 -17
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/ask-user-questions.ts +7 -2
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +5 -2
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +543 -202
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +700 -7
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +168 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
- package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +7 -1
- package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +232 -76
- package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
- package/src/resources/extensions/gsd/auto/phases.ts +58 -3013
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
- package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
- package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
- package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
- package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +52 -13
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +48 -33
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +26 -28
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +56 -366
- package/src/resources/extensions/gsd/auto.ts +69 -26
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +89 -18
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +5 -16
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/commands/context.ts +16 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
- package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
- package/src/resources/extensions/gsd/consent-question.ts +431 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +519 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/db-writer.ts +11 -19
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor-environment.ts +272 -155
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -22
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +176 -2375
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +195 -29
- package/src/resources/extensions/gsd/health-widget.ts +91 -27
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
- package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
- package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
- package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/notifications.ts +13 -6
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +42 -22
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/preferences.ts +18 -0
- package/src/resources/extensions/gsd/projection-flush.ts +20 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +9 -5
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
- package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/session-lock.ts +1 -1
- package/src/resources/extensions/gsd/skill-activation.ts +3 -6
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +16 -22
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +329 -22
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +273 -37
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +54 -1
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +12 -11
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +328 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
- package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +89 -59
- package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
- package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +27 -2
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +329 -0
- package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +67 -4
- package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +75 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +24 -2
- package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
- package/src/resources/extensions/gsd/tool-contract.ts +38 -3
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +183 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +45 -70
- package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
- package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +13 -40
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +16 -44
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +442 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
- package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
- package/src/resources/extensions/gsd/workflow-events.ts +12 -20
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
- package/src/resources/extensions/gsd/worktree-manager.ts +53 -29
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +29 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +49 -44
- package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
- package/src/resources/extensions/gsd/worktree.ts +7 -1
- package/src/resources/extensions/mcp-client/manager.ts +7 -1
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
- package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
- package/src/resources/shared/package-manager-detection.ts +1 -1
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/SKILL.md +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- package/src/resources/skills/gsd-browser/SKILL.md +0 -41
- /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → avEtvPrImYTq2gGe-hVNp}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → avEtvPrImYTq2gGe-hVNp}/_ssgManifest.js +0 -0
|
@@ -201,6 +201,41 @@ export function attachExternalResultsToToolBlocks(
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
function textFromExternalResult(result: ExternalToolResultPayload | undefined): string {
|
|
205
|
+
return (result?.content ?? [])
|
|
206
|
+
.map((block) => typeof block.text === "string" ? block.text : "")
|
|
207
|
+
.join("\n");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function isEmptyToolArguments(value: unknown): boolean {
|
|
211
|
+
return !!value
|
|
212
|
+
&& typeof value === "object"
|
|
213
|
+
&& !Array.isArray(value)
|
|
214
|
+
&& Object.keys(value as Record<string, unknown>).length === 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function sameToolSurface(a: ToolCall, b: ToolCall): boolean {
|
|
218
|
+
return a.name === b.name
|
|
219
|
+
&& (a as ToolCall & { mcpServer?: string }).mcpServer === (b as ToolCall & { mcpServer?: string }).mcpServer;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function shouldSuppressDuplicateToolUnavailableBlock(
|
|
223
|
+
block: AssistantMessage["content"][number],
|
|
224
|
+
allBlocks: AssistantMessage["content"],
|
|
225
|
+
): boolean {
|
|
226
|
+
if (block.type !== "toolCall") return false;
|
|
227
|
+
const externalResult = (block as ToolCallWithExternalResult).externalResult;
|
|
228
|
+
if (!externalResult?.isError) return false;
|
|
229
|
+
if (!isEmptyToolArguments(block.arguments)) return false;
|
|
230
|
+
if (!/No such tool available:/i.test(textFromExternalResult(externalResult))) return false;
|
|
231
|
+
|
|
232
|
+
return allBlocks.some((candidate) => {
|
|
233
|
+
if (candidate.type !== "toolCall" || candidate.id === block.id) return false;
|
|
234
|
+
const candidateResult = (candidate as ToolCallWithExternalResult).externalResult;
|
|
235
|
+
return candidateResult?.isError === false && sameToolSurface(block, candidate);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
204
239
|
/**
|
|
205
240
|
* Build the final assistant content that Agent Core consumes in
|
|
206
241
|
* `externalToolExecution` mode. This preserves tool-call blocks, attaches any
|
|
@@ -221,7 +256,9 @@ export function buildFinalAssistantContent(params: {
|
|
|
221
256
|
}
|
|
222
257
|
attachExternalResultsToToolBlocks(mergedToolBlocks, params.toolResultsById);
|
|
223
258
|
|
|
224
|
-
const finalContent: AssistantMessage["content"] =
|
|
259
|
+
const finalContent: AssistantMessage["content"] = mergedToolBlocks.filter(
|
|
260
|
+
(block) => !shouldSuppressDuplicateToolUnavailableBlock(block, mergedToolBlocks),
|
|
261
|
+
);
|
|
225
262
|
if (params.pendingContent && params.pendingContent.length > 0) {
|
|
226
263
|
for (const block of params.pendingContent) {
|
|
227
264
|
if (block.type === "text" || block.type === "thinking") {
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Auto-loop closeout, milestone report, and merge helpers.
|
|
3
|
+
|
|
4
|
+
import { importExtensionModule, type ExtensionAPI, type ExtensionContext } from "@gsd/pi-coding-agent";
|
|
5
|
+
|
|
6
|
+
import { join, basename } from "node:path";
|
|
7
|
+
import { existsSync, cpSync } from "node:fs";
|
|
8
|
+
import type { AutoSession } from "./session.js";
|
|
9
|
+
import type { LoopDeps } from "./loop-deps.js";
|
|
10
|
+
import type { GSDState } from "../types.js";
|
|
11
|
+
import type { IterationContext } from "./types.js";
|
|
12
|
+
import type { PostflightResult, PreflightResult } from "../clean-root-preflight.js";
|
|
13
|
+
import { MergeConflictError } from "../git-service.js";
|
|
14
|
+
import { findUnmergedCompletedMilestones } from "../unmerged-milestone-guard.js";
|
|
15
|
+
import { getIsolationMode } from "../preferences.js";
|
|
16
|
+
import { isDbAvailable, getMilestone } from "../gsd-db.js";
|
|
17
|
+
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
18
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
19
|
+
import { gsdRoot } from "../paths.js";
|
|
20
|
+
import { atomicWriteSync } from "../atomic-write.js";
|
|
21
|
+
import { logWarning, logError } from "../workflow-logger.js";
|
|
22
|
+
import { debugLog } from "../debug-logger.js";
|
|
23
|
+
import { _resolveReportBasePath } from "./phase-helpers.js";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* If a unit is in-flight, close it out, then stop auto-mode.
|
|
27
|
+
*/
|
|
28
|
+
export async function closeoutAndStop(
|
|
29
|
+
ctx: ExtensionContext,
|
|
30
|
+
pi: ExtensionAPI,
|
|
31
|
+
s: AutoSession,
|
|
32
|
+
deps: LoopDeps,
|
|
33
|
+
reason: string,
|
|
34
|
+
): Promise<void> {
|
|
35
|
+
if (s.currentUnit) {
|
|
36
|
+
await deps.closeoutUnit(
|
|
37
|
+
ctx,
|
|
38
|
+
s.basePath,
|
|
39
|
+
s.currentUnit.type,
|
|
40
|
+
s.currentUnit.id,
|
|
41
|
+
s.currentUnit.startedAt,
|
|
42
|
+
deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id),
|
|
43
|
+
);
|
|
44
|
+
s.clearCurrentUnit();
|
|
45
|
+
}
|
|
46
|
+
await deps.stopAuto(ctx, pi, reason);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function stopOnPostflightRecoveryNeeded(
|
|
50
|
+
ic: IterationContext,
|
|
51
|
+
result: PostflightResult,
|
|
52
|
+
milestoneId: string,
|
|
53
|
+
): Promise<{ action: "break"; reason: string } | null> {
|
|
54
|
+
if (!result.needsManualRecovery) return null;
|
|
55
|
+
const { ctx, pi, deps } = ic;
|
|
56
|
+
const reason = `Post-merge stash restore failed for milestone ${milestoneId}`;
|
|
57
|
+
ctx.ui.notify(
|
|
58
|
+
`${reason}. Resolve the working tree before resuming auto-mode. ${result.message}`,
|
|
59
|
+
"error",
|
|
60
|
+
);
|
|
61
|
+
await deps.stopAuto(ctx, pi, reason);
|
|
62
|
+
return { action: "break", reason: "postflight-stash-restore-failed" };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function restorePreflightStashOrStop(
|
|
66
|
+
ic: IterationContext,
|
|
67
|
+
preflight: PreflightResult,
|
|
68
|
+
milestoneId: string,
|
|
69
|
+
): Promise<{ action: "break"; reason: string } | null> {
|
|
70
|
+
if (!preflight.stashPushed) return null;
|
|
71
|
+
const { s, deps } = ic;
|
|
72
|
+
const result = deps.postflightPopStash(
|
|
73
|
+
s.originalBasePath || s.basePath,
|
|
74
|
+
milestoneId,
|
|
75
|
+
preflight.stashMarker,
|
|
76
|
+
ic.ctx.ui.notify.bind(ic.ctx.ui),
|
|
77
|
+
);
|
|
78
|
+
return stopOnPostflightRecoveryNeeded(ic, result, milestoneId);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Run a milestone merge surrounded by preflight stash + always-on postflight
|
|
83
|
+
* pop. The previous code popped the stash only after a successful merge, which
|
|
84
|
+
* leaked `gsd-preflight-stash:M00x:*` entries whenever `mergeAndExit` threw —
|
|
85
|
+
* leaving the user's pre-merge working tree silently stashed away after a
|
|
86
|
+
* merge-conflict or other merge error. This helper restores the stash on
|
|
87
|
+
* every exit path, then surfaces the merge or stash failure (in priority
|
|
88
|
+
* order) as the loop's stop reason.
|
|
89
|
+
*
|
|
90
|
+
* Returns a `break` action when auto-mode must stop, or `null` when the merge
|
|
91
|
+
* succeeded and the stash (if any) was restored cleanly.
|
|
92
|
+
*/
|
|
93
|
+
export async function _runMilestoneMergeWithStashRestore(
|
|
94
|
+
ic: IterationContext,
|
|
95
|
+
milestoneId: string,
|
|
96
|
+
options: { preserveCloseoutTranscript?: boolean } = {},
|
|
97
|
+
): Promise<{ action: "break"; reason: string } | null> {
|
|
98
|
+
const { ctx, pi, s, deps } = ic;
|
|
99
|
+
|
|
100
|
+
const preflight = deps.preflightCleanRoot(
|
|
101
|
+
s.originalBasePath || s.basePath,
|
|
102
|
+
milestoneId,
|
|
103
|
+
ctx.ui.notify.bind(ctx.ui),
|
|
104
|
+
);
|
|
105
|
+
if (preflight.blocked) {
|
|
106
|
+
const reason = preflight.blockedReason === "unmerged-conflicts"
|
|
107
|
+
? `Pre-merge unresolved Git conflicts block milestone ${milestoneId}`
|
|
108
|
+
: `Pre-merge dirty working tree overlaps milestone ${milestoneId}`;
|
|
109
|
+
await deps.stopAuto(ctx, pi, reason, {
|
|
110
|
+
preserveCompletedMilestoneBranch: true,
|
|
111
|
+
preserveCloseoutTranscript: options.preserveCloseoutTranscript,
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
action: "break",
|
|
115
|
+
reason: preflight.blockedReason === "unmerged-conflicts"
|
|
116
|
+
? "preflight-unmerged-conflicts"
|
|
117
|
+
: "preflight-dirty-overlap",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let mergeError: unknown = null;
|
|
122
|
+
const exitResult = deps.lifecycle.exitMilestone(
|
|
123
|
+
milestoneId,
|
|
124
|
+
{ merge: true },
|
|
125
|
+
ctx.ui,
|
|
126
|
+
);
|
|
127
|
+
if (exitResult.ok) {
|
|
128
|
+
s.milestoneMergedInPhases = true;
|
|
129
|
+
try {
|
|
130
|
+
const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
131
|
+
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
132
|
+
await rebuildMarkdownProjectionsFromDb(projectRoot);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
logWarning(
|
|
135
|
+
"engine",
|
|
136
|
+
`markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
mergeError = exitResult.cause ?? new Error(`exit ${exitResult.reason}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Always attempt to restore the stashed working tree, even on merge error.
|
|
144
|
+
// postflightPopStash itself does not throw; failures surface via the
|
|
145
|
+
// PostflightResult.needsManualRecovery flag.
|
|
146
|
+
let stashResult: PostflightResult | null = null;
|
|
147
|
+
if (preflight.stashPushed) {
|
|
148
|
+
stashResult = deps.postflightPopStash(
|
|
149
|
+
s.originalBasePath || s.basePath,
|
|
150
|
+
milestoneId,
|
|
151
|
+
preflight.stashMarker,
|
|
152
|
+
ctx.ui.notify.bind(ctx.ui),
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Merge failure takes priority over stash recovery — the merge is the
|
|
157
|
+
// authoritative gate. If the stash also needed manual recovery, the user
|
|
158
|
+
// already saw the postflightPopStash notify above.
|
|
159
|
+
if (mergeError) {
|
|
160
|
+
if (mergeError instanceof MergeConflictError) {
|
|
161
|
+
// A merge conflict is a recoverable human checkpoint, not an
|
|
162
|
+
// infrastructure failure — the user resolves the conflict and runs
|
|
163
|
+
// `/gsd auto` to resume. Pause (don't stop): stopAuto tears down the
|
|
164
|
+
// session and, because `milestoneMergedInPhases` stays false here,
|
|
165
|
+
// re-runs the already-failed worktree merge in its cleanup step
|
|
166
|
+
// (#2645), then drops the user out of the interactive TUI onto a
|
|
167
|
+
// "stopped" surface.
|
|
168
|
+
const conflictReason = `Merge conflict on milestone ${milestoneId}: ${mergeError.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`;
|
|
169
|
+
ctx.ui.notify(conflictReason, "error");
|
|
170
|
+
await deps.pauseAuto(ctx, pi, {
|
|
171
|
+
message: conflictReason,
|
|
172
|
+
category: "unknown",
|
|
173
|
+
});
|
|
174
|
+
return { action: "break", reason: "merge-conflict" };
|
|
175
|
+
}
|
|
176
|
+
logError("engine", "Milestone merge failed with non-conflict error", {
|
|
177
|
+
milestone: milestoneId,
|
|
178
|
+
error: String(mergeError),
|
|
179
|
+
});
|
|
180
|
+
// Like a merge conflict, a non-conflict merge failure (index lock,
|
|
181
|
+
// network, permissions) is recoverable — the user fixes the cause and
|
|
182
|
+
// runs `/gsd auto` to resume. Pause (don't stop) so the session stays
|
|
183
|
+
// resumable and stopAuto's teardown does not re-run the failed merge.
|
|
184
|
+
const mergeFailReason = `Merge error on milestone ${milestoneId}: ${mergeError instanceof Error ? mergeError.message : String(mergeError)}. Resolve and run /gsd auto to resume.`;
|
|
185
|
+
ctx.ui.notify(mergeFailReason, "error");
|
|
186
|
+
await deps.pauseAuto(ctx, pi, {
|
|
187
|
+
message: mergeFailReason,
|
|
188
|
+
category: "unknown",
|
|
189
|
+
});
|
|
190
|
+
return { action: "break", reason: "merge-failed" };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (stashResult) {
|
|
194
|
+
return stopOnPostflightRecoveryNeeded(ic, stashResult, milestoneId);
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function _runMilestoneMergeOnceWithStashRestore(
|
|
200
|
+
ic: IterationContext,
|
|
201
|
+
milestoneId: string,
|
|
202
|
+
options: { preserveCloseoutTranscript?: boolean } = {},
|
|
203
|
+
): Promise<{ action: "break"; reason: string } | null> {
|
|
204
|
+
if (ic.s.milestoneMergedInPhases) {
|
|
205
|
+
debugLog("autoLoop", {
|
|
206
|
+
phase: "milestone-merge-skip",
|
|
207
|
+
reason: "already-merged-in-phases",
|
|
208
|
+
milestoneId,
|
|
209
|
+
});
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return _runMilestoneMergeWithStashRestore(ic, milestoneId, options);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export async function shouldSkipTerminalMilestoneCloseout(
|
|
216
|
+
s: AutoSession,
|
|
217
|
+
state: Pick<GSDState, "phase" | "lastCompletedMilestone" | "activeMilestone">,
|
|
218
|
+
mid?: string | null,
|
|
219
|
+
): Promise<{ skip: boolean; milestoneId?: string }> {
|
|
220
|
+
const closeoutMilestoneId = mid ?? s.currentMilestoneId ?? state.lastCompletedMilestone?.id;
|
|
221
|
+
if (s.completionStopInProgress) {
|
|
222
|
+
return { skip: true, milestoneId: closeoutMilestoneId };
|
|
223
|
+
}
|
|
224
|
+
if (!closeoutMilestoneId) {
|
|
225
|
+
return { skip: false };
|
|
226
|
+
}
|
|
227
|
+
if (isDbAvailable()) refreshWorkflowDatabaseFromDisk();
|
|
228
|
+
const closeoutBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
229
|
+
let closeoutMergePending = false;
|
|
230
|
+
if (getIsolationMode(closeoutBasePath) !== "none") {
|
|
231
|
+
try {
|
|
232
|
+
const blockers = await findUnmergedCompletedMilestones(closeoutBasePath);
|
|
233
|
+
closeoutMergePending = blockers.some((blocker) => blocker.milestoneId === closeoutMilestoneId);
|
|
234
|
+
} catch {
|
|
235
|
+
// Fail open: without git/DB inspection we cannot safely treat closeout as done.
|
|
236
|
+
closeoutMergePending = true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const milestoneAlreadyClosedOut = isDbAvailable()
|
|
240
|
+
&& isClosedStatus(getMilestone(closeoutMilestoneId)?.status ?? "")
|
|
241
|
+
&& !closeoutMergePending;
|
|
242
|
+
if (milestoneAlreadyClosedOut) {
|
|
243
|
+
return { skip: true, milestoneId: closeoutMilestoneId };
|
|
244
|
+
}
|
|
245
|
+
return { skip: false, milestoneId: closeoutMilestoneId };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Generate and write an HTML milestone report snapshot.
|
|
250
|
+
*/
|
|
251
|
+
export async function generateMilestoneReport(
|
|
252
|
+
s: AutoSession,
|
|
253
|
+
ctx: ExtensionContext,
|
|
254
|
+
milestoneId: string,
|
|
255
|
+
): Promise<void> {
|
|
256
|
+
const { loadVisualizerData } = await importExtensionModule<typeof import("../visualizer-data.js")>(import.meta.url, "../visualizer-data.js");
|
|
257
|
+
const { generateHtmlReport } = await importExtensionModule<typeof import("../export-html.js")>(import.meta.url, "../export-html.js");
|
|
258
|
+
const { writeReportSnapshot } = await importExtensionModule<typeof import("../reports.js")>(import.meta.url, "../reports.js");
|
|
259
|
+
const { basename } = await import("node:path");
|
|
260
|
+
|
|
261
|
+
const reportBasePath = _resolveReportBasePath(s);
|
|
262
|
+
|
|
263
|
+
const snapData = await loadVisualizerData(reportBasePath);
|
|
264
|
+
const completedMs = snapData.milestones.find(
|
|
265
|
+
(m: { id: string }) => m.id === milestoneId,
|
|
266
|
+
);
|
|
267
|
+
const msTitle = completedMs?.title ?? milestoneId;
|
|
268
|
+
const gsdVersion = process.env.GSD_VERSION ?? "0.0.0";
|
|
269
|
+
const projName = basename(reportBasePath);
|
|
270
|
+
const doneSlices = snapData.milestones.reduce(
|
|
271
|
+
(acc: number, m: { slices: { done: boolean }[] }) =>
|
|
272
|
+
acc + m.slices.filter((sl: { done: boolean }) => sl.done).length,
|
|
273
|
+
0,
|
|
274
|
+
);
|
|
275
|
+
const totalSlices = snapData.milestones.reduce(
|
|
276
|
+
(acc: number, m: { slices: unknown[] }) => acc + m.slices.length,
|
|
277
|
+
0,
|
|
278
|
+
);
|
|
279
|
+
const outPath = writeReportSnapshot({
|
|
280
|
+
basePath: reportBasePath,
|
|
281
|
+
html: generateHtmlReport(snapData, {
|
|
282
|
+
projectName: projName,
|
|
283
|
+
projectPath: reportBasePath,
|
|
284
|
+
gsdVersion,
|
|
285
|
+
milestoneId,
|
|
286
|
+
indexRelPath: "index.html",
|
|
287
|
+
}),
|
|
288
|
+
milestoneId,
|
|
289
|
+
milestoneTitle: msTitle,
|
|
290
|
+
kind: "milestone",
|
|
291
|
+
projectName: projName,
|
|
292
|
+
projectPath: reportBasePath,
|
|
293
|
+
gsdVersion,
|
|
294
|
+
totalCost: snapData.totals?.cost ?? 0,
|
|
295
|
+
totalTokens: snapData.totals?.tokens.total ?? 0,
|
|
296
|
+
totalDuration: snapData.totals?.duration ?? 0,
|
|
297
|
+
doneSlices,
|
|
298
|
+
totalSlices,
|
|
299
|
+
doneMilestones: snapData.milestones.filter(
|
|
300
|
+
(m: { status: string }) => m.status === "complete",
|
|
301
|
+
).length,
|
|
302
|
+
totalMilestones: snapData.milestones.length,
|
|
303
|
+
phase: snapData.phase,
|
|
304
|
+
});
|
|
305
|
+
ctx.ui.notify(
|
|
306
|
+
`Report saved: .gsd/reports/${basename(outPath)} — open index.html to browse progression.`,
|
|
307
|
+
"info",
|
|
308
|
+
);
|
|
309
|
+
}
|
|
@@ -7,12 +7,21 @@ import { atomicWriteSync } from "../atomic-write.js";
|
|
|
7
7
|
import { gsdRoot } from "../paths.js";
|
|
8
8
|
import type { AutoSession } from "./session.js";
|
|
9
9
|
|
|
10
|
-
type RetrySession = Pick<AutoSession, "activeRunDir" | "basePath" | "verificationRetryCount"
|
|
10
|
+
type RetrySession = Pick<AutoSession, "activeRunDir" | "basePath" | "verificationRetryCount"> & {
|
|
11
|
+
exhaustedVerificationUnits?: Set<string>;
|
|
12
|
+
};
|
|
11
13
|
|
|
12
14
|
interface RetryStoreLogDeps {
|
|
13
15
|
logFailure: (err: unknown) => void;
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
function ensureExhaustedVerificationUnits(s: RetrySession): Set<string> {
|
|
19
|
+
if (!s.exhaustedVerificationUnits) {
|
|
20
|
+
s.exhaustedVerificationUnits = new Set<string>();
|
|
21
|
+
}
|
|
22
|
+
return s.exhaustedVerificationUnits;
|
|
23
|
+
}
|
|
24
|
+
|
|
16
25
|
export function customVerifyRetryStateDir(s: Pick<AutoSession, "activeRunDir" | "basePath">): string {
|
|
17
26
|
return s.activeRunDir ? join(s.activeRunDir, "runtime") : join(gsdRoot(s.basePath), "runtime");
|
|
18
27
|
}
|
|
@@ -25,7 +34,8 @@ export function hydrateCustomVerifyRetryCounts(
|
|
|
25
34
|
s: RetrySession,
|
|
26
35
|
deps: RetryStoreLogDeps,
|
|
27
36
|
): Map<string, number> {
|
|
28
|
-
|
|
37
|
+
const exhaustedUnits = ensureExhaustedVerificationUnits(s);
|
|
38
|
+
if (s.verificationRetryCount.size > 0 || exhaustedUnits.size > 0) {
|
|
29
39
|
return s.verificationRetryCount;
|
|
30
40
|
}
|
|
31
41
|
|
|
@@ -39,6 +49,12 @@ export function hydrateCustomVerifyRetryCounts(
|
|
|
39
49
|
s.verificationRetryCount.set(key, Math.floor(value));
|
|
40
50
|
}
|
|
41
51
|
}
|
|
52
|
+
const exhausted = raw && typeof raw === "object" && Array.isArray(raw.exhausted) ? raw.exhausted : [];
|
|
53
|
+
for (const key of exhausted) {
|
|
54
|
+
if (typeof key === "string" && key.length > 0) {
|
|
55
|
+
exhaustedUnits.add(key);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
42
58
|
} catch (err) {
|
|
43
59
|
deps.logFailure(err);
|
|
44
60
|
}
|
|
@@ -51,16 +67,18 @@ export function saveCustomVerifyRetryCounts(
|
|
|
51
67
|
deps: RetryStoreLogDeps,
|
|
52
68
|
): void {
|
|
53
69
|
const retryCounts = s.verificationRetryCount;
|
|
70
|
+
const exhaustedUnits = ensureExhaustedVerificationUnits(s);
|
|
54
71
|
const filePath = customVerifyRetryStatePath(s);
|
|
55
72
|
|
|
56
73
|
try {
|
|
57
|
-
if (!retryCounts || retryCounts.size === 0) {
|
|
74
|
+
if ((!retryCounts || retryCounts.size === 0) && (!exhaustedUnits || exhaustedUnits.size === 0)) {
|
|
58
75
|
unlinkSync(filePath);
|
|
59
76
|
return;
|
|
60
77
|
}
|
|
61
78
|
mkdirSync(customVerifyRetryStateDir(s), { recursive: true });
|
|
62
79
|
atomicWriteSync(filePath, JSON.stringify({
|
|
63
80
|
counts: Object.fromEntries(retryCounts),
|
|
81
|
+
exhausted: [...exhaustedUnits],
|
|
64
82
|
updatedAt: new Date().toISOString(),
|
|
65
83
|
}) + "\n");
|
|
66
84
|
} catch (err) {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { WindowEntry } from "./types.js";
|
|
8
|
+
import { parseDispatchKey } from "./dispatch-key.js";
|
|
8
9
|
import { summarizeLogs } from "../workflow-logger.js";
|
|
9
10
|
import { getLatestForUnit } from "../db/unit-dispatches.js";
|
|
10
11
|
|
|
@@ -15,6 +16,15 @@ import { getLatestForUnit } from "../db/unit-dispatches.js";
|
|
|
15
16
|
*/
|
|
16
17
|
const ENOENT_PATH_RE = /ENOENT[^']*'([^']+)'/;
|
|
17
18
|
|
|
19
|
+
function rowInsideRetryBudget(row: ReturnType<typeof getLatestForUnit>): boolean {
|
|
20
|
+
if (!row) return false;
|
|
21
|
+
if (row.attempt_n >= row.max_attempts) return false;
|
|
22
|
+
if (!row.next_run_at) return false;
|
|
23
|
+
const nextRun = Date.parse(row.next_run_at);
|
|
24
|
+
if (!Number.isFinite(nextRun)) return false;
|
|
25
|
+
return nextRun > Date.now();
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* Phase B / codex review MEDIUM B3 — retry coupling.
|
|
20
30
|
*
|
|
@@ -24,19 +34,26 @@ const ENOENT_PATH_RE = /ENOENT[^']*'([^']+)'/;
|
|
|
24
34
|
* waiting on its own backoff. Suppress the stuck verdict in that case so
|
|
25
35
|
* the retry budget can fully drain before we declare stuck.
|
|
26
36
|
*
|
|
37
|
+
* Window keys are compound (`unitType:unitId`, legacy `unitType/unitId`)
|
|
38
|
+
* while the production dispatch ledger keys rows by the bare unit id with
|
|
39
|
+
* the unit type in its own column. Look the bare unit id up first (with a
|
|
40
|
+
* unit_type match — the production shape), then fall back to the full
|
|
41
|
+
* compound key (test fixtures / legacy rows).
|
|
42
|
+
*
|
|
27
43
|
* Returns true if the dispatch ledger says we should suppress the stuck
|
|
28
44
|
* signal; false (no suppression) when the ledger is unavailable or has
|
|
29
45
|
* no opinion.
|
|
30
46
|
*/
|
|
31
47
|
function retryBudgetSuppresses(unitKey: string): boolean {
|
|
32
48
|
try {
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
const parsed = parseDispatchKey(unitKey);
|
|
50
|
+
if (parsed) {
|
|
51
|
+
const bare = getLatestForUnit(parsed.unitId);
|
|
52
|
+
if (bare && bare.unit_type === parsed.unitType && rowInsideRetryBudget(bare)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return rowInsideRetryBudget(getLatestForUnit(unitKey));
|
|
40
57
|
} catch {
|
|
41
58
|
return false;
|
|
42
59
|
}
|
|
@@ -71,6 +88,12 @@ export function detectStuck(
|
|
|
71
88
|
const last = window[window.length - 1];
|
|
72
89
|
const prev = window[window.length - 2];
|
|
73
90
|
|
|
91
|
+
// Rules 2 and 2b share one retry-budget verdict for `last.key` — compute it
|
|
92
|
+
// at most once per invocation (it hits the dispatch ledger).
|
|
93
|
+
let suppressionVerdict: boolean | undefined;
|
|
94
|
+
const suppressed = (): boolean =>
|
|
95
|
+
(suppressionVerdict ??= retryBudgetSuppresses(last.key));
|
|
96
|
+
|
|
74
97
|
// Rule 1: Same error repeated consecutively
|
|
75
98
|
if (last.error && prev.error && last.error === prev.error) {
|
|
76
99
|
return {
|
|
@@ -83,7 +106,7 @@ export function detectStuck(
|
|
|
83
106
|
// says we're inside the retry-backoff window (codex MEDIUM B3).
|
|
84
107
|
if (window.length >= 3) {
|
|
85
108
|
const lastThree = window.slice(-3);
|
|
86
|
-
if (lastThree.every((u) => u.key === last.key) && !
|
|
109
|
+
if (lastThree.every((u) => u.key === last.key) && !suppressed()) {
|
|
87
110
|
return {
|
|
88
111
|
stuck: true,
|
|
89
112
|
reason: `${last.key} derived 3 consecutive times without progress${suffix}`,
|
|
@@ -94,7 +117,7 @@ export function detectStuck(
|
|
|
94
117
|
// Rule 2b: Same unit key 3+ times anywhere in the active window — same
|
|
95
118
|
// retry-budget suppression as Rule 2.
|
|
96
119
|
const countInWindow = window.filter((entry) => entry.key === last.key).length;
|
|
97
|
-
if (countInWindow >= 3 && !
|
|
120
|
+
if (countInWindow >= 3 && !suppressed()) {
|
|
98
121
|
return {
|
|
99
122
|
stuck: true,
|
|
100
123
|
reason: `${last.key} derived ${countInWindow} times in last ${window.length} attempts without progress${suffix}`,
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Dispatch History module — the single home for the auto
|
|
3
|
+
// orchestrator's dispatch-decision window, cross-session rehydration, and
|
|
4
|
+
// stuck detection (#482 / #442 deepening).
|
|
5
|
+
/**
|
|
6
|
+
* auto/dispatch-history.ts — Dispatch History module.
|
|
7
|
+
*
|
|
8
|
+
* Owns the sliding window of recent dispatch decisions that the Auto
|
|
9
|
+
* Orchestration module consults for idempotency and stuck-loop detection.
|
|
10
|
+
*
|
|
11
|
+
* Before this module existed the orchestrator kept a private in-memory
|
|
12
|
+
* `dispatchKeyWindow: string[]` that was reset to `[]` in start()/resume().
|
|
13
|
+
* Because a fresh orchestrator is constructed per session, the window never
|
|
14
|
+
* saw dispatches from a previous session — a unit could be re-dispatched
|
|
15
|
+
* across session restarts indefinitely (issue #482: 146 re-dispatches of the
|
|
16
|
+
* same unit). This module rehydrates the window from the DB dispatch ledger
|
|
17
|
+
* (`unit_dispatches`, via getRecentUnitKeysForProjectRoot) so stuck detection
|
|
18
|
+
* survives process restarts, and it delegates the verdict to the full
|
|
19
|
+
* detect-stuck rule set (repeat-error / consecutive / oscillation / ENOENT,
|
|
20
|
+
* with retry-budget suppression) instead of the bare saturation count.
|
|
21
|
+
*
|
|
22
|
+
* Key format: the canonical dispatch key is `${unitType}:${unitId}`
|
|
23
|
+
* (e.g. "execute-task:M001/S01/T01"). The legacy auto/phases.ts path and the
|
|
24
|
+
* DB rehydration helper use `${unitType}/${unitId}`; normalizeDispatchKey
|
|
25
|
+
* converts those on rehydrate so one format lives in the window. The key
|
|
26
|
+
* grammar itself lives in auto/dispatch-key.ts and is re-exported here for
|
|
27
|
+
* import stability.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import type { WindowEntry } from "./types.js";
|
|
31
|
+
import { buildDispatchKey, normalizeDispatchKey, parseDispatchKey } from "./dispatch-key.js";
|
|
32
|
+
import { detectStuck } from "./detect-stuck.js";
|
|
33
|
+
import {
|
|
34
|
+
getLatestForUnit,
|
|
35
|
+
getRecentUnitKeysForProjectRoot,
|
|
36
|
+
} from "../db/unit-dispatches.js";
|
|
37
|
+
import { debugLog } from "../debug-logger.js";
|
|
38
|
+
|
|
39
|
+
export { buildDispatchKey, normalizeDispatchKey, parseDispatchKey } from "./dispatch-key.js";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Size of the dispatch-decision ring buffer. Mirrors the legacy
|
|
43
|
+
* `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is preserved across the
|
|
44
|
+
* cutover (issue #5791).
|
|
45
|
+
*/
|
|
46
|
+
export const STUCK_WINDOW_SIZE = 6;
|
|
47
|
+
|
|
48
|
+
export interface DispatchHistory {
|
|
49
|
+
/**
|
|
50
|
+
* Record a dispatch decision in the window (evicting oldest-first past the
|
|
51
|
+
* window size). When the window already holds an entry for the same unit,
|
|
52
|
+
* attaches the latest ledger error summary so the repeat-error and ENOENT
|
|
53
|
+
* stuck rules can fire; first-time dispatches (the common case) skip the
|
|
54
|
+
* ledger lookup entirely. Returns the canonical key.
|
|
55
|
+
*/
|
|
56
|
+
recordDispatch(unitType: string, unitId: string): string;
|
|
57
|
+
/** Read-only view of the current window, oldest-first. */
|
|
58
|
+
getRecentWindow(): readonly WindowEntry[];
|
|
59
|
+
/** Number of window entries matching the given canonical key. */
|
|
60
|
+
countMatching(key: string): number;
|
|
61
|
+
/**
|
|
62
|
+
* Run the full detect-stuck rule set over the window (all four rules plus
|
|
63
|
+
* retry-budget suppression via the dispatch ledger).
|
|
64
|
+
*/
|
|
65
|
+
detectStuck(): { stuck: true; reason: string } | null;
|
|
66
|
+
/**
|
|
67
|
+
* Seed the window from the DB dispatch ledger (cross-session continuity,
|
|
68
|
+
* #482). Legacy `${unitType}/${unitId}` keys are normalized. Degrades to a
|
|
69
|
+
* no-op when the ledger is unavailable. Returns the number of entries
|
|
70
|
+
* rehydrated.
|
|
71
|
+
*/
|
|
72
|
+
rehydrate(): number;
|
|
73
|
+
/** Clear the window after a successful stuck recovery (or hard stop). */
|
|
74
|
+
clearOnRecovery(): void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface DispatchHistoryOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Stable project scope used to rehydrate from the dispatch ledger. Resolved
|
|
80
|
+
* lazily so worktree adoption after construction is respected. Return
|
|
81
|
+
* null/empty to skip rehydration.
|
|
82
|
+
*/
|
|
83
|
+
resolveScopeId: () => string | null;
|
|
84
|
+
windowSize?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Fetch the latest dispatch ledger error for a unit, the single canonical
|
|
89
|
+
* lookup shared by the DispatchHistory window and the legacy
|
|
90
|
+
* `loopState.recentUnits` path in dispatch.ts. The ledger keys rows by the
|
|
91
|
+
* bare unit id with the unit type in its own column, so the lookup must use
|
|
92
|
+
* the bare id and require a unit_type match (a compound `type/id` key would
|
|
93
|
+
* miss the row, and another unit type's error on the same id must never be
|
|
94
|
+
* attached — it would trip the repeat-error rule spuriously).
|
|
95
|
+
*/
|
|
96
|
+
export function lookupLatestLedgerError(unitType: string, unitId: string): string | undefined {
|
|
97
|
+
try {
|
|
98
|
+
const row = getLatestForUnit(unitId);
|
|
99
|
+
if (!row || row.unit_type !== unitType) return undefined;
|
|
100
|
+
return row.error_summary ?? undefined;
|
|
101
|
+
} catch {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function createDispatchHistory(options: DispatchHistoryOptions): DispatchHistory {
|
|
107
|
+
const windowSize = options.windowSize ?? STUCK_WINDOW_SIZE;
|
|
108
|
+
let window: WindowEntry[] = [];
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
recordDispatch(unitType: string, unitId: string): string {
|
|
112
|
+
const key = buildDispatchKey(unitType, unitId);
|
|
113
|
+
// Ledger errors only feed the repeat-error/ENOENT rules, which need a
|
|
114
|
+
// prior occurrence of the same unit in the window — first-dispatch
|
|
115
|
+
// advances (the common case) pay zero DB cost.
|
|
116
|
+
const error = window.some((entry) => entry.key === key)
|
|
117
|
+
? lookupLatestLedgerError(unitType, unitId)
|
|
118
|
+
: undefined;
|
|
119
|
+
window.push({ key, error });
|
|
120
|
+
while (window.length > windowSize) window.shift();
|
|
121
|
+
return key;
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
getRecentWindow(): readonly WindowEntry[] {
|
|
125
|
+
return window;
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
countMatching(key: string): number {
|
|
129
|
+
return window.filter((entry) => entry.key === key).length;
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
detectStuck(): { stuck: true; reason: string } | null {
|
|
133
|
+
return detectStuck(window);
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
rehydrate(): number {
|
|
137
|
+
const scopeId = options.resolveScopeId();
|
|
138
|
+
if (!scopeId) return 0;
|
|
139
|
+
try {
|
|
140
|
+
const persisted = getRecentUnitKeysForProjectRoot(scopeId, windowSize);
|
|
141
|
+
if (persisted.length === 0) return 0;
|
|
142
|
+
const rebuilt: WindowEntry[] = [];
|
|
143
|
+
for (const { key } of persisted) {
|
|
144
|
+
const normalized = normalizeDispatchKey(key);
|
|
145
|
+
const parsed = parseDispatchKey(normalized);
|
|
146
|
+
const error =
|
|
147
|
+
parsed && rebuilt.some((entry) => entry.key === normalized)
|
|
148
|
+
? lookupLatestLedgerError(parsed.unitType, parsed.unitId)
|
|
149
|
+
: undefined;
|
|
150
|
+
rebuilt.push({ key: normalized, error });
|
|
151
|
+
}
|
|
152
|
+
window = rebuilt;
|
|
153
|
+
while (window.length > windowSize) window.shift();
|
|
154
|
+
return window.length;
|
|
155
|
+
} catch (err) {
|
|
156
|
+
debugLog("dispatchHistory", {
|
|
157
|
+
phase: "rehydrate-failed",
|
|
158
|
+
error: err instanceof Error ? err.message : String(err),
|
|
159
|
+
});
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
clearOnRecovery(): void {
|
|
165
|
+
window = [];
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|