@opengsd/gsd-pi 1.1.1-dev.b2556262 → 1.2.0-dev.844675c9

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.
Files changed (211) hide show
  1. package/dist/project-sessions.js +4 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -9
  4. package/dist/resources/extensions/gsd/auto/contracts.js +8 -1
  5. package/dist/resources/extensions/gsd/auto/orchestrator.js +659 -57
  6. package/dist/resources/extensions/gsd/auto-prompts.js +110 -1
  7. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  8. package/dist/resources/extensions/gsd/auto-tool-tracking.js +5 -0
  9. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +29 -0
  10. package/dist/resources/extensions/gsd/auto-worktree.js +24 -17
  11. package/dist/resources/extensions/gsd/auto.js +62 -464
  12. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +4 -1
  13. package/dist/resources/extensions/gsd/debug-logger.js +10 -0
  14. package/dist/resources/extensions/gsd/doctor-proactive.js +7 -2
  15. package/dist/resources/extensions/gsd/guided-flow.js +2 -2
  16. package/dist/resources/extensions/gsd/markdown-renderer.js +31 -32
  17. package/dist/resources/extensions/gsd/mcp-filter.js +6 -0
  18. package/dist/resources/extensions/gsd/native-git-bridge.js +45 -0
  19. package/dist/resources/extensions/gsd/prompts/discuss.md +6 -7
  20. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
  21. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -5
  22. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
  23. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
  24. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  25. package/dist/resources/extensions/gsd/prompts/research-milestone.md +2 -2
  26. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
  27. package/dist/resources/extensions/gsd/schemas/parsers.js +6 -1
  28. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +21 -1
  29. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +169 -20
  30. package/dist/resources/extensions/gsd/user-input-boundary.js +42 -4
  31. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  32. package/dist/web/standalone/.next/BUILD_ID +1 -1
  33. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  34. package/dist/web/standalone/.next/build-manifest.json +2 -2
  35. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  36. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  37. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  45. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  53. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  54. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  55. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  56. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  57. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  58. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  59. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  60. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  61. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  62. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  64. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  65. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  66. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  67. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  68. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  69. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  70. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  71. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  72. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  73. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  74. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  75. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  76. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  77. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  78. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  79. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  80. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  81. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  82. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  83. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  84. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  85. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  86. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  87. package/dist/web/standalone/.next/server/app/index.html +1 -1
  88. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  95. package/dist/web/standalone/.next/server/chunks/5047.js +2 -0
  96. package/dist/web/standalone/.next/server/chunks/5124.js +1 -0
  97. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  98. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  100. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  101. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  102. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  103. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  104. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  105. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  106. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  107. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  108. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  109. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  110. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  111. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  112. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  113. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  114. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  115. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  116. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  117. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  118. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  119. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  120. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  121. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  122. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  123. package/package.json +16 -11
  124. package/packages/cloud-mcp-gateway/package.json +2 -2
  125. package/packages/contracts/package.json +1 -1
  126. package/packages/daemon/package.json +4 -4
  127. package/packages/gsd-agent-core/package.json +5 -5
  128. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +1 -1
  129. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  130. package/packages/gsd-agent-modes/package.json +7 -7
  131. package/packages/mcp-server/package.json +3 -3
  132. package/packages/native/package.json +1 -1
  133. package/packages/pi-agent-core/package.json +1 -1
  134. package/packages/pi-ai/dist/models.generated.d.ts +0 -34
  135. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  136. package/packages/pi-ai/dist/models.generated.js +12 -46
  137. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  138. package/packages/pi-ai/package.json +1 -1
  139. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  140. package/packages/pi-coding-agent/dist/core/auth-storage.js +11 -3
  141. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  142. package/packages/pi-coding-agent/package.json +7 -7
  143. package/packages/pi-tui/package.json +2 -2
  144. package/packages/rpc-client/package.json +2 -2
  145. package/pkg/package.json +1 -1
  146. package/scripts/install/deps.js +10 -0
  147. package/scripts/link-workspace-packages.cjs +7 -40
  148. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -8
  149. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +2 -2
  150. package/src/resources/extensions/gsd/auto/contracts.ts +8 -119
  151. package/src/resources/extensions/gsd/auto/orchestrator.ts +794 -58
  152. package/src/resources/extensions/gsd/auto-prompts.ts +114 -1
  153. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  154. package/src/resources/extensions/gsd/auto-tool-tracking.ts +5 -0
  155. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +33 -0
  156. package/src/resources/extensions/gsd/auto-worktree.ts +24 -16
  157. package/src/resources/extensions/gsd/auto.ts +81 -500
  158. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +4 -0
  159. package/src/resources/extensions/gsd/debug-logger.ts +11 -0
  160. package/src/resources/extensions/gsd/doctor-proactive.ts +8 -2
  161. package/src/resources/extensions/gsd/guided-flow.ts +2 -2
  162. package/src/resources/extensions/gsd/markdown-renderer.ts +38 -19
  163. package/src/resources/extensions/gsd/mcp-filter.ts +7 -0
  164. package/src/resources/extensions/gsd/native-git-bridge.ts +48 -0
  165. package/src/resources/extensions/gsd/prompts/discuss.md +6 -7
  166. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
  167. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -5
  168. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
  169. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
  170. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  171. package/src/resources/extensions/gsd/prompts/research-milestone.md +2 -2
  172. package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
  173. package/src/resources/extensions/gsd/schemas/parsers.ts +6 -1
  174. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +31 -10
  175. package/src/resources/extensions/gsd/tests/artifact-db-drift-memo.test.ts +66 -0
  176. package/src/resources/extensions/gsd/tests/auto-dispatch-baseline-harness.test.ts +53 -0
  177. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +590 -855
  178. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +38 -10
  179. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +15 -0
  180. package/src/resources/extensions/gsd/tests/execute-summary-save-empty-project.test.ts +64 -1
  181. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +157 -0
  182. package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +75 -0
  183. package/src/resources/extensions/gsd/tests/native-merge-regular.test.ts +139 -0
  184. package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +127 -0
  185. package/src/resources/extensions/gsd/tests/parse-project-milestone-bridge.test.ts +77 -0
  186. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +4 -2
  187. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -2
  188. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +65 -0
  189. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +19 -5
  190. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +38 -0
  191. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +62 -0
  192. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +24 -0
  193. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -3
  194. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +183 -21
  195. package/src/resources/extensions/gsd/user-input-boundary.ts +37 -5
  196. package/dist/web/standalone/.next/server/chunks/678.js +0 -2
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +0 -21
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +0 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +0 -213
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +0 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts +0 -28
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts.map +0 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js +0 -249
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js.map +0 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts +0 -19
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts.map +0 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js +0 -797
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js.map +0 -1
  209. package/scripts/ensure-workspace-builds.cjs +0 -129
  210. /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → Qbr81pQ-pbQXP4bq2VXLv}/_buildManifest.js +0 -0
  211. /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → Qbr81pQ-pbQXP4bq2VXLv}/_ssgManifest.js +0 -0
