@joewinke/jatui 0.37.0 → 0.38.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 (266) hide show
  1. package/dist/artifact-blocks/AttachmentChip.svelte +66 -0
  2. package/dist/artifact-blocks/AttachmentChip.svelte.d.ts +7 -0
  3. package/dist/artifact-blocks/BlockComments.svelte +309 -0
  4. package/dist/artifact-blocks/BlockComments.svelte.d.ts +33 -0
  5. package/dist/artifact-blocks/BlockRenderer.svelte +674 -0
  6. package/dist/artifact-blocks/BlockRenderer.svelte.d.ts +55 -0
  7. package/dist/artifact-blocks/BlockVerdict.svelte +151 -0
  8. package/dist/artifact-blocks/BlockVerdict.svelte.d.ts +13 -0
  9. package/dist/artifact-blocks/BlocksArtifactView.svelte +1616 -0
  10. package/dist/artifact-blocks/BlocksArtifactView.svelte.d.ts +113 -0
  11. package/dist/artifact-blocks/CONTRACT.md +225 -0
  12. package/dist/artifact-blocks/CommentPill.svelte +49 -0
  13. package/dist/artifact-blocks/CommentPill.svelte.d.ts +16 -0
  14. package/dist/artifact-blocks/FoldedRounds.svelte +95 -0
  15. package/dist/artifact-blocks/FoldedRounds.svelte.d.ts +9 -0
  16. package/dist/artifact-blocks/Glyph.svelte +54 -0
  17. package/dist/artifact-blocks/Glyph.svelte.d.ts +10 -0
  18. package/dist/artifact-blocks/HistoryScrubber.svelte +500 -0
  19. package/dist/artifact-blocks/HistoryScrubber.svelte.d.ts +15 -0
  20. package/dist/artifact-blocks/Markdown.svelte +186 -0
  21. package/dist/artifact-blocks/Markdown.svelte.d.ts +30 -0
  22. package/dist/artifact-blocks/NoteComposer.svelte +31 -0
  23. package/dist/artifact-blocks/NoteComposer.svelte.d.ts +8 -0
  24. package/dist/artifact-blocks/PlainComposer.svelte +200 -0
  25. package/dist/artifact-blocks/PlainComposer.svelte.d.ts +15 -0
  26. package/dist/artifact-blocks/SectionTools.svelte +102 -0
  27. package/dist/artifact-blocks/SectionTools.svelte.d.ts +19 -0
  28. package/dist/artifact-blocks/adapter.d.ts +13 -0
  29. package/dist/artifact-blocks/adapter.js +31 -0
  30. package/dist/artifact-blocks/autoSend.d.ts +49 -0
  31. package/dist/artifact-blocks/autoSend.js +103 -0
  32. package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte +557 -0
  33. package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte.d.ts +48 -0
  34. package/dist/artifact-blocks/blocks/actions/block.d.ts +8 -0
  35. package/dist/artifact-blocks/blocks/actions/block.js +74 -0
  36. package/dist/artifact-blocks/blocks/actions/requests.d.ts +62 -0
  37. package/dist/artifact-blocks/blocks/actions/requests.js +26 -0
  38. package/dist/artifact-blocks/blocks/actions/schema.d.ts +168 -0
  39. package/dist/artifact-blocks/blocks/actions/schema.js +253 -0
  40. package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte +779 -0
  41. package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte.d.ts +40 -0
  42. package/dist/artifact-blocks/blocks/callout/block.d.ts +7 -0
  43. package/dist/artifact-blocks/blocks/callout/block.js +39 -0
  44. package/dist/artifact-blocks/blocks/callout/schema.d.ts +72 -0
  45. package/dist/artifact-blocks/blocks/callout/schema.js +115 -0
  46. package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte +875 -0
  47. package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte.d.ts +59 -0
  48. package/dist/artifact-blocks/blocks/chart/block.d.ts +9 -0
  49. package/dist/artifact-blocks/blocks/chart/block.js +70 -0
  50. package/dist/artifact-blocks/blocks/chart/schema.d.ts +171 -0
  51. package/dist/artifact-blocks/blocks/chart/schema.js +498 -0
  52. package/dist/artifact-blocks/blocks/chart/thumb.d.ts +2 -0
  53. package/dist/artifact-blocks/blocks/chart/thumb.js +201 -0
  54. package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte +1048 -0
  55. package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte.d.ts +16 -0
  56. package/dist/artifact-blocks/blocks/checklist/Icon.svelte +105 -0
  57. package/dist/artifact-blocks/blocks/checklist/Icon.svelte.d.ts +17 -0
  58. package/dist/artifact-blocks/blocks/checklist/block.d.ts +10 -0
  59. package/dist/artifact-blocks/blocks/checklist/block.js +63 -0
  60. package/dist/artifact-blocks/blocks/checklist/itemReview.d.ts +16 -0
  61. package/dist/artifact-blocks/blocks/checklist/itemReview.js +63 -0
  62. package/dist/artifact-blocks/blocks/checklist/labels.d.ts +62 -0
  63. package/dist/artifact-blocks/blocks/checklist/labels.js +96 -0
  64. package/dist/artifact-blocks/blocks/checklist/retest.d.ts +43 -0
  65. package/dist/artifact-blocks/blocks/checklist/retest.js +68 -0
  66. package/dist/artifact-blocks/blocks/checklist/schema.d.ts +84 -0
  67. package/dist/artifact-blocks/blocks/checklist/schema.js +91 -0
  68. package/dist/artifact-blocks/blocks/code/CodeBlock.svelte +128 -0
  69. package/dist/artifact-blocks/blocks/code/CodeBlock.svelte.d.ts +12 -0
  70. package/dist/artifact-blocks/blocks/code/block.d.ts +8 -0
  71. package/dist/artifact-blocks/blocks/code/block.js +31 -0
  72. package/dist/artifact-blocks/blocks/code/highlight.d.ts +34 -0
  73. package/dist/artifact-blocks/blocks/code/highlight.js +280 -0
  74. package/dist/artifact-blocks/blocks/code/schema.d.ts +32 -0
  75. package/dist/artifact-blocks/blocks/code/schema.js +39 -0
  76. package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte +290 -0
  77. package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte.d.ts +29 -0
  78. package/dist/artifact-blocks/blocks/collage/block.d.ts +9 -0
  79. package/dist/artifact-blocks/blocks/collage/block.js +29 -0
  80. package/dist/artifact-blocks/blocks/collage/schema.d.ts +52 -0
  81. package/dist/artifact-blocks/blocks/collage/schema.js +86 -0
  82. package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte +484 -0
  83. package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte.d.ts +25 -0
  84. package/dist/artifact-blocks/blocks/compare/block.d.ts +9 -0
  85. package/dist/artifact-blocks/blocks/compare/block.js +32 -0
  86. package/dist/artifact-blocks/blocks/compare/schema.d.ts +74 -0
  87. package/dist/artifact-blocks/blocks/compare/schema.js +148 -0
  88. package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte +392 -0
  89. package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte.d.ts +30 -0
  90. package/dist/artifact-blocks/blocks/diagram/block.d.ts +9 -0
  91. package/dist/artifact-blocks/blocks/diagram/block.js +50 -0
  92. package/dist/artifact-blocks/blocks/diagram/constants.d.ts +48 -0
  93. package/dist/artifact-blocks/blocks/diagram/constants.js +53 -0
  94. package/dist/artifact-blocks/blocks/diagram/schema.d.ts +161 -0
  95. package/dist/artifact-blocks/blocks/diagram/schema.js +621 -0
  96. package/dist/artifact-blocks/blocks/diagram/thumb.d.ts +2 -0
  97. package/dist/artifact-blocks/blocks/diagram/thumb.js +157 -0
  98. package/dist/artifact-blocks/blocks/diagram/types.d.ts +74 -0
  99. package/dist/artifact-blocks/blocks/diagram/types.js +1 -0
  100. package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte +81 -0
  101. package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte.d.ts +10 -0
  102. package/dist/artifact-blocks/blocks/diff/block.d.ts +7 -0
  103. package/dist/artifact-blocks/blocks/diff/block.js +36 -0
  104. package/dist/artifact-blocks/blocks/diff/schema.d.ts +18 -0
  105. package/dist/artifact-blocks/blocks/diff/schema.js +35 -0
  106. package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte +1055 -0
  107. package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte.d.ts +5 -0
  108. package/dist/artifact-blocks/blocks/diff-review/block.d.ts +15 -0
  109. package/dist/artifact-blocks/blocks/diff-review/block.js +64 -0
  110. package/dist/artifact-blocks/blocks/diff-review/decisions.d.ts +57 -0
  111. package/dist/artifact-blocks/blocks/diff-review/decisions.js +80 -0
  112. package/dist/artifact-blocks/blocks/diff-review/schema.d.ts +13 -0
  113. package/dist/artifact-blocks/blocks/diff-review/schema.js +84 -0
  114. package/dist/artifact-blocks/blocks/diff-review/types.d.ts +35 -0
  115. package/dist/artifact-blocks/blocks/diff-review/types.js +1 -0
  116. package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte +145 -0
  117. package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte.d.ts +5 -0
  118. package/dist/artifact-blocks/blocks/explainer/block.d.ts +8 -0
  119. package/dist/artifact-blocks/blocks/explainer/block.js +21 -0
  120. package/dist/artifact-blocks/blocks/explainer/schema.d.ts +26 -0
  121. package/dist/artifact-blocks/blocks/explainer/schema.js +69 -0
  122. package/dist/artifact-blocks/blocks/group-content.d.ts +10 -0
  123. package/dist/artifact-blocks/blocks/group-content.js +16 -0
  124. package/dist/artifact-blocks/blocks/group-data.d.ts +10 -0
  125. package/dist/artifact-blocks/blocks/group-data.js +7 -0
  126. package/dist/artifact-blocks/blocks/group-review.d.ts +10 -0
  127. package/dist/artifact-blocks/blocks/group-review.js +12 -0
  128. package/dist/artifact-blocks/blocks/group-visual.d.ts +17 -0
  129. package/dist/artifact-blocks/blocks/group-visual.js +14 -0
  130. package/dist/artifact-blocks/blocks/map/MapBlock.svelte +413 -0
  131. package/dist/artifact-blocks/blocks/map/MapBlock.svelte.d.ts +53 -0
  132. package/dist/artifact-blocks/blocks/map/block.d.ts +9 -0
  133. package/dist/artifact-blocks/blocks/map/block.js +62 -0
  134. package/dist/artifact-blocks/blocks/map/schema.d.ts +123 -0
  135. package/dist/artifact-blocks/blocks/map/schema.js +113 -0
  136. package/dist/artifact-blocks/blocks/map/thumb.d.ts +2 -0
  137. package/dist/artifact-blocks/blocks/map/thumb.js +69 -0
  138. package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte +33 -0
  139. package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte.d.ts +15 -0
  140. package/dist/artifact-blocks/blocks/markdown/block.d.ts +7 -0
  141. package/dist/artifact-blocks/blocks/markdown/block.js +28 -0
  142. package/dist/artifact-blocks/blocks/markdown/render.d.ts +17 -0
  143. package/dist/artifact-blocks/blocks/markdown/render.js +115 -0
  144. package/dist/artifact-blocks/blocks/markdown/schema.d.ts +10 -0
  145. package/dist/artifact-blocks/blocks/markdown/schema.js +23 -0
  146. package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte +2112 -0
  147. package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte.d.ts +5 -0
  148. package/dist/artifact-blocks/blocks/media-picker/block.d.ts +24 -0
  149. package/dist/artifact-blocks/blocks/media-picker/block.js +137 -0
  150. package/dist/artifact-blocks/blocks/media-picker/choices.d.ts +28 -0
  151. package/dist/artifact-blocks/blocks/media-picker/choices.js +35 -0
  152. package/dist/artifact-blocks/blocks/media-picker/decisions.d.ts +51 -0
  153. package/dist/artifact-blocks/blocks/media-picker/decisions.js +75 -0
  154. package/dist/artifact-blocks/blocks/media-picker/schema.d.ts +7 -0
  155. package/dist/artifact-blocks/blocks/media-picker/schema.js +199 -0
  156. package/dist/artifact-blocks/blocks/media-picker/types.d.ts +92 -0
  157. package/dist/artifact-blocks/blocks/media-picker/types.js +1 -0
  158. package/dist/artifact-blocks/blocks/media-picker/versions.d.ts +51 -0
  159. package/dist/artifact-blocks/blocks/media-picker/versions.js +118 -0
  160. package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte +213 -0
  161. package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte.d.ts +5 -0
  162. package/dist/artifact-blocks/blocks/mockup/block.d.ts +26 -0
  163. package/dist/artifact-blocks/blocks/mockup/block.js +52 -0
  164. package/dist/artifact-blocks/blocks/mockup/doc.d.ts +24 -0
  165. package/dist/artifact-blocks/blocks/mockup/doc.js +44 -0
  166. package/dist/artifact-blocks/blocks/mockup/sandbox.d.ts +21 -0
  167. package/dist/artifact-blocks/blocks/mockup/sandbox.js +27 -0
  168. package/dist/artifact-blocks/blocks/mockup/schema.d.ts +7 -0
  169. package/dist/artifact-blocks/blocks/mockup/schema.js +90 -0
  170. package/dist/artifact-blocks/blocks/mockup/types.d.ts +36 -0
  171. package/dist/artifact-blocks/blocks/mockup/types.js +17 -0
  172. package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte +359 -0
  173. package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte.d.ts +32 -0
  174. package/dist/artifact-blocks/blocks/program/block.d.ts +35 -0
  175. package/dist/artifact-blocks/blocks/program/block.js +68 -0
  176. package/dist/artifact-blocks/blocks/program/schema.d.ts +132 -0
  177. package/dist/artifact-blocks/blocks/program/schema.js +268 -0
  178. package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte +315 -0
  179. package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte.d.ts +24 -0
  180. package/dist/artifact-blocks/blocks/stats/block.d.ts +7 -0
  181. package/dist/artifact-blocks/blocks/stats/block.js +49 -0
  182. package/dist/artifact-blocks/blocks/stats/schema.d.ts +82 -0
  183. package/dist/artifact-blocks/blocks/stats/schema.js +43 -0
  184. package/dist/artifact-blocks/blocks/stats/thumb.d.ts +2 -0
  185. package/dist/artifact-blocks/blocks/stats/thumb.js +102 -0
  186. package/dist/artifact-blocks/blocks/table/TableBlock.svelte +490 -0
  187. package/dist/artifact-blocks/blocks/table/TableBlock.svelte.d.ts +28 -0
  188. package/dist/artifact-blocks/blocks/table/block.d.ts +9 -0
  189. package/dist/artifact-blocks/blocks/table/block.js +100 -0
  190. package/dist/artifact-blocks/blocks/table/schema.d.ts +143 -0
  191. package/dist/artifact-blocks/blocks/table/schema.js +278 -0
  192. package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte +347 -0
  193. package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte.d.ts +42 -0
  194. package/dist/artifact-blocks/blocks/timeline/block.d.ts +9 -0
  195. package/dist/artifact-blocks/blocks/timeline/block.js +96 -0
  196. package/dist/artifact-blocks/blocks/timeline/constants.d.ts +26 -0
  197. package/dist/artifact-blocks/blocks/timeline/constants.js +27 -0
  198. package/dist/artifact-blocks/blocks/timeline/schema.d.ts +102 -0
  199. package/dist/artifact-blocks/blocks/timeline/schema.js +405 -0
  200. package/dist/artifact-blocks/blocks/timeline/thumb.d.ts +2 -0
  201. package/dist/artifact-blocks/blocks/timeline/thumb.js +117 -0
  202. package/dist/artifact-blocks/blocks/timeline/types.d.ts +66 -0
  203. package/dist/artifact-blocks/blocks/timeline/types.js +1 -0
  204. package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte +169 -0
  205. package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte.d.ts +26 -0
  206. package/dist/artifact-blocks/blocks/transcript/block.d.ts +9 -0
  207. package/dist/artifact-blocks/blocks/transcript/block.js +86 -0
  208. package/dist/artifact-blocks/blocks/transcript/schema.d.ts +114 -0
  209. package/dist/artifact-blocks/blocks/transcript/schema.js +126 -0
  210. package/dist/artifact-blocks/builtins.d.ts +40 -0
  211. package/dist/artifact-blocks/builtins.js +22 -0
  212. package/dist/artifact-blocks/contractBlocks.d.ts +92 -0
  213. package/dist/artifact-blocks/contractBlocks.js +279 -0
  214. package/dist/artifact-blocks/history.d.ts +140 -0
  215. package/dist/artifact-blocks/history.js +363 -0
  216. package/dist/artifact-blocks/index.d.ts +40 -0
  217. package/dist/artifact-blocks/index.js +46 -0
  218. package/dist/artifact-blocks/listen/context.d.ts +30 -0
  219. package/dist/artifact-blocks/listen/context.js +30 -0
  220. package/dist/artifact-blocks/liveData.d.ts +78 -0
  221. package/dist/artifact-blocks/liveData.js +137 -0
  222. package/dist/artifact-blocks/liveDataPoller.d.ts +41 -0
  223. package/dist/artifact-blocks/liveDataPoller.js +140 -0
  224. package/dist/artifact-blocks/openNav.d.ts +46 -0
  225. package/dist/artifact-blocks/openNav.js +106 -0
  226. package/dist/artifact-blocks/pageReviewKeys.d.ts +17 -0
  227. package/dist/artifact-blocks/pageReviewKeys.js +115 -0
  228. package/dist/artifact-blocks/params.d.ts +98 -0
  229. package/dist/artifact-blocks/params.js +159 -0
  230. package/dist/artifact-blocks/registry.d.ts +27 -0
  231. package/dist/artifact-blocks/registry.js +83 -0
  232. package/dist/artifact-blocks/review/BlockIcon.svelte +99 -0
  233. package/dist/artifact-blocks/review/BlockIcon.svelte.d.ts +17 -0
  234. package/dist/artifact-blocks/review/BulkRejectForm.svelte +94 -0
  235. package/dist/artifact-blocks/review/BulkRejectForm.svelte.d.ts +11 -0
  236. package/dist/artifact-blocks/review/BulkUndoBar.svelte +40 -0
  237. package/dist/artifact-blocks/review/BulkUndoBar.svelte.d.ts +9 -0
  238. package/dist/artifact-blocks/review/ItemNote.svelte +193 -0
  239. package/dist/artifact-blocks/review/ItemNote.svelte.d.ts +33 -0
  240. package/dist/artifact-blocks/review/NoteToggle.svelte +52 -0
  241. package/dist/artifact-blocks/review/NoteToggle.svelte.d.ts +12 -0
  242. package/dist/artifact-blocks/review/TeamChip.svelte +71 -0
  243. package/dist/artifact-blocks/review/TeamChip.svelte.d.ts +8 -0
  244. package/dist/artifact-blocks/review/attachments.d.ts +10 -0
  245. package/dist/artifact-blocks/review/attachments.js +37 -0
  246. package/dist/artifact-blocks/review/bulk.d.ts +52 -0
  247. package/dist/artifact-blocks/review/bulk.js +61 -0
  248. package/dist/artifact-blocks/review/itemReview.d.ts +33 -0
  249. package/dist/artifact-blocks/review/itemReview.js +112 -0
  250. package/dist/artifact-blocks/review/roundLines.d.ts +14 -0
  251. package/dist/artifact-blocks/review/roundLines.js +20 -0
  252. package/dist/artifact-blocks/review/rounds.d.ts +86 -0
  253. package/dist/artifact-blocks/review/rounds.js +302 -0
  254. package/dist/artifact-blocks/review/saver.d.ts +23 -0
  255. package/dist/artifact-blocks/review/saver.js +48 -0
  256. package/dist/artifact-blocks/review/team.d.ts +31 -0
  257. package/dist/artifact-blocks/review/team.js +42 -0
  258. package/dist/artifact-blocks/review/visualOrder.d.ts +29 -0
  259. package/dist/artifact-blocks/review/visualOrder.js +66 -0
  260. package/dist/artifact-blocks/review.d.ts +180 -0
  261. package/dist/artifact-blocks/review.js +716 -0
  262. package/dist/artifact-blocks/thumb-kit.d.ts +80 -0
  263. package/dist/artifact-blocks/thumb-kit.js +149 -0
  264. package/dist/artifact-blocks/types.d.ts +513 -0
  265. package/dist/artifact-blocks/types.js +1 -0
  266. package/package.json +11 -2
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Markdown (jatui-vsuzi) — the ONE rich-prose surface of artifact blocks:
3
+ * source → the shared sanitized renderer (blocks/markdown/render.ts) →
4
+ * {@html}, with the prose styles carried HERE rather than borrowed from a
5
+ * host's typography plugin. A host without `@tailwindcss/typography` (the
6
+ * jat IDE) rendered MOS markdown as flat text with invisible links
7
+ * (PARAMS-SPEC §4); these scoped styles make headings, lists, tables,
8
+ * code and — above all — links visible everywhere.
9
+ *
10
+ * Token-only theming (DaisyUI `--color-*` → jatui radius tokens), light +
11
+ * dark by construction, phone-safe (tables scroll inside the block, long
12
+ * words wrap). Paragraphs and list items cap near 70ch.
13
+ *
14
+ * The {@html} here is the contract's sanctioned path: the HTML has passed
15
+ * marked + DOMPurify with the blocks URL policy.
16
+ */
17
+ import type { Snippet } from "svelte";
18
+ interface Props {
19
+ source: string | null | undefined;
20
+ /** Inline only: no paragraphs/headings (labels, option details). */
21
+ inline?: boolean;
22
+ /** Smaller body text (card sections, comment threads). */
23
+ size?: "base" | "sm";
24
+ class?: string;
25
+ /** Rendered before the prose (SectionTools floats here). */
26
+ children?: Snippet;
27
+ }
28
+ declare const Markdown: import("svelte").Component<Props, {}, "">;
29
+ type Markdown = ReturnType<typeof Markdown>;
30
+ export default Markdown;
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ /**
3
+ * NoteComposer (jatui-vsuzi) — the ONE composer mount every artifact-block
4
+ * surface uses (verdict notes, comment threads, the Finish note, and the
5
+ * blocks' own per-item notes). It resolves the host's composer from the
6
+ * adapter (HostAdapter.composer — MOS passes its ReviewComposer) and its
7
+ * upload leg (HostAdapter.upload(artifactId)); without either it falls back
8
+ * to jatui's text composer. Blocks import THIS, never a host composer.
9
+ */
10
+ import { hostAdapter } from "./adapter.js"
11
+ import PlainComposer from "./PlainComposer.svelte"
12
+ import type { NoteComposerProps } from "./types.js"
13
+
14
+ interface Props extends NoteComposerProps {
15
+ /** The artifact the note belongs to — the upload leg's target. */
16
+ artifactId: string
17
+ }
18
+
19
+ let {
20
+ artifactId,
21
+ text = $bindable(""),
22
+ clips = $bindable([]),
23
+ ...rest
24
+ }: Props = $props()
25
+
26
+ const adapter = hostAdapter()
27
+ const Composer = adapter.composer ?? PlainComposer
28
+ const upload = $derived(adapter.upload?.(artifactId))
29
+ </script>
30
+
31
+ <Composer bind:text bind:clips {...rest} upload={rest.upload ?? upload} />
@@ -0,0 +1,8 @@
1
+ import type { NoteComposerProps } from "./types.js";
2
+ interface Props extends NoteComposerProps {
3
+ /** The artifact the note belongs to — the upload leg's target. */
4
+ artifactId: string;
5
+ }
6
+ declare const NoteComposer: import("svelte").Component<Props, {}, "text" | "clips">;
7
+ type NoteComposer = ReturnType<typeof NoteComposer>;
8
+ export default NoteComposer;
@@ -0,0 +1,200 @@
1
+ <script lang="ts">
2
+ /**
3
+ * PlainComposer (jatui-vsuzi) — the default note composer when the host
4
+ * supplies none (HostAdapter.composer). Text first; with an `upload` leg
5
+ * it also takes files (picker, paste, drop) and shows them as chips. No
6
+ * recording: hosts that want voice/video/screen capture pass their own
7
+ * composer (MOS's ReviewComposer), which takes the same NoteComposerProps.
8
+ *
9
+ * Two modes, like every composer: a submit row (`submitLabel` +
10
+ * `onSubmit`, cleared on success, kept on failure) or host-driven
11
+ * (`bind:text` / `bind:clips`, no submit row).
12
+ */
13
+ import type { NoteAttachment, NoteComposerProps } from "./types.js"
14
+ import AttachmentChip from "./AttachmentChip.svelte"
15
+
16
+ let {
17
+ upload = undefined,
18
+ placeholder = "Type a note…",
19
+ label = "Note",
20
+ maxLength = undefined,
21
+ rows = 2,
22
+ submitLabel = undefined,
23
+ onSubmit = undefined,
24
+ busy = false,
25
+ disabled = false,
26
+ error = null,
27
+ onInput = undefined,
28
+ onBlur = undefined,
29
+ clips = $bindable([]),
30
+ onClipsChange = undefined,
31
+ maxClips = 10,
32
+ autofocus = false,
33
+ text = $bindable(""),
34
+ class: className = "",
35
+ }: NoteComposerProps = $props()
36
+
37
+ let inputEl = $state<HTMLTextAreaElement | null>(null)
38
+ let fileEl = $state<HTMLInputElement | null>(null)
39
+ let uploading = $state(0)
40
+ let localError = $state<string | null>(null)
41
+ let submitting = $state(false)
42
+
43
+ $effect(() => {
44
+ if (autofocus && inputEl) inputEl.focus()
45
+ })
46
+
47
+ const canAttach = $derived(Boolean(upload) && !disabled)
48
+ const shown = $derived(error ?? localError)
49
+
50
+ function setClips(next: NoteAttachment[]) {
51
+ clips = next
52
+ onClipsChange?.(next)
53
+ }
54
+
55
+ async function addFiles(files: Iterable<File>) {
56
+ if (!upload) return
57
+ for (const f of files) {
58
+ if ((clips?.length ?? 0) + uploading >= maxClips) {
59
+ localError = `Up to ${maxClips} attachments per note.`
60
+ break
61
+ }
62
+ uploading++
63
+ localError = null
64
+ try {
65
+ const clip = await upload(f, "file")
66
+ setClips([...(clips ?? []), clip])
67
+ } catch (e) {
68
+ localError = e instanceof Error ? e.message : "Couldn't attach that file."
69
+ } finally {
70
+ uploading--
71
+ }
72
+ }
73
+ }
74
+
75
+ function onPaste(e: ClipboardEvent) {
76
+ if (!canAttach) return
77
+ const files = [...(e.clipboardData?.files ?? [])]
78
+ if (files.length === 0) return
79
+ e.preventDefault()
80
+ void addFiles(files)
81
+ }
82
+
83
+ function onDrop(e: DragEvent) {
84
+ if (!canAttach) return
85
+ const files = [...(e.dataTransfer?.files ?? [])]
86
+ if (files.length === 0) return
87
+ e.preventDefault()
88
+ void addFiles(files)
89
+ }
90
+
91
+ async function submit() {
92
+ if (!onSubmit || submitting || busy) return
93
+ const body = text.trim()
94
+ if (!body && (clips?.length ?? 0) === 0) return
95
+ submitting = true
96
+ localError = null
97
+ try {
98
+ await onSubmit({ text: body, clips: clips ?? [] })
99
+ text = ""
100
+ setClips([])
101
+ } catch (e) {
102
+ // The draft stays; the host's `error` (or this) says why.
103
+ if (!error)
104
+ localError = e instanceof Error ? e.message : "Could not send that."
105
+ } finally {
106
+ submitting = false
107
+ }
108
+ }
109
+
110
+ function onKeydown(e: KeyboardEvent) {
111
+ if (submitLabel && e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
112
+ e.preventDefault()
113
+ void submit()
114
+ }
115
+ }
116
+ </script>
117
+
118
+ <div
119
+ class="flex flex-col gap-2 {className}"
120
+ ondragover={(e) => canAttach && e.preventDefault()}
121
+ ondrop={onDrop}
122
+ role="group"
123
+ aria-label={label}
124
+ data-plain-composer
125
+ >
126
+ <textarea
127
+ bind:this={inputEl}
128
+ bind:value={text}
129
+ class="textarea textarea-sm w-full rounded-field"
130
+ {rows}
131
+ maxlength={maxLength}
132
+ {placeholder}
133
+ aria-label={label}
134
+ disabled={disabled || busy || submitting}
135
+ oninput={() => onInput?.(text)}
136
+ onblur={() => onBlur?.()}
137
+ onpaste={onPaste}
138
+ onkeydown={onKeydown}
139
+ ></textarea>
140
+ {#if (clips?.length ?? 0) > 0 || uploading > 0}
141
+ <ul class="flex flex-wrap items-center gap-1.5" aria-label="Attachments">
142
+ {#each clips ?? [] as clip (clip.name)}
143
+ <li class="flex items-center gap-0.5">
144
+ <AttachmentChip {clip} />
145
+ {#if !disabled}
146
+ <button
147
+ type="button"
148
+ class="btn btn-ghost btn-xs btn-circle"
149
+ aria-label="Remove {clip.label ?? clip.name}"
150
+ onclick={() => setClips((clips ?? []).filter((c) => c !== clip))}
151
+ >✕</button
152
+ >
153
+ {/if}
154
+ </li>
155
+ {/each}
156
+ {#if uploading > 0}
157
+ <li class="text-base-content/60 flex items-center gap-1.5 text-xs">
158
+ <span class="loading loading-spinner loading-xs"></span>Attaching…
159
+ </li>
160
+ {/if}
161
+ </ul>
162
+ {/if}
163
+ {#if shown}
164
+ <p role="alert" class="text-error text-xs">{shown}</p>
165
+ {/if}
166
+ {#if canAttach || submitLabel}
167
+ <div class="flex flex-wrap items-center gap-2">
168
+ {#if canAttach}
169
+ <input
170
+ bind:this={fileEl}
171
+ type="file"
172
+ multiple
173
+ class="hidden"
174
+ onchange={(e) => {
175
+ const input = e.currentTarget as HTMLInputElement
176
+ void addFiles([...(input.files ?? [])])
177
+ input.value = ""
178
+ }}
179
+ />
180
+ <button
181
+ type="button"
182
+ class="btn btn-ghost btn-xs rounded-field"
183
+ onclick={() => fileEl?.click()}
184
+ >
185
+ Attach file
186
+ </button>
187
+ {/if}
188
+ {#if submitLabel}
189
+ <button
190
+ type="button"
191
+ class="btn btn-primary btn-sm rounded-field ml-auto"
192
+ disabled={disabled || busy || submitting || uploading > 0}
193
+ onclick={submit}
194
+ >
195
+ {busy || submitting ? "Sending…" : submitLabel}
196
+ </button>
197
+ {/if}
198
+ </div>
199
+ {/if}
200
+ </div>
@@ -0,0 +1,15 @@
1
+ /**
2
+ * PlainComposer (jatui-vsuzi) — the default note composer when the host
3
+ * supplies none (HostAdapter.composer). Text first; with an `upload` leg
4
+ * it also takes files (picker, paste, drop) and shows them as chips. No
5
+ * recording: hosts that want voice/video/screen capture pass their own
6
+ * composer (MOS's ReviewComposer), which takes the same NoteComposerProps.
7
+ *
8
+ * Two modes, like every composer: a submit row (`submitLabel` +
9
+ * `onSubmit`, cleared on success, kept on failure) or host-driven
10
+ * (`bind:text` / `bind:clips`, no submit row).
11
+ */
12
+ import type { NoteComposerProps } from "./types.js";
13
+ declare const PlainComposer: import("svelte").Component<NoteComposerProps, {}, "text" | "clips">;
14
+ type PlainComposer = ReturnType<typeof PlainComposer>;
15
+ export default PlainComposer;
@@ -0,0 +1,102 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SectionTools (origin mos-8fvt9) — a section's own controls on its
4
+ * heading row: the block's Listen pill (when it reads prose) and its
5
+ * comment pill, right-aligned and compact, ON the heading's line rather
6
+ * than stacked above it.
7
+ *
8
+ * Placement is a right float the heading (and the text after it) wraps
9
+ * around, so a long heading never collides with the controls on a phone.
10
+ * The host wraps it in a `flow-root` box so the float never overhangs
11
+ * into the next block. When a Listen player opens, its bar replaces the
12
+ * pill and the group takes the full width — the transport lives with the
13
+ * text it reads.
14
+ *
15
+ * Listen comes from the host's Listen snippet (HostAdapter.listen, or a
16
+ * provideBlockListen() override below it; none on a share link → no
17
+ * Listen); the comment pill is `ctx.tools` from BlockRenderer (none
18
+ * without comments → nothing). With neither, nothing renders at all.
19
+ */
20
+ import { hostAdapter } from "./adapter.js"
21
+ import { blockListen } from "./listen/context.js"
22
+ import type { BlockContext } from "./types.js"
23
+
24
+ interface Props {
25
+ ctx: BlockContext | undefined
26
+ /**
27
+ * Human name of what this block's Listen reads ("What this page is"),
28
+ * completing "Listen to: <label>". Omitted = no Listen (a block that
29
+ * is not prose: a stats grid, a table).
30
+ */
31
+ listenLabel?: string | null
32
+ /**
33
+ * A flex item in the block's own title row instead of a float (blocks
34
+ * whose title is a short line above a grid, table or media: a float
35
+ * there would narrow the grid beside it).
36
+ */
37
+ inline?: boolean
38
+ }
39
+
40
+ let { ctx, listenLabel = null, inline = false }: Props = $props()
41
+
42
+ const override = blockListen()
43
+ const adapter = hostAdapter()
44
+ const listen = $derived(
45
+ listenLabel !== null ? (override ? override.render : (adapter.listen ?? null)) : null,
46
+ )
47
+ const group = $derived(`block-${ctx?.blockId ?? ""}`)
48
+
49
+ /** The block's own section is the highlight/scroll-follow target: the
50
+ * group IS BlockRenderer's `<section id>`. */
51
+ function anchorFor(g: string): string {
52
+ return typeof CSS !== "undefined" && CSS.escape ? `#${CSS.escape(g)}` : `#${g}`
53
+ }
54
+ </script>
55
+
56
+ {#if listen || ctx?.tools}
57
+ <div class="section-tools" class:inline data-section-tools>
58
+ {#if listen}
59
+ {@render listen({ group, label: listenLabel ?? "", anchor: anchorFor(group) })}
60
+ {/if}
61
+ {#if ctx?.tools}
62
+ {@render ctx.tools()}
63
+ {/if}
64
+ </div>
65
+ {/if}
66
+
67
+ <style>
68
+ /* Float at the heading's right; the heading wraps around it. The element
69
+ right after the float drops its top margin (a prose h2 carries 2em),
70
+ so the heading's first line sits level with the controls instead of
71
+ a heading-margin below them. */
72
+ .section-tools {
73
+ float: right;
74
+ display: flex;
75
+ align-items: center;
76
+ gap: 0.375rem;
77
+ margin: 0 0 0.25rem 0.75rem;
78
+ }
79
+ .section-tools + :global(*) {
80
+ margin-top: 0 !important;
81
+ }
82
+ .section-tools.inline {
83
+ float: none;
84
+ flex-shrink: 0;
85
+ margin: 0 0 0 auto;
86
+ }
87
+ /* Open: the bar takes the full width, the comment pill stays beside it.
88
+ `.lc-bar` is jatui ListenControl's open bar; a host player can opt in
89
+ with `data-listen-open`. */
90
+ .section-tools:has(:global(.lc-bar)),
91
+ .section-tools:has(:global([data-listen-open])) {
92
+ float: none;
93
+ clear: both;
94
+ width: 100%;
95
+ margin: 0 0 0.5rem 0;
96
+ }
97
+ .section-tools:has(:global(.lc-bar)) > :global(:first-child),
98
+ .section-tools:has(:global([data-listen-open])) > :global(:first-child) {
99
+ flex: 1 1 auto;
100
+ min-width: 0;
101
+ }
102
+ </style>
@@ -0,0 +1,19 @@
1
+ import type { BlockContext } from "./types.js";
2
+ interface Props {
3
+ ctx: BlockContext | undefined;
4
+ /**
5
+ * Human name of what this block's Listen reads ("What this page is"),
6
+ * completing "Listen to: <label>". Omitted = no Listen (a block that
7
+ * is not prose: a stats grid, a table).
8
+ */
9
+ listenLabel?: string | null;
10
+ /**
11
+ * A flex item in the block's own title row instead of a float (blocks
12
+ * whose title is a short line above a grid, table or media: a float
13
+ * there would narrow the grid beside it).
14
+ */
15
+ inline?: boolean;
16
+ }
17
+ declare const SectionTools: import("svelte").Component<Props, {}, "">;
18
+ type SectionTools = ReturnType<typeof SectionTools>;
19
+ export default SectionTools;
@@ -0,0 +1,13 @@
1
+ import type { BlockServices, HostAdapter } from "./types.js";
2
+ /**
3
+ * The context key itself, for tests that mount a block or a chrome piece
4
+ * directly (`mount(C, { context: new Map([[HOST_ADAPTER_KEY, adapter]]) })`).
5
+ * Hosts call provideHostAdapter() (or pass `adapter` to the view).
6
+ */
7
+ export declare const HOST_ADAPTER_KEY: symbol;
8
+ /** Host-side: publish the adapter to every component below. */
9
+ export declare function provideHostAdapter(adapter: HostAdapter | null | undefined): void;
10
+ /** Component-side: the adapter, or the empty (read-only) one. */
11
+ export declare function hostAdapter(): HostAdapter;
12
+ /** The block services (always an object). */
13
+ export declare function hostServices(adapter: HostAdapter): BlockServices;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The HostAdapter on the Svelte context chain (jatui-vsuzi).
3
+ *
4
+ * BlocksArtifactView (or a bare BlockRenderer) publishes the host's adapter
5
+ * once; every component below — BlockVerdict, BlockComments, NoteComposer,
6
+ * SectionTools and any block — reads it from here instead of importing a
7
+ * host module. No adapter → the read-only defaults: no comments, no review
8
+ * send, text-only notes, no Listen, no history, no live-data refresh.
9
+ */
10
+ import { getContext, setContext } from "svelte";
11
+ const KEY = Symbol("artifact-blocks-host-adapter");
12
+ /**
13
+ * The context key itself, for tests that mount a block or a chrome piece
14
+ * directly (`mount(C, { context: new Map([[HOST_ADAPTER_KEY, adapter]]) })`).
15
+ * Hosts call provideHostAdapter() (or pass `adapter` to the view).
16
+ */
17
+ export const HOST_ADAPTER_KEY = KEY;
18
+ const EMPTY = Object.freeze({});
19
+ const NO_SERVICES = Object.freeze({});
20
+ /** Host-side: publish the adapter to every component below. */
21
+ export function provideHostAdapter(adapter) {
22
+ setContext(KEY, adapter ?? EMPTY);
23
+ }
24
+ /** Component-side: the adapter, or the empty (read-only) one. */
25
+ export function hostAdapter() {
26
+ return getContext(KEY) ?? EMPTY;
27
+ }
28
+ /** The block services (always an object). */
29
+ export function hostServices(adapter) {
30
+ return adapter.services ?? NO_SERVICES;
31
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Auto-send when a review is complete (mos-yra79, Joe 2026-10-19: "after I
3
+ * do it in the page I have to come back here and click Send? Why didn't
4
+ * they send at the time?").
5
+ *
6
+ * The moment the viewer decides the LAST open item on a page, the page
7
+ * sends by itself after a short grace: "All decided · sending in 5s ·
8
+ * Undo". Undo keeps the page a draft. The send is the page's own Send
9
+ * (Finish review / Done reviewing): no new semantics.
10
+ *
11
+ * The rule, as a state machine fed by the page on every change:
12
+ *
13
+ * - it arms only on a TRANSITION to complete seen in this tab. A page
14
+ * that loads already complete (an old unsent draft) never sends by
15
+ * itself; the desk's "Send all" is for those;
16
+ * - any open item again (an undecided verdict) cancels, and re-arms on
17
+ * the next completion;
18
+ * - Undo cancels and stays cancelled until the page is incomplete again,
19
+ * so a viewer who said "not yet" is not asked again by the next save;
20
+ * - typing (`bump`) restarts the grace, so a note the viewer is still
21
+ * writing is never cut off mid-word. The send flushes it first.
22
+ *
23
+ * Runes module: each call creates its own state capsule.
24
+ */
25
+ export interface AutoSend {
26
+ /** A send is counting down. */
27
+ readonly pending: boolean;
28
+ /** Whole seconds left on the countdown (0 when not pending). */
29
+ readonly remaining: number;
30
+ /** Feed the page's state: every unit decided, and a send is possible. */
31
+ update: (complete: boolean, eligible: boolean) => void;
32
+ /** Cancel the countdown and keep the page a draft. */
33
+ undo: () => void;
34
+ /** Send now, skipping the rest of the grace. */
35
+ sendNow: () => void;
36
+ /** The viewer is still typing: restart the grace. */
37
+ bump: () => void;
38
+ /** Tear down timers (unmount). */
39
+ stop: () => void;
40
+ }
41
+ interface AutoSendOptions {
42
+ /** The grace before the send, in ms. */
43
+ delayMs?: number;
44
+ /** The page's own send. */
45
+ onSend: () => void | Promise<void>;
46
+ }
47
+ export declare const AUTO_SEND_DELAY_MS = 5000;
48
+ export declare function createAutoSend(opts: AutoSendOptions): AutoSend;
49
+ export {};
@@ -0,0 +1,103 @@
1
+ /* autoSend.svelte.js generated by Svelte v5.53.11 */
2
+ import * as $ from 'svelte/internal/client';
3
+
4
+ export const AUTO_SEND_DELAY_MS = 5_000;
5
+
6
+ export function createAutoSend(opts) {
7
+ const delay = opts.delayMs ?? AUTO_SEND_DELAY_MS;
8
+ let pending = $.state(false);
9
+ let remaining = $.state(0);
10
+
11
+ /** The last state seen; null before the first update (the baseline). */
12
+ let wasComplete = null;
13
+
14
+ /** Undo was pressed on this completion. */
15
+ let dismissed = false;
16
+
17
+ let deadline = 0;
18
+ let fireTimer = null;
19
+ let tickTimer = null;
20
+
21
+ function clearTimers() {
22
+ if (fireTimer !== null) clearTimeout(fireTimer);
23
+ if (tickTimer !== null) clearInterval(tickTimer);
24
+
25
+ fireTimer = null;
26
+ tickTimer = null;
27
+ }
28
+
29
+ function cancel() {
30
+ clearTimers();
31
+ $.set(pending, false);
32
+ $.set(remaining, 0);
33
+ }
34
+
35
+ function fire() {
36
+ cancel();
37
+ void opts.onSend();
38
+ }
39
+
40
+ function arm() {
41
+ clearTimers();
42
+ $.set(pending, true);
43
+ deadline = Date.now() + delay;
44
+ $.set(remaining, Math.ceil(delay / 1000), true);
45
+ fireTimer = setTimeout(fire, delay);
46
+
47
+ tickTimer = setInterval(
48
+ () => {
49
+ $.set(remaining, Math.max(0, Math.ceil((deadline - Date.now()) / 1000)), true);
50
+ },
51
+ 250
52
+ );
53
+ }
54
+
55
+ return {
56
+ get pending() {
57
+ return $.get(pending);
58
+ },
59
+
60
+ get remaining() {
61
+ return $.get(remaining);
62
+ },
63
+
64
+ update(complete, eligible) {
65
+ const prev = wasComplete;
66
+
67
+ wasComplete = complete;
68
+
69
+ if (!complete) {
70
+ dismissed = false;
71
+
72
+ if ($.get(pending)) cancel();
73
+
74
+ return;
75
+ }
76
+
77
+ if (!eligible) {
78
+ if ($.get(pending)) cancel();
79
+
80
+ return;
81
+ }
82
+
83
+ if (prev === false && !$.get(pending) && !dismissed) arm();
84
+ },
85
+
86
+ undo() {
87
+ dismissed = true;
88
+ cancel();
89
+ },
90
+
91
+ sendNow() {
92
+ if ($.get(pending)) fire();
93
+ },
94
+
95
+ bump() {
96
+ if ($.get(pending)) arm();
97
+ },
98
+
99
+ stop() {
100
+ clearTimers();
101
+ }
102
+ };
103
+ }