@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
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Turns, read straight off the event log: who ran how many, how often they
3
+ * finished without an error, how long a turn takes, what one costs — and the
4
+ * same turns day by day and row by row. Nothing estimated: every number is
5
+ * a field an agent's own CLI reported on run_complete (or an error event).
6
+ */
7
+ import type { LoomEvent } from "../types.js";
8
+ export interface TurnRow {
9
+ id: number;
10
+ ts: number;
11
+ agentId: string;
12
+ chat: string;
13
+ ok: boolean;
14
+ durationMs?: number;
15
+ costUsd?: number;
16
+ inputTokens?: number;
17
+ outputTokens?: number;
18
+ model?: string;
19
+ error?: string;
20
+ }
21
+ export interface AgentStanding {
22
+ agentId: string;
23
+ turns: number;
24
+ ok: number;
25
+ errors: number;
26
+ successRate: number;
27
+ medianMs: number | null;
28
+ avgCostUsd: number | null;
29
+ totalCostUsd: number;
30
+ tokens: number;
31
+ }
32
+ export interface DayCount {
33
+ date: string;
34
+ turns: number;
35
+ errors: number;
36
+ costUsd: number;
37
+ }
38
+ export declare function turnRows(events: LoomEvent[]): TurnRow[];
39
+ /** Agents ranked by how reliably they finish, then by how many turns they've run. */
40
+ export declare function leaderboard(rows: TurnRow[]): AgentStanding[];
41
+ /**
42
+ * Trust: how often an agent's "done" held up. Read from what Loom checked —
43
+ * Proof's verdicts on its turns (verified / didn't hold / unverified), the
44
+ * loop watch catching it in circles, the shield catching a command that can't
45
+ * be taken back. Cost per verified "done" is its spend over the checks that
46
+ * held: what a result you can trust costs from this agent.
47
+ */
48
+ export interface Trust {
49
+ verified: number;
50
+ contradicted: number;
51
+ unverified: number;
52
+ /** verified / (verified + contradicted); null until something was checked either way. */
53
+ holdRate: number | null;
54
+ loops: number;
55
+ shield: number;
56
+ }
57
+ export declare function trustByAgent(events: LoomEvent[]): Record<string, Trust>;
58
+ /** The last `days` days, oldest first, every day present (zeros included). */
59
+ export declare function perDay(rows: TurnRow[], days: number, now?: number): DayCount[];
60
+ /** One row per turn, for a spreadsheet. */
61
+ export declare function turnsCsv(rows: TurnRow[]): string;
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Turns, read straight off the event log: who ran how many, how often they
3
+ * finished without an error, how long a turn takes, what one costs — and the
4
+ * same turns day by day and row by row. Nothing estimated: every number is
5
+ * a field an agent's own CLI reported on run_complete (or an error event).
6
+ */
7
+ const num = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
8
+ export function turnRows(events) {
9
+ const rows = [];
10
+ for (const e of events) {
11
+ if (!e.agentId || (e.kind !== "run_complete" && e.kind !== "error"))
12
+ continue;
13
+ const p = e.payload;
14
+ const row = { id: e.id, ts: e.ts, agentId: e.agentId, chat: e.chat ?? "main", ok: e.kind === "run_complete" };
15
+ const d = num(p.durationMs), c = num(p.costUsd), ti = num(p.inputTokens), to = num(p.outputTokens);
16
+ if (d !== undefined)
17
+ row.durationMs = d;
18
+ if (c !== undefined)
19
+ row.costUsd = c;
20
+ if (ti !== undefined)
21
+ row.inputTokens = ti;
22
+ if (to !== undefined)
23
+ row.outputTokens = to;
24
+ if (typeof p.model === "string")
25
+ row.model = p.model;
26
+ if (!row.ok)
27
+ row.error = String(p.message ?? p.error ?? "error").split("\n")[0].slice(0, 300);
28
+ rows.push(row);
29
+ }
30
+ return rows;
31
+ }
32
+ function median(xs) {
33
+ if (!xs.length)
34
+ return null;
35
+ const s = [...xs].sort((a, b) => a - b);
36
+ const mid = Math.floor(s.length / 2);
37
+ return s.length % 2 ? s[mid] : Math.round((s[mid - 1] + s[mid]) / 2);
38
+ }
39
+ /** Agents ranked by how reliably they finish, then by how many turns they've run. */
40
+ export function leaderboard(rows) {
41
+ const by = new Map();
42
+ for (const r of rows)
43
+ by.set(r.agentId, [...(by.get(r.agentId) ?? []), r]);
44
+ const out = [];
45
+ for (const [agentId, rs] of by) {
46
+ const ok = rs.filter((r) => r.ok);
47
+ const costs = ok.map((r) => r.costUsd).filter((c) => c !== undefined);
48
+ const total = costs.reduce((a, b) => a + b, 0);
49
+ out.push({
50
+ agentId,
51
+ turns: rs.length,
52
+ ok: ok.length,
53
+ errors: rs.length - ok.length,
54
+ successRate: rs.length ? ok.length / rs.length : 0,
55
+ medianMs: median(ok.map((r) => r.durationMs).filter((d) => d !== undefined)),
56
+ avgCostUsd: costs.length ? total / costs.length : null,
57
+ totalCostUsd: total,
58
+ tokens: rs.reduce((a, r) => a + (r.inputTokens ?? 0) + (r.outputTokens ?? 0), 0),
59
+ });
60
+ }
61
+ return out.sort((a, b) => b.successRate - a.successRate || b.turns - a.turns || a.agentId.localeCompare(b.agentId));
62
+ }
63
+ export function trustByAgent(events) {
64
+ const out = {};
65
+ const of = (id) => (out[id] ??= { verified: 0, contradicted: 0, unverified: 0, holdRate: null, loops: 0, shield: 0 });
66
+ for (const e of events) {
67
+ const p = e.payload;
68
+ if (e.kind === "proof" && typeof p.about === "string" && p.about) {
69
+ const t = of(p.about);
70
+ if (p.verdict === "verified")
71
+ t.verified++;
72
+ else if (p.verdict === "contradicted")
73
+ t.contradicted++;
74
+ else
75
+ t.unverified++;
76
+ }
77
+ else if (e.kind === "status" && e.agentId && p.state === "loop_detected")
78
+ of(e.agentId).loops++;
79
+ else if (e.kind === "status" && e.agentId && p.state === "shield_tripped")
80
+ of(e.agentId).shield++;
81
+ }
82
+ for (const t of Object.values(out))
83
+ t.holdRate = t.verified + t.contradicted ? t.verified / (t.verified + t.contradicted) : null;
84
+ return out;
85
+ }
86
+ function dayKey(ts) {
87
+ const d = new Date(ts);
88
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
89
+ }
90
+ /** The last `days` days, oldest first, every day present (zeros included). */
91
+ export function perDay(rows, days, now = Date.now()) {
92
+ const map = new Map();
93
+ const start = new Date(now);
94
+ start.setHours(0, 0, 0, 0);
95
+ for (let i = days - 1; i >= 0; i--) {
96
+ const d = new Date(start);
97
+ d.setDate(d.getDate() - i);
98
+ const k = dayKey(d.getTime());
99
+ map.set(k, { date: k, turns: 0, errors: 0, costUsd: 0 });
100
+ }
101
+ for (const r of rows) {
102
+ const c = map.get(dayKey(r.ts));
103
+ if (!c)
104
+ continue;
105
+ c.turns++;
106
+ if (!r.ok)
107
+ c.errors++;
108
+ c.costUsd += r.costUsd ?? 0;
109
+ }
110
+ return [...map.values()];
111
+ }
112
+ const csvCell = (v) => {
113
+ const s = v === undefined || v === null ? "" : String(v);
114
+ return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
115
+ };
116
+ /** One row per turn, for a spreadsheet. */
117
+ export function turnsCsv(rows) {
118
+ const head = ["time", "agent", "chat", "ok", "duration_ms", "cost_usd", "input_tokens", "output_tokens", "model", "error"];
119
+ const lines = rows.map((r) => [new Date(r.ts).toISOString(), r.agentId, r.chat, r.ok ? "yes" : "no", r.durationMs, r.costUsd, r.inputTokens, r.outputTokens, r.model, r.error]
120
+ .map(csvCell)
121
+ .join(","));
122
+ return [head.join(","), ...lines].join("\n") + "\n";
123
+ }
124
+ //# sourceMappingURL=turn-stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-stats.js","sourceRoot":"","sources":["../../src/core/turn-stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Is there a newer Loom, and can this copy fetch it?
3
+ *
4
+ * Two questions, and they have different answers depending on how Loom got
5
+ * here. A git checkout pulls and rebuilds; a global npm install reinstalls
6
+ * itself from the same spec it came from; anything else (a packaged desktop
7
+ * app, a copied folder) is told plainly to download the release rather than
8
+ * having a command guessed at and run over it.
9
+ *
10
+ * Nothing here decides on its own to upgrade. `check` looks, `plan` says what
11
+ * would happen in the exact words of the command, and the daemon runs it only
12
+ * when someone asks.
13
+ */
14
+ export type InstallKind = "git" | "npm-global" | "unknown";
15
+ export interface Release {
16
+ /** The tag without its leading v — comparable with VERSION. */
17
+ version: string;
18
+ tag: string;
19
+ url: string;
20
+ publishedAt: string | null;
21
+ }
22
+ export interface UpdatePlan {
23
+ /** What this copy is, and so what updating it means. */
24
+ install: InstallKind;
25
+ /** The directory the commands run in (a checkout, or the global prefix). */
26
+ cwd: string | null;
27
+ /** Each step, in the words that will be run — nothing hidden. */
28
+ steps: Array<{
29
+ cmd: string;
30
+ args: string[];
31
+ }>;
32
+ /** Null when we can update; otherwise why we won't try. */
33
+ refusal: string | null;
34
+ }
35
+ /** The repository releases are read from. Overridable for testing and forks. */
36
+ export declare const RELEASES_REPO: string;
37
+ /** How long a release check is trusted, so a background poll can't hammer the API. */
38
+ export declare const CHECK_TTL_MS: number;
39
+ /**
40
+ * Semver-ish comparison, enough for `v0.2.10` > `v0.2.9` and prereleases
41
+ * sorting under their release. Unknown shapes compare as equal, which means
42
+ * "no update" — the safe direction.
43
+ */
44
+ export declare function newerThan(a: string, b: string): boolean;
45
+ /** The newest published release, or null when the network or the repo says nothing. */
46
+ export declare function latestRelease(fetchImpl?: typeof fetch, repo?: string): Promise<Release | null>;
47
+ /**
48
+ * How this copy of Loom was installed, from where its own code sits.
49
+ *
50
+ * A checkout has a .git above it. A global npm install lives under a
51
+ * node_modules whose package.json is ours. Everything else is unknown, and
52
+ * unknown is a fine answer — it just means we don't run anything.
53
+ */
54
+ export declare function detectInstall(moduleDir: string): {
55
+ kind: InstallKind;
56
+ cwd: string | null;
57
+ spec?: string;
58
+ };
59
+ /** What updating this copy would actually run. */
60
+ export declare function plan(install: {
61
+ kind: InstallKind;
62
+ cwd: string | null;
63
+ spec?: string;
64
+ }): UpdatePlan;
65
+ /**
66
+ * A git checkout with uncommitted work is yours, not ours to move.
67
+ *
68
+ * Modified tracked files only. Untracked ones don't stop a fast-forward —
69
+ * refusing over a stray scratch file or a symlinked node_modules would block
70
+ * the update for something git is perfectly happy with. (If an untracked file
71
+ * would actually be overwritten, git itself refuses and that error is shown.)
72
+ */
73
+ export declare function refuseDirtyCheckout(status: string): string | null;
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Is there a newer Loom, and can this copy fetch it?
3
+ *
4
+ * Two questions, and they have different answers depending on how Loom got
5
+ * here. A git checkout pulls and rebuilds; a global npm install reinstalls
6
+ * itself from the same spec it came from; anything else (a packaged desktop
7
+ * app, a copied folder) is told plainly to download the release rather than
8
+ * having a command guessed at and run over it.
9
+ *
10
+ * Nothing here decides on its own to upgrade. `check` looks, `plan` says what
11
+ * would happen in the exact words of the command, and the daemon runs it only
12
+ * when someone asks.
13
+ */
14
+ import fs from "node:fs";
15
+ import path from "node:path";
16
+ /** The repository releases are read from. Overridable for testing and forks. */
17
+ export const RELEASES_REPO = process.env.LOOM_RELEASES_REPO || "nickthelegend/loom";
18
+ /** How long a release check is trusted, so a background poll can't hammer the API. */
19
+ export const CHECK_TTL_MS = 6 * 60 * 60_000;
20
+ /**
21
+ * Semver-ish comparison, enough for `v0.2.10` > `v0.2.9` and prereleases
22
+ * sorting under their release. Unknown shapes compare as equal, which means
23
+ * "no update" — the safe direction.
24
+ */
25
+ export function newerThan(a, b) {
26
+ const parse = (v) => {
27
+ const m = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/.exec(v.trim());
28
+ return m ? { nums: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] ?? null } : null;
29
+ };
30
+ const x = parse(a);
31
+ const y = parse(b);
32
+ if (!x || !y)
33
+ return false;
34
+ for (let i = 0; i < 3; i++) {
35
+ if (x.nums[i] !== y.nums[i])
36
+ return x.nums[i] > y.nums[i];
37
+ }
38
+ // 1.0.0 is newer than 1.0.0-rc1; two prereleases compare as strings.
39
+ if (x.pre === y.pre)
40
+ return false;
41
+ if (!x.pre)
42
+ return true;
43
+ if (!y.pre)
44
+ return false;
45
+ return x.pre > y.pre;
46
+ }
47
+ /** The newest published release, or null when the network or the repo says nothing. */
48
+ export async function latestRelease(fetchImpl = fetch, repo = RELEASES_REPO) {
49
+ const ctl = new AbortController();
50
+ const timer = setTimeout(() => ctl.abort(), 8000);
51
+ try {
52
+ const res = await fetchImpl(`https://api.github.com/repos/${repo}/releases/latest`, {
53
+ signal: ctl.signal,
54
+ headers: { accept: "application/vnd.github+json", "user-agent": "loom-updater" },
55
+ });
56
+ if (!res.ok)
57
+ return null;
58
+ const body = (await res.json());
59
+ if (!body.tag_name || body.draft)
60
+ return null;
61
+ return {
62
+ version: body.tag_name.replace(/^v/, ""),
63
+ tag: body.tag_name,
64
+ url: body.html_url ?? `https://github.com/${repo}/releases/tag/${body.tag_name}`,
65
+ publishedAt: body.published_at ?? null,
66
+ };
67
+ }
68
+ catch {
69
+ // offline, rate-limited, a repo with no releases: not an error, just no answer
70
+ return null;
71
+ }
72
+ finally {
73
+ clearTimeout(timer);
74
+ }
75
+ }
76
+ /**
77
+ * How this copy of Loom was installed, from where its own code sits.
78
+ *
79
+ * A checkout has a .git above it. A global npm install lives under a
80
+ * node_modules whose package.json is ours. Everything else is unknown, and
81
+ * unknown is a fine answer — it just means we don't run anything.
82
+ */
83
+ export function detectInstall(moduleDir) {
84
+ let dir = moduleDir;
85
+ for (let i = 0; i < 8; i++) {
86
+ if (fs.existsSync(path.join(dir, ".git")))
87
+ return { kind: "git", cwd: dir };
88
+ // .../lib/node_modules/@loompad/cli/dist → the package root holds package.json
89
+ const pkgFile = path.join(dir, "package.json");
90
+ if (fs.existsSync(pkgFile)) {
91
+ try {
92
+ const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf8"));
93
+ if (pkg.name && dir.includes(`${path.sep}node_modules${path.sep}`)) {
94
+ return { kind: "npm-global", cwd: dir, spec: `github:${RELEASES_REPO}` };
95
+ }
96
+ }
97
+ catch {
98
+ /* a package.json we can't read tells us nothing */
99
+ }
100
+ }
101
+ const parent = path.dirname(dir);
102
+ if (parent === dir)
103
+ break;
104
+ dir = parent;
105
+ }
106
+ return { kind: "unknown", cwd: null };
107
+ }
108
+ /** What updating this copy would actually run. */
109
+ export function plan(install) {
110
+ if (install.kind === "git" && install.cwd) {
111
+ return {
112
+ install: "git",
113
+ cwd: install.cwd,
114
+ steps: [
115
+ { cmd: "git", args: ["pull", "--ff-only"] },
116
+ { cmd: "npm", args: ["install", "--no-audit", "--no-fund"] },
117
+ { cmd: "npm", args: ["run", "build"] },
118
+ ],
119
+ refusal: null,
120
+ };
121
+ }
122
+ if (install.kind === "npm-global") {
123
+ return {
124
+ install: "npm-global",
125
+ cwd: install.cwd,
126
+ steps: [{ cmd: "npm", args: ["install", "-g", install.spec ?? `github:${RELEASES_REPO}`] }],
127
+ refusal: null,
128
+ };
129
+ }
130
+ return {
131
+ install: "unknown",
132
+ cwd: null,
133
+ steps: [],
134
+ refusal: "this copy of Loom wasn't installed from git or npm — download the release instead",
135
+ };
136
+ }
137
+ /**
138
+ * A git checkout with uncommitted work is yours, not ours to move.
139
+ *
140
+ * Modified tracked files only. Untracked ones don't stop a fast-forward —
141
+ * refusing over a stray scratch file or a symlinked node_modules would block
142
+ * the update for something git is perfectly happy with. (If an untracked file
143
+ * would actually be overwritten, git itself refuses and that error is shown.)
144
+ */
145
+ export function refuseDirtyCheckout(status) {
146
+ const tracked = status
147
+ .split("\n")
148
+ .filter((l) => l.trim() && !l.startsWith("??"));
149
+ return tracked.length
150
+ ? `this checkout has uncommitted changes to ${tracked.length} file${tracked.length === 1 ? "" : "s"} — commit or stash them first`
151
+ : null;
152
+ }
153
+ //# sourceMappingURL=updater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updater.js","sourceRoot":"","sources":["../../src/core/updater.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Where the money and the tokens went: one walk over a project's event log,
3
+ * broken down by agent, by model, by chat, by day and by tool.
4
+ *
5
+ * The totals follow the accounting rule (runtime/accounting.ts): a turn's
6
+ * dollars arrive on a `turn_cost` status, and the same figure may be copied
7
+ * onto `run_complete` — counting both would double it. So a turn's cost is
8
+ * the `turn_cost` seen for that agent since its last turn ended, or, when an
9
+ * adapter only reported it on `run_complete`, that. Every dollar lands on the
10
+ * turn that spent it, which is what lets it be split by model and chat.
11
+ *
12
+ * Nothing is invented: an adapter that reports no price (a subscription CLI, a
13
+ * free model) shows tokens and $0, and `unpriced` counts those turns so the UI
14
+ * can say the total is a floor, not the bill.
15
+ */
16
+ import type { LoomEvent } from "../types.js";
17
+ export interface UsageSlice {
18
+ usd: number;
19
+ turns: number;
20
+ tokensIn: number;
21
+ tokensOut: number;
22
+ /** The part of tokensIn served from the provider's cache. */
23
+ cachedIn: number;
24
+ /** The part of tokensOut spent thinking. */
25
+ reasoning: number;
26
+ ms: number;
27
+ }
28
+ export interface UsageAgent extends UsageSlice {
29
+ agentId: string;
30
+ kind?: string;
31
+ models: string[];
32
+ toolCalls: number;
33
+ toolFailures: number;
34
+ errors: number;
35
+ /** Turns that reported tokens but no price. */
36
+ unpriced: number;
37
+ }
38
+ export interface UsageReport {
39
+ since: number;
40
+ totals: UsageSlice & {
41
+ toolCalls: number;
42
+ toolFailures: number;
43
+ errors: number;
44
+ prompts: number;
45
+ questions: number;
46
+ filesChanged: number;
47
+ linesAdded: number;
48
+ linesRemoved: number;
49
+ unpriced: number;
50
+ /** Derived, so every client says the same thing. */
51
+ avgTurnMs: number;
52
+ usdPerTurn: number;
53
+ cacheHitRate: number;
54
+ };
55
+ byAgent: UsageAgent[];
56
+ byModel: Array<UsageSlice & {
57
+ model: string;
58
+ }>;
59
+ byChat: Array<UsageSlice & {
60
+ chat: string;
61
+ }>;
62
+ byDay: Array<UsageSlice & {
63
+ day: string;
64
+ }>;
65
+ byTool: Array<{
66
+ tool: string;
67
+ calls: number;
68
+ failures: number;
69
+ }>;
70
+ }
71
+ export declare function usageReport(events: readonly LoomEvent[], opts?: {
72
+ since?: number;
73
+ kinds?: Record<string, string>;
74
+ models?: Record<string, string>;
75
+ }): UsageReport;
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Where the money and the tokens went: one walk over a project's event log,
3
+ * broken down by agent, by model, by chat, by day and by tool.
4
+ *
5
+ * The totals follow the accounting rule (runtime/accounting.ts): a turn's
6
+ * dollars arrive on a `turn_cost` status, and the same figure may be copied
7
+ * onto `run_complete` — counting both would double it. So a turn's cost is
8
+ * the `turn_cost` seen for that agent since its last turn ended, or, when an
9
+ * adapter only reported it on `run_complete`, that. Every dollar lands on the
10
+ * turn that spent it, which is what lets it be split by model and chat.
11
+ *
12
+ * Nothing is invented: an adapter that reports no price (a subscription CLI, a
13
+ * free model) shows tokens and $0, and `unpriced` counts those turns so the UI
14
+ * can say the total is a floor, not the bill.
15
+ */
16
+ const blank = () => ({ usd: 0, turns: 0, tokensIn: 0, tokensOut: 0, cachedIn: 0, reasoning: 0, ms: 0 });
17
+ function add(into, t) {
18
+ into.usd += t.usd;
19
+ into.turns += t.turns;
20
+ into.tokensIn += t.tokensIn;
21
+ into.tokensOut += t.tokensOut;
22
+ into.cachedIn += t.cachedIn;
23
+ into.reasoning += t.reasoning;
24
+ into.ms += t.ms;
25
+ }
26
+ const num = (v) => {
27
+ const n = Number(v);
28
+ return Number.isFinite(n) && n > 0 ? n : 0;
29
+ };
30
+ /** Local calendar day, as the Observatory's daily series counts it. */
31
+ function dayOf(ts) {
32
+ const d = new Date(ts);
33
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
34
+ }
35
+ export function usageReport(events, opts = {}) {
36
+ const since = opts.since ?? 0;
37
+ const agents = new Map();
38
+ const models = new Map();
39
+ const chats = new Map();
40
+ const days = new Map();
41
+ const tools = new Map();
42
+ const pending = new Map(); // agent → turn_cost not yet tied to a turn
43
+ const totals = blank();
44
+ let toolCalls = 0, toolFailures = 0, errors = 0, prompts = 0, questions = 0, filesChanged = 0, linesAdded = 0, linesRemoved = 0, unpriced = 0;
45
+ const agent = (id) => {
46
+ let a = agents.get(id);
47
+ if (!a) {
48
+ a = { agentId: id, ...(opts.kinds?.[id] ? { kind: opts.kinds[id] } : {}), ...blank(), models: [], toolCalls: 0, toolFailures: 0, errors: 0, unpriced: 0 };
49
+ agents.set(id, a);
50
+ }
51
+ return a;
52
+ };
53
+ const slice = (m, k) => {
54
+ let s = m.get(k);
55
+ if (!s)
56
+ m.set(k, (s = blank()));
57
+ return s;
58
+ };
59
+ for (const e of events) {
60
+ if (e.ts < since)
61
+ continue;
62
+ const p = (e.payload ?? {});
63
+ const who = e.agentId ?? "unknown";
64
+ if (e.kind === "status" && p.state === "turn_cost") {
65
+ pending.set(who, (pending.get(who) ?? 0) + num(p.costUsd));
66
+ continue;
67
+ }
68
+ if (e.kind === "run_complete") {
69
+ const owed = pending.get(who) ?? 0;
70
+ pending.delete(who);
71
+ const usd = owed > 0 ? owed : num(p.costUsd);
72
+ const t = {
73
+ usd,
74
+ turns: 1,
75
+ tokensIn: num(p.inputTokens ?? p.tokensIn),
76
+ tokensOut: num(p.outputTokens ?? p.tokensOut),
77
+ cachedIn: num(p.cachedInputTokens),
78
+ reasoning: num(p.reasoningTokens),
79
+ ms: num(p.durationMs),
80
+ };
81
+ // a turn that didn't name its model ran on whatever the agent defaults to
82
+ const model = String(p.model ?? opts.models?.[who] ?? "") || (opts.kinds?.[who] ? `${opts.kinds[who]} · default model` : "unknown");
83
+ const a = agent(who);
84
+ add(a, t);
85
+ if (!a.models.includes(model))
86
+ a.models.push(model);
87
+ if (!usd && (t.tokensIn || t.tokensOut)) {
88
+ a.unpriced++;
89
+ unpriced++;
90
+ }
91
+ add(totals, t);
92
+ add(slice(models, model), t);
93
+ add(slice(chats, e.chat ?? "main"), t);
94
+ add(slice(days, dayOf(e.ts)), t);
95
+ continue;
96
+ }
97
+ if (e.kind === "tool_call") {
98
+ const failed = p.ok === false || !!p.error || (typeof p.exitCode === "number" && p.exitCode !== 0);
99
+ const name = String(p.server ? `${String(p.server)}.${String(p.tool ?? "tool")}` : p.tool ?? "tool");
100
+ const t = tools.get(name) ?? { calls: 0, failures: 0 };
101
+ t.calls++;
102
+ if (failed)
103
+ t.failures++;
104
+ tools.set(name, t);
105
+ const a = agent(who);
106
+ a.toolCalls++;
107
+ toolCalls++;
108
+ if (failed) {
109
+ a.toolFailures++;
110
+ toolFailures++;
111
+ }
112
+ continue;
113
+ }
114
+ if (e.kind === "error") {
115
+ if (e.agentId)
116
+ agent(who).errors++;
117
+ errors++;
118
+ continue;
119
+ }
120
+ if (e.kind === "message" && !e.agentId)
121
+ prompts++;
122
+ else if (e.kind === "needs_input")
123
+ questions++;
124
+ else if (e.kind === "turn_diff") {
125
+ filesChanged += Array.isArray(p.files) ? p.files.length : 0;
126
+ linesAdded += num(p.added);
127
+ linesRemoved += num(p.removed);
128
+ }
129
+ }
130
+ // money reported with no turn after it (an interrupted turn) still counts
131
+ for (const [who, usd] of pending) {
132
+ if (!usd)
133
+ continue;
134
+ agent(who).usd += usd;
135
+ totals.usd += usd;
136
+ slice(models, opts.models?.[who] || "unknown").usd += usd;
137
+ }
138
+ const bySpend = (a, b) => b.usd - a.usd || b.tokensIn + b.tokensOut - (a.tokensIn + a.tokensOut) || b.turns - a.turns;
139
+ return {
140
+ since,
141
+ totals: {
142
+ ...totals,
143
+ toolCalls,
144
+ toolFailures,
145
+ errors,
146
+ prompts,
147
+ questions,
148
+ filesChanged,
149
+ linesAdded,
150
+ linesRemoved,
151
+ unpriced,
152
+ avgTurnMs: totals.turns ? Math.round(totals.ms / totals.turns) : 0,
153
+ usdPerTurn: totals.turns ? totals.usd / totals.turns : 0,
154
+ cacheHitRate: totals.tokensIn ? totals.cachedIn / totals.tokensIn : 0,
155
+ },
156
+ byAgent: [...agents.values()].sort(bySpend),
157
+ byModel: [...models.entries()].map(([model, s]) => ({ model, ...s })).sort(bySpend),
158
+ byChat: [...chats.entries()].map(([chat, s]) => ({ chat, ...s })).sort(bySpend).slice(0, 20),
159
+ byDay: [...days.entries()].map(([day, s]) => ({ day, ...s })).sort((a, b) => a.day.localeCompare(b.day)),
160
+ byTool: [...tools.entries()].map(([tool, t]) => ({ tool, ...t })).sort((a, b) => b.calls - a.calls).slice(0, 20),
161
+ };
162
+ }
163
+ //# sourceMappingURL=usage.js.map