borgmcp 1.1.14 → 2.0.1

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 (459) hide show
  1. package/CONTRIBUTING.md +15 -0
  2. package/LICENSE +201 -33
  3. package/NOTICE +2 -0
  4. package/README.md +86 -37
  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.map +1 -0
  71. package/dist/codex-app-wake.js +432 -2
  72. package/dist/codex-app-wake.js.map +1 -0
  73. package/dist/codex-launch.d.ts.map +1 -0
  74. package/dist/codex-launch.js +102 -2
  75. package/dist/codex-launch.js.map +1 -0
  76. package/dist/codex-remote.d.ts +6 -1
  77. package/dist/codex-remote.d.ts.map +1 -0
  78. package/dist/codex-remote.js +394 -1
  79. package/dist/codex-remote.js.map +1 -0
  80. package/dist/codex-wake-resolve.d.ts.map +1 -0
  81. package/dist/codex-wake-resolve.js +127 -1
  82. package/dist/codex-wake-resolve.js.map +1 -0
  83. package/dist/config-utils.d.ts +2 -2
  84. package/dist/config-utils.d.ts.map +1 -0
  85. package/dist/config-utils.js +766 -3
  86. package/dist/config-utils.js.map +1 -0
  87. package/dist/config.d.ts +98 -61
  88. package/dist/config.d.ts.map +1 -0
  89. package/dist/config.js +426 -1
  90. package/dist/config.js.map +1 -0
  91. package/dist/console-prefix.d.ts.map +1 -0
  92. package/dist/console-prefix.js +96 -1
  93. package/dist/console-prefix.js.map +1 -0
  94. package/dist/cube-name.d.ts.map +1 -0
  95. package/dist/cube-name.js +67 -1
  96. package/dist/cube-name.js.map +1 -0
  97. package/dist/cubes.d.ts +126 -18
  98. package/dist/cubes.d.ts.map +1 -0
  99. package/dist/cubes.js +412 -4
  100. package/dist/cubes.js.map +1 -0
  101. package/dist/debug.d.ts.map +1 -0
  102. package/dist/debug.js +71 -1
  103. package/dist/debug.js.map +1 -0
  104. package/dist/direct-log.d.ts.map +1 -0
  105. package/dist/direct-log.js +11 -1
  106. package/dist/direct-log.js.map +1 -0
  107. package/dist/docs-sections.d.ts +11 -10
  108. package/dist/docs-sections.d.ts.map +1 -0
  109. package/dist/docs-sections.js +113 -3
  110. package/dist/docs-sections.js.map +1 -0
  111. package/dist/drone-lifecycle.d.ts +5 -21
  112. package/dist/drone-lifecycle.d.ts.map +1 -0
  113. package/dist/drone-lifecycle.js +57 -8
  114. package/dist/drone-lifecycle.js.map +1 -0
  115. package/dist/drone-management.d.ts +29 -0
  116. package/dist/drone-management.d.ts.map +1 -0
  117. package/dist/drone-management.js +109 -0
  118. package/dist/drone-management.js.map +1 -0
  119. package/dist/ensure-mcp-config.d.ts.map +1 -0
  120. package/dist/ensure-mcp-config.js +36 -1
  121. package/dist/ensure-mcp-config.js.map +1 -0
  122. package/dist/evict-drone.d.ts +10 -2
  123. package/dist/evict-drone.d.ts.map +1 -0
  124. package/dist/evict-drone.js +60 -1
  125. package/dist/evict-drone.js.map +1 -0
  126. package/dist/gc-orphan-inboxes.d.ts.map +1 -0
  127. package/dist/gc-orphan-inboxes.js +177 -1
  128. package/dist/gc-orphan-inboxes.js.map +1 -0
  129. package/dist/inbox-monitor.d.ts +1 -1
  130. package/dist/inbox-monitor.d.ts.map +1 -0
  131. package/dist/inbox-monitor.js +856 -3
  132. package/dist/inbox-monitor.js.map +1 -0
  133. package/dist/index.d.ts +6 -4
  134. package/dist/index.d.ts.map +1 -0
  135. package/dist/index.js +1034 -37
  136. package/dist/index.js.map +1 -0
  137. package/dist/launch-all-cmd.d.ts.map +1 -0
  138. package/dist/launch-all-cmd.js +377 -37
  139. package/dist/launch-all-cmd.js.map +1 -0
  140. package/dist/launch-all-command.d.ts.map +1 -0
  141. package/dist/launch-all-command.js +24 -1
  142. package/dist/launch-all-command.js.map +1 -0
  143. package/dist/launch-all-deps.d.ts +3 -8
  144. package/dist/launch-all-deps.d.ts.map +1 -0
  145. package/dist/launch-all-deps.js +99 -1
  146. package/dist/launch-all-deps.js.map +1 -0
  147. package/dist/launch-all-discovery.d.ts +1 -0
  148. package/dist/launch-all-discovery.d.ts.map +1 -0
  149. package/dist/launch-all-discovery.js +90 -4
  150. package/dist/launch-all-discovery.js.map +1 -0
  151. package/dist/launch-all-locks.d.ts.map +1 -0
  152. package/dist/launch-all-locks.js +54 -1
  153. package/dist/launch-all-locks.js.map +1 -0
  154. package/dist/launch-gate.d.ts +2 -2
  155. package/dist/launch-gate.d.ts.map +1 -0
  156. package/dist/launch-gate.js +73 -1
  157. package/dist/launch-gate.js.map +1 -0
  158. package/dist/lifecycle-log-guard.d.ts.map +1 -0
  159. package/dist/lifecycle-log-guard.js +93 -2
  160. package/dist/lifecycle-log-guard.js.map +1 -0
  161. package/dist/list-roles-render.d.ts.map +1 -0
  162. package/dist/list-roles-render.js +40 -6
  163. package/dist/list-roles-render.js.map +1 -0
  164. package/dist/local-log-routing.d.ts +19 -0
  165. package/dist/local-log-routing.d.ts.map +1 -0
  166. package/dist/local-log-routing.js +67 -0
  167. package/dist/local-log-routing.js.map +1 -0
  168. package/dist/local-manage-tool-result.d.ts +8 -0
  169. package/dist/local-manage-tool-result.d.ts.map +1 -0
  170. package/dist/local-manage-tool-result.js +10 -0
  171. package/dist/local-manage-tool-result.js.map +1 -0
  172. package/dist/local-server-cursor.d.ts +34 -0
  173. package/dist/local-server-cursor.d.ts.map +1 -0
  174. package/dist/local-server-cursor.js +151 -0
  175. package/dist/local-server-cursor.js.map +1 -0
  176. package/dist/log-audit.d.ts.map +1 -0
  177. package/dist/log-audit.js +194 -3
  178. package/dist/log-audit.js.map +1 -0
  179. package/dist/log-stream.d.ts +31 -18
  180. package/dist/log-stream.d.ts.map +1 -0
  181. package/dist/log-stream.js +1214 -12
  182. package/dist/log-stream.js.map +1 -0
  183. package/dist/model-presets.d.ts.map +1 -0
  184. package/dist/model-presets.js +19 -1
  185. package/dist/model-presets.js.map +1 -0
  186. package/dist/name-validator.d.ts.map +1 -0
  187. package/dist/name-validator.js +22 -1
  188. package/dist/name-validator.js.map +1 -0
  189. package/dist/opencode-drone.d.ts.map +1 -0
  190. package/dist/opencode-drone.js +438 -4
  191. package/dist/opencode-drone.js.map +1 -0
  192. package/dist/opencode-plugin.d.ts +1 -1
  193. package/dist/opencode-plugin.d.ts.map +1 -0
  194. package/dist/opencode-plugin.js +29 -4
  195. package/dist/opencode-plugin.js.map +1 -0
  196. package/dist/parse-assimilate-args.d.ts +1 -1
  197. package/dist/parse-assimilate-args.d.ts.map +1 -0
  198. package/dist/parse-assimilate-args.js +125 -1
  199. package/dist/parse-assimilate-args.js.map +1 -0
  200. package/dist/parse-launch-all-args.d.ts.map +1 -0
  201. package/dist/parse-launch-all-args.js +70 -1
  202. package/dist/parse-launch-all-args.js.map +1 -0
  203. package/dist/postinstall-banner.d.ts.map +1 -0
  204. package/dist/postinstall-banner.js +27 -2
  205. package/dist/postinstall-banner.js.map +1 -0
  206. package/dist/postinstall.d.ts.map +1 -0
  207. package/dist/postinstall.js +32 -5
  208. package/dist/postinstall.js.map +1 -0
  209. package/dist/readiness-probe.d.ts.map +1 -0
  210. package/dist/readiness-probe.js +9 -1
  211. package/dist/readiness-probe.js.map +1 -0
  212. package/dist/regen-format.d.ts.map +1 -0
  213. package/dist/regen-format.js +545 -13
  214. package/dist/regen-format.js.map +1 -0
  215. package/dist/regen.d.ts.map +1 -0
  216. package/dist/regen.js +141 -5
  217. package/dist/regen.js.map +1 -0
  218. package/dist/remote-client.d.ts +65 -175
  219. package/dist/remote-client.d.ts.map +1 -0
  220. package/dist/remote-client.js +942 -1
  221. package/dist/remote-client.js.map +1 -0
  222. package/dist/reset-local-seat-cmd.d.ts +50 -0
  223. package/dist/reset-local-seat-cmd.d.ts.map +1 -0
  224. package/dist/reset-local-seat-cmd.js +169 -0
  225. package/dist/reset-local-seat-cmd.js.map +1 -0
  226. package/dist/role-match.d.ts.map +1 -0
  227. package/dist/role-match.js +23 -1
  228. package/dist/role-match.js.map +1 -0
  229. package/dist/role-resolver.d.ts.map +1 -0
  230. package/dist/role-resolver.js +60 -1
  231. package/dist/role-resolver.js.map +1 -0
  232. package/dist/roster-render.d.ts.map +1 -0
  233. package/dist/roster-render.js +121 -3
  234. package/dist/roster-render.js.map +1 -0
  235. package/dist/seat-probe.d.ts +32 -13
  236. package/dist/seat-probe.d.ts.map +1 -0
  237. package/dist/seat-probe.js +78 -1
  238. package/dist/seat-probe.js.map +1 -0
  239. package/dist/seat-store.d.ts +76 -0
  240. package/dist/seat-store.d.ts.map +1 -0
  241. package/dist/seat-store.js +309 -0
  242. package/dist/seat-store.js.map +1 -0
  243. package/dist/seats.d.ts +303 -0
  244. package/dist/seats.d.ts.map +1 -0
  245. package/dist/seats.js +551 -0
  246. package/dist/seats.js.map +1 -0
  247. package/dist/self-path.d.ts +27 -0
  248. package/dist/self-path.d.ts.map +1 -0
  249. package/dist/self-path.js +43 -0
  250. package/dist/self-path.js.map +1 -0
  251. package/dist/server-endpoint.d.ts +9 -0
  252. package/dist/server-endpoint.d.ts.map +1 -0
  253. package/dist/server-endpoint.js +38 -0
  254. package/dist/server-endpoint.js.map +1 -0
  255. package/dist/server-errors.d.ts +50 -0
  256. package/dist/server-errors.d.ts.map +1 -0
  257. package/dist/server-errors.js +79 -0
  258. package/dist/server-errors.js.map +1 -0
  259. package/dist/server-handshake.d.ts +197 -0
  260. package/dist/server-handshake.d.ts.map +1 -0
  261. package/dist/server-handshake.js +505 -0
  262. package/dist/server-handshake.js.map +1 -0
  263. package/dist/server-response.d.ts +3 -0
  264. package/dist/server-response.d.ts.map +1 -0
  265. package/dist/server-response.js +67 -0
  266. package/dist/server-response.js.map +1 -0
  267. package/dist/server-trust.d.ts +14 -0
  268. package/dist/server-trust.d.ts.map +1 -0
  269. package/dist/server-trust.js +225 -0
  270. package/dist/server-trust.js.map +1 -0
  271. package/dist/setup-confirm.d.ts +3 -3
  272. package/dist/setup-confirm.d.ts.map +1 -0
  273. package/dist/setup-confirm.js +126 -2
  274. package/dist/setup-confirm.js.map +1 -0
  275. package/dist/setup.d.ts +5 -3
  276. package/dist/setup.d.ts.map +1 -0
  277. package/dist/setup.js +169 -46
  278. package/dist/setup.js.map +1 -0
  279. package/dist/shell-escape.d.ts.map +1 -0
  280. package/dist/shell-escape.js +22 -1
  281. package/dist/shell-escape.js.map +1 -0
  282. package/dist/spawn.d.ts +2 -2
  283. package/dist/spawn.d.ts.map +1 -0
  284. package/dist/spawn.js +29 -10
  285. package/dist/spawn.js.map +1 -0
  286. package/dist/startup-services.d.ts +0 -1
  287. package/dist/startup-services.d.ts.map +1 -0
  288. package/dist/startup-services.js +26 -1
  289. package/dist/startup-services.js.map +1 -0
  290. package/dist/stream-owner.d.ts +6 -2
  291. package/dist/stream-owner.d.ts.map +1 -0
  292. package/dist/stream-owner.js +547 -2
  293. package/dist/stream-owner.js.map +1 -0
  294. package/dist/stream-status.d.ts +1 -1
  295. package/dist/stream-status.d.ts.map +1 -0
  296. package/dist/stream-status.js +268 -3
  297. package/dist/stream-status.js.map +1 -0
  298. package/dist/sync-roles-render.d.ts.map +1 -0
  299. package/dist/sync-roles-render.js +118 -3
  300. package/dist/sync-roles-render.js.map +1 -0
  301. package/dist/sync.d.ts +1 -1
  302. package/dist/sync.d.ts.map +1 -0
  303. package/dist/sync.js +286 -22
  304. package/dist/sync.js.map +1 -0
  305. package/dist/terminal-title.d.ts.map +1 -0
  306. package/dist/terminal-title.js +68 -1
  307. package/dist/terminal-title.js.map +1 -0
  308. package/dist/token-store.d.ts +17 -111
  309. package/dist/token-store.d.ts.map +1 -0
  310. package/dist/token-store.js +81 -1
  311. package/dist/token-store.js.map +1 -0
  312. package/dist/tool-manifest.d.ts +4 -8
  313. package/dist/tool-manifest.d.ts.map +1 -0
  314. package/dist/tool-manifest.js +554 -1
  315. package/dist/tool-manifest.js.map +1 -0
  316. package/dist/tool-scope.d.ts +8 -12
  317. package/dist/tool-scope.d.ts.map +1 -0
  318. package/dist/tool-scope.js +97 -1
  319. package/dist/tool-scope.js.map +1 -0
  320. package/dist/types.d.ts +1 -5
  321. package/dist/types.d.ts.map +1 -0
  322. package/dist/types.js +5 -0
  323. package/dist/types.js.map +1 -0
  324. package/dist/unknown-subcommand.d.ts +1 -1
  325. package/dist/unknown-subcommand.d.ts.map +1 -0
  326. package/dist/unknown-subcommand.js +37 -1
  327. package/dist/unknown-subcommand.js.map +1 -0
  328. package/dist/version.d.ts +1 -1
  329. package/dist/version.d.ts.map +1 -0
  330. package/dist/version.js +78 -2
  331. package/dist/version.js.map +1 -0
  332. package/dist/working-repo.d.ts.map +1 -0
  333. package/dist/working-repo.js +81 -1
  334. package/dist/working-repo.js.map +1 -0
  335. package/dist/worktree-lifecycle.d.ts.map +1 -0
  336. package/dist/worktree-lifecycle.js +205 -2
  337. package/dist/worktree-lifecycle.js.map +1 -0
  338. package/docs/EXTRACTION_PROVENANCE.md +40 -0
  339. package/docs/LOCAL_SERVER.md +103 -0
  340. package/docs/RELEASING.md +120 -0
  341. package/package.json +52 -34
  342. package/src/agent-runtime.ts +69 -0
  343. package/src/assimilate-cmd.ts +1864 -0
  344. package/src/assimilate-deps.ts +444 -0
  345. package/src/assimilate-guard.ts +84 -0
  346. package/src/assimilate-welcome.ts +39 -0
  347. package/src/auth-env.ts +21 -0
  348. package/src/backends/launch-all-pastelist.ts +18 -0
  349. package/src/backends/launch-all-tmux.ts +75 -0
  350. package/src/backends/launch-all-windows.ts +110 -0
  351. package/src/bare-launch-menu.ts +148 -0
  352. package/src/claude-launch-args.ts +35 -0
  353. package/src/claude.ts +561 -0
  354. package/src/cleanup-cmd.ts +581 -0
  355. package/src/clear-rewake-core.ts +34 -0
  356. package/src/clear-rewake.ts +18 -0
  357. package/src/cli-help.ts +116 -0
  358. package/src/cli-platform.ts +127 -0
  359. package/src/cli-tool-approval.ts +716 -0
  360. package/src/codex-app-server.ts +238 -0
  361. package/src/codex-app-wake.ts +512 -0
  362. package/src/codex-launch.ts +140 -0
  363. package/src/codex-remote.ts +500 -0
  364. package/src/codex-wake-resolve.ts +155 -0
  365. package/src/config-utils.ts +811 -0
  366. package/src/config.ts +595 -0
  367. package/src/console-prefix.ts +99 -0
  368. package/src/cube-name.ts +69 -0
  369. package/src/cubes.ts +583 -0
  370. package/src/debug.ts +73 -0
  371. package/src/direct-log.ts +9 -0
  372. package/src/docs-sections.ts +129 -0
  373. package/src/drone-lifecycle.ts +62 -0
  374. package/src/drone-management.ts +162 -0
  375. package/src/ensure-mcp-config.ts +54 -0
  376. package/src/evict-drone.ts +82 -0
  377. package/src/gc-orphan-inboxes.ts +229 -0
  378. package/src/inbox-monitor.ts +1005 -0
  379. package/src/index.ts +1201 -0
  380. package/src/launch-all-cmd.ts +450 -0
  381. package/src/launch-all-command.ts +30 -0
  382. package/src/launch-all-deps.ts +188 -0
  383. package/src/launch-all-discovery.ts +118 -0
  384. package/src/launch-all-locks.ts +74 -0
  385. package/src/launch-gate.ts +80 -0
  386. package/src/lifecycle-log-guard.ts +144 -0
  387. package/src/list-roles-render.ts +52 -0
  388. package/src/local-log-routing.ts +106 -0
  389. package/src/local-manage-tool-result.ts +10 -0
  390. package/src/local-server-cursor.ts +188 -0
  391. package/src/log-audit.ts +207 -0
  392. package/src/log-stream.ts +1505 -0
  393. package/src/model-presets.ts +22 -0
  394. package/src/name-validator.ts +23 -0
  395. package/src/opencode-drone.ts +528 -0
  396. package/src/opencode-plugin.ts +38 -0
  397. package/src/parse-assimilate-args.ts +125 -0
  398. package/src/parse-launch-all-args.ts +100 -0
  399. package/src/postinstall-banner.ts +37 -0
  400. package/src/postinstall.ts +36 -0
  401. package/src/readiness-probe.ts +12 -0
  402. package/src/regen-format.ts +651 -0
  403. package/src/regen.ts +150 -0
  404. package/src/remote-client.ts +1379 -0
  405. package/src/reset-local-seat-cmd.ts +227 -0
  406. package/src/role-match.ts +29 -0
  407. package/src/role-resolver.ts +93 -0
  408. package/src/roster-render.ts +196 -0
  409. package/src/seat-probe.ts +115 -0
  410. package/src/seat-store.ts +333 -0
  411. package/src/seats.ts +741 -0
  412. package/src/self-path.ts +51 -0
  413. package/src/server-endpoint.ts +38 -0
  414. package/src/server-errors.ts +93 -0
  415. package/src/server-handshake.ts +783 -0
  416. package/src/server-response.ts +76 -0
  417. package/src/server-trust.ts +245 -0
  418. package/src/setup-confirm.ts +171 -0
  419. package/src/setup.ts +186 -0
  420. package/src/shell-escape.ts +22 -0
  421. package/src/spawn.ts +31 -0
  422. package/src/startup-services.ts +36 -0
  423. package/src/stream-owner.ts +686 -0
  424. package/src/stream-status.ts +337 -0
  425. package/src/sync-roles-render.ts +163 -0
  426. package/src/sync.ts +363 -0
  427. package/src/terminal-title.ts +76 -0
  428. package/src/token-store.ts +102 -0
  429. package/src/tool-manifest.ts +610 -0
  430. package/src/tool-scope.ts +110 -0
  431. package/src/types.ts +5 -0
  432. package/src/unknown-subcommand.ts +35 -0
  433. package/src/version.ts +82 -0
  434. package/src/working-repo.ts +99 -0
  435. package/src/worktree-lifecycle.ts +254 -0
  436. package/dist/auth-recovery.d.ts +0 -33
  437. package/dist/auth-recovery.js +0 -1
  438. package/dist/auth.d.ts +0 -103
  439. package/dist/auth.js +0 -39
  440. package/dist/device-auth.d.ts +0 -75
  441. package/dist/device-auth.js +0 -1
  442. package/dist/drone-address.d.ts +0 -26
  443. package/dist/drone-address.js +0 -1
  444. package/dist/get-started.d.ts +0 -20
  445. package/dist/get-started.js +0 -2
  446. package/dist/health-beat.d.ts +0 -134
  447. package/dist/health-beat.js +0 -1
  448. package/dist/role-section.d.ts +0 -110
  449. package/dist/role-section.js +0 -8
  450. package/dist/setup-action.d.ts +0 -20
  451. package/dist/setup-action.js +0 -1
  452. package/dist/stale-version-check.d.ts +0 -40
  453. package/dist/stale-version-check.js +0 -1
  454. package/dist/subscription-retry.d.ts +0 -40
  455. package/dist/subscription-retry.js +0 -1
  456. package/dist/templates.d.ts +0 -107
  457. package/dist/templates.js +0 -359
  458. package/dist/token-crypto.d.ts +0 -50
  459. package/dist/token-crypto.js +0 -1
