@adhdev/daemon-core 0.9.82-rc.40 → 0.9.82-rc.401

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 (417) 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 +199 -0
  10. package/dist/cli-adapters/provider-cli-adapter.d.ts +125 -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 +14 -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 +2 -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 +116 -0
  54. package/dist/commands/mesh-coordinator.d.ts +85 -1
  55. package/dist/commands/router.d.ts +256 -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 +77 -1
  60. package/dist/config/mesh-json-config.d.ts +299 -0
  61. package/dist/daemon/dev-server.d.ts +0 -2
  62. package/dist/detection/ide-detector.d.ts +13 -0
  63. package/dist/detection/win32-ide-version.d.ts +37 -0
  64. package/dist/git/change-impact-config.d.ts +159 -0
  65. package/dist/git/git-commands.d.ts +11 -1
  66. package/dist/git/git-diff.d.ts +6 -0
  67. package/dist/git/git-executor.d.ts +11 -0
  68. package/dist/git/git-status.d.ts +23 -0
  69. package/dist/git/git-types.d.ts +2 -50
  70. package/dist/git/git-worktree.d.ts +71 -1
  71. package/dist/git/index.d.ts +3 -1
  72. package/dist/index.d.ts +57 -13
  73. package/dist/index.js +45987 -17082
  74. package/dist/index.js.map +1 -1
  75. package/dist/index.mjs +45750 -16986
  76. package/dist/index.mjs.map +1 -1
  77. package/dist/installer.d.ts +1 -4
  78. package/dist/ipc/local-ipc-server.d.ts +91 -0
  79. package/dist/launch.d.ts +1 -1
  80. package/dist/logging/async-batch-writer.d.ts +10 -0
  81. package/dist/logging/log-redactor.d.ts +24 -0
  82. package/dist/logging/log-tail-reader.d.ts +81 -0
  83. package/dist/logging/logger.d.ts +1 -1
  84. package/dist/mesh/contracts.d.ts +164 -0
  85. package/dist/mesh/coordinator-prompt.d.ts +89 -0
  86. package/dist/mesh/coordinator-registry.d.ts +59 -0
  87. package/dist/mesh/mesh-active-work.d.ts +174 -0
  88. package/dist/mesh/mesh-coordinator-config.d.ts +21 -0
  89. package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
  90. package/dist/mesh/mesh-event-classify.d.ts +5 -0
  91. package/dist/mesh/mesh-event-forwarding.d.ts +19 -0
  92. package/dist/mesh/mesh-event-trace.d.ts +21 -0
  93. package/dist/mesh/mesh-events-coordinator.d.ts +4 -0
  94. package/dist/mesh/mesh-events-pending.d.ts +55 -0
  95. package/dist/mesh/mesh-events-stale.d.ts +61 -0
  96. package/dist/mesh/mesh-events-utils.d.ts +75 -0
  97. package/dist/mesh/mesh-events.d.ts +6 -49
  98. package/dist/mesh/mesh-fast-forward.d.ts +81 -0
  99. package/dist/mesh/mesh-host-ownership.d.ts +9 -0
  100. package/dist/mesh/mesh-init.d.ts +86 -0
  101. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -4
  102. package/dist/mesh/mesh-ledger.d.ts +77 -1
  103. package/dist/mesh/mesh-missions.d.ts +164 -0
  104. package/dist/mesh/mesh-node-identity.d.ts +289 -0
  105. package/dist/mesh/mesh-queue-assignment.d.ts +95 -0
  106. package/dist/mesh/mesh-reconcile-loop.d.ts +65 -0
  107. package/dist/mesh/mesh-refine-batch.d.ts +68 -0
  108. package/dist/mesh/mesh-refine-gates.d.ts +428 -0
  109. package/dist/mesh/mesh-refine-status.d.ts +62 -0
  110. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  111. package/dist/mesh/mesh-routing.d.ts +70 -0
  112. package/dist/mesh/mesh-runtime-store.d.ts +447 -0
  113. package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
  114. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  115. package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +30 -0
  116. package/dist/mesh/mesh-warmup-deadline.d.ts +68 -0
  117. package/dist/mesh/mesh-work-queue.d.ts +247 -5
  118. package/dist/mesh/preview-freshness.d.ts +18 -0
  119. package/dist/mesh/refine-config.d.ts +216 -0
  120. package/dist/mesh/worktree-bootstrap-config.d.ts +145 -0
  121. package/dist/providers/acp-provider-instance.d.ts +5 -0
  122. package/dist/providers/approval-utils.d.ts +20 -0
  123. package/dist/providers/chat-message-normalization.d.ts +13 -1
  124. package/dist/providers/cli-provider-instance.d.ts +167 -3
  125. package/dist/providers/contracts.d.ts +139 -6
  126. package/dist/providers/external-sources.d.ts +71 -0
  127. package/dist/providers/manual-attendance.d.ts +63 -0
  128. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  129. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  130. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  131. package/dist/providers/native-history/constants.d.ts +12 -0
  132. package/dist/providers/native-history/dispatcher.d.ts +27 -0
  133. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  134. package/dist/providers/native-history/index.d.ts +13 -0
  135. package/dist/providers/provider-instance-manager.d.ts +14 -0
  136. package/dist/providers/provider-instance.d.ts +23 -1
  137. package/dist/providers/provider-loader.d.ts +26 -4
  138. package/dist/providers/provider-trust.d.ts +31 -0
  139. package/dist/providers/read-chat-contract.d.ts +29 -0
  140. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  141. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +86 -0
  142. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  143. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  144. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  145. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  146. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  147. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  148. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  149. package/dist/providers/sdk/v1/index.d.ts +30 -0
  150. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  151. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  152. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  153. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  154. package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
  155. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  156. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  157. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  158. package/dist/providers/spec/adapter.d.ts +91 -0
  159. package/dist/providers/spec/cli-adapter.d.ts +223 -0
  160. package/dist/providers/spec/evaluator.d.ts +45 -0
  161. package/dist/providers/spec/fsm-driver.d.ts +407 -0
  162. package/dist/providers/spec/fsm-evaluator.d.ts +76 -0
  163. package/dist/providers/spec/fsm-loader.d.ts +14 -0
  164. package/dist/providers/spec/fsm-types.d.ts +174 -0
  165. package/dist/providers/spec/native-history-executor.d.ts +41 -0
  166. package/dist/providers/spec/pre-launch-trust.d.ts +16 -0
  167. package/dist/providers/spec/route.d.ts +4 -0
  168. package/dist/providers/spec/types.d.ts +222 -0
  169. package/dist/providers/status-monitor.d.ts +7 -7
  170. package/dist/providers/transcript-v2.d.ts +176 -0
  171. package/dist/providers/types/interactive-prompt.d.ts +84 -0
  172. package/dist/providers/working-dir.d.ts +17 -0
  173. package/dist/repo-mesh-types.d.ts +420 -13
  174. package/dist/runtime-defaults.d.ts +2 -0
  175. package/dist/sessions/registry.d.ts +6 -0
  176. package/dist/shared-types-extra.d.ts +2 -4
  177. package/dist/shared-types.d.ts +59 -2
  178. package/dist/status/normalize.d.ts +1 -1
  179. package/dist/status/normalize.js +1 -0
  180. package/dist/status/normalize.js.map +1 -1
  181. package/dist/status/normalize.mjs +1 -0
  182. package/dist/status/normalize.mjs.map +1 -1
  183. package/dist/status/reporter.d.ts +2 -0
  184. package/dist/status/snapshot.d.ts +26 -0
  185. package/dist/system/hash.d.ts +8 -0
  186. package/dist/system/load-better-sqlite3.d.ts +21 -0
  187. package/dist/types.d.ts +5 -0
  188. package/package.json +7 -3
  189. package/src/agent-stream/poller.ts +2 -3
  190. package/src/agent-stream/provider-adapter.ts +1 -1
  191. package/src/boot/daemon-lifecycle.ts +63 -12
  192. package/src/boot/process-hardening.ts +89 -0
  193. package/src/build-info.ts +73 -0
  194. package/src/chat/source-machine.ts +534 -0
  195. package/src/chat/source-resolver.ts +0 -0
  196. package/src/chat/subscription-updates.ts +20 -1
  197. package/src/cli-adapter-types.d.ts +3 -1
  198. package/src/cli-adapter-types.ts +68 -2
  199. package/src/cli-adapters/cli-script-runner.ts +421 -0
  200. package/src/cli-adapters/cli-state-engine.ts +1236 -0
  201. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  202. package/src/cli-adapters/provider-cli-adapter.ts +909 -1144
  203. package/src/cli-adapters/provider-cli-parse.d.ts +2 -0
  204. package/src/cli-adapters/provider-cli-parse.ts +19 -0
  205. package/src/cli-adapters/provider-cli-runtime.ts +56 -7
  206. package/src/cli-adapters/provider-cli-shared.d.ts +4 -0
  207. package/src/cli-adapters/provider-cli-shared.ts +121 -11
  208. package/src/cli-adapters/pty-transport.ts +2 -1
  209. package/src/cli-adapters/pty-write-chunking.ts +106 -0
  210. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  211. package/src/cli-adapters/resolve-executable.ts +90 -0
  212. package/src/cli-adapters/session-host-transport.ts +2 -1
  213. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +53 -29
  214. package/src/cli-adapters/terminal-backends/types.ts +10 -3
  215. package/src/cli-adapters/terminal-screen.ts +16 -81
  216. package/src/commands/WINDOWS-UPGRADE-LOCK-FAILURE.md +198 -0
  217. package/src/commands/chat-commands-debug-bundle.ts +398 -0
  218. package/src/commands/chat-commands-read.ts +2327 -0
  219. package/src/commands/chat-commands-scope.ts +54 -0
  220. package/src/commands/chat-commands-shared.ts +114 -0
  221. package/src/commands/chat-commands-write.ts +880 -0
  222. package/src/commands/chat-commands.ts +19 -1841
  223. package/src/commands/cli-manager.ts +527 -26
  224. package/src/commands/handler.ts +841 -2
  225. package/src/commands/high-family/index.ts +28 -0
  226. package/src/commands/high-family/mesh-coordinator-launch.ts +673 -0
  227. package/src/commands/high-family/mesh-events.ts +80 -0
  228. package/src/commands/high-family/mesh-status.ts +678 -0
  229. package/src/commands/high-family/types.ts +76 -0
  230. package/src/commands/low-family/coordinator-prompt.ts +72 -0
  231. package/src/commands/low-family/daemon-lifecycle.ts +107 -0
  232. package/src/commands/low-family/diagnostics.ts +57 -0
  233. package/src/commands/low-family/index.ts +37 -0
  234. package/src/commands/low-family/mesh-ledger.ts +62 -0
  235. package/src/commands/low-family/mesh-node-logs.ts +87 -0
  236. package/src/commands/low-family/notification.ts +116 -0
  237. package/src/commands/low-family/refine-config.ts +106 -0
  238. package/src/commands/low-family/session-host.ts +274 -0
  239. package/src/commands/low-family/spec-providerdev.ts +217 -0
  240. package/src/commands/low-family/status-meta.ts +112 -0
  241. package/src/commands/low-family/types.ts +39 -0
  242. package/src/commands/med-family/cli-agent.ts +238 -0
  243. package/src/commands/med-family/fast-forward.ts +230 -0
  244. package/src/commands/med-family/ide.ts +163 -0
  245. package/src/commands/med-family/index.ts +37 -0
  246. package/src/commands/med-family/mesh-crud.ts +874 -0
  247. package/src/commands/med-family/mesh-host-pairing.ts +234 -0
  248. package/src/commands/med-family/mesh-queue.ts +131 -0
  249. package/src/commands/med-family/mesh-restart.ts +92 -0
  250. package/src/commands/med-family/types.ts +120 -0
  251. package/src/commands/mesh-coordinator.ts +334 -124
  252. package/src/commands/router.ts +2516 -3221
  253. package/src/commands/stream-commands.ts +8 -0
  254. package/src/commands/upgrade-helper.ts +310 -45
  255. package/src/config/chat-history.ts +483 -24
  256. package/src/config/config.ts +12 -0
  257. package/src/config/mesh-config.ts +353 -22
  258. package/src/config/mesh-json-config.ts +617 -0
  259. package/src/config/recent-activity.ts +8 -2
  260. package/src/daemon/dev-auto-implement.ts +3 -2
  261. package/src/daemon/dev-cli-debug.ts +10 -1
  262. package/src/daemon/dev-server.ts +0 -541
  263. package/src/detection/cli-detector.ts +28 -9
  264. package/src/detection/ide-detector.ts +55 -16
  265. package/src/detection/win32-ide-version.ts +106 -0
  266. package/src/git/change-impact-config.ts +354 -0
  267. package/src/git/git-commands.ts +55 -14
  268. package/src/git/git-diff.ts +81 -11
  269. package/src/git/git-executor.ts +12 -0
  270. package/src/git/git-status.ts +574 -43
  271. package/src/git/git-types.ts +14 -62
  272. package/src/git/git-worktree.ts +261 -4
  273. package/src/git/index.ts +17 -0
  274. package/src/index.ts +171 -12
  275. package/src/installer.d.ts +1 -1
  276. package/src/installer.ts +8 -6
  277. package/src/ipc/local-ipc-server.ts +278 -0
  278. package/src/launch.d.ts +1 -1
  279. package/src/launch.ts +37 -28
  280. package/src/logging/async-batch-writer.ts +55 -0
  281. package/src/logging/command-log.ts +7 -5
  282. package/src/logging/log-redactor.ts +100 -0
  283. package/src/logging/log-tail-reader.ts +341 -0
  284. package/src/logging/logger.ts +14 -7
  285. package/src/mesh/contracts.ts +338 -0
  286. package/src/mesh/coordinator-prompt.ts +381 -33
  287. package/src/mesh/coordinator-registry.ts +121 -0
  288. package/src/mesh/mesh-active-work.ts +645 -0
  289. package/src/mesh/mesh-coordinator-config.ts +97 -0
  290. package/src/mesh/mesh-delivery-policy.ts +315 -0
  291. package/src/mesh/mesh-event-classify.ts +51 -0
  292. package/src/mesh/mesh-event-forwarding.ts +1773 -0
  293. package/src/mesh/mesh-event-trace.ts +67 -0
  294. package/src/mesh/mesh-events-coordinator.ts +31 -0
  295. package/src/mesh/mesh-events-pending.ts +590 -0
  296. package/src/mesh/mesh-events-stale.ts +389 -0
  297. package/src/mesh/mesh-events-utils.ts +443 -0
  298. package/src/mesh/mesh-events.ts +32 -1035
  299. package/src/mesh/mesh-fast-forward.ts +839 -0
  300. package/src/mesh/mesh-host-ownership.ts +73 -0
  301. package/src/mesh/mesh-init.ts +260 -0
  302. package/src/mesh/mesh-ledger-reconciliation.ts +12 -7
  303. package/src/mesh/mesh-ledger.ts +596 -102
  304. package/src/mesh/mesh-missions.ts +322 -0
  305. package/src/mesh/mesh-node-identity.ts +1887 -0
  306. package/src/mesh/mesh-queue-assignment.ts +1738 -0
  307. package/src/mesh/mesh-reconcile-loop.ts +1554 -0
  308. package/src/mesh/mesh-refine-batch.ts +205 -0
  309. package/src/mesh/mesh-refine-gates.ts +1660 -0
  310. package/src/mesh/mesh-refine-status.ts +231 -0
  311. package/src/mesh/mesh-review-inbox.ts +307 -0
  312. package/src/mesh/mesh-routing.ts +291 -0
  313. package/src/mesh/mesh-runtime-store.ts +1835 -0
  314. package/src/mesh/mesh-scheduling-runtime.ts +201 -0
  315. package/src/mesh/mesh-task-stats.ts +161 -0
  316. package/src/mesh/mesh-unresolved-forward-outbox.ts +185 -0
  317. package/src/mesh/mesh-warmup-deadline.ts +152 -0
  318. package/src/mesh/mesh-work-queue.ts +1141 -141
  319. package/src/mesh/preview-freshness.ts +118 -0
  320. package/src/mesh/refine-config.ts +423 -0
  321. package/src/mesh/worktree-bootstrap-config.ts +369 -0
  322. package/src/providers/acp-provider-instance.ts +43 -10
  323. package/src/providers/approval-utils.d.ts +5 -0
  324. package/src/providers/approval-utils.ts +57 -5
  325. package/src/providers/chat-message-normalization.ts +46 -6
  326. package/src/providers/cli-provider-instance.ts +1624 -103
  327. package/src/providers/contracts.d.ts +55 -0
  328. package/src/providers/contracts.ts +150 -6
  329. package/src/providers/extension-provider-instance.ts +12 -7
  330. package/src/providers/external-sources.ts +218 -0
  331. package/src/providers/ide-provider-instance.ts +35 -12
  332. package/src/providers/manual-attendance.ts +85 -0
  333. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  334. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  335. package/src/providers/native-history/codex-cli-transcript.ts +479 -0
  336. package/src/providers/native-history/constants.ts +19 -0
  337. package/src/providers/native-history/dispatcher.ts +339 -0
  338. package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
  339. package/src/providers/native-history/index.ts +30 -0
  340. package/src/providers/provider-instance-manager.ts +30 -0
  341. package/src/providers/provider-instance.ts +19 -1
  342. package/src/providers/provider-loader.ts +668 -50
  343. package/src/providers/provider-schema.ts +87 -14
  344. package/src/providers/provider-trust.ts +114 -0
  345. package/src/providers/read-chat-contract.ts +76 -16
  346. package/src/providers/sdk/README.md +49 -0
  347. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  348. package/src/providers/sdk/v1/builders/cli/detect-status.ts +313 -0
  349. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  350. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
  351. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  352. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  353. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  354. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  355. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  356. package/src/providers/sdk/v1/index.ts +152 -0
  357. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  358. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  359. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  360. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
  361. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  362. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  363. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  364. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  365. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  366. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  367. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  368. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  369. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  370. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  371. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  372. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  373. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  374. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  375. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  376. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  377. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  378. package/src/providers/sdk/v1/types/common/index.ts +229 -0
  379. package/src/providers/sdk/v1/validators/index.ts +19 -0
  380. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  381. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  382. package/src/providers/spec/adapter.ts +235 -0
  383. package/src/providers/spec/cli-adapter.ts +1056 -0
  384. package/src/providers/spec/evaluator.ts +407 -0
  385. package/src/providers/spec/fsm-driver.ts +1304 -0
  386. package/src/providers/spec/fsm-evaluator.ts +272 -0
  387. package/src/providers/spec/fsm-loader.ts +120 -0
  388. package/src/providers/spec/fsm-types.ts +273 -0
  389. package/src/providers/spec/native-history-executor.ts +1128 -0
  390. package/src/providers/spec/pre-launch-trust.ts +104 -0
  391. package/src/providers/spec/route.ts +51 -0
  392. package/src/providers/spec/types.ts +262 -0
  393. package/src/providers/status-monitor.d.ts +7 -7
  394. package/src/providers/status-monitor.ts +37 -22
  395. package/src/providers/transcript-v2.ts +567 -0
  396. package/src/providers/types/interactive-prompt.ts +536 -0
  397. package/src/providers/version-archive.ts +64 -24
  398. package/src/providers/working-dir.ts +23 -0
  399. package/src/repo-mesh-types.ts +629 -14
  400. package/src/runtime-defaults.ts +39 -0
  401. package/src/sessions/registry.ts +6 -0
  402. package/src/shared-types-extra.ts +2 -4
  403. package/src/shared-types.d.ts +8 -0
  404. package/src/shared-types.ts +64 -1
  405. package/src/status/builders.ts +26 -6
  406. package/src/status/normalize.ts +2 -0
  407. package/src/status/reporter.ts +19 -1
  408. package/src/status/snapshot.ts +95 -26
  409. package/src/system/hash.ts +23 -0
  410. package/src/system/host-memory.ts +29 -12
  411. package/src/system/load-better-sqlite3.ts +68 -0
  412. package/src/types.ts +5 -0
  413. package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
  414. package/dist/mesh/mesh-sync.d.ts +0 -53
  415. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
  416. package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
  417. package/src/mesh/mesh-sync.ts +0 -111
