borgmcp 1.1.15 → 2.0.2

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 (466) hide show
  1. package/CONTRIBUTING.md +15 -0
  2. package/LICENSE +201 -33
  3. package/NOTICE +2 -0
  4. package/README.md +85 -36
  5. package/SECURITY.md +7 -0
  6. package/dist/agent-runtime.d.ts.map +1 -0
  7. package/dist/agent-runtime.js +63 -1
  8. package/dist/agent-runtime.js.map +1 -0
  9. package/dist/assimilate-cmd.d.ts +96 -17
  10. package/dist/assimilate-cmd.d.ts.map +1 -0
  11. package/dist/assimilate-cmd.js +1396 -48
  12. package/dist/assimilate-cmd.js.map +1 -0
  13. package/dist/assimilate-deps.d.ts.map +1 -0
  14. package/dist/assimilate-deps.js +384 -3
  15. package/dist/assimilate-deps.js.map +1 -0
  16. package/dist/assimilate-guard.d.ts +5 -7
  17. package/dist/assimilate-guard.d.ts.map +1 -0
  18. package/dist/assimilate-guard.js +60 -2
  19. package/dist/assimilate-guard.js.map +1 -0
  20. package/dist/assimilate-welcome.d.ts +1 -1
  21. package/dist/assimilate-welcome.d.ts.map +1 -0
  22. package/dist/assimilate-welcome.js +32 -2
  23. package/dist/assimilate-welcome.js.map +1 -0
  24. package/dist/auth-env.d.ts +7 -50
  25. package/dist/auth-env.d.ts.map +1 -0
  26. package/dist/auth-env.js +22 -1
  27. package/dist/auth-env.js.map +1 -0
  28. package/dist/backends/launch-all-pastelist.d.ts.map +1 -0
  29. package/dist/backends/launch-all-pastelist.js +11 -4
  30. package/dist/backends/launch-all-pastelist.js.map +1 -0
  31. package/dist/backends/launch-all-tmux.d.ts.map +1 -0
  32. package/dist/backends/launch-all-tmux.js +49 -1
  33. package/dist/backends/launch-all-tmux.js.map +1 -0
  34. package/dist/backends/launch-all-windows.d.ts.map +1 -0
  35. package/dist/backends/launch-all-windows.js +86 -12
  36. package/dist/backends/launch-all-windows.js.map +1 -0
  37. package/dist/bare-launch-menu.d.ts.map +1 -0
  38. package/dist/bare-launch-menu.js +83 -6
  39. package/dist/bare-launch-menu.js.map +1 -0
  40. package/dist/claude-launch-args.d.ts.map +1 -0
  41. package/dist/claude-launch-args.js +34 -1
  42. package/dist/claude-launch-args.js.map +1 -0
  43. package/dist/claude.d.ts.map +1 -0
  44. package/dist/claude.js +486 -14
  45. package/dist/claude.js.map +1 -0
  46. package/dist/cleanup-cmd.d.ts +5 -5
  47. package/dist/cleanup-cmd.d.ts.map +1 -0
  48. package/dist/cleanup-cmd.js +453 -14
  49. package/dist/cleanup-cmd.js.map +1 -0
  50. package/dist/clear-rewake-core.d.ts.map +1 -0
  51. package/dist/clear-rewake-core.js +23 -2
  52. package/dist/clear-rewake-core.js.map +1 -0
  53. package/dist/clear-rewake.d.ts.map +1 -0
  54. package/dist/clear-rewake.js +19 -1
  55. package/dist/clear-rewake.js.map +1 -0
  56. package/dist/cli-help.d.ts +5 -0
  57. package/dist/cli-help.d.ts.map +1 -0
  58. package/dist/cli-help.js +104 -56
  59. package/dist/cli-help.js.map +1 -0
  60. package/dist/cli-platform.d.ts.map +1 -0
  61. package/dist/cli-platform.js +106 -4
  62. package/dist/cli-platform.js.map +1 -0
  63. package/dist/cli-tool-approval.d.ts +84 -0
  64. package/dist/cli-tool-approval.d.ts.map +1 -0
  65. package/dist/cli-tool-approval.js +583 -0
  66. package/dist/cli-tool-approval.js.map +1 -0
  67. package/dist/codex-app-server.d.ts.map +1 -0
  68. package/dist/codex-app-server.js +228 -4
  69. package/dist/codex-app-server.js.map +1 -0
  70. package/dist/codex-app-wake.d.ts +9 -11
  71. package/dist/codex-app-wake.d.ts.map +1 -0
  72. package/dist/codex-app-wake.js +436 -2
  73. package/dist/codex-app-wake.js.map +1 -0
  74. package/dist/codex-launch.d.ts.map +1 -0
  75. package/dist/codex-launch.js +102 -2
  76. package/dist/codex-launch.js.map +1 -0
  77. package/dist/codex-remote.d.ts +6 -1
  78. package/dist/codex-remote.d.ts.map +1 -0
  79. package/dist/codex-remote.js +394 -1
  80. package/dist/codex-remote.js.map +1 -0
  81. package/dist/codex-wake-resolve.d.ts +4 -4
  82. package/dist/codex-wake-resolve.d.ts.map +1 -0
  83. package/dist/codex-wake-resolve.js +127 -1
  84. package/dist/codex-wake-resolve.js.map +1 -0
  85. package/dist/config-utils.d.ts +2 -2
  86. package/dist/config-utils.d.ts.map +1 -0
  87. package/dist/config-utils.js +766 -3
  88. package/dist/config-utils.js.map +1 -0
  89. package/dist/config.d.ts +98 -61
  90. package/dist/config.d.ts.map +1 -0
  91. package/dist/config.js +426 -1
  92. package/dist/config.js.map +1 -0
  93. package/dist/console-prefix.d.ts.map +1 -0
  94. package/dist/console-prefix.js +96 -1
  95. package/dist/console-prefix.js.map +1 -0
  96. package/dist/cube-name.d.ts.map +1 -0
  97. package/dist/cube-name.js +67 -1
  98. package/dist/cube-name.js.map +1 -0
  99. package/dist/cubes.d.ts +126 -18
  100. package/dist/cubes.d.ts.map +1 -0
  101. package/dist/cubes.js +412 -4
  102. package/dist/cubes.js.map +1 -0
  103. package/dist/debug.d.ts.map +1 -0
  104. package/dist/debug.js +71 -1
  105. package/dist/debug.js.map +1 -0
  106. package/dist/direct-log.d.ts.map +1 -0
  107. package/dist/direct-log.js +11 -1
  108. package/dist/direct-log.js.map +1 -0
  109. package/dist/docs-sections.d.ts +11 -10
  110. package/dist/docs-sections.d.ts.map +1 -0
  111. package/dist/docs-sections.js +113 -3
  112. package/dist/docs-sections.js.map +1 -0
  113. package/dist/drone-lifecycle.d.ts +5 -21
  114. package/dist/drone-lifecycle.d.ts.map +1 -0
  115. package/dist/drone-lifecycle.js +57 -8
  116. package/dist/drone-lifecycle.js.map +1 -0
  117. package/dist/drone-management.d.ts +29 -0
  118. package/dist/drone-management.d.ts.map +1 -0
  119. package/dist/drone-management.js +109 -0
  120. package/dist/drone-management.js.map +1 -0
  121. package/dist/ensure-mcp-config.d.ts.map +1 -0
  122. package/dist/ensure-mcp-config.js +36 -1
  123. package/dist/ensure-mcp-config.js.map +1 -0
  124. package/dist/evict-drone.d.ts +10 -2
  125. package/dist/evict-drone.d.ts.map +1 -0
  126. package/dist/evict-drone.js +60 -1
  127. package/dist/evict-drone.js.map +1 -0
  128. package/dist/gc-orphan-inboxes.d.ts.map +1 -0
  129. package/dist/gc-orphan-inboxes.js +177 -1
  130. package/dist/gc-orphan-inboxes.js.map +1 -0
  131. package/dist/inbox-monitor.d.ts +1 -1
  132. package/dist/inbox-monitor.d.ts.map +1 -0
  133. package/dist/inbox-monitor.js +856 -3
  134. package/dist/inbox-monitor.js.map +1 -0
  135. package/dist/index.d.ts +6 -4
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +1034 -37
  138. package/dist/index.js.map +1 -0
  139. package/dist/launch-all-cmd.d.ts.map +1 -0
  140. package/dist/launch-all-cmd.js +377 -37
  141. package/dist/launch-all-cmd.js.map +1 -0
  142. package/dist/launch-all-command.d.ts.map +1 -0
  143. package/dist/launch-all-command.js +24 -1
  144. package/dist/launch-all-command.js.map +1 -0
  145. package/dist/launch-all-deps.d.ts +3 -8
  146. package/dist/launch-all-deps.d.ts.map +1 -0
  147. package/dist/launch-all-deps.js +99 -1
  148. package/dist/launch-all-deps.js.map +1 -0
  149. package/dist/launch-all-discovery.d.ts +1 -0
  150. package/dist/launch-all-discovery.d.ts.map +1 -0
  151. package/dist/launch-all-discovery.js +90 -4
  152. package/dist/launch-all-discovery.js.map +1 -0
  153. package/dist/launch-all-locks.d.ts.map +1 -0
  154. package/dist/launch-all-locks.js +54 -1
  155. package/dist/launch-all-locks.js.map +1 -0
  156. package/dist/launch-gate.d.ts +2 -2
  157. package/dist/launch-gate.d.ts.map +1 -0
  158. package/dist/launch-gate.js +73 -1
  159. package/dist/launch-gate.js.map +1 -0
  160. package/dist/lifecycle-log-guard.d.ts.map +1 -0
  161. package/dist/lifecycle-log-guard.js +93 -2
  162. package/dist/lifecycle-log-guard.js.map +1 -0
  163. package/dist/list-roles-render.d.ts.map +1 -0
  164. package/dist/list-roles-render.js +40 -6
  165. package/dist/list-roles-render.js.map +1 -0
  166. package/dist/local-log-routing.d.ts +19 -0
  167. package/dist/local-log-routing.d.ts.map +1 -0
  168. package/dist/local-log-routing.js +67 -0
  169. package/dist/local-log-routing.js.map +1 -0
  170. package/dist/local-manage-tool-result.d.ts +8 -0
  171. package/dist/local-manage-tool-result.d.ts.map +1 -0
  172. package/dist/local-manage-tool-result.js +10 -0
  173. package/dist/local-manage-tool-result.js.map +1 -0
  174. package/dist/local-server-cursor.d.ts +34 -0
  175. package/dist/local-server-cursor.d.ts.map +1 -0
  176. package/dist/local-server-cursor.js +151 -0
  177. package/dist/local-server-cursor.js.map +1 -0
  178. package/dist/log-audit.d.ts.map +1 -0
  179. package/dist/log-audit.js +194 -3
  180. package/dist/log-audit.js.map +1 -0
  181. package/dist/log-stream.d.ts +35 -18
  182. package/dist/log-stream.d.ts.map +1 -0
  183. package/dist/log-stream.js +1270 -12
  184. package/dist/log-stream.js.map +1 -0
  185. package/dist/model-presets.d.ts.map +1 -0
  186. package/dist/model-presets.js +19 -1
  187. package/dist/model-presets.js.map +1 -0
  188. package/dist/name-validator.d.ts.map +1 -0
  189. package/dist/name-validator.js +22 -1
  190. package/dist/name-validator.js.map +1 -0
  191. package/dist/opencode-drone.d.ts.map +1 -0
  192. package/dist/opencode-drone.js +438 -4
  193. package/dist/opencode-drone.js.map +1 -0
  194. package/dist/opencode-plugin.d.ts +1 -1
  195. package/dist/opencode-plugin.d.ts.map +1 -0
  196. package/dist/opencode-plugin.js +29 -4
  197. package/dist/opencode-plugin.js.map +1 -0
  198. package/dist/parse-assimilate-args.d.ts +1 -1
  199. package/dist/parse-assimilate-args.d.ts.map +1 -0
  200. package/dist/parse-assimilate-args.js +125 -1
  201. package/dist/parse-assimilate-args.js.map +1 -0
  202. package/dist/parse-launch-all-args.d.ts.map +1 -0
  203. package/dist/parse-launch-all-args.js +70 -1
  204. package/dist/parse-launch-all-args.js.map +1 -0
  205. package/dist/postinstall-banner.d.ts.map +1 -0
  206. package/dist/postinstall-banner.js +27 -2
  207. package/dist/postinstall-banner.js.map +1 -0
  208. package/dist/postinstall.d.ts.map +1 -0
  209. package/dist/postinstall.js +32 -5
  210. package/dist/postinstall.js.map +1 -0
  211. package/dist/readiness-probe.d.ts.map +1 -0
  212. package/dist/readiness-probe.js +9 -1
  213. package/dist/readiness-probe.js.map +1 -0
  214. package/dist/regen-format.d.ts.map +1 -0
  215. package/dist/regen-format.js +545 -13
  216. package/dist/regen-format.js.map +1 -0
  217. package/dist/regen.d.ts.map +1 -0
  218. package/dist/regen.js +141 -5
  219. package/dist/regen.js.map +1 -0
  220. package/dist/remote-client.d.ts +88 -173
  221. package/dist/remote-client.d.ts.map +1 -0
  222. package/dist/remote-client.js +997 -1
  223. package/dist/remote-client.js.map +1 -0
  224. package/dist/reset-local-seat-cmd.d.ts +50 -0
  225. package/dist/reset-local-seat-cmd.d.ts.map +1 -0
  226. package/dist/reset-local-seat-cmd.js +169 -0
  227. package/dist/reset-local-seat-cmd.js.map +1 -0
  228. package/dist/role-match.d.ts.map +1 -0
  229. package/dist/role-match.js +23 -1
  230. package/dist/role-match.js.map +1 -0
  231. package/dist/role-resolver.d.ts.map +1 -0
  232. package/dist/role-resolver.js +60 -1
  233. package/dist/role-resolver.js.map +1 -0
  234. package/dist/roster-render.d.ts.map +1 -0
  235. package/dist/roster-render.js +121 -3
  236. package/dist/roster-render.js.map +1 -0
  237. package/dist/seat-probe.d.ts +32 -13
  238. package/dist/seat-probe.d.ts.map +1 -0
  239. package/dist/seat-probe.js +78 -1
  240. package/dist/seat-probe.js.map +1 -0
  241. package/dist/seat-store.d.ts +76 -0
  242. package/dist/seat-store.d.ts.map +1 -0
  243. package/dist/seat-store.js +309 -0
  244. package/dist/seat-store.js.map +1 -0
  245. package/dist/seats.d.ts +375 -0
  246. package/dist/seats.d.ts.map +1 -0
  247. package/dist/seats.js +670 -0
  248. package/dist/seats.js.map +1 -0
  249. package/dist/self-path.d.ts +27 -0
  250. package/dist/self-path.d.ts.map +1 -0
  251. package/dist/self-path.js +43 -0
  252. package/dist/self-path.js.map +1 -0
  253. package/dist/server-endpoint.d.ts +9 -0
  254. package/dist/server-endpoint.d.ts.map +1 -0
  255. package/dist/server-endpoint.js +38 -0
  256. package/dist/server-endpoint.js.map +1 -0
  257. package/dist/server-errors.d.ts +50 -0
  258. package/dist/server-errors.d.ts.map +1 -0
  259. package/dist/server-errors.js +79 -0
  260. package/dist/server-errors.js.map +1 -0
  261. package/dist/server-handshake.d.ts +197 -0
  262. package/dist/server-handshake.d.ts.map +1 -0
  263. package/dist/server-handshake.js +533 -0
  264. package/dist/server-handshake.js.map +1 -0
  265. package/dist/server-response.d.ts +3 -0
  266. package/dist/server-response.d.ts.map +1 -0
  267. package/dist/server-response.js +67 -0
  268. package/dist/server-response.js.map +1 -0
  269. package/dist/server-trust.d.ts +14 -0
  270. package/dist/server-trust.d.ts.map +1 -0
  271. package/dist/server-trust.js +225 -0
  272. package/dist/server-trust.js.map +1 -0
  273. package/dist/session-continuity.d.ts +33 -0
  274. package/dist/session-continuity.d.ts.map +1 -0
  275. package/dist/session-continuity.js +220 -0
  276. package/dist/session-continuity.js.map +1 -0
  277. package/dist/setup-confirm.d.ts +3 -3
  278. package/dist/setup-confirm.d.ts.map +1 -0
  279. package/dist/setup-confirm.js +126 -2
  280. package/dist/setup-confirm.js.map +1 -0
  281. package/dist/setup.d.ts +5 -3
  282. package/dist/setup.d.ts.map +1 -0
  283. package/dist/setup.js +169 -46
  284. package/dist/setup.js.map +1 -0
  285. package/dist/shell-escape.d.ts.map +1 -0
  286. package/dist/shell-escape.js +22 -1
  287. package/dist/shell-escape.js.map +1 -0
  288. package/dist/spawn.d.ts +2 -2
  289. package/dist/spawn.d.ts.map +1 -0
  290. package/dist/spawn.js +29 -10
  291. package/dist/spawn.js.map +1 -0
  292. package/dist/startup-services.d.ts +0 -1
  293. package/dist/startup-services.d.ts.map +1 -0
  294. package/dist/startup-services.js +26 -1
  295. package/dist/startup-services.js.map +1 -0
  296. package/dist/stream-owner.d.ts +6 -2
  297. package/dist/stream-owner.d.ts.map +1 -0
  298. package/dist/stream-owner.js +547 -2
  299. package/dist/stream-owner.js.map +1 -0
  300. package/dist/stream-status.d.ts +1 -1
  301. package/dist/stream-status.d.ts.map +1 -0
  302. package/dist/stream-status.js +268 -3
  303. package/dist/stream-status.js.map +1 -0
  304. package/dist/sync-roles-render.d.ts.map +1 -0
  305. package/dist/sync-roles-render.js +118 -3
  306. package/dist/sync-roles-render.js.map +1 -0
  307. package/dist/sync.d.ts +1 -1
  308. package/dist/sync.d.ts.map +1 -0
  309. package/dist/sync.js +286 -22
  310. package/dist/sync.js.map +1 -0
  311. package/dist/terminal-title.d.ts.map +1 -0
  312. package/dist/terminal-title.js +68 -1
  313. package/dist/terminal-title.js.map +1 -0
  314. package/dist/token-store.d.ts +17 -111
  315. package/dist/token-store.d.ts.map +1 -0
  316. package/dist/token-store.js +81 -1
  317. package/dist/token-store.js.map +1 -0
  318. package/dist/tool-manifest.d.ts +4 -8
  319. package/dist/tool-manifest.d.ts.map +1 -0
  320. package/dist/tool-manifest.js +554 -1
  321. package/dist/tool-manifest.js.map +1 -0
  322. package/dist/tool-scope.d.ts +8 -12
  323. package/dist/tool-scope.d.ts.map +1 -0
  324. package/dist/tool-scope.js +97 -1
  325. package/dist/tool-scope.js.map +1 -0
  326. package/dist/types.d.ts +1 -5
  327. package/dist/types.d.ts.map +1 -0
  328. package/dist/types.js +5 -0
  329. package/dist/types.js.map +1 -0
  330. package/dist/unknown-subcommand.d.ts +1 -1
  331. package/dist/unknown-subcommand.d.ts.map +1 -0
  332. package/dist/unknown-subcommand.js +37 -1
  333. package/dist/unknown-subcommand.js.map +1 -0
  334. package/dist/version.d.ts +1 -1
  335. package/dist/version.d.ts.map +1 -0
  336. package/dist/version.js +78 -2
  337. package/dist/version.js.map +1 -0
  338. package/dist/working-repo.d.ts.map +1 -0
  339. package/dist/working-repo.js +81 -1
  340. package/dist/working-repo.js.map +1 -0
  341. package/dist/worktree-lifecycle.d.ts.map +1 -0
  342. package/dist/worktree-lifecycle.js +205 -2
  343. package/dist/worktree-lifecycle.js.map +1 -0
  344. package/docs/EXTRACTION_PROVENANCE.md +42 -0
  345. package/docs/LOCAL_SERVER.md +103 -0
  346. package/docs/RELEASING.md +129 -0
  347. package/package.json +52 -34
  348. package/src/agent-runtime.ts +69 -0
  349. package/src/assimilate-cmd.ts +1864 -0
  350. package/src/assimilate-deps.ts +444 -0
  351. package/src/assimilate-guard.ts +84 -0
  352. package/src/assimilate-welcome.ts +39 -0
  353. package/src/auth-env.ts +21 -0
  354. package/src/backends/launch-all-pastelist.ts +18 -0
  355. package/src/backends/launch-all-tmux.ts +75 -0
  356. package/src/backends/launch-all-windows.ts +110 -0
  357. package/src/bare-launch-menu.ts +148 -0
  358. package/src/claude-launch-args.ts +35 -0
  359. package/src/claude.ts +561 -0
  360. package/src/cleanup-cmd.ts +581 -0
  361. package/src/clear-rewake-core.ts +34 -0
  362. package/src/clear-rewake.ts +18 -0
  363. package/src/cli-help.ts +116 -0
  364. package/src/cli-platform.ts +127 -0
  365. package/src/cli-tool-approval.ts +716 -0
  366. package/src/codex-app-server.ts +238 -0
  367. package/src/codex-app-wake.ts +524 -0
  368. package/src/codex-launch.ts +140 -0
  369. package/src/codex-remote.ts +500 -0
  370. package/src/codex-wake-resolve.ts +155 -0
  371. package/src/config-utils.ts +811 -0
  372. package/src/config.ts +595 -0
  373. package/src/console-prefix.ts +99 -0
  374. package/src/cube-name.ts +69 -0
  375. package/src/cubes.ts +583 -0
  376. package/src/debug.ts +73 -0
  377. package/src/direct-log.ts +9 -0
  378. package/src/docs-sections.ts +129 -0
  379. package/src/drone-lifecycle.ts +62 -0
  380. package/src/drone-management.ts +162 -0
  381. package/src/ensure-mcp-config.ts +54 -0
  382. package/src/evict-drone.ts +82 -0
  383. package/src/gc-orphan-inboxes.ts +229 -0
  384. package/src/inbox-monitor.ts +1005 -0
  385. package/src/index.ts +1201 -0
  386. package/src/launch-all-cmd.ts +450 -0
  387. package/src/launch-all-command.ts +30 -0
  388. package/src/launch-all-deps.ts +188 -0
  389. package/src/launch-all-discovery.ts +118 -0
  390. package/src/launch-all-locks.ts +74 -0
  391. package/src/launch-gate.ts +80 -0
  392. package/src/lifecycle-log-guard.ts +144 -0
  393. package/src/list-roles-render.ts +52 -0
  394. package/src/local-log-routing.ts +106 -0
  395. package/src/local-manage-tool-result.ts +10 -0
  396. package/src/local-server-cursor.ts +188 -0
  397. package/src/log-audit.ts +207 -0
  398. package/src/log-stream.ts +1567 -0
  399. package/src/model-presets.ts +22 -0
  400. package/src/name-validator.ts +23 -0
  401. package/src/opencode-drone.ts +528 -0
  402. package/src/opencode-plugin.ts +38 -0
  403. package/src/parse-assimilate-args.ts +125 -0
  404. package/src/parse-launch-all-args.ts +100 -0
  405. package/src/postinstall-banner.ts +37 -0
  406. package/src/postinstall.ts +36 -0
  407. package/src/readiness-probe.ts +12 -0
  408. package/src/regen-format.ts +651 -0
  409. package/src/regen.ts +150 -0
  410. package/src/remote-client.ts +1457 -0
  411. package/src/reset-local-seat-cmd.ts +227 -0
  412. package/src/role-match.ts +29 -0
  413. package/src/role-resolver.ts +93 -0
  414. package/src/roster-render.ts +196 -0
  415. package/src/seat-probe.ts +115 -0
  416. package/src/seat-store.ts +333 -0
  417. package/src/seats.ts +911 -0
  418. package/src/self-path.ts +51 -0
  419. package/src/server-endpoint.ts +38 -0
  420. package/src/server-errors.ts +95 -0
  421. package/src/server-handshake.ts +816 -0
  422. package/src/server-response.ts +76 -0
  423. package/src/server-trust.ts +245 -0
  424. package/src/session-continuity.ts +280 -0
  425. package/src/setup-confirm.ts +171 -0
  426. package/src/setup.ts +186 -0
  427. package/src/shell-escape.ts +22 -0
  428. package/src/spawn.ts +31 -0
  429. package/src/startup-services.ts +36 -0
  430. package/src/stream-owner.ts +686 -0
  431. package/src/stream-status.ts +337 -0
  432. package/src/sync-roles-render.ts +163 -0
  433. package/src/sync.ts +363 -0
  434. package/src/terminal-title.ts +76 -0
  435. package/src/token-store.ts +102 -0
  436. package/src/tool-manifest.ts +610 -0
  437. package/src/tool-scope.ts +110 -0
  438. package/src/types.ts +5 -0
  439. package/src/unknown-subcommand.ts +35 -0
  440. package/src/version.ts +82 -0
  441. package/src/working-repo.ts +99 -0
  442. package/src/worktree-lifecycle.ts +254 -0
  443. package/dist/auth-recovery.d.ts +0 -33
  444. package/dist/auth-recovery.js +0 -1
  445. package/dist/auth.d.ts +0 -103
  446. package/dist/auth.js +0 -39
  447. package/dist/device-auth.d.ts +0 -75
  448. package/dist/device-auth.js +0 -1
  449. package/dist/drone-address.d.ts +0 -26
  450. package/dist/drone-address.js +0 -1
  451. package/dist/get-started.d.ts +0 -20
  452. package/dist/get-started.js +0 -2
  453. package/dist/health-beat.d.ts +0 -134
  454. package/dist/health-beat.js +0 -1
  455. package/dist/role-section.d.ts +0 -110
  456. package/dist/role-section.js +0 -8
  457. package/dist/setup-action.d.ts +0 -20
  458. package/dist/setup-action.js +0 -1
  459. package/dist/stale-version-check.d.ts +0 -40
  460. package/dist/stale-version-check.js +0 -1
  461. package/dist/subscription-retry.d.ts +0 -40
  462. package/dist/subscription-retry.js +0 -1
  463. package/dist/templates.d.ts +0 -107
  464. package/dist/templates.js +0 -359
  465. package/dist/token-crypto.d.ts +0 -50
  466. package/dist/token-crypto.js +0 -1
