@loompad/cli 0.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/ARCHITECTURE.md +96 -11
  2. package/CHANGELOG.md +1054 -0
  3. package/README.md +1473 -44
  4. package/THIRD_PARTY_NOTICES.md +275 -0
  5. package/dist/adapters/antigravity-cli.d.ts +62 -0
  6. package/dist/adapters/antigravity-cli.js +258 -0
  7. package/dist/adapters/antigravity-cli.js.map +1 -0
  8. package/dist/adapters/base.d.ts +61 -9
  9. package/dist/adapters/base.js +266 -15
  10. package/dist/adapters/base.js.map +1 -1
  11. package/dist/adapters/bridges/antigravity.d.ts +9 -12
  12. package/dist/adapters/bridges/antigravity.js +9 -12
  13. package/dist/adapters/bridges/antigravity.js.map +1 -1
  14. package/dist/adapters/echo.d.ts +1 -0
  15. package/dist/adapters/echo.js +59 -3
  16. package/dist/adapters/echo.js.map +1 -1
  17. package/dist/adapters/grok.d.ts +7 -0
  18. package/dist/adapters/grok.js +20 -10
  19. package/dist/adapters/grok.js.map +1 -1
  20. package/dist/adapters/index.d.ts +5 -1
  21. package/dist/adapters/index.js +53 -7
  22. package/dist/adapters/index.js.map +1 -1
  23. package/dist/adapters/model.d.ts +137 -0
  24. package/dist/adapters/model.js +527 -0
  25. package/dist/adapters/model.js.map +1 -0
  26. package/dist/adapters/opencode.d.ts +101 -1
  27. package/dist/adapters/opencode.js +874 -98
  28. package/dist/adapters/opencode.js.map +1 -1
  29. package/dist/cli/doctor.d.ts +32 -0
  30. package/dist/cli/doctor.js +89 -4
  31. package/dist/cli/doctor.js.map +1 -1
  32. package/dist/cli/index.js +2651 -87
  33. package/dist/cli/index.js.map +1 -1
  34. package/dist/cli/tui-model.js +3 -1
  35. package/dist/cli/tui-model.js.map +1 -1
  36. package/dist/cli/tui.js +44 -1
  37. package/dist/cli/tui.js.map +1 -1
  38. package/dist/cli/ui.d.ts +2 -0
  39. package/dist/cli/ui.js +13 -0
  40. package/dist/cli/ui.js.map +1 -1
  41. package/dist/core/ades.d.ts +32 -16
  42. package/dist/core/ades.js +57 -20
  43. package/dist/core/ades.js.map +1 -1
  44. package/dist/core/agent-state.d.ts +14 -0
  45. package/dist/core/agent-state.js +32 -0
  46. package/dist/core/agent-state.js.map +1 -0
  47. package/dist/core/approvals.d.ts +33 -0
  48. package/dist/core/approvals.js +29 -0
  49. package/dist/core/approvals.js.map +1 -0
  50. package/dist/core/backup.d.ts +19 -0
  51. package/dist/core/backup.js +86 -0
  52. package/dist/core/backup.js.map +1 -0
  53. package/dist/core/baton.d.ts +2 -2
  54. package/dist/core/baton.js.map +1 -1
  55. package/dist/core/brain-extract.d.ts +17 -0
  56. package/dist/core/brain-extract.js +28 -2
  57. package/dist/core/brain-extract.js.map +1 -1
  58. package/dist/core/brain-index.d.ts +71 -0
  59. package/dist/core/brain-index.js +204 -5
  60. package/dist/core/brain-index.js.map +1 -1
  61. package/dist/core/brain.d.ts +58 -2
  62. package/dist/core/brain.js +79 -1
  63. package/dist/core/brain.js.map +1 -1
  64. package/dist/core/chat-import.d.ts +71 -0
  65. package/dist/core/chat-import.js +419 -0
  66. package/dist/core/chat-import.js.map +1 -0
  67. package/dist/core/checkpoint.d.ts +107 -0
  68. package/dist/core/checkpoint.js +259 -0
  69. package/dist/core/checkpoint.js.map +1 -0
  70. package/dist/core/claude-cli.js +1 -1
  71. package/dist/core/claude-cli.js.map +1 -1
  72. package/dist/core/continuity/artifacts.d.ts +14 -0
  73. package/dist/core/continuity/artifacts.js +118 -0
  74. package/dist/core/continuity/artifacts.js.map +1 -0
  75. package/dist/core/continuity/capabilities.d.ts +65 -0
  76. package/dist/core/continuity/capabilities.js +129 -0
  77. package/dist/core/continuity/capabilities.js.map +1 -0
  78. package/dist/core/continuity/contracts.d.ts +352 -0
  79. package/dist/core/continuity/contracts.js +117 -0
  80. package/dist/core/continuity/contracts.js.map +1 -0
  81. package/dist/core/continuity/engine.d.ts +55 -0
  82. package/dist/core/continuity/engine.js +504 -0
  83. package/dist/core/continuity/engine.js.map +1 -0
  84. package/dist/core/continuity/store.d.ts +73 -0
  85. package/dist/core/continuity/store.js +438 -0
  86. package/dist/core/continuity/store.js.map +1 -0
  87. package/dist/core/conversations.d.ts +19 -0
  88. package/dist/core/conversations.js +87 -0
  89. package/dist/core/conversations.js.map +1 -0
  90. package/dist/core/crew-coordination.d.ts +6 -0
  91. package/dist/core/crew-coordination.js +24 -0
  92. package/dist/core/crew-coordination.js.map +1 -0
  93. package/dist/core/crew-policy.d.ts +18 -0
  94. package/dist/core/crew-policy.js +40 -0
  95. package/dist/core/crew-policy.js.map +1 -0
  96. package/dist/core/crew-protocol.d.ts +64 -0
  97. package/dist/core/crew-protocol.js +146 -0
  98. package/dist/core/crew-protocol.js.map +1 -0
  99. package/dist/core/crew-requests.d.ts +14 -0
  100. package/dist/core/crew-requests.js +22 -0
  101. package/dist/core/crew-requests.js.map +1 -0
  102. package/dist/core/crew.d.ts +395 -0
  103. package/dist/core/crew.js +1857 -0
  104. package/dist/core/crew.js.map +1 -0
  105. package/dist/core/digest.d.ts +40 -0
  106. package/dist/core/digest.js +94 -0
  107. package/dist/core/digest.js.map +1 -0
  108. package/dist/core/distill.js +3 -5
  109. package/dist/core/distill.js.map +1 -1
  110. package/dist/core/eventlog.d.ts +27 -25
  111. package/dist/core/eventlog.js +97 -150
  112. package/dist/core/eventlog.js.map +1 -1
  113. package/dist/core/events/contracts.d.ts +51 -0
  114. package/dist/core/events/contracts.js +2 -0
  115. package/dist/core/events/contracts.js.map +1 -0
  116. package/dist/core/events/jsonl-store.d.ts +23 -0
  117. package/dist/core/events/jsonl-store.js +90 -0
  118. package/dist/core/events/jsonl-store.js.map +1 -0
  119. package/dist/core/events/sqlite-store.d.ts +37 -0
  120. package/dist/core/events/sqlite-store.js +215 -0
  121. package/dist/core/events/sqlite-store.js.map +1 -0
  122. package/dist/core/forecast.d.ts +44 -0
  123. package/dist/core/forecast.js +46 -0
  124. package/dist/core/forecast.js.map +1 -0
  125. package/dist/core/free-pool.d.ts +65 -0
  126. package/dist/core/free-pool.js +171 -0
  127. package/dist/core/free-pool.js.map +1 -0
  128. package/dist/core/git.d.ts +30 -0
  129. package/dist/core/git.js +50 -2
  130. package/dist/core/git.js.map +1 -1
  131. package/dist/core/github-events.d.ts +53 -0
  132. package/dist/core/github-events.js +227 -0
  133. package/dist/core/github-events.js.map +1 -0
  134. package/dist/core/goal-lanes.d.ts +53 -0
  135. package/dist/core/goal-lanes.js +99 -0
  136. package/dist/core/goal-lanes.js.map +1 -0
  137. package/dist/core/hosted.d.ts +27 -0
  138. package/dist/core/hosted.js +50 -0
  139. package/dist/core/hosted.js.map +1 -0
  140. package/dist/core/http-server.d.ts +5 -0
  141. package/dist/core/http-server.js +8 -0
  142. package/dist/core/http-server.js.map +1 -0
  143. package/dist/core/invite-link.d.ts +31 -0
  144. package/dist/core/invite-link.js +45 -0
  145. package/dist/core/invite-link.js.map +1 -0
  146. package/dist/core/loops.d.ts +37 -0
  147. package/dist/core/loops.js +81 -0
  148. package/dist/core/loops.js.map +1 -0
  149. package/dist/core/mcp-catalog.d.ts +182 -0
  150. package/dist/core/mcp-catalog.js +431 -0
  151. package/dist/core/mcp-catalog.js.map +1 -0
  152. package/dist/core/mcp.d.ts +87 -0
  153. package/dist/core/mcp.js +181 -0
  154. package/dist/core/mcp.js.map +1 -0
  155. package/dist/core/memory.d.ts +1 -0
  156. package/dist/core/memory.js +5 -2
  157. package/dist/core/memory.js.map +1 -1
  158. package/dist/core/model-tools.d.ts +97 -0
  159. package/dist/core/model-tools.js +388 -0
  160. package/dist/core/model-tools.js.map +1 -0
  161. package/dist/core/notify.js +19 -1
  162. package/dist/core/notify.js.map +1 -1
  163. package/dist/core/orchestra.d.ts +635 -0
  164. package/dist/core/orchestra.js +2120 -0
  165. package/dist/core/orchestra.js.map +1 -0
  166. package/dist/core/permissions.d.ts +56 -0
  167. package/dist/core/permissions.js +122 -0
  168. package/dist/core/permissions.js.map +1 -0
  169. package/dist/core/preview-proxy.d.ts +70 -0
  170. package/dist/core/preview-proxy.js +563 -0
  171. package/dist/core/preview-proxy.js.map +1 -0
  172. package/dist/core/preview-shot.d.ts +46 -0
  173. package/dist/core/preview-shot.js +109 -0
  174. package/dist/core/preview-shot.js.map +1 -0
  175. package/dist/core/process.d.ts +36 -0
  176. package/dist/core/process.js +168 -0
  177. package/dist/core/process.js.map +1 -0
  178. package/dist/core/prompt-queue.d.ts +136 -0
  179. package/dist/core/prompt-queue.js +269 -0
  180. package/dist/core/prompt-queue.js.map +1 -0
  181. package/dist/core/prompts.d.ts +53 -0
  182. package/dist/core/prompts.js +127 -0
  183. package/dist/core/prompts.js.map +1 -0
  184. package/dist/core/proof.d.ts +82 -0
  185. package/dist/core/proof.js +216 -0
  186. package/dist/core/proof.js.map +1 -0
  187. package/dist/core/provider-text.d.ts +23 -0
  188. package/dist/core/provider-text.js +66 -0
  189. package/dist/core/provider-text.js.map +1 -0
  190. package/dist/core/providers.d.ts +152 -0
  191. package/dist/core/providers.js +343 -0
  192. package/dist/core/providers.js.map +1 -0
  193. package/dist/core/quota.d.ts +33 -0
  194. package/dist/core/quota.js +74 -0
  195. package/dist/core/quota.js.map +1 -0
  196. package/dist/core/recipes.d.ts +50 -0
  197. package/dist/core/recipes.js +99 -0
  198. package/dist/core/recipes.js.map +1 -0
  199. package/dist/core/registry.d.ts +54 -0
  200. package/dist/core/registry.js +62 -5
  201. package/dist/core/registry.js.map +1 -1
  202. package/dist/core/relay-client.d.ts +67 -0
  203. package/dist/core/relay-client.js +184 -0
  204. package/dist/core/relay-client.js.map +1 -0
  205. package/dist/core/relay-protocol.d.ts +140 -0
  206. package/dist/core/relay-protocol.js +189 -0
  207. package/dist/core/relay-protocol.js.map +1 -0
  208. package/dist/core/replay.d.ts +18 -0
  209. package/dist/core/replay.js +191 -0
  210. package/dist/core/replay.js.map +1 -0
  211. package/dist/core/review-triage.d.ts +41 -0
  212. package/dist/core/review-triage.js +124 -0
  213. package/dist/core/review-triage.js.map +1 -0
  214. package/dist/core/router.js +2 -2
  215. package/dist/core/router.js.map +1 -1
  216. package/dist/core/routes.d.ts +39 -3
  217. package/dist/core/routes.js +137 -4
  218. package/dist/core/routes.js.map +1 -1
  219. package/dist/core/run-command.d.ts +14 -0
  220. package/dist/core/run-command.js +45 -0
  221. package/dist/core/run-command.js.map +1 -0
  222. package/dist/core/runner-setup.d.ts +36 -0
  223. package/dist/core/runner-setup.js +114 -0
  224. package/dist/core/runner-setup.js.map +1 -0
  225. package/dist/core/search.js +0 -0
  226. package/dist/core/search.js.map +1 -1
  227. package/dist/core/semantic.d.ts +92 -0
  228. package/dist/core/semantic.js +227 -0
  229. package/dist/core/semantic.js.map +1 -0
  230. package/dist/core/servers.d.ts +115 -0
  231. package/dist/core/servers.js +305 -0
  232. package/dist/core/servers.js.map +1 -0
  233. package/dist/core/setup.js +64 -6
  234. package/dist/core/setup.js.map +1 -1
  235. package/dist/core/shield.d.ts +17 -0
  236. package/dist/core/shield.js +81 -0
  237. package/dist/core/shield.js.map +1 -0
  238. package/dist/core/shift.d.ts +69 -0
  239. package/dist/core/shift.js +120 -0
  240. package/dist/core/shift.js.map +1 -0
  241. package/dist/core/skill-install.d.ts +125 -0
  242. package/dist/core/skill-install.js +328 -0
  243. package/dist/core/skill-install.js.map +1 -0
  244. package/dist/core/skills.d.ts +116 -0
  245. package/dist/core/skills.js +223 -0
  246. package/dist/core/skills.js.map +1 -0
  247. package/dist/core/step-conditions.d.ts +65 -0
  248. package/dist/core/step-conditions.js +102 -0
  249. package/dist/core/step-conditions.js.map +1 -0
  250. package/dist/core/subagents.d.ts +45 -0
  251. package/dist/core/subagents.js +90 -0
  252. package/dist/core/subagents.js.map +1 -0
  253. package/dist/core/team-canon.d.ts +42 -0
  254. package/dist/core/team-canon.js +121 -0
  255. package/dist/core/team-canon.js.map +1 -0
  256. package/dist/core/team-crypto.d.ts +97 -0
  257. package/dist/core/team-crypto.js +175 -0
  258. package/dist/core/team-crypto.js.map +1 -0
  259. package/dist/core/team-hub.d.ts +514 -0
  260. package/dist/core/team-hub.js +964 -0
  261. package/dist/core/team-hub.js.map +1 -0
  262. package/dist/core/team-landing.d.ts +239 -0
  263. package/dist/core/team-landing.js +504 -0
  264. package/dist/core/team-landing.js.map +1 -0
  265. package/dist/core/team-leases.d.ts +44 -0
  266. package/dist/core/team-leases.js +145 -0
  267. package/dist/core/team-leases.js.map +1 -0
  268. package/dist/core/team-memory.d.ts +42 -0
  269. package/dist/core/team-memory.js +84 -0
  270. package/dist/core/team-memory.js.map +1 -0
  271. package/dist/core/team-policy.d.ts +85 -0
  272. package/dist/core/team-policy.js +191 -0
  273. package/dist/core/team-policy.js.map +1 -0
  274. package/dist/core/thread-md.d.ts +6 -0
  275. package/dist/core/thread-md.js +42 -0
  276. package/dist/core/thread-md.js.map +1 -0
  277. package/dist/core/turn-stats.d.ts +61 -0
  278. package/dist/core/turn-stats.js +124 -0
  279. package/dist/core/turn-stats.js.map +1 -0
  280. package/dist/core/updater.d.ts +73 -0
  281. package/dist/core/updater.js +153 -0
  282. package/dist/core/updater.js.map +1 -0
  283. package/dist/core/usage.d.ts +75 -0
  284. package/dist/core/usage.js +163 -0
  285. package/dist/core/usage.js.map +1 -0
  286. package/dist/core/windows-jobs.d.ts +15 -0
  287. package/dist/core/windows-jobs.js +170 -0
  288. package/dist/core/windows-jobs.js.map +1 -0
  289. package/dist/core/worktree-merge.d.ts +57 -0
  290. package/dist/core/worktree-merge.js +123 -0
  291. package/dist/core/worktree-merge.js.map +1 -0
  292. package/dist/core/worktree.d.ts +5 -0
  293. package/dist/core/worktree.js +45 -5
  294. package/dist/core/worktree.js.map +1 -1
  295. package/dist/core/worktrees.d.ts +6 -0
  296. package/dist/core/worktrees.js +21 -0
  297. package/dist/core/worktrees.js.map +1 -0
  298. package/dist/daemon/app-page.d.ts +0 -17
  299. package/dist/daemon/app-page.js +10 -6346
  300. package/dist/daemon/app-page.js.map +1 -1
  301. package/dist/daemon/auth.d.ts +24 -3
  302. package/dist/daemon/auth.js +66 -7
  303. package/dist/daemon/auth.js.map +1 -1
  304. package/dist/daemon/board.d.ts +7 -0
  305. package/dist/daemon/board.js +12 -1
  306. package/dist/daemon/board.js.map +1 -1
  307. package/dist/daemon/brand-icons.d.ts +6 -1
  308. package/dist/daemon/brand-icons.js +11 -3
  309. package/dist/daemon/brand-icons.js.map +1 -1
  310. package/dist/daemon/client.d.ts +665 -1
  311. package/dist/daemon/client.js +381 -3
  312. package/dist/daemon/client.js.map +1 -1
  313. package/dist/daemon/delivery.d.ts +34 -0
  314. package/dist/daemon/delivery.js +63 -0
  315. package/dist/daemon/delivery.js.map +1 -0
  316. package/dist/daemon/deploys.d.ts +62 -0
  317. package/dist/daemon/deploys.js +159 -0
  318. package/dist/daemon/deploys.js.map +1 -0
  319. package/dist/daemon/landing.d.ts +192 -0
  320. package/dist/daemon/landing.js +992 -0
  321. package/dist/daemon/landing.js.map +1 -0
  322. package/dist/daemon/onboard.d.ts +150 -0
  323. package/dist/daemon/onboard.js +390 -0
  324. package/dist/daemon/onboard.js.map +1 -0
  325. package/dist/daemon/proof.d.ts +70 -0
  326. package/dist/daemon/proof.js +172 -0
  327. package/dist/daemon/proof.js.map +1 -0
  328. package/dist/daemon/push.d.ts +19 -1
  329. package/dist/daemon/push.js +90 -3
  330. package/dist/daemon/push.js.map +1 -1
  331. package/dist/daemon/relay.d.ts +82 -0
  332. package/dist/daemon/relay.js +351 -0
  333. package/dist/daemon/relay.js.map +1 -0
  334. package/dist/daemon/routes/agent-discovery.d.ts +4 -0
  335. package/dist/daemon/routes/agent-discovery.js +29 -0
  336. package/dist/daemon/routes/agent-discovery.js.map +1 -0
  337. package/dist/daemon/routes/agent-settings.d.ts +4 -0
  338. package/dist/daemon/routes/agent-settings.js +94 -0
  339. package/dist/daemon/routes/agent-settings.js.map +1 -0
  340. package/dist/daemon/routes/agents.d.ts +4 -0
  341. package/dist/daemon/routes/agents.js +105 -0
  342. package/dist/daemon/routes/agents.js.map +1 -0
  343. package/dist/daemon/routes/alerts.d.ts +4 -0
  344. package/dist/daemon/routes/alerts.js +137 -0
  345. package/dist/daemon/routes/alerts.js.map +1 -0
  346. package/dist/daemon/routes/approvals.d.ts +4 -0
  347. package/dist/daemon/routes/approvals.js +40 -0
  348. package/dist/daemon/routes/approvals.js.map +1 -0
  349. package/dist/daemon/routes/assets.d.ts +3 -0
  350. package/dist/daemon/routes/assets.js +64 -0
  351. package/dist/daemon/routes/assets.js.map +1 -0
  352. package/dist/daemon/routes/board.d.ts +4 -0
  353. package/dist/daemon/routes/board.js +147 -0
  354. package/dist/daemon/routes/board.js.map +1 -0
  355. package/dist/daemon/routes/brain.d.ts +4 -0
  356. package/dist/daemon/routes/brain.js +270 -0
  357. package/dist/daemon/routes/brain.js.map +1 -0
  358. package/dist/daemon/routes/chats.d.ts +4 -0
  359. package/dist/daemon/routes/chats.js +249 -0
  360. package/dist/daemon/routes/chats.js.map +1 -0
  361. package/dist/daemon/routes/clients.d.ts +4 -0
  362. package/dist/daemon/routes/clients.js +49 -0
  363. package/dist/daemon/routes/clients.js.map +1 -0
  364. package/dist/daemon/routes/cloud.d.ts +4 -0
  365. package/dist/daemon/routes/cloud.js +46 -0
  366. package/dist/daemon/routes/cloud.js.map +1 -0
  367. package/dist/daemon/routes/config.d.ts +4 -0
  368. package/dist/daemon/routes/config.js +35 -0
  369. package/dist/daemon/routes/config.js.map +1 -0
  370. package/dist/daemon/routes/context.d.ts +51 -0
  371. package/dist/daemon/routes/context.js +2 -0
  372. package/dist/daemon/routes/context.js.map +1 -0
  373. package/dist/daemon/routes/crews.d.ts +4 -0
  374. package/dist/daemon/routes/crews.js +149 -0
  375. package/dist/daemon/routes/crews.js.map +1 -0
  376. package/dist/daemon/routes/files.d.ts +3 -0
  377. package/dist/daemon/routes/files.js +253 -0
  378. package/dist/daemon/routes/files.js.map +1 -0
  379. package/dist/daemon/routes/git.d.ts +4 -0
  380. package/dist/daemon/routes/git.js +96 -0
  381. package/dist/daemon/routes/git.js.map +1 -0
  382. package/dist/daemon/routes/history.d.ts +4 -0
  383. package/dist/daemon/routes/history.js +101 -0
  384. package/dist/daemon/routes/history.js.map +1 -0
  385. package/dist/daemon/routes/integrations-project.d.ts +3 -0
  386. package/dist/daemon/routes/integrations-project.js +103 -0
  387. package/dist/daemon/routes/integrations-project.js.map +1 -0
  388. package/dist/daemon/routes/integrations.d.ts +3 -0
  389. package/dist/daemon/routes/integrations.js +111 -0
  390. package/dist/daemon/routes/integrations.js.map +1 -0
  391. package/dist/daemon/routes/logs.d.ts +3 -0
  392. package/dist/daemon/routes/logs.js +40 -0
  393. package/dist/daemon/routes/logs.js.map +1 -0
  394. package/dist/daemon/routes/messages.d.ts +4 -0
  395. package/dist/daemon/routes/messages.js +60 -0
  396. package/dist/daemon/routes/messages.js.map +1 -0
  397. package/dist/daemon/routes/observability.d.ts +4 -0
  398. package/dist/daemon/routes/observability.js +247 -0
  399. package/dist/daemon/routes/observability.js.map +1 -0
  400. package/dist/daemon/routes/onboard.d.ts +12 -0
  401. package/dist/daemon/routes/onboard.js +67 -0
  402. package/dist/daemon/routes/onboard.js.map +1 -0
  403. package/dist/daemon/routes/orchestra.d.ts +4 -0
  404. package/dist/daemon/routes/orchestra.js +110 -0
  405. package/dist/daemon/routes/orchestra.js.map +1 -0
  406. package/dist/daemon/routes/pairing.d.ts +4 -0
  407. package/dist/daemon/routes/pairing.js +155 -0
  408. package/dist/daemon/routes/pairing.js.map +1 -0
  409. package/dist/daemon/routes/preview.d.ts +24 -0
  410. package/dist/daemon/routes/preview.js +122 -0
  411. package/dist/daemon/routes/preview.js.map +1 -0
  412. package/dist/daemon/routes/project-actions.d.ts +4 -0
  413. package/dist/daemon/routes/project-actions.js +53 -0
  414. package/dist/daemon/routes/project-actions.js.map +1 -0
  415. package/dist/daemon/routes/project-team.d.ts +4 -0
  416. package/dist/daemon/routes/project-team.js +201 -0
  417. package/dist/daemon/routes/project-team.js.map +1 -0
  418. package/dist/daemon/routes/projects.d.ts +14 -0
  419. package/dist/daemon/routes/projects.js +138 -0
  420. package/dist/daemon/routes/projects.js.map +1 -0
  421. package/dist/daemon/routes/prompts.d.ts +4 -0
  422. package/dist/daemon/routes/prompts.js +44 -0
  423. package/dist/daemon/routes/prompts.js.map +1 -0
  424. package/dist/daemon/routes/proof.d.ts +4 -0
  425. package/dist/daemon/routes/proof.js +22 -0
  426. package/dist/daemon/routes/proof.js.map +1 -0
  427. package/dist/daemon/routes/providers.d.ts +3 -0
  428. package/dist/daemon/routes/providers.js +60 -0
  429. package/dist/daemon/routes/providers.js.map +1 -0
  430. package/dist/daemon/routes/public.d.ts +4 -0
  431. package/dist/daemon/routes/public.js +64 -0
  432. package/dist/daemon/routes/public.js.map +1 -0
  433. package/dist/daemon/routes/queue.d.ts +4 -0
  434. package/dist/daemon/routes/queue.js +140 -0
  435. package/dist/daemon/routes/queue.js.map +1 -0
  436. package/dist/daemon/routes/routing.d.ts +4 -0
  437. package/dist/daemon/routes/routing.js +61 -0
  438. package/dist/daemon/routes/routing.js.map +1 -0
  439. package/dist/daemon/routes/runtime-handler.d.ts +2 -0
  440. package/dist/daemon/routes/runtime-handler.js +63 -0
  441. package/dist/daemon/routes/runtime-handler.js.map +1 -0
  442. package/dist/daemon/routes/search.d.ts +4 -0
  443. package/dist/daemon/routes/search.js +17 -0
  444. package/dist/daemon/routes/search.js.map +1 -0
  445. package/dist/daemon/routes/servers.d.ts +4 -0
  446. package/dist/daemon/routes/servers.js +133 -0
  447. package/dist/daemon/routes/servers.js.map +1 -0
  448. package/dist/daemon/routes/setup.d.ts +3 -0
  449. package/dist/daemon/routes/setup.js +50 -0
  450. package/dist/daemon/routes/setup.js.map +1 -0
  451. package/dist/daemon/routes/shift.d.ts +4 -0
  452. package/dist/daemon/routes/shift.js +30 -0
  453. package/dist/daemon/routes/shift.js.map +1 -0
  454. package/dist/daemon/routes/specs.d.ts +4 -0
  455. package/dist/daemon/routes/specs.js +57 -0
  456. package/dist/daemon/routes/specs.js.map +1 -0
  457. package/dist/daemon/routes/task-delivery.d.ts +4 -0
  458. package/dist/daemon/routes/task-delivery.js +38 -0
  459. package/dist/daemon/routes/task-delivery.js.map +1 -0
  460. package/dist/daemon/routes/team.d.ts +4 -0
  461. package/dist/daemon/routes/team.js +193 -0
  462. package/dist/daemon/routes/team.js.map +1 -0
  463. package/dist/daemon/routes/terminals.d.ts +4 -0
  464. package/dist/daemon/routes/terminals.js +87 -0
  465. package/dist/daemon/routes/terminals.js.map +1 -0
  466. package/dist/daemon/routes/tools.d.ts +4 -0
  467. package/dist/daemon/routes/tools.js +180 -0
  468. package/dist/daemon/routes/tools.js.map +1 -0
  469. package/dist/daemon/routes/updates.d.ts +4 -0
  470. package/dist/daemon/routes/updates.js +89 -0
  471. package/dist/daemon/routes/updates.js.map +1 -0
  472. package/dist/daemon/routes/voice.d.ts +4 -0
  473. package/dist/daemon/routes/voice.js +53 -0
  474. package/dist/daemon/routes/voice.js.map +1 -0
  475. package/dist/daemon/runner.d.ts +186 -0
  476. package/dist/daemon/runner.js +612 -0
  477. package/dist/daemon/runner.js.map +1 -0
  478. package/dist/daemon/runtime/accounting.d.ts +130 -0
  479. package/dist/daemon/runtime/accounting.js +303 -0
  480. package/dist/daemon/runtime/accounting.js.map +1 -0
  481. package/dist/daemon/runtime/agents.d.ts +16 -0
  482. package/dist/daemon/runtime/agents.js +71 -0
  483. package/dist/daemon/runtime/agents.js.map +1 -0
  484. package/dist/daemon/runtime/briefings.d.ts +134 -0
  485. package/dist/daemon/runtime/briefings.js +329 -0
  486. package/dist/daemon/runtime/briefings.js.map +1 -0
  487. package/dist/daemon/runtime/native-usage.d.ts +21 -0
  488. package/dist/daemon/runtime/native-usage.js +71 -0
  489. package/dist/daemon/runtime/native-usage.js.map +1 -0
  490. package/dist/daemon/runtime/queue.d.ts +94 -0
  491. package/dist/daemon/runtime/queue.js +222 -0
  492. package/dist/daemon/runtime/queue.js.map +1 -0
  493. package/dist/daemon/runtime/relay.d.ts +93 -0
  494. package/dist/daemon/runtime/relay.js +240 -0
  495. package/dist/daemon/runtime/relay.js.map +1 -0
  496. package/dist/daemon/runtime/turns.d.ts +202 -0
  497. package/dist/daemon/runtime/turns.js +663 -0
  498. package/dist/daemon/runtime/turns.js.map +1 -0
  499. package/dist/daemon/runtime-support.d.ts +76 -0
  500. package/dist/daemon/runtime-support.js +134 -0
  501. package/dist/daemon/runtime-support.js.map +1 -0
  502. package/dist/daemon/runtime.d.ts +739 -70
  503. package/dist/daemon/runtime.js +2751 -470
  504. package/dist/daemon/runtime.js.map +1 -1
  505. package/dist/daemon/server.d.ts +82 -55
  506. package/dist/daemon/server.js +674 -1435
  507. package/dist/daemon/server.js.map +1 -1
  508. package/dist/daemon/shift.d.ts +70 -0
  509. package/dist/daemon/shift.js +170 -0
  510. package/dist/daemon/shift.js.map +1 -0
  511. package/dist/daemon/specs.d.ts +92 -0
  512. package/dist/daemon/specs.js +285 -0
  513. package/dist/daemon/specs.js.map +1 -0
  514. package/dist/daemon/system.d.ts +208 -0
  515. package/dist/daemon/system.js +557 -0
  516. package/dist/daemon/system.js.map +1 -0
  517. package/dist/daemon/tasks.js +1 -1
  518. package/dist/daemon/team-brain.d.ts +136 -0
  519. package/dist/daemon/team-brain.js +659 -0
  520. package/dist/daemon/team-brain.js.map +1 -0
  521. package/dist/daemon/team-coordinator.d.ts +78 -0
  522. package/dist/daemon/team-coordinator.js +408 -0
  523. package/dist/daemon/team-coordinator.js.map +1 -0
  524. package/dist/daemon/team.d.ts +339 -0
  525. package/dist/daemon/team.js +1433 -0
  526. package/dist/daemon/team.js.map +1 -0
  527. package/dist/daemon/terminals.d.ts +22 -3
  528. package/dist/daemon/terminals.js +236 -16
  529. package/dist/daemon/terminals.js.map +1 -1
  530. package/dist/hub/client.d.ts +120 -0
  531. package/dist/hub/client.js +228 -0
  532. package/dist/hub/client.js.map +1 -0
  533. package/dist/hub/server.d.ts +32 -0
  534. package/dist/hub/server.js +180 -0
  535. package/dist/hub/server.js.map +1 -0
  536. package/dist/hub/supabase-client.d.ts +220 -0
  537. package/dist/hub/supabase-client.js +843 -0
  538. package/dist/hub/supabase-client.js.map +1 -0
  539. package/dist/observability/ask.d.ts +91 -0
  540. package/dist/observability/ask.js +179 -0
  541. package/dist/observability/ask.js.map +1 -0
  542. package/dist/observability/clickhouse.d.ts +33 -0
  543. package/dist/observability/clickhouse.js +48 -0
  544. package/dist/observability/clickhouse.js.map +1 -0
  545. package/dist/observability/decisions.d.ts +176 -0
  546. package/dist/observability/decisions.js +377 -0
  547. package/dist/observability/decisions.js.map +1 -0
  548. package/dist/observability/index.d.ts +89 -0
  549. package/dist/observability/index.js +348 -0
  550. package/dist/observability/index.js.map +1 -0
  551. package/dist/observability/insights.d.ts +151 -0
  552. package/dist/observability/insights.js +319 -0
  553. package/dist/observability/insights.js.map +1 -0
  554. package/dist/observability/logs-query.d.ts +82 -0
  555. package/dist/observability/logs-query.js +102 -0
  556. package/dist/observability/logs-query.js.map +1 -0
  557. package/dist/observability/logs.d.ts +72 -0
  558. package/dist/observability/logs.js +295 -0
  559. package/dist/observability/logs.js.map +1 -0
  560. package/dist/observability/metrics.d.ts +86 -0
  561. package/dist/observability/metrics.js +303 -0
  562. package/dist/observability/metrics.js.map +1 -0
  563. package/dist/observability/otlp.d.ts +127 -0
  564. package/dist/observability/otlp.js +242 -0
  565. package/dist/observability/otlp.js.map +1 -0
  566. package/dist/observability/snapshots.d.ts +43 -0
  567. package/dist/observability/snapshots.js +129 -0
  568. package/dist/observability/snapshots.js.map +1 -0
  569. package/dist/observability/triage.d.ts +49 -0
  570. package/dist/observability/triage.js +284 -0
  571. package/dist/observability/triage.js.map +1 -0
  572. package/dist/providers/adapter.d.ts +50 -0
  573. package/dist/providers/adapter.js +38 -0
  574. package/dist/providers/adapter.js.map +1 -0
  575. package/dist/providers/agent.d.ts +110 -0
  576. package/dist/providers/agent.js +487 -0
  577. package/dist/providers/agent.js.map +1 -0
  578. package/dist/providers/approvals.d.ts +24 -0
  579. package/dist/providers/approvals.js +78 -0
  580. package/dist/providers/approvals.js.map +1 -0
  581. package/dist/providers/attachments.d.ts +20 -0
  582. package/dist/providers/attachments.js +51 -0
  583. package/dist/providers/attachments.js.map +1 -0
  584. package/dist/providers/claude/adapter.d.ts +99 -0
  585. package/dist/providers/claude/adapter.js +790 -0
  586. package/dist/providers/claude/adapter.js.map +1 -0
  587. package/dist/providers/codex/adapter.d.ts +113 -0
  588. package/dist/providers/codex/adapter.js +881 -0
  589. package/dist/providers/codex/adapter.js.map +1 -0
  590. package/dist/providers/codex/instructions.d.ts +11 -0
  591. package/dist/providers/codex/instructions.js +154 -0
  592. package/dist/providers/codex/instructions.js.map +1 -0
  593. package/dist/providers/codex/rpc.d.ts +36 -0
  594. package/dist/providers/codex/rpc.js +104 -0
  595. package/dist/providers/codex/rpc.js.map +1 -0
  596. package/dist/providers/contracts.d.ts +339 -0
  597. package/dist/providers/contracts.js +19 -0
  598. package/dist/providers/contracts.js.map +1 -0
  599. package/dist/providers/directory.d.ts +70 -0
  600. package/dist/providers/directory.js +95 -0
  601. package/dist/providers/directory.js.map +1 -0
  602. package/dist/providers/errors.d.ts +47 -0
  603. package/dist/providers/errors.js +24 -0
  604. package/dist/providers/errors.js.map +1 -0
  605. package/dist/providers/index.d.ts +18 -0
  606. package/dist/providers/index.js +19 -0
  607. package/dist/providers/index.js.map +1 -0
  608. package/dist/providers/ingestion.d.ts +80 -0
  609. package/dist/providers/ingestion.js +330 -0
  610. package/dist/providers/ingestion.js.map +1 -0
  611. package/dist/providers/live.d.ts +22 -0
  612. package/dist/providers/live.js +56 -0
  613. package/dist/providers/live.js.map +1 -0
  614. package/dist/providers/process.d.ts +29 -0
  615. package/dist/providers/process.js +71 -0
  616. package/dist/providers/process.js.map +1 -0
  617. package/dist/providers/reaper.d.ts +33 -0
  618. package/dist/providers/reaper.js +65 -0
  619. package/dist/providers/reaper.js.map +1 -0
  620. package/dist/providers/service.d.ts +87 -0
  621. package/dist/providers/service.js +256 -0
  622. package/dist/providers/service.js.map +1 -0
  623. package/dist/sdk.d.ts +1 -1
  624. package/dist/sdk.js +1 -1
  625. package/dist/sdk.js.map +1 -1
  626. package/dist/types.d.ts +385 -6
  627. package/dist/types.js +1 -0
  628. package/dist/types.js.map +1 -1
  629. package/dist/version.d.ts +7 -0
  630. package/dist/version.js +16 -0
  631. package/dist/version.js.map +1 -0
  632. package/dist/web/app.css +4646 -0
  633. package/dist/web/app.js +22640 -0
  634. package/dist/web/app.js.map +7 -0
  635. package/dist/web/shell.html +39 -0
  636. package/docs/README.md +21 -0
  637. package/docs/SETUP.md +10 -0
  638. package/docs/adapters.md +21 -8
  639. package/docs/brain-continuity.md +186 -0
  640. package/docs/cloud.md +108 -0
  641. package/docs/crews.md +62 -0
  642. package/docs/design-system.md +31 -2
  643. package/docs/integration-notes.md +128 -20
  644. package/docs/loompad.md +105 -0
  645. package/docs/observability.md +220 -0
  646. package/docs/play-store.md +123 -0
  647. package/docs/proposals/agent-teams.md +249 -0
  648. package/docs/proposals/brain-continuity-implementation.md +468 -0
  649. package/docs/proposals/brain-session-continuity.md +623 -0
  650. package/docs/proposals/t3code-port.md +81 -0
  651. package/docs/proposals/t3code-reference.md +95 -0
  652. package/docs/refactoring/AGENT-TEAMS-PROGRESS.md +88 -0
  653. package/docs/refactoring/BOUNDARIES.md +120 -0
  654. package/docs/refactoring/BRAIN-AUDIT.md +176 -0
  655. package/docs/refactoring/BRAIN-NOTES.md +390 -0
  656. package/docs/refactoring/BRAIN-TODO.md +214 -0
  657. package/docs/refactoring/NOTES.md +129 -0
  658. package/docs/refactoring/T3-PORT-NOTES.md +165 -0
  659. package/docs/refactoring/T3-PORT-TODO.md +123 -0
  660. package/docs/refactoring/TODO.md +46 -0
  661. package/docs/refactoring/brain-benchmark-2026-09-28.json +48 -0
  662. package/docs/refactoring/brain-benchmark-audit-2026-09-28.json +48 -0
  663. package/docs/release-notes/v0.2.0.md +35 -0
  664. package/docs/release-notes/v0.2.1.md +59 -0
  665. package/docs/release-notes/v0.2.3.md +77 -0
  666. package/docs/release-notes/v0.2.4.md +128 -0
  667. package/docs/release-notes/v0.2.5.md +153 -0
  668. package/docs/release-notes/v0.2.6.md +62 -0
  669. package/docs/release-notes/v1.0.0.md +120 -0
  670. package/docs/release-notes/v1.0.1.md +77 -0
  671. package/docs/release-notes/v1.1.0.md +71 -0
  672. package/docs/release-notes/v1.1.1.md +38 -0
  673. package/docs/release-notes/v1.1.2.md +21 -0
  674. package/docs/teams-architecture.md +697 -0
  675. package/docs/teams.md +171 -0
  676. package/docs/windows.md +85 -0
  677. package/package.json +22 -9
  678. package/dist/adapters/claude-code.d.ts +0 -26
  679. package/dist/adapters/claude-code.js +0 -209
  680. package/dist/adapters/claude-code.js.map +0 -1
  681. package/dist/adapters/codex.d.ts +0 -51
  682. package/dist/adapters/codex.js +0 -291
  683. package/dist/adapters/codex.js.map +0 -1
  684. package/docs/img/board-linear.png +0 -0
  685. package/docs/img/board-projects.png +0 -0
  686. package/docs/img/brain.png +0 -0
  687. package/docs/img/settings.png +0 -0
  688. package/docs/img/workspace.png +0 -0