@@ -0,0 +1,188 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdir, open, readFile, rename, stat, unlink, writeFile } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+
6
+ const CURSOR_FILE = join(homedir(), '.config', 'borgmcp', 'local-server-cursors.json');
7
+ const CURSOR_LOCK = `${CURSOR_FILE}.lock`;
8
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9
+
10
+ export interface LocalServerCursor {
11
+ id: string;
12
+ created_at: string;
13
+ }
14
+
15
+ export interface LocalServerCursorBinding {
16
+ origin: string;
17
+ trustIdentity: string;
18
+ cubeId: string;
19
+ droneId: string;
20
+ /**
21
+ * client#41: cursor-purpose namespace. Absent (the default) is the UNREAD
22
+ * WATERMARK — the point `read-log unread_only` reads from and advances only
23
+ * on an explicit successful drain. `'stream'` is the SSE DELIVERY/RESUME
24
+ * cursor the live tail advances as it delivers events. Keeping these under
25
+ * separate keys stops SSE delivery from consuming the unread watermark (a
26
+ * wake-triggering entry would otherwise disappear from `unread_only` before
27
+ * the agent drained it — a silent missed wake).
28
+ */
29
+ purpose?: 'stream';
30
+ }
31
+
32
+ interface CursorFile {
33
+ version: 1;
34
+ cursors: Record<string, LocalServerCursor>;
35
+ }
36
+
37
+ function cursorKey(binding: LocalServerCursorBinding): string {
38
+ if (
39
+ new URL(binding.origin).origin !== binding.origin ||
40
+ !UUID_RE.test(binding.cubeId) ||
41
+ !UUID_RE.test(binding.droneId)
42
+ ) {
43
+ throw new Error('invalid local Borg server cursor binding');
44
+ }
45
+ const hash = createHash('sha256')
46
+ .update(binding.origin)
47
+ .update('\0')
48
+ .update(binding.trustIdentity)
49
+ .update('\0')
50
+ .update(binding.cubeId)
51
+ .update('\0')
52
+ .update(binding.droneId);
53
+ // The purpose component is appended ONLY when present, so the unread-watermark
54
+ // key (purpose absent) stays byte-identical to the pre-client#41 key — already
55
+ // persisted watermarks are not orphaned by the upgrade. The 'stream' delivery
56
+ // cursor gets a distinct key.
57
+ if (binding.purpose) {
58
+ hash.update('\0').update(binding.purpose);
59
+ }
60
+ return hash.digest('hex');
61
+ }
62
+
63
+ function validCursor(value: unknown): value is LocalServerCursor {
64
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;
65
+ const cursor = value as Record<string, unknown>;
66
+ return UUID_RE.test(String(cursor.id ?? '')) &&
67
+ typeof cursor.created_at === 'string' &&
68
+ Number.isFinite(Date.parse(cursor.created_at)) &&
69
+ new Date(cursor.created_at).toISOString() === cursor.created_at;
70
+ }
71
+
72
+ async function readState(): Promise<CursorFile> {
73
+ try {
74
+ const parsed = JSON.parse(await readFile(CURSOR_FILE, 'utf8')) as Partial<CursorFile>;
75
+ if (
76
+ parsed.version !== 1 ||
77
+ typeof parsed.cursors !== 'object' ||
78
+ parsed.cursors === null ||
79
+ Array.isArray(parsed.cursors) ||
80
+ Object.values(parsed.cursors).some((cursor) => !validCursor(cursor))
81
+ ) {
82
+ throw new Error('invalid');
83
+ }
84
+ return parsed as CursorFile;
85
+ } catch (error) {
86
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
87
+ return { version: 1, cursors: {} };
88
+ }
89
+ throw new Error('local Borg server cursor state is corrupt');
90
+ }
91
+ }
92
+
93
+ async function writeState(state: CursorFile): Promise<void> {
94
+ await mkdir(dirname(CURSOR_FILE), { recursive: true });
95
+ const temporary = `${CURSOR_FILE}.${process.pid}.${Date.now()}.tmp`;
96
+ await writeFile(temporary, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
97
+ await rename(temporary, CURSOR_FILE);
98
+ }
99
+
100
+ async function withLock<T>(operation: () => Promise<T>): Promise<T> {
101
+ await mkdir(dirname(CURSOR_LOCK), { recursive: true });
102
+ for (let attempt = 0; attempt < 200; attempt += 1) {
103
+ let handle;
104
+ try {
105
+ handle = await open(CURSOR_LOCK, 'wx', 0o600);
106
+ } catch (error) {
107
+ if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
108
+ try {
109
+ const metadata = await stat(CURSOR_LOCK);
110
+ if (Date.now() - metadata.mtimeMs > 30_000) {
111
+ await unlink(CURSOR_LOCK);
112
+ continue;
113
+ }
114
+ } catch (inspectionError) {
115
+ if ((inspectionError as NodeJS.ErrnoException).code === 'ENOENT') continue;
116
+ throw inspectionError;
117
+ }
118
+ await new Promise((resolvePromise) => setTimeout(resolvePromise, 10));
119
+ continue;
120
+ }
121
+ try {
122
+ return await operation();
123
+ } finally {
124
+ await handle.close();
125
+ try {
126
+ await unlink(CURSOR_LOCK);
127
+ } catch (error) {
128
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
129
+ }
130
+ }
131
+ }
132
+ throw new Error('local Borg server cursor state is busy');
133
+ }
134
+
135
+ export async function getLocalServerCursor(
136
+ binding: LocalServerCursorBinding,
137
+ ): Promise<LocalServerCursor | null> {
138
+ const key = cursorKey(binding);
139
+ const state = await readState();
140
+ return state.cursors[key] ?? null;
141
+ }
142
+
143
+ export async function advanceLocalServerCursor(
144
+ binding: LocalServerCursorBinding,
145
+ cursor: LocalServerCursor,
146
+ ): Promise<void> {
147
+ if (!validCursor(cursor)) throw new Error('invalid local Borg server cursor');
148
+ const key = cursorKey(binding);
149
+ await withLock(async () => {
150
+ const state = await readState();
151
+ const prior = state.cursors[key];
152
+ if (
153
+ prior &&
154
+ (prior.created_at > cursor.created_at ||
155
+ (prior.created_at === cursor.created_at && prior.id >= cursor.id))
156
+ ) {
157
+ return;
158
+ }
159
+ state.cursors[key] = cursor;
160
+ await writeState(state);
161
+ });
162
+ }
163
+
164
+ /**
165
+ * client#42: reset (delete) a persisted cursor for `binding`. Used by the SSE
166
+ * recovery path when the server returns 410 CURSOR_EXPIRED for the stream's
167
+ * resume cursor — the pointed-at entry has been pruned server-side, so the
168
+ * stale cursor can never be resumed and must be cleared, letting the next
169
+ * stream connect re-establish from a fresh valid point (the current tail)
170
+ * instead of looping forever on the dead cursor. No-op when no cursor is
171
+ * stored for the binding.
172
+ */
173
+ export async function clearLocalServerCursor(
174
+ binding: LocalServerCursorBinding,
175
+ ): Promise<void> {
176
+ const key = cursorKey(binding);
177
+ await withLock(async () => {
178
+ const state = await readState();
179
+ if (!(key in state.cursors)) return;
180
+ delete state.cursors[key];
181
+ await writeState(state);
182
+ });
183
+ }
184
+
185
+ export function encodeLocalServerCursor(cursor: LocalServerCursor): string {
186
+ if (!validCursor(cursor)) throw new Error('invalid local Borg server cursor');
187
+ return Buffer.from(JSON.stringify(cursor), 'utf8').toString('base64url');
188
+ }
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * borg-log-audit
4
+ *
5
+ * Domain-agnostic nudge: scans the Claude Code transcript and emits a
6
+ * one-line warning to stdout if the drone has accumulated MATERIAL_THRESHOLD
7
+ * or more state-changing tool calls (Edit / Write / Bash / etc.) since the
8
+ * last borg_log post. Wired in as a UserPromptSubmit hook so the warning
9
+ * becomes additional context for the next turn.
10
+ *
11
+ * Two refinements vs the v1 1-tool threshold (per drone-6's review):
12
+ * 1. Counts material tools across all assistant turns until either the
13
+ * threshold is hit OR a borg_log call is found (cooldown). One
14
+ * diagnostic Bash no longer triggers; substantive work always does.
15
+ * 2. Any borg_log in the scanback suppresses the nudge — so the drone
16
+ * gets a turn of breathing room after each post.
17
+ *
18
+ * Stays generic — knows nothing about git, branches, or any project's
19
+ * conventions. Only the Anthropic tool name `mcp__borg__borg_log` and a
20
+ * small set of canonical mutating tool names. If no cube is active in
21
+ * this project, silently exits.
22
+ *
23
+ * Hook input arrives as JSON on stdin (Claude Code's standard hook
24
+ * contract). The relevant field is `transcript_path`.
25
+ */
26
+
27
+ import { existsSync, readFileSync } from 'node:fs';
28
+ import { getActiveCube } from './cubes.js';
29
+ import { handleVersionFlag } from './version.js';
30
+ import { gateAllowsActivation } from './launch-gate.js';
31
+
32
+ const MATERIAL_TOOLS = new Set([
33
+ 'Edit',
34
+ 'Write',
35
+ 'MultiEdit',
36
+ 'NotebookEdit',
37
+ 'Bash',
38
+ 'apply_patch',
39
+ 'exec_command',
40
+ 'functions.exec_command',
41
+ 'functions.apply_patch',
42
+ ]);
43
+
44
+ const LOG_TOOL = 'mcp__borg__borg_log';
45
+
46
+ // Number of state-changing tool calls since the last borg_log that the
47
+ // drone is allowed before the audit nudges. 1 false-positives on
48
+ // diagnostic Bash (git status, ls, etc.); 3 has been comfortable in
49
+ // dogfooding — any substantive work crosses it within a turn or two.
50
+ const MATERIAL_THRESHOLD = 3;
51
+
52
+ // Cap on how many transcript entries we scan backwards before giving up.
53
+ // Sessions with thousands of turns still resolve in milliseconds at this
54
+ // bound, and anything truly old is no longer "the last span the drone
55
+ // failed to log."
56
+ const MAX_SCAN = 400;
57
+
58
+ interface HookInput {
59
+ transcript_path?: string;
60
+ cwd?: string;
61
+ }
62
+
63
+ function isUserPrompt(entry: any): boolean {
64
+ const type = entry?.type ?? entry?.role;
65
+ if (type !== 'user') return false;
66
+ const content = entry?.message?.content ?? entry?.content;
67
+ if (typeof content === 'string') return content.trim().length > 0;
68
+ if (!Array.isArray(content)) return false;
69
+ // A "real" user prompt has at least one text block. A tool_result-only
70
+ // user message is a continuation of an assistant span, not a prompt.
71
+ return content.some((b: any) => b?.type === 'text');
72
+ }
73
+
74
+ function isAssistant(entry: any): boolean {
75
+ const type = entry?.type ?? entry?.role;
76
+ return type === 'assistant' || type === 'response_item';
77
+ }
78
+
79
+ type ScanFinding =
80
+ | { kind: 'cooldown' } // hit a borg_log before threshold — suppress
81
+ | { kind: 'over_threshold'; count: number } // accumulated >= threshold
82
+ | { kind: 'under_threshold'; count: number }; // ran out of transcript
83
+
84
+ function scanAssistant(entry: any, state: { material: number; loggedRecently: boolean }): void {
85
+ const payload = entry?.payload;
86
+ const payloadToolName =
87
+ payload?.type === 'function_call' || payload?.type === 'custom_tool_call'
88
+ ? payload.name
89
+ : null;
90
+ if (typeof payloadToolName === 'string') {
91
+ if (payloadToolName === LOG_TOOL) {
92
+ state.loggedRecently = true;
93
+ return;
94
+ }
95
+ if (MATERIAL_TOOLS.has(payloadToolName)) state.material += 1;
96
+ }
97
+
98
+ const content = entry?.message?.content ?? entry?.content ?? [];
99
+ if (!Array.isArray(content)) return;
100
+ // Walk the blocks newest-first WITHIN the entry. The caller already
101
+ // visits entries newest-first. Counting forward within an entry would
102
+ // either miss post-log material work (if log is in the same entry as
103
+ // later material blocks) or inflate the count with pre-log work that
104
+ // the log already covered. Reversing here keeps "material since the
105
+ // last log" honest at block granularity.
106
+ for (let i = content.length - 1; i >= 0; i--) {
107
+ const block = content[i];
108
+ if (block?.type !== 'tool_use') continue;
109
+ if (block.name === LOG_TOOL) {
110
+ state.loggedRecently = true;
111
+ return;
112
+ }
113
+ if (MATERIAL_TOOLS.has(block.name)) state.material += 1;
114
+ }
115
+ }
116
+
117
+ async function readStdin(): Promise<string> {
118
+ if (process.stdin.isTTY) return '';
119
+ const chunks: Buffer[] = [];
120
+ for await (const chunk of process.stdin) chunks.push(chunk as Buffer);
121
+ return Buffer.concat(chunks).toString('utf-8');
122
+ }
123
+
124
+ async function main(): Promise<void> {
125
+ handleVersionFlag();
126
+ // gh#673 P1 (WI-4): the log-audit nudge only activates in
127
+ // borg-launched sessions — vanilla `claude` gets no borg hook output.
128
+ // Exit-0 no-op (a UserPromptSubmit hook must never block the prompt).
129
+ // ACTIVATION-only, never a security gate.
130
+ if (!gateAllowsActivation('borg-log-audit UserPromptSubmit hook')) {
131
+ return;
132
+ }
133
+ const raw = await readStdin();
134
+ let input: HookInput = {};
135
+ if (raw.trim()) {
136
+ try {
137
+ input = JSON.parse(raw);
138
+ } catch {
139
+ // No usable input — silent exit.
140
+ return;
141
+ }
142
+ }
143
+
144
+ if (!input.transcript_path || !existsSync(input.transcript_path)) return;
145
+ if (input.cwd && existsSync(input.cwd)) {
146
+ try {
147
+ process.chdir(input.cwd);
148
+ } catch {
149
+ // Best-effort only; fall back to the hook process cwd.
150
+ }
151
+ }
152
+
153
+ // Only nudge if there's an active cube in this project. Otherwise the
154
+ // hook is fully inert.
155
+ const active = await getActiveCube();
156
+ if (!active) return;
157
+
158
+ const lines = readFileSync(input.transcript_path, 'utf-8').split('\n').filter(Boolean);
159
+ if (lines.length === 0) return;
160
+
161
+ // Walk the transcript backwards from the end. The trailing entry MAY
162
+ // be the user prompt that triggered this hook; skip it if so. From
163
+ // there, accumulate material tool calls until either we hit a borg_log
164
+ // (cooldown — suppress) or we cross MATERIAL_THRESHOLD (nudge). The
165
+ // scan stops after MAX_SCAN entries to bound work on huge sessions.
166
+ let i = lines.length - 1;
167
+ const tail = safeParse(lines[i]);
168
+ if (tail && isUserPrompt(tail)) i--;
169
+
170
+ const state = { material: 0, loggedRecently: false };
171
+ let scanned = 0;
172
+ for (; i >= 0 && scanned < MAX_SCAN; i--, scanned++) {
173
+ const entry = safeParse(lines[i]);
174
+ if (!entry) continue;
175
+ if (isAssistant(entry)) {
176
+ scanAssistant(entry, state);
177
+ // Threshold has primacy over cooldown: when both could fire on the
178
+ // same entry (e.g. an entry containing [log, Bash, Bash, Bash]
179
+ // where the reversed scan first counts 3 material blocks before
180
+ // hitting the log), we want the nudge — the post-log material
181
+ // work hasn't been logged yet.
182
+ if (state.material >= MATERIAL_THRESHOLD) {
183
+ process.stdout.write(
184
+ `Heads up: ${state.material}+ state-changing tool calls since the last \`borg_log\` post. ` +
185
+ 'If that work was a substantive unit (a change that ships, a blocker hit, a finding ' +
186
+ "worth sharing), post to the cube log per your role's conventions before continuing.\n"
187
+ );
188
+ return;
189
+ }
190
+ if (state.loggedRecently) return; // cooldown
191
+ }
192
+ }
193
+ // Reached MAX_SCAN or start of transcript without finding either a
194
+ // log call or enough material work. Silent.
195
+ }
196
+
197
+ function safeParse(line: string): any | null {
198
+ try {
199
+ return JSON.parse(line);
200
+ } catch {
201
+ return null;
202
+ }
203
+ }
204
+
205
+ main().catch(() => {
206
+ // Never fail a hook — silent on error.
207
+ });