@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,857 @@
1
+ /**
2
+ * RF-ROUTER HIGH family — mesh aggregate status + review inbox.
3
+ *
4
+ * mesh_status: the coordinator's aggregate mesh render — resolves membership,
5
+ * gates the memory cache against pending coordinator events / explicit refresh,
6
+ * optionally fans out a direct peer-truth probe, then renders per-node health
7
+ * (live session records, local/remote/inline git truth, branch convergence) and
8
+ * folds in queue/ledger/missions/async-refine/historical-session/active-refine
9
+ * state. get_mesh_review_inbox: derives review-inbox items from node statuses +
10
+ * ledger and annotates each with a worktree git-diff summary. Extracted verbatim
11
+ * from executeDaemonCommand — only `this.*` router members became `ctx.*` and the
12
+ * relative dynamic-import paths were re-based one directory deeper.
13
+ */
14
+ import * as fs from 'fs';
15
+ import { hostname as osHostname } from 'os';
16
+ import { loadConfig } from '../../config/config.js';
17
+ import { getGitRepoStatus } from '../../git/git-status.js';
18
+ import {
19
+ normalizeMeshNodeId,
20
+ daemonIdsEquivalent,
21
+ normalizeNodeCapabilitySlots,
22
+ } from '@adhdev/mesh-shared';
23
+ import {
24
+ getPendingMeshCoordinatorEvents,
25
+ getMeshV2DrainCounters,
26
+ getMeshV2BackstopCounters,
27
+ isMeshProtocolV2EnforceEnabled,
28
+ } from '../../mesh/mesh-events.js';
29
+ import type { MeshProtocolV2Counters } from '../../repo-mesh-types.js';
30
+ import { getRecentUnroutableDeliveries } from '../../mesh/mesh-routing.js';
31
+ import { normalizeMeshDaemonRole, resolveMeshHostStatus } from '../../mesh/mesh-host-ownership.js';
32
+ import { buildPreviewFreshness } from '../../mesh/preview-freshness.js';
33
+ import { buildMeshAsyncRefineJobs } from '../../mesh/mesh-refine-status.js';
34
+ import { partitionSessionHostRecords } from '../../session-host/runtime-surface.js';
35
+ import {
36
+ readStringValue,
37
+ readObjectRecord,
38
+ readBooleanValue,
39
+ readMeshNodeMachineId,
40
+ readMeshNodeHostname,
41
+ readProviderPriorityFromPolicy,
42
+ buildMeshNodeMachineIdentity,
43
+ buildMeshNodeDisplayLabel,
44
+ collectLiveMeshSessionRecords,
45
+ readLiveMeshNodeWorkspace,
46
+ summarizeMeshSessionRecord,
47
+ buildInlineMeshTransitGitStatus,
48
+ deriveMeshNodeHealthFromGit,
49
+ buildLivePeerGitConnection,
50
+ probeRemoteMeshGitStatusWithRetry,
51
+ recordInlineMeshDirectGitTruth,
52
+ persistNodeReporterPlatform,
53
+ applyCachedInlineMeshNodeStatus,
54
+ applyInlineMeshBranchConvergence,
55
+ finalizeMeshNodeStatus,
56
+ summarizeInlineMeshBranchConvergence,
57
+ buildHistoricalMeshSessions,
58
+ hydrateInlineMeshDirectTruth,
59
+ MESH_NODE_LIVE_TRUTH_MARKER,
60
+ logRepoMeshStatusDebug,
61
+ summarizeRepoMeshStatusDebug,
62
+ MESH_DIRECT_PROBE_TIMEOUT_MS,
63
+ MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS,
64
+ } from '../router.js';
65
+ import type { HighFamilyContext, HighFamilyHandler } from './types.js';
66
+
67
+ export const meshStatusHandlers: Record<string, HighFamilyHandler> = {
68
+ mesh_status: async (ctx: HighFamilyContext, args: any) => {
69
+ const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
70
+ if (!meshId) return { success: false, error: 'meshId required' };
71
+ // Latency telemetry: stamp handler entry so every return path can
72
+ // report durationMs. Makes the detail-open cost measurable in the
73
+ // repo-mesh-status debug log (cache hit ≈ single-digit ms; a full
74
+ // live rebuild is the ~seconds path this change is reducing).
75
+ const startedAtMs = Date.now();
76
+ try {
77
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
78
+ const mesh = meshRecord?.mesh;
79
+ if (!mesh) return { success: false, error: 'Mesh not found' };
80
+ // Pass the evaluating daemon's id so a host mesh whose
81
+ // hostDaemonId was never persisted (HOST-MISSEED-FIRSTSETUP) gets
82
+ // pinned to THIS daemon — the dashboard then renders M4 as host
83
+ // instead of falling back to 'no host yet'.
84
+ const meshHost = resolveMeshHostStatus(mesh, { localDaemonId: ctx.deps.statusInstanceId });
85
+
86
+ const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
87
+ // Compact (default) elides each mission's full goal text from the
88
+ // payload — coordinators polling node health don't need every
89
+ // mission's multi-hundred-char goal repeated. verbose=true (or the
90
+ // explicit compact=false) restores full goals. Verbose bypasses the
91
+ // shared (compact) aggregate cache so a verbose call never poisons
92
+ // the compact cache and vice versa.
93
+ const verboseMissions = args?.verbose === true || args?.compact === false;
94
+ // See (B3) below: scope the peek to this daemon when the
95
+ // caller doesn't tell us, otherwise scoped events look
96
+ // missing and we falsely return a stale cache.
97
+ const peekScope = typeof args?.coordinatorDaemonId === 'string' && args.coordinatorDaemonId.trim()
98
+ ? args.coordinatorDaemonId.trim()
99
+ : (ctx.deps.statusInstanceId || undefined);
100
+ const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
101
+ const hadAggregateCache = ctx.aggregateMeshStatusCache.has(meshId);
102
+ if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
103
+ const cachedStatus = ctx.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
104
+ if (cachedStatus) {
105
+ logRepoMeshStatusDebug('return_cached', {
106
+ meshId,
107
+ command: 'mesh_status',
108
+ refreshRequested,
109
+ durationMs: Date.now() - startedAtMs,
110
+ summary: summarizeRepoMeshStatusDebug(cachedStatus),
111
+ });
112
+ return cachedStatus;
113
+ }
114
+ // SWR stale-serve: the strict serve above missed only because
115
+ // some node still has a pending peer-git probe (the
116
+ // shouldRefreshStalePendingAggregate gate). Rather than block
117
+ // this interactive detail-open on a full synchronous live
118
+ // rebuild, serve the held (slightly stale) snapshot instantly
119
+ // and kick ONE coalesced background freshen whose result
120
+ // repopulates the cache for the next poll/subscription push.
121
+ // allowStalePending relaxes ONLY the pending-git freshness gate;
122
+ // getCachedAggregateMeshStatus still enforces the queueRevision
123
+ // guard, so a genuine queue/identity mutation is never stale-served.
124
+ const staleStatus = ctx.getCachedAggregateMeshStatus(meshId, mesh, {
125
+ requireDirectPeerTruth: args?.requireDirectPeerTruth === true,
126
+ allowStalePending: true,
127
+ });
128
+ if (staleStatus) {
129
+ if (!ctx.swrRefreshInFlight.has(meshId)) {
130
+ ctx.swrRefreshInFlight.add(meshId);
131
+ // Fire-and-forget: a full refresh (peer fan-out) that
132
+ // rewrites the aggregate cache. Errors are swallowed —
133
+ // the stale snapshot was already returned to the caller.
134
+ void Promise.resolve()
135
+ .then(() => ctx.execute('mesh_status', {
136
+ meshId,
137
+ inlineMesh: args?.inlineMesh,
138
+ coordinatorDaemonId: args?.coordinatorDaemonId,
139
+ requireDirectPeerTruth: args?.requireDirectPeerTruth === true,
140
+ refresh: true,
141
+ }, 'mesh_status_swr_freshen'))
142
+ .catch(() => {})
143
+ .finally(() => { ctx.swrRefreshInFlight.delete(meshId); });
144
+ }
145
+ logRepoMeshStatusDebug('return_stale_swr', {
146
+ meshId,
147
+ command: 'mesh_status',
148
+ refreshRequested,
149
+ durationMs: Date.now() - startedAtMs,
150
+ summary: summarizeRepoMeshStatusDebug(staleStatus),
151
+ });
152
+ return staleStatus;
153
+ }
154
+ }
155
+ const refreshReason = refreshRequested
156
+ ? 'explicit_refresh'
157
+ : pendingCoordinatorEventCount > 0
158
+ ? 'pending_coordinator_events'
159
+ : hadAggregateCache
160
+ ? 'stale_pending_cache_refresh'
161
+ : 'cold_cache_miss';
162
+
163
+ const { getMeshQueueStats, getQueue } = await import('../../mesh/mesh-work-queue.js');
164
+ const queue = getQueue(meshId);
165
+ const queueSummary = getMeshQueueStats(meshId);
166
+
167
+ // Scheduling-runtime projection — the load-balancer's live view (tie-break
168
+ // strategy, global parallel caps + consumption, per-node load/priority/provider
169
+ // caps). Built from the SAME helper + args the MCP `mesh_status` tool uses
170
+ // (mesh-tools-status.ts: buildMeshSchedulingRuntime(mesh, getQueue(mesh.id)))
171
+ // so the dashboard surface and the coordinator MCP surface render an identical
172
+ // runtime. Without this the dashboard Status/Runtime tab showed the
173
+ // "not reported by this daemon (older build)" fallback (RepoMeshStatus.scheduling
174
+ // was never populated by this daemon-command producer). Computed once so each
175
+ // node entry can attach its slice and statusResult can carry the mesh rollup.
176
+ const { buildMeshSchedulingRuntime } = await import('../../mesh/mesh-scheduling-runtime.js');
177
+ const schedulingRuntime = buildMeshSchedulingRuntime(mesh, queue);
178
+ const schedulingByNode = new Map(schedulingRuntime.nodes.map(n => [n.nodeId, n]));
179
+
180
+ const { readLedgerEntries, getLedgerSummary } = await import('../../mesh/mesh-ledger.js');
181
+ const ledgerEntries = readLedgerEntries(meshId, { tail: 20 });
182
+ const asyncRefineLedgerEntries = readLedgerEntries(meshId, { tail: 100 });
183
+ const ledgerSummary = getLedgerSummary(meshId);
184
+ const sessionHostRecords = ctx.deps.sessionHostControl?.listSessions
185
+ ? await ctx.deps.sessionHostControl.listSessions().catch(() => [])
186
+ : [];
187
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
188
+
189
+ const localMachineId = loadConfig().machineId || '';
190
+ // Local daemon's operator-set nickname — stamped onto the self/base
191
+ // node at render time so the friendly label resolves even before the
192
+ // persisted node record (addNode) has been rewritten with it.
193
+ const localMachineNickname = (() => {
194
+ const nick = loadConfig().machineNickname;
195
+ return typeof nick === 'string' && nick.trim() ? nick.trim() : '';
196
+ })();
197
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
198
+ // Shared probe gate for this mesh_status call: the bootstrap
199
+ // hydrate below and the per-node render loop further down both
200
+ // probe the same peers — route both through this cache so they
201
+ // dedup within the call and reuse recent results across calls.
202
+ const meshGitProbeCache = ctx.meshGitProbeCache;
203
+ const directTruth = requireDirectPeerTruth
204
+ ? await hydrateInlineMeshDirectTruth({
205
+ mesh,
206
+ meshSource: meshRecord.source,
207
+ dispatchMeshCommand: ctx.deps.dispatchMeshCommand,
208
+ getMeshPeerConnectionStatus: ctx.deps.getMeshPeerConnectionStatus,
209
+ statusInstanceId: ctx.deps.statusInstanceId,
210
+ localMachineId,
211
+ // Standing-state model: only an explicit refresh fans
212
+ // out a blocking peer git probe. Default loads return
213
+ // held truth so one slow peer can't block the graph.
214
+ probeRemotePeers: refreshRequested,
215
+ probeCache: meshGitProbeCache,
216
+ })
217
+ : {
218
+ directEvidenceCount: 0,
219
+ localConfirmedCount: 0,
220
+ peerAttemptedCount: 0,
221
+ peerConfirmedCount: 0,
222
+ standingEvidenceCount: 0,
223
+ unavailableNodeIds: [] as string[],
224
+ deadNodeIds: [] as string[],
225
+ };
226
+ // Default/cached loads may not attempt a remote peer probe yet; do not surface that as
227
+ // a direct mesh truth failure until an explicit probe attempt actually fails.
228
+ const passivePeerTruthNotAttempted = requireDirectPeerTruth
229
+ && !refreshRequested
230
+ && directTruth.directEvidenceCount > 0
231
+ && directTruth.peerAttemptedCount === 0;
232
+ const effectiveDirectTruth = passivePeerTruthNotAttempted
233
+ ? { ...directTruth, unavailableNodeIds: [] as string[] }
234
+ : directTruth;
235
+ const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
236
+ const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0
237
+ && Array.isArray(mesh.nodes)
238
+ && mesh.nodes
239
+ .filter((node: any) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? ''))
240
+ .every((node: any) => node?.isLocalWorktree === true);
241
+ // Default (non-refresh) loads never hard-fail: held
242
+ // standing-state truth is returned and the graph renders
243
+ // immediately. The hard mesh_direct_peer_truth_unavailable
244
+ // failure is reserved for an explicit refresh that actually
245
+ // attempted a peer probe and could not confirm any evidence.
246
+ const directTruthSatisfied = !requireDirectPeerTruth
247
+ || !refreshRequested
248
+ || (effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees));
249
+ if (requireDirectPeerTruth && refreshRequested && !directTruthSatisfied) {
250
+ const failureResult = {
251
+ success: false,
252
+ code: 'mesh_direct_peer_truth_unavailable',
253
+ error: 'Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct mesh_status probes succeed.',
254
+ sourceOfTruth: {
255
+ membership: meshRecord.source === 'inline_cache'
256
+ ? 'coordinator_inline_mesh_cache'
257
+ : meshRecord.source === 'local_config'
258
+ ? 'local_mesh_config'
259
+ : 'inline_bootstrap_snapshot',
260
+ coordinatorOwnsLiveTruth: false,
261
+ currentStatus: 'direct_peer_truth_unavailable',
262
+ directPeerTruth: {
263
+ required: true,
264
+ satisfied: false,
265
+ directEvidenceCount: directTruth.directEvidenceCount,
266
+ localConfirmedCount: directTruth.localConfirmedCount,
267
+ peerAttemptedCount: directTruth.peerAttemptedCount,
268
+ peerConfirmedCount: directTruth.peerConfirmedCount,
269
+ unavailableNodeIds: directTruth.unavailableNodeIds,
270
+ },
271
+ },
272
+ };
273
+ logRepoMeshStatusDebug('direct_truth_unavailable', {
274
+ meshId,
275
+ command: 'mesh_status',
276
+ refreshRequested,
277
+ meshSource: meshRecord.source,
278
+ directTruth,
279
+ });
280
+ return failureResult;
281
+ }
282
+ const directTruthUnavailableNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
283
+ const coordinatorHostname = osHostname();
284
+ const selectedCoordinatorNodeId = readStringValue(
285
+ mesh.coordinator?.preferredNodeId,
286
+ normalizeMeshNodeId(mesh.nodes?.[0] as any),
287
+ );
288
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes)
289
+ ? selectedCoordinatorNodeId
290
+ : undefined;
291
+ const refreshedAt = new Date().toISOString();
292
+ // Per-node render is parallelized (Promise.allSettled below):
293
+ // each node's git probe (local getGitRepoStatus or the remote
294
+ // P2P fan-out) is independent, so serializing them stacked one
295
+ // slow node's latency onto every other node. Each node has its
296
+ // own bounded timeout; a rejected/timed-out node degrades to a
297
+ // partial/last-known status for THAT node only and never rejects
298
+ // the whole aggregate. Order is preserved by mapping over the
299
+ // original entries() index and re-assembling in order.
300
+ const renderMeshNode = async (nodeIndex: number, node: any): Promise<Record<string, unknown>> => {
301
+ const nodeId = normalizeMeshNodeId(node) ?? '';
302
+ const daemonId = readStringValue(node.daemonId);
303
+ const nodeMachineId = readMeshNodeMachineId(node as Record<string, unknown>);
304
+ const nodeHostname = readMeshNodeHostname(node as Record<string, unknown>);
305
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
306
+ const configuredCoordinatorNode = Boolean(
307
+ nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId,
308
+ );
309
+ const sparseConfiguredCoordinatorNode = configuredCoordinatorNode
310
+ && !daemonId
311
+ && !nodeMachineId
312
+ && !nodeHostname;
313
+ const isSelfNode = Boolean(
314
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId,
315
+ ) || Boolean(
316
+ daemonId && (daemonIdsEquivalent(daemonId, localMachineId) || daemonIdsEquivalent(daemonId, ctx.deps.statusInstanceId)),
317
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0)
318
+ || sparseConfiguredCoordinatorNode;
319
+ // The self/base node's friendly label comes from THIS daemon's
320
+ // local config.machineNickname. Stamp it onto the node record (if
321
+ // not already carried) so buildMeshNodeDisplayLabel below resolves
322
+ // to the nickname and labelSource reads 'explicit_metadata' even
323
+ // before addNode's persisted record has been rewritten.
324
+ if (isSelfNode && localMachineNickname && !readStringValue(node.machineNickname, node.machine_nickname)) {
325
+ node.machineNickname = localMachineNickname;
326
+ }
327
+ const machineIdentity = buildMeshNodeMachineIdentity(node as Record<string, unknown>, {
328
+ localMachineId,
329
+ localDaemonId: ctx.deps.statusInstanceId,
330
+ coordinatorHostname,
331
+ isSelfNode,
332
+ });
333
+ const status: Record<string, unknown> = {
334
+ nodeId,
335
+ machineLabel: buildMeshNodeDisplayLabel(node as Record<string, unknown>, nodeId, providerPriority),
336
+ labelSource: readStringValue(node.machineLabel, node.machine_label, node.machineNickname, node.machine_nickname, node.alias)
337
+ ? 'explicit_metadata'
338
+ : 'workspace_host_provider_context',
339
+ workspace: node.workspace,
340
+ repoRoot: node.repoRoot,
341
+ isLocalWorktree: node.isLocalWorktree,
342
+ worktreeBranch: node.worktreeBranch,
343
+ role: normalizeMeshDaemonRole(node.role) || (meshHost.hostNodeId && nodeId === meshHost.hostNodeId ? 'host' : undefined),
344
+ daemonId,
345
+ machineId: nodeMachineId || node.machineId,
346
+ machine: machineIdentity,
347
+ machineStatus: node.machineStatus,
348
+ health: 'unknown',
349
+ providers: node.providers || [],
350
+ // T7: surface self-healed provider versions + build version (from the
351
+ // git_status envelope, persisted on the node) so the coordinator/UI can
352
+ // spot a provider-version skew across nodes. Additive; omitted when a
353
+ // node has never reported them.
354
+ ...(node.reportedProviderVersions && typeof node.reportedProviderVersions === 'object'
355
+ ? { providerVersions: node.reportedProviderVersions }
356
+ : {}),
357
+ ...(typeof node.reportedDaemonBuildVersion === 'string' && node.reportedDaemonBuildVersion
358
+ ? { daemonBuildVersion: node.reportedDaemonBuildVersion }
359
+ : {}),
360
+ providerPriority,
361
+ // ORCHESTRATION_NODE_SLOTS.md: surface the node's capability
362
+ // slots so the dashboard slot editor can read them. Only
363
+ // emitted when explicitly configured (derived-from-legacy
364
+ // slots stay implicit — the editor shows the legacy fields).
365
+ ...(Array.isArray((node.policy as any)?.slots) && (node.policy as any).slots.length
366
+ ? { slots: normalizeNodeCapabilitySlots((node.policy as any).slots) }
367
+ : {}),
368
+ activeSessions: [],
369
+ activeSessionDetails: [],
370
+ launchReady: false,
371
+ };
372
+ // Per-node scheduling slice (load / priority / provider caps / claim-block
373
+ // reasons) read by the dashboard's MeshNodeSchedulingBadges. Full shape —
374
+ // unlike the MCP compact path this is a dashboard surface, so it keeps the
375
+ // whole RepoMeshNodeSchedulingStatus. Redundant nodeId dropped (the entry
376
+ // already carries it).
377
+ const nodeScheduling = schedulingByNode.get(nodeId);
378
+ if (nodeScheduling) {
379
+ const { nodeId: _omitNodeId, ...nodeSchedulingRest } = nodeScheduling;
380
+ status.scheduling = nodeSchedulingRest;
381
+ }
382
+ if (isSelfNode) {
383
+ status.connection = {
384
+ perspective: 'selected_coordinator',
385
+ source: 'mesh_peer_status',
386
+ state: 'self',
387
+ transport: 'local',
388
+ reported: true,
389
+ reason: 'Selected coordinator daemon',
390
+ lastStateChangeAt: refreshedAt,
391
+ };
392
+ } else if (daemonId) {
393
+ const connection = ctx.deps.getMeshPeerConnectionStatus?.(daemonId);
394
+ status.connection = connection ?? {
395
+ perspective: 'selected_coordinator',
396
+ source: 'not_reported',
397
+ state: 'unknown',
398
+ transport: 'unknown',
399
+ reported: false,
400
+ reason: 'No live mesh peer telemetry reported by the selected coordinator yet.',
401
+ };
402
+ } else {
403
+ status.connection = {
404
+ perspective: 'selected_coordinator',
405
+ source: 'not_reported',
406
+ state: 'unknown',
407
+ transport: 'unknown',
408
+ reported: false,
409
+ reason: 'Node has no daemon id, so mesh transport cannot be reported from the selected coordinator.',
410
+ };
411
+ }
412
+ const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
413
+ meshId,
414
+ node,
415
+ nodeId,
416
+ liveSessionRecords: liveMeshSessions,
417
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId,
418
+ });
419
+ const workspace = readLiveMeshNodeWorkspace({
420
+ meshId,
421
+ nodeId,
422
+ liveSessionRecords: matchedLiveSessionRecords,
423
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId,
424
+ }) || (typeof node.workspace === 'string' ? node.workspace : '');
425
+ status.workspace = workspace || node.workspace;
426
+ if (matchedLiveSessionRecords.length > 0) {
427
+ const sessionIds = matchedLiveSessionRecords
428
+ .map((record: any) => typeof record?.sessionId === 'string' ? record.sessionId : '')
429
+ .filter(Boolean);
430
+ const providerTypes = matchedLiveSessionRecords
431
+ .map((record: any) => readStringValue(record?.providerType))
432
+ .filter(Boolean) as string[];
433
+ status.activeSessions = sessionIds;
434
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
435
+ if (providerTypes.length > 0) {
436
+ status.providers = Array.from(new Set([...(Array.isArray(status.providers) ? status.providers as string[] : []), ...providerTypes]));
437
+ }
438
+ }
439
+ if (workspace) {
440
+ if (!fs.existsSync(workspace)) {
441
+ // Workspace not local — prefer direct live inline truth, then attempt a P2P git probe.
442
+ const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
443
+ let remoteProbeApplied = false;
444
+ if (inlineTransitGit) {
445
+ status.git = inlineTransitGit;
446
+ status.health = inlineTransitGit.isGitRepo
447
+ ? deriveMeshNodeHealthFromGit(inlineTransitGit as unknown as Record<string, unknown>)
448
+ : 'degraded';
449
+ const connection = readObjectRecord(status.connection);
450
+ const connectionState = readStringValue(connection.state);
451
+ const connectionReported = readBooleanValue(connection.reported) ?? false;
452
+ if (!connectionReported || connectionState === 'unknown') {
453
+ status.connection = buildLivePeerGitConnection(connection, refreshedAt);
454
+ }
455
+ remoteProbeApplied = true;
456
+ } else if (refreshRequested && !isSelfNode && daemonId && ctx.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
457
+ // Only an explicit refresh fans out a blocking
458
+ // per-node git probe. On the default load a peer
459
+ // with no held truth falls through to
460
+ // gitProbePending below — the graph still renders.
461
+ // Bounded retry (shared with the bootstrap hydrate
462
+ // path), gated on the peer staying connected, so a
463
+ // slow TURN-relayed peer is recovered rather than
464
+ // dropped after a single timeout.
465
+ const runNodeProbe = () => probeRemoteMeshGitStatusWithRetry({
466
+ dispatchMeshCommand: ctx.deps.dispatchMeshCommand,
467
+ daemonId,
468
+ workspace,
469
+ timeoutMs: MESH_DIRECT_PROBE_TIMEOUT_MS,
470
+ retryTimeoutMs: MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS,
471
+ getConnection: ctx.deps.getMeshPeerConnectionStatus,
472
+ onConnection: connection => { status.connection = connection; },
473
+ });
474
+ // Same shared cache as the bootstrap hydrate path: within one
475
+ // mesh_status call this dedups the bootstrap probe against this
476
+ // per-node probe for the same peer, and across calls it reuses a
477
+ // recent result so the dashboard auto-retry loop can't restart a
478
+ // fresh refreshUpstream probe seconds apart.
479
+ const remoteGit = await meshGitProbeCache.probe(daemonId, workspace, runNodeProbe);
480
+ if (remoteGit) {
481
+ status.git = remoteGit;
482
+ status[MESH_NODE_LIVE_TRUTH_MARKER] = true;
483
+ status.health = remoteGit.isGitRepo
484
+ ? deriveMeshNodeHealthFromGit(remoteGit as unknown as Record<string, unknown>)
485
+ : 'degraded';
486
+ const connection = readObjectRecord(status.connection);
487
+ const connectionState = readStringValue(connection.state);
488
+ const connectionReported = readBooleanValue(connection.reported) ?? false;
489
+ if (!connectionReported || connectionState === 'unknown') {
490
+ status.connection = buildLivePeerGitConnection(connection, refreshedAt);
491
+ }
492
+ const reporter = recordInlineMeshDirectGitTruth(node, remoteGit, 'selected_coordinator_mesh_p2p_git');
493
+ persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
494
+ remoteProbeApplied = true;
495
+ }
496
+ }
497
+ if (!remoteProbeApplied) {
498
+ const connectionState = readStringValue((status.connection as any)?.state);
499
+ const pendingPeerGitProbe = !inlineTransitGit
500
+ && !isSelfNode
501
+ && !!daemonId
502
+ && (
503
+ readStringValue(status.machineStatus) === 'online'
504
+ || readStringValue(status.health) === 'online'
505
+ || connectionState === 'connecting'
506
+ || connectionState === 'connected'
507
+ || connectionState === 'unknown'
508
+ );
509
+ if (pendingPeerGitProbe) {
510
+ status.gitProbePending = true;
511
+ status.health = 'unknown';
512
+ }
513
+ if (applyCachedInlineMeshNodeStatus(
514
+ status,
515
+ node,
516
+ pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : undefined,
517
+ )) {
518
+ applyInlineMeshBranchConvergence(mesh, node, status);
519
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
520
+ return status;
521
+ }
522
+ if (meshRecord?.source === 'inline_cache' && !isSelfNode) {
523
+ applyInlineMeshBranchConvergence(mesh, node, status);
524
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
525
+ return status;
526
+ }
527
+ }
528
+ } else {
529
+ try {
530
+ // Route through the shared per-request cache so this
531
+ // local probe reuses the bootstrap hydrate's probe for
532
+ // the same workspace (and vice versa) instead of
533
+ // re-shelling ~14 git processes across the 1.5s TTL.
534
+ const runLocalProbe = () => getGitRepoStatus(workspace, { timeoutMs: 10_000, refreshUpstream: true }) as unknown as Promise<Record<string, unknown> | null>;
535
+ const gitStatus = (await meshGitProbeCache.probeLocal(workspace, runLocalProbe)) as any;
536
+ if (!gitStatus) throw new Error('local_git_probe_unavailable');
537
+ status.git = gitStatus;
538
+ status[MESH_NODE_LIVE_TRUTH_MARKER] = true;
539
+ const reporter = recordInlineMeshDirectGitTruth(node, gitStatus as unknown as Record<string, unknown>, 'selected_coordinator_local_git');
540
+ persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
541
+ if (gitStatus.isGitRepo) {
542
+ status.health = deriveMeshNodeHealthFromGit(gitStatus as unknown as Record<string, unknown>);
543
+ } else {
544
+ status.health = 'degraded';
545
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
546
+ }
547
+ } catch {
548
+ if (!applyCachedInlineMeshNodeStatus(status, node)) {
549
+ status.health = 'degraded';
550
+ }
551
+ }
552
+ }
553
+ } else {
554
+ applyCachedInlineMeshNodeStatus(status, node);
555
+ }
556
+ applyInlineMeshBranchConvergence(mesh, node, status);
557
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
558
+ return status;
559
+ };
560
+ const meshNodeEntries = [...(mesh.nodes || []).entries()];
561
+ const settledNodeStatuses = await Promise.allSettled(
562
+ meshNodeEntries.map(([nodeIndex, node]) => renderMeshNode(nodeIndex, node)),
563
+ );
564
+ const nodeStatuses = settledNodeStatuses.map((settled, i) => {
565
+ if (settled.status === 'fulfilled') return settled.value;
566
+ // A per-node render should never reject (every git path is
567
+ // caught internally), but if one does, degrade to a minimal
568
+ // last-known/unknown entry for THAT node so a single failure
569
+ // can't drop the whole aggregate. Best-effort recovery of the
570
+ // node's cached inline truth, else an unknown-health stub.
571
+ const [nodeIndex, node] = meshNodeEntries[i];
572
+ const nodeId = normalizeMeshNodeId(node) ?? '';
573
+ const daemonId = readStringValue(node.daemonId);
574
+ const fallback: Record<string, unknown> = {
575
+ nodeId,
576
+ machineLabel: buildMeshNodeDisplayLabel(node as Record<string, unknown>, nodeId, readProviderPriorityFromPolicy(node.policy)),
577
+ workspace: node.workspace,
578
+ repoRoot: node.repoRoot,
579
+ isLocalWorktree: node.isLocalWorktree,
580
+ worktreeBranch: node.worktreeBranch,
581
+ daemonId,
582
+ machineId: readMeshNodeMachineId(node as Record<string, unknown>) || node.machineId,
583
+ health: 'unknown',
584
+ providers: node.providers || [],
585
+ activeSessions: [],
586
+ activeSessionDetails: [],
587
+ launchReady: false,
588
+ error: settled.reason instanceof Error ? settled.reason.message : 'node render failed',
589
+ };
590
+ applyCachedInlineMeshNodeStatus(fallback, node);
591
+ applyInlineMeshBranchConvergence(mesh, node, fallback);
592
+ finalizeMeshNodeStatus({ status: fallback, node, daemonId, isSelfNode: false, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
593
+ return fallback;
594
+ });
595
+
596
+ // (B3) Resolve the coordinator daemon scope for the peek.
597
+ // mesh_status is a read-only status query — it must not consume
598
+ // (drain) pending events as a side effect. Coordinators that see
599
+ // pendingCoordinatorEvents in the response are expected to call
600
+ // get_pending_mesh_events to explicitly drain them after processing.
601
+ const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === 'string' && args.coordinatorDaemonId.trim()
602
+ ? args.coordinatorDaemonId.trim()
603
+ : (ctx.deps.statusInstanceId || undefined);
604
+ const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
605
+ // R4: surface recent fail-loud routing drops so a coordinator/operator can see
606
+ // that a worker completion was lost (envelope present, mesh unresolved) instead
607
+ // of it vanishing silently. Diagnostic-only — never cached (see omit below).
608
+ const unroutableDeliveries = getRecentUnroutableDeliveries();
609
+ // T6 (B3c): live enforce/observability counters from this daemon. A
610
+ // process-lifetime snapshot (never cached — like unroutableDeliveries)
611
+ // so an operator/coordinator can read enforce state, quarantine tallies,
612
+ // and last-resort backstop fires straight from the aggregate status.
613
+ const meshProtocolV2Counters: MeshProtocolV2Counters = {
614
+ enforce: isMeshProtocolV2EnforceEnabled(),
615
+ drain: { ...getMeshV2DrainCounters() },
616
+ backstop: { ...getMeshV2BackstopCounters() },
617
+ };
618
+ const previewFreshness = (() => {
619
+ const localRepoRoot = nodeStatuses
620
+ .map((node: any) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace))
621
+ .find((candidate: string | undefined) => !!candidate && fs.existsSync(candidate));
622
+ return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : undefined;
623
+ })();
624
+ const asyncRefineJobs = buildMeshAsyncRefineJobs({
625
+ meshId,
626
+ ledgerEntries: asyncRefineLedgerEntries,
627
+ pendingEvents: [...pendingCoordinatorEvents],
628
+ });
629
+ const historicalSessions = buildHistoricalMeshSessions({
630
+ meshId,
631
+ nodes: mesh.nodes || [],
632
+ liveSessionRecords: liveMeshSessions,
633
+ });
634
+ const { getMeshStatusMissionSummaries } = await import('../../mesh/mesh-missions.js');
635
+ // withStats opts in to per-mission operational rollups (durations /
636
+ // retries) for the dashboard mission detail. The rollup scans a
637
+ // bounded ledger tail per mission, but only over the bounded set
638
+ // returned here (live + capped history), so the cost stays linear
639
+ // in visible missions rather than the whole mesh history.
640
+ const missions = getMeshStatusMissionSummaries(meshId, { verbose: verboseMissions, withStats: true });
641
+
642
+ // FIX C-backend: fold persisted MAGI cross-verification activity into the
643
+ // dashboard mesh_status payload so the web MAGI surface (extractMagiActivity)
644
+ // can read synthesis output — needs_verification counts, the independence
645
+ // banner, git skew, and a bounded needs_verification preview — without
646
+ // re-running collection. Mirrors the MCP mesh_status tool
647
+ // (mesh-tools-status.ts buildMeshMagiActivity / summarizeMeshMagiActivity).
648
+ // Read magi_dispatched/magi_synthesis entries over a wider tail than the 20
649
+ // rendered above (MAGI events are sparse — a 20-entry tail routinely misses
650
+ // the dispatch/synthesis pair). Compact (the default) folds synthesized groups
651
+ // to a bounded recent set + a count summary; verbose carries the full list.
652
+ const { buildMeshMagiActivity, summarizeMeshMagiActivity } = await import('../../mesh/mesh-magi-status.js');
653
+ const magiLedgerEntries = readLedgerEntries(meshId, { kind: ['magi_dispatched', 'magi_synthesis'], tail: 200 });
654
+ const magiActivity = buildMeshMagiActivity({ meshId, ledgerEntries: magiLedgerEntries });
655
+ let magiActivityFold: ReturnType<typeof summarizeMeshMagiActivity> | undefined;
656
+ if (magiActivity.length > 0 && !verboseMissions) {
657
+ magiActivityFold = summarizeMeshMagiActivity(magiActivity);
658
+ }
659
+ const statusResult = {
660
+ success: true,
661
+ meshId: mesh.id,
662
+ meshName: mesh.name,
663
+ repoIdentity: mesh.repoIdentity,
664
+ defaultBranch: mesh.defaultBranch,
665
+ refreshedAt,
666
+ meshHost,
667
+ sourceOfTruth: {
668
+ membership: meshRecord?.source === 'inline_cache'
669
+ ? 'coordinator_inline_mesh_cache'
670
+ : meshRecord?.source === 'local_config'
671
+ ? 'local_mesh_config'
672
+ : 'inline_bootstrap_snapshot',
673
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
674
+ meshHost: {
675
+ owner: 'mesh_host_daemon',
676
+ localRole: meshHost.role,
677
+ hostDaemonId: meshHost.hostDaemonId,
678
+ hostNodeId: meshHost.hostNodeId,
679
+ hostAddress: meshHost.hostAddress,
680
+ },
681
+ ...(requireDirectPeerTruth ? {
682
+ currentStatus: directTruthSatisfied ? 'live_git_and_session_probes' : 'direct_peer_truth_unavailable',
683
+ directPeerTruth: {
684
+ required: true,
685
+ satisfied: directTruthSatisfied,
686
+ directEvidenceCount: effectiveDirectTruth.directEvidenceCount,
687
+ localConfirmedCount: effectiveDirectTruth.localConfirmedCount,
688
+ peerAttemptedCount: effectiveDirectTruth.peerAttemptedCount,
689
+ peerConfirmedCount: effectiveDirectTruth.peerConfirmedCount,
690
+ unavailableNodeIds: effectiveDirectTruth.unavailableNodeIds,
691
+ partialNodeFailures: effectiveDirectTruth.unavailableNodeIds,
692
+ },
693
+ } : {}),
694
+ historicalEvidenceOnly: ['recoveryHints', 'ledger.summary', 'queue.summary', 'historicalSessions'],
695
+ },
696
+ branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
697
+ ...(previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {}),
698
+ nodes: nodeStatuses,
699
+ // Mesh-level scheduling rollup (strategy + global cap consumption). Mirrors
700
+ // the MCP `mesh_status` tool's `scheduling` block field-for-field so both
701
+ // surfaces read the same runtime; per-node detail lives on each
702
+ // nodes[].scheduling above.
703
+ scheduling: {
704
+ strategy: schedulingRuntime.strategy,
705
+ maxParallelTasks: schedulingRuntime.maxParallelTasks,
706
+ maxReadonlyParallelTasks: schedulingRuntime.maxReadonlyParallelTasks,
707
+ activeWriteAssigned: schedulingRuntime.activeWriteAssigned,
708
+ activeReadonlyAssigned: schedulingRuntime.activeReadonlyAssigned,
709
+ globalWriteCapReached: schedulingRuntime.globalWriteCapReached,
710
+ globalReadonlyCapReached: schedulingRuntime.globalReadonlyCapReached,
711
+ },
712
+ queue: { tasks: queue, summary: queueSummary },
713
+ ledger: { entries: ledgerEntries, summary: ledgerSummary },
714
+ ...(missions.length > 0 ? { missions } : {}),
715
+ // Compact (default): bounded folded groups + a status-count summary.
716
+ // Verbose: the full reconstructed activity list. Mirrors the MCP tool.
717
+ ...(magiActivity.length > 0
718
+ ? (magiActivityFold
719
+ ? {
720
+ ...(magiActivityFold.groups.length > 0 ? { magiActivity: magiActivityFold.groups } : {}),
721
+ magiActivitySummary: {
722
+ total: magiActivityFold.total,
723
+ byStatus: magiActivityFold.byStatus,
724
+ ...(magiActivityFold.staleSynthesized > 0 ? { staleSynthesized: magiActivityFold.staleSynthesized } : {}),
725
+ },
726
+ }
727
+ : { magiActivity })
728
+ : {}),
729
+ ...(asyncRefineJobs.length > 0 ? { asyncRefineJobs } : {}),
730
+ ...(historicalSessions ? { historicalSessions } : {}),
731
+ ...(pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {}),
732
+ ...(unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {}),
733
+ meshProtocolV2Counters,
734
+ activeRefineJobs: Array.from(ctx.runningRefineJobs.values())
735
+ .filter(job => job.meshId === meshId)
736
+ .map(job => ({
737
+ jobId: job.jobId,
738
+ nodeId: job.targetNodeId,
739
+ workspace: job.workspace,
740
+ startedAt: job.startedAt,
741
+ status: job.status,
742
+ targetCoordinatorDaemonId: job.targetCoordinatorDaemonId,
743
+ })),
744
+ };
745
+ const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, meshProtocolV2Counters: _meshProtocolV2Counters, ...cacheableStatusResult } = statusResult as any;
746
+ // Verbose carries full mission goals; never store it in the shared
747
+ // (compact) aggregate cache or a later compact poll would return the
748
+ // heavy goals from cache. Return it without caching.
749
+ const rememberedStatus = verboseMissions
750
+ ? cacheableStatusResult
751
+ : ctx.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
752
+ const returnedStatus = {
753
+ ...rememberedStatus,
754
+ ...(pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {}),
755
+ ...(unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {}),
756
+ meshProtocolV2Counters,
757
+ };
758
+ logRepoMeshStatusDebug('return_live', {
759
+ meshId,
760
+ command: 'mesh_status',
761
+ refreshRequested,
762
+ refreshReason,
763
+ meshSource: meshRecord.source,
764
+ directTruth,
765
+ durationMs: Date.now() - startedAtMs,
766
+ summary: summarizeRepoMeshStatusDebug(returnedStatus),
767
+ });
768
+ return returnedStatus;
769
+ } catch (e: any) {
770
+ return { success: false, error: e.message };
771
+ }
772
+ },
773
+
774
+ get_mesh_review_inbox: async (ctx: HighFamilyContext, args: any) => {
775
+ const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
776
+ if (!meshId) return { success: false, error: 'meshId required' };
777
+ try {
778
+ const { deriveMeshReviewInboxItems } = await import('../../mesh/mesh-review-inbox.js');
779
+ const { readLedgerEntries } = await import('../../mesh/mesh-ledger.js');
780
+ const { getGitDiffSummary } = await import('../../git/git-diff.js');
781
+ const { existsSync } = await import('node:fs');
782
+
783
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
784
+ const mesh = meshRecord?.mesh;
785
+ if (!mesh) return { success: false, error: 'Mesh not found' };
786
+
787
+ // Ensure we have a fresh aggregate status so nodeStatuses carry
788
+ // computed fields (connection.state, branchConvergence, isLocalWorktree)
789
+ // that the raw mesh.nodes config objects don't have.
790
+ // When the caller provides an inlineMesh, prefer its nodes directly
791
+ // (they already carry the computed fields from the coordinator).
792
+ const inlineNodes = args?.inlineMesh && Array.isArray((args.inlineMesh as any)?.nodes)
793
+ ? (args.inlineMesh as any).nodes as Record<string, unknown>[]
794
+ : null;
795
+ let cachedStatus = !inlineNodes ? ctx.getCachedAggregateMeshStatus(meshId, mesh, {}) : null;
796
+ if (!cachedStatus && !inlineNodes) {
797
+ const freshStatus = await ctx.execute('mesh_status', {
798
+ meshId,
799
+ inlineMesh: args?.inlineMesh,
800
+ refresh: true,
801
+ }, 'get_mesh_review_inbox');
802
+ cachedStatus = (freshStatus?.success !== false) ? freshStatus : null;
803
+ }
804
+ const nodeStatuses: Record<string, unknown>[] = inlineNodes
805
+ ? inlineNodes
806
+ : Array.isArray(cachedStatus?.nodes)
807
+ ? cachedStatus.nodes as Record<string, unknown>[]
808
+ : Array.isArray(mesh.nodes)
809
+ ? mesh.nodes as Record<string, unknown>[]
810
+ : [];
811
+
812
+ const ledgerEntries = readLedgerEntries(meshId, { tail: 300 });
813
+ const derivation = deriveMeshReviewInboxItems({ nodes: nodeStatuses, ledgerEntries });
814
+
815
+ for (const item of derivation.items) {
816
+ const workspace = item.workspace;
817
+ if (!workspace || !existsSync(workspace)) continue;
818
+ const baseRef = item.defaultBranch
819
+ ? `origin/${item.defaultBranch}`
820
+ : 'origin/main';
821
+ try {
822
+ const diffResult = await getGitDiffSummary(workspace, { baseRef, maxFiles: 100 });
823
+ if (diffResult.isGitRepo) {
824
+ item.diffSummary = {
825
+ baseRef,
826
+ files: diffResult.files.map(f => ({
827
+ path: f.path,
828
+ status: f.status,
829
+ insertions: f.insertions,
830
+ deletions: f.deletions,
831
+ binary: f.binary,
832
+ oldPath: f.oldPath,
833
+ })),
834
+ totalFiles: diffResult.files.length,
835
+ totalInsertions: diffResult.totalInsertions,
836
+ totalDeletions: diffResult.totalDeletions,
837
+ truncated: diffResult.truncated,
838
+ ...(diffResult.error ? { error: diffResult.error } : {}),
839
+ };
840
+ }
841
+ } catch {
842
+ item.diffSummary = null;
843
+ }
844
+ }
845
+
846
+ return {
847
+ success: true,
848
+ meshId,
849
+ inbox: derivation.items,
850
+ remoteNodesExcluded: derivation.remoteNodesExcluded,
851
+ excludedRemoteNodeIds: derivation.excludedRemoteNodeIds,
852
+ };
853
+ } catch (e: any) {
854
+ return { success: false, error: e.message };
855
+ }
856
+ },
857
+ };