@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.
- package/dist/artifact-blocks/AttachmentChip.svelte +66 -0
- package/dist/artifact-blocks/AttachmentChip.svelte.d.ts +7 -0
- package/dist/artifact-blocks/BlockComments.svelte +309 -0
- package/dist/artifact-blocks/BlockComments.svelte.d.ts +33 -0
- package/dist/artifact-blocks/BlockRenderer.svelte +674 -0
- package/dist/artifact-blocks/BlockRenderer.svelte.d.ts +55 -0
- package/dist/artifact-blocks/BlockVerdict.svelte +151 -0
- package/dist/artifact-blocks/BlockVerdict.svelte.d.ts +13 -0
- package/dist/artifact-blocks/BlocksArtifactView.svelte +1616 -0
- package/dist/artifact-blocks/BlocksArtifactView.svelte.d.ts +113 -0
- package/dist/artifact-blocks/CONTRACT.md +225 -0
- package/dist/artifact-blocks/CommentPill.svelte +49 -0
- package/dist/artifact-blocks/CommentPill.svelte.d.ts +16 -0
- package/dist/artifact-blocks/FoldedRounds.svelte +95 -0
- package/dist/artifact-blocks/FoldedRounds.svelte.d.ts +9 -0
- package/dist/artifact-blocks/Glyph.svelte +54 -0
- package/dist/artifact-blocks/Glyph.svelte.d.ts +10 -0
- package/dist/artifact-blocks/HistoryScrubber.svelte +500 -0
- package/dist/artifact-blocks/HistoryScrubber.svelte.d.ts +15 -0
- package/dist/artifact-blocks/Markdown.svelte +186 -0
- package/dist/artifact-blocks/Markdown.svelte.d.ts +30 -0
- package/dist/artifact-blocks/NoteComposer.svelte +31 -0
- package/dist/artifact-blocks/NoteComposer.svelte.d.ts +8 -0
- package/dist/artifact-blocks/PlainComposer.svelte +200 -0
- package/dist/artifact-blocks/PlainComposer.svelte.d.ts +15 -0
- package/dist/artifact-blocks/SectionTools.svelte +102 -0
- package/dist/artifact-blocks/SectionTools.svelte.d.ts +19 -0
- package/dist/artifact-blocks/adapter.d.ts +13 -0
- package/dist/artifact-blocks/adapter.js +31 -0
- package/dist/artifact-blocks/autoSend.d.ts +49 -0
- package/dist/artifact-blocks/autoSend.js +103 -0
- package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte +557 -0
- package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte.d.ts +48 -0
- package/dist/artifact-blocks/blocks/actions/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/actions/block.js +74 -0
- package/dist/artifact-blocks/blocks/actions/requests.d.ts +62 -0
- package/dist/artifact-blocks/blocks/actions/requests.js +26 -0
- package/dist/artifact-blocks/blocks/actions/schema.d.ts +168 -0
- package/dist/artifact-blocks/blocks/actions/schema.js +253 -0
- package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte +779 -0
- package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte.d.ts +40 -0
- package/dist/artifact-blocks/blocks/callout/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/callout/block.js +39 -0
- package/dist/artifact-blocks/blocks/callout/schema.d.ts +72 -0
- package/dist/artifact-blocks/blocks/callout/schema.js +115 -0
- package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte +875 -0
- package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte.d.ts +59 -0
- package/dist/artifact-blocks/blocks/chart/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/chart/block.js +70 -0
- package/dist/artifact-blocks/blocks/chart/schema.d.ts +171 -0
- package/dist/artifact-blocks/blocks/chart/schema.js +498 -0
- package/dist/artifact-blocks/blocks/chart/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/chart/thumb.js +201 -0
- package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte +1048 -0
- package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte.d.ts +16 -0
- package/dist/artifact-blocks/blocks/checklist/Icon.svelte +105 -0
- package/dist/artifact-blocks/blocks/checklist/Icon.svelte.d.ts +17 -0
- package/dist/artifact-blocks/blocks/checklist/block.d.ts +10 -0
- package/dist/artifact-blocks/blocks/checklist/block.js +63 -0
- package/dist/artifact-blocks/blocks/checklist/itemReview.d.ts +16 -0
- package/dist/artifact-blocks/blocks/checklist/itemReview.js +63 -0
- package/dist/artifact-blocks/blocks/checklist/labels.d.ts +62 -0
- package/dist/artifact-blocks/blocks/checklist/labels.js +96 -0
- package/dist/artifact-blocks/blocks/checklist/retest.d.ts +43 -0
- package/dist/artifact-blocks/blocks/checklist/retest.js +68 -0
- package/dist/artifact-blocks/blocks/checklist/schema.d.ts +84 -0
- package/dist/artifact-blocks/blocks/checklist/schema.js +91 -0
- package/dist/artifact-blocks/blocks/code/CodeBlock.svelte +128 -0
- package/dist/artifact-blocks/blocks/code/CodeBlock.svelte.d.ts +12 -0
- package/dist/artifact-blocks/blocks/code/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/code/block.js +31 -0
- package/dist/artifact-blocks/blocks/code/highlight.d.ts +34 -0
- package/dist/artifact-blocks/blocks/code/highlight.js +280 -0
- package/dist/artifact-blocks/blocks/code/schema.d.ts +32 -0
- package/dist/artifact-blocks/blocks/code/schema.js +39 -0
- package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte +290 -0
- package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte.d.ts +29 -0
- package/dist/artifact-blocks/blocks/collage/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/collage/block.js +29 -0
- package/dist/artifact-blocks/blocks/collage/schema.d.ts +52 -0
- package/dist/artifact-blocks/blocks/collage/schema.js +86 -0
- package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte +484 -0
- package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte.d.ts +25 -0
- package/dist/artifact-blocks/blocks/compare/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/compare/block.js +32 -0
- package/dist/artifact-blocks/blocks/compare/schema.d.ts +74 -0
- package/dist/artifact-blocks/blocks/compare/schema.js +148 -0
- package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte +392 -0
- package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte.d.ts +30 -0
- package/dist/artifact-blocks/blocks/diagram/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/diagram/block.js +50 -0
- package/dist/artifact-blocks/blocks/diagram/constants.d.ts +48 -0
- package/dist/artifact-blocks/blocks/diagram/constants.js +53 -0
- package/dist/artifact-blocks/blocks/diagram/schema.d.ts +161 -0
- package/dist/artifact-blocks/blocks/diagram/schema.js +621 -0
- package/dist/artifact-blocks/blocks/diagram/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/diagram/thumb.js +157 -0
- package/dist/artifact-blocks/blocks/diagram/types.d.ts +74 -0
- package/dist/artifact-blocks/blocks/diagram/types.js +1 -0
- package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte +81 -0
- package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte.d.ts +10 -0
- package/dist/artifact-blocks/blocks/diff/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/diff/block.js +36 -0
- package/dist/artifact-blocks/blocks/diff/schema.d.ts +18 -0
- package/dist/artifact-blocks/blocks/diff/schema.js +35 -0
- package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte +1055 -0
- package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/diff-review/block.d.ts +15 -0
- package/dist/artifact-blocks/blocks/diff-review/block.js +64 -0
- package/dist/artifact-blocks/blocks/diff-review/decisions.d.ts +57 -0
- package/dist/artifact-blocks/blocks/diff-review/decisions.js +80 -0
- package/dist/artifact-blocks/blocks/diff-review/schema.d.ts +13 -0
- package/dist/artifact-blocks/blocks/diff-review/schema.js +84 -0
- package/dist/artifact-blocks/blocks/diff-review/types.d.ts +35 -0
- package/dist/artifact-blocks/blocks/diff-review/types.js +1 -0
- package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte +145 -0
- package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/explainer/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/explainer/block.js +21 -0
- package/dist/artifact-blocks/blocks/explainer/schema.d.ts +26 -0
- package/dist/artifact-blocks/blocks/explainer/schema.js +69 -0
- package/dist/artifact-blocks/blocks/group-content.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-content.js +16 -0
- package/dist/artifact-blocks/blocks/group-data.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-data.js +7 -0
- package/dist/artifact-blocks/blocks/group-review.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-review.js +12 -0
- package/dist/artifact-blocks/blocks/group-visual.d.ts +17 -0
- package/dist/artifact-blocks/blocks/group-visual.js +14 -0
- package/dist/artifact-blocks/blocks/map/MapBlock.svelte +413 -0
- package/dist/artifact-blocks/blocks/map/MapBlock.svelte.d.ts +53 -0
- package/dist/artifact-blocks/blocks/map/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/map/block.js +62 -0
- package/dist/artifact-blocks/blocks/map/schema.d.ts +123 -0
- package/dist/artifact-blocks/blocks/map/schema.js +113 -0
- package/dist/artifact-blocks/blocks/map/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/map/thumb.js +69 -0
- package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte +33 -0
- package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte.d.ts +15 -0
- package/dist/artifact-blocks/blocks/markdown/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/markdown/block.js +28 -0
- package/dist/artifact-blocks/blocks/markdown/render.d.ts +17 -0
- package/dist/artifact-blocks/blocks/markdown/render.js +115 -0
- package/dist/artifact-blocks/blocks/markdown/schema.d.ts +10 -0
- package/dist/artifact-blocks/blocks/markdown/schema.js +23 -0
- package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte +2112 -0
- package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/media-picker/block.d.ts +24 -0
- package/dist/artifact-blocks/blocks/media-picker/block.js +137 -0
- package/dist/artifact-blocks/blocks/media-picker/choices.d.ts +28 -0
- package/dist/artifact-blocks/blocks/media-picker/choices.js +35 -0
- package/dist/artifact-blocks/blocks/media-picker/decisions.d.ts +51 -0
- package/dist/artifact-blocks/blocks/media-picker/decisions.js +75 -0
- package/dist/artifact-blocks/blocks/media-picker/schema.d.ts +7 -0
- package/dist/artifact-blocks/blocks/media-picker/schema.js +199 -0
- package/dist/artifact-blocks/blocks/media-picker/types.d.ts +92 -0
- package/dist/artifact-blocks/blocks/media-picker/types.js +1 -0
- package/dist/artifact-blocks/blocks/media-picker/versions.d.ts +51 -0
- package/dist/artifact-blocks/blocks/media-picker/versions.js +118 -0
- package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte +213 -0
- package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/mockup/block.d.ts +26 -0
- package/dist/artifact-blocks/blocks/mockup/block.js +52 -0
- package/dist/artifact-blocks/blocks/mockup/doc.d.ts +24 -0
- package/dist/artifact-blocks/blocks/mockup/doc.js +44 -0
- package/dist/artifact-blocks/blocks/mockup/sandbox.d.ts +21 -0
- package/dist/artifact-blocks/blocks/mockup/sandbox.js +27 -0
- package/dist/artifact-blocks/blocks/mockup/schema.d.ts +7 -0
- package/dist/artifact-blocks/blocks/mockup/schema.js +90 -0
- package/dist/artifact-blocks/blocks/mockup/types.d.ts +36 -0
- package/dist/artifact-blocks/blocks/mockup/types.js +17 -0
- package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte +359 -0
- package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte.d.ts +32 -0
- package/dist/artifact-blocks/blocks/program/block.d.ts +35 -0
- package/dist/artifact-blocks/blocks/program/block.js +68 -0
- package/dist/artifact-blocks/blocks/program/schema.d.ts +132 -0
- package/dist/artifact-blocks/blocks/program/schema.js +268 -0
- package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte +315 -0
- package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte.d.ts +24 -0
- package/dist/artifact-blocks/blocks/stats/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/stats/block.js +49 -0
- package/dist/artifact-blocks/blocks/stats/schema.d.ts +82 -0
- package/dist/artifact-blocks/blocks/stats/schema.js +43 -0
- package/dist/artifact-blocks/blocks/stats/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/stats/thumb.js +102 -0
- package/dist/artifact-blocks/blocks/table/TableBlock.svelte +490 -0
- package/dist/artifact-blocks/blocks/table/TableBlock.svelte.d.ts +28 -0
- package/dist/artifact-blocks/blocks/table/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/table/block.js +100 -0
- package/dist/artifact-blocks/blocks/table/schema.d.ts +143 -0
- package/dist/artifact-blocks/blocks/table/schema.js +278 -0
- package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte +347 -0
- package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte.d.ts +42 -0
- package/dist/artifact-blocks/blocks/timeline/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/timeline/block.js +96 -0
- package/dist/artifact-blocks/blocks/timeline/constants.d.ts +26 -0
- package/dist/artifact-blocks/blocks/timeline/constants.js +27 -0
- package/dist/artifact-blocks/blocks/timeline/schema.d.ts +102 -0
- package/dist/artifact-blocks/blocks/timeline/schema.js +405 -0
- package/dist/artifact-blocks/blocks/timeline/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/timeline/thumb.js +117 -0
- package/dist/artifact-blocks/blocks/timeline/types.d.ts +66 -0
- package/dist/artifact-blocks/blocks/timeline/types.js +1 -0
- package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte +169 -0
- package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte.d.ts +26 -0
- package/dist/artifact-blocks/blocks/transcript/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/transcript/block.js +86 -0
- package/dist/artifact-blocks/blocks/transcript/schema.d.ts +114 -0
- package/dist/artifact-blocks/blocks/transcript/schema.js +126 -0
- package/dist/artifact-blocks/builtins.d.ts +40 -0
- package/dist/artifact-blocks/builtins.js +22 -0
- package/dist/artifact-blocks/contractBlocks.d.ts +92 -0
- package/dist/artifact-blocks/contractBlocks.js +279 -0
- package/dist/artifact-blocks/history.d.ts +140 -0
- package/dist/artifact-blocks/history.js +363 -0
- package/dist/artifact-blocks/index.d.ts +40 -0
- package/dist/artifact-blocks/index.js +46 -0
- package/dist/artifact-blocks/listen/context.d.ts +30 -0
- package/dist/artifact-blocks/listen/context.js +30 -0
- package/dist/artifact-blocks/liveData.d.ts +78 -0
- package/dist/artifact-blocks/liveData.js +137 -0
- package/dist/artifact-blocks/liveDataPoller.d.ts +41 -0
- package/dist/artifact-blocks/liveDataPoller.js +140 -0
- package/dist/artifact-blocks/openNav.d.ts +46 -0
- package/dist/artifact-blocks/openNav.js +106 -0
- package/dist/artifact-blocks/pageReviewKeys.d.ts +17 -0
- package/dist/artifact-blocks/pageReviewKeys.js +115 -0
- package/dist/artifact-blocks/params.d.ts +98 -0
- package/dist/artifact-blocks/params.js +159 -0
- package/dist/artifact-blocks/registry.d.ts +27 -0
- package/dist/artifact-blocks/registry.js +83 -0
- package/dist/artifact-blocks/review/BlockIcon.svelte +99 -0
- package/dist/artifact-blocks/review/BlockIcon.svelte.d.ts +17 -0
- package/dist/artifact-blocks/review/BulkRejectForm.svelte +94 -0
- package/dist/artifact-blocks/review/BulkRejectForm.svelte.d.ts +11 -0
- package/dist/artifact-blocks/review/BulkUndoBar.svelte +40 -0
- package/dist/artifact-blocks/review/BulkUndoBar.svelte.d.ts +9 -0
- package/dist/artifact-blocks/review/ItemNote.svelte +193 -0
- package/dist/artifact-blocks/review/ItemNote.svelte.d.ts +33 -0
- package/dist/artifact-blocks/review/NoteToggle.svelte +52 -0
- package/dist/artifact-blocks/review/NoteToggle.svelte.d.ts +12 -0
- package/dist/artifact-blocks/review/TeamChip.svelte +71 -0
- package/dist/artifact-blocks/review/TeamChip.svelte.d.ts +8 -0
- package/dist/artifact-blocks/review/attachments.d.ts +10 -0
- package/dist/artifact-blocks/review/attachments.js +37 -0
- package/dist/artifact-blocks/review/bulk.d.ts +52 -0
- package/dist/artifact-blocks/review/bulk.js +61 -0
- package/dist/artifact-blocks/review/itemReview.d.ts +33 -0
- package/dist/artifact-blocks/review/itemReview.js +112 -0
- package/dist/artifact-blocks/review/roundLines.d.ts +14 -0
- package/dist/artifact-blocks/review/roundLines.js +20 -0
- package/dist/artifact-blocks/review/rounds.d.ts +86 -0
- package/dist/artifact-blocks/review/rounds.js +302 -0
- package/dist/artifact-blocks/review/saver.d.ts +23 -0
- package/dist/artifact-blocks/review/saver.js +48 -0
- package/dist/artifact-blocks/review/team.d.ts +31 -0
- package/dist/artifact-blocks/review/team.js +42 -0
- package/dist/artifact-blocks/review/visualOrder.d.ts +29 -0
- package/dist/artifact-blocks/review/visualOrder.js +66 -0
- package/dist/artifact-blocks/review.d.ts +180 -0
- package/dist/artifact-blocks/review.js +716 -0
- package/dist/artifact-blocks/thumb-kit.d.ts +80 -0
- package/dist/artifact-blocks/thumb-kit.js +149 -0
- package/dist/artifact-blocks/types.d.ts +513 -0
- package/dist/artifact-blocks/types.js +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared param helpers for artifact blocks (mos-bqeoa, epic mos-m1qrx).
|
|
3
|
+
*
|
|
4
|
+
* Block params are UNTRUSTED agent input. Every block schema composes these
|
|
5
|
+
* helpers instead of hand-rolling its own caps, so the security-relevant
|
|
6
|
+
* rules (URLs may never carry a scheme the browser can act on, text is
|
|
7
|
+
* length-capped, colors are theme tokens only) live in ONE place and can be
|
|
8
|
+
* tested once.
|
|
9
|
+
*
|
|
10
|
+
* Rendering rules these helpers exist to support (CONTRACT.md):
|
|
11
|
+
* - text is rendered as text — never `{@html}` (except the markdown
|
|
12
|
+
* block's sanitized renderer);
|
|
13
|
+
* - a resource URL (img/video/frame) is `https://…` or root-relative
|
|
14
|
+
* (`/path`) — never `http:`, protocol-relative (`//host`),
|
|
15
|
+
* `javascript:`, or any other scheme (`urlSchema`);
|
|
16
|
+
* - a navigation link may also be `http://…` (`linkUrlSchema`).
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
/**
|
|
20
|
+
* A URL an agent may publish. Two shapes only:
|
|
21
|
+
*
|
|
22
|
+
* - absolute HTTPS: `https://host/...` — the scheme is pinned to https, so
|
|
23
|
+
* an `http://` mixed-content load and every non-web scheme are refused;
|
|
24
|
+
* - root-relative: `/path/...` — stays on the host origin the page is
|
|
25
|
+
* already served from (never `//host`, which the browser resolves as
|
|
26
|
+
* protocol-relative and which would leave the origin).
|
|
27
|
+
*
|
|
28
|
+
* Refused by construction: `javascript:`, `data:`, `blob:`, `vbscript:`,
|
|
29
|
+
* `//cdn.evil`, `http://`, relative paths without a leading slash (they
|
|
30
|
+
* resolve against the artifact page URL and drift with routing), backslash
|
|
31
|
+
* tricks (`/\\evil.com` — browsers treat a backslash as a slash, and the
|
|
32
|
+
* point is to stay on-origin), control characters, and whitespace-padded
|
|
33
|
+
* strings that a href parser might otherwise trim.
|
|
34
|
+
*/
|
|
35
|
+
export declare const urlSchema: z.ZodString;
|
|
36
|
+
/**
|
|
37
|
+
* A NAVIGATION link an agent may publish (an `<a href>`, never a resource
|
|
38
|
+
* load): everything `urlSchema` takes, plus absolute `http://`. A link is
|
|
39
|
+
* the viewer choosing to go somewhere — the https pin exists to stop
|
|
40
|
+
* mixed-content LOADS (images, frames, media), which a link never does —
|
|
41
|
+
* and a jat control plane serves its task links over plain http on the
|
|
42
|
+
* tailnet (PARAMS-SPEC §1: meta href / primaryAction url are "http(s) or
|
|
43
|
+
* root-relative"). Every other refusal of urlSchema stands.
|
|
44
|
+
*/
|
|
45
|
+
export declare const linkUrlSchema: z.ZodString;
|
|
46
|
+
/** The link policy as a predicate (the markdown renderer's href check). */
|
|
47
|
+
export declare function isSafeLinkUrl(v: string): boolean;
|
|
48
|
+
/** The resource policy as a predicate (img/video src). */
|
|
49
|
+
export declare function isSafeResourceUrl(v: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* The DaisyUI semantic color tokens a block may tint itself with. A block
|
|
52
|
+
* receives `tone` and resolves it to classes (`text-${tone}` patterns are
|
|
53
|
+
* FORBIDDEN — dynamic class names break Tailwind extraction and the
|
|
54
|
+
* token-only theming rule); a component maps each token to its static
|
|
55
|
+
* class set instead. Hex/rgba/oklch literals are never accepted: theming is
|
|
56
|
+
* token-only, and a publish that hardcodes a color breaks every tenant's
|
|
57
|
+
* skin.
|
|
58
|
+
*/
|
|
59
|
+
export declare const TONE_TOKENS: readonly ["primary", "secondary", "accent", "neutral", "info", "success", "warning", "error"];
|
|
60
|
+
export type ToneToken = (typeof TONE_TOKENS)[number];
|
|
61
|
+
export declare const toneSchema: z.ZodEnum<{
|
|
62
|
+
error: "error";
|
|
63
|
+
warning: "warning";
|
|
64
|
+
info: "info";
|
|
65
|
+
success: "success";
|
|
66
|
+
primary: "primary";
|
|
67
|
+
secondary: "secondary";
|
|
68
|
+
neutral: "neutral";
|
|
69
|
+
accent: "accent";
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* A short line: titles, labels, captions, chip text. 200 matches the
|
|
73
|
+
* artifact title cap; a block header longer than that is copy nobody reads.
|
|
74
|
+
*/
|
|
75
|
+
export declare const shortTextSchema: z.ZodString;
|
|
76
|
+
/**
|
|
77
|
+
* Body text / descriptions / markdown-lite paragraphs. 5000 is several
|
|
78
|
+
* screens of prose; beyond that an agent should be publishing structure
|
|
79
|
+
* (more blocks), not one enormous paragraph.
|
|
80
|
+
*/
|
|
81
|
+
export declare const longTextSchema: z.ZodString;
|
|
82
|
+
/**
|
|
83
|
+
* An ISO 8601 date or datetime (`2026-10-08`, `2026-10-08T14:30:00Z` — full
|
|
84
|
+
* offsets accepted). Validated by parse, not just shape: `2026-02-30` is
|
|
85
|
+
* refused at publish rather than rendering as "Invalid Date".
|
|
86
|
+
*/
|
|
87
|
+
export declare const isoDateSchema: z.ZodString;
|
|
88
|
+
/**
|
|
89
|
+
* An optional URL field: absent/empty stays undefined rather than becoming
|
|
90
|
+
* "" (an empty href renders as a link to the current page).
|
|
91
|
+
*/
|
|
92
|
+
export declare const optionalUrlSchema: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
|
|
93
|
+
/**
|
|
94
|
+
* A list of capped strings for chips/tags/points. Blocks declare their own
|
|
95
|
+
* max length — a chart's max points is a chart decision — but each string is
|
|
96
|
+
* still shortText-capped so one element cannot smuggle a paragraph.
|
|
97
|
+
*/
|
|
98
|
+
export declare function shortTextList(max: number): z.ZodArray<z.ZodString>;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared param helpers for artifact blocks (mos-bqeoa, epic mos-m1qrx).
|
|
3
|
+
*
|
|
4
|
+
* Block params are UNTRUSTED agent input. Every block schema composes these
|
|
5
|
+
* helpers instead of hand-rolling its own caps, so the security-relevant
|
|
6
|
+
* rules (URLs may never carry a scheme the browser can act on, text is
|
|
7
|
+
* length-capped, colors are theme tokens only) live in ONE place and can be
|
|
8
|
+
* tested once.
|
|
9
|
+
*
|
|
10
|
+
* Rendering rules these helpers exist to support (CONTRACT.md):
|
|
11
|
+
* - text is rendered as text — never `{@html}` (except the markdown
|
|
12
|
+
* block's sanitized renderer);
|
|
13
|
+
* - a resource URL (img/video/frame) is `https://…` or root-relative
|
|
14
|
+
* (`/path`) — never `http:`, protocol-relative (`//host`),
|
|
15
|
+
* `javascript:`, or any other scheme (`urlSchema`);
|
|
16
|
+
* - a navigation link may also be `http://…` (`linkUrlSchema`).
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// URLs
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* A URL an agent may publish. Two shapes only:
|
|
24
|
+
*
|
|
25
|
+
* - absolute HTTPS: `https://host/...` — the scheme is pinned to https, so
|
|
26
|
+
* an `http://` mixed-content load and every non-web scheme are refused;
|
|
27
|
+
* - root-relative: `/path/...` — stays on the host origin the page is
|
|
28
|
+
* already served from (never `//host`, which the browser resolves as
|
|
29
|
+
* protocol-relative and which would leave the origin).
|
|
30
|
+
*
|
|
31
|
+
* Refused by construction: `javascript:`, `data:`, `blob:`, `vbscript:`,
|
|
32
|
+
* `//cdn.evil`, `http://`, relative paths without a leading slash (they
|
|
33
|
+
* resolve against the artifact page URL and drift with routing), backslash
|
|
34
|
+
* tricks (`/\\evil.com` — browsers treat a backslash as a slash, and the
|
|
35
|
+
* point is to stay on-origin), control characters, and whitespace-padded
|
|
36
|
+
* strings that a href parser might otherwise trim.
|
|
37
|
+
*/
|
|
38
|
+
export const urlSchema = z
|
|
39
|
+
.string()
|
|
40
|
+
.trim()
|
|
41
|
+
.min(1)
|
|
42
|
+
.max(2048)
|
|
43
|
+
.refine((v) => /^https:\/\/[^\s/?#]+[^\s]*$/.test(v) ||
|
|
44
|
+
/^\/(?!\/|\\)[^\s]*$/.test(v) ||
|
|
45
|
+
/^#[^\s]*$/.test(v), {
|
|
46
|
+
message: "must be an https:// URL or a root-relative path starting with a single /",
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* A NAVIGATION link an agent may publish (an `<a href>`, never a resource
|
|
50
|
+
* load): everything `urlSchema` takes, plus absolute `http://`. A link is
|
|
51
|
+
* the viewer choosing to go somewhere — the https pin exists to stop
|
|
52
|
+
* mixed-content LOADS (images, frames, media), which a link never does —
|
|
53
|
+
* and a jat control plane serves its task links over plain http on the
|
|
54
|
+
* tailnet (PARAMS-SPEC §1: meta href / primaryAction url are "http(s) or
|
|
55
|
+
* root-relative"). Every other refusal of urlSchema stands.
|
|
56
|
+
*/
|
|
57
|
+
export const linkUrlSchema = z
|
|
58
|
+
.string()
|
|
59
|
+
.trim()
|
|
60
|
+
.min(1)
|
|
61
|
+
.max(2048)
|
|
62
|
+
.refine((v) => isSafeLinkUrl(v), {
|
|
63
|
+
message: "must be an http(s):// URL or a root-relative path starting with a single /",
|
|
64
|
+
});
|
|
65
|
+
/** The link policy as a predicate (the markdown renderer's href check). */
|
|
66
|
+
export function isSafeLinkUrl(v) {
|
|
67
|
+
return (/^https?:\/\/[^\s/?#]+[^\s]*$/i.test(v) ||
|
|
68
|
+
/^\/(?!\/|\\)[^\s]*$/.test(v) ||
|
|
69
|
+
/^#[^\s]*$/.test(v));
|
|
70
|
+
}
|
|
71
|
+
/** The resource policy as a predicate (img/video src). */
|
|
72
|
+
export function isSafeResourceUrl(v) {
|
|
73
|
+
return /^https:\/\/[^\s/?#]+[^\s]*$/i.test(v) || /^\/(?!\/|\\)[^\s]*$/.test(v);
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Tone — an enum of THEME tokens, never a raw color
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
/**
|
|
79
|
+
* The DaisyUI semantic color tokens a block may tint itself with. A block
|
|
80
|
+
* receives `tone` and resolves it to classes (`text-${tone}` patterns are
|
|
81
|
+
* FORBIDDEN — dynamic class names break Tailwind extraction and the
|
|
82
|
+
* token-only theming rule); a component maps each token to its static
|
|
83
|
+
* class set instead. Hex/rgba/oklch literals are never accepted: theming is
|
|
84
|
+
* token-only, and a publish that hardcodes a color breaks every tenant's
|
|
85
|
+
* skin.
|
|
86
|
+
*/
|
|
87
|
+
export const TONE_TOKENS = [
|
|
88
|
+
"primary",
|
|
89
|
+
"secondary",
|
|
90
|
+
"accent",
|
|
91
|
+
"neutral",
|
|
92
|
+
"info",
|
|
93
|
+
"success",
|
|
94
|
+
"warning",
|
|
95
|
+
"error",
|
|
96
|
+
];
|
|
97
|
+
export const toneSchema = z.enum(TONE_TOKENS);
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Text caps
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
/**
|
|
102
|
+
* A short line: titles, labels, captions, chip text. 200 matches the
|
|
103
|
+
* artifact title cap; a block header longer than that is copy nobody reads.
|
|
104
|
+
*/
|
|
105
|
+
export const shortTextSchema = z.string().max(200);
|
|
106
|
+
/**
|
|
107
|
+
* Body text / descriptions / markdown-lite paragraphs. 5000 is several
|
|
108
|
+
* screens of prose; beyond that an agent should be publishing structure
|
|
109
|
+
* (more blocks), not one enormous paragraph.
|
|
110
|
+
*/
|
|
111
|
+
export const longTextSchema = z.string().max(5000);
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// Dates
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
/**
|
|
116
|
+
* An ISO 8601 date or datetime (`2026-10-08`, `2026-10-08T14:30:00Z` — full
|
|
117
|
+
* offsets accepted). Validated by parse, not just shape: `2026-02-30` is
|
|
118
|
+
* refused at publish rather than rendering as "Invalid Date".
|
|
119
|
+
*/
|
|
120
|
+
export const isoDateSchema = z
|
|
121
|
+
.string()
|
|
122
|
+
.min(4)
|
|
123
|
+
.max(64)
|
|
124
|
+
.refine((v) => {
|
|
125
|
+
// Date.parse is LENIENT: "2026-02-30" parses (it rolls over to March).
|
|
126
|
+
// Require the ISO shape, reject impossible calendar dates explicitly,
|
|
127
|
+
// then let the parser reject the rest (offsets, hours).
|
|
128
|
+
const m = v.match(/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/);
|
|
129
|
+
if (!m)
|
|
130
|
+
return false;
|
|
131
|
+
const [, y, mo, d, hh, mm, ss] = m;
|
|
132
|
+
const month = Number(mo);
|
|
133
|
+
if (month < 1 || month > 12)
|
|
134
|
+
return false;
|
|
135
|
+
const daysInMonth = new Date(Date.UTC(Number(y), month, 0)).getUTCDate();
|
|
136
|
+
if (Number(d) < 1 || Number(d) > daysInMonth)
|
|
137
|
+
return false;
|
|
138
|
+
if (hh !== undefined && (Number(hh) > 23 || Number(mm) > 59))
|
|
139
|
+
return false;
|
|
140
|
+
if (ss !== undefined && Number(ss) > 60)
|
|
141
|
+
return false; // leap second
|
|
142
|
+
return !Number.isNaN(Date.parse(v));
|
|
143
|
+
}, { message: "must be an ISO 8601 date or datetime" });
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Composed helpers blocks reach for
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
/**
|
|
148
|
+
* An optional URL field: absent/empty stays undefined rather than becoming
|
|
149
|
+
* "" (an empty href renders as a link to the current page).
|
|
150
|
+
*/
|
|
151
|
+
export const optionalUrlSchema = urlSchema.optional().or(z.literal(""));
|
|
152
|
+
/**
|
|
153
|
+
* A list of capped strings for chips/tags/points. Blocks declare their own
|
|
154
|
+
* max length — a chart's max points is a chart decision — but each string is
|
|
155
|
+
* still shortText-capped so one element cannot smuggle a paragraph.
|
|
156
|
+
*/
|
|
157
|
+
export function shortTextList(max) {
|
|
158
|
+
return z.array(shortTextSchema).max(max);
|
|
159
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The block catalog (jatui-vsuzi). MOS discovered `blocks/<type>/block.ts`
|
|
3
|
+
* with `import.meta.glob`; a published library cannot glob its consumer's
|
|
4
|
+
* folders, so jatui keeps an EXPLICIT registry:
|
|
5
|
+
*
|
|
6
|
+
* - the blocks jatui ships are listed once in `builtins.ts` and are in the
|
|
7
|
+
* catalog from this module's first import;
|
|
8
|
+
* - a host adds its own (or replaces one, deliberately) with
|
|
9
|
+
* `registerBlocks(def, …)`.
|
|
10
|
+
*
|
|
11
|
+
* A def's `type` must be kebab-case and unique; registering a second def
|
|
12
|
+
* under a taken type throws unless `{ replace: true }` says so — two blocks
|
|
13
|
+
* silently fighting over one name is how a page renders the wrong widget.
|
|
14
|
+
*/
|
|
15
|
+
import type { ArtifactBlockDef, BlocksSpec, BlockValidationError } from "./types";
|
|
16
|
+
/**
|
|
17
|
+
* Register one or more block defs. Throws on a malformed type or a
|
|
18
|
+
* duplicate (unless `replace`). Returns an unregister function for tests
|
|
19
|
+
* and hot reload.
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerBlocks(input: ArtifactBlockDef<any> | ArtifactBlockDef<any>[], opts?: {
|
|
22
|
+
replace?: boolean;
|
|
23
|
+
}): () => void;
|
|
24
|
+
export declare function blockDef(type: string): ArtifactBlockDef | undefined;
|
|
25
|
+
export declare function allBlockDefs(): ArtifactBlockDef[];
|
|
26
|
+
/** Validate a whole spec. Returns [] when every block is known and valid. */
|
|
27
|
+
export declare function validateBlocksSpec(spec: BlocksSpec): BlockValidationError[];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { blockLinkErrors } from "./contractBlocks";
|
|
2
|
+
import { BUILTIN_BLOCKS } from "./builtins.js";
|
|
3
|
+
// Module-level, one catalog per JS realm (SSR and the browser each build
|
|
4
|
+
// their own from the same builtins + host registrations). Built LAZILY, on
|
|
5
|
+
// the first call: a block that imports the registry (program validates its
|
|
6
|
+
// nested visual through blockDef) sits inside builtins.ts's own import
|
|
7
|
+
// graph, so when builtins.ts is the entry this module evaluates before
|
|
8
|
+
// BUILTIN_BLOCKS exists. By the first call every barrel has loaded.
|
|
9
|
+
let defs = null;
|
|
10
|
+
const catalog = () => (defs ??= new Map(BUILTIN_BLOCKS.map((d) => [d.type, d])));
|
|
11
|
+
const TYPE_RE = /^[a-z][a-z0-9-]{0,47}$/;
|
|
12
|
+
/**
|
|
13
|
+
* Register one or more block defs. Throws on a malformed type or a
|
|
14
|
+
* duplicate (unless `replace`). Returns an unregister function for tests
|
|
15
|
+
* and hot reload.
|
|
16
|
+
*/
|
|
17
|
+
export function registerBlocks(input, opts = {}) {
|
|
18
|
+
const list = Array.isArray(input) ? input : [input];
|
|
19
|
+
const cat = catalog();
|
|
20
|
+
for (const def of list) {
|
|
21
|
+
if (!def || typeof def.type !== "string" || !TYPE_RE.test(def.type))
|
|
22
|
+
throw new Error(`artifact block: type "${def?.type}" must be kebab-case (a-z0-9-)`);
|
|
23
|
+
if (cat.has(def.type) && cat.get(def.type) !== def && !opts.replace)
|
|
24
|
+
throw new Error(`artifact block "${def.type}" is already registered (pass { replace: true } to override it)`);
|
|
25
|
+
}
|
|
26
|
+
for (const def of list)
|
|
27
|
+
cat.set(def.type, def);
|
|
28
|
+
return () => {
|
|
29
|
+
for (const def of list)
|
|
30
|
+
if (cat.get(def.type) === def)
|
|
31
|
+
cat.delete(def.type);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function blockDef(type) {
|
|
35
|
+
return catalog().get(type);
|
|
36
|
+
}
|
|
37
|
+
export function allBlockDefs() {
|
|
38
|
+
return [...catalog().values()].sort((a, b) => a.type.localeCompare(b.type));
|
|
39
|
+
}
|
|
40
|
+
const BLOCK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
41
|
+
/** Validate a whole spec. Returns [] when every block is known and valid. */
|
|
42
|
+
export function validateBlocksSpec(spec) {
|
|
43
|
+
const errors = [];
|
|
44
|
+
const seen = new Set();
|
|
45
|
+
for (const b of spec.blocks ?? []) {
|
|
46
|
+
const def = catalog().get(b.type);
|
|
47
|
+
if (!BLOCK_ID_RE.test(b.id ?? ""))
|
|
48
|
+
errors.push({
|
|
49
|
+
blockId: String(b.id),
|
|
50
|
+
type: b.type,
|
|
51
|
+
path: "id",
|
|
52
|
+
message: "id must be lowercase a-z0-9_- (max 64)",
|
|
53
|
+
});
|
|
54
|
+
else if (seen.has(b.id))
|
|
55
|
+
errors.push({
|
|
56
|
+
blockId: b.id,
|
|
57
|
+
type: b.type,
|
|
58
|
+
path: "id",
|
|
59
|
+
message: "duplicate block id",
|
|
60
|
+
});
|
|
61
|
+
seen.add(b.id);
|
|
62
|
+
errors.push(...blockLinkErrors(b));
|
|
63
|
+
if (!def) {
|
|
64
|
+
errors.push({
|
|
65
|
+
blockId: b.id,
|
|
66
|
+
type: b.type,
|
|
67
|
+
path: "type",
|
|
68
|
+
message: `unknown block type (known: ${[...catalog().keys()].sort().join(", ")})`,
|
|
69
|
+
});
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const r = def.schema.safeParse(b.params);
|
|
73
|
+
if (!r.success)
|
|
74
|
+
for (const issue of r.error.issues)
|
|
75
|
+
errors.push({
|
|
76
|
+
blockId: b.id,
|
|
77
|
+
type: b.type,
|
|
78
|
+
path: issue.path.join("."),
|
|
79
|
+
message: issue.message,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return errors;
|
|
83
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* The glyphs the review / interactive blocks draw (lucide paths, ISC),
|
|
4
|
+
* inline so jatui carries no icon-library dependency — MOS imported these
|
|
5
|
+
* from lucide-svelte. Same props as a lucide component (`size`,
|
|
6
|
+
* `stroke-width`, `class`), so a port is a rename.
|
|
7
|
+
*/
|
|
8
|
+
export type BlockIconName =
|
|
9
|
+
| "check"
|
|
10
|
+
| "circle"
|
|
11
|
+
| "circle-check"
|
|
12
|
+
| "circle-help"
|
|
13
|
+
| "circle-alert"
|
|
14
|
+
| "info"
|
|
15
|
+
| "triangle-alert"
|
|
16
|
+
| "clock"
|
|
17
|
+
| "loader-circle"
|
|
18
|
+
| "send"
|
|
19
|
+
| "sticky-note"
|
|
20
|
+
| "circle-dot-dashed"
|
|
21
|
+
| "rotate-ccw"
|
|
22
|
+
| "external-link"
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
let {
|
|
27
|
+
name,
|
|
28
|
+
size = 16,
|
|
29
|
+
"stroke-width": strokeWidth = 2,
|
|
30
|
+
class: cls = "",
|
|
31
|
+
"aria-hidden": ariaHidden = "true",
|
|
32
|
+
}: {
|
|
33
|
+
name: BlockIconName
|
|
34
|
+
size?: number
|
|
35
|
+
"stroke-width"?: number
|
|
36
|
+
class?: string
|
|
37
|
+
"aria-hidden"?: "true" | "false" | boolean
|
|
38
|
+
} = $props()
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<svg
|
|
42
|
+
width={size}
|
|
43
|
+
height={size}
|
|
44
|
+
viewBox="0 0 24 24"
|
|
45
|
+
fill="none"
|
|
46
|
+
stroke="currentColor"
|
|
47
|
+
stroke-width={strokeWidth}
|
|
48
|
+
stroke-linecap="round"
|
|
49
|
+
stroke-linejoin="round"
|
|
50
|
+
class={cls}
|
|
51
|
+
aria-hidden={ariaHidden}
|
|
52
|
+
focusable="false"
|
|
53
|
+
>
|
|
54
|
+
{#if name === "check"}
|
|
55
|
+
<path d="M20 6 9 17l-5-5" />
|
|
56
|
+
{:else if name === "circle"}
|
|
57
|
+
<circle cx="12" cy="12" r="10" />
|
|
58
|
+
{:else if name === "circle-check"}
|
|
59
|
+
<circle cx="12" cy="12" r="10" /><path d="m9 12 2 2 4-4" />
|
|
60
|
+
{:else if name === "circle-help"}
|
|
61
|
+
<circle cx="12" cy="12" r="10" /><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" /><path
|
|
62
|
+
d="M12 17h.01"
|
|
63
|
+
/>
|
|
64
|
+
{:else if name === "circle-alert"}
|
|
65
|
+
<circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" />
|
|
66
|
+
{:else if name === "info"}
|
|
67
|
+
<circle cx="12" cy="12" r="10" /><path d="M12 16v-4" /><path d="M12 8h.01" />
|
|
68
|
+
{:else if name === "triangle-alert"}
|
|
69
|
+
<path
|
|
70
|
+
d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
|
|
71
|
+
/><path d="M12 9v4" /><path d="M12 17h.01" />
|
|
72
|
+
{:else if name === "clock"}
|
|
73
|
+
<circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" />
|
|
74
|
+
{:else if name === "loader-circle"}
|
|
75
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
76
|
+
{:else if name === "send"}
|
|
77
|
+
<path
|
|
78
|
+
d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"
|
|
79
|
+
/><path d="m21.854 2.147-10.94 10.939" />
|
|
80
|
+
{:else if name === "sticky-note"}
|
|
81
|
+
<path d="M16 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8Z" /><path
|
|
82
|
+
d="M15 3v4a2 2 0 0 0 2 2h4"
|
|
83
|
+
/>
|
|
84
|
+
{:else if name === "circle-dot-dashed"}
|
|
85
|
+
<path d="M10.1 2.18a9.93 9.93 0 0 1 3.8 0" /><path d="M17.6 3.71a9.95 9.95 0 0 1 2.69 2.7" /><path
|
|
86
|
+
d="M21.82 10.1a9.93 9.93 0 0 1 0 3.8"
|
|
87
|
+
/><path d="M20.29 17.6a9.95 9.95 0 0 1-2.7 2.69" /><path
|
|
88
|
+
d="M13.9 21.82a9.94 9.94 0 0 1-3.8 0"
|
|
89
|
+
/><path d="M6.4 20.29a9.95 9.95 0 0 1-2.69-2.7" /><path
|
|
90
|
+
d="M2.18 13.9a9.93 9.93 0 0 1 0-3.8"
|
|
91
|
+
/><path d="M3.71 6.4a9.95 9.95 0 0 1 2.7-2.69" /><circle cx="12" cy="12" r="1" />
|
|
92
|
+
{:else if name === "rotate-ccw"}
|
|
93
|
+
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /><path d="M3 3v5h5" />
|
|
94
|
+
{:else}
|
|
95
|
+
<path d="M15 3h6v6" /><path d="M10 14 21 3" /><path
|
|
96
|
+
d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
|
|
97
|
+
/>
|
|
98
|
+
{/if}
|
|
99
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The glyphs the review / interactive blocks draw (lucide paths, ISC),
|
|
3
|
+
* inline so jatui carries no icon-library dependency — MOS imported these
|
|
4
|
+
* from lucide-svelte. Same props as a lucide component (`size`,
|
|
5
|
+
* `stroke-width`, `class`), so a port is a rename.
|
|
6
|
+
*/
|
|
7
|
+
export type BlockIconName = "check" | "circle" | "circle-check" | "circle-help" | "circle-alert" | "info" | "triangle-alert" | "clock" | "loader-circle" | "send" | "sticky-note" | "circle-dot-dashed" | "rotate-ccw" | "external-link";
|
|
8
|
+
type $$ComponentProps = {
|
|
9
|
+
name: BlockIconName;
|
|
10
|
+
size?: number;
|
|
11
|
+
"stroke-width"?: number;
|
|
12
|
+
class?: string;
|
|
13
|
+
"aria-hidden"?: "true" | "false" | boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const BlockIcon: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
16
|
+
type BlockIcon = ReturnType<typeof BlockIcon>;
|
|
17
|
+
export default BlockIcon;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* BulkRejectForm — the confirm for a bulk Reject (mos-u8i35), inline in
|
|
4
|
+
* the block (diff-review, media-picker). A reject normally carries a
|
|
5
|
+
* reason, so instead of N notes the reviewer writes ONE: "Why? Applies to
|
|
6
|
+
* all N". It joins each item's own draft note, and every item can still
|
|
7
|
+
* get its own note after.
|
|
8
|
+
*
|
|
9
|
+
* Enter rejects (Shift+Enter is a new line); Esc or Cancel backs out.
|
|
10
|
+
*/
|
|
11
|
+
import { onMount } from "svelte"
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
count,
|
|
15
|
+
noun,
|
|
16
|
+
onConfirm,
|
|
17
|
+
onCancel,
|
|
18
|
+
}: {
|
|
19
|
+
/** How many items the reject will decide. */
|
|
20
|
+
count: number
|
|
21
|
+
/** Singular noun: "line", "item". */
|
|
22
|
+
noun: string
|
|
23
|
+
onConfirm: (note: string) => void
|
|
24
|
+
onCancel: () => void
|
|
25
|
+
} = $props()
|
|
26
|
+
|
|
27
|
+
let note = $state("")
|
|
28
|
+
let textarea = $state<HTMLTextAreaElement | null>(null)
|
|
29
|
+
const what = $derived(count === 1 ? `1 ${noun}` : `${count} ${noun}s`)
|
|
30
|
+
const ready = $derived(note.trim().length > 0)
|
|
31
|
+
|
|
32
|
+
onMount(() => textarea?.focus())
|
|
33
|
+
|
|
34
|
+
function submit() {
|
|
35
|
+
if (ready) onConfirm(note.trim())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function onKeydown(e: KeyboardEvent) {
|
|
39
|
+
if (e.isComposing) return
|
|
40
|
+
if (e.key === "Escape") {
|
|
41
|
+
e.preventDefault()
|
|
42
|
+
e.stopPropagation()
|
|
43
|
+
onCancel()
|
|
44
|
+
} else if (e.key === "Enter" && !e.shiftKey) {
|
|
45
|
+
e.preventDefault()
|
|
46
|
+
submit()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<form
|
|
52
|
+
class="mx-4 mt-3 flex flex-col gap-2 rounded-field border border-error/40 bg-error/5 px-3 py-2.5 text-sm sm:mx-5"
|
|
53
|
+
aria-label="Reject {what}"
|
|
54
|
+
data-bulk-reject-form
|
|
55
|
+
onsubmit={(e) => {
|
|
56
|
+
e.preventDefault()
|
|
57
|
+
submit()
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<p class="font-medium">Reject {what}?</p>
|
|
61
|
+
<label class="flex flex-col gap-1">
|
|
62
|
+
<span class="text-xs text-base-content/80">
|
|
63
|
+
Why? This note applies to all {what}. You can add a note to any one after.
|
|
64
|
+
</span>
|
|
65
|
+
<textarea
|
|
66
|
+
bind:this={textarea}
|
|
67
|
+
bind:value={note}
|
|
68
|
+
class="textarea textarea-sm min-h-16 w-full resize-y rounded-field border-base-content/15 bg-base-100 text-sm"
|
|
69
|
+
rows="2"
|
|
70
|
+
maxlength={2000}
|
|
71
|
+
required
|
|
72
|
+
onkeydown={onKeydown}
|
|
73
|
+
></textarea>
|
|
74
|
+
</label>
|
|
75
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
76
|
+
<span class="text-xs text-base-content/70"
|
|
77
|
+
>{noun[0].toUpperCase()}{noun.slice(1)}s you already decided stay as they
|
|
78
|
+
are.</span
|
|
79
|
+
>
|
|
80
|
+
<button
|
|
81
|
+
type="button"
|
|
82
|
+
class="btn btn-ghost btn-xs ml-auto rounded-field"
|
|
83
|
+
onclick={onCancel}>Cancel</button
|
|
84
|
+
>
|
|
85
|
+
<button
|
|
86
|
+
type="submit"
|
|
87
|
+
class="btn btn-error btn-xs rounded-field"
|
|
88
|
+
disabled={!ready}
|
|
89
|
+
data-bulk-reject-confirm
|
|
90
|
+
>
|
|
91
|
+
Reject {what}
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
</form>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
/** How many items the reject will decide. */
|
|
3
|
+
count: number;
|
|
4
|
+
/** Singular noun: "line", "item". */
|
|
5
|
+
noun: string;
|
|
6
|
+
onConfirm: (note: string) => void;
|
|
7
|
+
onCancel: () => void;
|
|
8
|
+
};
|
|
9
|
+
declare const BulkRejectForm: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type BulkRejectForm = ReturnType<typeof BulkRejectForm>;
|
|
11
|
+
export default BulkRejectForm;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* BulkUndoBar — "Accepted 12 lines. [Undo] [✕]" after a bulk verdict
|
|
4
|
+
* (mos-nv4eb, mos-u8i35). Tone follows the verdict the bulk cast. Undo
|
|
5
|
+
* reverts the bulk only; anything flipped after it stays flipped.
|
|
6
|
+
*/
|
|
7
|
+
let {
|
|
8
|
+
message,
|
|
9
|
+
tone,
|
|
10
|
+
onUndo,
|
|
11
|
+
onDismiss,
|
|
12
|
+
}: {
|
|
13
|
+
message: string
|
|
14
|
+
tone: "success" | "error"
|
|
15
|
+
onUndo: () => void
|
|
16
|
+
onDismiss: () => void
|
|
17
|
+
} = $props()
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div
|
|
21
|
+
class="mx-4 mt-3 flex items-center gap-2 rounded-field border px-3 py-2 text-sm sm:mx-5 {tone ===
|
|
22
|
+
'error'
|
|
23
|
+
? 'border-error/40 bg-error/10'
|
|
24
|
+
: 'border-success/40 bg-success/10'}"
|
|
25
|
+
role="status"
|
|
26
|
+
data-bulk-undo
|
|
27
|
+
>
|
|
28
|
+
<span>{message}</span>
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
class="btn btn-xs ml-auto rounded-field"
|
|
32
|
+
onclick={onUndo}>Undo</button
|
|
33
|
+
>
|
|
34
|
+
<button
|
|
35
|
+
type="button"
|
|
36
|
+
class="btn btn-ghost btn-xs rounded-field"
|
|
37
|
+
aria-label="Dismiss"
|
|
38
|
+
onclick={onDismiss}>✕</button
|
|
39
|
+
>
|
|
40
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
message: string;
|
|
3
|
+
tone: "success" | "error";
|
|
4
|
+
onUndo: () => void;
|
|
5
|
+
onDismiss: () => void;
|
|
6
|
+
};
|
|
7
|
+
declare const BulkUndoBar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type BulkUndoBar = ReturnType<typeof BulkUndoBar>;
|
|
9
|
+
export default BulkUndoBar;
|