@loompad/cli 0.1.0 → 1.1.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 (688) hide show
  1. package/ARCHITECTURE.md +96 -11
  2. package/CHANGELOG.md +1054 -0
  3. package/README.md +1473 -44
  4. package/THIRD_PARTY_NOTICES.md +275 -0
  5. package/dist/adapters/antigravity-cli.d.ts +62 -0
  6. package/dist/adapters/antigravity-cli.js +258 -0
  7. package/dist/adapters/antigravity-cli.js.map +1 -0
  8. package/dist/adapters/base.d.ts +61 -9
  9. package/dist/adapters/base.js +266 -15
  10. package/dist/adapters/base.js.map +1 -1
  11. package/dist/adapters/bridges/antigravity.d.ts +9 -12
  12. package/dist/adapters/bridges/antigravity.js +9 -12
  13. package/dist/adapters/bridges/antigravity.js.map +1 -1
  14. package/dist/adapters/echo.d.ts +1 -0
  15. package/dist/adapters/echo.js +59 -3
  16. package/dist/adapters/echo.js.map +1 -1
  17. package/dist/adapters/grok.d.ts +7 -0
  18. package/dist/adapters/grok.js +20 -10
  19. package/dist/adapters/grok.js.map +1 -1
  20. package/dist/adapters/index.d.ts +5 -1
  21. package/dist/adapters/index.js +53 -7
  22. package/dist/adapters/index.js.map +1 -1
  23. package/dist/adapters/model.d.ts +137 -0
  24. package/dist/adapters/model.js +527 -0
  25. package/dist/adapters/model.js.map +1 -0
  26. package/dist/adapters/opencode.d.ts +101 -1
  27. package/dist/adapters/opencode.js +874 -98
  28. package/dist/adapters/opencode.js.map +1 -1
  29. package/dist/cli/doctor.d.ts +32 -0
  30. package/dist/cli/doctor.js +89 -4
  31. package/dist/cli/doctor.js.map +1 -1
  32. package/dist/cli/index.js +2651 -87
  33. package/dist/cli/index.js.map +1 -1
  34. package/dist/cli/tui-model.js +3 -1
  35. package/dist/cli/tui-model.js.map +1 -1
  36. package/dist/cli/tui.js +44 -1
  37. package/dist/cli/tui.js.map +1 -1
  38. package/dist/cli/ui.d.ts +2 -0
  39. package/dist/cli/ui.js +13 -0
  40. package/dist/cli/ui.js.map +1 -1
  41. package/dist/core/ades.d.ts +32 -16
  42. package/dist/core/ades.js +57 -20
  43. package/dist/core/ades.js.map +1 -1
  44. package/dist/core/agent-state.d.ts +14 -0
  45. package/dist/core/agent-state.js +32 -0
  46. package/dist/core/agent-state.js.map +1 -0
  47. package/dist/core/approvals.d.ts +33 -0
  48. package/dist/core/approvals.js +29 -0
  49. package/dist/core/approvals.js.map +1 -0
  50. package/dist/core/backup.d.ts +19 -0
  51. package/dist/core/backup.js +86 -0
  52. package/dist/core/backup.js.map +1 -0
  53. package/dist/core/baton.d.ts +2 -2
  54. package/dist/core/baton.js.map +1 -1
  55. package/dist/core/brain-extract.d.ts +17 -0
  56. package/dist/core/brain-extract.js +28 -2
  57. package/dist/core/brain-extract.js.map +1 -1
  58. package/dist/core/brain-index.d.ts +71 -0
  59. package/dist/core/brain-index.js +204 -5
  60. package/dist/core/brain-index.js.map +1 -1
  61. package/dist/core/brain.d.ts +58 -2
  62. package/dist/core/brain.js +79 -1
  63. package/dist/core/brain.js.map +1 -1
  64. package/dist/core/chat-import.d.ts +71 -0
  65. package/dist/core/chat-import.js +419 -0
  66. package/dist/core/chat-import.js.map +1 -0
  67. package/dist/core/checkpoint.d.ts +107 -0
  68. package/dist/core/checkpoint.js +259 -0
  69. package/dist/core/checkpoint.js.map +1 -0
  70. package/dist/core/claude-cli.js +1 -1
  71. package/dist/core/claude-cli.js.map +1 -1
  72. package/dist/core/continuity/artifacts.d.ts +14 -0
  73. package/dist/core/continuity/artifacts.js +118 -0
  74. package/dist/core/continuity/artifacts.js.map +1 -0
  75. package/dist/core/continuity/capabilities.d.ts +65 -0
  76. package/dist/core/continuity/capabilities.js +129 -0
  77. package/dist/core/continuity/capabilities.js.map +1 -0
  78. package/dist/core/continuity/contracts.d.ts +352 -0
  79. package/dist/core/continuity/contracts.js +117 -0
  80. package/dist/core/continuity/contracts.js.map +1 -0
  81. package/dist/core/continuity/engine.d.ts +55 -0
  82. package/dist/core/continuity/engine.js +504 -0
  83. package/dist/core/continuity/engine.js.map +1 -0
  84. package/dist/core/continuity/store.d.ts +73 -0
  85. package/dist/core/continuity/store.js +438 -0
  86. package/dist/core/continuity/store.js.map +1 -0
  87. package/dist/core/conversations.d.ts +19 -0
  88. package/dist/core/conversations.js +87 -0
  89. package/dist/core/conversations.js.map +1 -0
  90. package/dist/core/crew-coordination.d.ts +6 -0
  91. package/dist/core/crew-coordination.js +24 -0
  92. package/dist/core/crew-coordination.js.map +1 -0
  93. package/dist/core/crew-policy.d.ts +18 -0
  94. package/dist/core/crew-policy.js +40 -0
  95. package/dist/core/crew-policy.js.map +1 -0
  96. package/dist/core/crew-protocol.d.ts +64 -0
  97. package/dist/core/crew-protocol.js +146 -0
  98. package/dist/core/crew-protocol.js.map +1 -0
  99. package/dist/core/crew-requests.d.ts +14 -0
  100. package/dist/core/crew-requests.js +22 -0
  101. package/dist/core/crew-requests.js.map +1 -0
  102. package/dist/core/crew.d.ts +395 -0
  103. package/dist/core/crew.js +1857 -0
  104. package/dist/core/crew.js.map +1 -0
  105. package/dist/core/digest.d.ts +40 -0
  106. package/dist/core/digest.js +94 -0
  107. package/dist/core/digest.js.map +1 -0
  108. package/dist/core/distill.js +3 -5
  109. package/dist/core/distill.js.map +1 -1
  110. package/dist/core/eventlog.d.ts +27 -25
  111. package/dist/core/eventlog.js +97 -150
  112. package/dist/core/eventlog.js.map +1 -1
  113. package/dist/core/events/contracts.d.ts +51 -0
  114. package/dist/core/events/contracts.js +2 -0
  115. package/dist/core/events/contracts.js.map +1 -0
  116. package/dist/core/events/jsonl-store.d.ts +23 -0
  117. package/dist/core/events/jsonl-store.js +90 -0
  118. package/dist/core/events/jsonl-store.js.map +1 -0
  119. package/dist/core/events/sqlite-store.d.ts +37 -0
  120. package/dist/core/events/sqlite-store.js +215 -0
  121. package/dist/core/events/sqlite-store.js.map +1 -0
  122. package/dist/core/forecast.d.ts +44 -0
  123. package/dist/core/forecast.js +46 -0
  124. package/dist/core/forecast.js.map +1 -0
  125. package/dist/core/free-pool.d.ts +65 -0
  126. package/dist/core/free-pool.js +171 -0
  127. package/dist/core/free-pool.js.map +1 -0
  128. package/dist/core/git.d.ts +30 -0
  129. package/dist/core/git.js +50 -2
  130. package/dist/core/git.js.map +1 -1
  131. package/dist/core/github-events.d.ts +53 -0
  132. package/dist/core/github-events.js +227 -0
  133. package/dist/core/github-events.js.map +1 -0
  134. package/dist/core/goal-lanes.d.ts +53 -0
  135. package/dist/core/goal-lanes.js +99 -0
  136. package/dist/core/goal-lanes.js.map +1 -0
  137. package/dist/core/hosted.d.ts +27 -0
  138. package/dist/core/hosted.js +50 -0
  139. package/dist/core/hosted.js.map +1 -0
  140. package/dist/core/http-server.d.ts +5 -0
  141. package/dist/core/http-server.js +8 -0
  142. package/dist/core/http-server.js.map +1 -0
  143. package/dist/core/invite-link.d.ts +31 -0
  144. package/dist/core/invite-link.js +45 -0
  145. package/dist/core/invite-link.js.map +1 -0
  146. package/dist/core/loops.d.ts +37 -0
  147. package/dist/core/loops.js +81 -0
  148. package/dist/core/loops.js.map +1 -0
  149. package/dist/core/mcp-catalog.d.ts +182 -0
  150. package/dist/core/mcp-catalog.js +431 -0
  151. package/dist/core/mcp-catalog.js.map +1 -0
  152. package/dist/core/mcp.d.ts +87 -0
  153. package/dist/core/mcp.js +181 -0
  154. package/dist/core/mcp.js.map +1 -0
  155. package/dist/core/memory.d.ts +1 -0
  156. package/dist/core/memory.js +5 -2
  157. package/dist/core/memory.js.map +1 -1
  158. package/dist/core/model-tools.d.ts +97 -0
  159. package/dist/core/model-tools.js +388 -0
  160. package/dist/core/model-tools.js.map +1 -0
  161. package/dist/core/notify.js +19 -1
  162. package/dist/core/notify.js.map +1 -1
  163. package/dist/core/orchestra.d.ts +635 -0
  164. package/dist/core/orchestra.js +2120 -0
  165. package/dist/core/orchestra.js.map +1 -0
  166. package/dist/core/permissions.d.ts +56 -0
  167. package/dist/core/permissions.js +122 -0
  168. package/dist/core/permissions.js.map +1 -0
  169. package/dist/core/preview-proxy.d.ts +70 -0
  170. package/dist/core/preview-proxy.js +563 -0
  171. package/dist/core/preview-proxy.js.map +1 -0
  172. package/dist/core/preview-shot.d.ts +46 -0
  173. package/dist/core/preview-shot.js +109 -0
  174. package/dist/core/preview-shot.js.map +1 -0
  175. package/dist/core/process.d.ts +36 -0
  176. package/dist/core/process.js +168 -0
  177. package/dist/core/process.js.map +1 -0
  178. package/dist/core/prompt-queue.d.ts +136 -0
  179. package/dist/core/prompt-queue.js +269 -0
  180. package/dist/core/prompt-queue.js.map +1 -0
  181. package/dist/core/prompts.d.ts +53 -0
  182. package/dist/core/prompts.js +127 -0
  183. package/dist/core/prompts.js.map +1 -0
  184. package/dist/core/proof.d.ts +82 -0
  185. package/dist/core/proof.js +216 -0
  186. package/dist/core/proof.js.map +1 -0
  187. package/dist/core/provider-text.d.ts +23 -0
  188. package/dist/core/provider-text.js +66 -0
  189. package/dist/core/provider-text.js.map +1 -0
  190. package/dist/core/providers.d.ts +152 -0
  191. package/dist/core/providers.js +343 -0
  192. package/dist/core/providers.js.map +1 -0
  193. package/dist/core/quota.d.ts +33 -0
  194. package/dist/core/quota.js +74 -0
  195. package/dist/core/quota.js.map +1 -0
  196. package/dist/core/recipes.d.ts +50 -0
  197. package/dist/core/recipes.js +99 -0
  198. package/dist/core/recipes.js.map +1 -0
  199. package/dist/core/registry.d.ts +54 -0
  200. package/dist/core/registry.js +62 -5
  201. package/dist/core/registry.js.map +1 -1
  202. package/dist/core/relay-client.d.ts +67 -0
  203. package/dist/core/relay-client.js +184 -0
  204. package/dist/core/relay-client.js.map +1 -0
  205. package/dist/core/relay-protocol.d.ts +140 -0
  206. package/dist/core/relay-protocol.js +189 -0
  207. package/dist/core/relay-protocol.js.map +1 -0
  208. package/dist/core/replay.d.ts +18 -0
  209. package/dist/core/replay.js +191 -0
  210. package/dist/core/replay.js.map +1 -0
  211. package/dist/core/review-triage.d.ts +41 -0
  212. package/dist/core/review-triage.js +124 -0
  213. package/dist/core/review-triage.js.map +1 -0
  214. package/dist/core/router.js +2 -2
  215. package/dist/core/router.js.map +1 -1
  216. package/dist/core/routes.d.ts +39 -3
  217. package/dist/core/routes.js +137 -4
  218. package/dist/core/routes.js.map +1 -1
  219. package/dist/core/run-command.d.ts +14 -0
  220. package/dist/core/run-command.js +45 -0
  221. package/dist/core/run-command.js.map +1 -0
  222. package/dist/core/runner-setup.d.ts +36 -0
  223. package/dist/core/runner-setup.js +114 -0
  224. package/dist/core/runner-setup.js.map +1 -0
  225. package/dist/core/search.js +0 -0
  226. package/dist/core/search.js.map +1 -1
  227. package/dist/core/semantic.d.ts +92 -0
  228. package/dist/core/semantic.js +227 -0
  229. package/dist/core/semantic.js.map +1 -0
  230. package/dist/core/servers.d.ts +115 -0
  231. package/dist/core/servers.js +305 -0
  232. package/dist/core/servers.js.map +1 -0
  233. package/dist/core/setup.js +64 -6
  234. package/dist/core/setup.js.map +1 -1
  235. package/dist/core/shield.d.ts +17 -0
  236. package/dist/core/shield.js +81 -0
  237. package/dist/core/shield.js.map +1 -0
  238. package/dist/core/shift.d.ts +69 -0
  239. package/dist/core/shift.js +120 -0
  240. package/dist/core/shift.js.map +1 -0
  241. package/dist/core/skill-install.d.ts +125 -0
  242. package/dist/core/skill-install.js +328 -0
  243. package/dist/core/skill-install.js.map +1 -0
  244. package/dist/core/skills.d.ts +116 -0
  245. package/dist/core/skills.js +223 -0
  246. package/dist/core/skills.js.map +1 -0
  247. package/dist/core/step-conditions.d.ts +65 -0
  248. package/dist/core/step-conditions.js +102 -0
  249. package/dist/core/step-conditions.js.map +1 -0
  250. package/dist/core/subagents.d.ts +45 -0
  251. package/dist/core/subagents.js +90 -0
  252. package/dist/core/subagents.js.map +1 -0
  253. package/dist/core/team-canon.d.ts +42 -0
  254. package/dist/core/team-canon.js +121 -0
  255. package/dist/core/team-canon.js.map +1 -0
  256. package/dist/core/team-crypto.d.ts +97 -0
  257. package/dist/core/team-crypto.js +175 -0
  258. package/dist/core/team-crypto.js.map +1 -0
  259. package/dist/core/team-hub.d.ts +514 -0
  260. package/dist/core/team-hub.js +964 -0
  261. package/dist/core/team-hub.js.map +1 -0
  262. package/dist/core/team-landing.d.ts +239 -0
  263. package/dist/core/team-landing.js +504 -0
  264. package/dist/core/team-landing.js.map +1 -0
  265. package/dist/core/team-leases.d.ts +44 -0
  266. package/dist/core/team-leases.js +145 -0
  267. package/dist/core/team-leases.js.map +1 -0
  268. package/dist/core/team-memory.d.ts +42 -0
  269. package/dist/core/team-memory.js +84 -0
  270. package/dist/core/team-memory.js.map +1 -0
  271. package/dist/core/team-policy.d.ts +85 -0
  272. package/dist/core/team-policy.js +191 -0
  273. package/dist/core/team-policy.js.map +1 -0
  274. package/dist/core/thread-md.d.ts +6 -0
  275. package/dist/core/thread-md.js +42 -0
  276. package/dist/core/thread-md.js.map +1 -0
  277. package/dist/core/turn-stats.d.ts +61 -0
  278. package/dist/core/turn-stats.js +124 -0
  279. package/dist/core/turn-stats.js.map +1 -0
  280. package/dist/core/updater.d.ts +73 -0
  281. package/dist/core/updater.js +153 -0
  282. package/dist/core/updater.js.map +1 -0
  283. package/dist/core/usage.d.ts +75 -0
  284. package/dist/core/usage.js +163 -0
  285. package/dist/core/usage.js.map +1 -0
  286. package/dist/core/windows-jobs.d.ts +15 -0
  287. package/dist/core/windows-jobs.js +170 -0
  288. package/dist/core/windows-jobs.js.map +1 -0
  289. package/dist/core/worktree-merge.d.ts +57 -0
  290. package/dist/core/worktree-merge.js +123 -0
  291. package/dist/core/worktree-merge.js.map +1 -0
  292. package/dist/core/worktree.d.ts +5 -0
  293. package/dist/core/worktree.js +45 -5
  294. package/dist/core/worktree.js.map +1 -1
  295. package/dist/core/worktrees.d.ts +6 -0
  296. package/dist/core/worktrees.js +21 -0
  297. package/dist/core/worktrees.js.map +1 -0
  298. package/dist/daemon/app-page.d.ts +0 -17
  299. package/dist/daemon/app-page.js +10 -6346
  300. package/dist/daemon/app-page.js.map +1 -1
  301. package/dist/daemon/auth.d.ts +24 -3
  302. package/dist/daemon/auth.js +66 -7
  303. package/dist/daemon/auth.js.map +1 -1
  304. package/dist/daemon/board.d.ts +7 -0
  305. package/dist/daemon/board.js +12 -1
  306. package/dist/daemon/board.js.map +1 -1
  307. package/dist/daemon/brand-icons.d.ts +6 -1
  308. package/dist/daemon/brand-icons.js +11 -3
  309. package/dist/daemon/brand-icons.js.map +1 -1
  310. package/dist/daemon/client.d.ts +665 -1
  311. package/dist/daemon/client.js +381 -3
  312. package/dist/daemon/client.js.map +1 -1
  313. package/dist/daemon/delivery.d.ts +34 -0
  314. package/dist/daemon/delivery.js +63 -0
  315. package/dist/daemon/delivery.js.map +1 -0
  316. package/dist/daemon/deploys.d.ts +62 -0
  317. package/dist/daemon/deploys.js +159 -0
  318. package/dist/daemon/deploys.js.map +1 -0
  319. package/dist/daemon/landing.d.ts +192 -0
  320. package/dist/daemon/landing.js +992 -0
  321. package/dist/daemon/landing.js.map +1 -0
  322. package/dist/daemon/onboard.d.ts +150 -0
  323. package/dist/daemon/onboard.js +390 -0
  324. package/dist/daemon/onboard.js.map +1 -0
  325. package/dist/daemon/proof.d.ts +70 -0
  326. package/dist/daemon/proof.js +172 -0
  327. package/dist/daemon/proof.js.map +1 -0
  328. package/dist/daemon/push.d.ts +19 -1
  329. package/dist/daemon/push.js +90 -3
  330. package/dist/daemon/push.js.map +1 -1
  331. package/dist/daemon/relay.d.ts +82 -0
  332. package/dist/daemon/relay.js +351 -0
  333. package/dist/daemon/relay.js.map +1 -0
  334. package/dist/daemon/routes/agent-discovery.d.ts +4 -0
  335. package/dist/daemon/routes/agent-discovery.js +29 -0
  336. package/dist/daemon/routes/agent-discovery.js.map +1 -0
  337. package/dist/daemon/routes/agent-settings.d.ts +4 -0
  338. package/dist/daemon/routes/agent-settings.js +94 -0
  339. package/dist/daemon/routes/agent-settings.js.map +1 -0
  340. package/dist/daemon/routes/agents.d.ts +4 -0
  341. package/dist/daemon/routes/agents.js +105 -0
  342. package/dist/daemon/routes/agents.js.map +1 -0
  343. package/dist/daemon/routes/alerts.d.ts +4 -0
  344. package/dist/daemon/routes/alerts.js +137 -0
  345. package/dist/daemon/routes/alerts.js.map +1 -0
  346. package/dist/daemon/routes/approvals.d.ts +4 -0
  347. package/dist/daemon/routes/approvals.js +40 -0
  348. package/dist/daemon/routes/approvals.js.map +1 -0
  349. package/dist/daemon/routes/assets.d.ts +3 -0
  350. package/dist/daemon/routes/assets.js +64 -0
  351. package/dist/daemon/routes/assets.js.map +1 -0
  352. package/dist/daemon/routes/board.d.ts +4 -0
  353. package/dist/daemon/routes/board.js +147 -0
  354. package/dist/daemon/routes/board.js.map +1 -0
  355. package/dist/daemon/routes/brain.d.ts +4 -0
  356. package/dist/daemon/routes/brain.js +270 -0
  357. package/dist/daemon/routes/brain.js.map +1 -0
  358. package/dist/daemon/routes/chats.d.ts +4 -0
  359. package/dist/daemon/routes/chats.js +249 -0
  360. package/dist/daemon/routes/chats.js.map +1 -0
  361. package/dist/daemon/routes/clients.d.ts +4 -0
  362. package/dist/daemon/routes/clients.js +49 -0
  363. package/dist/daemon/routes/clients.js.map +1 -0
  364. package/dist/daemon/routes/cloud.d.ts +4 -0
  365. package/dist/daemon/routes/cloud.js +46 -0
  366. package/dist/daemon/routes/cloud.js.map +1 -0
  367. package/dist/daemon/routes/config.d.ts +4 -0
  368. package/dist/daemon/routes/config.js +35 -0
  369. package/dist/daemon/routes/config.js.map +1 -0
  370. package/dist/daemon/routes/context.d.ts +51 -0
  371. package/dist/daemon/routes/context.js +2 -0
  372. package/dist/daemon/routes/context.js.map +1 -0
  373. package/dist/daemon/routes/crews.d.ts +4 -0
  374. package/dist/daemon/routes/crews.js +149 -0
  375. package/dist/daemon/routes/crews.js.map +1 -0
  376. package/dist/daemon/routes/files.d.ts +3 -0
  377. package/dist/daemon/routes/files.js +253 -0
  378. package/dist/daemon/routes/files.js.map +1 -0
  379. package/dist/daemon/routes/git.d.ts +4 -0
  380. package/dist/daemon/routes/git.js +96 -0
  381. package/dist/daemon/routes/git.js.map +1 -0
  382. package/dist/daemon/routes/history.d.ts +4 -0
  383. package/dist/daemon/routes/history.js +101 -0
  384. package/dist/daemon/routes/history.js.map +1 -0
  385. package/dist/daemon/routes/integrations-project.d.ts +3 -0
  386. package/dist/daemon/routes/integrations-project.js +103 -0
  387. package/dist/daemon/routes/integrations-project.js.map +1 -0
  388. package/dist/daemon/routes/integrations.d.ts +3 -0
  389. package/dist/daemon/routes/integrations.js +111 -0
  390. package/dist/daemon/routes/integrations.js.map +1 -0
  391. package/dist/daemon/routes/logs.d.ts +3 -0
  392. package/dist/daemon/routes/logs.js +40 -0
  393. package/dist/daemon/routes/logs.js.map +1 -0
  394. package/dist/daemon/routes/messages.d.ts +4 -0
  395. package/dist/daemon/routes/messages.js +60 -0
  396. package/dist/daemon/routes/messages.js.map +1 -0
  397. package/dist/daemon/routes/observability.d.ts +4 -0
  398. package/dist/daemon/routes/observability.js +247 -0
  399. package/dist/daemon/routes/observability.js.map +1 -0
  400. package/dist/daemon/routes/onboard.d.ts +12 -0
  401. package/dist/daemon/routes/onboard.js +67 -0
  402. package/dist/daemon/routes/onboard.js.map +1 -0
  403. package/dist/daemon/routes/orchestra.d.ts +4 -0
  404. package/dist/daemon/routes/orchestra.js +110 -0
  405. package/dist/daemon/routes/orchestra.js.map +1 -0
  406. package/dist/daemon/routes/pairing.d.ts +4 -0
  407. package/dist/daemon/routes/pairing.js +155 -0
  408. package/dist/daemon/routes/pairing.js.map +1 -0
  409. package/dist/daemon/routes/preview.d.ts +24 -0
  410. package/dist/daemon/routes/preview.js +122 -0
  411. package/dist/daemon/routes/preview.js.map +1 -0
  412. package/dist/daemon/routes/project-actions.d.ts +4 -0
  413. package/dist/daemon/routes/project-actions.js +53 -0
  414. package/dist/daemon/routes/project-actions.js.map +1 -0
  415. package/dist/daemon/routes/project-team.d.ts +4 -0
  416. package/dist/daemon/routes/project-team.js +201 -0
  417. package/dist/daemon/routes/project-team.js.map +1 -0
  418. package/dist/daemon/routes/projects.d.ts +14 -0
  419. package/dist/daemon/routes/projects.js +138 -0
  420. package/dist/daemon/routes/projects.js.map +1 -0
  421. package/dist/daemon/routes/prompts.d.ts +4 -0
  422. package/dist/daemon/routes/prompts.js +44 -0
  423. package/dist/daemon/routes/prompts.js.map +1 -0
  424. package/dist/daemon/routes/proof.d.ts +4 -0
  425. package/dist/daemon/routes/proof.js +22 -0
  426. package/dist/daemon/routes/proof.js.map +1 -0
  427. package/dist/daemon/routes/providers.d.ts +3 -0
  428. package/dist/daemon/routes/providers.js +60 -0
  429. package/dist/daemon/routes/providers.js.map +1 -0
  430. package/dist/daemon/routes/public.d.ts +4 -0
  431. package/dist/daemon/routes/public.js +64 -0
  432. package/dist/daemon/routes/public.js.map +1 -0
  433. package/dist/daemon/routes/queue.d.ts +4 -0
  434. package/dist/daemon/routes/queue.js +140 -0
  435. package/dist/daemon/routes/queue.js.map +1 -0
  436. package/dist/daemon/routes/routing.d.ts +4 -0
  437. package/dist/daemon/routes/routing.js +61 -0
  438. package/dist/daemon/routes/routing.js.map +1 -0
  439. package/dist/daemon/routes/runtime-handler.d.ts +2 -0
  440. package/dist/daemon/routes/runtime-handler.js +63 -0
  441. package/dist/daemon/routes/runtime-handler.js.map +1 -0
  442. package/dist/daemon/routes/search.d.ts +4 -0
  443. package/dist/daemon/routes/search.js +17 -0
  444. package/dist/daemon/routes/search.js.map +1 -0
  445. package/dist/daemon/routes/servers.d.ts +4 -0
  446. package/dist/daemon/routes/servers.js +133 -0
  447. package/dist/daemon/routes/servers.js.map +1 -0
  448. package/dist/daemon/routes/setup.d.ts +3 -0
  449. package/dist/daemon/routes/setup.js +50 -0
  450. package/dist/daemon/routes/setup.js.map +1 -0
  451. package/dist/daemon/routes/shift.d.ts +4 -0
  452. package/dist/daemon/routes/shift.js +30 -0
  453. package/dist/daemon/routes/shift.js.map +1 -0
  454. package/dist/daemon/routes/specs.d.ts +4 -0
  455. package/dist/daemon/routes/specs.js +57 -0
  456. package/dist/daemon/routes/specs.js.map +1 -0
  457. package/dist/daemon/routes/task-delivery.d.ts +4 -0
  458. package/dist/daemon/routes/task-delivery.js +38 -0
  459. package/dist/daemon/routes/task-delivery.js.map +1 -0
  460. package/dist/daemon/routes/team.d.ts +4 -0
  461. package/dist/daemon/routes/team.js +193 -0
  462. package/dist/daemon/routes/team.js.map +1 -0
  463. package/dist/daemon/routes/terminals.d.ts +4 -0
  464. package/dist/daemon/routes/terminals.js +87 -0
  465. package/dist/daemon/routes/terminals.js.map +1 -0
  466. package/dist/daemon/routes/tools.d.ts +4 -0
  467. package/dist/daemon/routes/tools.js +180 -0
  468. package/dist/daemon/routes/tools.js.map +1 -0
  469. package/dist/daemon/routes/updates.d.ts +4 -0
  470. package/dist/daemon/routes/updates.js +89 -0
  471. package/dist/daemon/routes/updates.js.map +1 -0
  472. package/dist/daemon/routes/voice.d.ts +4 -0
  473. package/dist/daemon/routes/voice.js +53 -0
  474. package/dist/daemon/routes/voice.js.map +1 -0
  475. package/dist/daemon/runner.d.ts +186 -0
  476. package/dist/daemon/runner.js +612 -0
  477. package/dist/daemon/runner.js.map +1 -0
  478. package/dist/daemon/runtime/accounting.d.ts +130 -0
  479. package/dist/daemon/runtime/accounting.js +303 -0
  480. package/dist/daemon/runtime/accounting.js.map +1 -0
  481. package/dist/daemon/runtime/agents.d.ts +16 -0
  482. package/dist/daemon/runtime/agents.js +71 -0
  483. package/dist/daemon/runtime/agents.js.map +1 -0
  484. package/dist/daemon/runtime/briefings.d.ts +134 -0
  485. package/dist/daemon/runtime/briefings.js +329 -0
  486. package/dist/daemon/runtime/briefings.js.map +1 -0
  487. package/dist/daemon/runtime/native-usage.d.ts +21 -0
  488. package/dist/daemon/runtime/native-usage.js +71 -0
  489. package/dist/daemon/runtime/native-usage.js.map +1 -0
  490. package/dist/daemon/runtime/queue.d.ts +94 -0
  491. package/dist/daemon/runtime/queue.js +222 -0
  492. package/dist/daemon/runtime/queue.js.map +1 -0
  493. package/dist/daemon/runtime/relay.d.ts +93 -0
  494. package/dist/daemon/runtime/relay.js +240 -0
  495. package/dist/daemon/runtime/relay.js.map +1 -0
  496. package/dist/daemon/runtime/turns.d.ts +202 -0
  497. package/dist/daemon/runtime/turns.js +663 -0
  498. package/dist/daemon/runtime/turns.js.map +1 -0
  499. package/dist/daemon/runtime-support.d.ts +76 -0
  500. package/dist/daemon/runtime-support.js +134 -0
  501. package/dist/daemon/runtime-support.js.map +1 -0
  502. package/dist/daemon/runtime.d.ts +739 -70
  503. package/dist/daemon/runtime.js +2751 -470
  504. package/dist/daemon/runtime.js.map +1 -1
  505. package/dist/daemon/server.d.ts +82 -55
  506. package/dist/daemon/server.js +674 -1435
  507. package/dist/daemon/server.js.map +1 -1
  508. package/dist/daemon/shift.d.ts +70 -0
  509. package/dist/daemon/shift.js +170 -0
  510. package/dist/daemon/shift.js.map +1 -0
  511. package/dist/daemon/specs.d.ts +92 -0
  512. package/dist/daemon/specs.js +285 -0
  513. package/dist/daemon/specs.js.map +1 -0
  514. package/dist/daemon/system.d.ts +208 -0
  515. package/dist/daemon/system.js +557 -0
  516. package/dist/daemon/system.js.map +1 -0
  517. package/dist/daemon/tasks.js +1 -1
  518. package/dist/daemon/team-brain.d.ts +136 -0
  519. package/dist/daemon/team-brain.js +659 -0
  520. package/dist/daemon/team-brain.js.map +1 -0
  521. package/dist/daemon/team-coordinator.d.ts +78 -0
  522. package/dist/daemon/team-coordinator.js +408 -0
  523. package/dist/daemon/team-coordinator.js.map +1 -0
  524. package/dist/daemon/team.d.ts +339 -0
  525. package/dist/daemon/team.js +1433 -0
  526. package/dist/daemon/team.js.map +1 -0
  527. package/dist/daemon/terminals.d.ts +22 -3
  528. package/dist/daemon/terminals.js +236 -16
  529. package/dist/daemon/terminals.js.map +1 -1
  530. package/dist/hub/client.d.ts +120 -0
  531. package/dist/hub/client.js +228 -0
  532. package/dist/hub/client.js.map +1 -0
  533. package/dist/hub/server.d.ts +32 -0
  534. package/dist/hub/server.js +180 -0
  535. package/dist/hub/server.js.map +1 -0
  536. package/dist/hub/supabase-client.d.ts +220 -0
  537. package/dist/hub/supabase-client.js +843 -0
  538. package/dist/hub/supabase-client.js.map +1 -0
  539. package/dist/observability/ask.d.ts +91 -0
  540. package/dist/observability/ask.js +179 -0
  541. package/dist/observability/ask.js.map +1 -0
  542. package/dist/observability/clickhouse.d.ts +33 -0
  543. package/dist/observability/clickhouse.js +48 -0
  544. package/dist/observability/clickhouse.js.map +1 -0
  545. package/dist/observability/decisions.d.ts +176 -0
  546. package/dist/observability/decisions.js +377 -0
  547. package/dist/observability/decisions.js.map +1 -0
  548. package/dist/observability/index.d.ts +89 -0
  549. package/dist/observability/index.js +348 -0
  550. package/dist/observability/index.js.map +1 -0
  551. package/dist/observability/insights.d.ts +151 -0
  552. package/dist/observability/insights.js +319 -0
  553. package/dist/observability/insights.js.map +1 -0
  554. package/dist/observability/logs-query.d.ts +82 -0
  555. package/dist/observability/logs-query.js +102 -0
  556. package/dist/observability/logs-query.js.map +1 -0
  557. package/dist/observability/logs.d.ts +72 -0
  558. package/dist/observability/logs.js +295 -0
  559. package/dist/observability/logs.js.map +1 -0
  560. package/dist/observability/metrics.d.ts +86 -0
  561. package/dist/observability/metrics.js +303 -0
  562. package/dist/observability/metrics.js.map +1 -0
  563. package/dist/observability/otlp.d.ts +127 -0
  564. package/dist/observability/otlp.js +242 -0
  565. package/dist/observability/otlp.js.map +1 -0
  566. package/dist/observability/snapshots.d.ts +43 -0
  567. package/dist/observability/snapshots.js +129 -0
  568. package/dist/observability/snapshots.js.map +1 -0
  569. package/dist/observability/triage.d.ts +49 -0
  570. package/dist/observability/triage.js +284 -0
  571. package/dist/observability/triage.js.map +1 -0
  572. package/dist/providers/adapter.d.ts +50 -0
  573. package/dist/providers/adapter.js +38 -0
  574. package/dist/providers/adapter.js.map +1 -0
  575. package/dist/providers/agent.d.ts +110 -0
  576. package/dist/providers/agent.js +487 -0
  577. package/dist/providers/agent.js.map +1 -0
  578. package/dist/providers/approvals.d.ts +24 -0
  579. package/dist/providers/approvals.js +78 -0
  580. package/dist/providers/approvals.js.map +1 -0
  581. package/dist/providers/attachments.d.ts +20 -0
  582. package/dist/providers/attachments.js +51 -0
  583. package/dist/providers/attachments.js.map +1 -0
  584. package/dist/providers/claude/adapter.d.ts +99 -0
  585. package/dist/providers/claude/adapter.js +790 -0
  586. package/dist/providers/claude/adapter.js.map +1 -0
  587. package/dist/providers/codex/adapter.d.ts +113 -0
  588. package/dist/providers/codex/adapter.js +881 -0
  589. package/dist/providers/codex/adapter.js.map +1 -0
  590. package/dist/providers/codex/instructions.d.ts +11 -0
  591. package/dist/providers/codex/instructions.js +154 -0
  592. package/dist/providers/codex/instructions.js.map +1 -0
  593. package/dist/providers/codex/rpc.d.ts +36 -0
  594. package/dist/providers/codex/rpc.js +104 -0
  595. package/dist/providers/codex/rpc.js.map +1 -0
  596. package/dist/providers/contracts.d.ts +339 -0
  597. package/dist/providers/contracts.js +19 -0
  598. package/dist/providers/contracts.js.map +1 -0
  599. package/dist/providers/directory.d.ts +70 -0
  600. package/dist/providers/directory.js +95 -0
  601. package/dist/providers/directory.js.map +1 -0
  602. package/dist/providers/errors.d.ts +47 -0
  603. package/dist/providers/errors.js +24 -0
  604. package/dist/providers/errors.js.map +1 -0
  605. package/dist/providers/index.d.ts +18 -0
  606. package/dist/providers/index.js +19 -0
  607. package/dist/providers/index.js.map +1 -0
  608. package/dist/providers/ingestion.d.ts +80 -0
  609. package/dist/providers/ingestion.js +330 -0
  610. package/dist/providers/ingestion.js.map +1 -0
  611. package/dist/providers/live.d.ts +22 -0
  612. package/dist/providers/live.js +56 -0
  613. package/dist/providers/live.js.map +1 -0
  614. package/dist/providers/process.d.ts +29 -0
  615. package/dist/providers/process.js +71 -0
  616. package/dist/providers/process.js.map +1 -0
  617. package/dist/providers/reaper.d.ts +33 -0
  618. package/dist/providers/reaper.js +65 -0
  619. package/dist/providers/reaper.js.map +1 -0
  620. package/dist/providers/service.d.ts +87 -0
  621. package/dist/providers/service.js +256 -0
  622. package/dist/providers/service.js.map +1 -0
  623. package/dist/sdk.d.ts +1 -1
  624. package/dist/sdk.js +1 -1
  625. package/dist/sdk.js.map +1 -1
  626. package/dist/types.d.ts +385 -6
  627. package/dist/types.js +1 -0
  628. package/dist/types.js.map +1 -1
  629. package/dist/version.d.ts +7 -0
  630. package/dist/version.js +16 -0
  631. package/dist/version.js.map +1 -0
  632. package/dist/web/app.css +4646 -0
  633. package/dist/web/app.js +22640 -0
  634. package/dist/web/app.js.map +7 -0
  635. package/dist/web/shell.html +39 -0
  636. package/docs/README.md +21 -0
  637. package/docs/SETUP.md +10 -0
  638. package/docs/adapters.md +21 -8
  639. package/docs/brain-continuity.md +186 -0
  640. package/docs/cloud.md +108 -0
  641. package/docs/crews.md +62 -0
  642. package/docs/design-system.md +31 -2
  643. package/docs/integration-notes.md +128 -20
  644. package/docs/loompad.md +105 -0
  645. package/docs/observability.md +220 -0
  646. package/docs/play-store.md +123 -0
  647. package/docs/proposals/agent-teams.md +249 -0
  648. package/docs/proposals/brain-continuity-implementation.md +468 -0
  649. package/docs/proposals/brain-session-continuity.md +623 -0
  650. package/docs/proposals/t3code-port.md +81 -0
  651. package/docs/proposals/t3code-reference.md +95 -0
  652. package/docs/refactoring/AGENT-TEAMS-PROGRESS.md +88 -0
  653. package/docs/refactoring/BOUNDARIES.md +120 -0
  654. package/docs/refactoring/BRAIN-AUDIT.md +176 -0
  655. package/docs/refactoring/BRAIN-NOTES.md +390 -0
  656. package/docs/refactoring/BRAIN-TODO.md +214 -0
  657. package/docs/refactoring/NOTES.md +129 -0
  658. package/docs/refactoring/T3-PORT-NOTES.md +165 -0
  659. package/docs/refactoring/T3-PORT-TODO.md +123 -0
  660. package/docs/refactoring/TODO.md +46 -0
  661. package/docs/refactoring/brain-benchmark-2026-09-28.json +48 -0
  662. package/docs/refactoring/brain-benchmark-audit-2026-09-28.json +48 -0
  663. package/docs/release-notes/v0.2.0.md +35 -0
  664. package/docs/release-notes/v0.2.1.md +59 -0
  665. package/docs/release-notes/v0.2.3.md +77 -0
  666. package/docs/release-notes/v0.2.4.md +128 -0
  667. package/docs/release-notes/v0.2.5.md +153 -0
  668. package/docs/release-notes/v0.2.6.md +62 -0
  669. package/docs/release-notes/v1.0.0.md +120 -0
  670. package/docs/release-notes/v1.0.1.md +77 -0
  671. package/docs/release-notes/v1.1.0.md +71 -0
  672. package/docs/release-notes/v1.1.1.md +38 -0
  673. package/docs/release-notes/v1.1.2.md +21 -0
  674. package/docs/teams-architecture.md +697 -0
  675. package/docs/teams.md +171 -0
  676. package/docs/windows.md +85 -0
  677. package/package.json +22 -9
  678. package/dist/adapters/claude-code.d.ts +0 -26
  679. package/dist/adapters/claude-code.js +0 -209
  680. package/dist/adapters/claude-code.js.map +0 -1
  681. package/dist/adapters/codex.d.ts +0 -51
  682. package/dist/adapters/codex.js +0 -291
  683. package/dist/adapters/codex.js.map +0 -1
  684. package/docs/img/board-linear.png +0 -0
  685. package/docs/img/board-projects.png +0 -0
  686. package/docs/img/brain.png +0 -0
  687. package/docs/img/settings.png +0 -0
  688. package/docs/img/workspace.png +0 -0
