@opengsd/gsd-pi 1.2.0-dev.9ad8ae33 → 1.2.0-dev.a6376d75

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 (264) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +1 -18
  4. package/dist/loader.js +6 -4
  5. package/dist/register-agent-bundles.d.ts +11 -2
  6. package/dist/register-agent-bundles.js +18 -4
  7. package/dist/resources/.managed-resources-content-hash +1 -1
  8. package/dist/resources/extensions/ask-user-questions.js +3 -2
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  10. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  11. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  12. package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
  13. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  14. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  15. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  16. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  17. package/dist/resources/extensions/gsd/auto/orchestrator.js +85 -15
  18. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  19. package/dist/resources/extensions/gsd/auto/phases.js +17 -2372
  20. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  21. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  22. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  23. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  24. package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
  25. package/dist/resources/extensions/gsd/auto.js +15 -1
  26. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
  27. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  28. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  29. package/dist/resources/extensions/gsd/db/queries.js +30 -0
  30. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  31. package/dist/resources/extensions/gsd/guided-flow.js +88 -2
  32. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  33. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  34. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  35. package/dist/resources/extensions/gsd/notifications.js +12 -7
  36. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  37. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -1
  38. package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -0
  39. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  40. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  41. package/dist/resources/extensions/gsd/state.js +6 -2
  42. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  43. package/dist/resources/extensions/gsd/tools/complete-task.js +62 -0
  44. package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
  45. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  46. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  47. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  48. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  49. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  50. package/dist/runtime-checks.d.ts +10 -0
  51. package/dist/runtime-checks.js +27 -0
  52. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  53. package/dist/web/standalone/.next/BUILD_ID +1 -1
  54. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  55. package/dist/web/standalone/.next/build-manifest.json +2 -2
  56. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  57. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/index.html +1 -1
  74. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  81. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  83. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  84. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  85. package/package.json +2 -2
  86. package/packages/cloud-mcp-gateway/package.json +2 -2
  87. package/packages/contracts/package.json +1 -1
  88. package/packages/daemon/package.json +4 -4
  89. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  90. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  91. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  92. package/packages/gsd-agent-core/package.json +5 -5
  93. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  94. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  95. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  96. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  97. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  98. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  99. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +50 -6
  100. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  101. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  102. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  103. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  104. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  105. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  106. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  107. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  108. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  109. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  110. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  111. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  112. package/packages/gsd-agent-modes/package.json +7 -7
  113. package/packages/mcp-server/README.md +12 -3
  114. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  115. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  116. package/packages/mcp-server/dist/cli-runner.js +137 -0
  117. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  118. package/packages/mcp-server/dist/cli.js +2 -58
  119. package/packages/mcp-server/dist/cli.js.map +1 -1
  120. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  121. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  122. package/packages/mcp-server/dist/pid-registry.js +452 -0
  123. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  124. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  125. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  126. package/packages/mcp-server/dist/probe-mode.js +10 -0
  127. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  128. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  129. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  130. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  131. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  132. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  133. package/packages/mcp-server/dist/workflow-tools.js +62 -43
  134. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  135. package/packages/mcp-server/package.json +5 -5
  136. package/packages/native/package.json +1 -1
  137. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  138. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  139. package/packages/pi-agent-core/package.json +1 -1
  140. package/packages/pi-ai/package.json +1 -1
  141. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  142. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  144. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  147. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  148. package/packages/pi-coding-agent/package.json +7 -7
  149. package/packages/pi-tui/dist/index.d.ts +1 -1
  150. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  151. package/packages/pi-tui/dist/index.js +1 -1
  152. package/packages/pi-tui/dist/index.js.map +1 -1
  153. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  154. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  155. package/packages/pi-tui/dist/terminal-image.js +54 -2
  156. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  157. package/packages/pi-tui/dist/tui.d.ts +8 -0
  158. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  159. package/packages/pi-tui/dist/tui.js +63 -18
  160. package/packages/pi-tui/dist/tui.js.map +1 -1
  161. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  162. package/packages/pi-tui/dist/utils.js +110 -36
  163. package/packages/pi-tui/dist/utils.js.map +1 -1
  164. package/packages/pi-tui/package.json +2 -2
  165. package/packages/rpc-client/package.json +2 -2
  166. package/pkg/dist/theme/theme.d.ts.map +1 -1
  167. package/pkg/dist/theme/theme.js +45 -17
  168. package/pkg/dist/theme/theme.js.map +1 -1
  169. package/pkg/package.json +1 -1
  170. package/src/resources/extensions/ask-user-questions.ts +7 -2
  171. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  172. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  173. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  174. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  175. package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
  176. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  177. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  178. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  179. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  180. package/src/resources/extensions/gsd/auto/orchestrator.ts +95 -15
  181. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  182. package/src/resources/extensions/gsd/auto/phases.ts +58 -3061
  183. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  184. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  185. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  186. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  187. package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
  188. package/src/resources/extensions/gsd/auto.ts +20 -1
  189. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
  190. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  191. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  192. package/src/resources/extensions/gsd/db/queries.ts +29 -0
  193. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  194. package/src/resources/extensions/gsd/guided-flow.ts +128 -2
  195. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  196. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  197. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  198. package/src/resources/extensions/gsd/notifications.ts +13 -6
  199. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  200. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -1
  201. package/src/resources/extensions/gsd/prompts/run-uat.md +2 -0
  202. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  203. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  204. package/src/resources/extensions/gsd/state.ts +7 -1
  205. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  206. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  207. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  208. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +76 -12
  209. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  210. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  211. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  212. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  213. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  214. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
  215. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  216. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
  217. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  218. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  219. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  220. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +16 -0
  221. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  222. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  223. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
  224. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  225. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  226. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  227. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  228. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  229. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  230. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  231. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  232. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  233. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
  234. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  235. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +1 -1
  236. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  237. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  238. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  239. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  240. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -1
  241. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  242. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  243. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  244. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
  245. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  246. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  247. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  248. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  249. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  250. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  251. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  252. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  253. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  254. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  255. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  256. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  257. package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
  258. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  259. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  260. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  261. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  262. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  263. /package/dist/web/standalone/.next/static/{FBNo5cT_chy7YNoAQsU3o → xyMkEaICFHJoa98VgJyzY}/_buildManifest.js +0 -0
  264. /package/dist/web/standalone/.next/static/{FBNo5cT_chy7YNoAQsU3o → xyMkEaICFHJoa98VgJyzY}/_ssgManifest.js +0 -0
