@adhdev/daemon-core 0.9.82-rc.49 → 0.9.82-rc.490

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 (473) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +9 -0
  2. package/dist/boot/process-hardening.d.ts +50 -0
  3. package/dist/build-info.d.ts +37 -0
  4. package/dist/chat/source-machine.d.ts +166 -0
  5. package/dist/chat/source-resolver.d.ts +104 -0
  6. package/dist/chat/subscription-updates.d.ts +1 -0
  7. package/dist/cli-adapter-types.d.ts +68 -2
  8. package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
  9. package/dist/cli-adapters/cli-state-engine.d.ts +220 -0
  10. package/dist/cli-adapters/provider-cli-adapter.d.ts +137 -64
  11. package/dist/cli-adapters/provider-cli-parse.d.ts +5 -0
  12. package/dist/cli-adapters/provider-cli-runtime.d.ts +34 -0
  13. package/dist/cli-adapters/provider-cli-shared.d.ts +74 -0
  14. package/dist/cli-adapters/pty-write-chunking.d.ts +34 -0
  15. package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
  16. package/dist/cli-adapters/resolve-executable.d.ts +69 -0
  17. package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +6 -3
  18. package/dist/cli-adapters/terminal-backends/types.d.ts +10 -2
  19. package/dist/cli-adapters/terminal-screen.d.ts +4 -11
  20. package/dist/commands/chat-commands-debug-bundle.d.ts +14 -0
  21. package/dist/commands/chat-commands-read.d.ts +23 -0
  22. package/dist/commands/chat-commands-scope.d.ts +39 -0
  23. package/dist/commands/chat-commands-shared.d.ts +33 -0
  24. package/dist/commands/chat-commands-write.d.ts +14 -0
  25. package/dist/commands/chat-commands.d.ts +10 -23
  26. package/dist/commands/cli-manager.d.ts +71 -1
  27. package/dist/commands/handler.d.ts +125 -0
  28. package/dist/commands/high-family/index.d.ts +3 -0
  29. package/dist/commands/high-family/mesh-coordinator-launch.d.ts +2 -0
  30. package/dist/commands/high-family/mesh-events.d.ts +2 -0
  31. package/dist/commands/high-family/mesh-status.d.ts +2 -0
  32. package/dist/commands/high-family/types.d.ts +64 -0
  33. package/dist/commands/low-family/coordinator-prompt.d.ts +9 -0
  34. package/dist/commands/low-family/daemon-lifecycle.d.ts +2 -0
  35. package/dist/commands/low-family/diagnostics.d.ts +2 -0
  36. package/dist/commands/low-family/index.d.ts +3 -0
  37. package/dist/commands/low-family/mesh-ledger.d.ts +10 -0
  38. package/dist/commands/low-family/mesh-node-logs.d.ts +2 -0
  39. package/dist/commands/low-family/notification.d.ts +2 -0
  40. package/dist/commands/low-family/refine-config.d.ts +2 -0
  41. package/dist/commands/low-family/session-host.d.ts +2 -0
  42. package/dist/commands/low-family/spec-providerdev.d.ts +11 -0
  43. package/dist/commands/low-family/status-meta.d.ts +2 -0
  44. package/dist/commands/low-family/types.d.ts +33 -0
  45. package/dist/commands/med-family/cli-agent.d.ts +2 -0
  46. package/dist/commands/med-family/fast-forward.d.ts +2 -0
  47. package/dist/commands/med-family/ide.d.ts +10 -0
  48. package/dist/commands/med-family/index.d.ts +3 -0
  49. package/dist/commands/med-family/mesh-crud.d.ts +48 -0
  50. package/dist/commands/med-family/mesh-host-pairing.d.ts +2 -0
  51. package/dist/commands/med-family/mesh-queue.d.ts +2 -0
  52. package/dist/commands/med-family/mesh-restart.d.ts +2 -0
  53. package/dist/commands/med-family/types.d.ts +152 -0
  54. package/dist/commands/mesh-coordinator.d.ts +85 -1
  55. package/dist/commands/router-aggregate-status.d.ts +24 -0
  56. package/dist/commands/router-mesh-session-owner.d.ts +59 -0
  57. package/dist/commands/router-refine.d.ts +151 -0
  58. package/dist/commands/router-worktree-cleanup.d.ts +133 -0
  59. package/dist/commands/router.d.ts +203 -15
  60. package/dist/commands/upgrade-helper.d.ts +41 -1
  61. package/dist/config/chat-history.d.ts +11 -0
  62. package/dist/config/config.d.ts +19 -0
  63. package/dist/config/mesh-config.d.ts +65 -0
  64. package/dist/config/mesh-json-config.d.ts +199 -0
  65. package/dist/config/registry-resolver.d.ts +54 -0
  66. package/dist/config/repo-settings.d.ts +77 -0
  67. package/dist/config/state-store.d.ts +30 -0
  68. package/dist/daemon/dev-server.d.ts +0 -2
  69. package/dist/detection/cli-detector.d.ts +17 -0
  70. package/dist/detection/ide-detector.d.ts +13 -0
  71. package/dist/detection/win32-ide-version.d.ts +37 -0
  72. package/dist/git/change-impact-config.d.ts +159 -0
  73. package/dist/git/git-commands.d.ts +26 -2
  74. package/dist/git/git-diff.d.ts +6 -0
  75. package/dist/git/git-executor.d.ts +11 -0
  76. package/dist/git/git-status.d.ts +80 -0
  77. package/dist/git/git-types.d.ts +2 -50
  78. package/dist/git/git-worktree.d.ts +71 -1
  79. package/dist/git/index.d.ts +3 -1
  80. package/dist/index.d.ts +70 -17
  81. package/dist/index.js +53532 -19073
  82. package/dist/index.js.map +1 -1
  83. package/dist/index.mjs +53283 -18989
  84. package/dist/index.mjs.map +1 -1
  85. package/dist/installer.d.ts +1 -4
  86. package/dist/ipc/local-ipc-server.d.ts +91 -0
  87. package/dist/launch.d.ts +1 -1
  88. package/dist/logging/async-batch-writer.d.ts +10 -0
  89. package/dist/logging/debug-config.d.ts +16 -0
  90. package/dist/logging/log-redactor.d.ts +24 -0
  91. package/dist/logging/log-tail-reader.d.ts +81 -0
  92. package/dist/logging/logger.d.ts +1 -1
  93. package/dist/mesh/contracts.d.ts +256 -0
  94. package/dist/mesh/coordinator-prompt.d.ts +76 -0
  95. package/dist/mesh/coordinator-registry.d.ts +59 -0
  96. package/dist/mesh/mesh-active-work.d.ts +203 -0
  97. package/dist/mesh/mesh-clone-grace.d.ts +8 -0
  98. package/dist/mesh/mesh-completion-synthesis.d.ts +4 -0
  99. package/dist/mesh/mesh-coordinator-config.d.ts +21 -0
  100. package/dist/mesh/mesh-delivery-policy.d.ts +104 -0
  101. package/dist/mesh/mesh-event-classify.d.ts +7 -0
  102. package/dist/mesh/mesh-event-forwarding.d.ts +58 -0
  103. package/dist/mesh/mesh-event-trace.d.ts +21 -0
  104. package/dist/mesh/mesh-events-coordinator.d.ts +4 -0
  105. package/dist/mesh/mesh-events-pending.d.ts +258 -0
  106. package/dist/mesh/mesh-events-stale.d.ts +61 -0
  107. package/dist/mesh/mesh-events-utils.d.ts +75 -0
  108. package/dist/mesh/mesh-events.d.ts +6 -49
  109. package/dist/mesh/mesh-fast-forward.d.ts +81 -0
  110. package/dist/mesh/mesh-host-ownership.d.ts +21 -1
  111. package/dist/mesh/mesh-init.d.ts +128 -0
  112. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -4
  113. package/dist/mesh/mesh-ledger.d.ts +139 -1
  114. package/dist/mesh/mesh-magi-status.d.ts +63 -0
  115. package/dist/mesh/mesh-missions.d.ts +281 -0
  116. package/dist/mesh/mesh-node-identity.d.ts +310 -0
  117. package/dist/mesh/mesh-queue-assignment.d.ts +162 -0
  118. package/dist/mesh/mesh-reconcile-acked-hold.d.ts +17 -0
  119. package/dist/mesh/mesh-reconcile-config.d.ts +6 -0
  120. package/dist/mesh/mesh-reconcile-identity.d.ts +6 -0
  121. package/dist/mesh/mesh-reconcile-loop.d.ts +84 -0
  122. package/dist/mesh/mesh-reconcile-v2-backstop.d.ts +16 -0
  123. package/dist/mesh/mesh-refine-batch.d.ts +68 -0
  124. package/dist/mesh/mesh-refine-gates.d.ts +457 -0
  125. package/dist/mesh/mesh-refine-status.d.ts +62 -0
  126. package/dist/mesh/mesh-remote-event-pull.d.ts +15 -0
  127. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  128. package/dist/mesh/mesh-routing.d.ts +70 -0
  129. package/dist/mesh/mesh-runtime-store.d.ts +567 -0
  130. package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
  131. package/dist/mesh/mesh-task-inflight.d.ts +46 -0
  132. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  133. package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +34 -0
  134. package/dist/mesh/mesh-warmup-deadline.d.ts +68 -0
  135. package/dist/mesh/mesh-work-queue.d.ts +392 -1
  136. package/dist/mesh/preview-freshness.d.ts +28 -0
  137. package/dist/mesh/refine-config.d.ts +97 -0
  138. package/dist/mesh/worktree-bootstrap-config.d.ts +219 -0
  139. package/dist/providers/acp-provider-instance.d.ts +5 -0
  140. package/dist/providers/approval-utils.d.ts +46 -0
  141. package/dist/providers/chat-message-normalization.d.ts +58 -1
  142. package/dist/providers/cli-provider-effect-format.d.ts +30 -0
  143. package/dist/providers/cli-provider-history-dedup.d.ts +17 -0
  144. package/dist/providers/cli-provider-input-prompt.d.ts +12 -0
  145. package/dist/providers/cli-provider-instance-types.d.ts +45 -0
  146. package/dist/providers/cli-provider-instance.d.ts +426 -30
  147. package/dist/providers/cli-provider-status-helpers.d.ts +46 -0
  148. package/dist/providers/cli-provider-transcript-merge.d.ts +7 -0
  149. package/dist/providers/contracts.d.ts +196 -6
  150. package/dist/providers/external-sources.d.ts +71 -0
  151. package/dist/providers/manual-attendance.d.ts +79 -0
  152. package/dist/providers/native-history/antigravity-claim-registry.d.ts +39 -0
  153. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +137 -0
  154. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  155. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  156. package/dist/providers/native-history/constants.d.ts +12 -0
  157. package/dist/providers/native-history/dispatcher.d.ts +44 -0
  158. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  159. package/dist/providers/native-history/index.d.ts +13 -0
  160. package/dist/providers/provider-instance-manager.d.ts +30 -0
  161. package/dist/providers/provider-instance.d.ts +31 -1
  162. package/dist/providers/provider-loader.d.ts +42 -5
  163. package/dist/providers/provider-trust.d.ts +31 -0
  164. package/dist/providers/read-chat-contract.d.ts +29 -0
  165. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  166. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +86 -0
  167. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  168. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  169. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  170. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  171. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  172. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  173. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  174. package/dist/providers/sdk/v1/index.d.ts +30 -0
  175. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  176. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  177. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  178. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  179. package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
  180. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  181. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  182. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  183. package/dist/providers/spec/adapter.d.ts +98 -0
  184. package/dist/providers/spec/cli-adapter.d.ts +223 -0
  185. package/dist/providers/spec/evaluator.d.ts +45 -0
  186. package/dist/providers/spec/fsm-driver.d.ts +449 -0
  187. package/dist/providers/spec/fsm-evaluator.d.ts +93 -0
  188. package/dist/providers/spec/fsm-loader.d.ts +14 -0
  189. package/dist/providers/spec/fsm-types.d.ts +202 -0
  190. package/dist/providers/spec/native-history-executor.d.ts +41 -0
  191. package/dist/providers/spec/pre-launch-trust.d.ts +16 -0
  192. package/dist/providers/spec/route.d.ts +4 -0
  193. package/dist/providers/spec/types.d.ts +244 -0
  194. package/dist/providers/status-monitor.d.ts +7 -7
  195. package/dist/providers/transcript-v2.d.ts +176 -0
  196. package/dist/providers/types/interactive-prompt.d.ts +84 -0
  197. package/dist/providers/working-dir.d.ts +17 -0
  198. package/dist/repo-mesh-types.d.ts +616 -12
  199. package/dist/runtime-defaults.d.ts +2 -0
  200. package/dist/session-host/managed-host.d.ts +64 -0
  201. package/dist/session-host/runtime-surface.d.ts +10 -16
  202. package/dist/sessions/registry.d.ts +26 -0
  203. package/dist/shared-types-extra.d.ts +2 -4
  204. package/dist/shared-types.d.ts +110 -55
  205. package/dist/status/chat-tail-hot-sessions.d.ts +40 -0
  206. package/dist/status/normalize.d.ts +1 -1
  207. package/dist/status/normalize.js +1 -0
  208. package/dist/status/normalize.js.map +1 -1
  209. package/dist/status/normalize.mjs +1 -0
  210. package/dist/status/normalize.mjs.map +1 -1
  211. package/dist/status/reporter.d.ts +2 -0
  212. package/dist/status/snapshot.d.ts +27 -0
  213. package/dist/system/hash.d.ts +8 -0
  214. package/dist/system/load-better-sqlite3.d.ts +21 -0
  215. package/dist/types.d.ts +20 -6
  216. package/package.json +11 -4
  217. package/src/agent-stream/poller.ts +2 -3
  218. package/src/agent-stream/provider-adapter.ts +1 -1
  219. package/src/boot/daemon-lifecycle.ts +80 -14
  220. package/src/boot/process-hardening.ts +89 -0
  221. package/src/build-info.ts +73 -0
  222. package/src/chat/source-machine.ts +534 -0
  223. package/src/chat/source-resolver.ts +0 -0
  224. package/src/chat/subscription-updates.ts +20 -1
  225. package/src/cli-adapter-types.d.ts +3 -1
  226. package/src/cli-adapter-types.ts +68 -2
  227. package/src/cli-adapters/cli-script-runner.ts +421 -0
  228. package/src/cli-adapters/cli-state-engine.ts +1282 -0
  229. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  230. package/src/cli-adapters/provider-cli-adapter.ts +1048 -1143
  231. package/src/cli-adapters/provider-cli-parse.d.ts +2 -0
  232. package/src/cli-adapters/provider-cli-parse.ts +19 -0
  233. package/src/cli-adapters/provider-cli-runtime.ts +56 -7
  234. package/src/cli-adapters/provider-cli-shared.d.ts +4 -0
  235. package/src/cli-adapters/provider-cli-shared.ts +121 -11
  236. package/src/cli-adapters/pty-transport.ts +2 -1
  237. package/src/cli-adapters/pty-write-chunking.ts +106 -0
  238. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  239. package/src/cli-adapters/resolve-executable.ts +204 -0
  240. package/src/cli-adapters/session-host-transport.ts +2 -1
  241. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +63 -29
  242. package/src/cli-adapters/terminal-backends/types.ts +10 -3
  243. package/src/cli-adapters/terminal-screen.ts +16 -81
  244. package/src/commands/chat-commands-debug-bundle.ts +398 -0
  245. package/src/commands/chat-commands-read.ts +2788 -0
  246. package/src/commands/chat-commands-scope.ts +54 -0
  247. package/src/commands/chat-commands-shared.ts +114 -0
  248. package/src/commands/chat-commands-write.ts +891 -0
  249. package/src/commands/chat-commands.ts +19 -1841
  250. package/src/commands/cli-manager.d.ts +2 -0
  251. package/src/commands/cli-manager.ts +724 -27
  252. package/src/commands/handler.ts +865 -2
  253. package/src/commands/high-family/index.ts +28 -0
  254. package/src/commands/high-family/mesh-coordinator-launch.ts +696 -0
  255. package/src/commands/high-family/mesh-events.ts +102 -0
  256. package/src/commands/high-family/mesh-status.ts +857 -0
  257. package/src/commands/high-family/types.ts +80 -0
  258. package/src/commands/low-family/coordinator-prompt.ts +125 -0
  259. package/src/commands/low-family/daemon-lifecycle.ts +120 -0
  260. package/src/commands/low-family/diagnostics.ts +57 -0
  261. package/src/commands/low-family/index.ts +37 -0
  262. package/src/commands/low-family/mesh-ledger.ts +62 -0
  263. package/src/commands/low-family/mesh-node-logs.ts +87 -0
  264. package/src/commands/low-family/notification.ts +116 -0
  265. package/src/commands/low-family/refine-config.ts +106 -0
  266. package/src/commands/low-family/session-host.ts +282 -0
  267. package/src/commands/low-family/spec-providerdev.ts +217 -0
  268. package/src/commands/low-family/status-meta.ts +112 -0
  269. package/src/commands/low-family/types.ts +39 -0
  270. package/src/commands/med-family/cli-agent.ts +270 -0
  271. package/src/commands/med-family/fast-forward.ts +230 -0
  272. package/src/commands/med-family/ide.ts +163 -0
  273. package/src/commands/med-family/index.ts +37 -0
  274. package/src/commands/med-family/mesh-crud.ts +1268 -0
  275. package/src/commands/med-family/mesh-host-pairing.ts +234 -0
  276. package/src/commands/med-family/mesh-queue.ts +167 -0
  277. package/src/commands/med-family/mesh-restart.ts +92 -0
  278. package/src/commands/med-family/types.ts +153 -0
  279. package/src/commands/mesh-coordinator.ts +334 -124
  280. package/src/commands/router-aggregate-status.ts +209 -0
  281. package/src/commands/router-mesh-session-owner.ts +114 -0
  282. package/src/commands/router-refine.ts +1794 -0
  283. package/src/commands/router-worktree-cleanup.ts +870 -0
  284. package/src/commands/router.ts +567 -4149
  285. package/src/commands/stream-commands.ts +8 -0
  286. package/src/commands/upgrade-helper.ts +310 -45
  287. package/src/config/chat-history.ts +517 -24
  288. package/src/config/config.ts +30 -0
  289. package/src/config/mesh-config.ts +300 -24
  290. package/src/config/mesh-json-config.ts +376 -0
  291. package/src/config/recent-activity.ts +8 -2
  292. package/src/config/registry-resolver.ts +100 -0
  293. package/src/config/repo-settings.ts +111 -0
  294. package/src/config/state-store.ts +55 -0
  295. package/src/daemon/dev-auto-implement.ts +3 -2
  296. package/src/daemon/dev-cli-debug.ts +10 -1
  297. package/src/daemon/dev-server.ts +0 -541
  298. package/src/detection/cli-detector.ts +94 -9
  299. package/src/detection/ide-detector.ts +55 -16
  300. package/src/detection/win32-ide-version.ts +106 -0
  301. package/src/git/change-impact-config.ts +354 -0
  302. package/src/git/git-commands.ts +112 -16
  303. package/src/git/git-diff.ts +81 -11
  304. package/src/git/git-executor.ts +12 -0
  305. package/src/git/git-status.ts +822 -48
  306. package/src/git/git-types.ts +14 -62
  307. package/src/git/git-worktree.ts +261 -4
  308. package/src/git/index.ts +17 -0
  309. package/src/index.ts +190 -13
  310. package/src/installer.d.ts +1 -1
  311. package/src/installer.ts +8 -6
  312. package/src/ipc/local-ipc-server.ts +278 -0
  313. package/src/launch.d.ts +1 -1
  314. package/src/launch.ts +37 -28
  315. package/src/logging/async-batch-writer.ts +55 -0
  316. package/src/logging/command-log.ts +7 -5
  317. package/src/logging/debug-config.ts +25 -0
  318. package/src/logging/debug-trace.ts +7 -2
  319. package/src/logging/log-redactor.ts +100 -0
  320. package/src/logging/log-tail-reader.ts +341 -0
  321. package/src/logging/logger.ts +14 -7
  322. package/src/mesh/contracts.ts +510 -0
  323. package/src/mesh/coordinator-prompt.ts +627 -34
  324. package/src/mesh/coordinator-registry.ts +121 -0
  325. package/src/mesh/mesh-active-work.ts +706 -0
  326. package/src/mesh/mesh-clone-grace.ts +68 -0
  327. package/src/mesh/mesh-completion-synthesis.ts +416 -0
  328. package/src/mesh/mesh-coordinator-config.ts +97 -0
  329. package/src/mesh/mesh-delivery-policy.ts +284 -0
  330. package/src/mesh/mesh-event-classify.ts +78 -0
  331. package/src/mesh/mesh-event-forwarding.ts +2030 -0
  332. package/src/mesh/mesh-event-trace.ts +67 -0
  333. package/src/mesh/mesh-events-coordinator.ts +32 -0
  334. package/src/mesh/mesh-events-pending.ts +1548 -0
  335. package/src/mesh/mesh-events-stale.ts +452 -0
  336. package/src/mesh/mesh-events-utils.ts +443 -0
  337. package/src/mesh/mesh-events.ts +43 -1035
  338. package/src/mesh/mesh-fast-forward.ts +856 -0
  339. package/src/mesh/mesh-host-ownership.ts +41 -3
  340. package/src/mesh/mesh-init.ts +350 -0
  341. package/src/mesh/mesh-ledger-reconciliation.ts +12 -7
  342. package/src/mesh/mesh-ledger.ts +897 -102
  343. package/src/mesh/mesh-magi-status.ts +223 -0
  344. package/src/mesh/mesh-missions.ts +695 -0
  345. package/src/mesh/mesh-node-identity.ts +2065 -0
  346. package/src/mesh/mesh-queue-assignment.ts +2498 -0
  347. package/src/mesh/mesh-reconcile-acked-hold.ts +230 -0
  348. package/src/mesh/mesh-reconcile-config.ts +66 -0
  349. package/src/mesh/mesh-reconcile-identity.ts +103 -0
  350. package/src/mesh/mesh-reconcile-loop.ts +1696 -0
  351. package/src/mesh/mesh-reconcile-v2-backstop.ts +62 -0
  352. package/src/mesh/mesh-refine-batch.ts +205 -0
  353. package/src/mesh/mesh-refine-gates.ts +1792 -0
  354. package/src/mesh/mesh-refine-status.ts +231 -0
  355. package/src/mesh/mesh-remote-event-pull.ts +279 -0
  356. package/src/mesh/mesh-review-inbox.ts +308 -0
  357. package/src/mesh/mesh-routing.ts +291 -0
  358. package/src/mesh/mesh-runtime-store.ts +2292 -0
  359. package/src/mesh/mesh-scheduling-runtime.ts +198 -0
  360. package/src/mesh/mesh-task-inflight.ts +70 -0
  361. package/src/mesh/mesh-task-stats.ts +161 -0
  362. package/src/mesh/mesh-unresolved-forward-outbox.ts +215 -0
  363. package/src/mesh/mesh-warmup-deadline.ts +152 -0
  364. package/src/mesh/mesh-work-queue.ts +1489 -145
  365. package/src/mesh/preview-freshness.ts +163 -0
  366. package/src/mesh/refine-config.ts +129 -12
  367. package/src/mesh/worktree-bootstrap-config.ts +599 -0
  368. package/src/providers/acp-provider-instance.ts +43 -10
  369. package/src/providers/approval-utils.d.ts +5 -0
  370. package/src/providers/approval-utils.ts +100 -6
  371. package/src/providers/chat-message-normalization.ts +126 -4
  372. package/src/providers/cli-provider-effect-format.ts +53 -0
  373. package/src/providers/cli-provider-history-dedup.ts +75 -0
  374. package/src/providers/cli-provider-input-prompt.ts +133 -0
  375. package/src/providers/cli-provider-instance-types.ts +131 -0
  376. package/src/providers/cli-provider-instance.ts +2771 -499
  377. package/src/providers/cli-provider-status-helpers.ts +123 -0
  378. package/src/providers/cli-provider-transcript-merge.ts +114 -0
  379. package/src/providers/contracts.d.ts +55 -0
  380. package/src/providers/contracts.ts +207 -6
  381. package/src/providers/extension-provider-instance.ts +12 -7
  382. package/src/providers/external-sources.ts +218 -0
  383. package/src/providers/ide-provider-instance.ts +35 -12
  384. package/src/providers/manual-attendance.ts +105 -0
  385. package/src/providers/native-history/antigravity-claim-registry.ts +138 -0
  386. package/src/providers/native-history/antigravity-cli-transcript.ts +1275 -0
  387. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  388. package/src/providers/native-history/codex-cli-transcript.ts +479 -0
  389. package/src/providers/native-history/constants.ts +19 -0
  390. package/src/providers/native-history/dispatcher.ts +617 -0
  391. package/src/providers/native-history/hermes-cli-transcript.ts +312 -0
  392. package/src/providers/native-history/index.ts +30 -0
  393. package/src/providers/provider-instance-manager.ts +71 -0
  394. package/src/providers/provider-instance.ts +24 -1
  395. package/src/providers/provider-loader.ts +700 -55
  396. package/src/providers/provider-schema.ts +93 -14
  397. package/src/providers/provider-trust.ts +114 -0
  398. package/src/providers/read-chat-contract.ts +76 -16
  399. package/src/providers/sdk/README.md +49 -0
  400. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  401. package/src/providers/sdk/v1/builders/cli/detect-status.ts +313 -0
  402. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  403. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +261 -0
  404. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  405. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  406. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  407. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  408. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  409. package/src/providers/sdk/v1/index.ts +152 -0
  410. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  411. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  412. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  413. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +538 -0
  414. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  415. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  416. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  417. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  418. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  419. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  420. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  421. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  422. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  423. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  424. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  425. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  426. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  427. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  428. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  429. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  430. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  431. package/src/providers/sdk/v1/types/common/index.ts +229 -0
  432. package/src/providers/sdk/v1/validators/index.ts +19 -0
  433. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  434. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  435. package/src/providers/spec/adapter.ts +246 -0
  436. package/src/providers/spec/cli-adapter.ts +1064 -0
  437. package/src/providers/spec/evaluator.ts +407 -0
  438. package/src/providers/spec/fsm-driver.ts +1528 -0
  439. package/src/providers/spec/fsm-evaluator.ts +290 -0
  440. package/src/providers/spec/fsm-loader.ts +128 -0
  441. package/src/providers/spec/fsm-types.ts +301 -0
  442. package/src/providers/spec/native-history-executor.ts +1241 -0
  443. package/src/providers/spec/pre-launch-trust.ts +104 -0
  444. package/src/providers/spec/route.ts +51 -0
  445. package/src/providers/spec/types.ts +284 -0
  446. package/src/providers/status-monitor.d.ts +7 -7
  447. package/src/providers/status-monitor.ts +37 -22
  448. package/src/providers/transcript-v2.ts +567 -0
  449. package/src/providers/types/interactive-prompt.ts +536 -0
  450. package/src/providers/version-archive.ts +64 -24
  451. package/src/providers/working-dir.ts +23 -0
  452. package/src/repo-mesh-types.ts +861 -14
  453. package/src/runtime-defaults.ts +39 -0
  454. package/src/session-host/managed-host.ts +218 -0
  455. package/src/session-host/runtime-surface.ts +20 -80
  456. package/src/sessions/registry.ts +44 -0
  457. package/src/shared-types-extra.ts +2 -4
  458. package/src/shared-types.d.ts +8 -0
  459. package/src/shared-types.ts +148 -55
  460. package/src/status/builders.ts +69 -6
  461. package/src/status/chat-tail-hot-sessions.ts +117 -2
  462. package/src/status/normalize.ts +2 -0
  463. package/src/status/reporter.ts +19 -1
  464. package/src/status/snapshot.ts +100 -27
  465. package/src/system/hash.ts +23 -0
  466. package/src/system/host-memory.ts +29 -12
  467. package/src/system/load-better-sqlite3.ts +68 -0
  468. package/src/types.ts +26 -6
  469. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
  470. package/dist/mesh/mesh-sync.d.ts +0 -53
  471. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
  472. package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
  473. package/src/mesh/mesh-sync.ts +0 -111
