@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,92 @@
1
+ /**
2
+ * The jat provider contract's block-level surface (jat
3
+ * docs/artifacts/provider-contract.md), read into the renderer's own blocks.
4
+ *
5
+ * - P10 `decision` block: the contract's decision card
6
+ * `{ question, options: [string | { letter?, label, detail? }],
7
+ * recommended?, context? }`. The renderer stores it as its NATIVE decision
8
+ * callout (variant `decision`, one option per letter, the context as the
9
+ * body), so every surface that already reads decision callouts — the
10
+ * page, the desk, the dock, the census, the Finish review panel — serves
11
+ * a contract card with no second renderer. The translation runs at
12
+ * publish; the stored spec is the callout.
13
+ * - P11 per-block task links (mos-4tgfj): a block may carry its OWN jat
14
+ * `taskId`, and a decision block that also carries one may name the
15
+ * jat-decision it mirrors (`decisionId`). A finished review answers each
16
+ * linked block on that block's task (feedbackReview.ts → F13).
17
+ *
18
+ * Pure and isomorphic: the service and the MCP publish tool both call it.
19
+ */
20
+ import { z } from "zod";
21
+ import type { BlockInstance, BlocksSpec, BlockValidationError } from "./types";
22
+ /**
23
+ * P11: a block `taskId` matches the P6 shape, and a `decisionId` only rides
24
+ * a decision block that also carries a `taskId`. Anything else is an error
25
+ * (the publish answers 422 and stores nothing).
26
+ */
27
+ export declare function blockLinkErrors(b: BlockInstance): BlockValidationError[];
28
+ /** A linked block's task (and mirrored decision), keyed by block id. */
29
+ interface BlockTaskLink {
30
+ taskId: string;
31
+ decisionId: string | null;
32
+ }
33
+ /**
34
+ * F13: block id → its own linked task, for the blocks of a STORED spec that
35
+ * carry a valid one (untrusted jsonb: anything malformed is skipped, never
36
+ * answered).
37
+ */
38
+ export declare function blockTasksOf(spec: unknown): Map<string, BlockTaskLink>;
39
+ export declare const decisionMetaSchema: z.ZodArray<z.ZodObject<{
40
+ label: z.ZodString;
41
+ value: z.ZodString;
42
+ href: z.ZodOptional<z.ZodString>;
43
+ title: z.ZodOptional<z.ZodString>;
44
+ tone: z.ZodOptional<z.ZodEnum<{
45
+ error: "error";
46
+ warning: "warning";
47
+ info: "info";
48
+ success: "success";
49
+ neutral: "neutral";
50
+ }>>;
51
+ }, z.core.$strip>>;
52
+ /** Sections' markdown shares the callout body's 20,000-character budget. */
53
+ export declare const DECISION_BODY_BUDGET = 20000;
54
+ export declare const decisionSectionsSchema: z.ZodArray<z.ZodObject<{
55
+ heading: z.ZodString;
56
+ markdown: z.ZodString;
57
+ open: z.ZodOptional<z.ZodBoolean>;
58
+ }, z.core.$strip>>;
59
+ export declare const decisionPrimaryActionSchema: z.ZodObject<{
60
+ label: z.ZodString;
61
+ url: z.ZodString;
62
+ }, z.core.$strip>;
63
+ export declare const blockGroupSchema: z.ZodObject<{
64
+ key: z.ZodString;
65
+ label: z.ZodString;
66
+ quiet: z.ZodOptional<z.ZodBoolean>;
67
+ }, z.core.$strip>;
68
+ export declare const decisionTitleSchema: z.ZodString;
69
+ /**
70
+ * The optional NEEDS YOU fields of one card, each validated alone: a
71
+ * well-formed field passes through (parsed, so trims apply), a malformed
72
+ * one is DROPPED and named in `warnings` — never a refused publish
73
+ * (PARAMS-SPEC §1 "drop (not refuse)").
74
+ */
75
+ export declare function decisionExtras(params: Record<string, unknown>): {
76
+ extras: Record<string, unknown>;
77
+ warnings: Array<[string, string]>;
78
+ };
79
+ /**
80
+ * Read a publish's spec through the contract: every `decision` block becomes
81
+ * a decision callout (its id, owner, taskId and decisionId kept), and the
82
+ * malformed ones come back as errors. A malformed OPTIONAL card field
83
+ * (title, meta, sections, primaryAction, group) is dropped and comes back
84
+ * as a warning — the publish still succeeds. Blocks of every other type
85
+ * pass through untouched, so this is idempotent on an already-native spec.
86
+ */
87
+ export declare function normalizeContractBlocks(spec: BlocksSpec): {
88
+ spec: BlocksSpec;
89
+ errors: BlockValidationError[];
90
+ warnings: BlockValidationError[];
91
+ };
92
+ export {};
@@ -0,0 +1,279 @@
1
+ /**
2
+ * The jat provider contract's block-level surface (jat
3
+ * docs/artifacts/provider-contract.md), read into the renderer's own blocks.
4
+ *
5
+ * - P10 `decision` block: the contract's decision card
6
+ * `{ question, options: [string | { letter?, label, detail? }],
7
+ * recommended?, context? }`. The renderer stores it as its NATIVE decision
8
+ * callout (variant `decision`, one option per letter, the context as the
9
+ * body), so every surface that already reads decision callouts — the
10
+ * page, the desk, the dock, the census, the Finish review panel — serves
11
+ * a contract card with no second renderer. The translation runs at
12
+ * publish; the stored spec is the callout.
13
+ * - P11 per-block task links (mos-4tgfj): a block may carry its OWN jat
14
+ * `taskId`, and a decision block that also carries one may name the
15
+ * jat-decision it mirrors (`decisionId`). A finished review answers each
16
+ * linked block on that block's task (feedbackReview.ts → F13).
17
+ *
18
+ * Pure and isomorphic: the service and the MCP publish tool both call it.
19
+ */
20
+ import { z } from "zod";
21
+ import { linkUrlSchema } from "./params";
22
+ /** Contract P6 shape: project key, dash, base-36 id, optional `.N` children. */
23
+ const BLOCK_TASK_ID_RE = /^[a-z0-9][a-z0-9_-]*-[a-z0-9]+(\.[0-9]+)*$/;
24
+ const MAX_BLOCK_TASK_ID = 64;
25
+ /** Contract P11: a jat-decision id. */
26
+ const DECISION_ID_RE = /^dec-[A-Za-z0-9_-]{1,64}$/;
27
+ const LETTER_RE = /^[A-Z]$/;
28
+ const MAX_OPTIONS = 26;
29
+ const MAX_LABEL = 120;
30
+ const MAX_DETAIL = 300;
31
+ const MAX_QUESTION = 500;
32
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
33
+ /** Is this block a decision card (the contract type, or the native callout)? */
34
+ function isDecisionInstance(b) {
35
+ return (b.type === "decision" ||
36
+ (b.type === "callout" && isObj(b.params) && b.params.variant === "decision"));
37
+ }
38
+ /**
39
+ * P11: a block `taskId` matches the P6 shape, and a `decisionId` only rides
40
+ * a decision block that also carries a `taskId`. Anything else is an error
41
+ * (the publish answers 422 and stores nothing).
42
+ */
43
+ export function blockLinkErrors(b) {
44
+ const errors = [];
45
+ const at = (path, message) => errors.push({ blockId: String(b.id), type: b.type, path, message });
46
+ if (b.taskId !== undefined) {
47
+ if (typeof b.taskId !== "string" ||
48
+ b.taskId.length > MAX_BLOCK_TASK_ID ||
49
+ !BLOCK_TASK_ID_RE.test(b.taskId))
50
+ at("taskId", "taskId must be a jat task id (e.g. mos-9unv1, jat-abc.3)");
51
+ }
52
+ if (b.decisionId !== undefined) {
53
+ if (!isDecisionInstance(b))
54
+ at("decisionId", "decisionId belongs on a decision block");
55
+ else if (typeof b.taskId !== "string")
56
+ at("decisionId", "decisionId needs the block's own taskId");
57
+ else if (typeof b.decisionId !== "string" ||
58
+ !DECISION_ID_RE.test(b.decisionId))
59
+ at("decisionId", "decisionId must look like dec-<id>");
60
+ }
61
+ return errors;
62
+ }
63
+ /**
64
+ * F13: block id → its own linked task, for the blocks of a STORED spec that
65
+ * carry a valid one (untrusted jsonb: anything malformed is skipped, never
66
+ * answered).
67
+ */
68
+ export function blockTasksOf(spec) {
69
+ const out = new Map();
70
+ const blocks = isObj(spec) && Array.isArray(spec.blocks) ? spec.blocks : [];
71
+ for (const b of blocks) {
72
+ if (!isObj(b) || typeof b.id !== "string")
73
+ continue;
74
+ if (typeof b.taskId !== "string" ||
75
+ b.taskId.length > MAX_BLOCK_TASK_ID ||
76
+ !BLOCK_TASK_ID_RE.test(b.taskId))
77
+ continue;
78
+ const decisionId = typeof b.decisionId === "string" &&
79
+ DECISION_ID_RE.test(b.decisionId) &&
80
+ isDecisionInstance({ type: String(b.type), params: b.params })
81
+ ? b.decisionId
82
+ : null;
83
+ out.set(b.id, { taskId: b.taskId, decisionId });
84
+ }
85
+ return out;
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // The NEEDS YOU card fields (PARAMS-SPEC §1, jat-j49id → jatui-vsuzi)
89
+ // ---------------------------------------------------------------------------
90
+ //
91
+ // Additive and optional: a decision card may carry a topic `title`, a
92
+ // compact `meta` row, collapsed markdown `sections`, a `primaryAction`
93
+ // link button and the `group` it belongs to. None of them is answerable —
94
+ // links navigate, they never post a verdict. Exported so the callout block
95
+ // validates its params with the SAME limits the normalizer enforces.
96
+ const META_TONES = ["neutral", "info", "success", "warning", "error"];
97
+ export const decisionMetaSchema = z
98
+ .array(z.object({
99
+ label: z.string().trim().min(1).max(24),
100
+ value: z.string().trim().min(1).max(80),
101
+ href: linkUrlSchema.optional(),
102
+ title: z.string().max(120).optional(),
103
+ tone: z.enum(META_TONES).optional(),
104
+ }))
105
+ .max(8);
106
+ /** Sections' markdown shares the callout body's 20,000-character budget. */
107
+ export const DECISION_BODY_BUDGET = 20_000;
108
+ export const decisionSectionsSchema = z
109
+ .array(z.object({
110
+ heading: z.string().trim().min(1).max(60),
111
+ markdown: z.string().max(DECISION_BODY_BUDGET),
112
+ open: z.boolean().optional(),
113
+ }))
114
+ .max(8)
115
+ .refine((list) => list.reduce((n, s) => n + s.markdown.length, 0) <= DECISION_BODY_BUDGET, `sections share a ${DECISION_BODY_BUDGET}-character budget`);
116
+ export const decisionPrimaryActionSchema = z.object({
117
+ label: z.string().trim().min(1).max(60),
118
+ url: linkUrlSchema,
119
+ });
120
+ export const blockGroupSchema = z.object({
121
+ key: z.string().regex(/^[a-z0-9-]{1,32}$/, "group key must be [a-z0-9-]{1,32}"),
122
+ label: z.string().trim().min(1).max(60),
123
+ quiet: z.boolean().optional(),
124
+ });
125
+ export const decisionTitleSchema = z.string().trim().min(1).max(120);
126
+ const DECISION_EXTRAS = {
127
+ title: decisionTitleSchema,
128
+ meta: decisionMetaSchema,
129
+ sections: decisionSectionsSchema,
130
+ primaryAction: decisionPrimaryActionSchema,
131
+ group: blockGroupSchema,
132
+ };
133
+ /**
134
+ * The optional NEEDS YOU fields of one card, each validated alone: a
135
+ * well-formed field passes through (parsed, so trims apply), a malformed
136
+ * one is DROPPED and named in `warnings` — never a refused publish
137
+ * (PARAMS-SPEC §1 "drop (not refuse)").
138
+ */
139
+ export function decisionExtras(params) {
140
+ const extras = {};
141
+ const warnings = [];
142
+ for (const [key, schema] of Object.entries(DECISION_EXTRAS)) {
143
+ if (params[key] === undefined)
144
+ continue;
145
+ const r = schema.safeParse(params[key]);
146
+ if (r.success)
147
+ extras[key] = r.data;
148
+ else {
149
+ const issue = r.error.issues[0];
150
+ const at = issue?.path.length ? `.${issue.path.join(".")}` : "";
151
+ warnings.push([
152
+ `${key}${at}`,
153
+ `dropped: ${issue?.message ?? "malformed"}`,
154
+ ]);
155
+ }
156
+ }
157
+ return { extras, warnings };
158
+ }
159
+ /**
160
+ * One contract decision card → the decision callout params, or the list of
161
+ * reasons it is not a card (P10). Letters default to A, B, C… by position;
162
+ * each becomes the callout option id (lower-cased), so a saved pick maps back
163
+ * to its letter.
164
+ */
165
+ function decisionToCallout(params) {
166
+ const errors = [];
167
+ if (!isObj(params))
168
+ return { ok: false, errors: [["", "params must be an object"]] };
169
+ const q = typeof params.question === "string"
170
+ ? params.question.trim()
171
+ : typeof params.title === "string"
172
+ ? params.title.trim()
173
+ : "";
174
+ if (!q)
175
+ errors.push(["question", "a decision needs a question"]);
176
+ else if (q.length > MAX_QUESTION)
177
+ errors.push([
178
+ "question",
179
+ `question must be ${MAX_QUESTION} characters or fewer`,
180
+ ]);
181
+ const raw = Array.isArray(params.options) ? params.options : null;
182
+ if (!raw || raw.length < 2 || raw.length > MAX_OPTIONS)
183
+ errors.push(["options", `a decision needs 2-${MAX_OPTIONS} options`]);
184
+ const options = [];
185
+ const seen = new Set();
186
+ for (const [i, o] of (raw ?? []).entries()) {
187
+ const label = typeof o === "string"
188
+ ? o.trim()
189
+ : isObj(o) && typeof o.label === "string"
190
+ ? o.label.trim()
191
+ : "";
192
+ const letter = isObj(o) && o.letter !== undefined
193
+ ? o.letter
194
+ : String.fromCharCode(65 + i);
195
+ const detail = isObj(o) && typeof o.detail === "string" ? o.detail.trim() : "";
196
+ if (!label)
197
+ errors.push([`options.${i}`, "an option needs a label"]);
198
+ else if (label.length > MAX_LABEL)
199
+ errors.push([
200
+ `options.${i}.label`,
201
+ `label must be ${MAX_LABEL} characters or fewer`,
202
+ ]);
203
+ if (typeof letter !== "string" || !LETTER_RE.test(letter))
204
+ errors.push([`options.${i}.letter`, "letter must be one capital A-Z"]);
205
+ else if (seen.has(letter))
206
+ errors.push([`options.${i}.letter`, `letter ${letter} is used twice`]);
207
+ else
208
+ seen.add(letter);
209
+ if (detail.length > MAX_DETAIL)
210
+ errors.push([
211
+ `options.${i}.detail`,
212
+ `detail must be ${MAX_DETAIL} characters or fewer`,
213
+ ]);
214
+ if (typeof letter === "string" && LETTER_RE.test(letter))
215
+ options.push({
216
+ id: letter.toLowerCase(),
217
+ letter,
218
+ label,
219
+ ...(detail ? { detail } : {}),
220
+ });
221
+ }
222
+ if (params.recommended !== undefined && !seen.has(String(params.recommended)))
223
+ errors.push([
224
+ "recommended",
225
+ "recommended must be one of the card's letters",
226
+ ]);
227
+ if (params.context !== undefined && typeof params.context !== "string")
228
+ errors.push(["context", "context must be markdown text"]);
229
+ if (errors.length)
230
+ return { ok: false, errors };
231
+ const { extras, warnings } = decisionExtras(params);
232
+ return {
233
+ ok: true,
234
+ warnings,
235
+ params: {
236
+ // The topic `title` (the card's `question` stays the ask itself).
237
+ ...extras,
238
+ variant: "decision",
239
+ question: q,
240
+ options,
241
+ ...(typeof params.recommended === "string"
242
+ ? { recommended: params.recommended }
243
+ : {}),
244
+ ...(typeof params.context === "string" && params.context.trim()
245
+ ? { body: params.context }
246
+ : {}),
247
+ },
248
+ };
249
+ }
250
+ /**
251
+ * Read a publish's spec through the contract: every `decision` block becomes
252
+ * a decision callout (its id, owner, taskId and decisionId kept), and the
253
+ * malformed ones come back as errors. A malformed OPTIONAL card field
254
+ * (title, meta, sections, primaryAction, group) is dropped and comes back
255
+ * as a warning — the publish still succeeds. Blocks of every other type
256
+ * pass through untouched, so this is idempotent on an already-native spec.
257
+ */
258
+ export function normalizeContractBlocks(spec) {
259
+ const errors = [];
260
+ const warnings = [];
261
+ if (!Array.isArray(spec?.blocks))
262
+ return { spec, errors, warnings };
263
+ let changed = false;
264
+ const blocks = spec.blocks.map((b) => {
265
+ if (!isObj(b) || b.type !== "decision")
266
+ return b;
267
+ const r = decisionToCallout(b.params);
268
+ if (!r.ok) {
269
+ for (const [path, message] of r.errors)
270
+ errors.push({ blockId: String(b.id), type: "decision", path, message });
271
+ return b;
272
+ }
273
+ for (const [path, message] of r.warnings)
274
+ warnings.push({ blockId: String(b.id), type: "decision", path, message });
275
+ changed = true;
276
+ return { ...b, type: "callout", params: r.params };
277
+ });
278
+ return { spec: changed ? { ...spec, blocks } : spec, errors, warnings };
279
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * History scrubber model (mos-p9m3g, living artifacts phase 4).
3
+ *
4
+ * "What did this page look like yesterday at 9am?" A blocks page has two
5
+ * clocks, and the state at any instant is one reading of each:
6
+ *
7
+ * LAYOUT the artifact_versions row live at that instant (the highest
8
+ * version created at or before it);
9
+ * DATA the artifact_data_history snapshot live at that instant (the
10
+ * newest recorded at or before it — migration 20272490000210
11
+ * captures every change of artifacts.data by trigger).
12
+ *
13
+ * This module is PURE (no db, no fetch): the history route resolves an
14
+ * instant with it on the server, and HistoryScrubber builds its timeline and
15
+ * diffs with it in the browser.
16
+ *
17
+ * Diffs are SHAPE-AWARE but never shape-dependent: a stats-shaped value
18
+ * (`cards[]` with label + numeric value) diffs as KPI deltas, a table-shaped
19
+ * value (`rows[]`) diffs as added / removed / changed rows, and anything
20
+ * else diffs as its changed numeric and text leaves. Data is untrusted: every
21
+ * reader here tolerates any JSON and caps what it reports.
22
+ */
23
+ /** Mirrors the trigger's prune rule in drizzle/20272490000210 — keep both in
24
+ * step. The scrubber names where the trail ends with these. */
25
+ export declare const HISTORY_RETENTION: {
26
+ readonly maxSnapshots: 500;
27
+ readonly maxAgeDays: 30;
28
+ readonly maxBytes: number;
29
+ };
30
+ /** A layout version, as the history route lists it. */
31
+ export interface HistoryVersion {
32
+ version: number;
33
+ /** ISO timestamp. */
34
+ createdAt: string;
35
+ kind: "html" | "blocks";
36
+ changeNote: string | null;
37
+ }
38
+ /** A data snapshot, as the history route lists it (no payload). */
39
+ export interface HistorySnapshot {
40
+ id: string;
41
+ /** ISO timestamp — when artifacts.data BECAME this value. */
42
+ at: string;
43
+ bytes: number;
44
+ /** The layout version live when the data changed (context only). */
45
+ version: number | null;
46
+ }
47
+ /** One stop on the scrubber: a layout publish or a data change. */
48
+ export interface TimelinePoint {
49
+ kind: "version" | "data";
50
+ /** ISO timestamp. */
51
+ at: string;
52
+ /** Epoch ms of `at` (sort key). */
53
+ ms: number;
54
+ version?: number;
55
+ snapshotId?: string;
56
+ }
57
+ /** What the page showed at one instant: which layout + which data. */
58
+ export interface PageStateRef {
59
+ /** Null before the first version (cannot happen for a real artifact). */
60
+ version: number | null;
61
+ /** Null when no snapshot exists at or before the instant. */
62
+ snapshotId: string | null;
63
+ /** When that snapshot's data took effect. */
64
+ dataAt: string | null;
65
+ }
66
+ /**
67
+ * Merge versions and snapshots into one chronological list (oldest first).
68
+ * Entries with an unparseable timestamp are dropped — a point the scrubber
69
+ * cannot place is a point it cannot honestly show. At equal instants a
70
+ * version sorts before a data change (a republish then a data push in the
71
+ * same second reads in that order).
72
+ */
73
+ export declare function buildTimeline(versions: readonly HistoryVersion[], snapshots: readonly HistorySnapshot[]): TimelinePoint[];
74
+ /**
75
+ * The page state live at `atMs`: the newest version created at or before it
76
+ * and the newest snapshot recorded at or before it. Before the first
77
+ * snapshot, snapshotId is null — the page showed its inline params (or the
78
+ * trail was pruned; the caller says which via `trailStart`).
79
+ */
80
+ export declare function stateAt(versions: readonly HistoryVersion[], snapshots: readonly HistorySnapshot[], atMs: number): PageStateRef;
81
+ /** The oldest instant the trail can answer for, or null with no snapshots. */
82
+ export declare function trailStart(snapshots: readonly HistorySnapshot[]): string | null;
83
+ export interface KpiDelta {
84
+ label: string;
85
+ then: number | null;
86
+ now: number | null;
87
+ /** now - then; null when either side is missing. */
88
+ delta: number | null;
89
+ /** delta / |then| (0.042 = +4.2%); null when then is 0 or missing. */
90
+ pct: number | null;
91
+ }
92
+ export interface RowChange {
93
+ key: string;
94
+ /** Columns whose cell differs (changed rows only). */
95
+ fields: string[];
96
+ }
97
+ export interface LeafChange {
98
+ path: string;
99
+ then: string | number | boolean | null | undefined;
100
+ now: string | number | boolean | null | undefined;
101
+ delta: number | null;
102
+ }
103
+ export type KeyDiff = {
104
+ key: string;
105
+ status: "added" | "removed" | "same";
106
+ } | {
107
+ key: string;
108
+ status: "changed";
109
+ shape: "kpi";
110
+ kpis: KpiDelta[];
111
+ } | {
112
+ key: string;
113
+ status: "changed";
114
+ shape: "table";
115
+ added: RowChange[];
116
+ removed: RowChange[];
117
+ changed: RowChange[];
118
+ /** Rows beyond MAX_DIFF_ENTRIES across the three lists. */
119
+ truncated: number;
120
+ } | {
121
+ key: string;
122
+ status: "changed";
123
+ shape: "value";
124
+ leaves: LeafChange[];
125
+ truncated: number;
126
+ };
127
+ export interface DataDiff {
128
+ keys: KeyDiff[];
129
+ /** Count of keys whose status is not "same". */
130
+ changedKeys: number;
131
+ }
132
+ /**
133
+ * Diff two live-data blobs key by key (`then` → `now`). Keys are reported in
134
+ * `now`'s order, then keys only `then` had. A non-object side reads as {}.
135
+ */
136
+ export declare function diffData(then: unknown, now: unknown): DataDiff;
137
+ /** "+4.2%", "−1,203", "0" — a signed delta for display (U+2212 minus). */
138
+ export declare function formatDelta(delta: number, pct?: number | null): string;
139
+ /** Parse a `?at=` query value: ISO-8601 or epoch ms. NaN when neither. */
140
+ export declare function parseInstant(raw: string | null): number;