@@ -0,0 +1,563 @@
1
+ /**
2
+ * The preview, served through Loom so the page can talk back.
3
+ *
4
+ * A dev server is a different origin from the app, and a browser will not let
5
+ * one origin read another's console. So Loom stands in front of the server: a
6
+ * small proxy on its own port that forwards everything — including the
7
+ * WebSocket a framework's hot reload rides on — and injects one script into
8
+ * HTML responses. That script reports what the page logs, what it fetches and
9
+ * what it threw, by postMessage, which crosses origins by design.
10
+ *
11
+ * What it never does on its own: change the page. The injection is additive,
12
+ * it runs before the app's own code only so it can see the first errors, and
13
+ * nothing else about the response is rewritten. The one thing that does alter
14
+ * the page is the colour-scheme toggle, and only while you hold it: it
15
+ * re-points the page's own `prefers-color-scheme` rules and puts every one of
16
+ * them back, exactly as it found them, when you go back to Auto.
17
+ */
18
+ import http from "node:http";
19
+ import https from "node:https";
20
+ import net from "node:net";
21
+ import { Readable } from "node:stream";
22
+ /** How long to wait for a dev server that accepted the connection to answer. */
23
+ export const UPSTREAM_TIMEOUT_MS = 20_000;
24
+ /** Marker so an injected page is obvious in view-source. */
25
+ export const BRIDGE_MARK = "loom-preview-bridge";
26
+ /**
27
+ * The script injected into previewed pages.
28
+ *
29
+ * Deliberately small, defensive and silent on failure: a preview that breaks
30
+ * the page it is previewing is worse than no preview. Everything it sends is
31
+ * one shape — {source:"loom-preview", kind, ...} — so the app has one reader.
32
+ */
33
+ export function bridgeScript() {
34
+ return ascii(BRIDGE_SOURCE);
35
+ }
36
+ /**
37
+ * Pure ASCII, so it can be spliced into a page's bytes whatever ASCII-based
38
+ * charset the page is in (see injectBytes). Only comments and string literals
39
+ * ever held anything else, and \uXXXX means the same thing in both.
40
+ */
41
+ function ascii(js) {
42
+ return js.replace(/[^\x00-\x7f]/g, (c) => "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0"));
43
+ }
44
+ const BRIDGE_SOURCE = `<script data-${BRIDGE_MARK}="1">(function(){
45
+ if (window.__loomPreviewBridge) return;
46
+ window.__loomPreviewBridge = 1;
47
+ var send = function(kind, payload){
48
+ try { parent.postMessage({ source: "loom-preview", kind: kind, at: Date.now(), payload: payload }, "*"); } catch (e) {}
49
+ };
50
+ var text = function(v){
51
+ if (typeof v === "string") return v;
52
+ if (v instanceof Error) return v.message + (v.stack ? "\\n" + v.stack : "");
53
+ try { return JSON.stringify(v); } catch (e) { return String(v); }
54
+ };
55
+ ["log", "info", "warn", "error", "debug"].forEach(function(level){
56
+ var original = console[level];
57
+ console[level] = function(){
58
+ try {
59
+ send("console", { level: level, text: Array.prototype.map.call(arguments, text).join(" ").slice(0, 4000) });
60
+ } catch (e) {}
61
+ return original && original.apply(console, arguments);
62
+ };
63
+ });
64
+ window.addEventListener("error", function(e){
65
+ send("console", { level: "error", text: (e.message || "error") + (e.filename ? " (" + e.filename + ":" + e.lineno + ")" : ""), stack: e.error && e.error.stack });
66
+ });
67
+ window.addEventListener("unhandledrejection", function(e){
68
+ send("console", { level: "error", text: "unhandled rejection: " + text(e.reason) });
69
+ });
70
+ var fetchImpl = window.fetch;
71
+ if (fetchImpl) {
72
+ window.fetch = function(input, init){
73
+ var started = Date.now();
74
+ var url = typeof input === "string" ? input : (input && input.url) || String(input);
75
+ var method = (init && init.method) || (input && input.method) || "GET";
76
+ return fetchImpl.apply(this, arguments).then(function(res){
77
+ send("network", { method: method, url: url, status: res.status, ms: Date.now() - started });
78
+ return res;
79
+ }, function(err){
80
+ send("network", { method: method, url: url, status: 0, ms: Date.now() - started, error: text(err) });
81
+ throw err;
82
+ });
83
+ };
84
+ }
85
+ var open = XMLHttpRequest.prototype.open;
86
+ var xhrSend = XMLHttpRequest.prototype.send;
87
+ XMLHttpRequest.prototype.open = function(method, url){
88
+ this.__loom = { method: method, url: url };
89
+ return open.apply(this, arguments);
90
+ };
91
+ XMLHttpRequest.prototype.send = function(){
92
+ var self = this;
93
+ var started = Date.now();
94
+ self.addEventListener("loadend", function(){
95
+ var m = self.__loom || {};
96
+ send("network", { method: m.method || "GET", url: m.url || "", status: self.status, ms: Date.now() - started });
97
+ });
98
+ return xhrSend.apply(this, arguments);
99
+ };
100
+ // The picker: Loom asks, the page answers with what's under the cursor.
101
+ var picking = false, box = null, last = null;
102
+ var outline = function(el){
103
+ if (!box) {
104
+ box = document.createElement("div");
105
+ box.style.cssText = "position:fixed;z-index:2147483647;pointer-events:none;border:2px solid #4c8dff;background:rgba(76,141,255,.14);border-radius:2px";
106
+ document.documentElement.appendChild(box);
107
+ }
108
+ var r = el.getBoundingClientRect();
109
+ box.style.left = r.left + "px"; box.style.top = r.top + "px";
110
+ box.style.width = r.width + "px"; box.style.height = r.height + "px";
111
+ };
112
+ var selectorFor = function(el){
113
+ if (el.id) return "#" + el.id;
114
+ var parts = [];
115
+ var node = el;
116
+ for (var depth = 0; node && node.nodeType === 1 && depth < 5; depth++) {
117
+ var part = node.tagName.toLowerCase();
118
+ var testid = node.getAttribute && (node.getAttribute("data-testid") || node.getAttribute("data-test-id"));
119
+ if (testid) { parts.unshift(part + '[data-testid="' + testid + '"]'); break; }
120
+ if (node.classList && node.classList.length) part += "." + Array.prototype.slice.call(node.classList, 0, 2).join(".");
121
+ var parent = node.parentElement;
122
+ if (parent) {
123
+ var same = Array.prototype.filter.call(parent.children, function(c){ return c.tagName === node.tagName; });
124
+ if (same.length > 1) part += ":nth-of-type(" + (same.indexOf(node) + 1) + ")";
125
+ }
126
+ parts.unshift(part);
127
+ node = node.parentElement;
128
+ if (node === document.body) break;
129
+ }
130
+ return parts.join(" > ");
131
+ };
132
+ var STYLE_KEYS = ["display", "position", "width", "height", "margin", "padding", "gap", "font-family", "font-size", "font-weight",
133
+ "line-height", "letter-spacing", "color", "background-color", "background-image", "border", "border-radius", "box-shadow",
134
+ "opacity", "flex-direction", "justify-content", "align-items", "grid-template-columns", "text-align", "z-index"];
135
+ var styleOf = function(el){
136
+ var out = {};
137
+ try {
138
+ var cs = getComputedStyle(el);
139
+ for (var i = 0; i < STYLE_KEYS.length; i++) {
140
+ var k = STYLE_KEYS[i], v = cs.getPropertyValue(k);
141
+ // the defaults say nothing: keep what this element actually sets
142
+ if (!v || v === "none" || v === "normal" || v === "auto" || v === "0px" || v === "static" || v === "rgba(0, 0, 0, 0)") continue;
143
+ out[k] = String(v).slice(0, 160);
144
+ }
145
+ } catch (e) {}
146
+ return out;
147
+ };
148
+ var onMove = function(e){
149
+ if (!picking) return;
150
+ var el = e.target;
151
+ if (!el || el === box) return;
152
+ last = el;
153
+ outline(el);
154
+ };
155
+ var onClick = function(e){
156
+ if (!picking) return;
157
+ e.preventDefault(); e.stopPropagation();
158
+ var el = last || e.target;
159
+ var r = el.getBoundingClientRect();
160
+ send("picked", {
161
+ selector: selectorFor(el),
162
+ tag: el.tagName.toLowerCase(),
163
+ // innerText is undefined on SVG elements — an icon would answer with
164
+ // nothing at all, which is the click most likely to be about an icon.
165
+ text: String(el.innerText || el.textContent || "").trim().slice(0, 300),
166
+ html: (el.outerHTML || "").slice(0, 1200),
167
+ rect: { x: Math.round(r.left), y: Math.round(r.top), w: Math.round(r.width), h: Math.round(r.height) },
168
+ // Design Mode: what the agent needs to change how it looks, not just what it is
169
+ styles: styleOf(el),
170
+ viewport: { w: window.innerWidth, h: window.innerHeight },
171
+ url: location.href,
172
+ });
173
+ stopPicking();
174
+ };
175
+ var stopPicking = function(){
176
+ picking = false;
177
+ if (box) { box.remove(); box = null; }
178
+ document.removeEventListener("mousemove", onMove, true);
179
+ document.removeEventListener("click", onClick, true);
180
+ };
181
+ // ---- colour scheme -------------------------------------------------
182
+ // No API lets a parent document set another page's prefers-color-scheme.
183
+ // But Loom is not outside this page: the proxy served it AND its
184
+ // stylesheets, so the rules are readable and the media queries can be
185
+ // re-pointed. Pages theme in three ways, so forcing is three things:
186
+ // the UA's own colour-scheme, the @media rules in the CSS, and the
187
+ // matchMedia() a script asked. Reverting is exact — every rule remembers
188
+ // the media text it came with, so "auto" is the page as it shipped.
189
+ var forced = null;
190
+ var mqls = [];
191
+ var saved = [];
192
+ var reading = 0;
193
+ var unreadable = 0;
194
+ var mmReal = window.matchMedia && window.matchMedia.bind(window);
195
+ var wants = function(q){ return /dark/i.test(String(q)) ? "dark" : /light/i.test(String(q)) ? "light" : ""; };
196
+ var forceMql = function(mql, q){
197
+ var side = wants(q);
198
+ try {
199
+ if (forced === null || !side) { delete mql.matches; return; }
200
+ var v = side === forced;
201
+ Object.defineProperty(mql, "matches", { configurable: true, get: function(){ return v; } });
202
+ } catch (e) {}
203
+ };
204
+ var fire = function(mql){
205
+ try {
206
+ var ev;
207
+ try { ev = new MediaQueryListEvent("change", { matches: mql.matches, media: mql.media }); }
208
+ catch (e) { ev = new Event("change"); }
209
+ mql.dispatchEvent(ev);
210
+ } catch (e) {}
211
+ };
212
+ if (mmReal) {
213
+ window.matchMedia = function(q){
214
+ var mql = mmReal(q);
215
+ if (/prefers-color-scheme/i.test(String(q))) {
216
+ mqls.push({ mql: mql, q: q });
217
+ forceMql(mql, q);
218
+ }
219
+ return mql;
220
+ };
221
+ }
222
+ var walk = function(rules, depth){
223
+ if (!rules || depth > 4) return;
224
+ for (var i = 0; i < rules.length; i++) {
225
+ var rule = rules[i];
226
+ var media = rule.media && rule.media.mediaText;
227
+ if (media && /prefers-color-scheme/i.test(media)) {
228
+ saved.push({ rule: rule, text: media });
229
+ try { rule.media.mediaText = wants(media) === forced ? "all" : "not all"; }
230
+ catch (e) { unreadable++; }
231
+ }
232
+ if (rule.cssRules) walk(rule.cssRules, depth + 1);
233
+ }
234
+ };
235
+ var applyScheme = function(){
236
+ reading = 0; unreadable = 0;
237
+ // Always put the page back first, then force. A forced rule reads "all",
238
+ // which no longer mentions prefers-color-scheme — so a rule rewritten once
239
+ // can never be found again, and dark → light would have been a one-way
240
+ // door if this went straight to forcing.
241
+ for (var r = 0; r < saved.length; r++) {
242
+ try { saved[r].rule.media.mediaText = saved[r].text; } catch (e) { unreadable++; }
243
+ }
244
+ saved = [];
245
+ if (forced !== null) {
246
+ var sheets = document.styleSheets || [];
247
+ for (var i = 0; i < sheets.length; i++) {
248
+ try { walk(sheets[i].cssRules, 0); reading++; }
249
+ catch (e) { unreadable++; } // a stylesheet from somewhere Loom doesn't serve
250
+ }
251
+ }
252
+ try {
253
+ document.documentElement.style.colorScheme = forced || "";
254
+ } catch (e) {}
255
+ for (var m = 0; m < mqls.length; m++) { forceMql(mqls[m].mql, mqls[m].q); fire(mqls[m].mql); }
256
+ send("scheme", { scheme: forced, sheets: reading, unreadable: unreadable });
257
+ };
258
+ // A framework that hot-reloads adds stylesheets after we've forced them.
259
+ try {
260
+ var pending = null;
261
+ new MutationObserver(function(){
262
+ if (forced === null || pending) return;
263
+ pending = setTimeout(function(){ pending = null; applyScheme(); }, 120);
264
+ }).observe(document.documentElement, { childList: true, subtree: true });
265
+ } catch (e) {}
266
+
267
+ // Back and forward, asked for by the app's own buttons: the page is another
268
+ // origin, so its history is only reachable from in here.
269
+ var go = function(n){ try { history.go(n); } catch (e) {} };
270
+ window.addEventListener("message", function(e){
271
+ // Only the window that framed this page gives it orders — never a popup
272
+ // or a sibling frame. (A message with no source is a test harness.)
273
+ if (e.source && e.source !== parent) return;
274
+ var d = e.data || {};
275
+ if (d.source !== "loom-app") return;
276
+ if (d.kind === "pick") {
277
+ picking = true;
278
+ document.addEventListener("mousemove", onMove, true);
279
+ document.addEventListener("click", onClick, true);
280
+ } else if (d.kind === "cancel-pick") {
281
+ stopPicking();
282
+ } else if (d.kind === "scheme") {
283
+ forced = d.value === "dark" ? "dark" : d.value === "light" ? "light" : null;
284
+ applyScheme();
285
+ } else if (d.kind === "history") {
286
+ if (d.go === -1 || d.go === 1) go(d.go);
287
+ }
288
+ });
289
+ // Does this page update itself? A dev server with hot module reload swaps
290
+ // code in place, and a hard reload from Loom would throw its state away.
291
+ // The bridge runs before the page's own scripts, so ask once now and again
292
+ // when the page has loaded — the HMR client is one of those scripts.
293
+ var hmr = function(){
294
+ try {
295
+ if (window.__vite_plugin_react_preamble_installed__ || window.__vite_is_modern_browser) return "vite";
296
+ if (document.querySelector('script[src*="/@vite/client"],script[src*="@react-refresh"]')) return "vite";
297
+ if (window.webpackHotUpdate || window.__webpack_hmr || window.__NEXT_HMR_CB || window.__NEXT_DATA__ && window.next) return "webpack";
298
+ for (var k in window) { if (/^webpackHotUpdate/.test(k)) return "webpack"; }
299
+ } catch (e) {}
300
+ return "";
301
+ };
302
+ send("ready", { url: location.href, title: document.title, hmr: !!hmr() });
303
+ // A single-page app moves without loading a page: say where it went, so the
304
+ // address bar (and what Reload and Screenshot point at) follows.
305
+ var lastHref = location.href;
306
+ var moved = function(){
307
+ if (location.href === lastHref) return;
308
+ lastHref = location.href;
309
+ send("nav", { url: location.href, title: document.title });
310
+ };
311
+ ["pushState", "replaceState"].forEach(function(name){
312
+ var original = history[name];
313
+ if (typeof original !== "function") return;
314
+ history[name] = function(){
315
+ var out = original.apply(this, arguments);
316
+ try { moved(); } catch (e) {}
317
+ return out;
318
+ };
319
+ });
320
+ window.addEventListener("popstate", moved);
321
+ window.addEventListener("hashchange", moved);
322
+ var hmrLater = function(){ var h = hmr(); if (h) send("hmr", { hmr: true, kind: h }); };
323
+ if (document.readyState === "complete") setTimeout(hmrLater, 0);
324
+ else window.addEventListener("load", function(){ setTimeout(hmrLater, 300); });
325
+ })();</script>`;
326
+ /** Put the bridge first, so it sees what the page does on its way up. */
327
+ export function injectBridge(html) {
328
+ const script = bridgeScript();
329
+ if (html.includes(`data-${BRIDGE_MARK}`))
330
+ return html;
331
+ const head = html.search(/<head[^>]*>/i);
332
+ if (head >= 0) {
333
+ const end = html.indexOf(">", head) + 1;
334
+ return html.slice(0, end) + script + html.slice(end);
335
+ }
336
+ const body = html.search(/<body[^>]*>/i);
337
+ if (body >= 0) {
338
+ const end = html.indexOf(">", body) + 1;
339
+ return html.slice(0, end) + script + html.slice(end);
340
+ }
341
+ // A fragment, or a page with neither: prepend rather than lose it.
342
+ return script + html;
343
+ }
344
+ /** A host that is this machine — the only kind the preview will stand in front of on its own. */
345
+ export function isLoopbackHost(hostname) {
346
+ const h = hostname.replace(/^\[|\]$/g, "").toLowerCase();
347
+ return h === "localhost" || h.endsWith(".localhost") || h === "::1" || /^127(\.\d{1,3}){3}$/.test(h);
348
+ }
349
+ const portOf = (u) => u.port || (u.protocol === "https:" ? "443" : "80");
350
+ /** Is `loc` the upstream itself (allowing localhost ≡ 127.0.0.1 on the same port)? */
351
+ function isUpstream(loc, to) {
352
+ if (loc.origin === to.origin)
353
+ return true;
354
+ return loc.protocol === to.protocol && portOf(loc) === portOf(to) && isLoopbackHost(loc.hostname) && isLoopbackHost(to.hostname);
355
+ }
356
+ /**
357
+ * A redirect the dev server sent with its own absolute address would walk the
358
+ * frame off the proxy (and lose the bridge). Point it back through us.
359
+ */
360
+ export function rewriteLocation(location, target, proxyOrigin) {
361
+ let loc;
362
+ try {
363
+ loc = new URL(location, target);
364
+ }
365
+ catch {
366
+ return location;
367
+ }
368
+ if (!/^([a-z][a-z0-9+.-]*:)?\/\//i.test(location))
369
+ return location; // a path: already ours
370
+ if (!isUpstream(loc, new URL(target)))
371
+ return location;
372
+ return proxyOrigin + loc.pathname + loc.search + loc.hash;
373
+ }
374
+ /**
375
+ * Will a browser show this page inside a frame on another origin? Read off the
376
+ * two headers that decide it, so a page that refuses can be said to refuse
377
+ * instead of leaving a white rectangle.
378
+ */
379
+ export function frameability(xFrameOptions, csp) {
380
+ const xfo = (xFrameOptions ?? "").trim().toLowerCase();
381
+ if (xfo === "deny" || xfo === "sameorigin")
382
+ return { frameable: false, reason: `X-Frame-Options: ${xfo.toUpperCase()}` };
383
+ for (const policy of (csp ?? "").split(",")) {
384
+ const directive = policy.split(";").map((d) => d.trim()).find((d) => /^frame-ancestors(\s|$)/i.test(d));
385
+ if (!directive)
386
+ continue;
387
+ const sources = directive.split(/\s+/).slice(1);
388
+ // only a wildcard lets an unrelated app frame it; 'self', 'none' or a list of hosts don't
389
+ if (!sources.some((x) => x === "*" || /^https?:$/i.test(x))) {
390
+ return { frameable: false, reason: `Content-Security-Policy: ${directive}` };
391
+ }
392
+ }
393
+ return { frameable: true, reason: "" };
394
+ }
395
+ /** Charsets whose bytes for `<`, `h`, `e`… are ASCII's — the bridge can be spliced into them as bytes. */
396
+ const ASCII_BASED = /^(utf-?8|us-ascii|ascii|iso-?8859-\d+|latin-?1|windows-125\d|cp125\d|koi8-[ru]|shift_jis|sjis|euc-jp|euc-kr|gbk|gb2312|gb18030|big5)$/i;
397
+ /**
398
+ * The bridge, in a page given as bytes. Decoding as latin1 maps every byte to
399
+ * one code unit and back, so whatever the page's own encoding, every byte that
400
+ * isn't the script comes out exactly as it went in.
401
+ */
402
+ export function injectBytes(body, contentType) {
403
+ const charset = /charset\s*=\s*"?([^";\s]+)/i.exec(contentType)?.[1];
404
+ if (charset && !ASCII_BASED.test(charset))
405
+ return null; // UTF-16 and friends: leave it be
406
+ // A byte-order mark for UTF-16/32 means the same, whatever the header said.
407
+ if (body.length >= 2 && ((body[0] === 0xfe && body[1] === 0xff) || (body[0] === 0xff && body[1] === 0xfe)))
408
+ return null;
409
+ return Buffer.from(injectBridge(body.toString("latin1")), "latin1");
410
+ }
411
+ /**
412
+ * Stand in front of `target` (http(s)://host:port) on a port of our own.
413
+ *
414
+ * Everything is forwarded as-is except HTML, which gets the bridge. The
415
+ * WebSocket upgrade is forwarded too — a framework's hot reload rides on it,
416
+ * and a preview that kills HMR would be a downgrade from an iframe.
417
+ *
418
+ * An https upstream is spoken to over TLS; a self-signed certificate is
419
+ * accepted only from this machine (a dev server's mkcert or vite's basic-ssl),
420
+ * never from anywhere else.
421
+ */
422
+ export async function startPreviewProxy(target, host = "127.0.0.1") {
423
+ const to = new URL(target);
424
+ const secure = to.protocol === "https:";
425
+ if (!secure && to.protocol !== "http:")
426
+ throw new Error(`can't preview ${to.protocol} — only http and https`);
427
+ const lib = secure ? https : http;
428
+ const upstreamHost = to.hostname.replace(/^\[|\]$/g, "");
429
+ const upstreamPort = Number(portOf(to));
430
+ const tls = secure ? { rejectUnauthorized: !isLoopbackHost(to.hostname), servername: net.isIP(upstreamHost) ? undefined : upstreamHost } : {};
431
+ let ownPort = 0;
432
+ const proxyOrigin = (req) => `http://${req.headers.host ?? `${host}:${ownPort}`}`;
433
+ /** The browser's headers, as the upstream expects to see them. */
434
+ const forwardHeaders = (req) => {
435
+ const headers = { ...req.headers, host: to.host };
436
+ // A server checking Origin/Referer (CSRF, CORS) should see itself, not us.
437
+ const self = proxyOrigin(req);
438
+ for (const k of ["origin", "referer"]) {
439
+ const v = req.headers[k];
440
+ if (typeof v === "string" && v.startsWith(self))
441
+ headers[k] = to.origin + v.slice(self.length);
442
+ }
443
+ return headers;
444
+ };
445
+ const server = http.createServer((req, res) => {
446
+ const upstream = lib.request({
447
+ host: upstreamHost,
448
+ port: upstreamPort,
449
+ method: req.method,
450
+ path: req.url,
451
+ headers: { ...forwardHeaders(req), "accept-encoding": "identity" },
452
+ ...tls,
453
+ }, (up) => {
454
+ const status = up.statusCode ?? 200;
455
+ const headers = { ...up.headers };
456
+ if (typeof headers.location === "string")
457
+ headers.location = rewriteLocation(headers.location, to.href, proxyOrigin(req));
458
+ const type = String(headers["content-type"] ?? "");
459
+ const html = /text\/html/i.test(type);
460
+ if (html) {
461
+ // The page must not be embedded-blocked by its own dev server.
462
+ delete headers["x-frame-options"];
463
+ delete headers["content-security-policy"];
464
+ }
465
+ const encoded = !!headers["content-encoding"] && headers["content-encoding"] !== "identity";
466
+ // Nothing to put a script into: not a page, no body, or one we can't read.
467
+ if (!html || encoded || req.method === "HEAD" || status === 204 || status === 304 || (status >= 100 && status < 200)) {
468
+ res.writeHead(status, headers);
469
+ up.pipe(res);
470
+ return;
471
+ }
472
+ const chunks = [];
473
+ up.on("data", (c) => chunks.push(c));
474
+ up.on("end", () => {
475
+ const raw = Buffer.concat(chunks);
476
+ const body = injectBytes(raw, type) ?? raw;
477
+ // We buffered it to inject, so the framing is ours now: a chunked
478
+ // header kept beside a content-length is an invalid response, and
479
+ // the browser drops the page rather than showing it.
480
+ delete headers["content-length"];
481
+ delete headers["transfer-encoding"];
482
+ res.writeHead(status, { ...headers, "content-length": body.length });
483
+ res.end(body);
484
+ });
485
+ });
486
+ upstream.on("error", (err) => {
487
+ if (res.headersSent)
488
+ return void res.end();
489
+ res.writeHead(502, { "content-type": "text/plain" });
490
+ res.end(`loom preview: the server didn't answer (${err.message})`);
491
+ });
492
+ // A server that accepts the connection and then says nothing would hold
493
+ // the preview open for ever. Say so instead.
494
+ upstream.setTimeout(UPSTREAM_TIMEOUT_MS, () => {
495
+ upstream.destroy();
496
+ if (res.headersSent)
497
+ return void res.end();
498
+ res.writeHead(504, { "content-type": "text/plain" });
499
+ res.end("loom preview: the server accepted the connection but never answered");
500
+ });
501
+ Readable.from(req).pipe(upstream);
502
+ });
503
+ // An upgraded socket is nobody's connection once it's hijacked: server.close()
504
+ // waits for it for ever unless we keep the pair and end them ourselves.
505
+ const upgraded = new Set();
506
+ // HMR and anything else the page opens a socket for.
507
+ server.on("upgrade", (req, socket, head) => {
508
+ upgraded.add(socket);
509
+ socket.on("close", () => upgraded.delete(socket));
510
+ const up = lib.request({
511
+ host: upstreamHost,
512
+ port: upstreamPort,
513
+ method: req.method,
514
+ path: req.url,
515
+ headers: forwardHeaders(req),
516
+ // A pooled agent never surfaces the upgrade — the socket has to be ours.
517
+ agent: false,
518
+ ...tls,
519
+ });
520
+ up.on("upgrade", (upRes, upSocket, upHead) => {
521
+ socket.write(`HTTP/1.1 101 Switching Protocols\r\n${Object.entries(upRes.headers)
522
+ .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(", ") : v}`)
523
+ .join("\r\n")}\r\n\r\n`);
524
+ // Whatever the server sent in the same packet as its 101 goes OUT to the
525
+ // client — unshifting it would feed the server's bytes back in as if the
526
+ // client had sent them, and the first hot-reload message would vanish.
527
+ if (upHead?.length)
528
+ socket.write(upHead);
529
+ upgraded.add(upSocket);
530
+ upSocket.on("close", () => upgraded.delete(upSocket));
531
+ upSocket.pipe(socket);
532
+ socket.pipe(upSocket);
533
+ upSocket.on("error", () => socket.destroy());
534
+ socket.on("error", () => upSocket.destroy());
535
+ });
536
+ // Refused the upgrade: hand its answer back rather than hanging up mute.
537
+ up.on("response", (upRes) => {
538
+ socket.end(`HTTP/1.1 ${upRes.statusCode ?? 502} ${upRes.statusMessage ?? ""}\r\nconnection: close\r\n\r\n`);
539
+ upRes.resume();
540
+ });
541
+ up.on("error", () => socket.destroy());
542
+ if (head?.length)
543
+ up.write(head);
544
+ up.end();
545
+ });
546
+ const port = await new Promise((resolve, reject) => {
547
+ server.once("error", reject);
548
+ server.listen(0, host, () => resolve(server.address().port));
549
+ });
550
+ ownPort = port;
551
+ return {
552
+ port,
553
+ target,
554
+ close: () => new Promise((resolve) => {
555
+ for (const s of upgraded)
556
+ s.destroy();
557
+ upgraded.clear();
558
+ server.closeAllConnections?.();
559
+ server.close(() => resolve());
560
+ }),
561
+ };
562
+ }
563
+ //# sourceMappingURL=preview-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-proxy.js","sourceRoot":"","sources":["../../src/core/preview-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A picture of the page Loom is previewing.
3
+ *
4
+ * The preview is an iframe pointing at someone else's origin, so the browser
5
+ * will not let the page photograph it — and a person who can see the bug on
6
+ * screen shouldn't have to describe it in words. The daemon takes the shot
7
+ * instead, with the Playwright the project already has for its specs, and the
8
+ * file lands where attachments live so the composer can carry it like any
9
+ * pasted image.
10
+ *
11
+ * A project without Playwright is told so plainly rather than handed an empty
12
+ * file: `npx --no-install` never installs anything behind your back.
13
+ */
14
+ import { spawn } from "./process.js";
15
+ export interface ShotRequest {
16
+ url: string;
17
+ width?: number;
18
+ height?: number;
19
+ /** What the page should think the OS is set to. */
20
+ colorScheme?: "light" | "dark";
21
+ fullPage?: boolean;
22
+ /** Just this element (a CSS selector from the preview's picker): its own picture, cropped. */
23
+ selector?: string;
24
+ timeoutMs?: number;
25
+ }
26
+ export declare const MAX_SHOT_MS = 45000;
27
+ /** The little script Playwright runs. Kept here so what it does is readable. */
28
+ export declare function shotScript(req: Required<Omit<ShotRequest, "timeoutMs" | "selector">> & {
29
+ selector?: string;
30
+ out: string;
31
+ }): string;
32
+ export interface ShotResult {
33
+ /** Where the PNG landed, absolute. */
34
+ file: string;
35
+ width: number;
36
+ height: number;
37
+ colorScheme: "light" | "dark";
38
+ fullPage: boolean;
39
+ }
40
+ /**
41
+ * Take the shot in `projectDir` (so the project's own Playwright and browsers
42
+ * are the ones used). Rejects with something a person can act on.
43
+ */
44
+ export declare function capture(projectDir: string, req: ShotRequest, spawnImpl?: typeof spawn): Promise<ShotResult>;
45
+ /** Playwright's failures, in words that say what to do. */
46
+ export declare function explain(stderr: string): string;