@@ -9,8 +9,21 @@ export declare function loomHome(): string;
9
9
  export declare function ensureLoomHome(): string;
10
10
  export declare function newId(bytes?: number): string;
11
11
  export declare function listProjects(): ProjectInfo[];
12
+ /**
13
+ * A directory as the filesystem knows it: absolute, with symlinks resolved.
14
+ *
15
+ * Comparing `path.resolve` strings registered one folder twice whenever it was
16
+ * reached through a symlink — on macOS every temp dir is (/var → /private/var),
17
+ * and a shell's cwd reports the resolved side. Two registry rows then meant two
18
+ * runtimes over ONE .loom/: two engines appending to the same log, each blind
19
+ * to the other's in-memory state. Found by an orchestra run whose reply landed
20
+ * in the twin.
21
+ */
22
+ export declare function canonicalDir(dir: string): string;
12
23
  export declare function findProject(idOrDirOrName: string): ProjectInfo | undefined;
13
24
  export declare function registerProject(dir: string, name: string): ProjectInfo;
25
+ /** Rename a project's label. The id — what tokens and state key on — never moves. */
26
+ export declare function renameProject(id: string, name: string): ProjectInfo | null;
14
27
  export declare function unregisterProject(id: string): void;
15
28
  export declare function projectLoomDir(projectDir: string): string;