@@ -4,7 +4,7 @@
4
4
  import type { ExtensionContext } from "@gsd/pi-coding-agent";
5
5
  import type { GSDState } from "./types.js";
6
6
  import { runProviderChecks, summariseProviderIssues } from "./doctor-providers.js";
7
- import { runEnvironmentChecks } from "./doctor-environment.js";
7
+ import { runEnvironmentChecks, runEnvironmentChecksAsync } from "./doctor-environment.js";
8
8
  import { loadEffectiveGSDPreferences } from "./preferences.js";
9
9
  import { nativeIsRepo, nativeLastCommitEpoch, nativeGetCurrentBranch, nativeCommitSubject } from "./native-git-bridge.js";
10
10
  import { loadLedgerFromDisk, getProjectTotals } from "./metrics.js";
@@ -22,7 +22,31 @@ export const HEALTH_WIDGET_ACTIVE_HINTS =
22
22
 
23
23
  // ── Data loader ────────────────────────────────────────────────────────────────
24
24
 
25
- function loadHealthWidgetData(basePath: string): HealthWidgetData {
25
+ // Last-commit lookup is subprocess-backed (native-git-bridge git spawns),
26
+ // so it is treated like the other expensive checks: skipped on first paint,
27
+ // run only by the background refresh.
28
+ function loadLastCommitInfo(basePath: string): { epoch: number | null; message: string | null } {
29
+ try {
30
+ if (nativeIsRepo(basePath)) {
31
+ const branch = nativeGetCurrentBranch(basePath);
32
+ const epoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
33
+ if (epoch > 0) {
34
+ return { epoch, message: nativeCommitSubject(basePath, branch || "HEAD") || null };
35
+ }
36
+ }
37
+ } catch { /* non-fatal */ }
38
+ return { epoch: null, message: null };
39
+ }
40
+
41
+ function loadHealthWidgetData(
42
+ basePath: string,
43
+ options?: { includeChecks?: boolean },
44
+ ): HealthWidgetData {
45
+ // `includeChecks` gates the expensive subprocess-backed checks (provider +
46
+ // environment doctor: `lsof`, `docker`, `node --version`, ...). The initial
47
+ // synchronous render passes `false` so first paint is never blocked on them;
48
+ // the async refresh (off the first-paint path) runs the full suite.
49
+ const includeChecks = options?.includeChecks ?? true;
26
50
  let budgetCeiling: number | undefined;
27
51
  let budgetSpent = 0;
28
52
  let providerIssue: string | null = null;
@@ -44,40 +68,73 @@ function loadHealthWidgetData(basePath: string): HealthWidgetData {
44
68
  }
45
69
  } catch { /* non-fatal */ }
46
70
 
71
+ if (includeChecks) {
72
+ try {
73
+ const providerResults = runProviderChecks();
74
+ providerIssue = summariseProviderIssues(providerResults);
75
+ } catch { /* non-fatal */ }
76
+
77
+ try {
78
+ const envResults = runEnvironmentChecks(basePath);
79
+ for (const r of envResults) {
80
+ if (r.status === "error") environmentErrorCount++;
81
+ else if (r.status === "warning") environmentWarningCount++;
82
+ }
83
+ } catch { /* non-fatal */ }
84
+ }
85
+
86
+ // ── Last commit info ── (git spawns — gated like the other expensive checks)
87
+ if (includeChecks) {
88
+ const commit = loadLastCommitInfo(basePath);
89
+ lastCommitEpoch = commit.epoch;
90
+ lastCommitMessage = commit.message;
91
+ }
92
+
93
+ return {
94
+ projectState,
95
+ budgetCeiling,
96
+ budgetSpent,
97
+ providerIssue,
98
+ environmentErrorCount,
99
+ environmentWarningCount,
100
+ lastCommitEpoch,
101
+ lastCommitMessage,
102
+ lastRefreshed: Date.now(),
103
+ };
104
+ }
105
+
106
+ // Non-blocking variant used by the widget's background refresh: the cheap fields
107
+ // come from the synchronous snapshot, then provider + environment checks are
108
+ // layered in off the event-loop critical path (env checks run concurrently via
109
+ // runEnvironmentChecksAsync). Keeps the always-on widget from stalling the UI on
110
+ // its initial enrichment or its 60s refresh.
111
+ async function loadHealthWidgetDataAsync(basePath: string): Promise<HealthWidgetData> {
112
+ const data = loadHealthWidgetData(basePath, { includeChecks: false });
113
+ let providerIssue = data.providerIssue;
114
+ let environmentErrorCount = 0;
115
+ let environmentWarningCount = 0;
116
+
47
117
  try {
48
- const providerResults = runProviderChecks();
49
- providerIssue = summariseProviderIssues(providerResults);
118
+ providerIssue = summariseProviderIssues(runProviderChecks());
50
119
  } catch { /* non-fatal */ }
51
120
 
52
121
  try {
53
- const envResults = runEnvironmentChecks(basePath);
122
+ const envResults = await runEnvironmentChecksAsync(basePath);
54
123
  for (const r of envResults) {
55
124
  if (r.status === "error") environmentErrorCount++;
56
125
  else if (r.status === "warning") environmentWarningCount++;
57
126
  }
58
127
  } catch { /* non-fatal */ }
59
128
 
60
- // ── Last commit info ──
61
- try {
62
- if (nativeIsRepo(basePath)) {
63
- const branch = nativeGetCurrentBranch(basePath);
64
- const epoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
65
- if (epoch > 0) {
66
- lastCommitEpoch = epoch;
67
- lastCommitMessage = nativeCommitSubject(basePath, branch || "HEAD") || null;
68
- }
69
- }
70
- } catch { /* non-fatal */ }
129
+ const commit = loadLastCommitInfo(basePath);
71
130
 
72
131
  return {
73
- projectState,
74
- budgetCeiling,
75
- budgetSpent,
132
+ ...data,
76
133
  providerIssue,
77
134
  environmentErrorCount,
78
135
  environmentWarningCount,
79
- lastCommitEpoch,
80
- lastCommitMessage,
136
+ lastCommitEpoch: commit.epoch,
137
+ lastCommitMessage: commit.message,
81
138
  lastRefreshed: Date.now(),
82
139
  };
83
140
  }