@@ -0,0 +1,231 @@
1
+ import type { MeshLedgerEntry } from './mesh-ledger.js';
2
+ import type { PendingMeshCoordinatorEvent } from './mesh-events.js';
3
+ import type { MeshAsyncJobLifecycle } from '../repo-mesh-types.js';
4
+
5
+ export type MeshAsyncRefineJobStatus = 'accepted' | 'running' | 'completed' | 'failed';
6
+
7
+ export interface MeshAsyncRefineJobSummary extends MeshAsyncJobLifecycle {
8
+ jobId: string;
9
+ interactionId?: string;
10
+ status: MeshAsyncRefineJobStatus;
11
+ meshId?: string;
12
+ nodeId?: string;
13
+ targetNodeId?: string;
14
+ targetDaemonId?: string;
15
+ workspace?: string;
16
+ branch?: string;
17
+ into?: string;
18
+ retryOfJobId?: string;
19
+ lastEvent?: string;
20
+ lastLedgerKind?: string;
21
+ lastUpdatedAt?: string;
22
+ instruction: string;
23
+ }
24
+
25
+ function readString(value: unknown): string | undefined {
26
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
27
+ }
28
+
29
+ function readRecord(value: unknown): Record<string, unknown> | undefined {
30
+ return value && typeof value === 'object' && !Array.isArray(value)
31
+ ? value as Record<string, unknown>
32
+ : undefined;
33
+ }
34
+
35
+ function eventStatus(event: string | undefined, fallback?: string): MeshAsyncRefineJobStatus | undefined {
36
+ if (event === 'refine:accepted') return 'accepted';
37
+ if (event === 'refine:completed') return 'completed';
38
+ if (event === 'refine:failed') return 'failed';
39
+ if (fallback === 'completed' || fallback === 'failed' || fallback === 'accepted') return fallback;
40
+ return undefined;
41
+ }
42
+
43
+ function ledgerStatus(kind: string, fallback?: string): MeshAsyncRefineJobStatus {
44
+ if (kind === 'task_completed') return 'completed';
45
+ if (kind === 'task_failed') return 'failed';
46
+ if (fallback === 'accepted') return 'accepted';
47
+ return 'running';
48
+ }
49
+
50
+ function instructionForStatus(status: MeshAsyncRefineJobStatus): string {
51
+ if (status === 'accepted') return 'Refine job is accepted; wait for asyncRefineJobs or pendingCoordinatorEvents to report running/completed/failed.';
52
+ if (status === 'running') return 'Refine job is running; do not poll the ledger repeatedly. Watch asyncRefineJobs or pendingCoordinatorEvents for the terminal result.';
53
+ if (status === 'completed') return 'Refine job completed; inspect branch convergence and cleanup evidence before reporting final merge state.';
54
+ return 'Refine job failed; inspect result/finalBranchConvergenceState in mesh_task_history, fix the blocker, then rerun mesh_refine_node when ready.';
55
+ }
56
+
57
+ function mergeJob(
58
+ jobs: Map<string, MeshAsyncRefineJobSummary>,
59
+ patch: Partial<MeshAsyncRefineJobSummary> & { jobId?: string },
60
+ ): void {
61
+ const jobId = readString(patch.jobId);
62
+ if (!jobId) return;
63
+ const previous = jobs.get(jobId);
64
+ const status = patch.status || previous?.status || 'running';
65
+ const definedPatch = Object.fromEntries(
66
+ Object.entries(patch).filter(([, value]) => value !== undefined),
67
+ ) as Partial<MeshAsyncRefineJobSummary>;
68
+ jobs.set(jobId, {
69
+ ...previous,
70
+ ...definedPatch,
71
+ jobId,
72
+ status,
73
+ instruction: instructionForStatus(status),
74
+ });
75
+ }
76
+
77
+ export function buildMeshAsyncRefineJobs(args: {
78
+ meshId?: string;
79
+ ledgerEntries?: MeshLedgerEntry[];
80
+ pendingEvents?: PendingMeshCoordinatorEvent[];
81
+ }): MeshAsyncRefineJobSummary[] {
82
+ const jobs = new Map<string, MeshAsyncRefineJobSummary>();
83
+
84
+ for (const entry of args.ledgerEntries || []) {
85
+ const payload = readRecord(entry.payload);
86
+ if (payload?.source !== 'refine_mesh_node_async_job') continue;
87
+ const refineJob = readRecord(payload.refineJob);
88
+ const result = readRecord(payload.result);
89
+ const finalState = readRecord(payload.finalBranchConvergenceState) || readRecord(result?.finalBranchConvergenceState);
90
+ const jobId = readString(refineJob?.jobId);
91
+ if (!jobId) continue;
92
+ const status = ledgerStatus(entry.kind, readString(refineJob?.status));
93
+ mergeJob(jobs, {
94
+ jobId,
95
+ interactionId: readString(refineJob?.interactionId),
96
+ status,
97
+ meshId: readString(refineJob?.meshId) || args.meshId,
98
+ nodeId: readString(refineJob?.nodeId) || entry.nodeId,
99
+ targetNodeId: readString(refineJob?.nodeId) || entry.nodeId,
100
+ targetDaemonId: readString(refineJob?.targetDaemonId),
101
+ workspace: readString(refineJob?.workspace),
102
+ branch: readString(result?.branch) || readString(finalState?.branch),
103
+ into: readString(result?.into) || readString(finalState?.baseBranch),
104
+ startedAt: readString(refineJob?.startedAt),
105
+ completedAt: readString(refineJob?.completedAt),
106
+ retryOfJobId: readString(refineJob?.retryOfJobId) || readString(payload.retryOfJobId),
107
+ lastLedgerKind: entry.kind,
108
+ lastUpdatedAt: entry.timestamp,
109
+ });
110
+ }
111
+
112
+ for (const event of args.pendingEvents || []) {
113
+ const metadata = readRecord(event.metadataEvent);
114
+ if (metadata?.source !== 'refine_mesh_node_async_job') continue;
115
+ const result = readRecord(metadata.result);
116
+ const finalState = readRecord(result?.finalBranchConvergenceState);
117
+ const jobId = readString(metadata.jobId);
118
+ if (!jobId) continue;
119
+ const status = eventStatus(event.event, readString(metadata.status));
120
+ mergeJob(jobs, {
121
+ jobId,
122
+ interactionId: readString(metadata.interactionId),
123
+ ...(status ? { status } : {}),
124
+ meshId: readString(metadata.meshId) || event.meshId || args.meshId,
125
+ nodeId: readString(metadata.nodeId) || event.nodeId,
126
+ targetNodeId: readString(metadata.nodeId) || event.nodeId,
127
+ targetDaemonId: readString(metadata.targetDaemonId),
128
+ workspace: readString(metadata.workspace) || event.workspace,
129
+ branch: readString(result?.branch) || readString(finalState?.branch),
130
+ into: readString(result?.into) || readString(finalState?.baseBranch),
131
+ startedAt: readString(metadata.startedAt),
132
+ completedAt: readString(metadata.completedAt),
133
+ retryOfJobId: readString(metadata.retryOfJobId),
134
+ lastEvent: event.event,
135
+ lastUpdatedAt: new Date(event.queuedAt).toISOString(),
136
+ });
137
+ }
138
+
139
+ return Array.from(jobs.values()).sort((a, b) => {
140
+ const aTime = new Date(a.lastUpdatedAt || a.startedAt || '').getTime();
141
+ const bTime = new Date(b.lastUpdatedAt || b.startedAt || '').getTime();
142
+ return (Number.isFinite(bTime) ? bTime : 0) - (Number.isFinite(aTime) ? aTime : 0);
143
+ });
144
+ }
145
+
146
+ const TERMINAL_REFINE_STATUSES = new Set<MeshAsyncRefineJobStatus>(['completed', 'failed']);
147
+
148
+ /** Terminal refine jobs older than this (relative to the newest job in the set) are
149
+ * "stale" — already-resolved historical refinery rejections/successes that should not
150
+ * keep inflating the status counts in mesh_status. 6h covers a long working session
151
+ * while still folding multi-day-old residue. */
152
+ export const STALE_TERMINAL_REFINE_WINDOW_MS = 6 * 60 * 60 * 1000;
153
+
154
+ /** Cap on how many recent terminal jobs are counted even if all fall inside the freshness
155
+ * window — prevents a burst of refines from dominating the summary. */
156
+ export const RECENT_TERMINAL_REFINE_CAP = 8;
157
+
158
+ export interface MeshAsyncRefineJobsSummary {
159
+ /** Count of jobs reflected in `byStatus` (active jobs + recent terminal jobs). */
160
+ total: number;
161
+ byStatus: Record<string, number>;
162
+ /** Terminal jobs dropped from the counts because they are stale residue. */
163
+ staleTerminal: number;
164
+ /** Non-terminal (accepted/running) jobs still in flight. */
165
+ activeJobs: MeshAsyncRefineJobSummary[];
166
+ }
167
+
168
+ function jobActivityTime(job: MeshAsyncRefineJobSummary): number {
169
+ const raw = job.lastUpdatedAt || job.completedAt || job.startedAt || '';
170
+ const t = new Date(raw).getTime();
171
+ return Number.isFinite(t) ? t : 0;
172
+ }
173
+
174
+ /**
175
+ * Build a compact summary of refine jobs that folds stale terminal jobs.
176
+ *
177
+ * The full job list (from `buildMeshAsyncRefineJobs`) is derived from a recent ledger
178
+ * window and deduped by jobId, but it still includes every terminal (completed/failed)
179
+ * job that happens to fall in that window — including multi-day-old refinery rejections
180
+ * that have long since been resolved. Those stale terminals inflate `byStatus.failed`
181
+ * and read as "current breakage" when they are historical noise.
182
+ *
183
+ * Active (accepted/running) jobs are always counted. Terminal jobs are counted only when
184
+ * they are recent: within `STALE_TERMINAL_REFINE_WINDOW_MS` of the newest job's activity
185
+ * time AND among the `RECENT_TERMINAL_REFINE_CAP` most-recent terminals. Everything else
186
+ * is folded into `staleTerminal` and excluded from `byStatus`.
187
+ *
188
+ * Freshness is measured relative to the newest job in the set (not wall-clock), so the
189
+ * result is deterministic for a given input — important for tests and for stale-clock
190
+ * environments.
191
+ */
192
+ export function summarizeMeshAsyncRefineJobs(
193
+ jobs: MeshAsyncRefineJobSummary[],
194
+ ): MeshAsyncRefineJobsSummary {
195
+ const activeJobs: MeshAsyncRefineJobSummary[] = [];
196
+ const terminalJobs: MeshAsyncRefineJobSummary[] = [];
197
+ for (const job of jobs) {
198
+ if (TERMINAL_REFINE_STATUSES.has(job.status)) terminalJobs.push(job);
199
+ else activeJobs.push(job);
200
+ }
201
+
202
+ // Newest activity across ALL jobs anchors the freshness window.
203
+ let newest = 0;
204
+ for (const job of jobs) newest = Math.max(newest, jobActivityTime(job));
205
+ const cutoff = newest - STALE_TERMINAL_REFINE_WINDOW_MS;
206
+
207
+ const terminalByRecency = [...terminalJobs].sort(
208
+ (a, b) => jobActivityTime(b) - jobActivityTime(a),
209
+ );
210
+ const freshTerminal = terminalByRecency
211
+ .filter(job => jobActivityTime(job) >= cutoff)
212
+ .slice(0, RECENT_TERMINAL_REFINE_CAP);
213
+ const freshTerminalIds = new Set(freshTerminal.map(job => job.jobId));
214
+
215
+ const byStatus: Record<string, number> = {};
216
+ for (const job of activeJobs) {
217
+ byStatus[job.status] = (byStatus[job.status] ?? 0) + 1;
218
+ }
219
+ for (const job of freshTerminal) {
220
+ byStatus[job.status] = (byStatus[job.status] ?? 0) + 1;
221
+ }
222
+
223
+ const staleTerminal = terminalJobs.length - freshTerminalIds.size;
224
+
225
+ return {
226
+ total: activeJobs.length + freshTerminal.length,
227
+ byStatus,
228
+ staleTerminal,
229
+ activeJobs,
230
+ };
231
+ }
@@ -0,0 +1,279 @@
1
+ // ---------------------------------------------------------------------------
2
+ // mesh-remote-event-pull — cloud P2P remote-node pull helpers for the reconcile loop
3
+ // ---------------------------------------------------------------------------
4
+ // Extracted from mesh-reconcile-loop.ts (A-3 god-module decomposition, pure move,
5
+ // no behavior change). These helpers implement the reconcile loop's cloud-only
6
+ // PHASE that pulls pending coordinator events + worker status from REMOTE worker
7
+ // node daemons over P2P (get_pending_mesh_events / read_chat / get_status_metadata)
8
+ // and the payload-unwrapping utilities that tolerate the varied transport envelope
9
+ // shapes a local commandHandler vs. a remote dispatchMeshCommand returns.
10
+ //
11
+ // mesh-completion-synthesis.ts (the PHASE-4 synth) consumes several of these
12
+ // (unwrapReadChatPayload, readChatPayloadStatus, reprobeWorkerStatus,
13
+ // realTerminalEmitPendingForTask, collectLiveNodesWithSessions); the reconcile
14
+ // loop itself consumes pullRemoteNodeQueues.
15
+ // ---------------------------------------------------------------------------
16
+
17
+ import type { DaemonComponents } from '../boot/daemon-lifecycle.js';
18
+ import type { LocalMeshEntry } from '../repo-mesh-types.js';
19
+ import { getPendingMeshCoordinatorEvents, serializeV2EnvelopeToWire } from './mesh-events-pending.js';
20
+ import type { PendingMeshCoordinatorEvent } from './mesh-events-pending.js';
21
+ import { handleMeshForwardEvent } from './mesh-events-coordinator.js';
22
+ import { readNonEmptyString } from './mesh-events-utils.js';
23
+ import { daemonIdsEquivalent } from '@adhdev/mesh-shared';
24
+ import { daemonIdListIncludes } from './mesh-reconcile-identity.js';
25
+
26
+ // Cloud-only: poll each remote worker node daemon for pending coordinator events
27
+ // and re-inject them locally via handleMeshForwardEvent (which re-queues +
28
+ // surfaces to the live coordinator on the next tick / immediately if idle).
29
+ //
30
+ // Scoping: the remote handler (get_pending_mesh_events) drains its queue filtered
31
+ // by coordinatorDaemonId — returning events targeted at that id OR unscoped, and
32
+ // leaving events targeted at a *different* coordinator. A remote worker stamps the
33
+ // coordinator id in one of SEVERAL forms (the canonical status id `standalone_`/
34
+ // `daemon_<machineId>` stamped by the MCP layer, the bare machineId stamped by the
35
+ // local queue path, OR — most commonly for remote launches — the coordinator mesh
36
+ // node's config-form `daemonId`, which resolveCoordinatorDaemonId prefers and which
37
+ // is NOT canonicalised). `candidateDaemonIds` is the already-expanded self-identity
38
+ // set (resolveCoordinatorSelfIds: runtime drain ids ∪ this daemon's mesh-config node/
39
+ // host id forms), so we pull ONCE PER candidate id and a completion stamped with any
40
+ // of them is recovered. The remote drain is atomic (drained=1), so issuing multiple
41
+ // pulls cannot double-deliver — the first pull that matches consumes the event; the
42
+ // rest see nothing. When no ids resolve we fall back to a single unscoped pull.
43
+ export async function pullRemoteNodeQueues(
44
+ components: DaemonComponents,
45
+ mesh: LocalMeshEntry,
46
+ localDaemonId: string | undefined,
47
+ candidateDaemonIds: string[],
48
+ ): Promise<void> {
49
+ const dispatchMeshCommand = components.dispatchMeshCommand;
50
+ if (!dispatchMeshCommand) return;
51
+ const meshId = mesh.id;
52
+
53
+ // One args object per candidate coordinator-id form, or a single unscoped pull
54
+ // when none resolve.
55
+ const pulls: Array<Record<string, unknown>> = candidateDaemonIds.length > 0
56
+ ? candidateDaemonIds.map(id => ({ meshId, coordinatorDaemonId: id }))
57
+ : [{ meshId }];
58
+
59
+ // Parallelize across nodes: a single connected-but-slow node must not serially
60
+ // block the other nodes for the rest of the tick. Each node callback is fully
61
+ // self-contained (local/candidate skip, peer-connected pre-check, per-candidate
62
+ // pulls, extract→re-inject) and best-effort — allSettled swallows per-node errors.
63
+ await Promise.allSettled(mesh.nodes.map(async (node) => {
64
+ const nodeDaemonId = readNonEmptyString(node.daemonId);
65
+ // Skip nodes without a daemon, and nodes on THIS daemon (their events are
66
+ // already in the local queue drained in PHASE 2). "This daemon" is matched
67
+ // against the full self-identity set (candidateDaemonIds), not just the bare
68
+ // localDaemonId — a self node can be registered under the config-form daemonId
69
+ // (`daemon_<machineId>`) which would NOT equal bare localDaemonId, and pulling
70
+ // from ourselves over P2P is both wasteful and a self-dispatch hazard.
71
+ if (!nodeDaemonId) return;
72
+ if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) return;
73
+ if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) return;
74
+
75
+ // Peer-connected pre-check (EVENT-DELIVERY-DELAY fix(a)): a degraded peer whose
76
+ // DataChannel is not open would sink this pull into peer.connectQueue and stall
77
+ // until CONNECT_TIMEOUT_MS (90s), formerly freezing the whole serial loop and
78
+ // delaying completion-event recovery from healthy nodes. Skip such a node THIS
79
+ // tick and retry next tick — LOSSLESS: an unconnected peer has not drained
80
+ // anything (drained=0 preserved), so its events are recovered whole on the next
81
+ // successful tick. Skip = delay, never loss.
82
+ // • snapshot present and state !== 'connected' → skip (continue next tick).
83
+ // • snapshot null/undefined (getter unwired, e.g. standalone) → DO NOT skip;
84
+ // fall through to the legacy path so this stays regression-free.
85
+ const peerSnapshot = components.getMeshPeerConnectionStatus?.(nodeDaemonId);
86
+ if (peerSnapshot && String(peerSnapshot.state) !== 'connected') return;
87
+
88
+ for (const pendingEventArgs of pulls) {
89
+ let events: unknown;
90
+ try {
91
+ events = await dispatchMeshCommand(nodeDaemonId, 'get_pending_mesh_events', pendingEventArgs);
92
+ } catch {
93
+ // Remote pull is best-effort; the node may be offline. Retry next tick.
94
+ break; // node unreachable — don't bother with the other id form this tick.
95
+ }
96
+ const list = extractPendingEvents(events).filter(e => readNonEmptyString(e?.meshId) === meshId);
97
+ for (const event of list) {
98
+ const payload = buildForwardPayloadFromPending(event);
99
+ if (!payload.event || !payload.meshId) continue;
100
+ try {
101
+ handleMeshForwardEvent(components, payload);
102
+ } catch { /* best-effort re-inject */ }
103
+ }
104
+ }
105
+ }));
106
+ }
107
+
108
+ // Pull the read_chat payload out of whatever envelope the transport returned.
109
+ // A local commandHandler.handle() returns the CommandResult directly; a remote
110
+ // dispatchMeshCommand returns it possibly wrapped in { payload } / { result }.
111
+ export function unwrapReadChatPayload(raw: unknown): Record<string, unknown> | null {
112
+ let cursor: unknown = raw;
113
+ for (let depth = 0; depth < 4 && cursor && typeof cursor === 'object'; depth++) {
114
+ const record = cursor as Record<string, unknown>;
115
+ if (Array.isArray(record.messages)) return record;
116
+ if (record.payload && typeof record.payload === 'object') { cursor = record.payload; continue; }
117
+ if (record.result && typeof record.result === 'object') { cursor = record.result; continue; }
118
+ if (record.data && typeof record.data === 'object') { cursor = record.data; continue; }
119
+ break;
120
+ }
121
+ return cursor && typeof cursor === 'object' ? cursor as Record<string, unknown> : null;
122
+ }
123
+
124
+ export function readChatPayloadStatus(payload: Record<string, unknown> | null): string {
125
+ return readNonEmptyString(payload?.status).toLowerCase();
126
+ }
127
+
128
+ // R4e fix (3): peek the pending-events queue for a REAL (worker-emitted) terminal completion
129
+ // already queued for a task — used to yield the in-flight synth to the worker's own emit. Broad
130
+ // peek (no daemon-id scoping) matched precisely by taskId, so a worker stamp in any daemon-id form
131
+ // is still recognized. Best-effort: a peek failure returns false (proceed to synth — never block
132
+ // delivery). A prior SYNTH's still-queued pending event also names this taskId, but a synth always
133
+ // writes its terminal ledger atomically, so hasTerminalLedgerAfterDispatch downstream already
134
+ // no-ops that case — this guard is specifically for an as-yet-unledgered worker emit in flight.
135
+ export function realTerminalEmitPendingForTask(meshId: string, taskId: string): boolean {
136
+ let pending: readonly PendingMeshCoordinatorEvent[];
137
+ try {
138
+ pending = getPendingMeshCoordinatorEvents(meshId);
139
+ } catch {
140
+ return false;
141
+ }
142
+ return pending.some(e =>
143
+ readNonEmptyString(e.metadataEvent?.taskId) === taskId
144
+ && (e.event === 'agent:generating_completed' || e.event === 'agent:stopped'));
145
+ }
146
+
147
+ // R4e fix (2): one fresh read_chat status read for the worker session, via the same local/remote
148
+ // transport PHASE 4 uses. Returns the lowercased status, or null when the read is inconclusive
149
+ // (transport error, success:false, no payload) — callers treat null as "no new evidence, proceed".
150
+ export async function reprobeWorkerStatus(
151
+ components: DaemonComponents,
152
+ args: { isLocalNode: boolean; nodeDaemonId: string; readArgs: Record<string, unknown> },
153
+ ): Promise<string | null> {
154
+ try {
155
+ if (args.isLocalNode) {
156
+ const r = await components.commandHandler.handle('read_chat', args.readArgs);
157
+ if (r && (r as { success?: boolean }).success === false) return null;
158
+ return readChatPayloadStatus(unwrapReadChatPayload(r));
159
+ }
160
+ if (components.dispatchMeshCommand) {
161
+ const r = await components.dispatchMeshCommand(args.nodeDaemonId, 'read_chat', args.readArgs);
162
+ const p = unwrapReadChatPayload(r);
163
+ if (p && (p as { success?: boolean }).success === false) return null;
164
+ return readChatPayloadStatus(p);
165
+ }
166
+ } catch {
167
+ return null;
168
+ }
169
+ return null;
170
+ }
171
+
172
+ // Probe each node for its live session list (get_status_metadata) and return mesh.nodes
173
+ // decorated with a `sessions` array — the shape buildMeshActiveWork / sessionStatusFromNodes
174
+ // consume to decide whether a dispatched session is still present. Best-effort: an unreachable
175
+ // node yields an empty session list rather than throwing.
176
+ export async function collectLiveNodesWithSessions(
177
+ components: DaemonComponents,
178
+ mesh: LocalMeshEntry,
179
+ selfIds: string[],
180
+ localDaemonId: string | undefined,
181
+ ): Promise<any[]> {
182
+ const dispatchMeshCommand = components.dispatchMeshCommand;
183
+ return Promise.all(mesh.nodes.map(async (node) => {
184
+ const nodeDaemonId = readNonEmptyString(node.daemonId);
185
+ const isLocalNode = !nodeDaemonId
186
+ || daemonIdListIncludes(selfIds, nodeDaemonId)
187
+ || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
188
+ // Peer-connected pre-check (EVENT-DELIVERY-DELAY fix(a)): mirror pullRemoteNodeQueues.
189
+ // Without this the 90s connect-deadline block re-enters via this Promise.all —
190
+ // a degraded remote's get_status_metadata sinks into peer.connectQueue and stalls
191
+ // the whole prune probe. Only call the remote when the peer is 'connected'; an
192
+ // unconnected peer is left undecorated (empty session list), same as unreachable.
193
+ // Getter unwired (null/undefined) → do NOT skip, fall through (regression-free).
194
+ if (!isLocalNode) {
195
+ const peerSnapshot = components.getMeshPeerConnectionStatus?.(nodeDaemonId);
196
+ if (peerSnapshot && String(peerSnapshot.state) !== 'connected') return node;
197
+ }
198
+ let statusResult: unknown;
199
+ try {
200
+ if (isLocalNode) {
201
+ statusResult = await components.commandHandler.handle('get_status_metadata', {});
202
+ } else if (dispatchMeshCommand) {
203
+ statusResult = await dispatchMeshCommand(nodeDaemonId, 'get_status_metadata', {});
204
+ } else {
205
+ return node; // remote node, no P2P transport — leave undecorated
206
+ }
207
+ } catch {
208
+ return node; // unreachable — leave undecorated (empty session list)
209
+ }
210
+ const sessions = extractStatusMetadataSessions(statusResult);
211
+ return sessions.length > 0 ? { ...node, sessions } : node;
212
+ }));
213
+ }
214
+
215
+ // Pull the live session list out of a get_status_metadata result, tolerating the same
216
+ // envelope shapes unwrapReadChatPayload handles (direct CommandResult or { payload }/{ result }).
217
+ export function extractStatusMetadataSessions(raw: unknown): any[] {
218
+ let cursor: unknown = raw;
219
+ for (let depth = 0; depth < 4 && cursor && typeof cursor === 'object'; depth++) {
220
+ const record = cursor as Record<string, unknown>;
221
+ const status = record.status && typeof record.status === 'object' ? record.status as Record<string, unknown> : undefined;
222
+ if (status && Array.isArray(status.sessions)) return status.sessions;
223
+ if (Array.isArray(record.sessions)) return record.sessions;
224
+ if (record.payload && typeof record.payload === 'object') { cursor = record.payload; continue; }
225
+ if (record.result && typeof record.result === 'object') { cursor = record.result; continue; }
226
+ if (record.data && typeof record.data === 'object') { cursor = record.data; continue; }
227
+ break;
228
+ }
229
+ return [];
230
+ }
231
+
232
+ export function extractPendingEvents(raw: unknown): any[] {
233
+ if (Array.isArray(raw)) return raw;
234
+ if (raw && typeof raw === 'object') {
235
+ const events = (raw as Record<string, unknown>).events;
236
+ if (Array.isArray(events)) return events;
237
+ }
238
+ return [];
239
+ }
240
+
241
+ // Flatten a queued PendingMeshCoordinatorEvent into the flat payload shape
242
+ // handleMeshForwardEvent expects (mirrors the MCP buildMeshForwardPayloadFromPendingEvent).
243
+ export function buildForwardPayloadFromPending(event: any): Record<string, unknown> {
244
+ const metadata = event?.metadataEvent && typeof event.metadataEvent === 'object'
245
+ ? event.metadataEvent as Record<string, unknown>
246
+ : {};
247
+ return {
248
+ event: readNonEmptyString(event?.event),
249
+ meshId: readNonEmptyString(event?.meshId),
250
+ nodeId: readNonEmptyString(event?.nodeId) || readNonEmptyString(metadata.meshNodeId),
251
+ workspace: readNonEmptyString(event?.workspace) || readNonEmptyString(metadata.workspace),
252
+ // Preserve the originating coordinator session id across the relay. It is normally
253
+ // carried inside metadataEvent.meshCoordinatorSessionId (spread below), but pass the
254
+ // top-level field through explicitly too so the handleMeshForwardEvent whitelist
255
+ // recovers it regardless of which carrier the producing daemon used.
256
+ ...(readNonEmptyString(event?.targetCoordinatorSessionId)
257
+ ? { targetCoordinatorSessionId: readNonEmptyString(event.targetCoordinatorSessionId) }
258
+ : {}),
259
+ ...metadata,
260
+ // NOTIF-MISS (FIX 3): surface the dispatch task id at the TOP LEVEL so the relay's
261
+ // received-stage trace (and buildRelayMetadataEvent) recovers it regardless of which
262
+ // carrier the producing daemon used. The metadata spread above may carry the id only as
263
+ // `meshActiveTaskId` (a worker provider event), leaving top-level `taskId` unset and the
264
+ // received stage rendering `task=-`. Resolve both carriers into an explicit `taskId` so
265
+ // dedup stays task-scoped end-to-end. Only set when a non-empty id exists (no clobber to
266
+ // undefined when neither is present).
267
+ ...((): Record<string, unknown> => {
268
+ const tid = readNonEmptyString(metadata.taskId) || readNonEmptyString(metadata.meshActiveTaskId);
269
+ return tid ? { taskId: tid } : {};
270
+ })(),
271
+ // T4 (B3b): carry the v2 envelope (protocolVersion/eventId/scope/dispatchedBy/
272
+ // intendedFor) across the P2P relay boundary at the TOP LEVEL. These live on the
273
+ // pending event itself, not inside metadataEvent, so without this the remote pull
274
+ // re-queue would re-stamp a fresh eventId — breaking cross-machine idempotency and
275
+ // downgrading the relayed completion to v1 broadcast routing. Spread LAST so the
276
+ // authoritative envelope always wins over any stale key the metadata spread carried.
277
+ ...serializeV2EnvelopeToWire(event as PendingMeshCoordinatorEvent),
278
+ };
279
+ }