@swirls/looms 0.0.2 → 0.2.0

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 (375) hide show
  1. package/CHANGELOG.md +24 -2
  2. package/dist/actor/cell.d.ts +9 -4
  3. package/dist/actor/cell.js +7 -11
  4. package/dist/actor/host.d.ts +7 -3
  5. package/dist/actor/host.js +57 -33
  6. package/dist/actor/index.d.ts +1 -1
  7. package/dist/actor/index.js +1 -1
  8. package/dist/actor/routing.d.ts +12 -1
  9. package/dist/actor/routing.js +57 -51
  10. package/dist/agent/agent-session.d.ts +5 -0
  11. package/dist/agent/agent-session.js +270 -0
  12. package/dist/agent/debugger/agent-chat.d.ts +2 -0
  13. package/dist/agent/debugger/agent-chat.js +176 -0
  14. package/dist/agent/debugger/index.d.ts +5 -0
  15. package/dist/agent/debugger/index.js +19 -0
  16. package/dist/agent/debugger/summarize.d.ts +2 -0
  17. package/dist/agent/debugger/summarize.js +51 -0
  18. package/dist/agent/debugger/token-usage.d.ts +3 -0
  19. package/dist/agent/debugger/token-usage.js +11 -0
  20. package/dist/agent/definitions-store.d.ts +2 -3
  21. package/dist/agent/definitions-store.js +2 -4
  22. package/dist/agent/definitions.d.ts +47 -29
  23. package/dist/agent/definitions.js +39 -12
  24. package/dist/agent/effects.d.ts +359 -2
  25. package/dist/agent/effects.js +60 -34
  26. package/dist/agent/events.d.ts +175 -19
  27. package/dist/agent/events.js +45 -10
  28. package/dist/agent/index.d.ts +1 -0
  29. package/dist/agent/index.js +1 -0
  30. package/dist/agent/llm.d.ts +11 -2
  31. package/dist/agent/llm.js +13 -3
  32. package/dist/agent/module.d.ts +812 -78
  33. package/dist/agent/module.js +16 -4
  34. package/dist/agent/scope.d.ts +174 -18
  35. package/dist/agent/signals.d.ts +26 -1
  36. package/dist/agent/signals.js +79 -0
  37. package/dist/agent/threads.d.ts +3 -33
  38. package/dist/agent/threads.js +20 -25
  39. package/dist/agent/tool-schema.d.ts +1 -17
  40. package/dist/agent/tool-schema.js +3 -43
  41. package/dist/agent/types.d.ts +49 -4
  42. package/dist/agent/types.js +5 -5
  43. package/dist/ai-vercel/index.d.ts +1 -0
  44. package/dist/ai-vercel/index.js +1 -0
  45. package/dist/ai-vercel/messages.js +22 -7
  46. package/dist/ai-vercel/vercel-evaluator.d.ts +36 -0
  47. package/dist/ai-vercel/vercel-evaluator.js +73 -0
  48. package/dist/ai-vercel/vercel-llm.js +64 -44
  49. package/dist/approval/debugger/approvals-view.d.ts +3 -0
  50. package/dist/approval/debugger/approvals-view.js +16 -0
  51. package/dist/approval/debugger/index.d.ts +4 -0
  52. package/dist/approval/debugger/index.js +11 -0
  53. package/dist/approval/debugger/summarize.d.ts +2 -0
  54. package/dist/approval/debugger/summarize.js +17 -0
  55. package/dist/approval/effects.d.ts +89 -0
  56. package/dist/approval/module.d.ts +179 -29
  57. package/dist/approval/projections.d.ts +0 -14
  58. package/dist/approval/projections.js +20 -3
  59. package/dist/approval/signals.d.ts +2 -0
  60. package/dist/approval/signals.js +18 -2
  61. package/dist/cli/cli.js +2 -0
  62. package/dist/cli/commands.js +12 -16
  63. package/dist/client/client.d.ts +1213 -18
  64. package/dist/client/client.js +120 -120
  65. package/dist/client/index.d.ts +1 -1
  66. package/dist/client/index.js +1 -1
  67. package/dist/client/sse.d.ts +13 -0
  68. package/dist/client/sse.js +38 -44
  69. package/dist/cloudflare/alarm-scheduler.d.ts +12 -2
  70. package/dist/cloudflare/alarm-scheduler.js +34 -7
  71. package/dist/cloudflare/durable-object.d.ts +10 -2
  72. package/dist/cloudflare/durable-object.js +59 -28
  73. package/dist/cloudflare/event-store.d.ts +7 -2
  74. package/dist/cloudflare/event-store.js +8 -7
  75. package/dist/cloudflare/index.d.ts +2 -2
  76. package/dist/cloudflare/index.js +2 -2
  77. package/dist/cloudflare/router.d.ts +1 -1
  78. package/dist/cloudflare/router.js +15 -16
  79. package/dist/core/catalog.d.ts +3 -3
  80. package/dist/core/catalog.js +2 -5
  81. package/dist/core/coalesce.js +5 -3
  82. package/dist/core/compose.d.ts +2 -1
  83. package/dist/core/compose.js +19 -2
  84. package/dist/core/debugger-host.d.ts +16 -0
  85. package/dist/core/debugger-host.js +1 -0
  86. package/dist/core/definition-store.d.ts +11 -0
  87. package/dist/core/definition-store.js +6 -0
  88. package/dist/core/effects.d.ts +127 -15
  89. package/dist/core/effects.js +89 -17
  90. package/dist/core/envelope.d.ts +27 -7
  91. package/dist/core/envelope.js +20 -6
  92. package/dist/core/event-codec.d.ts +4 -2
  93. package/dist/core/event-codec.js +10 -5
  94. package/dist/core/event-index.js +1 -3
  95. package/dist/core/fold.d.ts +3 -0
  96. package/dist/core/fold.js +171 -24
  97. package/dist/core/ids.d.ts +5 -0
  98. package/dist/core/ids.js +35 -2
  99. package/dist/core/index.d.ts +7 -1
  100. package/dist/core/index.js +6 -1
  101. package/dist/core/kind.d.ts +22 -0
  102. package/dist/core/kind.js +17 -0
  103. package/dist/core/limits.d.ts +34 -0
  104. package/dist/core/limits.js +46 -0
  105. package/dist/core/match.d.ts +1 -0
  106. package/dist/core/match.js +10 -1
  107. package/dist/core/module-scope.d.ts +22 -20
  108. package/dist/core/module-scope.js +38 -28
  109. package/dist/core/module.d.ts +18 -5
  110. package/dist/core/module.js +4 -0
  111. package/dist/core/projection.d.ts +13 -13
  112. package/dist/core/projection.js +9 -5
  113. package/dist/core/protocol.d.ts +68 -11
  114. package/dist/core/protocol.js +82 -11
  115. package/dist/core/published.d.ts +43 -0
  116. package/dist/core/published.js +44 -0
  117. package/dist/core/replay.d.ts +312 -3
  118. package/dist/core/replay.js +11 -1
  119. package/dist/core/schema.d.ts +11 -20
  120. package/dist/core/schema.js +63 -80
  121. package/dist/core/serialize.js +2 -4
  122. package/dist/core/snapshot-store.d.ts +6 -1
  123. package/dist/core/snapshot-store.js +15 -2
  124. package/dist/core/snapshots.d.ts +5 -1
  125. package/dist/core/snapshots.js +10 -15
  126. package/dist/core/sqlite-store.js +95 -11
  127. package/dist/core/state.d.ts +142 -4
  128. package/dist/core/state.js +78 -0
  129. package/dist/core/store.d.ts +38 -3
  130. package/dist/core/store.js +77 -22
  131. package/dist/core/thread.d.ts +10 -9
  132. package/dist/core/types.d.ts +5 -8
  133. package/dist/core/types.js +28 -24
  134. package/dist/core/validate-event.js +14 -4
  135. package/dist/core/worker-callback.d.ts +17 -0
  136. package/dist/core/worker-callback.js +1 -0
  137. package/dist/debugger/app/assets/index-B3Ah8WAE.css +2 -0
  138. package/dist/debugger/app/assets/index-Qb371t_O.js +22 -0
  139. package/dist/debugger/app/assets/rolldown-runtime-CbXtAM7H.js +1 -0
  140. package/dist/debugger/app/assets/routes-CjtEHgPQ.js +47 -0
  141. package/dist/debugger/app/index.html +14 -0
  142. package/dist/debugger/components/composer.d.ts +17 -0
  143. package/dist/debugger/components/composer.js +25 -0
  144. package/dist/debugger/components/debugger-split.d.ts +2 -1
  145. package/dist/debugger/components/debugger-split.js +2 -2
  146. package/dist/debugger/components/event-inspector.d.ts +2 -1
  147. package/dist/debugger/components/event-inspector.js +25 -16
  148. package/dist/debugger/components/event-stream.d.ts +2 -1
  149. package/dist/debugger/components/event-stream.js +14 -74
  150. package/dist/debugger/components/follow-list.d.ts +19 -0
  151. package/dist/debugger/components/follow-list.js +96 -0
  152. package/dist/debugger/components/json-tree.d.ts +11 -0
  153. package/dist/debugger/components/json-tree.js +120 -0
  154. package/dist/debugger/components/json-view.js +2 -2
  155. package/dist/debugger/components/run-tree.js +53 -20
  156. package/dist/debugger/components/status-dot.d.ts +4 -0
  157. package/dist/debugger/components/status-dot.js +6 -2
  158. package/dist/debugger/context.d.ts +14 -0
  159. package/dist/debugger/context.js +17 -0
  160. package/dist/debugger/contracts.d.ts +7 -4
  161. package/dist/debugger/events/builtin-families.d.ts +3 -0
  162. package/dist/debugger/events/builtin-families.js +9 -0
  163. package/dist/debugger/events/catalog.d.ts +3 -4
  164. package/dist/debugger/events/catalog.js +27 -17
  165. package/dist/debugger/events/protocol-summarize.d.ts +1 -2
  166. package/dist/debugger/events/protocol-summarize.js +42 -24
  167. package/dist/debugger/index.d.ts +20 -6
  168. package/dist/debugger/index.js +19 -5
  169. package/dist/debugger/lib/cn.d.ts +1 -0
  170. package/dist/debugger/lib/cn.js +3 -0
  171. package/dist/debugger/lib/event-meta.d.ts +2 -3
  172. package/dist/debugger/lib/event-meta.js +6 -12
  173. package/dist/debugger/lib/json.d.ts +25 -0
  174. package/dist/debugger/lib/json.js +87 -0
  175. package/dist/debugger/lib/payload.d.ts +7 -0
  176. package/dist/debugger/lib/payload.js +11 -0
  177. package/dist/debugger/lib/time.d.ts +3 -0
  178. package/dist/debugger/lib/time.js +24 -0
  179. package/dist/debugger/plugin.d.ts +36 -0
  180. package/dist/debugger/plugin.js +14 -0
  181. package/dist/debugger/server/index.d.ts +14 -0
  182. package/dist/debugger/server/index.js +114 -0
  183. package/dist/debugger/shell/debugger-shell.d.ts +15 -0
  184. package/dist/debugger/shell/debugger-shell.js +43 -0
  185. package/dist/debugger/shell/definition-key.d.ts +3 -0
  186. package/dist/debugger/shell/definition-key.js +4 -0
  187. package/dist/debugger/shell/events-pane.d.ts +12 -0
  188. package/dist/debugger/shell/events-pane.js +25 -0
  189. package/dist/debugger/shell/projections-panel.d.ts +4 -0
  190. package/dist/debugger/shell/projections-panel.js +59 -0
  191. package/dist/debugger/shell/run-controls.d.ts +4 -0
  192. package/dist/debugger/shell/run-controls.js +72 -0
  193. package/dist/debugger/shell/run-search.d.ts +6 -0
  194. package/dist/debugger/shell/run-search.js +102 -0
  195. package/dist/debugger/shell/run-type-menu.d.ts +6 -0
  196. package/dist/debugger/shell/run-type-menu.js +11 -0
  197. package/dist/debugger/shell/schema-form.d.ts +31 -0
  198. package/dist/debugger/shell/schema-form.js +117 -0
  199. package/dist/debugger/shell/start-form.d.ts +3 -0
  200. package/dist/debugger/shell/start-form.js +75 -0
  201. package/dist/debugger/shell/use-start-run.d.ts +14 -0
  202. package/dist/debugger/shell/use-start-run.js +32 -0
  203. package/dist/debugger/shell/workspace.d.ts +6 -0
  204. package/dist/debugger/shell/workspace.js +15 -0
  205. package/dist/debugger/styles.css +111 -27
  206. package/dist/debugger/ui/button.d.ts +24 -0
  207. package/dist/debugger/ui/button.js +24 -0
  208. package/dist/debugger/ui/command.d.ts +9 -0
  209. package/dist/debugger/ui/command.js +24 -0
  210. package/dist/debugger/ui/dropdown-menu.d.ts +13 -0
  211. package/dist/debugger/ui/dropdown-menu.js +37 -0
  212. package/dist/debugger/ui/panel.d.ts +14 -0
  213. package/dist/debugger/ui/panel.js +16 -0
  214. package/dist/debugger/ui/popover.d.ts +7 -0
  215. package/dist/debugger/ui/popover.js +17 -0
  216. package/dist/debugger/ui/resizable.d.ts +7 -0
  217. package/dist/debugger/ui/resizable.js +14 -0
  218. package/dist/debugger/ui/scroll-area.d.ts +2 -1
  219. package/dist/debugger/ui/scroll-area.js +5 -3
  220. package/dist/debugger/ui/select.d.ts +10 -0
  221. package/dist/debugger/ui/select.js +21 -0
  222. package/dist/debugger/ui/tabs.js +2 -2
  223. package/dist/debugger/ui/textarea.d.ts +3 -0
  224. package/dist/debugger/ui/textarea.js +7 -0
  225. package/dist/evaluator/definitions-store.d.ts +11 -0
  226. package/dist/evaluator/definitions-store.js +8 -0
  227. package/dist/evaluator/definitions.d.ts +18 -0
  228. package/dist/evaluator/definitions.js +4 -0
  229. package/dist/evaluator/effects.d.ts +226 -0
  230. package/dist/evaluator/effects.js +132 -0
  231. package/dist/evaluator/evaluator.d.ts +24 -0
  232. package/dist/evaluator/evaluator.js +67 -0
  233. package/dist/evaluator/events.d.ts +59 -0
  234. package/dist/evaluator/events.js +21 -0
  235. package/dist/evaluator/index.d.ts +11 -0
  236. package/dist/evaluator/index.js +11 -0
  237. package/dist/evaluator/module.d.ts +606 -0
  238. package/dist/evaluator/module.js +25 -0
  239. package/dist/evaluator/projections.d.ts +50 -0
  240. package/dist/evaluator/projections.js +20 -0
  241. package/dist/evaluator/scope.d.ts +59 -0
  242. package/dist/evaluator/scope.js +7 -0
  243. package/dist/evaluator/signals.d.ts +3 -0
  244. package/dist/evaluator/signals.js +17 -0
  245. package/dist/evaluator/threads.d.ts +62 -0
  246. package/dist/evaluator/threads.js +117 -0
  247. package/dist/evaluator/types.d.ts +125 -0
  248. package/dist/evaluator/types.js +51 -0
  249. package/dist/projectors/delivery.d.ts +83 -0
  250. package/dist/projectors/delivery.js +182 -0
  251. package/dist/projectors/index-model.d.ts +1 -1
  252. package/dist/projectors/index-model.js +4 -6
  253. package/dist/projectors/index.d.ts +2 -0
  254. package/dist/projectors/index.js +2 -0
  255. package/dist/projectors/memory.d.ts +1 -1
  256. package/dist/projectors/memory.js +10 -8
  257. package/dist/projectors/postgres.js +44 -58
  258. package/dist/projectors/projector.d.ts +17 -0
  259. package/dist/projectors/projector.js +26 -1
  260. package/dist/projectors/sqlite-delivery.d.ts +4 -0
  261. package/dist/projectors/sqlite-delivery.js +147 -0
  262. package/dist/projectors/sqlite.js +23 -23
  263. package/dist/projectors/with-projectors.d.ts +7 -2
  264. package/dist/projectors/with-projectors.js +27 -28
  265. package/dist/react/notify.js +11 -8
  266. package/dist/react/react.d.ts +2 -3
  267. package/dist/react/react.js +14 -30
  268. package/dist/react/sse.d.ts +1 -1
  269. package/dist/react/sse.js +1 -1
  270. package/dist/react/store.d.ts +3 -3
  271. package/dist/react/store.js +109 -119
  272. package/dist/runtime/cancellation.d.ts +16 -0
  273. package/dist/runtime/cancellation.js +129 -0
  274. package/dist/runtime/deadline-transition-planner.d.ts +31 -0
  275. package/dist/runtime/deadline-transition-planner.js +139 -0
  276. package/dist/runtime/dispatch-effect.d.ts +3 -2
  277. package/dist/runtime/dispatch-effect.js +7 -13
  278. package/dist/runtime/errors.d.ts +51 -0
  279. package/dist/runtime/errors.js +39 -0
  280. package/dist/runtime/{runtime-helpers.d.ts → helpers.d.ts} +24 -4
  281. package/dist/runtime/{runtime-helpers.js → helpers.js} +56 -19
  282. package/dist/runtime/index.d.ts +3 -3
  283. package/dist/runtime/index.js +3 -3
  284. package/dist/runtime/ingress.d.ts +15 -0
  285. package/dist/runtime/ingress.js +42 -0
  286. package/dist/runtime/local-effect-executor.d.ts +21 -0
  287. package/dist/runtime/local-effect-executor.js +137 -0
  288. package/dist/runtime/looms.d.ts +30 -4
  289. package/dist/runtime/looms.js +57 -37
  290. package/dist/runtime/observer.d.ts +45 -0
  291. package/dist/runtime/observer.js +11 -0
  292. package/dist/runtime/repository.d.ts +55 -0
  293. package/dist/runtime/repository.js +293 -0
  294. package/dist/runtime/retry-policy.d.ts +16 -0
  295. package/dist/runtime/retry-policy.js +29 -0
  296. package/dist/runtime/run-execution-context.d.ts +30 -0
  297. package/dist/runtime/run-execution-context.js +56 -0
  298. package/dist/runtime/run-start.d.ts +4 -0
  299. package/dist/runtime/run-start.js +44 -0
  300. package/dist/runtime/runtime.d.ts +6 -87
  301. package/dist/runtime/runtime.js +248 -470
  302. package/dist/runtime/server/auth.d.ts +41 -0
  303. package/dist/runtime/server/auth.js +45 -0
  304. package/dist/runtime/server/debugger-host.d.ts +11 -0
  305. package/dist/runtime/server/debugger-host.js +32 -0
  306. package/dist/runtime/server/fetch-handler.d.ts +18 -0
  307. package/dist/runtime/server/fetch-handler.js +62 -0
  308. package/dist/runtime/server/http.d.ts +38 -0
  309. package/dist/runtime/server/http.js +66 -0
  310. package/dist/runtime/server/route-table.d.ts +55 -0
  311. package/dist/runtime/server/route-table.js +74 -0
  312. package/dist/runtime/server/routes/definitions.d.ts +3 -0
  313. package/dist/runtime/server/routes/definitions.js +20 -0
  314. package/dist/runtime/server/routes/effects.d.ts +3 -0
  315. package/dist/runtime/server/routes/effects.js +59 -0
  316. package/dist/runtime/server/routes/operations.d.ts +3 -0
  317. package/dist/runtime/server/routes/operations.js +14 -0
  318. package/dist/runtime/server/routes/runs.d.ts +3 -0
  319. package/dist/runtime/server/routes/runs.js +199 -0
  320. package/dist/runtime/server.d.ts +4 -8
  321. package/dist/runtime/server.js +6 -211
  322. package/dist/runtime/sse.d.ts +2 -1
  323. package/dist/runtime/sse.js +24 -17
  324. package/dist/runtime/types.d.ts +117 -0
  325. package/dist/runtime/types.js +1 -0
  326. package/dist/runtime/wake-engine.d.ts +20 -0
  327. package/dist/runtime/wake-engine.js +311 -0
  328. package/dist/runtime/wake-scheduler.d.ts +3 -4
  329. package/dist/runtime/wake-scheduler.js +25 -31
  330. package/dist/runtime/worker-callbacks.d.ts +16 -0
  331. package/dist/runtime/worker-callbacks.js +167 -0
  332. package/dist/runtime/worker-effect-dispatch.d.ts +36 -0
  333. package/dist/runtime/worker-effect-dispatch.js +126 -0
  334. package/dist/s2/config.d.ts +1 -1
  335. package/dist/s2/config.js +1 -1
  336. package/dist/s2/lite.js +70 -82
  337. package/dist/s2/pagination.d.ts +15 -0
  338. package/dist/s2/pagination.js +36 -0
  339. package/dist/s2/projector.js +6 -5
  340. package/dist/s2/snapshot-store.js +188 -161
  341. package/dist/s2/store.d.ts +3 -21
  342. package/dist/s2/store.js +71 -165
  343. package/dist/testing/index.d.ts +15 -0
  344. package/dist/testing/index.js +53 -16
  345. package/dist/workflow/debugger/index.d.ts +4 -0
  346. package/dist/workflow/debugger/index.js +11 -0
  347. package/dist/workflow/debugger/nodes-view.d.ts +3 -0
  348. package/dist/workflow/debugger/nodes-view.js +13 -0
  349. package/dist/workflow/debugger/summarize.d.ts +2 -0
  350. package/dist/workflow/debugger/summarize.js +30 -0
  351. package/dist/workflow/definitions-store.d.ts +2 -3
  352. package/dist/workflow/definitions-store.js +2 -2
  353. package/dist/workflow/definitions.d.ts +78 -22
  354. package/dist/workflow/definitions.js +80 -14
  355. package/dist/workflow/effects.d.ts +453 -107
  356. package/dist/workflow/effects.js +214 -115
  357. package/dist/workflow/events.d.ts +149 -5
  358. package/dist/workflow/events.js +27 -5
  359. package/dist/workflow/graph.d.ts +56 -0
  360. package/dist/workflow/graph.js +207 -0
  361. package/dist/workflow/index.d.ts +1 -0
  362. package/dist/workflow/index.js +1 -0
  363. package/dist/workflow/module.d.ts +1047 -266
  364. package/dist/workflow/projections.d.ts +14 -12
  365. package/dist/workflow/projections.js +30 -8
  366. package/dist/workflow/scope.d.ts +146 -4
  367. package/dist/workflow/threads.d.ts +383 -155
  368. package/dist/workflow/threads.js +308 -110
  369. package/package.json +26 -2
  370. package/dist/debugger/events/domain-summarize.d.ts +0 -3
  371. package/dist/debugger/events/domain-summarize.js +0 -107
  372. package/dist/debugger/events/family.d.ts +0 -8
  373. package/dist/debugger/events/family.js +0 -44
  374. package/dist/runtime/events-api.d.ts +0 -4
  375. package/dist/runtime/events-api.js +0 -84
