@adhdev/daemon-core 0.9.82-rc.43 → 0.9.82-rc.430

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 (425) 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 +200 -0
  10. package/dist/cli-adapters/provider-cli-adapter.d.ts +126 -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 +7 -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 +15 -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 +60 -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 +29 -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 +142 -0
  54. package/dist/commands/mesh-coordinator.d.ts +85 -1
  55. package/dist/commands/router.d.ts +276 -2
  56. package/dist/commands/upgrade-helper.d.ts +41 -1
  57. package/dist/config/chat-history.d.ts +9 -0
  58. package/dist/config/config.d.ts +5 -0
  59. package/dist/config/mesh-config.d.ts +100 -1
  60. package/dist/config/mesh-json-config.d.ts +199 -0
  61. package/dist/config/repo-settings.d.ts +77 -0
  62. package/dist/daemon/dev-server.d.ts +0 -2
  63. package/dist/detection/ide-detector.d.ts +13 -0
  64. package/dist/detection/win32-ide-version.d.ts +37 -0
  65. package/dist/git/change-impact-config.d.ts +159 -0
  66. package/dist/git/git-commands.d.ts +11 -1
  67. package/dist/git/git-diff.d.ts +6 -0
  68. package/dist/git/git-executor.d.ts +11 -0
  69. package/dist/git/git-status.d.ts +57 -0
  70. package/dist/git/git-types.d.ts +2 -50
  71. package/dist/git/git-worktree.d.ts +71 -1
  72. package/dist/git/index.d.ts +3 -1
  73. package/dist/index.d.ts +64 -14
  74. package/dist/index.js +49391 -19228
  75. package/dist/index.js.map +1 -1
  76. package/dist/index.mjs +48574 -18570
  77. package/dist/index.mjs.map +1 -1
  78. package/dist/installer.d.ts +1 -4
  79. package/dist/ipc/local-ipc-server.d.ts +91 -0
  80. package/dist/launch.d.ts +1 -1
  81. package/dist/logging/async-batch-writer.d.ts +10 -0
  82. package/dist/logging/log-redactor.d.ts +24 -0
  83. package/dist/logging/log-tail-reader.d.ts +81 -0
  84. package/dist/logging/logger.d.ts +1 -1
  85. package/dist/mesh/contracts.d.ts +164 -0
  86. package/dist/mesh/coordinator-prompt.d.ts +89 -0
  87. package/dist/mesh/coordinator-registry.d.ts +59 -0
  88. package/dist/mesh/mesh-active-work.d.ts +174 -0
  89. package/dist/mesh/mesh-clone-grace.d.ts +8 -0
  90. package/dist/mesh/mesh-coordinator-config.d.ts +21 -0
  91. package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
  92. package/dist/mesh/mesh-event-classify.d.ts +5 -0
  93. package/dist/mesh/mesh-event-forwarding.d.ts +41 -0
  94. package/dist/mesh/mesh-event-trace.d.ts +21 -0
  95. package/dist/mesh/mesh-events-coordinator.d.ts +4 -0
  96. package/dist/mesh/mesh-events-pending.d.ts +69 -0
  97. package/dist/mesh/mesh-events-stale.d.ts +61 -0
  98. package/dist/mesh/mesh-events-utils.d.ts +75 -0
  99. package/dist/mesh/mesh-events.d.ts +6 -49
  100. package/dist/mesh/mesh-fast-forward.d.ts +81 -0
  101. package/dist/mesh/mesh-host-ownership.d.ts +9 -0
  102. package/dist/mesh/mesh-init.d.ts +86 -0
  103. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -4
  104. package/dist/mesh/mesh-ledger.d.ts +77 -1
  105. package/dist/mesh/mesh-magi-status.d.ts +63 -0
  106. package/dist/mesh/mesh-missions.d.ts +189 -0
  107. package/dist/mesh/mesh-node-identity.d.ts +289 -0
  108. package/dist/mesh/mesh-queue-assignment.d.ts +113 -0
  109. package/dist/mesh/mesh-reconcile-loop.d.ts +65 -0
  110. package/dist/mesh/mesh-refine-batch.d.ts +68 -0
  111. package/dist/mesh/mesh-refine-gates.d.ts +428 -0
  112. package/dist/mesh/mesh-refine-status.d.ts +62 -0
  113. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  114. package/dist/mesh/mesh-routing.d.ts +70 -0
  115. package/dist/mesh/mesh-runtime-store.d.ts +450 -0
  116. package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
  117. package/dist/mesh/mesh-task-inflight.d.ts +46 -0
  118. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  119. package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +30 -0
  120. package/dist/mesh/mesh-warmup-deadline.d.ts +68 -0
  121. package/dist/mesh/mesh-work-queue.d.ts +290 -5
  122. package/dist/mesh/preview-freshness.d.ts +18 -0
  123. package/dist/mesh/refine-config.d.ts +216 -0
  124. package/dist/mesh/worktree-bootstrap-config.d.ts +145 -0
  125. package/dist/providers/acp-provider-instance.d.ts +5 -0
  126. package/dist/providers/approval-utils.d.ts +20 -0
  127. package/dist/providers/chat-message-normalization.d.ts +31 -1
  128. package/dist/providers/cli-provider-instance.d.ts +221 -3
  129. package/dist/providers/contracts.d.ts +139 -6
  130. package/dist/providers/external-sources.d.ts +71 -0
  131. package/dist/providers/manual-attendance.d.ts +63 -0
  132. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  133. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  134. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  135. package/dist/providers/native-history/constants.d.ts +12 -0
  136. package/dist/providers/native-history/dispatcher.d.ts +27 -0
  137. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  138. package/dist/providers/native-history/index.d.ts +13 -0
  139. package/dist/providers/provider-instance-manager.d.ts +29 -0
  140. package/dist/providers/provider-instance.d.ts +23 -1
  141. package/dist/providers/provider-loader.d.ts +26 -4
  142. package/dist/providers/provider-trust.d.ts +31 -0
  143. package/dist/providers/read-chat-contract.d.ts +29 -0
  144. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  145. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +86 -0
  146. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  147. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  148. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  149. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  150. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  151. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  152. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  153. package/dist/providers/sdk/v1/index.d.ts +30 -0
  154. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  155. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  156. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  157. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  158. package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
  159. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  160. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  161. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  162. package/dist/providers/spec/adapter.d.ts +91 -0
  163. package/dist/providers/spec/cli-adapter.d.ts +223 -0
  164. package/dist/providers/spec/evaluator.d.ts +45 -0
  165. package/dist/providers/spec/fsm-driver.d.ts +422 -0
  166. package/dist/providers/spec/fsm-evaluator.d.ts +76 -0
  167. package/dist/providers/spec/fsm-loader.d.ts +14 -0
  168. package/dist/providers/spec/fsm-types.d.ts +174 -0
  169. package/dist/providers/spec/native-history-executor.d.ts +41 -0
  170. package/dist/providers/spec/pre-launch-trust.d.ts +16 -0
  171. package/dist/providers/spec/route.d.ts +4 -0
  172. package/dist/providers/spec/types.d.ts +222 -0
  173. package/dist/providers/status-monitor.d.ts +7 -7
  174. package/dist/providers/transcript-v2.d.ts +176 -0
  175. package/dist/providers/types/interactive-prompt.d.ts +84 -0
  176. package/dist/providers/working-dir.d.ts +17 -0
  177. package/dist/repo-mesh-types.d.ts +501 -13
  178. package/dist/runtime-defaults.d.ts +2 -0
  179. package/dist/sessions/registry.d.ts +6 -0
  180. package/dist/shared-types-extra.d.ts +2 -4
  181. package/dist/shared-types.d.ts +59 -2
  182. package/dist/status/normalize.d.ts +1 -1
  183. package/dist/status/normalize.js +1 -0
  184. package/dist/status/normalize.js.map +1 -1
  185. package/dist/status/normalize.mjs +1 -0
  186. package/dist/status/normalize.mjs.map +1 -1
  187. package/dist/status/reporter.d.ts +2 -0
  188. package/dist/status/snapshot.d.ts +26 -0
  189. package/dist/system/hash.d.ts +8 -0
  190. package/dist/system/load-better-sqlite3.d.ts +21 -0
  191. package/dist/types.d.ts +5 -0
  192. package/package.json +7 -3
  193. package/src/agent-stream/poller.ts +2 -3
  194. package/src/agent-stream/provider-adapter.ts +1 -1
  195. package/src/boot/daemon-lifecycle.ts +63 -12
  196. package/src/boot/process-hardening.ts +89 -0
  197. package/src/build-info.ts +73 -0
  198. package/src/chat/source-machine.ts +534 -0
  199. package/src/chat/source-resolver.ts +0 -0
  200. package/src/chat/subscription-updates.ts +20 -1
  201. package/src/cli-adapter-types.d.ts +3 -1
  202. package/src/cli-adapter-types.ts +68 -2
  203. package/src/cli-adapters/cli-script-runner.ts +421 -0
  204. package/src/cli-adapters/cli-state-engine.ts +1246 -0
  205. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  206. package/src/cli-adapters/provider-cli-adapter.ts +914 -1144
  207. package/src/cli-adapters/provider-cli-parse.d.ts +2 -0
  208. package/src/cli-adapters/provider-cli-parse.ts +19 -0
  209. package/src/cli-adapters/provider-cli-runtime.ts +56 -7
  210. package/src/cli-adapters/provider-cli-shared.d.ts +4 -0
  211. package/src/cli-adapters/provider-cli-shared.ts +121 -11
  212. package/src/cli-adapters/pty-transport.ts +2 -1
  213. package/src/cli-adapters/pty-write-chunking.ts +106 -0
  214. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  215. package/src/cli-adapters/resolve-executable.ts +204 -0
  216. package/src/cli-adapters/session-host-transport.ts +2 -1
  217. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +63 -29
  218. package/src/cli-adapters/terminal-backends/types.ts +10 -3
  219. package/src/cli-adapters/terminal-screen.ts +16 -81
  220. package/src/commands/WINDOWS-UPGRADE-LOCK-FAILURE.md +198 -0
  221. package/src/commands/chat-commands-debug-bundle.ts +398 -0
  222. package/src/commands/chat-commands-read.ts +2327 -0
  223. package/src/commands/chat-commands-scope.ts +54 -0
  224. package/src/commands/chat-commands-shared.ts +114 -0
  225. package/src/commands/chat-commands-write.ts +891 -0
  226. package/src/commands/chat-commands.ts +19 -1841
  227. package/src/commands/cli-manager.ts +544 -26
  228. package/src/commands/handler.ts +841 -2
  229. package/src/commands/high-family/index.ts +28 -0
  230. package/src/commands/high-family/mesh-coordinator-launch.ts +678 -0
  231. package/src/commands/high-family/mesh-events.ts +80 -0
  232. package/src/commands/high-family/mesh-status.ts +710 -0
  233. package/src/commands/high-family/types.ts +76 -0
  234. package/src/commands/low-family/coordinator-prompt.ts +72 -0
  235. package/src/commands/low-family/daemon-lifecycle.ts +107 -0
  236. package/src/commands/low-family/diagnostics.ts +57 -0
  237. package/src/commands/low-family/index.ts +37 -0
  238. package/src/commands/low-family/mesh-ledger.ts +62 -0
  239. package/src/commands/low-family/mesh-node-logs.ts +87 -0
  240. package/src/commands/low-family/notification.ts +116 -0
  241. package/src/commands/low-family/refine-config.ts +106 -0
  242. package/src/commands/low-family/session-host.ts +274 -0
  243. package/src/commands/low-family/spec-providerdev.ts +217 -0
  244. package/src/commands/low-family/status-meta.ts +112 -0
  245. package/src/commands/low-family/types.ts +39 -0
  246. package/src/commands/med-family/cli-agent.ts +238 -0
  247. package/src/commands/med-family/fast-forward.ts +230 -0
  248. package/src/commands/med-family/ide.ts +163 -0
  249. package/src/commands/med-family/index.ts +37 -0
  250. package/src/commands/med-family/mesh-crud.ts +1066 -0
  251. package/src/commands/med-family/mesh-host-pairing.ts +234 -0
  252. package/src/commands/med-family/mesh-queue.ts +167 -0
  253. package/src/commands/med-family/mesh-restart.ts +92 -0
  254. package/src/commands/med-family/types.ts +143 -0
  255. package/src/commands/mesh-coordinator.ts +334 -124
  256. package/src/commands/router.ts +2711 -3254
  257. package/src/commands/stream-commands.ts +8 -0
  258. package/src/commands/upgrade-helper.ts +310 -45
  259. package/src/config/chat-history.ts +483 -24
  260. package/src/config/config.ts +12 -0
  261. package/src/config/mesh-config.ts +495 -22
  262. package/src/config/mesh-json-config.ts +376 -0
  263. package/src/config/recent-activity.ts +8 -2
  264. package/src/config/repo-settings.ts +111 -0
  265. package/src/daemon/dev-auto-implement.ts +3 -2
  266. package/src/daemon/dev-cli-debug.ts +10 -1
  267. package/src/daemon/dev-server.ts +0 -541
  268. package/src/detection/cli-detector.ts +28 -9
  269. package/src/detection/ide-detector.ts +55 -16
  270. package/src/detection/win32-ide-version.ts +106 -0
  271. package/src/git/change-impact-config.ts +354 -0
  272. package/src/git/git-commands.ts +59 -15
  273. package/src/git/git-diff.ts +81 -11
  274. package/src/git/git-executor.ts +12 -0
  275. package/src/git/git-status.ts +767 -48
  276. package/src/git/git-types.ts +14 -62
  277. package/src/git/git-worktree.ts +261 -4
  278. package/src/git/index.ts +17 -0
  279. package/src/index.ts +194 -12
  280. package/src/installer.d.ts +1 -1
  281. package/src/installer.ts +8 -6
  282. package/src/ipc/local-ipc-server.ts +278 -0
  283. package/src/launch.d.ts +1 -1
  284. package/src/launch.ts +37 -28
  285. package/src/logging/async-batch-writer.ts +55 -0
  286. package/src/logging/command-log.ts +7 -5
  287. package/src/logging/log-redactor.ts +100 -0
  288. package/src/logging/log-tail-reader.ts +341 -0
  289. package/src/logging/logger.ts +14 -7
  290. package/src/mesh/contracts.ts +338 -0
  291. package/src/mesh/coordinator-prompt.ts +381 -33
  292. package/src/mesh/coordinator-registry.ts +121 -0
  293. package/src/mesh/mesh-active-work.ts +645 -0
  294. package/src/mesh/mesh-clone-grace.ts +68 -0
  295. package/src/mesh/mesh-coordinator-config.ts +97 -0
  296. package/src/mesh/mesh-delivery-policy.ts +315 -0
  297. package/src/mesh/mesh-event-classify.ts +51 -0
  298. package/src/mesh/mesh-event-forwarding.ts +1888 -0
  299. package/src/mesh/mesh-event-trace.ts +67 -0
  300. package/src/mesh/mesh-events-coordinator.ts +32 -0
  301. package/src/mesh/mesh-events-pending.ts +656 -0
  302. package/src/mesh/mesh-events-stale.ts +389 -0
  303. package/src/mesh/mesh-events-utils.ts +443 -0
  304. package/src/mesh/mesh-events.ts +33 -1035
  305. package/src/mesh/mesh-fast-forward.ts +843 -0
  306. package/src/mesh/mesh-host-ownership.ts +73 -0
  307. package/src/mesh/mesh-init.ts +260 -0
  308. package/src/mesh/mesh-ledger-reconciliation.ts +12 -7
  309. package/src/mesh/mesh-ledger.ts +656 -102
  310. package/src/mesh/mesh-magi-status.ts +223 -0
  311. package/src/mesh/mesh-missions.ts +449 -0
  312. package/src/mesh/mesh-node-identity.ts +1887 -0
  313. package/src/mesh/mesh-queue-assignment.ts +1918 -0
  314. package/src/mesh/mesh-reconcile-loop.ts +1780 -0
  315. package/src/mesh/mesh-refine-batch.ts +205 -0
  316. package/src/mesh/mesh-refine-gates.ts +1673 -0
  317. package/src/mesh/mesh-refine-status.ts +231 -0
  318. package/src/mesh/mesh-review-inbox.ts +307 -0
  319. package/src/mesh/mesh-routing.ts +291 -0
  320. package/src/mesh/mesh-runtime-store.ts +1853 -0
  321. package/src/mesh/mesh-scheduling-runtime.ts +198 -0
  322. package/src/mesh/mesh-task-inflight.ts +70 -0
  323. package/src/mesh/mesh-task-stats.ts +161 -0
  324. package/src/mesh/mesh-unresolved-forward-outbox.ts +185 -0
  325. package/src/mesh/mesh-warmup-deadline.ts +152 -0
  326. package/src/mesh/mesh-work-queue.ts +1243 -141
  327. package/src/mesh/preview-freshness.ts +118 -0
  328. package/src/mesh/refine-config.ts +423 -0
  329. package/src/mesh/worktree-bootstrap-config.ts +450 -0
  330. package/src/providers/acp-provider-instance.ts +43 -10
  331. package/src/providers/approval-utils.d.ts +5 -0
  332. package/src/providers/approval-utils.ts +57 -5
  333. package/src/providers/chat-message-normalization.ts +92 -4
  334. package/src/providers/cli-provider-instance.ts +1933 -104
  335. package/src/providers/contracts.d.ts +55 -0
  336. package/src/providers/contracts.ts +150 -6
  337. package/src/providers/extension-provider-instance.ts +12 -7
  338. package/src/providers/external-sources.ts +218 -0
  339. package/src/providers/ide-provider-instance.ts +35 -12
  340. package/src/providers/manual-attendance.ts +85 -0
  341. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  342. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  343. package/src/providers/native-history/codex-cli-transcript.ts +479 -0
  344. package/src/providers/native-history/constants.ts +19 -0
  345. package/src/providers/native-history/dispatcher.ts +339 -0
  346. package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
  347. package/src/providers/native-history/index.ts +30 -0
  348. package/src/providers/provider-instance-manager.ts +71 -0
  349. package/src/providers/provider-instance.ts +19 -1
  350. package/src/providers/provider-loader.ts +668 -50
  351. package/src/providers/provider-schema.ts +87 -14
  352. package/src/providers/provider-trust.ts +114 -0
  353. package/src/providers/read-chat-contract.ts +76 -16
  354. package/src/providers/sdk/README.md +49 -0
  355. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  356. package/src/providers/sdk/v1/builders/cli/detect-status.ts +313 -0
  357. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  358. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
  359. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  360. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  361. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  362. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  363. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  364. package/src/providers/sdk/v1/index.ts +152 -0
  365. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  366. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  367. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  368. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
  369. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  370. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  371. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  372. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  373. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  374. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  375. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  376. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  377. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  378. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  379. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  380. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  381. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  382. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  383. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  384. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  385. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  386. package/src/providers/sdk/v1/types/common/index.ts +229 -0
  387. package/src/providers/sdk/v1/validators/index.ts +19 -0
  388. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  389. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  390. package/src/providers/spec/adapter.ts +235 -0
  391. package/src/providers/spec/cli-adapter.ts +1056 -0
  392. package/src/providers/spec/evaluator.ts +407 -0
  393. package/src/providers/spec/fsm-driver.ts +1410 -0
  394. package/src/providers/spec/fsm-evaluator.ts +272 -0
  395. package/src/providers/spec/fsm-loader.ts +120 -0
  396. package/src/providers/spec/fsm-types.ts +273 -0
  397. package/src/providers/spec/native-history-executor.ts +1128 -0
  398. package/src/providers/spec/pre-launch-trust.ts +104 -0
  399. package/src/providers/spec/route.ts +51 -0
  400. package/src/providers/spec/types.ts +262 -0
  401. package/src/providers/status-monitor.d.ts +7 -7
  402. package/src/providers/status-monitor.ts +37 -22
  403. package/src/providers/transcript-v2.ts +567 -0
  404. package/src/providers/types/interactive-prompt.ts +536 -0
  405. package/src/providers/version-archive.ts +64 -24
  406. package/src/providers/working-dir.ts +23 -0
  407. package/src/repo-mesh-types.ts +740 -14
  408. package/src/runtime-defaults.ts +39 -0
  409. package/src/sessions/registry.ts +6 -0
  410. package/src/shared-types-extra.ts +2 -4
  411. package/src/shared-types.d.ts +8 -0
  412. package/src/shared-types.ts +64 -1
  413. package/src/status/builders.ts +26 -6
  414. package/src/status/normalize.ts +2 -0
  415. package/src/status/reporter.ts +19 -1
  416. package/src/status/snapshot.ts +95 -26
  417. package/src/system/hash.ts +23 -0
  418. package/src/system/host-memory.ts +29 -12
  419. package/src/system/load-better-sqlite3.ts +68 -0
  420. package/src/types.ts +5 -0
  421. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
  422. package/dist/mesh/mesh-sync.d.ts +0 -53
  423. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
  424. package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
  425. package/src/mesh/mesh-sync.ts +0 -111
