@vibefield/rosetta-room 0.0.0-stage → 0.1.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 (435) hide show
  1. package/README.md +247 -2
  2. package/dist/HistoryRoom.d.ts +98 -0
  3. package/dist/HistoryRoom.js +440 -0
  4. package/dist/TranscriptReader.d.ts +22 -0
  5. package/dist/TranscriptReader.js +72 -0
  6. package/dist/components/ColdStart.d.ts +4 -0
  7. package/dist/components/ColdStart.js +5 -0
  8. package/dist/components/FilterChips.d.ts +4 -0
  9. package/dist/components/FilterChips.js +5 -0
  10. package/dist/components/HostAct.d.ts +9 -0
  11. package/dist/components/HostAct.js +16 -0
  12. package/dist/components/HostMenu.d.ts +41 -0
  13. package/dist/components/HostMenu.js +216 -0
  14. package/dist/components/IngestStatus.d.ts +4 -0
  15. package/dist/components/IngestStatus.js +20 -0
  16. package/dist/components/ListActivityNotice.d.ts +5 -0
  17. package/dist/components/ListActivityNotice.js +4 -0
  18. package/dist/components/ListSections.d.ts +20 -0
  19. package/dist/components/ListSections.js +39 -0
  20. package/dist/components/RenameHeading.d.ts +9 -0
  21. package/dist/components/RenameHeading.js +75 -0
  22. package/dist/components/SearchStrip.d.ts +5 -0
  23. package/dist/components/SearchStrip.js +8 -0
  24. package/dist/components/SummaryMetrics.d.ts +13 -0
  25. package/dist/components/SummaryMetrics.js +9 -0
  26. package/dist/components/SummaryPanels.d.ts +35 -0
  27. package/dist/components/SummaryPanels.js +117 -0
  28. package/dist/components/Transcript.d.ts +46 -0
  29. package/dist/components/Transcript.js +358 -0
  30. package/dist/components/charts/ActivityChartDetail.d.ts +13 -0
  31. package/dist/components/charts/ActivityChartDetail.js +78 -0
  32. package/dist/components/charts/CalendarHeatmap.d.ts +16 -0
  33. package/dist/components/charts/CalendarHeatmap.js +55 -0
  34. package/dist/components/charts/DayActivityChart.d.ts +8 -0
  35. package/dist/components/charts/DayActivityChart.js +71 -0
  36. package/dist/components/charts/ModelsChartDetail.d.ts +7 -0
  37. package/dist/components/charts/ModelsChartDetail.js +19 -0
  38. package/dist/components/charts/ProjectChartDialog.d.ts +19 -0
  39. package/dist/components/charts/ProjectChartDialog.js +39 -0
  40. package/dist/components/charts/Streamgraph.d.ts +16 -0
  41. package/dist/components/charts/Streamgraph.js +94 -0
  42. package/dist/components/charts/Treemap.d.ts +26 -0
  43. package/dist/components/charts/Treemap.js +81 -0
  44. package/dist/components/charts/index.d.ts +9 -0
  45. package/dist/components/charts/index.js +4 -0
  46. package/dist/components/charts/streamgraph-layout.d.ts +23 -0
  47. package/dist/components/charts/streamgraph-layout.js +114 -0
  48. package/dist/components/charts/treemap-layout.d.ts +32 -0
  49. package/dist/components/charts/treemap-layout.js +140 -0
  50. package/dist/components/charts/types.d.ts +65 -0
  51. package/dist/components/charts/types.js +8 -0
  52. package/dist/components/file-viewer/FileViewerBrowsers.d.ts +10 -0
  53. package/dist/components/file-viewer/FileViewerBrowsers.js +65 -0
  54. package/dist/components/file-viewer/FileViewerDialog.d.ts +33 -0
  55. package/dist/components/file-viewer/FileViewerDialog.js +82 -0
  56. package/dist/components/file-viewer/FileViewerHeader.d.ts +26 -0
  57. package/dist/components/file-viewer/FileViewerHeader.js +17 -0
  58. package/dist/components/file-viewer/ImageGalleryDialog.d.ts +14 -0
  59. package/dist/components/file-viewer/ImageGalleryDialog.js +98 -0
  60. package/dist/components/file-viewer/diff/index.d.ts +2 -0
  61. package/dist/components/file-viewer/diff/index.js +2 -0
  62. package/dist/components/file-viewer/diff/parse.d.ts +2 -0
  63. package/dist/components/file-viewer/diff/parse.js +164 -0
  64. package/dist/components/file-viewer/diff/types.d.ts +44 -0
  65. package/dist/components/file-viewer/diff/types.js +7 -0
  66. package/dist/components/file-viewer/gallery-source.d.ts +11 -0
  67. package/dist/components/file-viewer/gallery-source.js +75 -0
  68. package/dist/components/file-viewer/image-resource.d.ts +19 -0
  69. package/dist/components/file-viewer/image-resource.js +60 -0
  70. package/dist/components/file-viewer/index.d.ts +5 -0
  71. package/dist/components/file-viewer/index.js +8 -0
  72. package/dist/components/file-viewer/markdown/blocks.d.ts +2 -0
  73. package/dist/components/file-viewer/markdown/blocks.js +277 -0
  74. package/dist/components/file-viewer/markdown/index.d.ts +4 -0
  75. package/dist/components/file-viewer/markdown/index.js +35 -0
  76. package/dist/components/file-viewer/markdown/inline.d.ts +10 -0
  77. package/dist/components/file-viewer/markdown/inline.js +178 -0
  78. package/dist/components/file-viewer/markdown/render.d.ts +9 -0
  79. package/dist/components/file-viewer/markdown/render.js +78 -0
  80. package/dist/components/file-viewer/markdown/types.d.ts +57 -0
  81. package/dist/components/file-viewer/markdown/types.js +11 -0
  82. package/dist/components/file-viewer/minimap/CodeMinimap.d.ts +10 -0
  83. package/dist/components/file-viewer/minimap/CodeMinimap.js +296 -0
  84. package/dist/components/file-viewer/minimap/layout.d.ts +60 -0
  85. package/dist/components/file-viewer/minimap/layout.js +117 -0
  86. package/dist/components/file-viewer/minimap/palette.d.ts +2 -0
  87. package/dist/components/file-viewer/minimap/palette.js +73 -0
  88. package/dist/components/file-viewer/minimap/raster.d.ts +19 -0
  89. package/dist/components/file-viewer/minimap/raster.js +122 -0
  90. package/dist/components/file-viewer/registry.d.ts +25 -0
  91. package/dist/components/file-viewer/registry.js +182 -0
  92. package/dist/components/file-viewer/syntax/grammars.d.ts +16 -0
  93. package/dist/components/file-viewer/syntax/grammars.js +221 -0
  94. package/dist/components/file-viewer/syntax/index.d.ts +8 -0
  95. package/dist/components/file-viewer/syntax/index.js +9 -0
  96. package/dist/components/file-viewer/syntax/languages.d.ts +14 -0
  97. package/dist/components/file-viewer/syntax/languages.js +115 -0
  98. package/dist/components/file-viewer/syntax/tokenize-config.d.ts +2 -0
  99. package/dist/components/file-viewer/syntax/tokenize-config.js +132 -0
  100. package/dist/components/file-viewer/syntax/tokenize-css.d.ts +2 -0
  101. package/dist/components/file-viewer/syntax/tokenize-css.js +169 -0
  102. package/dist/components/file-viewer/syntax/tokenize-markup.d.ts +2 -0
  103. package/dist/components/file-viewer/syntax/tokenize-markup.js +124 -0
  104. package/dist/components/file-viewer/syntax/tokenize.d.ts +9 -0
  105. package/dist/components/file-viewer/syntax/tokenize.js +289 -0
  106. package/dist/components/file-viewer/syntax/types.d.ts +74 -0
  107. package/dist/components/file-viewer/syntax/types.js +13 -0
  108. package/dist/components/file-viewer/types.d.ts +111 -0
  109. package/dist/components/file-viewer/types.js +8 -0
  110. package/dist/components/file-viewer/use-file-content.d.ts +26 -0
  111. package/dist/components/file-viewer/use-file-content.js +144 -0
  112. package/dist/components/file-viewer/views/BinaryView.d.ts +2 -0
  113. package/dist/components/file-viewer/views/BinaryView.js +34 -0
  114. package/dist/components/file-viewer/views/CodeView.d.ts +2 -0
  115. package/dist/components/file-viewer/views/CodeView.js +46 -0
  116. package/dist/components/file-viewer/views/DiffBody.d.ts +7 -0
  117. package/dist/components/file-viewer/views/DiffBody.js +77 -0
  118. package/dist/components/file-viewer/views/DiffView.d.ts +2 -0
  119. package/dist/components/file-viewer/views/DiffView.js +11 -0
  120. package/dist/components/file-viewer/views/ImageView.d.ts +9 -0
  121. package/dist/components/file-viewer/views/ImageView.js +28 -0
  122. package/dist/components/file-viewer/views/MarkdownView.d.ts +9 -0
  123. package/dist/components/file-viewer/views/MarkdownView.js +20 -0
  124. package/dist/components/file-viewer/views/SvgView.d.ts +9 -0
  125. package/dist/components/file-viewer/views/SvgView.js +10 -0
  126. package/dist/components/git/ChangeTree.d.ts +20 -0
  127. package/dist/components/git/ChangeTree.js +35 -0
  128. package/dist/components/git/CommitViewer.d.ts +12 -0
  129. package/dist/components/git/CommitViewer.js +85 -0
  130. package/dist/components/git/GitChanges.d.ts +17 -0
  131. package/dist/components/git/GitChanges.js +70 -0
  132. package/dist/components/git/GitHistory.d.ts +9 -0
  133. package/dist/components/git/GitHistory.js +58 -0
  134. package/dist/components/git/co-author.d.ts +14 -0
  135. package/dist/components/git/co-author.js +55 -0
  136. package/dist/components/git/git-file-source.d.ts +18 -0
  137. package/dist/components/git/git-file-source.js +53 -0
  138. package/dist/components/git/git-host.d.ts +24 -0
  139. package/dist/components/git/git-host.js +130 -0
  140. package/dist/components/git/index.d.ts +10 -0
  141. package/dist/components/git/index.js +12 -0
  142. package/dist/components/git/path-tree.d.ts +23 -0
  143. package/dist/components/git/path-tree.js +73 -0
  144. package/dist/components/git/session-files.d.ts +9 -0
  145. package/dist/components/git/session-files.js +50 -0
  146. package/dist/components/git/types.d.ts +92 -0
  147. package/dist/components/git/types.js +9 -0
  148. package/dist/components/projects/ProjectActivitySparkline.d.ts +6 -0
  149. package/dist/components/projects/ProjectActivitySparkline.js +12 -0
  150. package/dist/components/projects/ProjectList.d.ts +25 -0
  151. package/dist/components/projects/ProjectList.js +43 -0
  152. package/dist/components/projects/ProjectListItem.d.ts +19 -0
  153. package/dist/components/projects/ProjectListItem.js +78 -0
  154. package/dist/components/projects/ProjectsColumn.d.ts +19 -0
  155. package/dist/components/projects/ProjectsColumn.js +36 -0
  156. package/dist/components/projects/index.d.ts +8 -0
  157. package/dist/components/projects/index.js +4 -0
  158. package/dist/components/search/MatchStepper.d.ts +9 -0
  159. package/dist/components/search/MatchStepper.js +14 -0
  160. package/dist/components/search/SearchLauncher.d.ts +12 -0
  161. package/dist/components/search/SearchLauncher.js +13 -0
  162. package/dist/components/search/SearchSheet.d.ts +29 -0
  163. package/dist/components/search/SearchSheet.js +230 -0
  164. package/dist/components/search/index.d.ts +8 -0
  165. package/dist/components/search/index.js +4 -0
  166. package/dist/components/search/shortcut.d.ts +25 -0
  167. package/dist/components/search/shortcut.js +32 -0
  168. package/dist/components/sessions/SessionList.d.ts +24 -0
  169. package/dist/components/sessions/SessionList.js +76 -0
  170. package/dist/components/sessions/SessionListItem.d.ts +13 -0
  171. package/dist/components/sessions/SessionListItem.js +58 -0
  172. package/dist/components/sessions/SessionsColumn.d.ts +26 -0
  173. package/dist/components/sessions/SessionsColumn.js +32 -0
  174. package/dist/components/sessions/index.d.ts +9 -0
  175. package/dist/components/sessions/index.js +4 -0
  176. package/dist/components/sessions/session-display.d.ts +8 -0
  177. package/dist/components/sessions/session-display.js +18 -0
  178. package/dist/components/sessions/types.d.ts +7 -0
  179. package/dist/components/sessions/types.js +1 -0
  180. package/dist/components/transcript/Activity.d.ts +45 -0
  181. package/dist/components/transcript/Activity.js +75 -0
  182. package/dist/components/transcript/Anchor.d.ts +8 -0
  183. package/dist/components/transcript/Anchor.js +23 -0
  184. package/dist/components/transcript/Attachments.d.ts +21 -0
  185. package/dist/components/transcript/Attachments.js +138 -0
  186. package/dist/components/transcript/AuthoredMessage.d.ts +19 -0
  187. package/dist/components/transcript/AuthoredMessage.js +17 -0
  188. package/dist/components/transcript/Compaction.d.ts +9 -0
  189. package/dist/components/transcript/Compaction.js +50 -0
  190. package/dist/components/transcript/DayPill.d.ts +38 -0
  191. package/dist/components/transcript/DayPill.js +68 -0
  192. package/dist/components/transcript/Document.d.ts +32 -0
  193. package/dist/components/transcript/Document.js +503 -0
  194. package/dist/components/transcript/Favicon.d.ts +32 -0
  195. package/dist/components/transcript/Favicon.js +71 -0
  196. package/dist/components/transcript/HeadOfDocument.d.ts +19 -0
  197. package/dist/components/transcript/HeadOfDocument.js +44 -0
  198. package/dist/components/transcript/Ledger.d.ts +53 -0
  199. package/dist/components/transcript/Ledger.js +182 -0
  200. package/dist/components/transcript/LineDetail.d.ts +24 -0
  201. package/dist/components/transcript/LineDetail.js +81 -0
  202. package/dist/components/transcript/Marker.d.ts +33 -0
  203. package/dist/components/transcript/Marker.js +21 -0
  204. package/dist/components/transcript/MessagePreview.d.ts +12 -0
  205. package/dist/components/transcript/MessagePreview.js +58 -0
  206. package/dist/components/transcript/Prompt.d.ts +20 -0
  207. package/dist/components/transcript/Prompt.js +55 -0
  208. package/dist/components/transcript/Prose.d.ts +19 -0
  209. package/dist/components/transcript/Prose.js +109 -0
  210. package/dist/components/transcript/ReceiptPill.d.ts +10 -0
  211. package/dist/components/transcript/ReceiptPill.js +10 -0
  212. package/dist/components/transcript/ResponseHead.d.ts +9 -0
  213. package/dist/components/transcript/ResponseHead.js +36 -0
  214. package/dist/components/transcript/Subthread.d.ts +19 -0
  215. package/dist/components/transcript/Subthread.js +96 -0
  216. package/dist/components/transcript/Team.d.ts +53 -0
  217. package/dist/components/transcript/Team.js +185 -0
  218. package/dist/components/transcript/Thinking.d.ts +24 -0
  219. package/dist/components/transcript/Thinking.js +50 -0
  220. package/dist/components/transcript/TimelineMeta.d.ts +9 -0
  221. package/dist/components/transcript/TimelineMeta.js +161 -0
  222. package/dist/components/transcript/TranscriptLoading.d.ts +10 -0
  223. package/dist/components/transcript/TranscriptLoading.js +10 -0
  224. package/dist/components/transcript/WebDetail.d.ts +8 -0
  225. package/dist/components/transcript/WebDetail.js +29 -0
  226. package/dist/components/transcript/Workflow.d.ts +12 -0
  227. package/dist/components/transcript/Workflow.js +208 -0
  228. package/dist/components/transcript/activity-plan.d.ts +84 -0
  229. package/dist/components/transcript/activity-plan.js +209 -0
  230. package/dist/components/transcript/attachment-file-source.d.ts +23 -0
  231. package/dist/components/transcript/attachment-file-source.js +103 -0
  232. package/dist/components/transcript/attachment-gallery.d.ts +12 -0
  233. package/dist/components/transcript/attachment-gallery.js +33 -0
  234. package/dist/components/transcript/detail-parts.d.ts +50 -0
  235. package/dist/components/transcript/detail-parts.js +295 -0
  236. package/dist/components/transcript/disclosure-state.d.ts +6 -0
  237. package/dist/components/transcript/disclosure-state.js +32 -0
  238. package/dist/components/transcript/disclosure-store.d.ts +8 -0
  239. package/dist/components/transcript/disclosure-store.js +31 -0
  240. package/dist/components/transcript/document-model.d.ts +15 -0
  241. package/dist/components/transcript/document-model.js +104 -0
  242. package/dist/components/transcript/document-plan.d.ts +28 -0
  243. package/dist/components/transcript/document-plan.js +145 -0
  244. package/dist/components/transcript/fold-preference.d.ts +17 -0
  245. package/dist/components/transcript/fold-preference.js +63 -0
  246. package/dist/components/transcript/glyphs.d.ts +15 -0
  247. package/dist/components/transcript/glyphs.js +47 -0
  248. package/dist/components/transcript/index.d.ts +23 -0
  249. package/dist/components/transcript/index.js +22 -0
  250. package/dist/components/transcript/message-file-source.d.ts +15 -0
  251. package/dist/components/transcript/message-file-source.js +31 -0
  252. package/dist/components/transcript/message-preview.d.ts +9 -0
  253. package/dist/components/transcript/message-preview.js +46 -0
  254. package/dist/components/transcript/read-file-source.d.ts +7 -0
  255. package/dist/components/transcript/read-file-source.js +34 -0
  256. package/dist/components/transcript/reader-context.d.ts +13 -0
  257. package/dist/components/transcript/reader-context.js +55 -0
  258. package/dist/components/transcript/reading-identity.d.ts +2 -0
  259. package/dist/components/transcript/reading-identity.js +52 -0
  260. package/dist/components/transcript/scroll-to-row.d.ts +2 -0
  261. package/dist/components/transcript/scroll-to-row.js +13 -0
  262. package/dist/components/transcript/thread-index.d.ts +14 -0
  263. package/dist/components/transcript/thread-index.js +40 -0
  264. package/dist/components/transcript/thread-navigation.d.ts +5 -0
  265. package/dist/components/transcript/thread-navigation.js +3 -0
  266. package/dist/components/transcript/timeline-meta-file-source.d.ts +6 -0
  267. package/dist/components/transcript/timeline-meta-file-source.js +55 -0
  268. package/dist/components/transcript/timeline-meta-state.d.ts +12 -0
  269. package/dist/components/transcript/timeline-meta-state.js +24 -0
  270. package/dist/components/ui/ColumnHeading.d.ts +27 -0
  271. package/dist/components/ui/ColumnHeading.js +7 -0
  272. package/dist/components/ui/ConfirmDialog.d.ts +14 -0
  273. package/dist/components/ui/ConfirmDialog.js +22 -0
  274. package/dist/components/ui/DialogShell.d.ts +18 -0
  275. package/dist/components/ui/DialogShell.js +40 -0
  276. package/dist/components/ui/EmptyState.d.ts +10 -0
  277. package/dist/components/ui/EmptyState.js +6 -0
  278. package/dist/components/ui/ListSummaryHeader.d.ts +9 -0
  279. package/dist/components/ui/ListSummaryHeader.js +6 -0
  280. package/dist/components/ui/ListToolbar.d.ts +6 -0
  281. package/dist/components/ui/ListToolbar.js +5 -0
  282. package/dist/components/ui/ResultGroupHeader.d.ts +9 -0
  283. package/dist/components/ui/ResultGroupHeader.js +5 -0
  284. package/dist/components/ui/SegmentedControl.d.ts +16 -0
  285. package/dist/components/ui/SegmentedControl.js +9 -0
  286. package/dist/components/ui/SummaryMetric.d.ts +13 -0
  287. package/dist/components/ui/SummaryMetric.js +10 -0
  288. package/dist/components/ui/Veil.d.ts +7 -0
  289. package/dist/components/ui/Veil.js +5 -0
  290. package/dist/components/ui/index.d.ts +20 -0
  291. package/dist/components/ui/index.js +10 -0
  292. package/dist/components/worktree/WorktreeColumn.d.ts +22 -0
  293. package/dist/components/worktree/WorktreeColumn.js +170 -0
  294. package/dist/components/worktree/WorktreeFileTree.d.ts +19 -0
  295. package/dist/components/worktree/WorktreeFileTree.js +60 -0
  296. package/dist/components/worktree/WorktreeHeader.d.ts +32 -0
  297. package/dist/components/worktree/WorktreeHeader.js +81 -0
  298. package/dist/components/worktree/WorktreeList.d.ts +8 -0
  299. package/dist/components/worktree/WorktreeList.js +12 -0
  300. package/dist/components/worktree/index.d.ts +12 -0
  301. package/dist/components/worktree/index.js +7 -0
  302. package/dist/components/worktree/types.d.ts +17 -0
  303. package/dist/components/worktree/types.js +3 -0
  304. package/dist/components/worktree/use-worktree-guest.d.ts +21 -0
  305. package/dist/components/worktree/use-worktree-guest.js +92 -0
  306. package/dist/components/worktree/worktree-file-commands.d.ts +19 -0
  307. package/dist/components/worktree/worktree-file-commands.js +112 -0
  308. package/dist/components/worktree/worktree-file-source.d.ts +15 -0
  309. package/dist/components/worktree/worktree-file-source.js +75 -0
  310. package/dist/components/worktree/worktree-host.d.ts +31 -0
  311. package/dist/components/worktree/worktree-host.js +242 -0
  312. package/dist/fixtures/index.d.ts +24 -0
  313. package/dist/fixtures/index.js +292 -0
  314. package/dist/host-inputs.d.ts +231 -0
  315. package/dist/host-inputs.js +35 -0
  316. package/dist/index.d.ts +18 -0
  317. package/dist/index.js +14 -0
  318. package/dist/lib/activity-details.d.ts +23 -0
  319. package/dist/lib/activity-details.js +78 -0
  320. package/dist/lib/activity-order.d.ts +32 -0
  321. package/dist/lib/activity-order.js +86 -0
  322. package/dist/lib/agent-paths.d.ts +6 -0
  323. package/dist/lib/agent-paths.js +19 -0
  324. package/dist/lib/agents.d.ts +15 -0
  325. package/dist/lib/agents.js +60 -0
  326. package/dist/lib/catalog-status.d.ts +3 -0
  327. package/dist/lib/catalog-status.js +10 -0
  328. package/dist/lib/chart-data.d.ts +14 -0
  329. package/dist/lib/chart-data.js +151 -0
  330. package/dist/lib/day-activity.d.ts +21 -0
  331. package/dist/lib/day-activity.js +56 -0
  332. package/dist/lib/format.d.ts +24 -0
  333. package/dist/lib/format.js +116 -0
  334. package/dist/lib/hooks.d.ts +118 -0
  335. package/dist/lib/hooks.js +608 -0
  336. package/dist/lib/icons.d.ts +21 -0
  337. package/dist/lib/icons.js +49 -0
  338. package/dist/lib/image-media.d.ts +6 -0
  339. package/dist/lib/image-media.js +30 -0
  340. package/dist/lib/ingest-activity.d.ts +50 -0
  341. package/dist/lib/ingest-activity.js +151 -0
  342. package/dist/lib/ingest.d.ts +25 -0
  343. package/dist/lib/ingest.js +70 -0
  344. package/dist/lib/model-labels.d.ts +5 -0
  345. package/dist/lib/model-labels.js +28 -0
  346. package/dist/lib/model.d.ts +73 -0
  347. package/dist/lib/model.js +141 -0
  348. package/dist/lib/motion.d.ts +13 -0
  349. package/dist/lib/motion.js +80 -0
  350. package/dist/lib/room-storage.d.ts +13 -0
  351. package/dist/lib/room-storage.js +40 -0
  352. package/dist/lib/search-results.d.ts +27 -0
  353. package/dist/lib/search-results.js +83 -0
  354. package/dist/lib/search-sheet.d.ts +119 -0
  355. package/dist/lib/search-sheet.js +282 -0
  356. package/dist/lib/sections.d.ts +19 -0
  357. package/dist/lib/sections.js +36 -0
  358. package/dist/lib/session-activity.d.ts +5 -0
  359. package/dist/lib/session-activity.js +15 -0
  360. package/dist/lib/session-leases.d.ts +15 -0
  361. package/dist/lib/session-leases.js +61 -0
  362. package/dist/lib/spend.d.ts +42 -0
  363. package/dist/lib/spend.js +112 -0
  364. package/dist/lib/tint.d.ts +9 -0
  365. package/dist/lib/tint.js +53 -0
  366. package/dist/lib/transcript/collaboration.d.ts +97 -0
  367. package/dist/lib/transcript/collaboration.js +423 -0
  368. package/dist/lib/transcript/families.d.ts +212 -0
  369. package/dist/lib/transcript/families.js +906 -0
  370. package/dist/lib/transcript/favicons.d.ts +54 -0
  371. package/dist/lib/transcript/favicons.js +183 -0
  372. package/dist/lib/transcript/head-of-document.d.ts +27 -0
  373. package/dist/lib/transcript/head-of-document.js +274 -0
  374. package/dist/lib/transcript/head-state.d.ts +182 -0
  375. package/dist/lib/transcript/head-state.js +305 -0
  376. package/dist/lib/transcript/history-window.d.ts +13 -0
  377. package/dist/lib/transcript/history-window.js +52 -0
  378. package/dist/lib/transcript/images.d.ts +8 -0
  379. package/dist/lib/transcript/images.js +60 -0
  380. package/dist/lib/transcript/index.d.ts +15 -0
  381. package/dist/lib/transcript/index.js +8 -0
  382. package/dist/lib/transcript/ledger.d.ts +143 -0
  383. package/dist/lib/transcript/ledger.js +513 -0
  384. package/dist/lib/transcript/protocol.d.ts +23 -0
  385. package/dist/lib/transcript/protocol.js +1 -0
  386. package/dist/lib/transcript/sittings.d.ts +75 -0
  387. package/dist/lib/transcript/sittings.js +147 -0
  388. package/dist/lib/transcript/tail-scroll.d.ts +36 -0
  389. package/dist/lib/transcript/tail-scroll.js +167 -0
  390. package/dist/lib/transcript/tail-state.d.ts +17 -0
  391. package/dist/lib/transcript/tail-state.js +30 -0
  392. package/dist/lib/transcript/turns.d.ts +192 -0
  393. package/dist/lib/transcript/turns.js +576 -0
  394. package/dist/lib/transcript/use-transcript-opening.d.ts +12 -0
  395. package/dist/lib/transcript/use-transcript-opening.js +31 -0
  396. package/dist/lib/transcript/use-transcript-tail.d.ts +25 -0
  397. package/dist/lib/transcript/use-transcript-tail.js +158 -0
  398. package/dist/lib/transcript/vocabulary.d.ts +119 -0
  399. package/dist/lib/transcript/vocabulary.js +293 -0
  400. package/dist/lib/transcript/web-address.d.ts +6 -0
  401. package/dist/lib/transcript/web-address.js +18 -0
  402. package/dist/lib/transcript/workflow.d.ts +31 -0
  403. package/dist/lib/transcript/workflow.js +133 -0
  404. package/dist/lib/use-activity-order.d.ts +2 -0
  405. package/dist/lib/use-activity-order.js +23 -0
  406. package/dist/lib/use-day-usage.d.ts +8 -0
  407. package/dist/lib/use-day-usage.js +31 -0
  408. package/dist/lib/use-deferred-list-order.d.ts +26 -0
  409. package/dist/lib/use-deferred-list-order.js +142 -0
  410. package/dist/lib/use-ingest-activity.d.ts +2 -0
  411. package/dist/lib/use-ingest-activity.js +49 -0
  412. package/dist/lib/use-list-motion.d.ts +4 -0
  413. package/dist/lib/use-list-motion.js +67 -0
  414. package/dist/ports.d.ts +222 -0
  415. package/dist/ports.js +3 -0
  416. package/dist/room-context.d.ts +60 -0
  417. package/dist/room-context.js +87 -0
  418. package/dist/styles/activity-chart.css +127 -0
  419. package/dist/styles/attachments.css +29 -0
  420. package/dist/styles/favicon.css +73 -0
  421. package/dist/styles/history-room.css +18 -0
  422. package/dist/styles/host-inputs.css +250 -0
  423. package/dist/styles/image-gallery.css +30 -0
  424. package/dist/styles/ingest.css +51 -0
  425. package/dist/styles/message-preview.css +34 -0
  426. package/dist/styles/models-chart.css +66 -0
  427. package/dist/styles/project-chart.css +19 -0
  428. package/dist/styles/reader.css +33 -0
  429. package/dist/styles/room.css +1411 -0
  430. package/dist/styles/search.css +252 -0
  431. package/dist/styles/transcript-activity.css +70 -0
  432. package/dist/styles/transcript-head.css +220 -0
  433. package/dist/styles/transcript-loading.css +57 -0
  434. package/dist/styles/transcript.css +1226 -0
  435. package/package.json +61 -4