@@ -1 +1,99 @@
1
- import{spawnSync as i}from"node:child_process";import{existsSync as n,mkdirSync as s,readFileSync as c,writeFileSync as u,unlinkSync as a,statSync as d,readdirSync as l}from"node:fs";import{homedir as p}from"node:os";import{createInterface as m}from"node:readline/promises";import{readAllProjectIdentities as f,getProjectCliPreferenceForPath as y,findProjectRoot as h,getActiveCube as g}from"./cubes.js";import{getRoster as w,getCube as S,getValidToken as P,API_URL as b}from"./remote-client.js";import{defaultProbeSeat as A}from"./seat-probe.js";function x(){return{runSync:(t,r,e)=>{const o=i(t,r,{encoding:"utf-8",cwd:e?.cwd});if(o.error)throw o.error;if(o.status!==0)throw new Error(`${t} exited ${o.status}: ${(o.stderr??"").toString().trim()}`);return(o.stdout??"").toString()},runSyncExitCode:(t,r)=>i(t,r,{encoding:"utf-8"}).status??1,attachInteractive:(t,r)=>{i(t,r,{stdio:"inherit"})},cwd:()=>process.cwd(),pathExists:t=>n(t),homedir:()=>p(),mkdirp:t=>{s(t,{recursive:!0})},readFileOpt:t=>{try{return c(t,"utf-8")}catch{return null}},writeFile:(t,r,e)=>{u(t,r,{mode:e??384})},unlinkOpt:t=>{try{a(t)}catch{}},statMtime:t=>{try{return d(t).mtimeMs}catch{return null}},listDir:t=>{try{return l(t)}catch{return[]}},getCachedAuth:async()=>{try{return{token:await P(),apiUrl:b}}catch{return null}},getRoster:(t,r,e)=>w(t,r,e),getCube:(t,r,e)=>S(e),probeSeat:(t,r)=>A(t,r),getCliPreferenceForPath:t=>y(t),readAllProjectIdentities:()=>f(),findProjectRoot:t=>h(t),getActiveCube:()=>g(),prompt:async t=>{const r=m({input:process.stdin,output:process.stdout});try{return(await r.question(t)).trim()}finally{r.close()}},isTTY:()=>process.stdin.isTTY===!0,getEnv:t=>process.env[t],platform:()=>process.platform,stderr:t=>{process.stderr.write(t)},stdout:t=>{process.stdout.write(t)}}}export{x as buildDefaultLaunchAllDeps};
1
+ // gh#556 Part 2 `borg launch-all [cube]` dependency seam.
2
+ //
3
+ // LaunchAllDeps is the full injectable seam list (per spec §10) so every
4
+ // pure module (discovery / parser / orchestrator / backends) is unit-testable
5
+ // with vi.fn() stubs. buildDefaultLaunchAllDeps() (added in launch-all-cmd
6
+ // wiring / Phase 4) wires the real-IO production modules.
7
+ import { spawnSync } from 'node:child_process';
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, statSync, readdirSync, } from 'node:fs';
9
+ import { homedir as osHomedir } from 'node:os';
10
+ import { createInterface } from 'node:readline/promises';
11
+ import { readAllProjectIdentities as cubesReadAllProjectIdentities, getProjectCliPreferenceForPath, findProjectRoot, getActiveCube, } from './cubes.js';
12
+ import { getRoster, getCube } from './remote-client.js';
13
+ import { defaultProbeSeat } from './seat-probe.js';
14
+ /** Real-IO factory wiring production modules (spec §10). Test code stubs LaunchAllDeps directly. */
15
+ export function buildDefaultLaunchAllDeps() {
16
+ return {
17
+ runSync: (cmd, args, opts) => {
18
+ const r = spawnSync(cmd, args, { encoding: 'utf-8', cwd: opts?.cwd });
19
+ if (r.error)
20
+ throw r.error;
21
+ if (r.status !== 0) {
22
+ throw new Error(`${cmd} exited ${r.status}: ${(r.stderr ?? '').toString().trim()}`);
23
+ }
24
+ return (r.stdout ?? '').toString();
25
+ },
26
+ runSyncExitCode: (cmd, args) => spawnSync(cmd, args, { encoding: 'utf-8' }).status ?? 1,
27
+ attachInteractive: (cmd, args) => {
28
+ spawnSync(cmd, args, { stdio: 'inherit' });
29
+ },
30
+ cwd: () => process.cwd(),
31
+ pathExists: (p) => existsSync(p),
32
+ homedir: () => osHomedir(),
33
+ mkdirp: (dir) => {
34
+ mkdirSync(dir, { recursive: true });
35
+ },
36
+ readFileOpt: (p) => {
37
+ try {
38
+ return readFileSync(p, 'utf-8');
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ },
44
+ writeFile: (p, content, mode) => {
45
+ writeFileSync(p, content, { mode: mode ?? 0o600 });
46
+ },
47
+ unlinkOpt: (p) => {
48
+ try {
49
+ unlinkSync(p);
50
+ }
51
+ catch {
52
+ /* ENOENT ignored */
53
+ }
54
+ },
55
+ statMtime: (p) => {
56
+ try {
57
+ return statSync(p).mtimeMs;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ },
63
+ listDir: (p) => {
64
+ try {
65
+ return readdirSync(p);
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ },
71
+ getRoster: (token, apiUrl, since, serverTrustIdentity) => getRoster(token, apiUrl, since, serverTrustIdentity),
72
+ // getCube uses the drone session token via authedFetch (cubeId-only); apiUrl/token unused.
73
+ getCube: (_apiUrl, _token, cubeId) => getCube(cubeId),
74
+ probeSeat: (sessionToken, apiUrl, serverTrustIdentity) => defaultProbeSeat(sessionToken, apiUrl, serverTrustIdentity),
75
+ getCliPreferenceForPath: (projectPath) => getProjectCliPreferenceForPath(projectPath),
76
+ readAllProjectIdentities: () => cubesReadAllProjectIdentities(),
77
+ findProjectRoot: (dir) => findProjectRoot(dir),
78
+ getActiveCube: () => getActiveCube(),
79
+ prompt: async (message) => {
80
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
81
+ try {
82
+ return (await rl.question(message)).trim();
83
+ }
84
+ finally {
85
+ rl.close();
86
+ }
87
+ },
88
+ isTTY: () => process.stdin.isTTY === true,
89
+ getEnv: (name) => process.env[name],
90
+ platform: () => process.platform,
91
+ stderr: (line) => {
92
+ process.stderr.write(line);
93
+ },
94
+ stdout: (line) => {
95
+ process.stdout.write(line);
96
+ },
97
+ };
98
+ }
99
+ //# sourceMappingURL=launch-all-deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-all-deps.js","sourceRoot":"","sources":["../src/launch-all-deps.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export interface DroneCandidate {
6
6
  droneLabel: string;
7
7
  sessionToken: string;
8
8
  apiUrl: string;
9
+ serverTrustIdentity?: string;
9
10
  }
10
11
  /**
11
12
  * --only TIER-1 (local, no server call): exact case-insensitive droneLabel match,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-all-discovery.d.ts","sourceRoot":"","sources":["../src/launch-all-discovery.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,EAAE,CAmBrE;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CA0C3B"}
@@ -1,4 +1,90 @@
1
- const u=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function c(o){return u.test(o)}function d(o,t){const i=o.toLowerCase(),e=t.toLowerCase();return i===e||i.startsWith(e)}function l(o){let t;try{t=o("git",["worktree","list","--porcelain"])}catch(e){throw new Error(`launch-all: git worktree list failed \u2014 must be run from inside a git repository
2
- (inner: ${e instanceof Error?e.message:String(e)})`)}return t.trim().split(/\n\n+/).slice(1).map(e=>{const s=e.match(/^worktree (.+)$/m);return s?s[1].trim():null}).filter(e=>e!==null)}async function f(o,t){const i=l((r,n)=>t.runSync(r,n)),e=await t.readAllProjectIdentities(),s=new Map(e.map(r=>[r.projectPath,r.cube])),a=[];for(const r of i){if(!t.pathExists(r)){t.stderr(`skipping ${r}: directory not found (orphaned worktree \u2014 run \`git worktree prune\`)
3
- `);continue}const n=s.get(r);if(n&&n.cubeId===o.targetCubeId){if(!c(n.cubeId)||!c(n.droneId)){t.stderr(`skipping ${r}: cubes.json entry has malformed cubeId/droneId \u2014 re-assimilate to fix
4
- `);continue}o.only!==void 0&&!d(n.droneLabel,o.only)||a.push({worktreeDir:r,cubeId:n.cubeId,droneId:n.droneId,droneLabel:n.droneLabel,sessionToken:n.sessionToken,apiUrl:n.apiUrl})}}return a}export{f as discoverDroneCandidates,l as enumerateLinkedWorktrees,d as matchesOnlyLabel};
1
+ // gh#556 Part 2 drone-worktree discovery for `borg launch-all`.
2
+ //
3
+ // Scheme-agnostic: enumerates `git worktree list --porcelain` (the authoritative
4
+ // source covering BOTH old sibling paths and new ~/.borg/worktrees/<repo>/<name>
5
+ // paths from Part 1) and cross-references ~/.config/borgmcp/cubes.json, keeping
6
+ // only worktrees whose saved identity has cubeId === target.
7
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8
+ function isUuid(s) {
9
+ return UUID_RE.test(s);
10
+ }
11
+ /**
12
+ * --only TIER-1 (local, no server call): exact case-insensitive droneLabel match,
13
+ * OR droneLabel prefix match (`--only drone` matches `drone-1`, `drone-2`, ...).
14
+ * Tier-2 (role-name) matching is best-effort in the orchestrator (spec §8.4).
15
+ */
16
+ export function matchesOnlyLabel(droneLabel, only) {
17
+ const l = droneLabel.toLowerCase();
18
+ const o = only.toLowerCase();
19
+ return l === o || l.startsWith(o);
20
+ }
21
+ /**
22
+ * Enumerate the LINKED worktree paths from `git worktree list --porcelain`,
23
+ * dropping the main worktree (always block[0]). Throws a user-readable error if
24
+ * the command fails (not inside a git repo).
25
+ */
26
+ export function enumerateLinkedWorktrees(runSync) {
27
+ let raw;
28
+ try {
29
+ raw = runSync('git', ['worktree', 'list', '--porcelain']);
30
+ }
31
+ catch (e) {
32
+ throw new Error(`launch-all: git worktree list failed — must be run from inside a git repository\n` +
33
+ ` (inner: ${e instanceof Error ? e.message : String(e)})`);
34
+ }
35
+ const blocks = raw.trim().split(/\n\n+/);
36
+ // blocks[0] is the main worktree — always drop it.
37
+ return blocks
38
+ .slice(1)
39
+ .map((block) => {
40
+ const m = block.match(/^worktree (.+)$/m);
41
+ return m ? m[1].trim() : null;
42
+ })
43
+ .filter((p) => p !== null);
44
+ }
45
+ /**
46
+ * Full discovery pipeline (spec §3.5): enumerate → cubes.json lookup → filter
47
+ * (dir-present / has-entry / cubeId-match / UUID-valid / --only) → candidates in
48
+ * stable porcelain order.
49
+ */
50
+ export async function discoverDroneCandidates(opts, deps) {
51
+ const worktreePaths = enumerateLinkedWorktrees((cmd, args) => deps.runSync(cmd, args));
52
+ const identities = await deps.readAllProjectIdentities();
53
+ const byPath = new Map(identities.map((e) => [e.projectPath, e.cube]));
54
+ const candidates = [];
55
+ for (const worktreeDir of worktreePaths) {
56
+ // 1. directory not present on disk (orphaned worktree)
57
+ if (!deps.pathExists(worktreeDir)) {
58
+ deps.stderr(`skipping ${worktreeDir}: directory not found (orphaned worktree — run \`git worktree prune\`)\n`);
59
+ continue;
60
+ }
61
+ // 2. no cubes.json entry → not a drone worktree; skip silently
62
+ const cube = byPath.get(worktreeDir);
63
+ if (!cube)
64
+ continue;
65
+ // 3. cubeId mismatch → different cube; skip silently
66
+ if (cube.cubeId !== opts.targetCubeId)
67
+ continue;
68
+ // 4. malformed entry (cubeId/droneId not UUID) → warn + skip
69
+ if (!isUuid(cube.cubeId) || !isUuid(cube.droneId)) {
70
+ deps.stderr(`skipping ${worktreeDir}: its saved seat has a malformed cubeId/droneId — re-assimilate to fix\n`);
71
+ continue;
72
+ }
73
+ // 5. --only filter (tier-1 label) → skip silently (counted in the filter report)
74
+ if (opts.only !== undefined && !matchesOnlyLabel(cube.droneLabel, opts.only))
75
+ continue;
76
+ candidates.push({
77
+ worktreeDir,
78
+ cubeId: cube.cubeId,
79
+ droneId: cube.droneId,
80
+ droneLabel: cube.droneLabel,
81
+ sessionToken: cube.sessionToken,
82
+ apiUrl: cube.apiUrl,
83
+ ...(cube.serverTrustIdentity === undefined
84
+ ? {}
85
+ : { serverTrustIdentity: cube.serverTrustIdentity }),
86
+ });
87
+ }
88
+ return candidates;
89
+ }
90
+ //# sourceMappingURL=launch-all-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-all-discovery.js","sourceRoot":"","sources":["../src/launch-all-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-all-locks.d.ts","sourceRoot":"","sources":["../src/launch-all-locks.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,eAAO,MAAM,aAAa,QAAgB,CAAC;AAE3C,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,IAAI,CAIN;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQxF;AAED,sFAAsF;AACtF,wBAAgB,UAAU,CACxB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAWxC"}
@@ -1 +1,54 @@
1
- import{createHash as s}from"node:crypto";import{join as a}from"node:path";const u=300*1e3;function m(t){return s("sha1").update(t,"utf8").digest("hex")}function l(t,r){return a(t,".config","borgmcp","locks",r)}function f(t,r,e){return a(l(t,r),m(e)+".pid")}function k(t,r,e,i,n){t.mkdirp(l(t.homedir(),r));const o={launchedAt:n,droneLabel:e,worktreeDir:i};t.writeFile(f(t.homedir(),r,i),JSON.stringify(o),384)}function d(t,r,e){const i=l(t.homedir(),r);for(const n of t.listDir(i)){if(!n.endsWith(".pid"))continue;const o=a(i,n),c=t.statMtime(o);c!==null&&e-c>u&&t.unlinkOpt(o)}}function x(t,r,e,i){const n=t.readFileOpt(f(t.homedir(),r,e));if(n===null)return{live:!1};try{const o=JSON.parse(n),c=Date.parse(o.launchedAt);return Number.isFinite(c)?{live:i-c<=u,launchedAt:o.launchedAt}:{live:!1}}catch{return{live:!1}}}export{u as LOCK_STALE_MS,x as isLockLive,f as lockPath,l as locksDir,d as sweepStaleLocks,m as worktreeLockName,k as writeLockMarker};
1
+ // gh#556 Part 2 per-worktree launch lock markers (spec §6).
2
+ //
3
+ // Timestamp-based markers (the agent PID is not synchronously available when
4
+ // `borg assimilate --here` is dispatched via tmux send-keys). A marker <5min old
5
+ // means the seat appears live → skip unless --force. Markers are never deleted by
6
+ // launch-all itself; the next invocation sweeps mtime-stale (>5min) markers.
7
+ import { createHash } from 'node:crypto';
8
+ import { join } from 'node:path';
9
+ export const LOCK_STALE_MS = 5 * 60 * 1000;
10
+ /** SHA-1 hex of the worktree abs path → fixed-length collision-safe filename. */
11
+ export function worktreeLockName(absPath) {
12
+ return createHash('sha1').update(absPath, 'utf8').digest('hex');
13
+ }
14
+ export function locksDir(homeDir, cubeId) {
15
+ return join(homeDir, '.config', 'borgmcp', 'locks', cubeId);
16
+ }
17
+ export function lockPath(homeDir, cubeId, absPath) {
18
+ return join(locksDir(homeDir, cubeId), worktreeLockName(absPath) + '.pid');
19
+ }
20
+ /** Write the launch marker (mkdir -p the cube's locks dir first). Mode 0o600. */
21
+ export function writeLockMarker(deps, cubeId, droneLabel, worktreeDir, launchedAtISO) {
22
+ deps.mkdirp(locksDir(deps.homedir(), cubeId));
23
+ const marker = { launchedAt: launchedAtISO, droneLabel, worktreeDir };
24
+ deps.writeFile(lockPath(deps.homedir(), cubeId, worktreeDir), JSON.stringify(marker), 0o600);
25
+ }
26
+ /** Delete mtime-stale (>5min) `.pid` markers in locks/<cubeId>/ (crash cleanup). */
27
+ export function sweepStaleLocks(deps, cubeId, nowMs) {
28
+ const dir = locksDir(deps.homedir(), cubeId);
29
+ for (const name of deps.listDir(dir)) {
30
+ if (!name.endsWith('.pid'))
31
+ continue;
32
+ const p = join(dir, name);
33
+ const mtime = deps.statMtime(p);
34
+ if (mtime !== null && nowMs - mtime > LOCK_STALE_MS)
35
+ deps.unlinkOpt(p);
36
+ }
37
+ }
38
+ /** True iff a fresh (<=5min by its launchedAt content) marker exists for the seat. */
39
+ export function isLockLive(deps, cubeId, worktreeDir, nowMs) {
40
+ const raw = deps.readFileOpt(lockPath(deps.homedir(), cubeId, worktreeDir));
41
+ if (raw === null)
42
+ return { live: false };
43
+ try {
44
+ const marker = JSON.parse(raw);
45
+ const t = Date.parse(marker.launchedAt);
46
+ if (!Number.isFinite(t))
47
+ return { live: false };
48
+ return { live: nowMs - t <= LOCK_STALE_MS, launchedAt: marker.launchedAt };
49
+ }
50
+ catch {
51
+ return { live: false };
52
+ }
53
+ }
54
+ //# sourceMappingURL=launch-all-locks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-all-locks.js","sourceRoot":"","sources":["../src/launch-all-locks.ts"],"names":[],"mappings":"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"}
@@ -28,8 +28,8 @@
28
28
  * SR-BINDING (1482e7f9): BORG_SESSION is ACTIVATION-ONLY. It is
29
29
  * user-settable by design (manual BORG_SESSION=1 is a supported override
30
30
  * for power users/tests) and MUST NEVER be consulted for an access or
31
- * security decision — server-side OAuth + drone-session auth are the
32
- * security boundary and are unchanged by this gate.
31
+ * security decision — server-side drone-session auth is the
32
+ * security boundary and is unchanged by this gate.
33
33
  */
34
34
  export declare const BORG_SESSION_ENV = "BORG_SESSION";
35
35
  /** True when this process runs inside a borg-launched session. */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-gate.d.ts","sourceRoot":"","sources":["../src/launch-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAErD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAMnG"}
@@ -1 +1,73 @@
1
- import{envToggleOn as t}from"./auth-env.js";import{debugLog as s}from"./debug.js";const e="BORG_SESSION";function i(o=process.env){return t(o[e])}function u(o){return`\u25FC ${o} is inactive: this session wasn't launched via \`borg\`, so the borg coordination surface is dormant (vanilla Claude Code). To use cube coordination, re-launch from a terminal with \`borg\` (or \`borg assimilate\` to set up a seat first). Power users can opt in manually by launching with BORG_SESSION=1.`}function g(){return["-c",`mcp_servers.borg.env.${e}="1"`]}function l(o,r=process.env){const n=i(r);return n||s(`launch-gate: ${o} dormant \u2014 BORG_SESSION absent (not a borg-launched session; gh#673)`),n}export{e as BORG_SESSION_ENV,u as borgSessionToolNotice,g as codexBorgSessionConfigArgs,l as gateAllowsActivation,i as isBorgSession};
1
+ /**
2
+ * gh#673 P1 — the borg-launch ACTIVATION gate (WI-4 + WI-5-claude).
3
+ *
4
+ * The `borg` wrapper sets BORG_SESSION=1 in the agent's launch env
5
+ * (claude.ts / assimilate-cmd.ts launchEnv — same pattern as
6
+ * BORG_CODEX_REMOTE_WAKE). Claude Code spawns the borg-mcp MCP child and
7
+ * runs hook commands with that env inherited, so four activation bins
8
+ * gate on it:
9
+ * 1. the MCP tool surface (index.ts CallTool top) — a vanilla session
10
+ * gets a non-silent re-launch notice per tool, never a half-success;
11
+ * 2. the borg-regen SessionStart hook bin — exit-0 no-op;
12
+ * 3. the borg-clear-rewake clear-only hook bin — exit-0 no-op;
13
+ * 4. the borg-log-audit UserPromptSubmit hook bin — exit-0 no-op.
14
+ * Result: `claude` launched directly is vanilla Claude Code; `borg`
15
+ * launches get the full surface.
16
+ *
17
+ * Codex (V2/V2b probes): codex does NOT forward parent env to MCP
18
+ * children — only the pinned [mcp_servers.borg.env] list — so simple
19
+ * launchEnv inheritance can't deliver the marker there. But a
20
+ * PER-INVOCATION `-c 'mcp_servers.borg.env.BORG_SESSION="1"'` config
21
+ * override DOES reach the child (V2b-proven). The borg wrapper appends
22
+ * `codexBorgSessionConfigArgs()` to every codex launch, so codex rides
23
+ * the exact same isBorgSession() gate: vanilla codex children lack the
24
+ * var and gate dormant; borg-launched children carry it. The codex
25
+ * SessionStart hook bin gates via the codex PROCESS env, which the
26
+ * wrapper's launchEnv marks directly.
27
+ *
28
+ * SR-BINDING (1482e7f9): BORG_SESSION is ACTIVATION-ONLY. It is
29
+ * user-settable by design (manual BORG_SESSION=1 is a supported override
30
+ * for power users/tests) and MUST NEVER be consulted for an access or
31
+ * security decision — server-side drone-session auth is the
32
+ * security boundary and is unchanged by this gate.
33
+ */
34
+ import { envToggleOn } from './auth-env.js';
35
+ import { debugLog } from './debug.js';
36
+ export const BORG_SESSION_ENV = 'BORG_SESSION';
37
+ /** True when this process runs inside a borg-launched session. */
38
+ export function isBorgSession(env = process.env) {
39
+ return envToggleOn(env[BORG_SESSION_ENV]);
40
+ }
41
+ /**
42
+ * The non-silent per-tool notice a vanilla (non-borg-launched) session
43
+ * receives when invoking a borg_* tool. Explains the state — nothing is
44
+ * wrong with the cube — and points at the borg launch path.
45
+ */
46
+ export function borgSessionToolNotice(toolName) {
47
+ return (`◼ ${toolName} is inactive: this session wasn't launched via \`borg\`, so the borg ` +
48
+ `coordination surface is dormant (vanilla Claude Code). To use cube coordination, ` +
49
+ `re-launch from a terminal with \`borg\` (or \`borg assimilate\` to set up a seat first). ` +
50
+ `Power users can opt in manually by launching with BORG_SESSION=1.`);
51
+ }
52
+ /**
53
+ * The per-invocation codex config override that injects BORG_SESSION into
54
+ * the codex-spawned borg-mcp child's pinned env (V2b-proven mechanism —
55
+ * inherited env never reaches codex MCP children). Appended to the codex
56
+ * launch args by both launch sites (claude.ts + assimilate-cmd.ts).
57
+ * TOML string value, hence the inner quotes.
58
+ */
59
+ export function codexBorgSessionConfigArgs() {
60
+ return ['-c', `mcp_servers.borg.env.${BORG_SESSION_ENV}="1"`];
61
+ }
62
+ /**
63
+ * Gate decision with BORG_DEBUG observability — one funnel so every bin
64
+ * logs refusals the same way.
65
+ */
66
+ export function gateAllowsActivation(surface, env = process.env) {
67
+ const allowed = isBorgSession(env);
68
+ if (!allowed) {
69
+ debugLog(`launch-gate: ${surface} dormant — BORG_SESSION absent (not a borg-launched session; gh#673)`);
70
+ }
71
+ return allowed;
72
+ }
73
+ //# sourceMappingURL=launch-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-gate.js","sourceRoot":"","sources":["../src/launch-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAE/C,kEAAkE;AAClE,MAAM,UAAU,aAAa,CAAC,MAAyB,OAAO,CAAC,GAAG;IAChE,OAAO,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,OAAO,CACL,KAAK,QAAQ,uEAAuE;QACpF,mFAAmF;QACnF,2FAA2F;QAC3F,mEAAmE,CACpE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,CAAC,IAAI,EAAE,wBAAwB,gBAAgB,MAAM,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,MAAyB,OAAO,CAAC,GAAG;IACxF,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,QAAQ,CAAC,gBAAgB,OAAO,sEAAsE,CAAC,CAAC;IAC1G,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-log-guard.d.ts","sourceRoot":"","sources":["../src/lifecycle-log-guard.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,CAAC;AAElD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,mBAAmB;IAC3B,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;CACH;AAMD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAUjF;AA8BD,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,GAAG,SAAS,EACtC,KAAK,GAAE,MAAmB,GACzB;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,CAqBvD;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,CAAC,CAMhE;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,GAAG,SAAS,EACxC,MAAM,GAAE,MAAiC,GACxC,mBAAmB,CAqBrB;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -1,2 +1,93 @@
1
- import{mkdir as u,readFile as f,writeFile as d}from"node:fs/promises";import{homedir as p}from"node:os";import{dirname as y,join as A}from"node:path";const n=A(p(),".config","borgmcp","lifecycle-log-state.json"),S=600*1e3;function o(e){return e.startsWith("ARRIVAL: ")?"arrival":e.startsWith("READY: ")&&e.includes("capacity clean")&&e.includes("awaiting next dispatch")?"ready":null}function s(e){return`${e.cubeId}:${e.droneId}`}async function l(){try{const e=await f(n,"utf8"),t=JSON.parse(e);if(t&&typeof t=="object"&&t.entries&&typeof t.entries=="object"&&!Array.isArray(t.entries))return t}catch(e){if(e?.code!=="ENOENT")throw e}return{entries:{}}}async function w(e){await u(y(n),{recursive:!0}),await d(n,JSON.stringify(e,null,2)+`
2
- `,{mode:384})}function L(e,t,r=Date.now()){const i=o(e);if(!i)return{suppress:!1,signal:null};if(i==="arrival"){const a=t?.lastArrival?.at?new Date(t.lastArrival.at).getTime():NaN,c=Number.isFinite(a)&&r-a<S;return{suppress:t?.lastArrival?.message===e&&c,signal:i}}return{suppress:t?.idleReady?.open===!0&&t.idleReady.message===e,signal:i}}async function h(e,t){const r=await l();return L(t,r.entries[s(e)])}function R(e,t,r=new Date().toISOString()){const i=o(e);return i==="arrival"?{...t,lastArrival:{message:e,at:r}}:i==="ready"?{...t,idleReady:{message:e,open:!0,at:r}}:t?.idleReady?.open?{...t,idleReady:{...t.idleReady,open:!1,at:r}}:t??{}}async function N(e,t){const r=await l(),i=s(e);r.entries[i]=R(t,r.entries[i]),await w(r)}export{o as lifecycleSignalForMessage,R as nextLifecycleStateAfterLog,N as recordLifecycleLog,h as shouldSuppressLifecycleLog,L as shouldSuppressLifecycleLogFromState};
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ const STATE_FILE = join(homedir(), '.config', 'borgmcp', 'lifecycle-log-state.json');
5
+ const ARRIVAL_DUPLICATE_WINDOW_MS = 10 * 60 * 1000;
6
+ export function lifecycleSignalForMessage(message) {
7
+ if (message.startsWith('ARRIVAL: '))
8
+ return 'arrival';
9
+ if (message.startsWith('READY: ') &&
10
+ message.includes('capacity clean') &&
11
+ message.includes('awaiting next dispatch')) {
12
+ return 'ready';
13
+ }
14
+ return null;
15
+ }
16
+ function stateKey(subject) {
17
+ return `${subject.cubeId}:${subject.droneId}`;
18
+ }
19
+ async function readState() {
20
+ try {
21
+ const raw = await readFile(STATE_FILE, 'utf8');
22
+ const parsed = JSON.parse(raw);
23
+ if (parsed &&
24
+ typeof parsed === 'object' &&
25
+ parsed.entries &&
26
+ typeof parsed.entries === 'object' &&
27
+ !Array.isArray(parsed.entries)) {
28
+ return parsed;
29
+ }
30
+ }
31
+ catch (err) {
32
+ if (err?.code !== 'ENOENT')
33
+ throw err;
34
+ }
35
+ return { entries: {} };
36
+ }
37
+ async function writeState(state) {
38
+ await mkdir(dirname(STATE_FILE), { recursive: true });
39
+ await writeFile(STATE_FILE, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
40
+ }
41
+ export function shouldSuppressLifecycleLogFromState(message, state, nowMs = Date.now()) {
42
+ const signal = lifecycleSignalForMessage(message);
43
+ if (!signal)
44
+ return { suppress: false, signal: null };
45
+ if (signal === 'arrival') {
46
+ const lastArrivalAt = state?.lastArrival?.at
47
+ ? new Date(state.lastArrival.at).getTime()
48
+ : NaN;
49
+ const isRecent = Number.isFinite(lastArrivalAt) &&
50
+ nowMs - lastArrivalAt < ARRIVAL_DUPLICATE_WINDOW_MS;
51
+ return {
52
+ suppress: state?.lastArrival?.message === message && isRecent,
53
+ signal,
54
+ };
55
+ }
56
+ return {
57
+ suppress: state?.idleReady?.open === true && state.idleReady.message === message,
58
+ signal,
59
+ };
60
+ }
61
+ export async function shouldSuppressLifecycleLog(subject, message) {
62
+ const state = await readState();
63
+ return shouldSuppressLifecycleLogFromState(message, state.entries[stateKey(subject)]);
64
+ }
65
+ export function nextLifecycleStateAfterLog(message, current, nowIso = new Date().toISOString()) {
66
+ const signal = lifecycleSignalForMessage(message);
67
+ if (signal === 'arrival') {
68
+ return {
69
+ ...current,
70
+ lastArrival: { message, at: nowIso },
71
+ };
72
+ }
73
+ if (signal === 'ready') {
74
+ return {
75
+ ...current,
76
+ idleReady: { message, open: true, at: nowIso },
77
+ };
78
+ }
79
+ if (current?.idleReady?.open) {
80
+ return {
81
+ ...current,
82
+ idleReady: { ...current.idleReady, open: false, at: nowIso },
83
+ };
84
+ }
85
+ return current ?? {};
86
+ }
87
+ export async function recordLifecycleLog(subject, message) {
88
+ const state = await readState();
89
+ const key = stateKey(subject);
90
+ state.entries[key] = nextLifecycleStateAfterLog(message, state.entries[key]);
91
+ await writeState(state);
92
+ }
93
+ //# sourceMappingURL=lifecycle-log-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-log-guard.js","sourceRoot":"","sources":["../src/lifecycle-log-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-roles-render.d.ts","sourceRoot":"","sources":["../src/list-roles-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAkB7E"}
@@ -1,6 +1,40 @@
1
- function i(n,a){if(!n.length)return"No roles in this cube yet.";const l=n.map(e=>{const t=[e.role_class==="queen"?"Queen":null,e.is_human_seat?"human-seat":null,e.is_default?"default":null,e.is_mandatory?"mandatory":null,e.can_broadcast?"can-broadcast":null,e.receives_all_direct?"receives-all-direct":null].filter(Boolean).join(", "),o=t?` (${t})`:"",s=e.short_description||"_(no description)_";return`- **${e.name}**${o} \`${e.id}\` \u2014 ${s}`});return`Roles in cube ${a} (${n.length}):
2
-
3
- ${l.join(`
4
- `)}
5
-
6
- Use the role IDs above with \`borg_reassign-drone\` to change a drone's role.`}export{i as renderRoleList};
1
+ /**
2
+ * Sprint 6 / gh#153 — pure render function for `borg_list-roles` MCP tool.
3
+ *
4
+ * Extracted from the inline `case 'borg_list-roles'` handler in
5
+ * `index.ts` per drone-3's QA-FAIL 2026-05-18T13:27:53Z so the render
6
+ * logic is unit-testable without exercising the full MCP tool dispatch
7
+ * stack. The handler simply calls `renderRoleList(roles, cubeId)` and
8
+ * returns its output.
9
+ */
10
+ /**
11
+ * Render the role registry for a cube as a markdown list with role IDs
12
+ * exposed for use with `borg_reassign-drone`. Returns the empty-roles
13
+ * placeholder when the input array is empty.
14
+ *
15
+ * Each role line shape:
16
+ * - **<name>**(<tags>) `<uuid>` — <description>
17
+ *
18
+ * Tags collected in order: Queen, human-seat, default, mandatory, can-broadcast,
19
+ * receives-all-direct. Joined with `, `; suffix omitted entirely when no tags apply.
20
+ */
21
+ export function renderRoleList(roles, cubeId) {
22
+ if (!roles.length) {
23
+ return 'No roles in this cube yet.';
24
+ }
25
+ const lines = roles.map((r) => {
26
+ const tags = [
27
+ r.role_class === 'queen' ? 'Queen' : null,
28
+ r.is_human_seat ? 'human-seat' : null,
29
+ r.is_default ? 'default' : null,
30
+ r.is_mandatory ? 'mandatory' : null,
31
+ r.can_broadcast ? 'can-broadcast' : null,
32
+ r.receives_all_direct ? 'receives-all-direct' : null,
33
+ ].filter(Boolean).join(', ');
34
+ const tagSuffix = tags ? ` (${tags})` : '';
35
+ const desc = r.short_description || '_(no description)_';
36
+ return `- **${r.name}**${tagSuffix} \`${r.id}\` — ${desc}`;
37
+ });
38
+ return `Roles in cube ${cubeId} (${roles.length}):\n\n${lines.join('\n')}\n\nUse the role IDs above with \`borg_reassign-drone\` to change a drone's role.`;
39
+ }
40
+ //# sourceMappingURL=list-roles-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-roles-render.js","sourceRoot":"","sources":["../src/list-roles-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB,EAAE,MAAc;IACnE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,4BAA4B,CAAC;IACtC,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG;YACX,CAAC,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YACzC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI;YACrC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;YAC/B,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YACnC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;YACxC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI;SACrD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,CAAC,CAAC,iBAAiB,IAAI,oBAAoB,CAAC;QACzD,OAAO,OAAO,CAAC,CAAC,IAAI,KAAK,SAAS,MAAM,CAAC,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;IACH,OAAO,iBAAiB,MAAM,KAAK,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,mFAAmF,CAAC;AAC9J,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface LocalRoutingDrone {
2
+ id: string;
3
+ label?: string | null;
4
+ role_id?: string | null;
5
+ }
6
+ export interface LocalRoutingRole {
7
+ id: string;
8
+ name: string;
9
+ is_human_seat?: boolean;
10
+ }
11
+ /**
12
+ * Resolve the public `borg_log to:` addressing forms against the local
13
+ * server's authoritative cube roster. This intentionally mirrors the hosted
14
+ * route resolver: exact drone id/label first, then displayed short UUID, then
15
+ * role name/slug expansion. Every failure is closed before the log POST so a
16
+ * miss can never degrade into a broadcast.
17
+ */
18
+ export declare function resolveLocalLogRecipients(recipients: readonly string[], drones: readonly LocalRoutingDrone[], roles: readonly LocalRoutingRole[]): string[];
19
+ //# sourceMappingURL=local-log-routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-log-routing.d.ts","sourceRoot":"","sources":["../src/local-log-routing.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,MAAM,EAAE,SAAS,iBAAiB,EAAE,EACpC,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,MAAM,EAAE,CAgFV"}