16
29
  export declare function readProjectConfig(projectDir: string): ProjectConfig | null;
@@ -29,8 +42,24 @@ export interface ProjectState {
29
42
  * and haven't said anything in yet, still exists.
30
43
  */
31
44
  chats?: ChatInfo[];
45
+ /** Work-in-progress limits per board column; a column over its limit warns. */
46
+ boardLimits?: Record<string, number>;
32
47
  /** Task cards you wrote yourself. See BoardTask. */
33
48
  tasks?: BoardTask[];
49
+ /** Per-agent spend budgets in USD/day, set from the Observatory burn-rate panel. */
50
+ budgets?: Record<string, number>;
51
+ /**
52
+ * Agents paused by a firing alert (self-heal). Keyed by agent id; the value
53
+ * records why, when, and who to hand the baton back to once the alert
54
+ * resolves — so the loop can retry the original agent, not just fail over.
55
+ */
56
+ quarantine?: Record<string, {
57
+ reason: string;
58
+ since: number;
59
+ displaced: boolean;
60
+ }>;
61
+ /** Chats brought in from an agent's own history: "<source>:<session id>" → the Loom chat it became. */
62
+ imports?: Record<string, string>;
34
63
  }
35
64
  /**
36
65
  * A card you made, as opposed to the ones the board derives from live agents
@@ -44,6 +73,21 @@ export interface BoardTask {
44
73
  column: string;
45
74
  /** Optional agent this is meant for. */