@@ -0,0 +1,223 @@
1
+ // MAGI (Multi-Agent Ground-truth Insight) activity reconstruction for mesh_status.
2
+ //
3
+ // MAGI cross-verification runs are persisted in the mesh ledger as `magi_dispatched`
4
+ // (fan-out enqueued) and `magi_synthesis` (collected + synthesized) entries, keyed by
5
+ // consensusGroupId. This module reconstructs the latest per-group activity from a
6
+ // ledger window and folds it into a BOUNDED mesh_status section so a coordinator (and
7
+ // the web dashboard's extractMagiActivity) can read the synthesis fields — the
8
+ // needs_verification counts, independence banner, and git skew — without re-running
9
+ // collection. Mirrors mesh-refine-status.ts (buildMeshAsyncRefineJobs / summarize…).
10
+ //
11
+ // Pure: operates on a ledger-entry array. No I/O, no Node/DOM APIs.
12
+
13
+ import type { MeshLedgerEntry } from './mesh-ledger.js';
14
+ import type { MagiGitSkew } from '@adhdev/mesh-shared';
15
+
16
+ export type MeshMagiActivityStatus = 'running' | 'synthesized';
17
+
18
+ /** A bounded needs_verification preview item (claim text + category only). */
19
+ export interface MeshMagiNeedsVerificationItem {
20
+ claim: string;
21
+ category: string;
22
+ }
23
+
24
+ export interface MeshMagiActivitySummary {
25
+ consensusGroupId: string;
26
+ status: MeshMagiActivityStatus;
27
+ missionId?: string;
28
+ panel?: string;
29
+ question?: string;
30
+ replicaCount?: number;
31
+ answered?: number;
32
+ missing?: number;
33
+ staleReplicas?: number;
34
+ needsVerificationCount?: number;
35
+ agreedCount?: number;
36
+ independenceBanner?: string | null;
37
+ gitSkew?: MagiGitSkew;
38
+ /** Bounded sample of the needs_verification clusters (claim + category). */
39
+ needsVerification?: MeshMagiNeedsVerificationItem[];
40
+ openQuestions?: string[];
41
+ lastLedgerKind?: string;
42
+ lastUpdatedAt?: string;
43
+ }
44
+
45
+ function readString(value: unknown): string | undefined {
46
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
47
+ }
48
+
49
+ function readRecord(value: unknown): Record<string, unknown> | undefined {
50
+ return value && typeof value === 'object' && !Array.isArray(value)
51
+ ? value as Record<string, unknown>
52
+ : undefined;
53
+ }
54
+
55
+ function readNumber(value: unknown): number | undefined {
56
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
57
+ }
58
+
59
+ /** Cap on inlined needs_verification preview items per group (keeps the payload bounded). */
60
+ export const MAGI_NEEDS_VERIFICATION_PREVIEW_CAP = 8;
61
+
62
+ function summarizeNeedsVerification(synthesis: Record<string, unknown> | undefined): MeshMagiNeedsVerificationItem[] | undefined {
63
+ const list = Array.isArray(synthesis?.needsVerification) ? synthesis!.needsVerification : undefined;
64
+ if (!list) return undefined;
65
+ const items: MeshMagiNeedsVerificationItem[] = [];
66
+ for (const raw of list.slice(0, MAGI_NEEDS_VERIFICATION_PREVIEW_CAP)) {
67
+ const r = readRecord(raw);
68
+ const claim = readString(r?.claim);
69
+ if (!claim) continue;
70
+ items.push({ claim, category: readString(r?.category) || 'needs_verification' });
71
+ }
72
+ return items;
73
+ }
74
+
75
+ function mergeGroup(
76
+ groups: Map<string, MeshMagiActivitySummary>,
77
+ patch: Partial<MeshMagiActivitySummary> & { consensusGroupId?: string },
78
+ ): void {
79
+ const consensusGroupId = readString(patch.consensusGroupId);
80
+ if (!consensusGroupId) return;
81
+ const previous = groups.get(consensusGroupId);
82
+ // synthesized is terminal-ish and must not be downgraded back to running by an
83
+ // out-of-order dispatch entry.
84
+ const status: MeshMagiActivityStatus = patch.status === 'synthesized' || previous?.status === 'synthesized'
85
+ ? 'synthesized'
86
+ : 'running';
87
+ const definedPatch = Object.fromEntries(
88
+ Object.entries(patch).filter(([, v]) => v !== undefined),
89
+ ) as Partial<MeshMagiActivitySummary>;
90
+ groups.set(consensusGroupId, { ...previous, ...definedPatch, consensusGroupId, status });
91
+ }
92
+
93
+ /**
94
+ * Reconstruct per-consensusGroup MAGI activity from a ledger window. The newest
95
+ * `magi_synthesis` for a group supplies the synthesis fields; a `magi_dispatched`
96
+ * with no later synthesis stays `running`. Deduped by consensusGroupId, newest first.
97
+ */
98
+ export function buildMeshMagiActivity(args: {
99
+ meshId?: string;
100
+ ledgerEntries?: MeshLedgerEntry[];
101
+ }): MeshMagiActivitySummary[] {
102
+ const groups = new Map<string, MeshMagiActivitySummary>();
103
+
104
+ for (const entry of args.ledgerEntries || []) {
105
+ const payload = readRecord(entry.payload);
106
+ if (payload?.source !== 'magi') continue;
107
+ const consensusGroupId = readString(payload.consensusGroupId);
108
+ if (!consensusGroupId) continue;
109
+
110
+ if (entry.kind === 'magi_synthesis') {
111
+ const synthesis = readRecord(payload.synthesis);
112
+ mergeGroup(groups, {
113
+ consensusGroupId,
114
+ status: 'synthesized',
115
+ missionId: readString(payload.missionId),
116
+ panel: readString(payload.panel),
117
+ question: readString(payload.question),
118
+ replicaCount: readNumber(synthesis?.replicasExpected) ?? readNumber(payload.replicaCount),
119
+ answered: readNumber(synthesis?.replicasAnswered),
120
+ missing: readNumber(synthesis?.replicasMissing),
121
+ staleReplicas: readNumber(payload.staleReplicas) ?? readNumber(synthesis?.staleReplicas),
122
+ needsVerificationCount: Array.isArray(synthesis?.needsVerification) ? synthesis!.needsVerification.length : undefined,
123
+ agreedCount: Array.isArray(synthesis?.agreed) ? synthesis!.agreed.length : undefined,
124
+ independenceBanner: synthesis && 'independenceBanner' in synthesis ? (synthesis.independenceBanner as string | null) : undefined,
125
+ gitSkew: readRecord(synthesis?.gitSkew) as unknown as MagiGitSkew | undefined,
126
+ needsVerification: summarizeNeedsVerification(synthesis),
127
+ openQuestions: Array.isArray(synthesis?.openQuestions) ? (synthesis!.openQuestions as string[]).slice(0, 10) : undefined,
128
+ lastLedgerKind: entry.kind,
129
+ lastUpdatedAt: entry.timestamp,
130
+ });
131
+ } else if (entry.kind === 'magi_dispatched') {
132
+ mergeGroup(groups, {
133
+ consensusGroupId,
134
+ status: 'running',
135
+ missionId: readString(payload.missionId),
136
+ panel: readString(payload.panel),
137
+ question: readString(payload.question),
138
+ replicaCount: readNumber(payload.replicaCount),
139
+ lastLedgerKind: entry.kind,
140
+ lastUpdatedAt: entry.timestamp,
141
+ });
142
+ }
143
+ }
144
+
145
+ return Array.from(groups.values()).sort((a, b) => {
146
+ const at = new Date(a.lastUpdatedAt || '').getTime();
147
+ const bt = new Date(b.lastUpdatedAt || '').getTime();
148
+ return (Number.isFinite(bt) ? bt : 0) - (Number.isFinite(at) ? at : 0);
149
+ });
150
+ }
151
+
152
+ /** Synthesized groups older than this (relative to the newest activity in the set) are
153
+ * folded out of the active list — already-resolved historical runs that should not keep
154
+ * inflating mesh_status. 6h covers a long working session. */
155
+ export const STALE_MAGI_WINDOW_MS = 6 * 60 * 60 * 1000;
156
+
157
+ /** Cap on recent synthesized groups kept in the active list even if all are fresh. */
158
+ export const RECENT_MAGI_CAP = 6;
159
+
160
+ export interface MeshMagiActivitySummaryFold {
161
+ total: number;
162
+ byStatus: Record<string, number>;
163
+ /** Synthesized groups dropped from the active list as stale historical residue. */
164
+ staleSynthesized: number;
165
+ /** Bounded set of recent/active groups (running first, then recent synthesized). */
166
+ groups: MeshMagiActivitySummary[];
167
+ }
168
+
169
+ function activityTime(g: MeshMagiActivitySummary): number {
170
+ const t = new Date(g.lastUpdatedAt || '').getTime();
171
+ return Number.isFinite(t) ? t : 0;
172
+ }
173
+
174
+ /**
175
+ * Bound the MAGI activity list for mesh_status: running groups are always kept; synthesized
176
+ * groups are kept only when recent (within STALE_MAGI_WINDOW_MS of the newest activity AND
177
+ * among the RECENT_MAGI_CAP most-recent). Freshness is measured relative to the newest group
178
+ * (not wall-clock) so the result is deterministic for a given input. Mirrors
179
+ * summarizeMeshAsyncRefineJobs.
180
+ */
181
+ export function summarizeMeshMagiActivity(
182
+ activity: MeshMagiActivitySummary[],
183
+ ): MeshMagiActivitySummaryFold {
184
+ const running: MeshMagiActivitySummary[] = [];
185
+ const synthesized: MeshMagiActivitySummary[] = [];
186
+ for (const g of activity) {
187
+ if (g.status === 'synthesized') synthesized.push(g);
188
+ else running.push(g);
189
+ }
190
+
191
+ let newest = 0;
192
+ for (const g of activity) newest = Math.max(newest, activityTime(g));
193
+ const cutoff = newest - STALE_MAGI_WINDOW_MS;
194
+
195
+ const synthesizedByRecency = [...synthesized].sort((a, b) => activityTime(b) - activityTime(a));
196
+ const freshSynthesized = synthesizedByRecency
197
+ .filter(g => activityTime(g) >= cutoff)
198
+ .slice(0, RECENT_MAGI_CAP);
199
+
200
+ const byStatus: Record<string, number> = {};
201
+ for (const g of [...running, ...freshSynthesized]) {
202
+ byStatus[g.status] = (byStatus[g.status] ?? 0) + 1;
203
+ }
204
+
205
+ // Running first (most actionable), then recent synthesized — both newest-first.
206
+ const runningByRecency = [...running].sort((a, b) => activityTime(b) - activityTime(a));
207
+ return {
208
+ total: running.length + freshSynthesized.length,
209
+ byStatus,
210
+ staleSynthesized: synthesized.length - freshSynthesized.length,
211
+ groups: [...runningByRecency, ...freshSynthesized],
212
+ };
213
+ }
214
+
215
+ /** Latest persisted synthesis activity for one consensusGroupId, or undefined. */
216
+ export function getMeshMagiActivityByGroup(
217
+ ledgerEntries: MeshLedgerEntry[],
218
+ consensusGroupId: string,
219
+ ): MeshMagiActivitySummary | undefined {
220
+ const key = readString(consensusGroupId);
221
+ if (!key) return undefined;
222
+ return buildMeshMagiActivity({ ledgerEntries }).find(g => g.consensusGroupId === key);
223
+ }
@@ -0,0 +1,449 @@
1
+ /**
2
+ * M3: Mission persistence (minimal form).
3
+ *
4
+ * A mission is a persistent record of a multi-task goal so the plan lives in
5
+ * the system rather than in the coordinator LLM's context. Coordinator
6
+ * sessions can die or compact; a new coordinator reads the mission back at
7
+ * launch and continues.
8
+ *
9
+ * Explicit non-goals (see docs/mesh-product-plan-v2.md Phase M3): this is not
10
+ * a workflow engine and there is no automatic takeover daemon. Progress is
11
+ * never stored — it is derived from queue task statuses (mission_id) at
12
+ * query time.
13
+ */
14
+
15
+ import { randomUUID } from 'crypto';
16
+ import { MeshRuntimeStore } from './mesh-runtime-store.js';
17
+ import { getQueue } from './mesh-work-queue.js';
18
+ import { computeMeshMissionStats, type MeshMissionStats } from './mesh-task-stats.js';
19
+ import { appendLedgerEntry } from './mesh-ledger.js';
20
+
21
+ /**
22
+ * Max chars of mission goal text written into a ledger entry payload. Mission
23
+ * goals can be hundreds–thousands of chars; the ledger is an append-only audit
24
+ * stream, so we store a bounded summary (+ a length/truncated flag) rather than
25
+ * the full text to keep the ledger from bloating on repeated goal rewrites.
26
+ */
27
+ const LEDGER_GOAL_SUMMARY_MAX = 200;
28
+
29
+ function summarizeGoalForLedger(goal: string): string {
30
+ return goal.length > LEDGER_GOAL_SUMMARY_MAX ? goal.slice(0, LEDGER_GOAL_SUMMARY_MAX) : goal;
31
+ }
32
+
33
+ export type MeshMissionStatus = 'active' | 'paused' | 'completed' | 'abandoned';
34
+
35
+ export const MESH_MISSION_STATUSES: MeshMissionStatus[] = ['active', 'paused', 'completed', 'abandoned'];
36
+
37
+ /**
38
+ * Provenance of a mission. `magi` marks an inline mission auto-created by a
39
+ * mesh_magi_review fan-out (one per cross-verification run). `coordinator` (the
40
+ * default semantic for an unstamped/legacy mission) marks a coordinator- or
41
+ * user-authored mission. Used to bound the accumulation of completed MAGI missions
42
+ * out of the default mesh_mission_list surface — see listMeshMissionSummaries.
43
+ */
44
+ export type MeshMissionSource = 'magi' | 'coordinator';
45
+
46
+ export interface MeshMissionRecord {
47
+ id: string;
48
+ meshId: string;
49
+ title: string;
50
+ goal: string;
51
+ status: MeshMissionStatus;
52
+ /**
53
+ * Optional provenance tag. Absent on missions created before this field existed
54
+ * and on coordinator/user missions that don't bother stamping it — both are
55
+ * treated as coordinator missions (never auto-hidden). Only explicit `magi`
56
+ * missions are bounded out of the default list once completed.
57
+ */
58
+ source?: MeshMissionSource;
59
+ createdAt: string;
60
+ updatedAt: string;
61
+ }
62
+
63
+ export interface MeshMissionTaskAggregate {
64
+ total: number;
65
+ pending: number;
66
+ assigned: number;
67
+ completed: number;
68
+ failed: number;
69
+ cancelled: number;
70
+ /** Pending tasks held back by a dependency failure (blockedReason set). */
71
+ blocked: number;
72
+ /** Latest updatedAt across the mission's tasks, or null with no tasks. */
73
+ lastActivityAt: string | null;
74
+ }
75
+
76
+ export interface MeshMissionSummary extends MeshMissionRecord {
77
+ tasks: MeshMissionTaskAggregate;
78
+ /**
79
+ * Operational rollup (durations / attempts) derived from the ledger via
80
+ * computeMeshMissionStats. Optional: only populated by surfaces that opt in
81
+ * (e.g. mesh_status), since the rollup scans a bounded ledger tail per
82
+ * mission. Absent on the lightweight task-aggregate-only summaries.
83
+ */
84
+ stats?: MeshMissionStats;
85
+ }
86
+
87
+ /**
88
+ * Slim mission summary for the mesh_status compact (default) surface. Drops the
89
+ * full `goal` text — which can be hundreds of chars per mission and is repeated
90
+ * for every mission on every status call — keeping only a short preview plus a
91
+ * `goalTruncated` flag when the original was longer. The stored goal is never
92
+ * mutated; this is an output-only projection. Coordinators that need the full
93
+ * goal call mesh_status with verbose=true, or read the mission directly via
94
+ * mesh_mission_upsert / getMeshMission.
95
+ */
96
+ export interface MeshMissionSlimSummary extends Omit<MeshMissionSummary, 'goal'> {
97
+ /** Short preview of the goal (≤ GOAL_PREVIEW_MAX chars), '' when goal empty. */
98
+ goalPreview: string;
99
+ /** True when the stored goal was longer than the preview (full text elided). */
100
+ goalTruncated: boolean;
101
+ }
102
+
103
+ /** Max chars of goal text retained in the slim (compact) mission summary. */
104
+ export const GOAL_PREVIEW_MAX = 120;
105
+
106
+ /**
107
+ * Shorter goal preview used by the mesh_status compact (LLM coordinator) surface.
108
+ * The coordinator only needs to recognize a mission, not read its full goal, and
109
+ * mesh_status repeats every live mission on every poll — so the status preview is
110
+ * tighter than the dashboard / mesh_mission_list preview (GOAL_PREVIEW_MAX).
111
+ */
112
+ export const COMPACT_STATUS_GOAL_PREVIEW_MAX = 80;
113
+
114
+ function normalizeMissionStatus(value: unknown): MeshMissionStatus {
115
+ return MESH_MISSION_STATUSES.includes(value as MeshMissionStatus)
116
+ ? value as MeshMissionStatus
117
+ : 'active';
118
+ }
119
+
120
+ function normalizeMissionSource(value: unknown): MeshMissionSource | undefined {
121
+ return value === 'magi' || value === 'coordinator' ? value : undefined;
122
+ }
123
+
124
+ export function upsertMeshMission(meshId: string, input: {
125
+ id?: string;
126
+ title: string;
127
+ goal?: string;
128
+ status?: string;
129
+ source?: MeshMissionSource;
130
+ }): MeshMissionRecord {
131
+ const title = typeof input.title === 'string' ? input.title.trim() : '';
132
+ if (!title) throw new Error('mission_title_required: a mission needs a non-empty title');
133
+ if (input.status !== undefined && !MESH_MISSION_STATUSES.includes(input.status as MeshMissionStatus)) {
134
+ throw new Error(`invalid_mission_status: '${input.status}' (valid: ${MESH_MISSION_STATUSES.join(', ')})`);
135
+ }
136
+ const id = typeof input.id === 'string' && input.id.trim() ? input.id.trim() : randomUUID();
137
+ const store = MeshRuntimeStore.getInstance();
138
+ const existing = store.getMission(meshId, id);
139
+ const prevStatus = existing ? normalizeMissionStatus(existing.status) : null;
140
+ const prevGoal = existing?.goal ?? '';
141
+ const record = {
142
+ id,
143
+ meshId,
144
+ title,
145
+ goal: typeof input.goal === 'string' ? input.goal : existing?.goal ?? '',
146
+ status: normalizeMissionStatus(input.status ?? existing?.status),
147
+ // source is write-once: only forwarded when the caller supplies one. The
148
+ // store COALESCEs it against the existing value, so a later status/goal
149
+ // upsert that omits source never clears a previously-stamped tag.
150
+ ...(input.source ? { source: input.source } : {}),
151
+ };
152
+ store.upsertMission(record);
153
+ const saved = store.getMission(meshId, id)!;
154
+ const result: MeshMissionRecord = {
155
+ ...saved,
156
+ status: normalizeMissionStatus(saved.status),
157
+ source: normalizeMissionSource(saved.source),
158
+ };
159
+
160
+ // Mission audit trail: record this mutation in the mesh ledger so mission
161
+ // lifecycle (create, goal rewrite, status transition) is auditable alongside
162
+ // task events and survives a coordinator restart. Best-effort: a ledger
163
+ // failure must never break the primary mission write.
164
+ appendMissionLedgerEntries(meshId, {
165
+ isCreate: !existing,
166
+ record: result,
167
+ prevStatus,
168
+ prevGoal,
169
+ });
170
+
171
+ return result;
172
+ }
173
+
174
+ /**
175
+ * Append the relevant ledger entries for a mission upsert. Emits at most one
176
+ * entry per distinct change:
177
+ * - new mission → mission_created
178
+ * - status differs from prior → mission_status_changed
179
+ * - goal text differs from prior → mission_goal_updated (no-op rewrites skipped)
180
+ */
181
+ function appendMissionLedgerEntries(
182
+ meshId: string,
183
+ args: { isCreate: boolean; record: MeshMissionRecord; prevStatus: MeshMissionStatus | null; prevGoal: string },
184
+ ): void {
185
+ const { isCreate, record, prevStatus, prevGoal } = args;
186
+ try {
187
+ if (isCreate) {
188
+ const goal = record.goal ?? '';
189
+ appendLedgerEntry(meshId, {
190
+ kind: 'mission_created',
191
+ payload: {
192
+ missionId: record.id,
193
+ title: record.title,
194
+ goalSummary: summarizeGoalForLedger(goal),
195
+ goalLength: goal.length,
196
+ goalTruncated: goal.length > LEDGER_GOAL_SUMMARY_MAX,
197
+ status: record.status,
198
+ },
199
+ });
200
+ return;
201
+ }
202
+ if (prevStatus !== null && prevStatus !== record.status) {
203
+ appendLedgerEntry(meshId, {
204
+ kind: 'mission_status_changed',
205
+ payload: {
206
+ missionId: record.id,
207
+ title: record.title,
208
+ fromStatus: prevStatus,
209
+ toStatus: record.status,
210
+ },
211
+ });
212
+ }
213
+ const nextGoal = record.goal ?? '';
214
+ if (nextGoal !== prevGoal) {
215
+ appendLedgerEntry(meshId, {
216
+ kind: 'mission_goal_updated',
217
+ payload: {
218
+ missionId: record.id,
219
+ title: record.title,
220
+ prevGoalSummary: summarizeGoalForLedger(prevGoal),
221
+ nextGoalSummary: summarizeGoalForLedger(nextGoal),
222
+ prevGoalLength: prevGoal.length,
223
+ nextGoalLength: nextGoal.length,
224
+ goalTruncated: prevGoal.length > LEDGER_GOAL_SUMMARY_MAX || nextGoal.length > LEDGER_GOAL_SUMMARY_MAX,
225
+ },
226
+ });
227
+ }
228
+ } catch { /* audit trail is best-effort; never break the mission write */ }
229
+ }
230
+
231
+ export function getMeshMissions(meshId: string, statuses?: MeshMissionStatus[]): MeshMissionRecord[] {
232
+ return MeshRuntimeStore.getInstance().getMissions(meshId, statuses)
233
+ .map(m => ({ ...m, status: normalizeMissionStatus(m.status), source: normalizeMissionSource(m.source) }));
234
+ }
235
+
236
+ export function getMeshMission(meshId: string, missionId: string): MeshMissionRecord | null {
237
+ const record = MeshRuntimeStore.getInstance().getMission(meshId, missionId);
238
+ return record ? { ...record, status: normalizeMissionStatus(record.status), source: normalizeMissionSource(record.source) } : null;
239
+ }
240
+
241
+ /** Aggregate task statuses for a mission at query time (no stored progress). */
242
+ export function summarizeMissionTasks(meshId: string, missionId: string): MeshMissionTaskAggregate {
243
+ const tasks = getQueue(meshId).filter(task => task.missionId === missionId);
244
+ const aggregate: MeshMissionTaskAggregate = {
245
+ total: tasks.length,
246
+ pending: 0,
247
+ assigned: 0,
248
+ completed: 0,
249
+ failed: 0,
250
+ cancelled: 0,
251
+ blocked: 0,
252
+ lastActivityAt: null,
253
+ };
254
+ for (const task of tasks) {
255
+ if (task.status === 'pending') aggregate.pending += 1;
256
+ else if (task.status === 'assigned') aggregate.assigned += 1;
257
+ else if (task.status === 'completed') aggregate.completed += 1;
258
+ else if (task.status === 'failed') aggregate.failed += 1;
259
+ else if (task.status === 'cancelled') aggregate.cancelled += 1;
260
+ if (task.status === 'pending' && task.blockedReason) aggregate.blocked += 1;
261
+ if (task.updatedAt && (!aggregate.lastActivityAt || task.updatedAt > aggregate.lastActivityAt)) {
262
+ aggregate.lastActivityAt = task.updatedAt;
263
+ }
264
+ }
265
+ return aggregate;
266
+ }
267
+
268
+ export function summarizeMeshMission(meshId: string, mission: MeshMissionRecord): MeshMissionSummary {
269
+ return { ...mission, tasks: summarizeMissionTasks(meshId, mission.id) };
270
+ }
271
+
272
+ /** Active mission summaries for mesh_status / coordinator prompt injection. */
273
+ export function getActiveMeshMissionSummaries(meshId: string): MeshMissionSummary[] {
274
+ return getMeshMissions(meshId, ['active']).map(mission => summarizeMeshMission(meshId, mission));
275
+ }
276
+
277
+ /** Project a full mission summary down to the slim (goal-elided) shape. */
278
+ function slimMissionSummary(summary: MeshMissionSummary, previewMax: number = GOAL_PREVIEW_MAX): MeshMissionSlimSummary {
279
+ const goal = typeof summary.goal === 'string' ? summary.goal : '';
280
+ const goalTruncated = goal.length > previewMax;
281
+ const { goal: _omitGoal, ...rest } = summary;
282
+ return {
283
+ ...rest,
284
+ goalPreview: goalTruncated ? goal.slice(0, previewMax) : goal,
285
+ goalTruncated,
286
+ };
287
+ }
288
+
289
+ /**
290
+ * Mission summaries for the mesh_status dashboard surface: every active/paused
291
+ * mission plus a capped, newest-first slice of completed/abandoned history so
292
+ * the dashboard can render a collapsible "history" section without unbounded
293
+ * payload growth. Returned newest-first within each group (active/paused first,
294
+ * then history), so the frontend can split on `status` directly.
295
+ *
296
+ * Compact mode (the default) elides each mission's full `goal` text — which is
297
+ * repeated verbatim on every status poll and dominates the payload when a mesh
298
+ * has many missions — returning only a short `goalPreview` + `goalTruncated`
299
+ * flag. Pass `verbose: true` to get the full `goal` text per mission. The stored
300
+ * goal is untouched in both modes; this is an output-only projection.
301
+ */
302
+ export function getMeshStatusMissionSummaries(
303
+ meshId: string,
304
+ options?: { historyLimit?: number; verbose?: boolean; withStats?: boolean },
305
+ ): MeshMissionSummary[] | MeshMissionSlimSummary[] {
306
+ const historyLimit = Math.max(0, options?.historyLimit ?? 10);
307
+ const all = getMeshMissions(meshId);
308
+ const live = all.filter(m => m.status === 'active' || m.status === 'paused');
309
+ const history = all
310
+ .filter(m => m.status === 'completed' || m.status === 'abandoned')
311
+ .sort((a, b) => (b.updatedAt || '').localeCompare(a.updatedAt || ''))
312
+ .slice(0, historyLimit);
313
+ let full = [...live, ...history].map(mission => summarizeMeshMission(meshId, mission));
314
+ // Operational stats (durations / attempts) are an opt-in projection: each
315
+ // mission's rollup scans a bounded ledger tail, so we only compute it for
316
+ // the bounded set we are about to return (live + capped history), not for
317
+ // every mission in the mesh. The dashboard graph opts in so mission detail
318
+ // can show wall-clock / retries without a second round trip.
319
+ if (options?.withStats) {
320
+ full = full.map(summary => ({ ...summary, stats: computeMeshMissionStats(meshId, summary.id) }));
321
+ }
322
+ return options?.verbose ? full : full.map(summary => slimMissionSummary(summary));
323
+ }
324
+
325
+ /** Folded completed/abandoned history for the mesh_status compact surface. */
326
+ export interface MeshStatusMissionsHistoryFold {
327
+ /** Total completed + abandoned missions. */
328
+ count: number;
329
+ /** Count by lifecycle status (e.g. { completed, abandoned }). */
330
+ byStatus: Record<string, number>;
331
+ /** Newest-first id list (capped) so each folded mission stays addressable. */
332
+ missionIds: string[];
333
+ note: string;
334
+ }
335
+
336
+ /** Compact mesh_status mission projection: live detail + folded history. */
337
+ export interface MeshStatusMissionsCompact {
338
+ /**
339
+ * Active + paused missions, goal-elided to COMPACT_STATUS_GOAL_PREVIEW_MAX and
340
+ * WITHOUT the operational `stats` rollup — the `tasks` aggregate already carries
341
+ * progress, and stats (durations/retries) is a verbose/dashboard concern.
342
+ */
343
+ live: MeshMissionSlimSummary[];
344
+ /** Completed + abandoned missions folded to counts + ids; null when none. */
345
+ historyFold: MeshStatusMissionsHistoryFold | null;
346
+ }
347
+
348
+ /**
349
+ * Mission projection for the mesh_status COMPACT (LLM coordinator) surface.
350
+ *
351
+ * Unlike getMeshStatusMissionSummaries (which emits every live mission plus a
352
+ * capped slice of full-detail history, each carrying a stats rollup), this keeps
353
+ * per-mission detail ONLY for live (active/paused) missions and folds the whole
354
+ * completed/abandoned history into a counts + id-list summary. Combined with the
355
+ * tighter goal preview and dropped stats, this is what keeps the compact
356
+ * mesh_status payload bounded as a mesh accumulates missions — the missions
357
+ * section previously dominated the payload (full goalPreview + tasks + stats per
358
+ * mission, for every live mission and up to 10 history missions, on every poll).
359
+ *
360
+ * The stored missions are untouched; this is an output-only projection. Full
361
+ * mission detail (goal text + stats + history) stays available via
362
+ * mesh_status verbose=true or mesh_mission_list.
363
+ */
364
+ export function getMeshStatusMissionsCompact(
365
+ meshId: string,
366
+ options?: { previewMax?: number; historyIdLimit?: number },
367
+ ): MeshStatusMissionsCompact {
368
+ const previewMax = Math.max(0, options?.previewMax ?? COMPACT_STATUS_GOAL_PREVIEW_MAX);
369
+ const historyIdLimit = Math.max(0, options?.historyIdLimit ?? 20);
370
+ const all = getMeshMissions(meshId);
371
+ const live = all
372
+ .filter(m => m.status === 'active' || m.status === 'paused')
373
+ .map(mission => slimMissionSummary(summarizeMeshMission(meshId, mission), previewMax));
374
+ const history = all
375
+ .filter(m => m.status === 'completed' || m.status === 'abandoned')
376
+ .sort((a, b) => (b.updatedAt || '').localeCompare(a.updatedAt || ''));
377
+ let historyFold: MeshStatusMissionsHistoryFold | null = null;
378
+ if (history.length > 0) {
379
+ const byStatus: Record<string, number> = {};
380
+ for (const m of history) byStatus[m.status] = (byStatus[m.status] ?? 0) + 1;
381
+ historyFold = {
382
+ count: history.length,
383
+ byStatus,
384
+ missionIds: history.slice(0, historyIdLimit).map(m => m.id),
385
+ note: 'Completed/abandoned missions are folded to counts + ids in compact mesh_status. Use mesh_mission_list or mesh_status verbose=true for their goal/task detail.',
386
+ };
387
+ }
388
+ return { live, historyFold };
389
+ }
390
+
391
+ /**
392
+ * Read-only mission listing for the mesh_mission_list tool. Returns summaries
393
+ * (record + live task aggregate) for missions matching `statuses` — or every
394
+ * mission when `statuses` is omitted/empty — newest-first by updatedAt. Unlike
395
+ * getMeshStatusMissionSummaries this does NOT cap or group by lifecycle, so a
396
+ * coordinator can deliberately surface paused/abandoned/completed missions that
397
+ * the live status view would hide or truncate.
398
+ *
399
+ * MAGI bounding: by default this EXCLUDES completed MAGI missions (source==='magi'
400
+ * && status==='completed') — a mesh_magi_review fan-out auto-creates one inline
401
+ * mission per run and auto-closes it on collection, so without this they accumulate
402
+ * unbounded and drown out coordinator missions in the list. In-progress MAGI missions
403
+ * (active/paused) are still shown so a running cross-verification stays visible. Pass
404
+ * `includeMagi: true` to return every mission including completed MAGI ones. A mission
405
+ * with no `source` (legacy / coordinator) is never affected.
406
+ *
407
+ * Compact (the default) elides each goal to a capped preview + goalTruncated
408
+ * flag; verbose returns the full goal text. The stored goal is never mutated.
409
+ */
410
+ export function listMeshMissionSummaries(
411
+ meshId: string,
412
+ options?: { statuses?: MeshMissionStatus[]; verbose?: boolean; includeMagi?: boolean },
413
+ ): MeshMissionSummary[] | MeshMissionSlimSummary[] {
414
+ const statuses = options?.statuses && options.statuses.length > 0 ? options.statuses : undefined;
415
+ const includeMagi = options?.includeMagi === true;
416
+ const missions = getMeshMissions(meshId, statuses)
417
+ // Bound completed-MAGI accumulation by default. Only a mission EXPLICITLY
418
+ // tagged source==='magi' AND completed is hidden — coordinator/legacy
419
+ // (source undefined) missions and in-progress MAGI missions always pass.
420
+ .filter(m => includeMagi || !(m.source === 'magi' && m.status === 'completed'))
421
+ .sort((a, b) => (b.updatedAt || '').localeCompare(a.updatedAt || ''));
422
+ const full = missions.map(mission => summarizeMeshMission(meshId, mission));
423
+ return options?.verbose ? full : full.map(summary => slimMissionSummary(summary));
424
+ }
425
+
426
+ /**
427
+ * M3-3: render active missions as a prompt section for {{mission}}.
428
+ * Empty string when no active mission — the prompt stays byte-identical to
429
+ * the pre-M3 output in that case (regression guarantee).
430
+ */
431
+ export function buildMissionPromptSection(meshId: string): string {
432
+ const summaries = getActiveMeshMissionSummaries(meshId);
433
+ if (summaries.length === 0) return '';
434
+ const lines: string[] = ['## Active Mission' + (summaries.length > 1 ? 's' : '')];
435
+ for (const mission of summaries) {
436
+ const t = mission.tasks;
437
+ lines.push(
438
+ `- **${mission.title}** (id: \`${mission.id}\`)`
439
+ + (mission.goal ? `\n Goal: ${mission.goal}` : '')
440
+ + `\n Tasks: ${t.total} total — ${t.pending} pending (${t.blocked} blocked), ${t.assigned} assigned, ${t.completed} completed, ${t.failed} failed, ${t.cancelled} cancelled`
441
+ + (t.lastActivityAt ? `\n Last activity: ${t.lastActivityAt}` : ''),
442
+ );
443
+ }
444
+ lines.push(
445
+ 'Continue this mission from its current task state. Do not re-enqueue tasks that already exist — check mesh_view_queue first. '
446
+ + 'Update the mission with mesh_mission_upsert when its goal changes or it reaches a terminal state (completed/abandoned).',
447
+ );
448
+ return lines.join('\n');
449
+ }