@@ -1,24 +1,54 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ChevronDown, ChevronRight } from 'lucide-react';
3
- import { memo, useCallback, useState } from 'react';
2
+ import { useVirtualizer } from '@tanstack/react-virtual';
3
+ import { ChevronRight } from 'lucide-react';
4
+ import { useCallback, useMemo, useRef, useState } from 'react';
4
5
  import { cn, shortId } from '../lib/cn.js';
5
- import { statusClass } from '../lib/status.js';
6
- import { StatusDot } from './status-dot.js';
7
- const NodeRow = memo(function NodeRow({ node, depth, selected, counts, collapsed, onToggle, onSelect, }) {
6
+ import { PanelHeader, PanelTitle } from '../ui/panel.js';
7
+ import { ScrollArea } from '../ui/scroll-area.js';
8
+ import { StatusBadge, StatusDot } from './status-dot.js';
9
+ const ROW_HEIGHT = 28;
10
+ const INDENT = 14;
11
+ function flatten(root, collapsed) {
12
+ const rows = [];
13
+ if (!root) {
14
+ return rows;
15
+ }
16
+ const stack = [{ node: root, depth: 0 }];
17
+ while (stack.length > 0) {
18
+ const next = stack.pop();
19
+ if (!next) {
20
+ break;
21
+ }
22
+ rows.push(next);
23
+ if (!collapsed.has(next.node.threadId)) {
24
+ for (let index = next.node.children.length - 1; index >= 0; index--) {
25
+ const child = next.node.children[index];
26
+ if (child) {
27
+ stack.push({ node: child, depth: next.depth + 1 });
28
+ }
29
+ }
30
+ }
31
+ }
32
+ return rows;
33
+ }
34
+ function NodeRow({ row, selected, count, collapsed, onToggle, onSelect, }) {
35
+ const { node, depth } = row;
8
36
  const hasChildren = node.children.length > 0;
9
- const isCollapsed = collapsed.has(node.threadId);
10
- const count = counts.get(node.threadId) ?? 0;
11
- const handleToggle = useCallback(() => {
12
- onToggle(node.threadId);
13
- }, [onToggle, node.threadId]);
14
- const handleSelect = useCallback(() => {
15
- onSelect(node.threadId);
16
- }, [onSelect, node.threadId]);
17
- return (_jsxs("li", { className: "relative", children: [_jsxs("div", { className: cn('flex items-center gap-1 rounded-md py-0.5 pr-1 text-xs transition-colors', selected === node.threadId ? 'bg-accent font-medium' : 'hover:bg-accent/50'), style: { paddingLeft: 8 + depth * 14 }, children: [hasChildren ? (_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground size-4 shrink-0", onClick: handleToggle, "aria-label": isCollapsed ? 'Expand thread' : 'Collapse thread', children: isCollapsed ? _jsx(ChevronRight, { className: "size-3" }) : _jsx(ChevronDown, { className: "size-3" }) })) : (_jsx("span", { className: "size-4 shrink-0" })), _jsxs("button", { type: "button", className: "flex min-w-0 flex-1 items-center gap-1.5 text-left", onClick: handleSelect, children: [_jsx(StatusDot, { status: node.status }), _jsxs("span", { className: "truncate", children: [_jsx("span", { className: "text-foreground font-medium", children: node.definitionName }), _jsxs("span", { className: "text-muted-foreground ml-1 font-mono text-[10px]", children: ["(", node.kind, ")"] })] }), _jsx("span", { className: cn('shrink-0 text-[10px]', statusClass(node.status)), children: node.status }), _jsx("span", { className: "text-muted-foreground ml-auto shrink-0 font-mono text-[10px]", children: count })] })] }), hasChildren && !isCollapsed ? (_jsx("ul", { className: "relative", children: node.children.map((child) => (_jsx(NodeRow, { node: child, depth: depth + 1, selected: selected, counts: counts, collapsed: collapsed, onToggle: onToggle, onSelect: onSelect }, child.threadId))) })) : null] }));
18
- });
37
+ return (_jsxs("div", { className: cn('group/row relative flex h-7 items-center rounded-md pr-2 text-xs', selected ? 'bg-accent text-foreground' : 'hover:bg-accent/50'), style: { paddingLeft: 4 + depth * INDENT }, title: `${node.definitionName} · ${node.kind} · ${node.status}`, children: [Array.from({ length: depth }, (_, level) => (_jsx("span", { "aria-hidden": true, className: "bg-border absolute inset-y-0 w-px", style: { left: 12 + level * INDENT } }, level))), hasChildren ? (_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground hover:bg-background/40 flex size-4 shrink-0 items-center justify-center rounded-sm", onClick: () => onToggle(node.threadId), "aria-label": collapsed ? 'Expand thread' : 'Collapse thread', "aria-expanded": !collapsed, children: _jsx(ChevronRight, { className: cn('ease-snappy size-3 transition-transform duration-100', !collapsed && 'rotate-90') }) })) : (_jsx("span", { className: "size-4 shrink-0" })), _jsxs("button", { type: "button", className: "flex h-full min-w-0 flex-1 items-center gap-2 pl-1 text-left", onClick: () => onSelect(node.threadId), children: [_jsx(StatusDot, { status: node.status }), _jsxs("span", { className: "min-w-0 truncate", children: [_jsx("span", { className: "font-medium", children: node.definitionName }), _jsx("span", { className: "text-muted-foreground ml-1.5 font-mono text-[10px]", children: node.kind })] }), _jsx("span", { className: "text-muted-foreground ml-auto shrink-0 font-mono text-[10px] tabular-nums", children: count })] })] }));
38
+ }
19
39
  export function RunTree({ runId, runStatus, tree, eventCounts, totalEventCount, selectedThread, onSelectThread, formatRunLabel = shortId, showHeading = true, }) {
20
- const [collapsed, setCollapsed] = useState(new Set());
40
+ const [collapsed, setCollapsed] = useState(() => new Set());
21
41
  const runCount = totalEventCount ?? eventCounts.get('run') ?? 0;
42
+ const rows = useMemo(() => flatten(tree.root, collapsed), [tree.root, collapsed]);
43
+ const parentRef = useRef(null);
44
+ const virtualizer = useVirtualizer({
45
+ count: rows.length,
46
+ getScrollElement: () => parentRef.current,
47
+ estimateSize: () => ROW_HEIGHT,
48
+ overscan: 12,
49
+ getItemKey: (index) => rows[index]?.node.threadId ?? index,
50
+ useFlushSync: false,
51
+ });
22
52
  const toggle = useCallback((id) => {
23
53
  setCollapsed((prev) => {
24
54
  const next = new Set(prev);
@@ -31,8 +61,11 @@ export function RunTree({ runId, runStatus, tree, eventCounts, totalEventCount,
31
61
  return next;
32
62
  });
33
63
  }, []);
34
- const handleSelectRoot = useCallback(() => {
35
- onSelectThread(undefined);
36
- }, [onSelectThread]);
37
- return (_jsxs("div", { children: [showHeading && (_jsx("h2", { className: "text-muted-foreground px-2 pb-1 text-[11px] font-medium tracking-wide uppercase", children: "Run tree" })), _jsxs("button", { type: "button", onClick: handleSelectRoot, className: cn('mb-0.5 flex w-full items-center gap-1.5 rounded-md px-2 py-1 text-left text-xs', !selectedThread ? 'bg-accent' : 'hover:bg-accent/50'), children: [_jsx(StatusDot, { status: runStatus }), _jsx("span", { className: "truncate font-mono", children: formatRunLabel(runId) }), _jsx("span", { className: cn('ml-auto', statusClass(runStatus)), children: runStatus }), _jsx("span", { className: "text-muted-foreground font-mono text-[10px]", children: runCount })] }), tree.root ? (_jsx("ul", { children: _jsx(NodeRow, { node: tree.root, depth: 0, selected: selectedThread, counts: eventCounts, collapsed: collapsed, onToggle: toggle, onSelect: onSelectThread }) })) : (_jsx("p", { className: "text-muted-foreground px-2 text-xs", children: "Waiting for threads\u2026" }))] }));
64
+ return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [showHeading ? (_jsxs(PanelHeader, { children: [_jsx(PanelTitle, { children: "Run tree" }), _jsx(StatusBadge, { status: runStatus, className: "ml-auto" })] })) : null, _jsx("div", { className: "px-2 pt-2", children: _jsxs("button", { type: "button", onClick: () => onSelectThread(undefined), className: cn('flex h-7 w-full items-center gap-2 rounded-md px-2 text-left text-xs', !selectedThread ? 'bg-accent text-foreground' : 'hover:bg-accent/50'), children: [_jsx("span", { className: "text-muted-foreground", children: "All threads" }), _jsx("span", { className: "text-muted-foreground/70 truncate font-mono text-[10px]", children: formatRunLabel(runId) }), _jsx("span", { className: "text-muted-foreground ml-auto font-mono text-[10px] tabular-nums", children: runCount })] }) }), rows.length === 0 ? (_jsx("p", { className: "text-muted-foreground px-4 py-2 text-xs", children: "Waiting for threads\u2026" })) : (_jsx(ScrollArea, { viewportRef: parentRef, className: "min-h-0 flex-1", children: _jsx("div", { className: "relative mx-2 mb-2", style: { height: virtualizer.getTotalSize() }, children: virtualizer.getVirtualItems().map((item) => {
65
+ const row = rows[item.index];
66
+ if (!row) {
67
+ return null;
68
+ }
69
+ return (_jsx("div", { className: "absolute top-0 left-0 w-full", style: { transform: `translateY(${item.start}px)`, height: ROW_HEIGHT }, children: _jsx(NodeRow, { row: row, selected: selectedThread === row.node.threadId, count: eventCounts.get(row.node.threadId) ?? 0, collapsed: collapsed.has(row.node.threadId), onToggle: toggle, onSelect: onSelectThread }) }, item.key));
70
+ }) }) }))] }));
38
71
  }
@@ -1,3 +1,7 @@
1
1
  export declare function StatusDot({ status }: {
2
2
  status: string;
3
3
  }): import("react").JSX.Element;
4
+ export declare function StatusBadge({ status, className }: {
5
+ status: string;
6
+ className?: string;
7
+ }): import("react").JSX.Element;
@@ -1,5 +1,9 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { statusDotClass } from '../lib/status.js';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ import { statusClass, statusDotClass } from '../lib/status.js';
3
4
  export function StatusDot({ status }) {
4
5
  return _jsx("span", { className: statusDotClass(status), "aria-hidden": true });
5
6
  }
7
+ export function StatusBadge({ status, className }) {
8
+ return (_jsxs("span", { className: cn('inline-flex h-5 shrink-0 items-center gap-1.5 rounded-full bg-current/10 px-2 text-[11px] font-medium', statusClass(status), className), children: [_jsx(StatusDot, { status: status }), status] }));
9
+ }
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type LoomsClient } from '@swirls/looms/client';
3
+ import type { DebuggerPlugin } from './plugin';
4
+ export interface DebuggerContextValue {
5
+ readonly client: LoomsClient;
6
+ readonly plugins: readonly DebuggerPlugin[];
7
+ }
8
+ /** Supplies one Looms host to both the API client and the run stores. */
9
+ export declare function DebuggerProvider({ endpoint, plugins, children, }: {
10
+ endpoint?: string;
11
+ plugins: readonly DebuggerPlugin[];
12
+ children: ReactNode;
13
+ }): import("react").JSX.Element;
14
+ export declare function useDebugger(): DebuggerContextValue;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from 'react';
3
+ import { createLoomsClient } from '@swirls/looms/client';
4
+ import { LoomsProvider } from '@swirls/looms/react';
5
+ const DebuggerContext = createContext(null);
6
+ /** Supplies one Looms host to both the API client and the run stores. */
7
+ export function DebuggerProvider({ endpoint = '', plugins, children, }) {
8
+ const value = useMemo(() => ({ client: createLoomsClient({ baseUrl: endpoint }), plugins }), [endpoint, plugins]);
9
+ return (_jsx(LoomsProvider, { endpoint: endpoint, children: _jsx(DebuggerContext.Provider, { value: value, children: children }) }));
10
+ }
11
+ export function useDebugger() {
12
+ const value = useContext(DebuggerContext);
13
+ if (!value) {
14
+ throw new Error('useDebugger must be used within DebuggerProvider');
15
+ }
16
+ return value;
17
+ }
@@ -1,12 +1,15 @@
1
1
  import type { EventEnvelope, JsonValue, ReplayStep, ThreadTree } from '@swirls/looms/core';
2
- import type { EventFamily, EventSummary } from './events/family';
2
+ export type EventSummary = {
3
+ title: string;
4
+ detail?: string;
5
+ };
3
6
  export type DebuggerEvent<TType extends string = string> = Pick<EventEnvelope<TType>, 'id' | 'runId' | 'seq' | 'ts' | 'type' | 'payload' | 'threadId' | 'causationId' | 'ephemeral'> & Partial<Pick<EventEnvelope<TType>, 'parentThreadId' | 'correlationId' | 'effectId' | 'origin'>>;
4
7
  export type EventStreamCatalog<TEvent extends DebuggerEvent = DebuggerEvent> = {
5
8
  families: readonly string[];
6
9
  familyOf: (type: string) => string;
7
- familyClass: (family: string) => string;
10
+ familyColor: (family: string) => string;
8
11
  summarize: (event: TEvent) => EventSummary;
9
- searchText?: (event: TEvent) => string;
12
+ searchText: (event: TEvent) => string;
10
13
  };
11
14
  export type ReplayLoader = (input: {
12
15
  runId: string;
@@ -19,4 +22,4 @@ export type RunTreeModel = {
19
22
  eventCounts: Map<string, number>;
20
23
  totalEventCount?: number;
21
24
  };
22
- export type { EventFamily, EventSummary, JsonValue, ReplayStep, ThreadTree };
25
+ export type { JsonValue, ReplayStep, ThreadTree };
@@ -0,0 +1,3 @@
1
+ import type { EventFamilyView } from '../plugin';
2
+ export declare const runtimeFamily: EventFamilyView;
3
+ export declare const builtinFamilies: readonly EventFamilyView[];
@@ -0,0 +1,9 @@
1
+ export const runtimeFamily = {
2
+ family: 'runtime',
3
+ prefix: 'runtime.',
4
+ color: 'oklch(0.76 0.13 155)',
5
+ };
6
+ export const builtinFamilies = [
7
+ { family: 'wait', prefix: 'runtime.wait', color: 'oklch(0.8 0.14 85)' },
8
+ runtimeFamily,
9
+ ];
@@ -1,6 +1,5 @@
1
1
  import type { DebuggerEvent, EventStreamCatalog } from '../contracts';
2
- import { type EventSummary } from './family';
3
- export declare function summarizeEvent(event: DebuggerEvent): EventSummary;
4
- export declare function searchText<TEvent extends DebuggerEvent>(event: TEvent, summarize?: (event: TEvent) => EventSummary): string;
5
- export declare function createDefaultCatalog<TEvent extends DebuggerEvent = DebuggerEvent>(): EventStreamCatalog<TEvent>;
2
+ import type { DebuggerPlugin } from '../plugin';
3
+ /** Each event type belongs to the family view with the longest matching prefix. */
4
+ export declare function createEventCatalog<TEvent extends DebuggerEvent = DebuggerEvent>(plugins?: readonly DebuggerPlugin[]): EventStreamCatalog<TEvent>;
6
5
  export declare const defaultEventCatalog: EventStreamCatalog;
@@ -1,27 +1,37 @@
1
1
  import { compactJson } from '../lib/cn.js';
2
- import { summarizeDomainEvent } from './domain-summarize.js';
3
- import { DEFAULT_FAMILIES, familyClass, familyFromPrefix } from './family.js';
2
+ import { builtinFamilies, runtimeFamily } from './builtin-families.js';
4
3
  import { summarizeProtocolEvent } from './protocol-summarize.js';
5
- export function summarizeEvent(event) {
6
- return (summarizeProtocolEvent(event) ??
7
- summarizeDomainEvent(event) ?? {
8
- title: event.type,
9
- detail: compactJson(event.payload),
10
- });
4
+ function prefixOf(view) {
5
+ return view.prefix ?? `${view.family}.`;
11
6
  }
12
- export function searchText(event, summarize = summarizeEvent) {
13
- const summary = summarize(event);
7
+ function searchText(event, summary) {
14
8
  return [event.type, event.threadId ?? '', summary.title, summary.detail ?? '', event.id]
15
9
  .join(' ')
16
10
  .toLowerCase();
17
11
  }
18
- export function createDefaultCatalog() {
12
+ /** Each event type belongs to the family view with the longest matching prefix. */
13
+ export function createEventCatalog(plugins = []) {
14
+ const views = [...plugins.flatMap((plugin) => plugin.families ?? []), ...builtinFamilies];
15
+ // ES2022 has no Array#toSorted. `views` is a fresh array.
16
+ // oxlint-disable-next-line unicorn/no-array-sort
17
+ const byPrefix = views.sort((left, right) => prefixOf(right).length - prefixOf(left).length);
18
+ const colors = new Map(views.map((view) => [view.family, view.color]));
19
+ function viewOf(type) {
20
+ return byPrefix.find((view) => type.startsWith(prefixOf(view))) ?? runtimeFamily;
21
+ }
22
+ function summarize(event) {
23
+ return (summarizeProtocolEvent(event) ??
24
+ viewOf(event.type).summarize?.(event) ?? {
25
+ title: event.type,
26
+ detail: compactJson(event.payload),
27
+ });
28
+ }
19
29
  return {
20
- families: DEFAULT_FAMILIES,
21
- familyOf: familyFromPrefix,
22
- familyClass,
23
- summarize: (event) => summarizeEvent(event),
24
- searchText: (event) => searchText(event),
30
+ families: [...new Set(views.map((view) => view.family))],
31
+ familyOf: (type) => viewOf(type).family,
32
+ familyColor: (family) => colors.get(family) ?? runtimeFamily.color,
33
+ summarize,
34
+ searchText: (event) => searchText(event, summarize(event)),
25
35
  };
26
36
  }
27
- export const defaultEventCatalog = createDefaultCatalog();
37
+ export const defaultEventCatalog = createEventCatalog();
@@ -1,3 +1,2 @@
1
- import type { DebuggerEvent } from '../contracts';
2
- import type { EventSummary } from './family';
1
+ import type { DebuggerEvent, EventSummary } from '../contracts';
3
2
  export declare function summarizeProtocolEvent(event: DebuggerEvent): EventSummary | undefined;
@@ -1,43 +1,37 @@
1
- import { isJsonNumber, isJsonObject, isJsonString, isProtocolType, } from '@swirls/looms/core';
1
+ import { isJsonNumber, isJsonString, isProtocolType } from '@swirls/looms/core';
2
2
  import { compactJson } from '../lib/cn.js';
3
- function obj(value) {
4
- return isJsonObject(value) ? value : {};
5
- }
6
- function text(value) {
7
- return isJsonString(value) ? value : undefined;
8
- }
9
- function numeric(value) {
10
- return isJsonNumber(value) ? String(value) : undefined;
11
- }
3
+ import { jsonFields, jsonNumberText, jsonText } from '../lib/payload.js';
12
4
  export function summarizeProtocolEvent(event) {
13
5
  if (!isProtocolType(event.type)) {
14
6
  return undefined;
15
7
  }
16
- const payload = obj(event.payload);
8
+ const payload = jsonFields(event.payload);
17
9
  switch (event.type) {
18
10
  case 'runtime.run.started':
19
11
  return {
20
12
  title: 'run started',
21
- detail: `${text(payload.kind) ?? 'run'}:${text(payload.definitionName) ?? 'unknown'}`,
13
+ detail: `${jsonText(payload.kind) ?? 'run'}:${jsonText(payload.definitionName) ?? 'unknown'}`,
22
14
  };
23
15
  case 'runtime.run.completed':
24
16
  return {
25
- title: text(payload.error) ? 'run failed' : 'run completed',
26
- detail: text(payload.error) ?? compactJson(payload.output ?? null),
17
+ title: jsonText(payload.error) ? 'run failed' : 'run completed',
18
+ detail: jsonText(payload.error) ?? compactJson(payload.output ?? null),
27
19
  };
20
+ case 'runtime.run.cancelled':
21
+ return { title: 'run cancelled', detail: jsonText(payload.reason) };
28
22
  case 'runtime.thread.started':
29
23
  return {
30
24
  title: 'thread started',
31
- detail: `${text(payload.kind) ?? 'thread'}:${text(payload.definitionName) ?? 'unknown'}`,
25
+ detail: `${jsonText(payload.kind) ?? 'thread'}:${jsonText(payload.definitionName) ?? 'unknown'}`,
32
26
  };
33
27
  case 'runtime.thread.completed':
34
28
  return { title: 'thread completed', detail: compactJson(payload.output ?? null) };
35
29
  case 'runtime.thread.failed':
36
- return { title: 'thread failed', detail: text(payload.error) };
30
+ return { title: 'thread failed', detail: jsonText(payload.error) };
37
31
  case 'runtime.thread.cancelled':
38
- return { title: 'thread cancelled', detail: text(payload.reason) };
32
+ return { title: 'thread cancelled', detail: jsonText(payload.reason) };
39
33
  case 'runtime.wait.registered': {
40
- const on = obj(payload.on ?? null);
34
+ const on = jsonFields(payload.on ?? null);
41
35
  const type = on.type;
42
36
  const detail = isJsonString(type)
43
37
  ? type
@@ -49,22 +43,46 @@ export function summarizeProtocolEvent(event) {
49
43
  return { title: 'wait registered', detail };
50
44
  }
51
45
  case 'runtime.wait.satisfied': {
52
- const waited = obj(payload.event ?? null);
53
- return { title: 'wait satisfied', detail: text(waited.type) };
46
+ const waited = jsonFields(payload.event ?? null);
47
+ return { title: 'wait satisfied', detail: jsonText(waited.type) };
54
48
  }
55
49
  case 'runtime.timer.set':
56
- return { title: 'timer set', detail: numeric(payload.wakeAt) };
50
+ return { title: 'timer set', detail: jsonNumberText(payload.wakeAt) };
57
51
  case 'runtime.timer.fired':
58
52
  return { title: 'timer fired' };
59
53
  case 'runtime.effect.failed':
60
- return { title: 'effect failed', detail: text(payload.error) };
54
+ return { title: 'effect failed', detail: jsonText(payload.error) };
55
+ case 'runtime.effect.attempt.started':
56
+ return { title: 'effect attempt started', detail: jsonNumberText(payload.attempt) };
57
+ case 'runtime.effect.queued':
58
+ return { title: 'effect queued', detail: jsonNumberText(payload.attempt) };
59
+ case 'runtime.effect.dispatched':
60
+ return { title: 'effect dispatched', detail: jsonNumberText(payload.attempt) };
61
+ case 'runtime.effect.worker.started':
62
+ return { title: 'worker started effect', detail: jsonNumberText(payload.attempt) };
63
+ case 'runtime.effect.heartbeat':
64
+ return { title: 'effect heartbeat', detail: jsonNumberText(payload.attempt) };
65
+ case 'runtime.effect.completed':
66
+ return { title: 'effect completed', detail: jsonNumberText(payload.attempt) };
67
+ case 'runtime.effect.cancel.requested':
68
+ return { title: 'effect cancellation requested', detail: jsonNumberText(payload.attempt) };
69
+ case 'runtime.effect.cancelled':
70
+ return { title: 'effect cancelled', detail: jsonNumberText(payload.attempt) };
71
+ case 'runtime.effect.timed_out':
72
+ return { title: 'effect timed out', detail: jsonText(payload.timeout) };
73
+ case 'runtime.effect.ambiguous':
74
+ return { title: 'effect outcome ambiguous', detail: jsonText(payload.error) };
75
+ case 'runtime.effect.retry.scheduled':
76
+ return { title: 'effect retry scheduled', detail: jsonText(payload.error) };
61
77
  case 'runtime.snapshot.taken':
62
- return { title: 'snapshot', detail: `seq ${numeric(payload.seq) ?? ''}` };
78
+ return { title: 'snapshot', detail: `seq ${jsonNumberText(payload.seq) ?? ''}` };
63
79
  case 'runtime.signal.received':
64
80
  return { title: 'signal', detail: compactJson(event.payload) };
81
+ case 'runtime.thread.cancel.requested':
82
+ return { title: 'thread cancellation requested', detail: jsonText(payload.threadId) };
65
83
  default: {
66
84
  const exhaustiveType = event.type;
67
- return { title: 'event', detail: compactJson(obj(exhaustiveType)) };
85
+ return { title: 'event', detail: compactJson(jsonFields(exhaustiveType)) };
68
86
  }
69
87
  }
70
88
  }
@@ -1,17 +1,31 @@
1
- export type { DebuggerEvent, EventFamily, EventStreamCatalog, EventSummary, ReplayLoader, ReplayStep, RunTreeModel, ThreadTree, } from './contracts';
2
- export { DEFAULT_FAMILIES, familyClass, familyFromPrefix } from './events/family';
1
+ export type { DebuggerEvent, EventStreamCatalog, EventSummary, ReplayLoader, ReplayStep, RunTreeModel, ThreadTree, } from './contracts';
2
+ export { createEventCatalog, defaultEventCatalog } from './events/catalog';
3
3
  export { summarizeProtocolEvent } from './events/protocol-summarize';
4
- export { summarizeDomainEvent } from './events/domain-summarize';
5
- export { createDefaultCatalog, defaultEventCatalog, searchText, summarizeEvent, } from './events/catalog';
6
- export { cn, compactJson, shortId } from './lib/cn';
4
+ export { DebuggerProvider, useDebugger, type DebuggerContextValue } from './context';
5
+ export { projectionFor, workspaceFor, type DebuggerPlugin, type EventFamilyView, type ProjectionView, type WorkspaceContext, type WorkspaceView, } from './plugin';
6
+ export { DebuggerShell, type DebuggerSelection } from './shell/debugger-shell';
7
+ export { StartForm } from './shell/start-form';
8
+ export { useStartRun, type StartRun } from './shell/use-start-run';
9
+ export { formInput, inputForm, messageInput, type FormField, type FormValues, type InputForm, } from './shell/schema-form';
10
+ export { cn, compactJson, errorMessage, shortId } from './lib/cn';
11
+ export { jsonFields, jsonNumberText, jsonText } from './lib/payload';
7
12
  export { statusClass, statusDotClass, type StatusKind } from './lib/status';
8
13
  export { countEventsByThread, runStatusFromEvents, startedAtFromEvents } from './lib/event-counts';
9
14
  export { projectRunView, type ProjectedRunView } from './lib/project-run';
10
- export { StatusDot } from './components/status-dot';
15
+ export { StatusBadge, StatusDot } from './components/status-dot';
11
16
  export { JsonView } from './components/json-view';
17
+ export { JsonTree } from './components/json-tree';
18
+ export { parseStructuredJson } from './lib/json';
19
+ export { FollowList } from './components/follow-list';
20
+ export { Composer } from './components/composer';
12
21
  export { RunTree } from './components/run-tree';
13
22
  export { EventStream } from './components/event-stream';
14
23
  export { EventInspector } from './components/event-inspector';
15
24
  export { DebuggerSplit } from './components/debugger-split';
25
+ export { Button, type ButtonSize, type ButtonVariant } from './ui/button';
16
26
  export { Checkbox } from './ui/checkbox';
27
+ export { Input } from './ui/input';
28
+ export { Textarea } from './ui/textarea';
29
+ export { EmptyState, Kbd, PanelHeader, PanelTitle } from './ui/panel';
30
+ export { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
17
31
  export { ScrollArea, ScrollBar } from './ui/scroll-area';
@@ -1,16 +1,30 @@
1
- export { DEFAULT_FAMILIES, familyClass, familyFromPrefix } from './events/family.js';
1
+ export { createEventCatalog, defaultEventCatalog } from './events/catalog.js';
2
2
  export { summarizeProtocolEvent } from './events/protocol-summarize.js';
3
- export { summarizeDomainEvent } from './events/domain-summarize.js';
4
- export { createDefaultCatalog, defaultEventCatalog, searchText, summarizeEvent, } from './events/catalog.js';
5
- export { cn, compactJson, shortId } from './lib/cn.js';
3
+ export { DebuggerProvider, useDebugger } from './context.js';
4
+ export { projectionFor, workspaceFor, } from './plugin.js';
5
+ export { DebuggerShell } from './shell/debugger-shell.js';
6
+ export { StartForm } from './shell/start-form.js';
7
+ export { useStartRun } from './shell/use-start-run.js';
8
+ export { formInput, inputForm, messageInput, } from './shell/schema-form.js';
9
+ export { cn, compactJson, errorMessage, shortId } from './lib/cn.js';
10
+ export { jsonFields, jsonNumberText, jsonText } from './lib/payload.js';
6
11
  export { statusClass, statusDotClass } from './lib/status.js';
7
12
  export { countEventsByThread, runStatusFromEvents, startedAtFromEvents } from './lib/event-counts.js';
8
13
  export { projectRunView } from './lib/project-run.js';
9
- export { StatusDot } from './components/status-dot.js';
14
+ export { StatusBadge, StatusDot } from './components/status-dot.js';
10
15
  export { JsonView } from './components/json-view.js';
16
+ export { JsonTree } from './components/json-tree.js';
17
+ export { parseStructuredJson } from './lib/json.js';
18
+ export { FollowList } from './components/follow-list.js';
19
+ export { Composer } from './components/composer.js';
11
20
  export { RunTree } from './components/run-tree.js';
12
21
  export { EventStream } from './components/event-stream.js';
13
22
  export { EventInspector } from './components/event-inspector.js';
14
23
  export { DebuggerSplit } from './components/debugger-split.js';
24
+ export { Button } from './ui/button.js';
15
25
  export { Checkbox } from './ui/checkbox.js';
26
+ export { Input } from './ui/input.js';
27
+ export { Textarea } from './ui/textarea.js';
28
+ export { EmptyState, Kbd, PanelHeader, PanelTitle } from './ui/panel.js';
29
+ export { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select.js';
16
30
  export { ScrollArea, ScrollBar } from './ui/scroll-area.js';
@@ -3,3 +3,4 @@ import type { JsonValue } from '@swirls/looms/core';
3
3
  export declare function cn(...inputs: ClassValue[]): string;
4
4
  export declare function shortId(id: string): string;
5
5
  export declare function compactJson(value: JsonValue): string;
6
+ export declare function errorMessage(cause: unknown): string;
@@ -15,3 +15,6 @@ export function compactJson(value) {
15
15
  }
16
16
  return text.length > 96 ? `${text.slice(0, 93)}…` : text;
17
17
  }
18
+ export function errorMessage(cause) {
19
+ return cause instanceof Error ? cause.message : String(cause);
20
+ }
@@ -1,8 +1,7 @@
1
- import type { DebuggerEvent, EventStreamCatalog } from '../contracts';
2
- import type { EventSummary } from '../events/family';
1
+ import type { DebuggerEvent, EventStreamCatalog, EventSummary } from '../contracts';
3
2
  export interface CachedEventMeta {
4
3
  summary: EventSummary;
5
4
  searchText: string;
6
5
  family: string;
7
6
  }
8
- export declare function getEventMeta<TEvent extends DebuggerEvent>(event: TEvent, catalog?: EventStreamCatalog<TEvent>): CachedEventMeta;
7
+ export declare function getEventMeta<TEvent extends DebuggerEvent>(event: TEvent, catalog: EventStreamCatalog<TEvent>): CachedEventMeta;
@@ -1,20 +1,14 @@
1
- import { searchText, summarizeEvent } from '../events/catalog.js';
2
1
  const metaCache = new WeakMap();
3
2
  export function getEventMeta(event, catalog) {
4
3
  const existing = metaCache.get(event);
5
4
  if (existing && existing.catalog === catalog) {
6
5
  return existing.meta;
7
6
  }
8
- const family = catalog ? catalog.familyOf(event.type) : 'runtime';
9
- const summary = catalog ? catalog.summarize(event) : summarizeEvent(event);
10
- const text = catalog?.searchText
11
- ? catalog.searchText(event)
12
- : searchText(event, catalog ? catalog.summarize : summarizeEvent);
13
- const meta = { summary, searchText: text, family };
14
- metaCache.set(event, {
15
- // SAFETY: EventStreamCatalog is covariant over event for cache identity compares.
16
- catalog: catalog,
17
- meta,
18
- });
7
+ const meta = {
8
+ summary: catalog.summarize(event),
9
+ searchText: catalog.searchText(event),
10
+ family: catalog.familyOf(event.type),
11
+ };
12
+ metaCache.set(event, { catalog, meta });
19
13
  return meta;
20
14
  }
@@ -0,0 +1,25 @@
1
+ import { type JsonObject, type JsonValue } from '@swirls/looms/core';
2
+ export type JsonNode = {
3
+ readonly kind: 'object';
4
+ readonly value: JsonObject;
5
+ } | {
6
+ readonly kind: 'array';
7
+ readonly value: readonly JsonValue[];
8
+ } | {
9
+ readonly kind: 'string';
10
+ readonly value: string;
11
+ } | {
12
+ readonly kind: 'number';
13
+ readonly value: number;
14
+ } | {
15
+ readonly kind: 'boolean';
16
+ readonly value: boolean;
17
+ } | {
18
+ readonly kind: 'null';
19
+ };
20
+ export declare function jsonNode(value: JsonValue): JsonNode;
21
+ /** Parses text that holds a JSON object or array; plain strings and scalars stay text. */
22
+ export declare function parseStructuredJson(text: string): JsonObject | readonly JsonValue[] | undefined;
23
+ export declare function jsonEntries(node: JsonNode): readonly (readonly [string, JsonValue])[];
24
+ /** One-line summary shown beside a collapsed object or array. */
25
+ export declare function jsonPreview(node: JsonNode, budget?: number): string;
@@ -0,0 +1,87 @@
1
+ import { Option, Predicate, Schema } from 'effect';
2
+ import { isJsonObject } from '@swirls/looms/core';
3
+ const decodeJsonText = Schema.decodeOption(Schema.fromJsonString(Schema.Json));
4
+ export function jsonNode(value) {
5
+ if (value === null) {
6
+ return { kind: 'null' };
7
+ }
8
+ if (Array.isArray(value)) {
9
+ return { kind: 'array', value };
10
+ }
11
+ if (Predicate.isString(value)) {
12
+ return { kind: 'string', value };
13
+ }
14
+ if (Predicate.isNumber(value)) {
15
+ return { kind: 'number', value };
16
+ }
17
+ if (Predicate.isBoolean(value)) {
18
+ return { kind: 'boolean', value };
19
+ }
20
+ return { kind: 'object', value: isJsonObject(value) ? value : {} };
21
+ }
22
+ /** Parses text that holds a JSON object or array; plain strings and scalars stay text. */
23
+ export function parseStructuredJson(text) {
24
+ const trimmed = text.trimStart();
25
+ if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
26
+ return undefined;
27
+ }
28
+ const decoded = decodeJsonText(text);
29
+ if (Option.isNone(decoded)) {
30
+ return undefined;
31
+ }
32
+ const value = decoded.value;
33
+ return Array.isArray(value) || isJsonObject(value) ? value : undefined;
34
+ }
35
+ export function jsonEntries(node) {
36
+ switch (node.kind) {
37
+ case 'object':
38
+ return Object.entries(node.value);
39
+ case 'array':
40
+ return node.value.map((item, index) => [String(index), item]);
41
+ case 'string':
42
+ case 'number':
43
+ case 'boolean':
44
+ case 'null':
45
+ return [];
46
+ default: {
47
+ const exhaustive = node;
48
+ return exhaustive;
49
+ }
50
+ }
51
+ }
52
+ function scalarPreview(value) {
53
+ const node = jsonNode(value);
54
+ switch (node.kind) {
55
+ case 'object':
56
+ return Object.keys(node.value).length === 0 ? '{}' : '{…}';
57
+ case 'array':
58
+ return `[${node.value.length}]`;
59
+ case 'string':
60
+ return JSON.stringify(node.value.length > 24 ? `${node.value.slice(0, 24)}…` : node.value);
61
+ case 'number':
62
+ case 'boolean':
63
+ return String(node.value);
64
+ case 'null':
65
+ return 'null';
66
+ default: {
67
+ const exhaustive = node;
68
+ return exhaustive;
69
+ }
70
+ }
71
+ }
72
+ /** One-line summary shown beside a collapsed object or array. */
73
+ export function jsonPreview(node, budget = 72) {
74
+ const entries = jsonEntries(node);
75
+ const open = node.kind === 'array' ? '[' : '{';
76
+ const close = node.kind === 'array' ? ']' : '}';
77
+ let text = '';
78
+ for (const [key, value] of entries) {
79
+ const part = node.kind === 'array' ? scalarPreview(value) : `${key}: ${scalarPreview(value)}`;
80
+ const next = text ? `${text}, ${part}` : part;
81
+ if (next.length > budget) {
82
+ return `${open} ${text ? `${text}, ` : ''}… ${close}`;
83
+ }
84
+ text = next;
85
+ }
86
+ return text ? `${open} ${text} ${close}` : `${open}${close}`;
87
+ }
@@ -0,0 +1,7 @@
1
+ import { type JsonValue } from '@swirls/looms/core';
2
+ /** Fields of a JSON object, or no fields for any other value. */
3
+ export declare function jsonFields(value: JsonValue | null | undefined): {
4
+ [key: string]: JsonValue;
5
+ };
6
+ export declare function jsonText(value: JsonValue | undefined): string | undefined;
7
+ export declare function jsonNumberText(value: JsonValue | undefined): string | undefined;