46
75
  agent?: string;
76
+ /**
77
+ * Tasks this one cannot start before. A card with an unfinished blocker is
78
+ * refused dispatch — an agent picking up work whose prerequisite isn't done
79
+ * produces work that has to be thrown away, which is worse than waiting.
80
+ */
81
+ blockedBy?: string[];
82
+ /** How much it matters, when you've said. */
83
+ priority?: "high" | "medium" | "low";
84
+ /** When it's due, as a local date: YYYY-MM-DD. */
85
+ due?: string;
86
+ /** A crew card (core/crew.ts): the crew, its goal, where it is, and which teammate holds it. */
87
+ crew?: string;
88
+ goal?: string;
89
+ stage?: string;
90
+ claimedBy?: string;
47
91
  createdAt: number;
48
92
  }
49
93
  export declare function readProjectState(projectDir: string): ProjectState;
@@ -56,9 +100,19 @@ export interface PairedClient {
56
100
  name: string;
57
101
  token: string;
58
102
  createdAt: number;
103
+ /** When this device last made a request (written at most every 10 min). */
104
+ lastSeen?: number;
59
105
  /** Expo push token, when the device registered for notifications. */
60
106
  pushToken?: string;
61
107
  platform?: string;
108
+ /** Which push categories this device wants (questions, approvals, done, goals); absent means all. */
109
+ pushKinds?: string[];
110
+ /**
111
+ * Project ids this token may touch. Absent means all — which keeps every
112
+ * client paired before scoping existed exactly as powerful as it was.
113
+ * Pairing a phone for one project used to hand over the whole daemon.
114
+ */
115
+ projects?: string[];
62
116
  }