@@ -30,11 +30,11 @@ import { playNotificationBell, sendDesktopNotification } from "./notifications.j
30
30
  import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, } from "./auto-budget.js";
31
31
  import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, isDeterministicPolicyError, } from "./auto-tool-tracking.js";
32
32
  import { closeoutUnit } from "./auto-unit-closeout.js";
33
- import { selectAndApplyModel, resolveModelId, clearToolBaseline, getToolBaselineSnapshot } from "./auto-model-selection.js";
33
+ import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
34
34
  import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
35
35
  import { resetHookState, runPreDispatchHooks, restoreHookState, clearPersistedHookState, } from "./post-unit-hooks.js";
36
36
  import { runGSDDoctor, rebuildState } from "./doctor.js";
37
- import { preDispatchHealthGate, recordHealthSnapshot, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
37
+ import { preDispatchHealthGate, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
38
38
  import { clearSkillSnapshot } from "./skill-discovery.js";
39
39
  import { captureAvailableSkills, resetSkillTelemetry, } from "./skill-telemetry.js";
40
40
  import { getInstalledSkillNames } from "./skills.js";
@@ -48,7 +48,7 @@ import { isAbsolute, join } from "node:path";
48
48
  import { pathToFileURL } from "node:url";
49
49
  import { readFileSync, existsSync, mkdirSync } from "node:fs";
50
50
  import { atomicWriteSync } from "./atomic-write.js";
51
- import { captureIntegrationBranch, detectWorktreeName, getCurrentBranch, getMainBranch, setActiveMilestoneId, resolveProjectRoot, } from "./worktree.js";
51
+ import { captureIntegrationBranch, detectWorktreeName, getCurrentBranch, getMainBranch, setActiveMilestoneId, } from "./worktree.js";
52
52
  import { GitServiceImpl } from "./git-service.js";
53
53
  import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
54
54
  import { createAutoWorktree, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree.js";
@@ -66,7 +66,7 @@ import { isClosedStatus } from "./status-guards.js";
66
66
  import { MILESTONE_ID_RE } from "./milestone-ids.js";
67
67
  import { updateProgressWidget as _updateProgressWidget, setCompletionProgressWidget, setAutoOutcomeWidget, setAutoActiveStatus, updateSliceProgressCache, clearSliceProgressCache, unitVerb, } from "./auto-dashboard.js";
68
68
  import { registerSigtermHandler as _registerSigtermHandler, deregisterSigtermHandler as _deregisterSigtermHandler, } from "./auto-supervisor.js";
69
- import { isDbAvailable, getMilestone, getMilestoneSlices, getSlice, getTask, refreshOpenDatabaseFromDisk, } from "./gsd-db.js";
69
+ import { isDbAvailable, getMilestone, getMilestoneSlices, } from "./gsd-db.js";
70
70
  import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
71
71
  import { writeUnitRuntimeRecord } from "./unit-runtime.js";
72
72
  import { countPendingCaptures } from "./captures.js";
@@ -94,13 +94,7 @@ import { runAutoLoopWithUok } from "./uok/kernel.js";
94
94
  import { resolveUokFlags } from "./uok/flags.js";
95
95
  import { validateDirectory } from "./validate-directory.js";
96
96
  import { createAutoOrchestrator } from "./auto/orchestrator.js";
97
- import { reconcileBeforeDispatch } from "./state-reconciliation.js";
98
- import { compileUnitToolContract } from "./tool-contract.js";
99
- import { createWorktreeSafetyModule } from "./worktree-safety.js";
100
- import { repairAutoWorktreeSafetyFailure, resolvePausedAutoWorktreePath, } from "./auto-worktree-repair.js";
101
- import { resolveManifest } from "./unit-context-manifest.js";
102
- import { classifyFailure } from "./recovery-classification.js";
103
- import { supportsStructuredQuestions } from "./workflow-mcp.js";
97
+ import { resolvePausedAutoWorktreePath, } from "./auto-worktree-repair.js";
104
98
  import { WorktreeLifecycle, } from "./worktree-lifecycle.js";
105
99
  import { WorktreeStateProjection } from "./worktree-state-projection.js";
106
100
  import { reorderForCaching } from "./prompt-ordering.js";
@@ -350,6 +344,15 @@ export function startAutoDetached(ctx, pi, base, verboseMode, options) {
350
344
  export function shouldUseWorktreeIsolation(basePath) {
351
345
  return getIsolationMode(basePath) === "worktree";
352
346
  }
347
+ function resolveEffectiveUnitIsolationMode(configuredMode, isolationDegraded) {
348
+ return configuredMode === "worktree" && isolationDegraded ? "branch" : configuredMode;
349
+ }
350
+ export function _resolveEffectiveUnitIsolationModeForTest(configuredMode, isolationDegraded) {
351
+ return resolveEffectiveUnitIsolationMode(configuredMode, isolationDegraded);
352
+ }
353
+ function getEffectiveUnitIsolationMode(basePath) {
354
+ return resolveEffectiveUnitIsolationMode(getIsolationMode(basePath), s.isolationDegraded);
355
+ }
353
356
  /** Crash recovery prompt — set by startAuto, consumed by the main loop */
354
357
  /** Pending verification retry — set when gate fails with retries remaining, consumed by autoLoop */
355
358
  /** Verification retry count per unitId — separate from s.unitDispatchCount which tracks artifact-missing retries */
@@ -730,6 +733,38 @@ function setLifecycleOutcome(ctx, input) {
730
733
  startedAt: s.autoStartTime,
731
734
  });
732
735
  }
736
+ const TERMINAL_CLOSEOUT_COMMANDS = [
737
+ "/gsd status for overview",
738
+ "/gsd visualize to inspect",
739
+ "/gsd notifications for history",
740
+ "/gsd start for new work",
741
+ ];
742
+ function setTerminalCloseoutOutcome(ctx, input) {
743
+ if (!ctx?.hasUI)
744
+ return;
745
+ const milestoneLabel = input.milestoneId ? `Milestone ${input.milestoneId}` : "Milestone";
746
+ const title = input.allMilestonesComplete ? "All milestones complete" : `${milestoneLabel} complete`;
747
+ const titleLine = input.milestoneTitle && input.milestoneId
748
+ ? `${input.milestoneTitle}. `
749
+ : "";
750
+ const nextAction = input.allMilestonesComplete
751
+ ? "Review the closeout, then start new work when ready."
752
+ : "Review the closeout, then start the next milestone when ready.";
753
+ ctx.ui.setHeader?.(() => ({
754
+ render() { return []; },
755
+ invalidate() { },
756
+ }));
757
+ ctx.ui.setStatus?.("gsd-step", undefined);
758
+ ctx.ui.setWidget?.("gsd-progress", undefined);
759
+ setLifecycleOutcome(ctx, {
760
+ status: "complete",
761
+ title,
762
+ detail: `${titleLine}${input.reason ?? "Milestone closeout finished."}`,
763
+ nextAction,
764
+ commands: TERMINAL_CLOSEOUT_COMMANDS,
765
+ unitLabel: input.milestoneId ? `complete-milestone ${input.milestoneId}` : null,
766
+ });
767
+ }
733
768
  function handleLostSessionLock(ctx, lockStatus) {
734
769
  debugLog("session-lock-lost", {
735
770
  lockBase: lockBase(),
@@ -849,7 +884,6 @@ export async function cleanupAfterLoopExit(ctx) {
849
884
  if (!s.paused) {
850
885
  if (preserveCompletionSurface) {
851
886
  ctx.ui.setStatus("gsd-auto", undefined);
852
- s.completionStopInProgress = false;
853
887
  if (preserveStepSurface) {
854
888
  s.preserveStepSurfaceAfterLoopExit = false;
855
889
  }
@@ -961,6 +995,7 @@ export async function stopAuto(ctx, pi, reason, options = {}) {
961
995
  const completionStopRequested = Boolean(options.completionWidget);
962
996
  const preserveCloseoutTranscript = !isHeadlessStop && (options.preserveCloseoutTranscript ?? completionStopRequested);
963
997
  const installCompletionWidget = completionStopRequested && !preserveCloseoutTranscript;
998
+ const installTerminalCloseoutOutcome = completionStopRequested && preserveCloseoutTranscript;
964
999
  const preserveCompletionSurface = completionStopRequested || preserveCloseoutTranscript;
965
1000
  s.completionStopInProgress = preserveCompletionSurface;
966
1001
  playNotificationBell("stop", loadedPreferences?.notifications);
@@ -1270,6 +1305,14 @@ export async function stopAuto(ctx, pi, reason, options = {}) {
1270
1305
  ctx.ui.notify(`${stopNotificationPrefix}.`, "info");
1271
1306
  }
1272
1307
  }
1308
+ if (installTerminalCloseoutOutcome && ctx && options.completionWidget) {
1309
+ setTerminalCloseoutOutcome(ctx, {
1310
+ milestoneId: completionMilestoneId,
1311
+ milestoneTitle: options.completionWidget.milestoneTitle ?? null,
1312
+ allMilestonesComplete: options.completionWidget.allMilestonesComplete,
1313
+ reason: reason ?? "Milestone closeout finished.",
1314
+ });
1315
+ }
1273
1316
  // ── Step 9: Cmux sidebar / event log ──
1274
1317
  try {
1275
1318
  pi?.events.emit(CMUX_CHANNELS.SIDEBAR, { action: "clear", preferences: loadedPreferences });
@@ -1593,457 +1636,6 @@ export function buildWorktreeLifecycleDeps() {
1593
1636
  function buildLifecycle() {
1594
1637
  return new WorktreeLifecycle(s, buildWorktreeLifecycleDeps());
1595
1638
  }
1596
- /**
1597
- * Build the production `DispatchAdapter` used by `createWiredAutoOrchestrationModule`.
1598
- *
1599
- * Exported so tests can verify parity with `runDispatch`'s `resolveDispatch` call —
1600
- * the wired adapter must derive `structuredQuestionsAvailable`, `sessionContextWindow`,
1601
- * `sessionProvider`, and `modelRegistry` the same way phases.ts:runDispatch does.
1602
- */
1603
- export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
1604
- function getAlreadyClosedDispatchReason(unitType, unitId) {
1605
- if (!isDbAvailable())
1606
- return null;
1607
- refreshOpenDatabaseFromDisk();
1608
- const { milestone, slice, task } = parseUnitId(unitId);
1609
- if (unitType === "execute-task" && milestone && slice && task) {
1610
- const row = getTask(milestone, slice, task);
1611
- return row && isClosedStatus(row.status)
1612
- ? `execute-task ${unitId} is already ${row.status}`
1613
- : null;
1614
- }
1615
- if (unitType === "complete-slice" && milestone && slice) {
1616
- const row = getSlice(milestone, slice);
1617
- return row && isClosedStatus(row.status)
1618
- ? `complete-slice ${unitId} is already ${row.status}`
1619
- : null;
1620
- }
1621
- return null;
1622
- }
1623
- function shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath) {
1624
- const activeMilestoneId = state.activeMilestone?.id;
1625
- const currentMilestoneId = activeSession?.currentMilestoneId;
1626
- if (!activeSession || !activeMilestoneId || !currentMilestoneId || activeMilestoneId === currentMilestoneId) {
1627
- return false;
1628
- }
1629
- const scopedWorktreeMilestone = (activeSession.basePath ? detectWorktreeName(activeSession.basePath) : null) ??
1630
- detectWorktreeName(activeDispatchBasePath);
1631
- if (scopedWorktreeMilestone && scopedWorktreeMilestone !== activeMilestoneId) {
1632
- return false;
1633
- }
1634
- const currentMilestone = state.registry.find((milestone) => milestone.id === currentMilestoneId);
1635
- return !!currentMilestone && isClosedStatus(currentMilestone.status);
1636
- }
1637
- return {
1638
- async decideNextUnit(input) {
1639
- const state = input.stateSnapshot;
1640
- const active = state.activeMilestone;
1641
- if (!active)
1642
- return null;
1643
- const activeSession = input.session ?? session;
1644
- const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
1645
- if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
1646
- activeSession.currentMilestoneId = active.id;
1647
- }
1648
- const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
1649
- // Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
1650
- // (#5789). Prefer caller-supplied values when present so test harnesses and
1651
- // alternative wirings can inject deterministic snapshots; otherwise pull from
1652
- // the captured pi/ctx references.
1653
- const sessionProvider = input.sessionProvider ?? ctx.model?.provider;
1654
- const sessionContextWindow = input.sessionContextWindow ?? ctx.model?.contextWindow;
1655
- const modelRegistry = input.modelRegistry ?? ctx.modelRegistry;
1656
- const authMode = sessionProvider && typeof ctx.modelRegistry?.getProviderAuthMode === "function"
1657
- ? ctx.modelRegistry.getProviderAuthMode(sessionProvider)
1658
- : undefined;
1659
- // Use baseline snapshot — same reason as phases.ts:runDispatch: the live
1660
- // active set may be narrowed by the prior unit before selectAndApplyModel
1661
- // restores it, causing false transport-preflight failures (#477 follow-up).
1662
- const activeTools = getToolBaselineSnapshot(pi);
1663
- // Mirrors runDispatch: deep-planning keeps approval gates in plain chat
1664
- // because structured questions can be cancelled outside the chat turn on
1665
- // some transports.
1666
- const structuredQuestionsAvailable = input.structuredQuestionsAvailable ??
1667
- (prefs?.planning_depth === "deep"
1668
- ? "false"
1669
- : supportsStructuredQuestions(activeTools, {
1670
- authMode,
1671
- baseUrl: ctx.model?.baseUrl,
1672
- })
1673
- ? "true"
1674
- : "false");
1675
- const pendingRetry = session?.pendingVerificationRetryDispatch;
1676
- if (session && pendingRetry) {
1677
- session.pendingVerificationRetryDispatch = null;
1678
- const alreadyClosedReason = getAlreadyClosedDispatchReason(pendingRetry.unitType, pendingRetry.unitId);
1679
- if (alreadyClosedReason) {
1680
- session.pendingOrchestrationDispatch = null;
1681
- session.pendingVerificationRetry = null;
1682
- return { kind: "skipped", reason: alreadyClosedReason };
1683
- }
1684
- session.pendingOrchestrationDispatch = pendingRetry;
1685
- return {
1686
- unitType: pendingRetry.unitType,
1687
- unitId: pendingRetry.unitId,
1688
- reason: "verification-retry",
1689
- preconditions: [],
1690
- };
1691
- }
1692
- const action = await resolveDispatch({
1693
- basePath: activeDispatchBasePath,
1694
- mid: active.id,
1695
- midTitle: active.title,
1696
- state,
1697
- prefs,
1698
- session: activeSession,
1699
- structuredQuestionsAvailable,
1700
- sessionContextWindow,
1701
- sessionProvider,
1702
- modelRegistry,
1703
- activeTools,
1704
- sessionAuthMode: authMode,
1705
- sessionBaseUrl: ctx.model?.baseUrl,
1706
- });
1707
- if (action.action === "stop") {
1708
- if (session)
1709
- session.pendingOrchestrationDispatch = null;
1710
- return {
1711
- kind: "blocked",
1712
- reason: action.reason,
1713
- action: action.level === "warning" ? "pause" : "stop",
1714
- };
1715
- }
1716
- if (action.action !== "dispatch") {
1717
- if (session)
1718
- session.pendingOrchestrationDispatch = null;
1719
- return {
1720
- kind: "skipped",
1721
- reason: action.matchedRule ?? "dispatch-skip",
1722
- };
1723
- }
1724
- const alreadyClosedReason = getAlreadyClosedDispatchReason(action.unitType, action.unitId);
1725
- if (alreadyClosedReason) {
1726
- if (session) {
1727
- session.pendingOrchestrationDispatch = null;
1728
- session.pendingVerificationRetry = null;
1729
- }
1730
- return { kind: "skipped", reason: alreadyClosedReason };
1731
- }
1732
- if (session) {
1733
- const pending = {
1734
- unitType: action.unitType,
1735
- unitId: action.unitId,
1736
- prompt: action.prompt,
1737
- pauseAfterUatDispatch: action.pauseAfterDispatch ?? false,
1738
- state,
1739
- mid: active.id,
1740
- midTitle: active.title,
1741
- };
1742
- session.pendingOrchestrationDispatch = pending;
1743
- }
1744
- return {
1745
- unitType: action.unitType,
1746
- unitId: action.unitId,
1747
- reason: action.matchedRule ?? "dispatch",
1748
- preconditions: [],
1749
- };
1750
- },
1751
- };
1752
- }
1753
- function isUsableLiveOrchestratorBasePath(basePath) {
1754
- if (!basePath || !existsSync(basePath))
1755
- return false;
1756
- if (!detectWorktreeName(basePath))
1757
- return true;
1758
- try {
1759
- return readFileSync(join(basePath, ".git"), "utf8").trim().startsWith("gitdir: ");
1760
- }
1761
- catch {
1762
- return false;
1763
- }
1764
- }
1765
- export function resolveLiveOrchestratorBasePath(input) {
1766
- const primary = input.sessionBasePath || input.capturedBasePath;
1767
- if (isUsableLiveOrchestratorBasePath(primary))
1768
- return primary;
1769
- const fallbacks = [
1770
- input.originalBasePath,
1771
- input.runtimeBasePath,
1772
- resolveProjectRoot(input.capturedBasePath),
1773
- ];
1774
- for (const candidate of fallbacks) {
1775
- if (candidate && isUsableLiveOrchestratorBasePath(candidate)) {
1776
- return candidate;
1777
- }
1778
- }
1779
- return input.runtimeBasePath || input.capturedBasePath;
1780
- }
1781
- /**
1782
- * Thin entry glue for the new Auto Orchestration module.
1783
- *
1784
- * This intentionally wires only dispatch + error notification today, with
1785
- * no behavior changes to the existing auto loop. It provides a concrete seam
1786
- * the next refactor steps can adopt incrementally.
1787
- */
1788
- export function createWiredAutoOrchestrationModule(ctx, pi, dispatchBasePath, runtimeBasePath = resolveProjectRoot(dispatchBasePath)) {
1789
- const flowId = `auto-orchestrator-${Date.now()}`;
1790
- let seq = 0;
1791
- const getLiveDispatchBasePath = () => resolveLiveOrchestratorBasePath({
1792
- capturedBasePath: dispatchBasePath,
1793
- runtimeBasePath,
1794
- sessionBasePath: s.basePath,
1795
- originalBasePath: s.originalBasePath,
1796
- });
1797
- const deps = {
1798
- stateReconciliation: {
1799
- async reconcileBeforeDispatch() {
1800
- const activeBasePath = getLiveDispatchBasePath();
1801
- const result = await reconcileBeforeDispatch(activeBasePath);
1802
- // Failure-path summaries written by gsd_summary_save create
1803
- // artifact-db-status-divergence blockers for tasks that are still
1804
- // pending (gsd_task_complete never ran). These tasks can still be
1805
- // dispatched and the drift self-heals once they complete successfully.
1806
- const hardBlockers = result.blockers.filter((b) => !b.includes("has SUMMARY artifact while DB status is") &&
1807
- !b.includes("has SUMMARY on disk while DB status is") &&
1808
- !b.includes("has task SUMMARY artifacts but no DB tasks"));
1809
- if (hardBlockers.length > 0) {
1810
- return {
1811
- ok: false,
1812
- reason: hardBlockers[0],
1813
- stateSnapshot: result.stateSnapshot,
1814
- };
1815
- }
1816
- const repairedKinds = result.repaired.map((d) => d.kind);
1817
- return {
1818
- ok: true,
1819
- reason: repairedKinds.length > 0
1820
- ? `repaired: ${repairedKinds.join(", ")}`
1821
- : "clean",
1822
- stateSnapshot: result.stateSnapshot,
1823
- };
1824
- },
1825
- },
1826
- dispatch: createWiredDispatchAdapter(ctx, pi, dispatchBasePath, s),
1827
- recovery: {
1828
- async classifyAndRecover(input) {
1829
- const recovery = classifyFailure(input);
1830
- return { action: recovery.action, reason: recovery.reason };
1831
- },
1832
- },
1833
- toolContract: {
1834
- async compileUnitToolContract(unitType) {
1835
- const result = compileUnitToolContract(unitType);
1836
- if (!result.ok)
1837
- return { ok: false, reason: result.detail };
1838
- return { ok: true, reason: result.contract.validationRules.join(", ") };
1839
- },
1840
- },
1841
- worktree: {
1842
- async prepareForUnit(unitType, unitId) {
1843
- const manifest = resolveManifest(unitType);
1844
- if (!manifest) {
1845
- return {
1846
- ok: false,
1847
- reason: `No Unit manifest is registered for ${unitType}`,
1848
- };
1849
- }
1850
- if (getIsolationMode(runtimeBasePath) !== "worktree") {
1851
- return { ok: true, reason: "not-required" };
1852
- }
1853
- const writeScope = manifest.tools.mode === "all" || manifest.tools.mode === "docs"
1854
- ? "source-writing"
1855
- : "planning-only";
1856
- if (getIsolationMode(runtimeBasePath) !== "worktree") {
1857
- return { ok: true, reason: "isolation-not-worktree" };
1858
- }
1859
- const safety = createWorktreeSafetyModule();
1860
- const activeBasePath = getLiveDispatchBasePath();
1861
- const snapshot = await deriveState(activeBasePath);
1862
- const milestoneId = snapshot.activeMilestone?.id ?? null;
1863
- const expectedBranch = milestoneId ? autoWorktreeBranch(milestoneId) : null;
1864
- let result = safety.validateUnitRoot({
1865
- unitType,
1866
- unitId,
1867
- writeScope,
1868
- projectRoot: runtimeBasePath,
1869
- unitRoot: activeBasePath,
1870
- milestoneId,
1871
- isolationMode: getIsolationMode(runtimeBasePath),
1872
- expectedBranch,
1873
- });
1874
- if (!result.ok) {
1875
- const repaired = await repairAutoWorktreeSafetyFailure({
1876
- safetyResult: result,
1877
- projectRoot: runtimeBasePath,
1878
- activeRoot: activeBasePath,
1879
- milestoneId,
1880
- enterMilestone: async (id) => {
1881
- buildLifecycle().adoptSessionRoot(runtimeBasePath, s.originalBasePath || runtimeBasePath);
1882
- const enterResult = buildLifecycle().enterMilestone(id, {
1883
- notify: ctx.ui.notify.bind(ctx.ui),
1884
- });
1885
- if (!enterResult.ok)
1886
- return { ok: false, reason: enterResult.reason };
1887
- rebuildScope(s.basePath, s.currentMilestoneId);
1888
- return { ok: true };
1889
- },
1890
- revalidate: () => safety.validateUnitRoot({
1891
- unitType,
1892
- unitId,
1893
- writeScope,
1894
- projectRoot: runtimeBasePath,
1895
- unitRoot: getLiveDispatchBasePath(),
1896
- milestoneId,
1897
- isolationMode: getIsolationMode(runtimeBasePath),
1898
- expectedBranch,
1899
- }),
1900
- });
1901
- result = repaired.result;
1902
- if (result.ok) {
1903
- return { ok: true, reason: repaired.repaired ? `repaired-${result.kind}` : result.kind };
1904
- }
1905
- const repairDetail = repaired.repairReason
1906
- ? ` (repair skipped: ${repaired.repairReason})`
1907
- : "";
1908
- return { ok: false, reason: `${result.kind}: ${result.reason}${repairDetail}` };
1909
- }
1910
- return { ok: true, reason: result.kind };
1911
- },
1912
- async syncAfterUnit() { },
1913
- async cleanupOnStop() { },
1914
- },
1915
- health: {
1916
- checkResourcesStale() {
1917
- return checkResourcesStale(s.resourceVersionOnStart);
1918
- },
1919
- async preAdvanceGate() {
1920
- try {
1921
- const gate = await preDispatchHealthGate(getLiveDispatchBasePath());
1922
- if (gate.proceed) {
1923
- return {
1924
- kind: "pass",
1925
- fixesApplied: gate.fixesApplied,
1926
- };
1927
- }
1928
- return {
1929
- kind: "fail",
1930
- reason: gate.reason ?? "Pre-dispatch health check failed — run /gsd doctor for details.",
1931
- action: gate.severity ?? "pause",
1932
- };
1933
- }
1934
- catch (error) {
1935
- return { kind: "threw", error };
1936
- }
1937
- },
1938
- async postAdvanceRecord(result) {
1939
- if (result.kind === "error") {
1940
- recordHealthSnapshot(1, 0, 0, [{
1941
- code: "orchestration-error",
1942
- message: result.reason ?? "orchestration error",
1943
- severity: "error",
1944
- unitId: "orchestration",
1945
- }], [], "orchestration");
1946
- }
1947
- else if (result.kind === "blocked") {
1948
- recordHealthSnapshot(0, 1, 0, [{
1949
- code: "orchestration-blocked",
1950
- message: result.reason ?? "orchestration blocked",
1951
- severity: "warning",
1952
- unitId: "orchestration",
1953
- }], [], "orchestration");
1954
- }
1955
- },
1956
- },
1957
- runtime: {
1958
- async ensureLockOwnership() {
1959
- const status = getSessionLockStatus(runtimeBasePath);
1960
- if (!status.valid || status.failureReason === "pid-mismatch") {
1961
- throw new Error("session lock held by another process");
1962
- }
1963
- },
1964
- async journalTransition(event) {
1965
- const eventType = event.name === "start"
1966
- ? "orchestrator-iteration-start"
1967
- : event.name === "resume"
1968
- ? "orchestrator-iteration-start"
1969
- : event.name === "advance"
1970
- ? "orchestrator-dispatch-match"
1971
- : event.name === "advance-blocked"
1972
- ? "orchestrator-guard-block"
1973
- : event.name === "advance-stopped"
1974
- ? "orchestrator-dispatch-stop"
1975
- : event.name === "advance-error"
1976
- ? "orchestrator-iteration-end"
1977
- : event.name === "advance-paused" || event.name === "advance-retry"
1978
- ? "orchestrator-guard-block"
1979
- : event.name === "stop"
1980
- ? "orchestrator-terminal"
1981
- : "orchestrator-iteration-end";
1982
- _emitJournalEvent(runtimeBasePath, {
1983
- ts: new Date().toISOString(),
1984
- flowId,
1985
- seq: ++seq,
1986
- eventType,
1987
- data: {
1988
- source: "auto-orchestrator",
1989
- name: event.name,
1990
- reason: event.reason,
1991
- unitType: event.unitType,
1992
- unitId: event.unitId,
1993
- },
1994
- });
1995
- },
1996
- },
1997
- notifications: {
1998
- async notifyLifecycle(event) {
1999
- if (event.name === "error") {
2000
- ctx.ui.notify(event.detail ?? "auto orchestration error", "error");
2001
- }
2002
- },
2003
- },
2004
- uokGate: {
2005
- async emit(input) {
2006
- const activeBasePath = getLiveDispatchBasePath();
2007
- const prefs = loadEffectiveGSDPreferences(activeBasePath)?.preferences;
2008
- const uokFlags = resolveUokFlags(prefs);
2009
- if (!uokFlags.gates)
2010
- return;
2011
- const milestoneId = input.milestoneId ?? s.currentMilestoneId ?? undefined;
2012
- try {
2013
- const { UokGateRunner } = await import("./uok/gate-runner.js");
2014
- const runner = new UokGateRunner();
2015
- runner.register({
2016
- id: input.gateId,
2017
- type: input.gateType,
2018
- execute: async () => ({
2019
- outcome: input.outcome,
2020
- failureClass: input.failureClass,
2021
- rationale: input.rationale,
2022
- findings: input.findings ?? "",
2023
- }),
2024
- });
2025
- await runner.run(input.gateId, {
2026
- basePath: activeBasePath,
2027
- traceId: `pre-dispatch:${flowId}`,
2028
- turnId: `orch-${seq}`,
2029
- milestoneId,
2030
- unitType: "pre-dispatch",
2031
- unitId: `orch-${seq}`,
2032
- });
2033
- }
2034
- catch (err) {
2035
- logWarning("engine", `uok gate emit failed: ${getErrorMessage(err)}`, {
2036
- file: "auto.ts",
2037
- gateId: input.gateId,
2038
- gateType: input.gateType,
2039
- ...(milestoneId ? { milestoneId } : {}),
2040
- });
2041
- }
2042
- },
2043
- },
2044
- };
2045
- return createAutoOrchestrator(deps);
2046
- }
2047
1639
  function notifyResumeBlocked(ctx, result) {
2048
1640
  const resumeCmd = s.stepMode ? "/gsd next" : "/gsd auto";
2049
1641
  ctx.ui.notify(`Auto-mode blocked: ${result.reason}. Fix and run ${resumeCmd} to resume.`, "warning");
@@ -2056,7 +1648,13 @@ function notifyResumeBlocked(ctx, result) {
2056
1648
  });
2057
1649
  }
2058
1650
  function ensureOrchestrationModule(ctx, pi, basePath) {
2059
- s.orchestration = createWiredAutoOrchestrationModule(ctx, pi, basePath, lockBase());
1651
+ s.orchestration = createAutoOrchestrator({
1652
+ ctx,
1653
+ pi,
1654
+ dispatchBasePath: basePath,
1655
+ runtimeBasePath: lockBase(),
1656
+ session: s,
1657
+ });
2060
1658
  }
2061
1659
  /**
2062
1660
  * Build the LoopDeps object from auto.ts private scope.
@@ -11,7 +11,7 @@ import { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer,
11
11
  import { resolveManifest } from "../unit-context-manifest.js";
12
12
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
13
13
  import { loadFile, saveFile, formatContinue } from "../files.js";
14
- import { clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError, } from "../auto-runtime-state.js";
14
+ import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError, } from "../auto-runtime-state.js";
15
15
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
16
16
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
17
17
  import { saveActivityLog } from "../activity-log.js";
@@ -109,7 +109,9 @@ export const MINIMAL_GSD_TOOL_NAMES = [
109
109
  "gsd_checkpoint_db",
110
110
  "gsd_plan_milestone",
111
111
  "memory_query",
112
+ "gsd_memory_query",
112
113
  "capture_thought",
114
+ "gsd_capture_thought",
113
115
  ];
114
116
  export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
115
117
  "ask_user_questions",
@@ -624,6 +626,7 @@ export function registerHooks(pi, ecosystemHandlers) {
624
626
  }
625
627
  });
626
628
  pi.on("before_agent_start", async (event, ctx) => {
629
+ clearAutoCompletionStopInProgress();
627
630
  resetPendingGatePauseGuard();
628
631
  applyMinimalGsdToolSurface(pi);
629
632
  // Wait for ecosystem loader to finish (no-op after first turn).
@@ -21,6 +21,7 @@ const _counters = {
21
21
  parsePlanTotalMs: 0,
22
22
  dispatches: 0,
23
23
  renders: 0,
24
+ gitInvocations: 0,
24
25
  };
25
26
  /** Max debug log files to keep. Older ones are pruned on enable. */
26
27
  const MAX_DEBUG_LOGS = 5;
@@ -118,6 +119,14 @@ export function debugCount(counter, value = 1) {
118
119
  return;
119
120
  _counters[counter] += value;
120
121
  }
122
+ /**
123
+ * Snapshot the current debug counters. Used by the per-dispatch benchmark
124
+ * harness (#442) to read counts without disabling debug (which is what
125
+ * writeDebugSummary does). Returns a copy so callers can't mutate internal state.
126
+ */
127
+ export function getDebugCounters() {
128
+ return { ..._counters };
129
+ }
121
130
  /** Record a peak value (only updates if new value is higher). */
122
131
  export function debugPeak(counter, value) {
123
132
  if (!_enabled)
@@ -154,6 +163,7 @@ export function writeDebugSummary() {
154
163
  avgTtsrCheck_ms,
155
164
  ttsrPeakBuffer: _counters.ttsrPeakBuffer,
156
165
  renders: _counters.renders,
166
+ gitInvocations: _counters.gitInvocations,
157
167
  });
158
168
  return disableDebug();
159
169
  }