@@ -95,8 +152,13 @@ export function initHealthWidget(ctx: ExtensionContext): void {
95
152
 
96
153
  const basePath = projectRoot();
97
154
 
98
- // String-array fallback — used in RPC mode (factory is a no-op there)
99
- const initialData = loadHealthWidgetData(basePath);
155
+ // String-array fallback — used in RPC mode (factory is a no-op there).
156
+ // Skip the expensive provider/environment doctor checks here: this runs
157
+ // synchronously on the interactive-startup path, where running them would
158
+ // block first paint by ~0.9s (lsof/docker probes, otherwise run again
159
+ // immediately by the factory below). The factory's async refresh fills in
160
+ // real health once the screen is up.
161
+ const initialData = loadHealthWidgetData(basePath, { includeChecks: false });
100
162
  ctx.ui.setWidget("gsd-health", buildHealthLines(initialData), { placement: "belowEditor" });
101
163
 
102
164
  // Factory-based widget for TUI mode — replaces the string-array above
@@ -110,7 +172,7 @@ export function initHealthWidget(ctx: ExtensionContext): void {
110
172
  if (refreshInFlight) return;
111
173
  refreshInFlight = true;
112
174
  try {
113
- data = loadHealthWidgetData(basePath);
175
+ data = await loadHealthWidgetDataAsync(basePath);
114
176
  cachedLines = undefined;
115
177
  if (!isDisposed) _tui.requestRender();
116
178
  } catch { /* non-fatal */ } finally {
@@ -118,9 +180,11 @@ export function initHealthWidget(ctx: ExtensionContext): void {
118
180
  }
119
181
  };
120
182
 
121
- // Fire first enrichment immediately. requestRender() inside is a no-op
122
- // if the widget has not yet rendered, so this is safe before factory return.
123
- void refresh();
183
+ // Fire the first full enrichment off the first-paint path. setTimeout(0)
184
+ // yields to the initial render + input loop, so the expensive doctor checks
185
+ // (provider + environment) never delay the moment the user sees the UI.
186
+ // requestRender() inside refresh repaints the widget once data is ready.
187
+ setTimeout(() => { void refresh(); }, 0);
124
188
 
125
189
  const refreshTimer = setInterval(() => {
126
190
  void refresh();
@@ -0,0 +1,39 @@
1
+ // mcp-bridge.ts — stable runtime seam for MCP server consumption (phase 1).
2
+ export {
3
+ loadWriteGateSnapshot,
4
+ shouldBlockPendingGateInSnapshot,
5
+ shouldBlockQueueExecutionInSnapshot,
6
+ } from "./bootstrap/write-gate.js";
7
+ export { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
8
+ export {
9
+ _getAdapter,
10
+ checkpointDatabase,
11
+ closeDatabase,
12
+ getAllMilestones,
13
+ getDb,
14
+ getGateResults,
15
+ getMilestoneSlices,
16
+ getPendingGates,
17
+ getSliceTasks,
18
+ insertDecision,
19
+ insertMilestone,
20
+ insertSlice,
21
+ openDatabase,
22
+ upsertMilestonePlanning,
23
+ } from "./gsd-db.js";
24
+ export { invalidateStateCache, isReusableGhostMilestone } from "./state.js";
25
+ export { loadEffectiveGSDPreferences } from "./preferences.js";
26
+ export {
27
+ saveDecisionToDb,
28
+ saveRequirementToDb,
29
+ updateRequirementInDb,
30
+ } from "./db-writer.js";
31
+ export { rebuildState } from "./doctor.js";
32
+ export { queryJournal } from "./journal.js";
33
+ export {
34
+ claimReservedId,
35
+ findMilestoneIds,
36
+ getReservedMilestoneIds,
37
+ milestoneIdSort,
38
+ nextMilestoneId,
39
+ } from "./milestone-ids.js";
@@ -74,8 +74,8 @@ export function evaluateAllCompleteSettlement(
74
74
  action: "pause",
75
75
  message:
76
76
  `Milestone ${milestoneId} is complete, but its worktree branch has not been merged to main. ` +
77
- `Retry with \`/gsd dispatch complete-milestone ${milestoneId}\` or merge manually.`,
78
- nextAction: `Retry \`/gsd dispatch complete-milestone ${milestoneId}\` or merge manually.`,
77
+ `Retry with \`/gsd dispatch complete-milestone ${milestoneId}\` to finish the system-owned merge.`,
78
+ nextAction: `Retry \`/gsd dispatch complete-milestone ${milestoneId}\`.`,
79
79
  milestoneId,
80
80
  };
81
81
  }
@@ -4,7 +4,12 @@
4
4
  import { execFileSync } from "node:child_process";
5
5
  import type { NotificationPreferences } from "./types.js";
6
6
  import { loadEffectiveGSDPreferences } from "./preferences.js";
7
- import { sendRemoteNotification } from "../remote-questions/notify.js";
7
+ import { sendRemoteNotification as _sendRemoteNotification } from "../remote-questions/notify.js";
8
+
9
+ /** Swappable dispatcher for remote notifications — exported so tests can mock it. */
10
+ export const remoteNotificationDispatcher = {
11
+ send: _sendRemoteNotification,
12
+ };
8
13
 
9
14
  export type NotifyLevel = "info" | "success" | "warning" | "error";
10
15
  export type NotificationKind = "complete" | "error" | "budget" | "milestone" | "attention";
@@ -30,28 +35,30 @@ export function sendDesktopNotification(
30
35
  level: NotifyLevel = "info",
31
36
  kind: NotificationKind = "complete",
32
37
  projectName?: string,
38
+ deps: { notifications?: NotificationPreferences } = {},
33
39
  ): void {
34
40
  // When a projectName is provided and the title is the default "GSD",
35
41
  // replace it with a project-qualified title for multi-project clarity.
36
42
  if (projectName && title === "GSD") {
37
43
  title = formatNotificationTitle(projectName);
38
44
  }
39
- const loaded = loadEffectiveGSDPreferences()?.preferences;
45
+ const loadedPreferences = loadEffectiveGSDPreferences()?.preferences;
46
+ const notifications = deps.notifications ?? loadedPreferences?.notifications;
40
47
 
41
48
  // Remote notifications fire independently of desktop preferences.
42
49
  // sendRemoteNotification handles "not configured" gracefully (early return).
43
- void sendRemoteNotification(title, message).catch(() => {});
50
+ void remoteNotificationDispatcher.send(title, message).catch(() => {});
44
51
 
45
- if (!shouldSendDesktopNotification(kind, loaded?.notifications)) return;
52
+ if (!shouldSendDesktopNotification(kind, notifications)) return;
46
53
 
47
54
  // cmux delivery and desktop delivery are independent — if cmux import or
48
55
  // delivery fails, we must still attempt the native desktop notification.
49
56
  const runCmux = async () => {
50
57
  try {
51
58
  const { CmuxClient, emitOsc777Notification, resolveCmuxConfig } = await import("../cmux/index.js");
52
- const cmux = resolveCmuxConfig(loaded);
59
+ const cmux = resolveCmuxConfig(loadedPreferences);
53
60
  if (cmux.notifications) {
54
- const delivered = CmuxClient.fromPreferences(loaded).notify(title, message);
61
+ const delivered = CmuxClient.fromPreferences(loadedPreferences).notify(title, message);
55
62
  if (delivered) return true;
56
63
  emitOsc777Notification(title, message);
57
64
  }
@@ -38,7 +38,7 @@ Use `subagent` only when useful: reviewer, security, or tester. Apply findings b
38
38
  10. Prepare `gsd_slice_complete` content with camelCase fields `milestoneId`, `sliceId`, `sliceTitle`, `oneLiner`, `narrative`, `verification`, and `uatContent`.
39
39
  11. Draft concrete UAT with preconditions, steps, expected outcomes, edge cases, and UAT Type. Declare the type as a bullet under a `## UAT Type` heading, exactly like `- UAT mode: browser-executable`.
40
40
  **Web apps:** when inlined Web App UAT guidance is present, declare `browser-executable` or `runtime-executable` (not `artifact-driven`) for localhost/browser/screenshot steps; include dev-server preconditions and name Playwright specs when they exist.
41
- 12. Review the inlined task-summary excerpts for DECISIONS.md/KNOWLEDGE.md-worthy decisions and gotchas. Read full `*-SUMMARY.md` only if needed. Capture with `capture_thought`; do not append knowledge files.
41
+ 12. Review the inlined task-summary excerpts for DECISIONS.md/KNOWLEDGE.md-worthy decisions and gotchas. Read full `*-SUMMARY.md` only if needed. Capture with `gsd_capture_thought` (MCP-scoped `mcp__...__gsd_capture_thought`), not bare `capture_thought`; do not append knowledge files.
42
42
  13. When verification passes, call `gsd_slice_complete`. The DB-backed tool is the canonical write path. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}`. Do not edit roadmap checkboxes.
43
43
  14. Do not run git commands.
44
44
  15. If the current project state needs refresh, call `gsd_summary_save` with `artifact_type: "PROJECT"` and the full updated project markdown as `content`; omit `milestone_id`. Do not write or edit `.gsd/PROJECT.md` directly.
@@ -52,6 +52,7 @@ You execute. The inlined task plan is authoritative. Verify referenced files and
52
52
 
53
53
  - If task sections exist for Failure Modes (Q5), Load Profile (Q6), Negative Tests (Q7), or Observability Impact, implement and verify them.
54
54
  - Verify must-haves with concrete commands or observable behavior.
55
+ - Run verification commands through `gsd_exec` / Context Mode evidence when workflow MCP tools are presented. Use `gsd_exec_search` before rerunning noisy checks, and `gsd_resume` after compaction or resume. Do not call direct `bash` for final verification evidence in this unit.
55
56
  - Run slice-level verification from the slice plan. Final tasks need all checks passing; intermediate tasks should record partial passes.
56
57
  - Populate `## Verification Evidence` with `formatEvidenceTable` rows: command, exit code, verdict, duration. If no checks were found, say so.
57
58
  - For UI/browser/DOM/user-visible web changes, exercise the real flow and record explicit checks.
@@ -64,7 +65,7 @@ Keep about **{{verificationBudget}}** for verification and summary. If context i
64
65
 
65
66
  - If the plan is fundamentally invalid, set `blocker_discovered: true` in the summary and explain.
66
67
  - For downstream-impacting ambiguity that cannot be resolved from code, plans, or decisions, include an `escalation` object with question, options, recommendation, rationale, and `continueWithDefault`.
67
- - Capture meaningful architecture/pattern/observability decisions with `capture_thought`; capture non-obvious gotchas or conventions only when they save future investigation.
68
+ - Capture meaningful architecture/pattern/observability decisions with `gsd_capture_thought` (or MCP-scoped `mcp__...__gsd_capture_thought`) when workflow MCP tools are presented; capture non-obvious gotchas or conventions only when they save future investigation.
68
69
  - Use the inlined Task Summary template below. Read `{{taskSummaryTemplatePath}}` only if the inlined template is absent or visibly truncated.
69
70
  - Call `gsd_task_complete` with camelCase fields `milestoneId`, `sliceId`, `taskId`, `oneLiner`, `narrative`, `verification`, and `verificationEvidence`. Include `blockerDiscovered: true` when a stale-path safety failure or other plan-invalidating blocker prevents execution.
70
71
  - The DB-backed tool is the canonical write path. Do **not** manually write `{{taskSummaryPath}}` or edit PLAN.md checkboxes; the tool renders the summary and updates state.
@@ -10,6 +10,8 @@ If any inlined plan, summary, verification command, or prior artifact names an a
10
10
 
11
11
  All relevant context has been preloaded below. Start working immediately without re-reading these files.
12
12
 
13
+ If a `.gsd/**` or `.gsd/**/*` glob returns no matches, treat that as a possible symlink-backed traversal limitation; do not infer that the GSD harness is missing. Use the preloaded UAT context and direct `.gsd/...` file paths named in this prompt instead.
14
+
13
15
  {{inlinedContext}}
14
16
 
15
17
  {{skillActivation}}
@@ -25,4 +25,5 @@ Follow the workflow defined below. Execute each phase in order, completing one b
25
25
  3. **Atomic commits.** Commit working code after each meaningful change. Use conventional commit format: `<type>(<scope>): <description>`.
26
26
  4. **Verify before shipping.** Run the project's test suite and build before marking the workflow complete.
27
27
  5. **Decision gates, not ceremony.** After each phase, summarize what changed. For low/medium complexity, ask for confirmation only when the next phase depends on a real user choice or external approval. For high complexity, confirm before proceeding to each new phase.
28
- 6. **Stay focused.** This is a {{complexity}}-complexity workflow. Match your ceremony level to the task don't over-engineer or under-deliver.
28
+ 6. **Persist workflow state.** If the artifact directory contains `STATE.json`, update it after each phase: mark the finished phase `completed`, mark the next phase `active`, set `currentPhase` to the active phase index, and refresh `updatedAt`. When every phase is completed, set `completedAt` to the completion timestamp.
29
+ 7. **Stay focused.** This is a {{complexity}}-complexity workflow. Match your ceremony level to the task — don't over-engineer or under-deliver.
@@ -134,11 +134,8 @@ const SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9-]*$/;
134
134
  function formatSkillActivationBlock(skillNames: string[]): string {
135
135
  const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
136
136
  if (safe.length === 0) return "";
137
- // Use explicit parameter syntax so LLMs pass { skill: "..." } instead of { name: "..." }.
138
- // The function-call-like syntax `Skill('name')` led LLMs to infer a positional
139
- // parameter name, causing tool validation failures — see #2224.
140
- const calls = safe.map(name => `Call Skill({ skill: '${name}' })`).join('. ');
141
- return `<skill_activation>${calls}.</skill_activation>`;
137
+ const reads = safe.map(name => `Read the installed '${name}' skill file from <available_skills>`).join(". ");
138
+ return `<skill_activation>${reads}.</skill_activation>`;
142
139
  }
143
140
 
144
141
  /**
@@ -157,7 +154,7 @@ function formatSkillRecommendationsBlock(unitType: string | undefined, skillName
157
154
  if (!unitType) return "";
158
155
  const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
159
156
  if (safe.length === 0) return "";
160
- return `<skill_recommendations unit="${unitType}">For this unit type, also consider invoking: ${safe.join(", ")}. Use Skill({ skill: 'name' }) when relevant — these are recommendations, not requirements.</skill_recommendations>`;
157
+ return `<skill_recommendations unit="${unitType}">For this unit type, also consider reading these installed skill files from <available_skills>: ${safe.join(", ")}. These are recommendations, not requirements.</skill_recommendations>`;
161
158
  }
162
159
 
163
160
  export function buildSkillActivationBlock(params: {
@@ -60,6 +60,7 @@ import {
60
60
  getAllMilestones,
61
61
  getMilestone,
62
62
  getMilestoneSlices,
63
+ getSlicesByMilestoneIds,
63
64
  getSliceTasks,
64
65
  getReplanHistory,
65
66
  getSlice,
@@ -477,13 +478,18 @@ async function buildRegistryAndFindActive(
477
478
  let activeMilestoneHasDraft = false;
478
479
  let firstDeferredQueuedShell: { id: string; title: string; deps: string[]; hasDraftContext: boolean } | null = null;
479
480
 
481
+ const activeMilestoneIds = milestones
482
+ .filter((m) => !parkedMilestoneIds.has(m.id))
483
+ .map((m) => m.id);
484
+ const slicesByMilestone = getSlicesByMilestoneIds(activeMilestoneIds);
485
+
480
486
  for (const m of milestones) {
481
487
  if (parkedMilestoneIds.has(m.id)) {
482
488
  registry.push({ id: m.id, title: stripMilestonePrefix(m.title) || m.id, status: 'parked' });
483
489
  continue;
484
490
  }
485
491
 
486
- const slices = getMilestoneSlices(m.id);
492
+ const slices = slicesByMilestone.get(m.id) ?? [];
487
493
 
488
494
  // DB-authoritative completeness (#4179): only trust completeMilestoneIds,
489
495
  // which is itself derived from DB status. SUMMARY-file presence alone must
@@ -2,7 +2,7 @@ import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
 
4
4
  import { _buildAbortedPauseContext, isUserInitiatedAbortMessage } from "../bootstrap/agent-end-recovery.js";
5
- import { _buildCancelledUnitStopReason, _isPauseOriginCancelledResult } from "../auto/phases.js";
5
+ import { _buildCancelledUnitStopReason, _isPauseOriginCancelledResult } from "../auto/phase-helpers.js";
6
6
 
7
7
  test("aborted agent_end maps errorMessage into structured aborted pause context", () => {
8
8
  const withMessage = _buildAbortedPauseContext({ errorMessage: "provider aborted request" });
@@ -1,7 +1,7 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
 
4
- import { runPreDispatch } from "../auto/phases.ts";
4
+ import { runPreDispatch } from "../auto/pre-dispatch.ts";
5
5
 
6
6
  test("blocked remediation warning uses /gsd dispatch reassess and hides internal tool name", async () => {
7
7
  const notifications: Array<{ message: string; level?: string }> = [];