@loompad/cli 0.1.0 → 1.1.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 (687) hide show
  1. package/ARCHITECTURE.md +96 -11
  2. package/CHANGELOG.md +1042 -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 +4643 -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/teams-architecture.md +697 -0
  674. package/docs/teams.md +171 -0
  675. package/docs/windows.md +85 -0
  676. package/package.json +22 -9
  677. package/dist/adapters/claude-code.d.ts +0 -26
  678. package/dist/adapters/claude-code.js +0 -209
  679. package/dist/adapters/claude-code.js.map +0 -1
  680. package/dist/adapters/codex.d.ts +0 -51
  681. package/dist/adapters/codex.js +0 -291
  682. package/dist/adapters/codex.js.map +0 -1
  683. package/docs/img/board-linear.png +0 -0
  684. package/docs/img/board-projects.png +0 -0
  685. package/docs/img/brain.png +0 -0
  686. package/docs/img/settings.png +0 -0
  687. package/docs/img/workspace.png +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,1048 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.1.1] — 2026-10-16
11
+
12
+ Found installing 1.1.0 on a Mac whose projects live on an external drive.
13
+
14
+ ### Fixed
15
+
16
+ - **Loom Desktop explains a slow start instead of sitting blank.** The first
17
+ time it reads projects on an external drive (or in Documents or Desktop),
18
+ macOS asks whether Loom Desktop may access those files, and the background
19
+ service waits for the answer. The window now says *Starting Loom…* at once,
20
+ and after a few seconds that macOS may be asking, and to choose Allow.
21
+ - **It no longer starts a second background service** onto a port that's
22
+ taken when the first is running but waiting on that prompt. It waits for
23
+ the first one, up to five minutes.
24
+ - **The error page gives an installed app's advice**: quit and reopen, where
25
+ the permission lives in System Settings, and where the log is. It no longer
26
+ says "run npm run build". The pairing request has a timeout.
27
+ - **Builds prune compiled files whose source is gone.** Leftovers in a
28
+ long-lived checkout changed the build fingerprint the desktop app and the
29
+ CLI compare, so the same release could look like two builds and each would
30
+ restart the other's background service.
31
+
32
+
33
+ ## [1.1.0] — 2026-10-16
34
+
35
+ ### Can you trust what your agents did?
36
+
37
+ - **Proof**: when a reply claims the tests, build, typecheck or lint pass,
38
+ Loom checks the claim against what that turn actually ran, and re-runs the
39
+ tests in a clean worktree holding exactly the agent's changes. The verdict
40
+ is a card in the thread: Verified, Didn't hold (with why), or Unverified.
41
+ Every turn card has **Check it**; `loom proof` from a terminal.
42
+ - **Loop watch**: the same command failing three times in a turn (or the same
43
+ call five times) gets a card with Stop / Nudge it / Hand it off, and a push.
44
+ `watchdog.auto: "nudge"` also stops it and tells it to step back, once.
45
+ - **Blast-Radius Shield**: a force-push, `reset --hard`, a recursive delete
46
+ outside the project, `DROP TABLE`, `terraform destroy`, `npm publish`,
47
+ `sudo`, `curl | sh`, and the like get a red card and a push the moment an
48
+ agent runs them. `shield.auto: "stop"` (the default on a night shift) stops
49
+ the turn.
50
+ - **Review Triage**: every turn card says which files to read first, and why:
51
+ an added secret, a deleted or skipped test, auth code, a migration, CI,
52
+ dependencies, risky calls, a big change with no test.
53
+ - **Scorecards**: each agent's record of how often its "done" held up, its
54
+ circles and shield trips, and cost per verified result, in the
55
+ Observatory leaderboard, the phone, and `loom scorecard`.
56
+
57
+ ### Work that carries on without you
58
+
59
+ - **Night Shift**: line up tasks, one per line. They run one after another, a
60
+ chat each, while you're away, guarded by Proof, the loop watch and the
61
+ shield, and stop at a stop-by time or a budget. One morning report says how
62
+ each went. Desktop ⋯ → Night shift, phone 🌙, or `loom shift`.
63
+ - **Quota Relay**: an agent that hits its usage limit mid-task hands its work
64
+ (and a briefing) to the next agent, routes new prompts there while it's out,
65
+ and takes the baton back when the window resets.
66
+ - **Pre-flight forecast**: the composer shows what a turn on the chosen agent
67
+ usually costs and takes, from its own recent turns, and turns amber when
68
+ one more could cross its daily budget.
69
+ - **Replay**: export any chat as one self-contained HTML page to share, with
70
+ no scripts and nothing to load. ⋯ → Export as replay, or `loom replay`.
71
+ - **Design Mode**: a picked element in the Browser tab brings its computed
72
+ styles and its own screenshot into the composer.
73
+
74
+ ### Agent Teams
75
+
76
+ - **Persistent teammates** (P2) with their own native sessions and **crew
77
+ memory**. Teammates can now `remember` decisions, constraints and
78
+ conventions themselves.
79
+ - **Parallel builders** in isolated worktrees, and **races** where you pick
80
+ the result (P3).
81
+ - **Team coordination**: crews across teammates' daemons, owner requests, and
82
+ runners that execute crew goals. Full crew controls on desktop and phone.
83
+
84
+ ### Windows and a lighter daemon
85
+
86
+ - Windows **Job Object** containment, native continuity on Windows, and
87
+ OpenCode 1.19 continuity. Fixes for ConPTY exit races and CLI launching.
88
+ - **Memory**: the daemon starts ~25 MB lighter (the Claude SDK loads on first
89
+ use), idle OpenCode servers stop after 30 minutes, CLI probes are cached,
90
+ event reads are indexed, and long sessions no longer leak turn text,
91
+ attachments or socket backlogs.
92
+ - OpenCode bash calls report their exit code, so a failing command no longer
93
+ reads as a success.
94
+
95
+ ### Fixed
96
+
97
+ - A prompt sent to an agent just after its usage window reset, before the
98
+ baton came back, failed with "does not hold the baton". A stand-in that was
99
+ mid-turn at the reset kept the baton for good.
100
+ - A runner's dropped progress heartbeat left a goal's PR invisible to the
101
+ team for up to a minute; it's re-sent after 5 seconds.
102
+ - Phone sign-in aligned with GitHub; OAuth callbacks are validated.
103
+
104
+
105
+ ### One link to bring a teammate in, and crews of agents
106
+
107
+ - **Invite** (a project's header, or `loom invite`) gives you one https link.
108
+ Opening it signs the teammate in with GitHub, joins the team, and clones the
109
+ repo; for a private repo, your Loom grants push access on join and theirs
110
+ accepts GitHub's invitation. It then opens the repo with *their* agents,
111
+ shares it with the team, and sets up your crews. Without Loom, the link's
112
+ page shows one command that installs it and joins. `loom join <link>` does
113
+ the same from a terminal.
114
+ - **Crews** (Agent Teams, Phase 1): a lead, builders, a reviewer and a tester
115
+ work one goal in its own worktree. The Lead plans, you approve, and each card
116
+ is built, reviewed (with rounds of changes) and tested; then you apply the
117
+ branch. Use the Crew tab, or `loom crew create|goal|say|approve|stop|resume|apply`.
118
+ - The Crew tab: the crew's faces in a hero, each teammate as a card that
119
+ lights up while it works, the goal's progress, a board with a column per
120
+ stage, an approval banner, the channel as a conversation, and a composer
121
+ that knows whether you're starting, answering or changing the plan. Pick
122
+ which agent sits in each seat when you make a crew, and swap one later.
123
+ - Crews keep going when an agent misbehaves: a teammate that goes silent is
124
+ interrupted and retried once (`stallMinutes`, default 8); a turn that errors
125
+ is retried once; a reviewer or tester whose turn failed fails the card
126
+ instead of approving it.
127
+ - **Fixed:** OpenCode chat turns could end after a step that only ran tools,
128
+ before the answer, when the model was slow to start its next step. And
129
+ interrupting an OpenCode turn that never answered no longer waits out the hour.
130
+ - **Fixed:** a project forgot which tab you were on whenever it redrew while
131
+ loading, so you landed back on Chat.
132
+ - Team invite links are https links now. `loom://team/join#…` links still work
133
+ anywhere a link is accepted.
134
+
135
+ ### A hundred small things (the enhancement sweep)
136
+
137
+ Ranked, filed as #109–#208, and built top down. Each one was tried in the
138
+ running app with real agents before the next started.
139
+
140
+ **In the thread**
141
+ - **Find** (⌘F) with highlighted matches; **drafts** that survive reloads and
142
+ chat switches; **↑** recalls your last prompts; **[ / ]** jump between them.
143
+ - A reply's ⋯ menu: **Retry**, **Retry with…** another agent, **Continue** a
144
+ stopped reply, **Edit & resend**, **Quote**, **Star**, **Copy link**
145
+ (permalinks), **Branch from here**, **Make a card**, **Read aloud**.
146
+ - 👍 / 👎 on replies, counted on the Insights leaderboard.
147
+ - Day separators, relative times that stay fresh, **Show more** on very long
148
+ messages, a token estimate in the composer, **Reply length** (Brief /
149
+ Normal / Detailed), `{{variables}}` in saved prompts.
150
+ - **Mermaid** blocks get *Draw diagram* — the renderer is fetched the first
151
+ time you press it, never before.
152
+ - Export a thread to Markdown (also `loom export`).
153
+ - Error cards you can act on: a countdown on rate limits, *Send to…* another
154
+ agent, *Copy details*.
155
+ - A prompt sent while Loom is down waits and sends itself.
156
+ - Very long live threads trim themselves; the outline rail lists your prompts.
157
+
158
+ **The sidebar**
159
+ - Pin, archive and unread dots on chats; **folders** (right-click → Move to
160
+ folder…, fold them, rename or ungroup); **Group chats by agent**.
161
+ - *Since you were here*: back on a new day, Main opens with what happened
162
+ while you were away.
163
+
164
+ **Orchestra**
165
+ - The plan as a **graph** and a **timeline**; a live cost and time ticker;
166
+ **Run again**; a finish flourish.
167
+ - **Resume**: a run Loom stopped by restarting picks up where it was.
168
+ - **Race**: every picked agent takes the same goal in its own worktree; the
169
+ entrants sit side by side with a diff each, and *Pick this one* merges only
170
+ that one.
171
+
172
+ **Agents, memory, board, insights**
173
+ - Per-agent **standing instructions**, **pictures**, model **temperature and
174
+ max tokens**, and **Check** — installed, signed in, model listed, no prompt
175
+ sent.
176
+ - Memory you can **edit**, **export** and **import**; which memories agents
177
+ actually get (*used N×*, Most used); a **graph** of memories joined by the
178
+ files they share.
179
+ - Board cards with **priority** and **due** dates; **WIP limits** on columns.
180
+ - Insights: an agent **leaderboard**, an activity **heatmap**, costs as
181
+ **CSV**, and month-end at this pace.
182
+ - Diffs **side by side**, and **revert one file** of a turn.
183
+
184
+ **The app around it**
185
+ - Tab title and favicon show what's working and who needs you; a finished turn
186
+ in a hidden tab notifies (with an optional chime); **?** lists every
187
+ shortcut; **focus mode** (⌘.); a first-run tour.
188
+ - Text size, density and accent colour; view transitions between tabs;
189
+ reduced-motion respected; skeleton loaders; the branch in the status bar;
190
+ empty states you can recognise; a project whose folder is gone says so.
191
+ - Terminal find and clear. Diagnostics says what's running. Project settings →
192
+ Storage shows the log's size and compacts it.
193
+ - Voice input without a transcriber uses the browser's own speech recognition.
194
+ - CLI: `loom backup`, `loom export`, `loom stats`, `loom completion zsh|bash`,
195
+ `loom orchestra:resume`; `loom pair` carries the Loom Cloud route.
196
+ - Hardened edges: security headers, a throttled pairing claim, JSON errors
197
+ instead of Express's HTML pages (which leaked stack traces).
198
+
199
+ **On the phone**
200
+ - Follows the system theme; long-press a message to copy or share; a copy
201
+ button on code; pull to refresh; unread and working dots on the chat chips;
202
+ haptics.
203
+ - The daemon card graphs **link quality** over the last two minutes.
204
+ - An **offline copy** of the project list and your last eight threads, per
205
+ paired daemon, cleared on unpair.
206
+ - Android's status bar no longer covers every screen's header.
207
+
208
+ **Fixed on the way**
209
+ - Every *Rename…* used `window.prompt`, which the desktop app doesn't have —
210
+ they silently did nothing. An in-app dialog replaces all seven.
211
+ - A turn's diff was logged to Main whatever chat the turn ran in.
212
+ - An orchestra task's second attempt sent an empty prompt.
213
+ - A queued prompt lost its reply length.
214
+ - A skipped tab transition filled the console with uncaught rejections.
215
+ - `npm test` skipped four DOM suites; it runs them now.
216
+
217
+ ### Replies you can watch being written
218
+
219
+ - **The thread showed nothing between your send and the finished reply** —
220
+ fifteen seconds of a blank pane, then a wall of text. Nothing between an
221
+ adapter and the socket carried text that wasn't a finished event.
222
+ - Replies now stream token by token: Claude Code (`--include-partial-messages`),
223
+ OpenCode 1.18+ (`session.next.text.delta`, which the adapter had never
224
+ listened for), OpenAI-compatible model agents, and every orchestra worker in
225
+ its own task thread. The typing is a `stream` socket frame and is **never
226
+ logged** — the finished message is still the record, exactly once.
227
+ - Model agents logged a reply as a message per sentence (and a message per
228
+ reasoning token), which read as one answer chopped into a stack of bubbles.
229
+ They log it once now.
230
+ - **Stop keeps what was written.** A turn stopped mid-reply used to throw away
231
+ everything you'd watched arrive; it's kept, marked *stopped*.
232
+ - From the moment you send, the thread shows who's on it, for how long, and
233
+ what they're doing ("Codex · shell: npm test · 54s") instead of nothing.
234
+
235
+ ### A thread that reads like a document
236
+
237
+ - One reading column; replies have a byline (the agent's mark, name, model and
238
+ time) instead of a bordered bubble; prose is Geist, mono only for code.
239
+ - A run of tool calls folds into one line — *Ran 3 commands, read 2 files* —
240
+ that opens to the list.
241
+ - Every turn ends on a footer: who, how long, which model, what it cost.
242
+ - An orchestrator's plan is a card of tasks, agents and files, not a page of
243
+ JSON. An empty round says "still looking" rather than "didn't parse". A
244
+ task's status updates in its own row instead of adding a line per state.
245
+ - Code blocks are syntax-highlighted with a language label; markdown tables
246
+ render; errors are a card with the provider's raw payload folded away.
247
+ - The thread stays where you are when you've scrolled up to read, with a
248
+ **Latest** pill, instead of yanking you to the bottom on every event.
249
+ - **Load earlier messages** pages the thread backwards (`?before=` on the
250
+ events API); it stopped at the last 60 events before.
251
+ - An empty thread offers something to start with instead of a blank pane.
252
+
253
+ ### Picking who and on what
254
+
255
+ - The agent and its model are one control in the composer. The agent picker
256
+ shows each agent's model and permission mode, hides switched-off agents, and
257
+ ticks with a check (it was the info icon).
258
+ - The model picker has descriptions, keyboard navigation, **free models
259
+ first**, and fits the window (it ran off the top with Orchestrate open).
260
+ - **Picking a model agent's model from the list broke the agent.** The list
261
+ leads each id with its provider (`openrouter/google/gemma…`), and that whole
262
+ string went to the provider as the model name. It's split now, on save and
263
+ for configs already saved that way.
264
+ - A model agent with the generic id is named by its model ("gemma-4-31b-it").
265
+ - **Ask several models** is in the composer's More menu: tick models, and
266
+ what's in the box goes to each, a thread apiece. It was CLI-only.
267
+
268
+ ### Orchestrate
269
+
270
+ - The cast panel reads as Lead / Team / At once, and each worker chip has two
271
+ zones — include/leave out, and its model and mode — so a click on the chip
272
+ no longer lands on a badge and opens a menu instead.
273
+ - The cast is remembered per project; a reload reset it to "every agent" and
274
+ the next run quietly used agents you'd left out.
275
+ - Each task thread is pinned to its worker: the sidebar says who, and the
276
+ composer in that thread aims at that agent.
277
+ - A finished run ends on a result card with **Apply to your branch**; a run
278
+ that ended before any task finished no longer offers an Apply with nothing
279
+ on its branch.
280
+ - Loom's own `.loom/` state no longer counts as "uncommitted changes" in the
281
+ warning every run showed.
282
+ - Fleet said "no agents running" above a run with workers in flight.
283
+
284
+ ### One workspace at every window size
285
+
286
+ - **Narrowing the window swapped in the phone layout** and took the sidebar,
287
+ the tabs and the panels away. On anything with a mouse the workspace now
288
+ stays at every width: the sidebar slims, then slides in behind a toggle; tabs
289
+ go icon-only (each with a tooltip); the right panel steps aside. The single
290
+ column is for touch phones only.
291
+ - Tabs say what they are: **Chat, Orchestra, Agents, Board, Memory, Insights**
292
+ (they were Thread, Fleet, Brain and Observatory), each with a one-line hint.
293
+ - A turn reads as a timeline: the agent's mark, a hairline through its tool
294
+ steps, a node where it ends. Your prompt is the card that opens a turn;
295
+ code blocks have an editor header; file edits are a review card
296
+ ("Edited 3 files +12 −4"); a reply can be copied from its byline; the
297
+ composer's border lights up when you're in it and send lights up when
298
+ there's something to send.
299
+
300
+ ### And the rest
301
+
302
+ - **Loom on Node older than 22.5 showed every thread empty** — no node:sqlite,
303
+ so it opened a fresh JSONL log beside the real one (a shell that put nvm's
304
+ Node 20 first after a reboot). The CLI now refuses to start on <22.5 and says
305
+ why, and the log refuses to open an empty fallback beside a log.db.
306
+
307
+ - `loom up --restart` left the old daemon alive — its port freed, the process
308
+ and everything it held still running — because shutdown waited on the
309
+ browser's keep-alive and WebSocket connections forever. They're closed now,
310
+ and a stuck shutdown exits after five seconds.
311
+ - The sidebar rebuilt itself every five seconds, dropping hover and focus under
312
+ the pointer; it only redraws when something changed. Older threads fold
313
+ behind "Show N older".
314
+ - The everyday confirmations (abort a run, remove a project, clear the queue,
315
+ update Loom) are an in-app dialog; the browser's own was dismissed unseen by
316
+ some embedders, so Abort simply did nothing.
317
+ - Escape closes any composer menu; the right panel opens by default only on
318
+ wide windows; a reload reopens the project you were in.
319
+ - **Reload mid-reply and the reply is still there.** A thread's first page
320
+ carries what agents are typing in it right now, and stream frames carry their
321
+ offset, so a window opened mid-answer shows the whole reply so far and keeps
322
+ going without repeating or dropping words.
323
+ - When the daemon stops answering, one banner says so and how to start it,
324
+ instead of a "Failed to fetch" toast every few seconds; it clears itself and
325
+ the views refresh when the daemon is back.
326
+ - Terminals stopped stacking a "restored scrollback" divider and prompt for
327
+ every restart nobody typed through.
328
+
329
+ ### On the phone
330
+
331
+ - Replies stream in live, over the LAN, the tailnet or Loom Cloud, and render
332
+ as markdown — code blocks, lists, bold, inline code. The orchestrator's plan
333
+ reads as a plan card, not a JSON dump, and the Fleet previews drop the marks.
334
+ - The Pair screen's second button said "Paste link instead" and actually
335
+ submitted the fields. It now says Connect when something's typed (Enter works
336
+ too) and pastes from the clipboard when nothing is.
337
+ - A thread that can't load (the route still settling, the daemon down) says so
338
+ and retries until it does, instead of sitting blank; "Network request failed"
339
+ became a sentence that says what to check.
340
+
341
+ ## [1.0.1] — 2026-09-21
342
+
343
+ ### Orchestra spawns its workers again
344
+
345
+ - **An orchestrator's plan was being thrown away before it ran.** Every run
346
+ planned tasks and started none: the Fleet sat idle, no task threads appeared,
347
+ and the thread said *"your reply had no ```loom actions block"* directly
348
+ underneath a reply that plainly contained one.
349
+ - The engine parses accumulated turn text, and that text was capped to its
350
+ **last** 20,000 characters. A plan's block sits at the END of a long reply,
351
+ so the cap kept the closing fence and threw away the opening one; the parser
352
+ saw an unterminated block and reported nothing to run. **The better the
353
+ orchestrator planned, the more certainly its plan was binned.** Measured on a
354
+ real run: seven consecutive plans of 6, 5, 5, 5, 5, 8 and 8 tasks, every one
355
+ parseable from the log and every one destroyed.
356
+ - The budget is now far clear of any plausible reply, and when it is reached
357
+ the cut is made at the start of the actions block rather than at a blind
358
+ character offset — so what protects memory can never decapitate the payload.
359
+
360
+ ### Answer an agent where it asked
361
+
362
+ - **An agent's question is now a card you can answer in the thread.** It was a
363
+ line of text with nothing to click, which made the one moment Loom exists to
364
+ surface — an agent blocked on a human — the worst affordance in the app.
365
+ - The answer goes to **the agent that asked**, taken from the card. Through the
366
+ composer it went to `state.selected`, which in an orchestra thread is the
367
+ orchestrator — so answering a worker sent the answer to the wrong agent.
368
+ - A question that plainly offers a choice becomes buttons. Anything ambiguous
369
+ falls back to the text box, because a wrong guess puts words in your mouth
370
+ and sends them to an agent.
371
+
372
+ ### A giant icon no longer eats the Board
373
+
374
+ - Board → GitHub rendered a single enormous ⓘ filling the pane whenever `gh`
375
+ couldn't list pull requests, pushing the columns out of view.
376
+ - `svg()` emitted no width or height, so an icon in a container that forgot its
377
+ CSS rule stretched to fill the line — and `.bnote` was such a container.
378
+ Icons now carry an intrinsic size, so a **future** icon dropped somewhere
379
+ unstyled looks slightly wrong instead of covering the screen.
380
+
381
+ ## [1.0.0] — 2026-09-21
382
+
383
+ ### Rewind — put the work back the way it was
384
+
385
+ - **A checkpoint before every turn**, and **Rewind** on the Update card of the
386
+ turn it undoes. There is a **Rewind…** list under More for all of them, and
387
+ `loom rewind` in the terminal. The honest answer to *undo that* used to be
388
+ "read the diff and retype it": `turn_diff` looks like the answer and isn't,
389
+ since its patch is truncated at 12KB and an untracked file appears in it as
390
+ a line with no content.
391
+ - **It restores files, not history.** HEAD does not move, your commits are not
392
+ touched, and the thread is not edited. What happened still happened.
393
+ - **`.gitignore` applies at capture**, so `node_modules`, build output, `.env`
394
+ and `.loom/` are never read, never stored and never restored — which is why
395
+ a rewind cannot eat the event log.
396
+ - **A rewind is itself rewindable.** It saves what it is about to replace
397
+ before replacing it, and hands that back: *Undo the rewind* in the thread,
398
+ an id on the command line.
399
+ - **Refused while an agent is mid-turn**, naming who. Replacing the tree under
400
+ a running agent puts the damage in whatever it writes next.
401
+ - Checkpoints live on hidden refs under `refs/loom/checkpoints/`, so no branch
402
+ listing, no stash and no `git log` shows one. The newest 60 are kept.
403
+
404
+ ### A transcript you can turn up
405
+
406
+ - **Normal / Thinking / Verbose**, under More. Normal drops reasoning entirely
407
+ rather than folding it — the working out is not the transcript. Verbose
408
+ opens it and attaches the raw payload to tool calls and to the
409
+ orchestrator's brief, the two places a summary stands in for something
410
+ bigger. Remembered per project.
411
+ - **A long block is readable to the end.** Code wraps instead of scrolling out
412
+ of the bubble, and every block — markdown or raw — carries a copy button.
413
+ The orchestrator's `{"actions": …}` plan used to be clipped in a scroll box
414
+ with no way to reach the closing brace.
415
+
416
+ ### Orchestrating from Main stays in Main
417
+
418
+ - **The orchestrator answers in the thread you asked in.** It used to open one
419
+ of its own and walk you into it, leaving the goal you typed behind in a
420
+ thread that then said nothing about it.
421
+ - **Each task row opens that task's thread.** They were findable only by
422
+ hunting the sidebar for a title you half remembered.
423
+ - **A borrowed thread is given back.** Replying in a run's own thread steers
424
+ the run for good; a thread the run borrowed stops answering for it once the
425
+ run is terminal, so Main goes back to being Main rather than forwarding
426
+ every later message to a finished goal.
427
+
428
+ ### A thread says who's working in it, and whether it's still going
429
+
430
+ - **A task thread is labelled with the agent doing that task**, not with
431
+ whoever holds the project baton. During a run with four workers every task
432
+ thread used to claim to be the baton holder, so a Codex task and an
433
+ Antigravity task looked identical. A thread pinned to an agent answers the
434
+ same way.
435
+ - **Thread rows show status** — a live pulse while a task runs, green when it
436
+ finishes, red when it fails, amber when it's waiting. Every answer comes
437
+ from a status the daemon already reports; a thread it can't know about gets
438
+ no mark rather than a guess.
439
+ - The status payload now carries one row per task (thread, agent, kind,
440
+ state) instead of only a count, which is what made both of those possible.
441
+
442
+ ### Models in Orchestrate
443
+
444
+ - **Every agent chip carries its model**, orchestrator and workers alike,
445
+ beside its permission chip. Orchestrate could pick who ran a goal and never
446
+ what they ran it on: the model picker was bound to the one agent the chat
447
+ composer is aimed at, which in Orchestrate is nobody.
448
+ - **A dashed “+ model” chip** adds an API model to the cast and opens its
449
+ picker straight away. Until a model is picked the chip warns, and Orchestrate
450
+ refuses to start — naming the agent — rather than failing three tasks in.
451
+ - The model list's provider-asked source had no case in its footer, so it
452
+ printed *“no model list for this agent”* directly above 446 of them. And it
453
+ no longer offers a model agent a **Default**, which for that kind is the one
454
+ option that cannot work.
455
+
456
+ ## [0.2.6] — 2026-09-20
457
+
458
+ ### Right-click, and a composer that fits
459
+
460
+ - **Right-click a project** for everything you can do to it: open, new chat,
461
+ settings, **rename**, copy path, and **Remove from Loom**. Those were
462
+ scattered — settings behind a gear, rename nowhere at all, and removing a
463
+ project only in `loom projects --forget`.
464
+ - It says **Remove from Loom**, not Delete, and the confirm says the folder,
465
+ the history and `.loom/` stay on disk. A menu item that says delete and
466
+ doesn't is as bad as one that says delete and does.
467
+ - **Right-click a thread** to open it, rename it, pin which agent answers in
468
+ it, or forget it. The main thread offers only what applies to it, rather
469
+ than offering everything and refusing half.
470
+ - Escape and any click outside close the menu, arrow keys walk it, and it
471
+ flips rather than hanging off the edge of the window.
472
+ - **MCPs and Skills moved into a More menu** in the composer, which also
473
+ reaches Prompts and Attach. That row was holding the model, the agent, a
474
+ permission chip, five buttons and send, and wrapped on a narrow window. The
475
+ count badge stayed outside — *two skills are on* is the part you need
476
+ without opening anything.
477
+
478
+ ### Setup tells the truth about this machine
479
+
480
+ - **Claude Code showed "not installed" on machines where it is.** Anthropic's
481
+ installer puts the binary in `~/.local/bin`, and Loom trusted `PATH` alone —
482
+ which an interactive shell has and a detached daemon may not. Codex, Grok
483
+ and Antigravity already looked in their known locations; claude-code was the
484
+ one still guessing. Telling someone to reinstall software they already have
485
+ is the worst kind of wrong answer.
486
+ - **The Model (API) row said "couldn't confirm it's signed in" and printed a
487
+ blank command.** There is nothing to sign in to: a model agent is usable
488
+ when a provider has a key, so it says which providers are configured, and
489
+ when none is, it gives you `loom providers:set …` instead of an empty box.
490
+ - **The desktop app says Loom in the menu bar**, in a dev run as well as a
491
+ packaged one. macOS takes that title from the running bundle, not from
492
+ `app.setName()` — which is why setting the name in code never fixed it. The
493
+ `.app` filename is unchanged, so the Homebrew cask keeps working.
494
+
495
+ ## [0.2.5] — 2026-09-20
496
+
497
+ ### Install it with Homebrew
498
+
499
+ - **`brew tap nickthelegend/loom https://github.com/nickthelegend/loom` then
500
+ `brew install --cask loom-desktop`** — and `brew upgrade --cask` after that,
501
+ which is a real update path for the macOS build that can't replace itself.
502
+ The cask carries both architectures and is regenerated from the published
503
+ checksums by the release job, so it can't go stale.
504
+ - **Check for Updates… recognises a Homebrew install** and hands you the
505
+ `brew upgrade` command instead of downloading over a copy brew is tracking —
506
+ the same rule the Linux `.deb` already had. **Run it in Loom** runs it in
507
+ Loom's own terminal, the one in the dock, so you watch the upgrade rather
508
+ than having it happen invisibly inside the app.
509
+ - It does **not** get you past Gatekeeper, and doesn't pretend to: brew
510
+ quarantines cask downloads on purpose. First launch asks once, as it does
511
+ for a dmg you downloaded yourself. The cask deliberately does not strip the
512
+ quarantine attribute — that protection exists *because* the app is unsigned.
513
+
514
+ ### A model agent can write, when you say so
515
+
516
+ - **`--write`** gives a model agent `write_file`, and **`--run "npm test"`**
517
+ gives it `run` with an allow-list. Every write and every command is a card
518
+ in the thread that you allow or deny before anything happens — the same
519
+ approval surface Claude Code's "always ask" already uses, now asked from
520
+ inside the daemon instead of over MCP.
521
+ - **It asks in `auto` too**, which is stricter than the CLI mapping and
522
+ deliberately so: a CLI in your roster is one you installed and signed into,
523
+ and a model agent is a name you picked off a provider's list an hour ago.
524
+ `bypass` is the only mode that doesn't ask, because that is what bypass
525
+ means.
526
+ - **The card says what would happen** — *write src/app.ts: 40 lines
527
+ (replacing 12) — fix the port* — rather than dumping the whole new file at
528
+ you.
529
+ - The allow-list is a prefix match on whole commands and there is no shell, so
530
+ `npm test` permits `npm test --watch` and refuses `npm testify`,
531
+ `npm test; rm -rf ~`, backticks, pipes and redirection. A tool is only
532
+ offered when it can be used: no allow-list, no `run` tool at all.
533
+ - With nobody to ask — no daemon, a script, a test — the answer is **no**. A
534
+ tool that proceeded because the UI wasn't wired up would be the worst
535
+ failure this could have.
536
+
537
+ ### A model agent can read the project
538
+
539
+ - **`"tools": true`** on a `model` agent gives it `read_file`, `list_files`
540
+ and `search` — read-only, inside the project, `.git` and `.loom` excluded,
541
+ every path resolved and proven contained before anything opens it. A
542
+ reviewer that can't read the file it's reviewing is being asked to guess.
543
+ - Each call appears in the thread as a `tool_call`, like any other agent's
544
+ work, and the loop is bounded: after eight hops the model is told to answer
545
+ with what it has rather than being cut off mid-thought.
546
+ - **No writing and no shell.** A model that can write files is exactly as
547
+ dangerous as a CLI that can, and the right answer is the permission layer
548
+ Loom already has. That's the rest of #87, and it stays open for it — a free
549
+ model editing a repository because it felt like it is not a thing to ship
550
+ quietly.
551
+
552
+ ### Ask several models at once
553
+
554
+ - **`loom ask --models a,b,c "…"`** sends one prompt to several models at the
555
+ same time, each in its own thread named after the model, with the project's
556
+ memory brief attached. `--free` picks the free ones the providers have right
557
+ now, up to `--limit`. With free quota, asking five models costs what asking
558
+ one costs — and *which of these is right* is a judgement a person makes in
559
+ ten seconds and a model makes badly.
560
+ - The agents that run are **transient**: five asks don't leave five agents in
561
+ your roster. The threads stay, because those are the part worth keeping.
562
+ - One model failing doesn't take the others down — its thread carries the
563
+ error, the rest carry their answers.
564
+
565
+ ### A thread remembers who answers in it
566
+
567
+ - **Pin an agent to a thread** and it answers there, whoever holds the baton —
568
+ so two threads can be talking to two agents at once, which is the point of
569
+ having agents that cost nothing. Picking an agent for a new chat now pins it
570
+ instead of handing over the baton, and the sidebar shows which thread is
571
+ with whom.
572
+ - **It doesn't take the baton.** The baton is the write lock for work on the
573
+ repository; a conversation doesn't need it, and taking it would stop
574
+ whatever is actually working.
575
+ - A thread can pin a **model** too, for agents that can change model per turn
576
+ (the `model` kind). Binding one to an agent that bakes its model into a
577
+ spawned process is refused where you can fix it, rather than ignored where
578
+ you'd never notice. The main thread still follows the baton — that's what
579
+ makes it the main thread — and a thread whose agent has left the roster
580
+ falls back to the baton rather than becoming one nobody can type in.
581
+
582
+ ### Agents that are models, not CLIs
583
+
584
+ - **A new agent kind, `model`.** It's an HTTP endpoint rather than a
585
+ subprocess: OpenAI-compatible chat completions, streamed into the thread as
586
+ they arrive, with reasoning shown as reasoning and token counts on
587
+ `run_complete`. Nothing to install. It has no tools yet, so what it's for is
588
+ the thinking work — planning, reviewing, summarising, answering — which is
589
+ most of what a fleet does between edits.
590
+ - **Providers, and keys where keys belong.** OpenRouter, AgentRouter, OpenAI,
591
+ Groq and a local Ollama are known by name; anything else speaking
592
+ `/v1/chat/completions` works with a base URL. The project config names a
593
+ *provider*, never a secret: keys live in the environment or in
594
+ `~/.loom/providers.json` (0600), and no route, log or listing ever returns
595
+ one — you get the last four characters. `loom providers`,
596
+ `loom providers:set <id> --key …`.
597
+ - **`loom models`** asks each configured provider what it can run right now,
598
+ cached for ten minutes and refreshable, with the free ones marked. A model
599
+ list that's typed out by hand goes stale; one that's asked for doesn't.
600
+ - **Fallbacks that read the answer.** A dry free pool (402) or a rate limit
601
+ (429) moves to the next model in `fallbacks` and says so once in the thread;
602
+ a wrong or retired model name (503) stops, because trying something else
603
+ would hide the typo rather than fix it. Each refusal is explained in its own
604
+ terms — a rejected *client* is not a rejected key.
605
+
606
+ ### Retrieval that can follow a synonym
607
+
608
+ - **A semantic channel for the brain** (`brain.semantic`, or Settings →
609
+ Brain): all-MiniLM-L6-v2 embeddings unioned with the three lexical channels,
610
+ so *how does login work* reaches a note about Supabase JWKS. Measured on the
611
+ recall set that shipped with 0.2.4: recall@5 **0.50 → 1.00** on synonyms,
612
+ **0.80 → 1.00** across word forms, unchanged at **1.00** on literal queries.
613
+ Warm cost is about a millisecond a query.
614
+ - It is **not** a dependency and never will be: the model is 23MB but its ONNX
615
+ runtime is ~470MB, so Loom asks you to install that yourself
616
+ (`npm i -g @huggingface/transformers`) and behaves exactly as before when
617
+ it's missing — a channel that can be absent must fail into the old answer,
618
+ not into an error. Vectors are cached per memory hash beside the brain, and
619
+ the model stays offline after its first download.
620
+
621
+ ### macOS gets the update too
622
+
623
+ - **Help → Check for Updates… on macOS** now finds the build for your
624
+ architecture, downloads it, and **verifies its SHA-256** against the
625
+ checksums the release publishes — a file that doesn't match is deleted
626
+ rather than opened — then opens the disk image for you to drag across. The
627
+ drag stays yours: macOS only lets an app signed by a certificate it trusts
628
+ replace itself, and this build is ad-hoc signed. The checking is the part
629
+ worth having; the checksums have shipped since 0.2.0 and nobody compares
630
+ them by hand.
631
+
632
+ ## [0.2.4] — 2026-09-20
633
+
634
+ ### The desktop app can update itself, where that's honest
635
+
636
+ - **Help → Check for Updates…** on **Windows** and the **Linux AppImage**:
637
+ it asks before downloading, installs on quit, and restarts only when you
638
+ press Restart. On **macOS** it refuses and says why — the build is ad-hoc
639
+ signed, and macOS only replaces an app signed by a certificate it already
640
+ trusts — and opens the releases page instead. A `.deb` install is left to
641
+ the package manager that owns it. The release now publishes the update feed
642
+ for those two platforms and deliberately not for macOS: advertising an
643
+ update the OS will refuse to install is worse than advertising none.
644
+
645
+ ### Dark mode in the preview
646
+
647
+ - **Auto / light / dark for the previewed page**, independent of Loom's own
648
+ theme and remembered per project, alongside the widths. It re-points the
649
+ page's own `prefers-color-scheme` rules through the proxy bridge and makes
650
+ `matchMedia` answer to match, so both CSS-themed and JS-themed apps follow;
651
+ Auto restores every rule exactly as it shipped. Where Loom can't reach the
652
+ page it says so rather than offering a switch that does nothing, and the
653
+ screenshot — a real browser — honours the scheme either way.
654
+ - The width you chose is now actually **read back**: it was being saved and
655
+ never restored, which is the same as not remembering it.
656
+ - A screenshot and an element pick both carry the conditions they were taken
657
+ under (*375×812, dark mode*) into the prompt.
658
+
659
+ ### The baton can carry the work
660
+
661
+ - **`git.mergeOnHandoff`** (with `worktreePerAgent`): handing the baton from A
662
+ to B merges `agent/A` into B's checkout, so the next agent starts from what
663
+ the last one finished. It refuses rather than guesses — uncommitted work on
664
+ either side, or a merge already in progress, is reported instead of merged —
665
+ and a conflict is left in the tree with the files named, in the briefing and
666
+ in the handoff event. A conflict stops a route instead of prompting an agent
667
+ on top of conflict markers.
668
+
669
+ ### Routes: steps that decide whether to run
670
+
671
+ - **A route step can carry a condition on the previous turn** and is skipped
672
+ when it doesn't hold: `loom route 'planner,executor,reviewer?lines>200' "…"`,
673
+ or `{ "step": "reviewer", "when": "lines>200" }` in the project config.
674
+ Conditions read the turn's own diff — `changed>N`, `changed<N`, `lines>N`,
675
+ `lines<N`, `touched:<glob>`, `!touched:<glob>` — and nothing else: a
676
+ condition must be something Loom measured, never a judgement about the work.
677
+ Unreadable ones are refused when the route is defined rather than quietly
678
+ never matching, the first step can't be conditional (no turn to measure),
679
+ and a skipped step appears in the thread with the numbers that decided it.
680
+ Skipping isn't failing — the route completes.
681
+
682
+ ### A pull request you asked for
683
+
684
+ - **Open PR on a review card.** With branch-per-card on, a card in review shows
685
+ what a PR would carry — the branch, its commits, its files and the exact
686
+ command — and opens it only when you press the button. Asking pushes
687
+ nothing; publishing has never been implicit and still isn't.
688
+
689
+ ### Coming back to a project
690
+
691
+ - **A digest of what happened while you were away** — goals, landings,
692
+ failures, a dead server, and what's waiting on you, newest first and each
693
+ line clicking through to the moment it came from. Shown when you've actually
694
+ been away; `loom digest --since 8` in the terminal.
695
+ - **The desktop app's notifications carry the question itself**, not "an agent
696
+ needs you", and on macOS you can answer from the notification. Nothing fires
697
+ while you're looking at that conversation.
698
+
699
+ ### Goals: a spend cap, and more than one at a time
700
+
701
+ - **`loom orchestrate --max-usd 2`** stops a goal at its cap the way the team
702
+ budget always did — running work finishes, nothing new starts, and the goal
703
+ waits for you. A project default lives in `budgets.perGoalUsd`, and a word
704
+ lands in the thread at 80% rather than the stop being the first you hear.
705
+ - **`maxConcurrentGoals`** lets disjoint goals run side by side. A goal's
706
+ scope is the `touches` its plan declares; one that hasn't said what it
707
+ touches counts as everything and waits. Overlaps queue with the collision
708
+ named. Still one at a time unless you ask for more.
709
+
710
+ ### The queue can wait, and can be kept
711
+
712
+ - **Queue for later**: a prompt can be held for a time, until a goal actually
713
+ **lands**, until that goal's **checks go green**, or until the project has
714
+ been quiet for a while. The row says what it's waiting for and a click
715
+ releases it. (`loom queue at 03:00 …`, `loom queue after green:<runId> …`)
716
+ - **Recipes**: save what's queued and run it on any project. Steps remember
717
+ their target by **role**, so a recipe travels; anything the project can't
718
+ resolve becomes an Auto prompt rather than a refusal. (`loom queue save`,
719
+ `loom queue run`, `loom queue recipes`)
720
+ - **Drag to reorder** in the web app; the arrows stay for anyone who can't
721
+ drag, and the phone gained up/down controls it never had.
722
+
723
+ ## [0.2.3] — 2026-09-20
724
+
725
+ ### The Browser tab knows your dev servers
726
+
727
+ - **Loom can run them.** Declared under `servers` in `.loom/config.json` and
728
+ suggested from `package.json` (a suggestion you accept, never something that
729
+ starts itself). Start, stop and restart from the Browser tab or the CLI.
730
+ - **The state is a fact, not a guess**: *running* means a port answered,
731
+ *starting* means the process is up and nothing is listening yet, and
732
+ *crashed* carries the exit code.
733
+ - **Its output is there too**, under the page it serves — which is where the
734
+ reason for a blank frame usually is — and a server that dies while an agent
735
+ is working against it says so in the thread.
736
+ - Clicking a server points the preview at it; no more typing ports from memory.
737
+ - Every server Loom started is stopped when the daemon goes, so nothing is left
738
+ holding a port.
739
+ - `loom servers`, `loom servers start|stop|restart <name>`, `loom servers logs
740
+ <name>`.
741
+ - **The preview emulates a width** — Fit / 375 / 768 / 1280, remembered per
742
+ project and scaled down when the dock is narrower than the page.
743
+ - **It reloads when an agent changes files** (a toggle, on by default), so
744
+ watching a change land doesn't involve remembering to refresh.
745
+ - **The previewed page reports back.** Loom previews a server through its own
746
+ proxy — forwarding everything, including the hot-reload socket — and injects
747
+ one script. The **Page** pane shows the page's console and its requests,
748
+ live, and a click puts a line into the composer as context.
749
+ - **An element picker.** Click the thing that's wrong in the preview and its
750
+ selector, text, box and markup land in the composer.
751
+ - **A camera button puts the view into the composer.** The page is another
752
+ origin and can't photograph itself, so the daemon takes the shot with the
753
+ project's own Playwright; a project without it is told exactly that.
754
+
755
+ ### An Update button that actually updates
756
+
757
+ - **Loom says when a newer version is out** — checked against the published
758
+ release, cached for hours, shown as a pill in the status bar.
759
+ - **One button in Settings → Updates**, which says exactly what it will run
760
+ before it runs it: a git checkout pulls and rebuilds, a global npm install
761
+ reinstalls itself, and anything else is pointed at the release rather than
762
+ having a command guessed at and run over it.
763
+ - **A checkout with uncommitted changes is refused** (modified tracked files —
764
+ an untracked scratch file doesn't stop a fast-forward).
765
+ - The commands' output streams while they run, then the daemon restarts on the
766
+ new build and the page reconnects to it.
767
+ - `loom update [--check] [--yes]` does the same from the terminal.
768
+
769
+ ## [0.2.1] — 2026-09-20
770
+
771
+ ### The prompt queue
772
+
773
+ - **What you type while something is running now waits where you can see it.** A
774
+ prompt sent to a busy agent used to be queued invisibly — logged into the
775
+ thread as if it had been sent, with nothing to look at and nothing to change —
776
+ and a goal typed while another goal ran was refused outright.
777
+ - **The queue is a surface**, above the composer on the web, the desktop app and
778
+ the phone, and `loom queue` in the terminal: every waiting prompt with who
779
+ takes it, editable in place, movable, removable, pausable.
780
+ - **Each prompt names its own target:** one agent, the **orchestrator** (a whole
781
+ new goal, started when the running one finishes), or the auto router — and you
782
+ can change it while the prompt waits. The baton moves with it.
783
+ - **A question holds the queue:** an agent that stops to ask you something isn't
784
+ answered by whatever you queued behind it. The queue waits and names who
785
+ asked; your typed reply goes straight out and lifts the hold, so what was
786
+ waiting runs next. A pause you set yourself stays until you resume it.
787
+ - **Stop pauses the queue** instead of emptying it, and a prompt that can't be
788
+ sent (budget, quarantine, a policy, a missing agent) stays put with the reason
789
+ on the queue rather than disappearing.
790
+ - **A prompt enters the conversation when it is sent**, not when it is queued, so
791
+ the thread stays an honest record of what each agent was actually asked.
792
+ - Survives a daemon restart, reloaded **paused** (`.loom/queue.json`). API:
793
+ `GET/POST /api/projects/:id/queue`, `PATCH|DELETE .../queue/:itemId`,
794
+ `POST .../queue/pause`, `DELETE .../queue`, plus a live `queue` socket frame.
795
+
796
+ ### Fixed
797
+
798
+ - **An override of `loom/review` made while that review is still running** is no
799
+ longer overwritten when the review finishes (D61) — found on a real PR, where
800
+ a late review wrote `failure` over the owner's decision.
801
+ - **A turn is no longer blamed for Loom's own `.loom/` files.** In a project that
802
+ doesn't gitignore `.loom/`, the event log and the queue file were landing in
803
+ the agent's turn diff.
804
+ - **grok-code and agy** are detected from their own auth files instead of being
805
+ reported signed-out, and the status bar says **live**, not offline, before a
806
+ project is open.
807
+ - **A reply that lands after its window closed** no longer throws from a redraw.
808
+ - **An overridden review leaves its status where the owner put it.** A review
809
+ coming back to a commit that was already overridden kept the decision but
810
+ posted nothing, leaving its own "reviewing…" status pending — on a repo that
811
+ requires `loom/review`, for ever.
812
+ - **Retargeting a queued prompt** to an agent the project doesn't have is
813
+ refused when you make the change, not when the queue reaches it.
814
+
815
+ ### Loom Teams, Phase 6: land in turn, hear it now
816
+
817
+ - **6 more design decisions** (D79–D84), settled with the owner.
818
+ - **The landing train:** on a repo with no merge queue, Land queues a goal in its
819
+ lanes and Loom merges it on its turn: fresh main in, the fast tests, a push,
820
+ green checks on that commit, then `gh pr merge --squash`. The slot is a team-hub
821
+ lease on `.loom/landing/<lane>` held as a hard zone, so every hub (in-memory,
822
+ `loom hub`, hosted SQL) arbitrates it with no new API. Waiting goals show
823
+ **queued** and go as soon as the lane frees. A red check on its turn hands the
824
+ lane on, and the goal rejoins when it's green. Repos with a merge queue land as
825
+ before.
826
+ - **Lanes:** `landing.lanes` in `loom.team.json` are path scopes; goals in
827
+ different lanes land at the same time.
828
+ - **GitHub webhooks into the hub, no App needed:** `loom hub` takes
829
+ `POST /github/webhook/:teamId`, checks `X-Hub-Signature-256` against the team's
830
+ secret, and posts PR, check, review and deploy events to the feed.
831
+ `loom team webhook [--install] [--rotate]` sets it up. The hosted hub gets a
832
+ `github-webhook` Edge Function and `supabase/migrations/0009_phase6.sql`
833
+ (deployment pending).
834
+ - **Polling and webhooks agree:** one mapping (`src/core/github-events.ts`) gives
835
+ both the same dedupe keys, so a fact is posted once. Failing checks are now one
836
+ feed event per check and commit, and `gh pr list` polling reads `headRefOid`.
837
+ - **Faster fixes:** a check result or merge for one of your goal PRs makes your
838
+ daemon look at it immediately, not at the next 30-second poll.
839
+ - **UI:** a `queued` landing chip (desktop and phone), and feed lines for the
840
+ train and for reviews that arrive by webhook.
841
+
842
+ ## [0.2.0] — 2026-09-19
843
+
844
+ Loom Teams: five phases, 78 design decisions, several people and their agents on
845
+ one repo. The sections below go phase by phase, newest first.
846
+
847
+ ### Loom Teams: loose ends closed
848
+
849
+ - **Paste-the-URL sign-in** for the hosted hub on machines without a browser
850
+ (`loom team signin --paste`; `loom runner join` uses it by default).
851
+ - **Stacks fold when a lower PR keeps failing:** its lower PRs close and the top
852
+ one retargets the base branch, so the normal fix loop can fix it.
853
+ - **CI minutes per goal:** Actions time on a goal's branch is recorded when it
854
+ lands and shown in team spend (desktop and phone).
855
+ - **Docs:** a Teams user guide ([docs/teams.md](docs/teams.md)), a docs index,
856
+ a source map, and READMEs for `supabase/`, `src/hub/`, `test/`, `scripts/`
857
+ and `hardware/`.
858
+
859
+ ### Loom Teams, Phase 5: runners
860
+
861
+ - **12 more design decisions** (D67–D78), settled in a design interview.
862
+ - **Runners:** a member's always-on Loom daemon that takes goals from the team
863
+ hub. Pair it with `loom runner pair` / `join` (a device of the same member,
864
+ revocable with key rotation); keep it up with `loom runner install` or
865
+ `Dockerfile.runner`.
866
+ - **Jobs on the hub:** start / continue / fix / return / land, with atomic claims,
867
+ heartbeats carrying a progress snapshot, and stale reclaim (MemoryHub, `loom
868
+ hub`, SQL `0007_runners.sql`).
869
+ - **Move a running goal** to a runner at a safe point (branches pushed to
870
+ `refs/loom/run/<id>/*`, the orchestrator resumes there) and **bring it back**;
871
+ Land reaches goals that live on a runner.
872
+ - **Trust tier:** a fresh clone (or container) per goal, a scrubbed environment,
873
+ `runners.permissions` as the ceiling, shared runners only when
874
+ `runners.shared` allows, a fine-grained token checked by `loom runner doctor`.
875
+ - **Away-from-keyboard CI fixes:** the owner's runner takes a goal that needs
876
+ someone once the owner has been offline 15 minutes.
877
+ - **Deploys and release notes:** deployment results in the feed, a phone alert
878
+ when a failed deploy contains your goal, `loom team release-notes --since`.
879
+ - **Phone:** tapping an alert opens its project and goal.
880
+
881
+ ### Loom Teams, Phase 4: land safely
882
+
883
+ - **15 more design decisions** (D52–D66), settled in a design interview.
884
+ - **Checks come back to the owner:** the owner's daemon polls its goal PRs every
885
+ 30s (`gh pr checks --required`). A failing check is rerun once; a pass on rerun
886
+ is labelled `loom:flaky`. A real failure's log tail (fenced as untrusted) reopens
887
+ the goal, and the fix is pushed to the same PR. At most 2 attempts, then the
888
+ goal needs a human and the phone is alerted.
889
+ - **Cross-vendor review:** a different-vendor agent reviews each goal PR on open
890
+ and after each fix (max 3), posts a COMMENT review and a `loom/review` status;
891
+ only high findings fail it, and they share the fix budget. Owners can override
892
+ with a reason.
893
+ - **Land** (`loom land`, a button on desktop and phone): fresh main merged in,
894
+ `landing.fastTest` from `loom.team.json`, push, `gh pr merge --auto --squash`.
895
+ Conflicts get one agent attempt; hard-zone conflicts go to a human.
896
+ - **Stacks** (opt-in, `delivery.stack: "auto"`): big goals become 2–4 PRs cut
897
+ along the integration branch's merge commits, landed bottom-up.
898
+ - **Adopt:** a teammate takes a stuck goal whose owner is away, fixes it on the
899
+ owner's branch, and hands it back; the owner's daemon backs off meanwhile.
900
+ - **Budgets:** per-goal cap (pauses the goal) and per-member daily cap (no new
901
+ goals); cost rollups per member/day, per goal and per landed PR.
902
+ - **Doctor:** `loom team doctor` reports merge-queue traps and opens a PR adding
903
+ `merge_group:` to workflows. It never changes settings.
904
+ - **Hosted hub:** `SupabaseHubClient` over RPC and Realtime, GitHub sign-in via
905
+ Supabase (loopback), `loom team signin` defaults to hosted; SQL `0005`
906
+ (`extend_lease`, `team_member_list`) and `0006` (landing feed events).
907
+
908
+ ### Loom Teams, Phase 3: one brain
909
+
910
+ - **12 more design decisions** (D40–D51), settled in a design interview.
911
+ - **Team memories:** durable memories from a shared project are published to the
912
+ hub sealed under the team key, with an HMAC of the normalized text. The hub
913
+ merges exact twins as confirmations without reading them (MemoryHub, `loom hub`
914
+ and SQL `0004_team_memories.sql`, tested on Postgres).
915
+ - **Who can change what:** only a memory's author edits or forgets it; a teammate
916
+ records a correction that supersedes it. Resolving keeps the loser, linked to
917
+ the winner, which inherits its confirmations.
918
+ - **Tiered briefings:** canon > confirmed by 2+ > your own > a teammate's
919
+ proposal, each line labelled. Failures and facts age out of briefings after ~90
920
+ days unless re-confirmed.
921
+ - **Untrusted memories:** a turn that read the web, GitHub issue/PR text or a
922
+ fetched URL marks what it taught as untrusted. Untrusted memories stay personal
923
+ until you trust them.
924
+ - **Canon in `AGENTS.md`:** a Loom-managed section with per-line markers; lines
925
+ added by hand count too. Promotion goes through one rolling `loom/canon` PR,
926
+ which also adds `@AGENTS.md` to `CLAUDE.md`. The native-memory import skips the
927
+ section, so canon never loops back in.
928
+ - **Live team context** in worker and handoff briefings, up to 1.5k characters:
929
+ - teammates' leases on the same paths;
930
+ - open PRs that change them (PR feed events now carry changed paths);
931
+ - failing checks;
932
+ - predicted conflicts.
933
+ - **Inbox:** contradictions, near-duplicates, corrections, untrusted memories and
934
+ promotion candidates. REST `/api/projects/:id/team/brain[/:action]` and
935
+ `loom team brain`.
936
+
937
+ ### Loom Teams, Phase 2: stop colliding
938
+
939
+ - **12 more design decisions** (D28–D39), settled in a design interview.
940
+ - **Leases:**
941
+ - scopes are expanded to real files plus directory prefixes, and hard zones come
942
+ from `loom.team.json`;
943
+ - hub claim, extend, renew, landing and release, with atomic hard-zone
944
+ arbitration, in both MemoryHub and SQL (tested on Postgres).
945
+ - **Orchestra holds** stop a task from starting:
946
+ - **decide:** the task overlaps a teammate's lease and needs an `overlap`
947
+ decision;
948
+ - **wait:** it waits for another goal's PR to merge, then rebases onto main;
949
+ - **zone:** it queues behind a held hard zone;
950
+ - **capacity:** the team is at its agent limit;
951
+ - "Stop waiting" releases a wait by hand.
952
+ - **Drift:** when a worker edits outside its declared touches, the lease widens and
953
+ the team is told. Drift into someone else's hard zone pauses the worker.
954
+ - **WIP refs** (`refs/loom/wip/<member>/<run>`) plus `git merge-tree` predict
955
+ conflicts. Both owners and both orchestrators hear about them.
956
+ - **Leases are released when the goal lands.** "Landing" means a merged PR, a
957
+ delivered push, or an applied run.
958
+ - **Team policy enforced:** permission ceiling (`bypassRequiresPlan`), agent
959
+ allowlist, protected-branch delivery (forces a PR), and per-member and
960
+ team-wide concurrency caps.
961
+ - **Fixes:**
962
+ - an orchestrator replying with no actions while nothing was running looped
963
+ until the round limit, and now waits for a human;
964
+ - an abort during a run's final wrap-up was overwritten by "completed";
965
+ - a member's own `gh` poll reporting their PR merged was ignored.
966
+
967
+ ### Loom Teams, Phase 1: see each other
968
+
969
+ - **The design is settled:** 27 decisions from a design interview, recorded in
970
+ docs/teams-architecture.md §1a.
971
+ - **Team crypto:**
972
+ - an XChaCha20-Poly1305 team key;
973
+ - an X25519 sealed box for key envelopes;
974
+ - Ed25519 signatures on everything a daemon publishes;
975
+ - the invite link carries the key in its `#fragment`.
976
+ - **The hub:**
977
+ - the `HubClient` protocol, with `MemoryHub` as the reference rules;
978
+ - `loom hub`, a self-hosted hub over HTTP + WebSocket;
979
+ - the hosted hub's SQL (RLS plus rule functions), tested against a real Postgres.
980
+ - **Team Link in the daemon:**
981
+ - sign-in, create, invite, join and leave;
982
+ - removal rotates the key forward;
983
+ - opt-in project sharing, with auto-match on the git remote;
984
+ - heartbeats carry intent only;
985
+ - a goal/plan/PR feed, with `gh` polling when there is no GitHub App.
986
+ - **Worker commits carry `Loom-Goal`, `Loom-Task`, `Loom-Agent` and `Loom-Member`
987
+ trailers.**
988
+ - **The orchestra protocol gains `touches`** (declared file globs per task).
989
+ - **Fix:** a removed member's daemon now hears its own removal. It was cut off
990
+ before the announcement.
991
+
992
+ ### Permissions, plan mode, git delivery, fleet, prompts
993
+
994
+ - **Permission modes per agent: bypass, auto, always ask.**
995
+ - Each is mapped onto each CLI's own flags, and every cell was verified against
996
+ the real CLI (`scripts/verify-permissions.mjs`).
997
+ - Always ask on Claude Code routes each tool use to a real approval in Loom,
998
+ through a built-in MCP permission-prompt server. Verified with the real CLI
999
+ (`scripts/verify-approvals.mjs`).
1000
+ - Two cells measured broken are shown as unavailable instead of lying: OpenCode
1001
+ "ask", and Antigravity "auto" (which writes to agy's scratch folder).
1002
+ - **Plan mode.**
1003
+ - Chat turns write a markdown plan instead of code.
1004
+ - Orchestras commit `plans/<run>/PLAN.md` plus a spec per task before workers
1005
+ start, and write results back at the end.
1006
+ - **Git delivery policy: none, commit, push, or PR.** Covers chat turns and finished
1007
+ orchestras. PR mode pushes the run's branch and opens a PR with `gh`.
1008
+ - **Fleet:** `GET /api/activity` and a Fleet view of every agent's thread, task and
1009
+ last step.
1010
+ - **Prompt manager:** saved and pinned prompts, plus automatic sent-prompt history
1011
+ (`/api/prompts`).
1012
+ - **Teams:** researched architecture in docs/teams-architecture.md.
1013
+
1014
+ ### Orchestra: one orchestrator, many parallel workers
1015
+
1016
+ - **`loom orchestrate "<goal>"`**, plus Orchestrate mode in the app.
1017
+ - Any agent can orchestrate: Claude Code, Codex, Antigravity, Grok or OpenCode.
1018
+ It plans the goal into a task graph.
1019
+ - Worker agents run every ready task at once, mixed kinds or several of the same
1020
+ kind. Each task gets its own thread and git worktree.
1021
+ - Finished work merges into `loom/orchestra/<run>/main`, and the orchestrator
1022
+ reviews, follows up, or finishes.
1023
+ - `orchestra:apply` merges the run into your branch. Nothing touches it before
1024
+ that.
1025
+ - Verified against the real CLIs:
1026
+ - Claude orchestrating Codex and Antigravity (278 s);
1027
+ - Codex orchestrating Grok, OpenCode and Claude Code (82 s, $0.31).
1028
+ - Both delivered working code with passing tests
1029
+ (`scripts/verify-orchestra.mjs`).
1030
+ - Design credit: Agent Orchestrator (Apache-2.0). See THIRD_PARTY_NOTICES.md.
1031
+
1032
+ ### Loom Cloud: reach your agents from any network
1033
+
1034
+ - A Supabase Realtime relay, end-to-end encrypted (XChaCha20-Poly1305). The key
1035
+ exists only in the pairing QR's URL fragment, so Supabase relays ciphertext.
1036
+ - Relayed requests run against the daemon with the phone's own token. The admin
1037
+ bootstrap is refused over the relay.
1038
+ - New commands: `loom cloud enable|disable|rotate`. Setup guide: docs/cloud.md.
1039
+ - Connection patterns credited to T3 Code (MIT).
1040
+
1041
+ ### Fixes found by running the real agents
1042
+
1043
+ - A worker's `.loom/` state made `git add` fail whenever the project gitignored
1044
+ `.loom/`. That failed every real Codex task.
1045
+ - A project reached through a symlink (every macOS temp dir) registered twice, so
1046
+ two runtimes ran over one `.loom/`.
1047
+ - OpenCode's default model is refused headless ("Model is unavailable"). With no
1048
+ model pinned, the adapter now picks one the server can actually run.
1049
+ - `test/git.test.ts` assumed the default branch is `main`; CI runners use `master`.
1050
+
1051
+
10
1052
  ### Hardening (production-readiness pass)
11
1053
 
12
1054
  - **Closed a DNS-rebinding path to the admin token.** `GET /api/bootstrap` handed