@@ -0,0 +1,133 @@
1
+ function attemptFact(row, action) {
2
+ const timing = row.body.type === "tool_use" ? row.body.tool.timing : null;
3
+ const status = row.body.type === "tool_use" ? row.body.tool.status.value : "unknown";
4
+ const at = timing?.started_at ?? row.at;
5
+ const completedAt = timing?.completed_at ?? null;
6
+ return {
7
+ timelineId: row.timeline_id,
8
+ attempt: action.attempt ?? 1,
9
+ taskId: action.task_id,
10
+ runId: action.run_id,
11
+ resumed: (action.attempt ?? 1) > 1 || action.resume_id !== null,
12
+ status,
13
+ at,
14
+ completedAt,
15
+ durationMs: timing?.duration_ms ??
16
+ (at !== null && completedAt !== null && completedAt >= at ? completedAt - at : null),
17
+ summary: action.callback_summary,
18
+ };
19
+ }
20
+ function hydratedAttemptFact(attempt) {
21
+ return {
22
+ timelineId: attempt.timeline_id,
23
+ attempt: attempt.attempt,
24
+ taskId: attempt.task_id,
25
+ runId: null,
26
+ resumed: attempt.resumed,
27
+ status: attempt.status,
28
+ at: attempt.at,
29
+ completedAt: attempt.completed_at,
30
+ durationMs: attempt.duration_ms,
31
+ summary: attempt.summary,
32
+ };
33
+ }
34
+ export function workflowAttemptIndex(rows) {
35
+ const mutableByRunId = new Map();
36
+ const byTimelineId = new Map();
37
+ for (const row of rows) {
38
+ if (row.body.type !== "tool_use" || row.body.tool.action.type !== "workflow")
39
+ continue;
40
+ const action = row.body.tool.action;
41
+ const fact = attemptFact(row, action);
42
+ byTimelineId.set(row.timeline_id, fact);
43
+ if (action.run_id === null)
44
+ continue;
45
+ const attempts = mutableByRunId.get(action.run_id);
46
+ if (attempts === undefined)
47
+ mutableByRunId.set(action.run_id, [fact]);
48
+ else
49
+ attempts.push(fact);
50
+ }
51
+ const byRunId = new Map();
52
+ for (const [runId, attempts] of mutableByRunId) {
53
+ byRunId.set(runId, attempts.sort((left, right) => left.at === right.at ? left.attempt - right.attempt : (left.at ?? Number.MAX_SAFE_INTEGER) - (right.at ?? Number.MAX_SAFE_INTEGER)));
54
+ }
55
+ return { byRunId, byTimelineId };
56
+ }
57
+ export function workflowAttemptsFor(index, row) {
58
+ if (row.body.type !== "tool_use" || row.body.tool.action.type !== "workflow")
59
+ return [];
60
+ const action = row.body.tool.action;
61
+ const runId = action.run_id;
62
+ if (runId !== null) {
63
+ const attempts = new Map((action.run?.attempts ?? []).map((attempt) => {
64
+ const fact = hydratedAttemptFact(attempt);
65
+ return [fact.timelineId, { ...fact, runId }];
66
+ }));
67
+ // Rows already loaded by the client carry fresher live lifecycle facts
68
+ // than the read-time run join. Overlay them without making pagination the
69
+ // source of the attempt list.
70
+ for (const fact of index.byRunId.get(runId) ?? [])
71
+ attempts.set(fact.timelineId, fact);
72
+ return [...attempts.values()].sort((left, right) => left.at === right.at
73
+ ? left.attempt - right.attempt
74
+ : (left.at ?? Number.MAX_SAFE_INTEGER) - (right.at ?? Number.MAX_SAFE_INTEGER));
75
+ }
76
+ const attempt = index.byTimelineId.get(row.timeline_id);
77
+ return attempt === undefined ? [] : [attempt];
78
+ }
79
+ /** Observed child-response metadata wins. A sidecar configuration is a
80
+ * labelled fallback, never presented as observation. */
81
+ export function workflowRuntime(worker, defaultModel) {
82
+ const observedModels = [...new Set(worker.observed_models ?? [])];
83
+ const observedEfforts = [...new Set(worker.observed_efforts ?? [])];
84
+ if (observedModels.length > 1 || observedEfforts.length > 1) {
85
+ return {
86
+ basis: "varies",
87
+ model: observedModels.length > 1 ? `varies (${observedModels.length})` : (observedModels[0] ?? "model varies"),
88
+ effort: observedEfforts.length > 1 ? `varies (${observedEfforts.length})` : (observedEfforts[0] ?? "unknown"),
89
+ };
90
+ }
91
+ if (observedModels.length === 1 || observedEfforts.length === 1) {
92
+ return {
93
+ basis: "observed",
94
+ model: observedModels[0] ?? "unknown",
95
+ effort: observedEfforts[0] ?? "unknown",
96
+ };
97
+ }
98
+ const model = worker.configured_model ?? defaultModel;
99
+ const effort = worker.configured_effort;
100
+ if (model !== null || effort !== null) {
101
+ return {
102
+ basis: "configured",
103
+ model: model ?? "unknown",
104
+ effort: effort ?? "unknown",
105
+ };
106
+ }
107
+ return { basis: "unknown", model: "unknown", effort: "unknown" };
108
+ }
109
+ /** Terminal run state refines unfinished worker rows without falsifying the
110
+ * native worker outcome. Cached completion is called reused and claims no
111
+ * fresh accounting. */
112
+ export function workflowWorkerState(worker, runStatus) {
113
+ if (worker.cached && worker.state === "done")
114
+ return "reused";
115
+ if (["killed", "cancelled", "stopped"].includes(runStatus)) {
116
+ if (worker.state === "progress")
117
+ return "interrupted";
118
+ if (worker.state === "start")
119
+ return "never started";
120
+ }
121
+ switch (worker.state) {
122
+ case "done":
123
+ return "done";
124
+ case "error":
125
+ return "error";
126
+ case "progress":
127
+ return "running";
128
+ case "start":
129
+ return "queued";
130
+ case "unknown":
131
+ return "status unknown";
132
+ }
133
+ }
@@ -0,0 +1,2 @@
1
+ import type { MetaState } from "@vibefield/rosetta-protocol";
2
+ export declare function useActivityOrder(meta: MetaState | null, snapshotVersion: number, live: boolean, bootstrapping: boolean, now: number): import("./activity-order.js").ActivityOrder;
@@ -0,0 +1,23 @@
1
+ import { useState } from "react";
2
+ import { advanceActivityOrder } from "./activity-order.js";
3
+ export function useActivityOrder(meta, snapshotVersion, live, bootstrapping, now) {
4
+ const [state, setState] = useState(() => ({
5
+ meta, snapshotVersion, live, bootstrapping,
6
+ order: advanceActivityOrder(null, meta?.sessions ?? [], { now, live: false, bootstrapping }),
7
+ }));
8
+ if (state.meta !== meta || state.snapshotVersion !== snapshotVersion ||
9
+ state.live !== live || state.bootstrapping !== bootstrapping) {
10
+ const next = {
11
+ meta, snapshotVersion, live, bootstrapping,
12
+ order: advanceActivityOrder(state.order, meta?.sessions ?? [], {
13
+ now, bootstrapping,
14
+ live: live && state.live && state.snapshotVersion === snapshotVersion,
15
+ }),
16
+ };
17
+ // Pure render-time adjustment keeps ordering and rows in the same commit;
18
+ // no effect publishes a stale intermediate order or mutates a render ref.
19
+ setState(next);
20
+ return next.order;
21
+ }
22
+ return state.order;
23
+ }
@@ -0,0 +1,8 @@
1
+ import type { DayUsageResponse } from "@vibefield/rosetta-protocol";
2
+ /** Requests follow selection, not hover. Superseded requests cannot replace
3
+ * the day being read, including during retry or project changes. */
4
+ export declare function useDayUsage(projectId: string, day: string | null, offsetMinutes: number): {
5
+ status: "ready" | "error" | "loading";
6
+ data: DayUsageResponse | null;
7
+ retry: () => void;
8
+ };
@@ -0,0 +1,31 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useRoom } from "../room-context.js";
3
+ /** Requests follow selection, not hover. Superseded requests cannot replace
4
+ * the day being read, including during retry or project changes. */
5
+ export function useDayUsage(projectId, day, offsetMinutes) {
6
+ const key = JSON.stringify([projectId, day, offsetMinutes]);
7
+ const [result, setResult] = useState(null);
8
+ const [revision, setRevision] = useState(0);
9
+ const { catalog } = useRoom();
10
+ useEffect(() => {
11
+ if (!day)
12
+ return;
13
+ let cancelled = false;
14
+ const controller = new AbortController();
15
+ setResult({ key, status: "loading", data: null });
16
+ catalog.dayUsage(projectId, day, offsetMinutes, controller.signal).then(data => {
17
+ if (!cancelled)
18
+ setResult({ key, status: data.day === day ? "ready" : "error",
19
+ data: data.day === day ? data : null });
20
+ }).catch(() => {
21
+ if (!cancelled)
22
+ setResult({ key, status: "error", data: null });
23
+ });
24
+ return () => { cancelled = true; controller.abort(); };
25
+ }, [catalog, projectId, day, offsetMinutes, key, revision]);
26
+ return {
27
+ status: result?.key === key ? result.status : "loading",
28
+ data: result?.key === key ? result.data : null,
29
+ retry: () => setRevision(value => value + 1),
30
+ };
31
+ }
@@ -0,0 +1,26 @@
1
+ import type { FocusEvent, PointerEvent, UIEvent } from "react";
2
+ export interface ListPosition {
3
+ readonly id: string;
4
+ readonly day: number | null;
5
+ /** Which of a host's sections the row is drawn in (R3); absent without them. */
6
+ readonly section?: number;
7
+ }
8
+ /** Hold geometry, never row data. Pointer, keyboard and scroll activity all
9
+ * protect the same snapshot, including day membership and new insertions. */
10
+ export declare function useDeferredListOrder(desired: readonly ListPosition[], scope: string): {
11
+ items: readonly ListPosition[];
12
+ pending: boolean;
13
+ scrollRef: import("react").RefObject<HTMLDivElement | null>;
14
+ hostProps: {
15
+ onPointerEnter: (event: PointerEvent<HTMLDivElement>) => void;
16
+ onPointerLeave: () => void;
17
+ onPointerDownCapture: () => void;
18
+ onPointerUpCapture: () => void;
19
+ onPointerCancel: () => void;
20
+ onFocusCapture: () => void;
21
+ onBlurCapture: (event: FocusEvent<HTMLDivElement>) => void;
22
+ onWheelCapture: () => void;
23
+ };
24
+ onScroll: (event: UIEvent<HTMLDivElement>) => void;
25
+ apply: () => void;
26
+ };
@@ -0,0 +1,142 @@
1
+ import { useEffect, useLayoutEffect, useRef, useState } from "react";
2
+ const idle = (scope) => ({
3
+ scope, hovered: false, focused: false, pressed: false, away: false, scrolling: false,
4
+ });
5
+ const signature = (items) => JSON.stringify(items);
6
+ /** Hold geometry, never row data. Pointer, keyboard and scroll activity all
7
+ * protect the same snapshot, including day membership and new insertions. */
8
+ export function useDeferredListOrder(desired, scope) {
9
+ const wanted = signature(desired);
10
+ const [view, setView] = useState({ scope, items: desired, signature: wanted });
11
+ const [interaction, setInteraction] = useState(() => idle(scope));
12
+ const scrollRef = useRef(null);
13
+ const timer = useRef(null);
14
+ const reveal = useRef(false);
15
+ const focusAfterReveal = useRef(false);
16
+ const anchor = useRef(null);
17
+ const held = interaction.scope === scope && (interaction.hovered || interaction.focused || interaction.pressed ||
18
+ interaction.away || interaction.scrolling);
19
+ let current = view;
20
+ if (view.scope !== scope || (!held && view.signature !== wanted)) {
21
+ current = { scope, items: desired, signature: wanted };
22
+ setView(current);
23
+ if (interaction.scope !== scope)
24
+ setInteraction(idle(scope));
25
+ }
26
+ else if (held && view.signature !== wanted) {
27
+ // Authoritative removals cannot leave clickable ghosts behind. Preserve
28
+ // the first surviving visible row when removing something above it.
29
+ const present = new Set(desired.map(item => item.id));
30
+ const remaining = view.items.filter(item => present.has(item.id));
31
+ if (remaining.length !== view.items.length) {
32
+ current = { scope, items: remaining, signature: signature(remaining) };
33
+ setView(current);
34
+ }
35
+ }
36
+ const mark = (patch) => setInteraction(previous => {
37
+ const base = previous.scope === scope ? previous : idle(scope);
38
+ return base === previous && Object.keys(patch).every(key => base[key] === patch[key])
39
+ ? previous : { ...base, ...patch };
40
+ });
41
+ const rememberAnchor = () => {
42
+ const container = scrollRef.current;
43
+ if (!container || container.scrollTop <= 2) {
44
+ anchor.current = null;
45
+ return;
46
+ }
47
+ const elements = container.querySelectorAll("[data-motion-key]");
48
+ let low = 0;
49
+ let high = elements.length;
50
+ // The search keeps low < high <= elements.length, so mid names an
51
+ // element, and the window below stops at elements.length.
52
+ const elementAt = (index) => elements[index];
53
+ while (low < high) {
54
+ const mid = (low + high) >>> 1;
55
+ const row = elementAt(mid);
56
+ if (row.offsetTop + row.offsetHeight <= container.scrollTop)
57
+ low = mid + 1;
58
+ else
59
+ high = mid;
60
+ }
61
+ const rows = [];
62
+ for (let index = low; index < Math.min(low + 3, elements.length); index++) {
63
+ const row = elementAt(index);
64
+ rows.push({ id: row.dataset.motionKey, offset: row.offsetTop - container.scrollTop });
65
+ }
66
+ anchor.current = { scope, rows };
67
+ };
68
+ useLayoutEffect(() => {
69
+ const container = scrollRef.current;
70
+ if (!container)
71
+ return;
72
+ if (reveal.current) {
73
+ reveal.current = false;
74
+ container.scrollTop = 0;
75
+ if (focusAfterReveal.current) {
76
+ container.querySelector("[data-motion-key]")?.focus({ preventScroll: true });
77
+ }
78
+ focusAfterReveal.current = false;
79
+ }
80
+ else if (anchor.current?.scope === scope) {
81
+ const rows = new Map(Array.from(container.querySelectorAll("[data-motion-key]"), row => [row.dataset.motionKey, row]));
82
+ for (const saved of anchor.current.rows) {
83
+ const row = rows.get(saved.id);
84
+ if (!row)
85
+ continue;
86
+ container.scrollTop = row.offsetTop - saved.offset;
87
+ break;
88
+ }
89
+ }
90
+ rememberAnchor();
91
+ });
92
+ useLayoutEffect(() => {
93
+ if (scrollRef.current)
94
+ scrollRef.current.scrollTop = 0;
95
+ anchor.current = null;
96
+ }, [scope]);
97
+ useEffect(() => () => {
98
+ if (timer.current !== null)
99
+ clearTimeout(timer.current);
100
+ }, [scope]);
101
+ const scrollActivity = () => {
102
+ mark({ scrolling: true });
103
+ if (timer.current !== null)
104
+ clearTimeout(timer.current);
105
+ timer.current = setTimeout(() => {
106
+ setInteraction(previous => previous.scope === scope ? { ...previous, scrolling: false } : previous);
107
+ timer.current = null;
108
+ }, 180);
109
+ };
110
+ return {
111
+ items: current.items,
112
+ pending: current.signature !== wanted,
113
+ scrollRef,
114
+ hostProps: {
115
+ onPointerEnter: (event) => {
116
+ if (event.pointerType !== "touch")
117
+ mark({ hovered: true });
118
+ },
119
+ onPointerLeave: () => mark({ hovered: false, pressed: false }),
120
+ onPointerDownCapture: () => mark({ pressed: true }),
121
+ onPointerUpCapture: () => mark({ pressed: false }),
122
+ onPointerCancel: () => mark({ pressed: false }),
123
+ onFocusCapture: () => mark({ focused: true }),
124
+ onBlurCapture: (event) => {
125
+ if (!event.currentTarget.contains(event.relatedTarget))
126
+ mark({ focused: false });
127
+ },
128
+ onWheelCapture: scrollActivity,
129
+ },
130
+ onScroll: (event) => {
131
+ mark({ away: event.currentTarget.scrollTop > 2 });
132
+ rememberAnchor();
133
+ scrollActivity();
134
+ },
135
+ apply: () => {
136
+ focusAfterReveal.current = document.activeElement?.hasAttribute("data-list-updates") ?? false;
137
+ reveal.current = true;
138
+ setView({ scope, items: desired, signature: wanted });
139
+ mark({ away: false });
140
+ },
141
+ };
142
+ }
@@ -0,0 +1,2 @@
1
+ import type { ActivityFeed, IngestActivity } from "./ingest-activity.js";
2
+ export declare function useIngestActivity(feed: ActivityFeed): IngestActivity | null;
@@ -0,0 +1,49 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { activityPhase, progressBytes, progressDuration, sampleActivity } from "./ingest-activity.js";
3
+ export function useIngestActivity(feed) {
4
+ const phase = activityPhase(feed);
5
+ const [samples, setSamples] = useState(null);
6
+ const [now, setNow] = useState(Date.now);
7
+ const sawWork = useRef(false);
8
+ const [showCompletion, setShowCompletion] = useState(false);
9
+ const key = phase?.key;
10
+ useEffect(() => {
11
+ const current = activityPhase(feed);
12
+ if (current)
13
+ setSamples((previous) => sampleActivity(previous, feed, current));
14
+ setNow(Date.now());
15
+ }, [feed]);
16
+ useEffect(() => {
17
+ if (key && key !== "ready" && key !== "paused")
18
+ sawWork.current = true;
19
+ if (key !== "ready")
20
+ return;
21
+ setShowCompletion(sawWork.current);
22
+ const timer = window.setTimeout(() => { setShowCompletion(false); sawWork.current = false; }, 5_000);
23
+ return () => window.clearTimeout(timer);
24
+ }, [key]);
25
+ useEffect(() => {
26
+ if (!key || (key === "ready" && !showCompletion))
27
+ return;
28
+ const timer = window.setInterval(() => setNow(Date.now()), 1_000);
29
+ return () => window.clearInterval(timer);
30
+ }, [key, showCompletion]);
31
+ if (!phase || (key === "ready" && !showCompletion))
32
+ return null;
33
+ const sinceAnswer = Math.max(0, now - (feed.receivedAt ?? now));
34
+ const elapsed = `${progressDuration(feed.uptimeMs + (phase.active ? sinceAnswer : 0))} elapsed`;
35
+ const sinceChange = Math.max(0, now - (samples?.changedAt ?? now));
36
+ const rate = sinceChange < 4_000 && samples?.identity === `${feed.startedAt}:${phase.key}:${phase.unit}`
37
+ ? samples.rate : null;
38
+ let footer = "Connected";
39
+ if (feed.connectionError)
40
+ footer = `Last update ${progressDuration(sinceAnswer)} ago`;
41
+ else if (rate && phase.unit)
42
+ footer = phase.unit === "bytes"
43
+ ? `${progressBytes(rate)}/s` : `${Math.round(rate).toLocaleString()} ${phase.unit === "documents" ? "messages" : phase.unit === "records" ? "items" : phase.unit}/s`;
44
+ else if (phase.unit && sinceChange >= 10_000)
45
+ footer = `Connected · No new counts for ${progressDuration(sinceChange)}`;
46
+ else if (!phase.active)
47
+ footer = key === "ready" ? "Complete" : key === "paused" ? "Paused" : "Ready to browse";
48
+ return { phase, feed, footer, elapsed };
49
+ }
@@ -0,0 +1,4 @@
1
+ import type { RefObject } from "react";
2
+ /** Call after rendering stable, sibling rows with data-motion-key identities.
3
+ * `order` includes group labels so crossing a day boundary also moves rows. */
4
+ export declare function useListMotion(order: string, scope: string, externalRef?: RefObject<HTMLDivElement | null>): RefObject<HTMLDivElement | null>;
@@ -0,0 +1,67 @@
1
+ import { useLayoutEffect, useRef } from "react";
2
+ import { ListMotion, REDUCED_MOTION_QUERY } from "./motion.js";
3
+ /** Call after rendering stable, sibling rows with data-motion-key identities.
4
+ * `order` includes group labels so crossing a day boundary also moves rows. */
5
+ export function useListMotion(order, scope, externalRef) {
6
+ const ownRef = useRef(null);
7
+ const ref = externalRef ?? ownRef;
8
+ const refresh = useRef(null);
9
+ useLayoutEffect(() => {
10
+ const container = ref.current;
11
+ if (container === null)
12
+ return;
13
+ const instance = new ListMotion();
14
+ const preference = window.matchMedia(REDUCED_MOTION_QUERY);
15
+ const sizes = new Map();
16
+ const observed = new Set();
17
+ const resize = new ResizeObserver((entries) => {
18
+ let changed = false;
19
+ for (const { target, contentRect } of entries) {
20
+ const previous = sizes.get(target);
21
+ if (previous &&
22
+ (Math.abs(previous.width - contentRect.width) > 0.5 ||
23
+ Math.abs(previous.height - contentRect.height) > 0.5))
24
+ changed = true;
25
+ sizes.set(target, { width: contentRect.width, height: contentRect.height });
26
+ }
27
+ // Progress labels, font metrics and window resizing can change row
28
+ // heights without a reorder. Keep the next animation's origin current.
29
+ if (changed)
30
+ instance.update(container, preference.matches);
31
+ });
32
+ refresh.current = () => {
33
+ const current = new Set([
34
+ container,
35
+ ...container.querySelectorAll("[data-motion-key]"),
36
+ ]);
37
+ for (const element of observed) {
38
+ if (current.has(element))
39
+ continue;
40
+ resize.unobserve(element);
41
+ observed.delete(element);
42
+ sizes.delete(element);
43
+ }
44
+ for (const element of current) {
45
+ if (!observed.has(element))
46
+ resize.observe(element);
47
+ observed.add(element);
48
+ }
49
+ instance.update(container, preference.matches);
50
+ };
51
+ const changed = () => {
52
+ if (preference.matches)
53
+ instance.cancel();
54
+ };
55
+ preference.addEventListener("change", changed);
56
+ return () => {
57
+ instance.cancel();
58
+ resize.disconnect();
59
+ preference.removeEventListener("change", changed);
60
+ refresh.current = null;
61
+ };
62
+ }, [scope]);
63
+ useLayoutEffect(() => {
64
+ refresh.current?.();
65
+ }, [order, scope]);
66
+ return ref;
67
+ }