@@ -8,7 +8,8 @@
8
8
 
9
9
  import { existsSync, readFileSync, writeFileSync } from 'fs';
10
10
  import { join } from 'path';
11
- import { randomUUID } from 'crypto';
11
+ import { randomBytes, randomUUID } from 'crypto';
12
+ import { shortHash } from '../system/hash.js';
12
13
  import { getConfigDir } from './config.js';
13
14
  import type {
14
15
  LocalMeshConfig,
@@ -18,8 +19,11 @@ import type {
18
19
  RepoMeshNodePolicy,
19
20
  RepoMeshNodeCapabilities,
20
21
  RepoMeshCoordinatorConfig,
22
+ RepoMeshHostMetadata,
23
+ RepoMeshDaemonRole,
21
24
  } from '../repo-mesh-types.js';
22
- import { DEFAULT_MESH_POLICY } from '../repo-mesh-types.js';
25
+ import { mergeAndNormalizePolicy } from '../repo-mesh-types.js';
26
+ import { createDefaultMeshHostMetadata } from '../mesh/mesh-host-ownership.js';
23
27
 
24
28
  // ─── Persistence ────────────────────────────────
25
29
 
@@ -33,12 +37,85 @@ function loadMeshConfig(): LocalMeshConfig {
33
37
  try {
34
38
  const raw = JSON.parse(readFileSync(path, 'utf-8'));
35
39
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
36
- return raw as LocalMeshConfig;
40
+ const config = raw as LocalMeshConfig;
41
+ const migrated = migrateLoadedMeshConfig(config);
42
+ // Persist eagerly when the on-load migration changed anything, so the
43
+ // dead field is gone from disk even on a pure-read path (mesh_status /
44
+ // mesh_list_nodes) that never otherwise mutates the config. Best-effort:
45
+ // a write failure (e.g. read-only fs) must not break reads, so swallow.
46
+ if (migrated) {
47
+ try {
48
+ saveMeshConfig(config);
49
+ } catch {
50
+ // keep the in-memory strip; disk converges on the next mutating op
51
+ }
52
+ }
53
+ return config;
37
54
  } catch {
38
55
  return { meshes: [] };
39
56
  }
40
57
  }
41
58
 
59
+ /**
60
+ * In-place migration applied to every loaded meshes.json. Strips data that
61
+ * outlived the feature that wrote it so the persisted config converges on the
62
+ * current schema the next time it is saved.
63
+ *
64
+ * Currently: drops the dead `role` field from each node policy's providerRoles
65
+ * entries. providerRoles is retained for its `maxParallel` per-(node, provider)
66
+ * cap, but the routing `role` was removed (routing is governed solely by
67
+ * required_tags). A meshes.json written before the removal still carries
68
+ * `role: "validator"` etc.; this drops it on load so mesh_status / mesh_list_nodes
69
+ * never surface the dead field and the next saveMeshConfig() persists it gone.
70
+ *
71
+ * Returns true when the config was mutated (caller may persist eagerly).
72
+ */
73
+ function migrateLoadedMeshConfig(config: LocalMeshConfig): boolean {
74
+ let changed = false;
75
+ for (const mesh of config.meshes) {
76
+ if (!mesh || !Array.isArray(mesh.nodes)) continue;
77
+ for (const node of mesh.nodes) {
78
+ if (stripDeadRoleFromProviderRoles(node?.policy)) changed = true;
79
+ }
80
+ }
81
+ return changed;
82
+ }
83
+
84
+ /**
85
+ * Drop the legacy `role` field from each providerRoles entry of a node policy,
86
+ * in place. Keeps providerType + maxParallel (the still-meaningful per-(node,
87
+ * provider) cap). Defensive against malformed entries — non-object items are
88
+ * left untouched. Returns true when at least one `role` field was removed.
89
+ */
90
+ function stripDeadRoleFromProviderRoles(policy: unknown): boolean {
91
+ if (!policy || typeof policy !== 'object') return false;
92
+ const roles = (policy as { providerRoles?: unknown }).providerRoles;
93
+ if (!Array.isArray(roles)) return false;
94
+ let changed = false;
95
+ for (const entry of roles) {
96
+ if (entry && typeof entry === 'object' && !Array.isArray(entry)
97
+ && Object.prototype.hasOwnProperty.call(entry, 'role')) {
98
+ delete (entry as Record<string, unknown>).role;
99
+ changed = true;
100
+ }
101
+ }
102
+ return changed;
103
+ }
104
+
105
+ function normalizeCapabilityTags(value: unknown): string[] | undefined {
106
+ if (!Array.isArray(value)) return undefined;
107
+ const seen = new Set<string>();
108
+ const tags = value
109
+ .map(tag => typeof tag === 'string' ? tag.trim() : '')
110
+ .filter(Boolean)
111
+ .filter(tag => {
112
+ if (seen.has(tag)) return false;
113
+ seen.add(tag);
114
+ return true;
115
+ });
116
+ return tags.length ? tags : undefined;
117
+ }
118
+
42
119
  function saveMeshConfig(config: LocalMeshConfig): void {
43
120
  const path = getMeshConfigPath();
44
121
  writeFileSync(path, JSON.stringify(config, null, 2), { encoding: 'utf-8', mode: 0o600 });
@@ -74,24 +151,11 @@ export function normalizeRepoIdentity(remoteUrl: string): string {
74
151
 
75
152
  // ─── CRUD Operations ────────────────────────────
76
153
 
77
- const SESSION_CLEANUP_MODES = new Set(['preserve', 'stop', 'delete_stopped', 'stop_and_delete']);
78
- const SPAWNED_SESSION_VISIBILITY_MODES = new Set(['visible', 'hidden']);
79
-
80
- function mergeMeshPolicy(base: RepoMeshPolicy | undefined, patch: Partial<RepoMeshPolicy> | undefined): RepoMeshPolicy {
81
- const policy: RepoMeshPolicy = { ...DEFAULT_MESH_POLICY, ...(base || {}), ...(patch || {}) };
82
- if (!['block', 'warn', 'checkpoint_then_continue'].includes(policy.dirtyWorkspaceBehavior)) {
83
- policy.dirtyWorkspaceBehavior = 'warn';
84
- }
85
- const maxParallelTasks = Number(policy.maxParallelTasks);
86
- policy.maxParallelTasks = Number.isFinite(maxParallelTasks) ? Math.max(1, Math.min(8, Math.floor(maxParallelTasks))) : 2;
87
- if (!SESSION_CLEANUP_MODES.has(String(policy.sessionCleanupOnNodeRemove))) {
88
- policy.sessionCleanupOnNodeRemove = 'preserve';
89
- }
90
- if (!SPAWNED_SESSION_VISIBILITY_MODES.has(String(policy.spawnedSessionVisibility))) {
91
- policy.spawnedSessionVisibility = 'visible';
92
- }
93
- return policy;
94
- }
154
+ // Single source of truth for default+merge+per-field normalization is
155
+ // mergeAndNormalizePolicy in repo-mesh-types.ts. This thin alias keeps the local
156
+ // call sites (createMesh/updateMesh) reading naturally while ensuring config
157
+ // writes go through the exact same normalizer the scheduler/display paths use.
158
+ const mergeMeshPolicy = mergeAndNormalizePolicy;
95
159
 
96
160
  export function listMeshes(): LocalMeshEntry[] {
97
161
  return loadMeshConfig().meshes;
@@ -112,6 +176,7 @@ export interface CreateMeshOptions {
112
176
  defaultBranch?: string;
113
177
  policy?: Partial<RepoMeshPolicy>;
114
178
  coordinator?: RepoMeshCoordinatorConfig;
179
+ meshHost?: RepoMeshHostMetadata;
115
180
  }
116
181
 
117
182
  export function createMesh(opts: CreateMeshOptions): LocalMeshEntry {
@@ -133,6 +198,7 @@ export function createMesh(opts: CreateMeshOptions): LocalMeshEntry {
133
198
  defaultBranch: opts.defaultBranch,
134
199
  policy: mergeMeshPolicy(undefined, opts.policy),
135
200
  coordinator: opts.coordinator || {},
201
+ meshHost: opts.meshHost || createDefaultMeshHostMetadata(),
136
202
  nodes: [],
137
203
  createdAt: now,
138
204
  updatedAt: now,
@@ -148,6 +214,7 @@ export interface UpdateMeshOptions {
148
214
  defaultBranch?: string;
149
215
  policy?: Partial<RepoMeshPolicy>;
150
216
  coordinator?: RepoMeshCoordinatorConfig;
217
+ meshHost?: RepoMeshHostMetadata;
151
218
  }
152
219
 
153
220
  export function updateMesh(meshId: string, opts: UpdateMeshOptions): LocalMeshEntry | undefined {
@@ -159,6 +226,7 @@ export function updateMesh(meshId: string, opts: UpdateMeshOptions): LocalMeshEn
159
226
  if (opts.defaultBranch !== undefined) mesh.defaultBranch = opts.defaultBranch;
160
227
  if (opts.policy) mesh.policy = mergeMeshPolicy(mesh.policy, opts.policy);
161
228
  if (opts.coordinator) mesh.coordinator = opts.coordinator;
229
+ if (opts.meshHost) mesh.meshHost = opts.meshHost;
162
230
  mesh.updatedAt = new Date().toISOString();
163
231
 
164
232
  saveMeshConfig(config);
@@ -174,6 +242,240 @@ export function deleteMesh(meshId: string): boolean {
174
242
  return true;
175
243
  }
176
244
 
245
+ function normalizeManualHostAddress(hostAddress: string): string {
246
+ const normalized = hostAddress.trim().replace(/\/+$/, '');
247
+ if (!normalized) throw new Error('hostAddress required');
248
+ let parsed: URL;
249
+ try {
250
+ parsed = new URL(normalized);
251
+ } catch {
252
+ throw new Error('hostAddress must be a valid http(s) or ws(s) URL');
253
+ }
254
+ if (!['http:', 'https:', 'ws:', 'wss:'].includes(parsed.protocol)) {
255
+ throw new Error('hostAddress must use http, https, ws, or wss');
256
+ }
257
+ return normalized;
258
+ }
259
+
260
+ export function tokenIdForManualPairing(token: string): string {
261
+ return `tok_${shortHash(token)}`;
262
+ }
263
+
264
+ function normalizeTokenExpiry(value: unknown): string | undefined {
265
+ if (typeof value !== 'string' || !value.trim()) return undefined;
266
+ const date = new Date(value);
267
+ if (Number.isNaN(date.getTime())) throw new Error('expiresAt must be a valid ISO date');
268
+ return date.toISOString();
269
+ }
270
+
271
+ function assertPairingTokenValid(pairing: RepoMeshHostMetadata['pairing'], rawToken: string, nowIso: string): { ok: true; tokenId: string } | { ok: false; reason: string; expectedTokenId?: string; presentedTokenId?: string } {
272
+ const token = rawToken.trim();
273
+ if (!token) return { ok: false, reason: 'token required' };
274
+ const presentedTokenId = tokenIdForManualPairing(token);
275
+ const expectedTokenId = pairing?.tokenId;
276
+ if (!expectedTokenId || pairing?.status === 'not_configured' || pairing?.status === 'revoked') {
277
+ return { ok: false, reason: 'host pairing token is not configured', presentedTokenId };
278
+ }
279
+ if (pairing.expiresAt && new Date(pairing.expiresAt).getTime() <= new Date(nowIso).getTime()) {
280
+ return { ok: false, reason: 'host pairing token expired', expectedTokenId, presentedTokenId };
281
+ }
282
+ if (presentedTokenId !== expectedTokenId) {
283
+ return { ok: false, reason: 'invalid pairing token', expectedTokenId, presentedTokenId };
284
+ }
285
+ return { ok: true, tokenId: presentedTokenId };
286
+ }
287
+
288
+ export interface ConfigureMeshHostPairingOptions {
289
+ hostAddress: string;
290
+ token: string;
291
+ now?: string;
292
+ }
293
+
294
+ export function configureMeshHostPairing(
295
+ meshId: string,
296
+ opts: ConfigureMeshHostPairingOptions,
297
+ ): { mesh: LocalMeshEntry; meshHost: RepoMeshHostMetadata; hostAddress: string } | undefined {
298
+ const hostAddress = normalizeManualHostAddress(opts.hostAddress);
299
+ const token = opts.token.trim();
300
+ if (!token) throw new Error('token required');
301
+
302
+ const config = loadMeshConfig();
303
+ const mesh = config.meshes.find(m => m.id === meshId);
304
+ if (!mesh) return undefined;
305
+
306
+ const now = opts.now || new Date().toISOString();
307
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
308
+ const meshHost: RepoMeshHostMetadata = {
309
+ ...previous,
310
+ role: 'member',
311
+ hostAddress,
312
+ pairing: {
313
+ status: 'pairing',
314
+ tokenId: tokenIdForManualPairing(token),
315
+ lastPairedAt: now,
316
+ },
317
+ };
318
+
319
+ mesh.meshHost = meshHost;
320
+ mesh.updatedAt = now;
321
+ saveMeshConfig(config);
322
+ return { mesh, meshHost, hostAddress };
323
+ }
324
+
325
+ export interface CreateMeshHostPairingTokenOptions {
326
+ token?: string;
327
+ expiresAt?: string;
328
+ now?: string;
329
+ }
330
+
331
+ export function createMeshHostPairingToken(
332
+ meshId: string,
333
+ opts: CreateMeshHostPairingTokenOptions = {},
334
+ ): { mesh: LocalMeshEntry; meshHost: RepoMeshHostMetadata; token: string; tokenId: string; expiresAt?: string } | undefined {
335
+ const config = loadMeshConfig();
336
+ const mesh = config.meshes.find(m => m.id === meshId);
337
+ if (!mesh) return undefined;
338
+ const now = opts.now || new Date().toISOString();
339
+ const token = (opts.token || `mhj_${randomBytes(24).toString('base64url')}`).trim();
340
+ if (!token) throw new Error('token required');
341
+ const tokenId = tokenIdForManualPairing(token);
342
+ const expiresAt = normalizeTokenExpiry(opts.expiresAt);
343
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
344
+ if (previous.role === 'member') {
345
+ throw new Error('Mesh Host daemon required to create host pairing tokens; member daemons cannot mint host join tokens.');
346
+ }
347
+ const meshHost: RepoMeshHostMetadata = {
348
+ ...previous,
349
+ role: 'host',
350
+ pairing: {
351
+ status: 'pairing',
352
+ tokenId,
353
+ lastPairedAt: now,
354
+ ...(expiresAt ? { expiresAt } : {}),
355
+ },
356
+ };
357
+ mesh.meshHost = meshHost;
358
+ mesh.updatedAt = now;
359
+ saveMeshConfig(config);
360
+ return { mesh, meshHost, token, tokenId, ...(expiresAt ? { expiresAt } : {}) };
361
+ }
362
+
363
+ export interface MeshHostJoinMemberNodeInput {
364
+ id?: string;
365
+ workspace: string;
366
+ repoRoot?: string;
367
+ daemonId?: string;
368
+ machineId?: string;
369
+ userOverrides?: Partial<RepoMeshNodeCapabilities>;
370
+ policy?: RepoMeshNodePolicy;
371
+ role?: RepoMeshDaemonRole;
372
+ }
373
+
374
+ export interface ApplyMeshHostJoinOptions {
375
+ token: string;
376
+ memberNode: MeshHostJoinMemberNodeInput;
377
+ memberMeshId?: string;
378
+ now?: string;
379
+ }
380
+
381
+ export function applyMeshHostJoinRequest(
382
+ meshId: string,
383
+ opts: ApplyMeshHostJoinOptions,
384
+ ): { accepted: true; mesh: LocalMeshEntry; meshHost: RepoMeshHostMetadata; node: LocalMeshNodeEntry; tokenId: string } | { accepted: false; mesh?: LocalMeshEntry; meshHost?: RepoMeshHostMetadata; tokenId?: string; reason: string } | undefined {
385
+ const config = loadMeshConfig();
386
+ const mesh = config.meshes.find(m => m.id === meshId);
387
+ if (!mesh) return undefined;
388
+ const now = opts.now || new Date().toISOString();
389
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
390
+ if (previous.role === 'member') {
391
+ return { accepted: false, mesh, meshHost: previous, reason: 'Mesh Host daemon required to accept join requests' };
392
+ }
393
+ const meshHost: RepoMeshHostMetadata = { ...previous, role: 'host' };
394
+ const validation = assertPairingTokenValid(meshHost.pairing, opts.token, now);
395
+ if (!validation.ok) {
396
+ mesh.meshHost = {
397
+ ...meshHost,
398
+ pairing: {
399
+ ...(meshHost.pairing || { status: 'not_configured' as const }),
400
+ status: 'rejected',
401
+ lastRejectedAt: now,
402
+ },
403
+ };
404
+ mesh.updatedAt = now;
405
+ saveMeshConfig(config);
406
+ return { accepted: false, mesh, meshHost: mesh.meshHost, tokenId: validation.presentedTokenId, reason: validation.reason };
407
+ }
408
+
409
+ const workspace = opts.memberNode.workspace.trim();
410
+ if (!workspace) throw new Error('memberNode.workspace required');
411
+ const memberId = opts.memberNode.id?.trim();
412
+ let node = mesh.nodes.find(n => (memberId && n.id === memberId) || n.workspace === workspace);
413
+ if (node) {
414
+ node.workspace = workspace;
415
+ node.repoRoot = opts.memberNode.repoRoot;
416
+ node.daemonId = opts.memberNode.daemonId;
417
+ node.machineId = opts.memberNode.machineId;
418
+ node.userOverrides = opts.memberNode.userOverrides || node.userOverrides || {};
419
+ node.policy = { ...(node.policy || {}), ...(opts.memberNode.policy || {}) };
420
+ node.role = 'member';
421
+ } else {
422
+ if (mesh.nodes.length >= 10) throw new Error('Maximum 10 nodes per mesh');
423
+ node = {
424
+ id: memberId || `node_${randomUUID().replace(/-/g, '')}`,
425
+ workspace,
426
+ repoRoot: opts.memberNode.repoRoot,
427
+ daemonId: opts.memberNode.daemonId,
428
+ machineId: opts.memberNode.machineId,
429
+ userOverrides: opts.memberNode.userOverrides || {},
430
+ policy: opts.memberNode.policy || {},
431
+ role: 'member',
432
+ };
433
+ mesh.nodes.push(node);
434
+ }
435
+ mesh.meshHost = {
436
+ ...meshHost,
437
+ pairing: {
438
+ ...(meshHost.pairing || {}),
439
+ status: 'paired',
440
+ tokenId: validation.tokenId,
441
+ joinedAt: now,
442
+ lastPairedAt: meshHost.pairing?.lastPairedAt || now,
443
+ ...(meshHost.pairing?.expiresAt ? { expiresAt: meshHost.pairing.expiresAt } : {}),
444
+ },
445
+ };
446
+ mesh.updatedAt = now;
447
+ saveMeshConfig(config);
448
+ return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
449
+ }
450
+
451
+ export function markMeshHostPairingJoined(
452
+ meshId: string,
453
+ opts: { hostDaemonId?: string; hostNodeId?: string; joinedAt?: string; token?: string; tokenId?: string },
454
+ ): { mesh: LocalMeshEntry; meshHost: RepoMeshHostMetadata } | undefined {
455
+ const config = loadMeshConfig();
456
+ const mesh = config.meshes.find(m => m.id === meshId);
457
+ if (!mesh) return undefined;
458
+ const now = opts.joinedAt || new Date().toISOString();
459
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
460
+ const tokenId = opts.tokenId || (opts.token ? tokenIdForManualPairing(opts.token) : previous.pairing?.tokenId);
461
+ mesh.meshHost = {
462
+ ...previous,
463
+ role: 'member',
464
+ ...(opts.hostDaemonId ? { hostDaemonId: opts.hostDaemonId } : {}),
465
+ ...(opts.hostNodeId ? { hostNodeId: opts.hostNodeId } : {}),
466
+ pairing: {
467
+ ...(previous.pairing || {}),
468
+ status: 'paired',
469
+ ...(tokenId ? { tokenId } : {}),
470
+ joinedAt: now,
471
+ lastPairedAt: previous.pairing?.lastPairedAt || now,
472
+ },
473
+ };
474
+ mesh.updatedAt = now;
475
+ saveMeshConfig(config);
476
+ return { mesh, meshHost: mesh.meshHost };
477
+ }
478
+
177
479
  // ─── Node Operations ────────────────────────────
178
480
 
179
481
  export interface AddNodeOptions {
@@ -181,11 +483,14 @@ export interface AddNodeOptions {
181
483
  repoRoot?: string;
182
484
  daemonId?: string;
183
485
  machineId?: string;
486
+ capabilities?: string[];
184
487
  userOverrides?: Partial<RepoMeshNodeCapabilities>;
185
488
  policy?: RepoMeshNodePolicy;
186
489
  isLocalWorktree?: boolean;
187
490
  worktreeBranch?: string;
188
491
  clonedFromNodeId?: string;
492
+ worktreeBootstrap?: LocalMeshNodeEntry['worktreeBootstrap'];
493
+ role?: RepoMeshDaemonRole;
189
494
  }
190
495
 
191
496
  export function addNode(meshId: string, opts: AddNodeOptions): LocalMeshNodeEntry | undefined {
@@ -208,11 +513,14 @@ export function addNode(meshId: string, opts: AddNodeOptions): LocalMeshNodeEntr
208
513
  repoRoot: opts.repoRoot,
209
514
  daemonId: opts.daemonId,
210
515
  machineId: opts.machineId,
516
+ capabilities: normalizeCapabilityTags(opts.capabilities),
211
517
  userOverrides: opts.userOverrides || {},
212
518
  policy: opts.policy || {},
213
519
  isLocalWorktree: opts.isLocalWorktree,
214
520
  worktreeBranch: opts.worktreeBranch,
215
521
  clonedFromNodeId: opts.clonedFromNodeId,
522
+ worktreeBootstrap: opts.worktreeBootstrap,
523
+ role: opts.role,
216
524
  };
217
525
 
218
526
  mesh.nodes.push(node);
@@ -238,7 +546,19 @@ export function removeNode(meshId: string, nodeId: string): boolean {
238
546
  export function updateNode(
239
547
  meshId: string,
240
548
  nodeId: string,
241
- opts: { userOverrides?: Partial<RepoMeshNodeCapabilities>; policy?: RepoMeshNodePolicy },
549
+ opts: {
550
+ userOverrides?: Partial<RepoMeshNodeCapabilities>;
551
+ policy?: RepoMeshNodePolicy;
552
+ worktreeBootstrap?: LocalMeshNodeEntry['worktreeBootstrap'];
553
+ /** Per-node instruction surfaced in the coordinator prompt. Pass an
554
+ * empty string or undefined to clear it. */
555
+ systemPrompt?: string;
556
+ /** Live self-reported platform/arch from the owning daemon's git_status
557
+ * envelope. Persisted distinctly from userOverrides (auto-detected, not
558
+ * operator intent) so capability-tag os=/arch= self-heals across loads. */
559
+ reportedPlatform?: string;
560
+ reportedArch?: string;
561
+ },
242
562
  ): LocalMeshNodeEntry | undefined {
243
563
  const config = loadMeshConfig();
244
564
  const mesh = config.meshes.find(m => m.id === meshId);
@@ -248,7 +568,18 @@ export function updateNode(
248
568
  if (!node) return undefined;
249
569
 
250
570
  if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
571
+ if (opts.reportedPlatform && opts.reportedPlatform.trim()) node.reportedPlatform = opts.reportedPlatform.trim();
572
+ if (opts.reportedArch && opts.reportedArch.trim()) node.reportedArch = opts.reportedArch.trim();
251
573
  if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
574
+ if (opts.worktreeBootstrap) node.worktreeBootstrap = opts.worktreeBootstrap;
575
+ if (Object.prototype.hasOwnProperty.call(opts, 'systemPrompt')) {
576
+ // Honor explicit clears: { systemPrompt: undefined } drops the field.
577
+ if (opts.systemPrompt && opts.systemPrompt.trim()) {
578
+ node.systemPrompt = opts.systemPrompt;
579
+ } else {
580
+ delete node.systemPrompt;
581
+ }
582
+ }
252
583
  mesh.updatedAt = new Date().toISOString();
253
584
  saveMeshConfig(config);
254
585
  return node;