63
117
  export interface DaemonConfig {
64
118
  host: string;
@@ -59,23 +59,63 @@ function registryFile() {
59
59
  export function listProjects() {
60
60
  return readJson(registryFile(), { projects: [] }).projects;
61
61
  }
62
+ /**
63
+ * A directory as the filesystem knows it: absolute, with symlinks resolved.
64
+ *
65
+ * Comparing `path.resolve` strings registered one folder twice whenever it was
66
+ * reached through a symlink — on macOS every temp dir is (/var → /private/var),
67
+ * and a shell's cwd reports the resolved side. Two registry rows then meant two
68
+ * runtimes over ONE .loom/: two engines appending to the same log, each blind
69
+ * to the other's in-memory state. Found by an orchestra run whose reply landed
70
+ * in the twin.
71
+ */
72
+ export function canonicalDir(dir) {
73
+ const abs = path.resolve(dir);
74
+ try {
75
+ return fs.realpathSync(abs);
76
+ }
77
+ catch {
78
+ return abs;
79
+ }
80
+ }
62
81
  export function findProject(idOrDirOrName) {
63
82
  const projects = listProjects();
64
- const dir = path.resolve(idOrDirOrName);
65
- return projects.find((p) => p.id === idOrDirOrName || p.name === idOrDirOrName || path.resolve(p.dir) === dir);
83
+ const byKey = projects.find((p) => p.id === idOrDirOrName || p.name === idOrDirOrName);
84
+ if (byKey)
85
+ return byKey;
86
+ const dir = canonicalDir(idOrDirOrName);
87
+ return projects.find((p) => canonicalDir(p.dir) === dir);
66
88
  }
67
89
  export function registerProject(dir, name) {
68
90
  ensureLoomHome();
69
91
  const reg = readJson(registryFile(), { projects: [] });
70
92
  const resolved = path.resolve(dir);
71
- const existing = reg.projects.find((p) => path.resolve(p.dir) === resolved);
93
+ const canonical = canonicalDir(dir);
94
+ const existing = reg.projects.find((p) => canonicalDir(p.dir) === canonical);
72
95
  if (existing)
73
96
  return existing;
74
- const info = { id: newId(), name, dir: resolved };
97
+ // The signature says string and every caller is typed, but the name usually
98
+ // originates in a JSON file read through an unchecked cast — so "required"
99
+ // is a claim about the code, not about the bytes on disk. A registry row with
100
+ // no name is unfixable from the UI (nothing to click) and leaks into every
101
+ // surface that prints a project. Fall back to the directory, which is what
102
+ // the caller would have chosen anyway.
103
+ const label = String(name ?? "").trim() || path.basename(resolved);
104
+ const info = { id: newId(), name: label, dir: resolved };
75
105
  reg.projects.push(info);
76
106
  writeJson(registryFile(), reg);
77
107
  return info;
78
108
  }
109
+ /** Rename a project's label. The id — what tokens and state key on — never moves. */
110
+ export function renameProject(id, name) {
111
+ const reg = readJson(registryFile(), { projects: [] });
112
+ const info = reg.projects.find((p) => p.id === id);
113
+ if (!info)
114
+ return null;
115
+ info.name = name;
116
+ writeJson(registryFile(), reg);
117
+ return info;
118
+ }
79
119
  export function unregisterProject(id) {
80
120
  const reg = readJson(registryFile(), { projects: [] });
81
121
  reg.projects = reg.projects.filter((p) => p.id !== id);
@@ -94,7 +134,24 @@ export function readProjectConfig(projectDir) {
94
134
  return readJson(file, { name: path.basename(projectDir), agents: [] });
95
135
  }
96
136
  export function writeProjectConfig(projectDir, cfg) {
97
- writeJson(path.join(projectLoomDir(projectDir), "config.json"), cfg);
137
+ const dir = projectLoomDir(projectDir), file = path.join(dir, "config.json");
138
+ fs.mkdirSync(dir, { recursive: true });
139
+ const temporary = path.join(dir, `.config-${crypto.randomUUID()}.tmp`);
140
+ const fd = fs.openSync(temporary, "wx", fs.existsSync(file) ? fs.statSync(file).mode & 0o777 : 0o600);
141
+ try {
142
+ try {
143
+ fs.writeFileSync(fd, JSON.stringify(cfg, null, 2) + "\n");
144
+ fs.fsyncSync(fd);
145
+ }
146
+ finally {
147
+ fs.closeSync(fd);
148
+ }
149
+ fs.renameSync(temporary, file);
150
+ }
151
+ finally {
152
+ if (fs.existsSync(temporary))
153
+ fs.unlinkSync(temporary);
154
+ }
98
155
  }
99
156
  export function readProjectState(projectDir) {
100
157
  return readJson(path.join(projectLoomDir(projectDir), "state.json"), {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Loom Cloud — the client end of the relay (phone, CLI, tests).
3
+ *
4
+ * Gives a remote client the two things a direct connection gives it: `request`
5
+ * (an HTTP call to the daemon) and `stream` (the /ws event feed), carried as
6
+ * encrypted envelopes over a broadcast transport. Dependency-free apart from
7
+ * relay-protocol.ts, so the Expo app runs this exact file (app/src/relay-client.ts
8
+ * is a copy — keep them in step).
9
+ *
10
+ * Reconnection follows T3 Code's connection supervisor (github.com/pingdotgg/
11
+ * t3code, MIT): capped backoff, a liveness ping, and a forced fresh stream
12
+ * after the app has been in the background — mobile OSes kill sockets without
13
+ * telling anyone.
14
+ */
15
+ import { type RelayCredentials, type RelayTransport } from "./relay-protocol.js";
16
+ export interface RelayResult {
17
+ status: number;
18
+ body: unknown;
19
+ }
20
+ export interface StreamHandlers {
21
+ onFrame: (frame: unknown) => void;
22
+ onState?: (open: boolean, code?: number) => void;
23
+ }
24
+ export declare class RelayClient {
25
+ private transport;
26
+ readonly id: string;
27
+ private key;
28
+ private decoder;
29
+ private pending;
30
+ private pongs;
31
+ private stream;
32
+ private streamOpen;
33
+ private retryTimer;
34
+ private closed;
35
+ daemon: {
36
+ version: string;
37
+ name: string;
38
+ } | null;
39
+ constructor(transport: RelayTransport, creds: RelayCredentials, opts?: {
40
+ clientId?: string;
41
+ });
42
+ private send;
43
+ private handle;
44
+ /** An HTTP call to the daemon, through the relay. */
45
+ request(method: string, path: string, opts?: {
46
+ auth?: string;
47
+ body?: unknown;
48
+ timeoutMs?: number;
49
+ }): Promise<RelayResult>;
50
+ /** Round-trip time to the daemon in ms, or null when it doesn't answer. */
51
+ ping(timeoutMs?: number): Promise<number | null>;
52
+ /** Open the live event feed (the /ws frames). Replaces any previous one. */
53
+ openStream(auth: string, handlers: StreamHandlers, project?: string): void;
54
+ /** Force a fresh stream — call when the app returns to the foreground. */
55
+ refresh(): void;
56
+ isStreaming(): boolean;
57
+ closeStream(): void;
58
+ private resubscribe;
59
+ private scheduleResubscribe;
60
+ close(): Promise<void>;
61
+ }
62
+ /** Parse the cloud part of a pairing link fragment (`relay=…&sb=…&sbk=…`). */
63
+ export declare function parseCloudFragment(fragment: string): {
64
+ relay: string;
65
+ supabaseUrl: string;
66
+ anonKey: string;
67
+ } | null;
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Loom Cloud — the client end of the relay (phone, CLI, tests).
3
+ *
4
+ * Gives a remote client the two things a direct connection gives it: `request`
5
+ * (an HTTP call to the daemon) and `stream` (the /ws event feed), carried as
6
+ * encrypted envelopes over a broadcast transport. Dependency-free apart from
7
+ * relay-protocol.ts, so the Expo app runs this exact file (app/src/relay-client.ts
8
+ * is a copy — keep them in step).
9
+ *
10
+ * Reconnection follows T3 Code's connection supervisor (github.com/pingdotgg/
11
+ * t3code, MIT): capped backoff, a liveness ping, and a forced fresh stream
12
+ * after the app has been in the background — mobile OSes kill sockets without
13
+ * telling anyone.
14
+ */
15
+ import { encodeMessage, fromB64, RelayDecoder, toB64, } from "./relay-protocol.js";
16
+ const RETRY_MS = [1000, 3000, 8000, 16000];
17
+ function randomId() {
18
+ const b = new Uint8Array(12);
19
+ globalThis.crypto.getRandomValues(b);
20
+ return toB64(b);
21
+ }
22
+ export class RelayClient {
23
+ transport;
24
+ id;
25
+ key;
26
+ decoder;
27
+ pending = new Map();
28
+ pongs = new Map();
29
+ stream = null;
30
+ streamOpen = false;
31
+ retryTimer = null;
32
+ closed = false;
33
+ daemon = null;
34
+ constructor(transport, creds, opts = {}) {
35
+ this.transport = transport;
36
+ this.id = opts.clientId ?? randomId();
37
+ this.key = fromB64(creds.key);
38
+ this.decoder = new RelayDecoder(this.key, "d");
39
+ transport.onEnvelope((env) => {
40
+ const msg = this.decoder.push(env);
41
+ if (msg)
42
+ this.handle(msg);
43
+ });
44
+ }
45
+ async send(msg) {
46
+ for (const env of encodeMessage(this.key, "c", msg))
47
+ await this.transport.send(env);
48
+ }
49
+ handle(msg) {
50
+ if (msg.t === "res" && msg.to === this.id) {
51
+ const p = this.pending.get(msg.id);
52
+ if (!p)
53
+ return;
54
+ clearTimeout(p.timer);
55
+ this.pending.delete(msg.id);
56
+ p.resolve({ status: msg.status, body: msg.body });
57
+ }
58
+ else if (msg.t === "pong" && msg.to === this.id) {
59
+ this.daemon = msg.daemon;
60
+ const cb = this.pongs.get(msg.ts);
61
+ this.pongs.delete(msg.ts);
62
+ cb?.(Date.now() - msg.ts);
63
+ }
64
+ else if (msg.t === "evs" && msg.to === this.id) {
65
+ for (const f of msg.frames)
66
+ this.stream?.handlers.onFrame(f);
67
+ }
68
+ else if (msg.t === "stream" && msg.to === this.id) {
69
+ this.streamOpen = msg.open;
70
+ this.stream?.handlers.onState?.(msg.open, msg.code);
71
+ if (msg.open && this.stream)
72
+ this.stream.attempt = 0;
73
+ // 4401 = the token was refused: retrying would only be refused again.
74
+ if (!msg.open && this.stream && msg.code !== 4401 && !this.closed)
75
+ this.scheduleResubscribe();
76
+ }
77
+ }
78
+ /** An HTTP call to the daemon, through the relay. */
79
+ request(method, path, opts = {}) {
80
+ const id = randomId();
81
+ return new Promise((resolve) => {
82
+ const timer = setTimeout(() => {
83
+ this.pending.delete(id);
84
+ resolve({ status: 504, body: { error: "the daemon did not answer through Loom Cloud — is it running?" } });
85
+ }, opts.timeoutMs ?? 30_000);
86
+ this.pending.set(id, { resolve, timer });
87
+ void this.send({
88
+ t: "req",
89
+ id,
90
+ from: this.id,
91
+ method,
92
+ path,
93
+ ts: Date.now(),
94
+ ...(opts.auth ? { auth: opts.auth } : {}),
95
+ ...(opts.body !== undefined ? { body: opts.body } : {}),
96
+ }).catch((err) => {
97
+ clearTimeout(timer);
98
+ this.pending.delete(id);
99
+ resolve({ status: 503, body: { error: `relay send failed: ${err.message}` } });
100
+ });
101
+ });
102
+ }
103
+ /** Round-trip time to the daemon in ms, or null when it doesn't answer. */
104
+ ping(timeoutMs = 8000) {
105
+ const ts = Date.now() + Math.random();
106
+ return new Promise((resolve) => {
107
+ const timer = setTimeout(() => {
108
+ this.pongs.delete(ts);
109
+ resolve(null);
110
+ }, timeoutMs);
111
+ this.pongs.set(ts, (ms) => {
112
+ clearTimeout(timer);
113
+ resolve(ms);
114
+ });
115
+ void this.send({ t: "ping", from: this.id, ts }).catch(() => resolve(null));
116
+ });
117
+ }
118
+ /** Open the live event feed (the /ws frames). Replaces any previous one. */
119
+ openStream(auth, handlers, project) {
120
+ this.stream = { auth, handlers, attempt: 0, ...(project ? { project } : {}) };
121
+ void this.resubscribe();
122
+ }
123
+ /** Force a fresh stream — call when the app returns to the foreground. */
124
+ refresh() {
125
+ if (this.stream)
126
+ void this.resubscribe();
127
+ }
128
+ isStreaming() {
129
+ return this.streamOpen;
130
+ }
131
+ closeStream() {
132
+ this.stream = null;
133
+ this.streamOpen = false;
134
+ if (this.retryTimer)
135
+ clearTimeout(this.retryTimer);
136
+ void this.send({ t: "unsub", from: this.id }).catch(() => { });
137
+ }
138
+ async resubscribe() {
139
+ if (!this.stream || this.closed)
140
+ return;
141
+ await this.send({
142
+ t: "sub",
143
+ from: this.id,
144
+ auth: this.stream.auth,
145
+ ...(this.stream.project ? { project: this.stream.project } : {}),
146
+ }).catch(() => this.scheduleResubscribe());
147
+ }
148
+ scheduleResubscribe() {
149
+ if (!this.stream || this.retryTimer)
150
+ return;
151
+ const delay = RETRY_MS[Math.min(this.stream.attempt, RETRY_MS.length - 1)];
152
+ this.stream.attempt++;
153
+ this.retryTimer = setTimeout(() => {
154
+ this.retryTimer = null;
155
+ void this.resubscribe();
156
+ }, delay);
157
+ }
158
+ async close() {
159
+ this.closed = true;
160
+ if (this.retryTimer)
161
+ clearTimeout(this.retryTimer);
162
+ for (const p of this.pending.values())
163
+ clearTimeout(p.timer);
164
+ this.pending.clear();
165
+ await this.transport.close();
166
+ }
167
+ }
168
+ /** Parse the cloud part of a pairing link fragment (`relay=…&sb=…&sbk=…`). */
169
+ export function parseCloudFragment(fragment) {
170
+ const params = new URLSearchParams(fragment.replace(/^#/, ""));
171
+ const relay = params.get("relay");
172
+ const sb = params.get("sb");
173
+ const sbk = params.get("sbk");
174
+ if (!relay || !sb || !sbk)
175
+ return null;
176
+ const dec = new TextDecoder();
177
+ try {
178
+ return { relay, supabaseUrl: dec.decode(fromB64(sb)), anonKey: dec.decode(fromB64(sbk)) };
179
+ }
180
+ catch {
181
+ return null;
182
+ }
183
+ }
184
+ //# sourceMappingURL=relay-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../../src/core/relay-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Loom Cloud relay — the wire format.
3
+ *
4
+ * Reaching your daemon from a phone on another network without a VPN: both
5
+ * ends join one Supabase Realtime broadcast channel and pass encrypted
6
+ * envelopes through it. The daemon turns each request into an ordinary local
7
+ * HTTP call (or WebSocket) against itself, with the phone's own paired token,
8
+ * so every auth and scope rule is the one the LAN path already enforces.
9
+ *
10
+ * **Supabase sees only ciphertext.** The channel name and the 32-byte key are
11
+ * minted by the daemon and travel only inside the pairing QR / link fragment.
12
+ * Every envelope is XChaCha20-Poly1305 with a fresh random nonce; a message
13
+ * that doesn't authenticate is dropped. The relay can't read your code, your
14
+ * prompts or your tokens, and it can't forge a request.
15
+ *
16
+ * Pattern credits: the pairing token rides the URL *fragment* (never sent to a
17
+ * server) and clients resume a stream from a sequence number — both from
18
+ * T3 Code (github.com/pingdotgg/t3code, MIT).
19
+ *
20
+ * This file is dependency-light on purpose (only @noble/ciphers): the Expo app
21
+ * carries a copy (app/src/relay-protocol.ts) and the two must stay in step.
22
+ */
23
+ export declare const RELAY_PROTOCOL = 1;
24
+ /** Supabase's default broadcast payload cap is 256 KB; stay well under after base64. */
25
+ export declare const MAX_CHUNK: number;
26
+ /** A request from a client, executed by the daemon against itself. */
27
+ export interface RelayRequest {
28
+ t: "req";
29
+ id: string;
30
+ from: string;
31
+ method: string;
32
+ path: string;
33
+ auth?: string;
34
+ body?: unknown;
35
+ /**
36
+ * When the client sent it (ms). Inside the sealed envelope, so nobody on the
37
+ * relay can change it: the daemon refuses a request stamped too far from
38
+ * now, and remembers the ids it has run — a captured request can't be sent
39
+ * again. Absent from clients older than this field.
40
+ */
41
+ ts?: number;
42
+ }
43
+ export interface RelayResponse {
44
+ t: "res";
45
+ id: string;
46
+ to: string;
47
+ status: number;
48
+ body: unknown;
49
+ }
50
+ /** Open (or replace) a live event stream for a client — a remote WebSocket. */
51
+ export interface RelaySubscribe {
52
+ t: "sub";
53
+ from: string;
54
+ auth: string;
55
+ project?: string;
56
+ }
57
+ export interface RelayUnsubscribe {
58
+ t: "unsub";
59
+ from: string;
60
+ }
61
+ /** Live frames for one client, batched. Each frame is exactly a /ws frame. */
62
+ export interface RelayEvents {
63
+ t: "evs";
64
+ to: string;
65
+ frames: unknown[];
66
+ }
67
+ /** Stream state for one client: open, or closed with the /ws close code. */
68
+ export interface RelayStreamState {
69
+ t: "stream";
70
+ to: string;
71
+ open: boolean;
72
+ code?: number;
73
+ }
74
+ export interface RelayPing {
75
+ t: "ping";
76
+ from: string;
77
+ ts: number;
78
+ }
79
+ export interface RelayPong {
80
+ t: "pong";
81
+ to: string;
82
+ ts: number;
83
+ daemon: {
84
+ version: string;
85
+ name: string;
86
+ };
87
+ }
88
+ export type RelayMessage = RelayRequest | RelayResponse | RelaySubscribe | RelayUnsubscribe | RelayEvents | RelayStreamState | RelayPing | RelayPong;
89
+ /** What actually crosses Supabase. `p` is set when a message spans parts. */
90
+ export interface RelayEnvelope {
91
+ v: number;
92
+ /** direction: c = client→daemon, d = daemon→client. Each side ignores its own. */
93
+ d: "c" | "d";
94
+ /** base64 of nonce‖ciphertext */
95
+ x: string;
96
+ /** multipart: [messageId, index, count] */
97
+ p?: [string, number, number];
98
+ }
99
+ export declare function toB64(bytes: Uint8Array): string;
100
+ export declare function fromB64(s: string): Uint8Array;
101
+ export interface RelayCredentials {
102
+ /** Channel id — also unguessable, but secrecy rests on the key. */
103
+ channel: string;
104
+ /** 32-byte key, base64url. */
105
+ key: string;
106
+ }
107
+ export declare function newRelayCredentials(): RelayCredentials;
108
+ /** The Supabase channel topic for a credential set. */
109
+ export declare function relayTopic(channel: string): string;
110
+ /** `channel.key` — the compact form carried in a pairing link. */
111
+ export declare function packCredentials(c: RelayCredentials): string;
112
+ export declare function unpackCredentials(s: string): RelayCredentials | null;
113
+ export declare function seal(key: Uint8Array, plaintext: Uint8Array): string;
114
+ /** Null when the envelope doesn't authenticate — never throws on hostile input. */
115
+ export declare function open(key: Uint8Array, sealed: string): Uint8Array | null;
116
+ /** Encode a message into one or more envelopes (split when large). */
117
+ export declare function encodeMessage(key: Uint8Array, dir: "c" | "d", msg: RelayMessage): RelayEnvelope[];
118
+ /**
119
+ * Reassembles multipart messages and decrypts. Feed every envelope from the
120
+ * other side; it yields each complete message once.
121
+ */
122
+ export declare class RelayDecoder {
123
+ private key;
124
+ /** Which direction this side reads: the daemon reads "c", the client "d". */
125
+ private reads;
126
+ private parts;
127
+ constructor(key: Uint8Array,
128
+ /** Which direction this side reads: the daemon reads "c", the client "d". */
129
+ reads: "c" | "d");
130
+ push(env: unknown): RelayMessage | null;
131
+ private gc;
132
+ }
133
+ /** Where envelopes go: Supabase in production, an in-memory bus in tests. */
134
+ export interface RelayTransport {
135
+ send(env: RelayEnvelope): Promise<void>;
136
+ onEnvelope(cb: (env: unknown) => void): void;
137
+ /** Resolves once the transport is joined and can send. */
138
+ ready(): Promise<void>;
139
+ close(): Promise<void>;
140
+ }