@lostgradient/cinder 0.7.0 → 0.9.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/CHANGELOG.md +23 -0
- package/README.md +7 -2
- package/components.json +59 -15
- package/dist/components/_internal/command-list-context.d.ts +3 -3
- package/dist/components/_internal/create-command-list-state.svelte.d.ts +11 -11
- package/dist/components/access-gate/index.js +201 -126
- package/dist/components/approval-card/approval-card-actions.svelte.d.ts +16 -0
- package/dist/components/approval-card/approval-card-state.d.ts +65 -0
- package/dist/components/approval-card/approval-card.css +269 -92
- package/dist/components/approval-card/approval-card.schema.js +10 -31
- package/dist/components/approval-card/approval-card.svelte.d.ts +3 -3
- package/dist/components/approval-card/approval-card.types.d.ts +14 -28
- package/dist/components/approval-card/index.d.ts +1 -1
- package/dist/components/approval-card/index.js +4268 -2884
- package/dist/components/card/card.css +5 -0
- package/dist/components/card/card.schema.js +2 -2
- package/dist/components/card/card.types.d.ts +2 -2
- package/dist/components/card/index.js +2 -1
- package/dist/components/chat/chat.schema.js +48 -1
- package/dist/components/chat/chat.svelte.d.ts +6 -2
- package/dist/components/chat/chat.types.d.ts +37 -0
- package/dist/components/chat/container/chat.svelte.d.ts +6 -2
- package/dist/components/chat/index.d.ts +3 -3
- package/dist/components/chat/index.js +1099 -4865
- package/dist/components/chat/input/chat-attachment-serialization.d.ts +9 -0
- package/dist/components/chat/input/chat-input.svelte.d.ts +24 -0
- package/dist/components/chat/input/index.d.ts +1 -0
- package/dist/components/chat-composer-popover/chat-composer-popover-filter.d.ts +11 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.css +7 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.css.d.ts +1 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.schema.d.ts +3 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.schema.js +150 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.svelte.d.ts +46 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.types.d.ts +77 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.variables.d.ts +2 -0
- package/dist/components/chat-composer-popover/chat-composer-popover.variables.js +61 -0
- package/dist/components/chat-composer-popover/index.d.ts +6 -0
- package/dist/components/chat-composer-popover/index.js +3285 -0
- package/dist/components/chat-conversation-header/index.js +1627 -5600
- package/dist/components/chat-conversation-list/index.js +15 -3988
- package/dist/components/code-block/code-block.schema.js +5 -1
- package/dist/components/code-block/code-block.types.d.ts +6 -0
- package/dist/components/code-block/index.js +4 -4
- package/dist/components/command-item/index.js +7 -6
- package/dist/components/command-menu/command-menu.schema.js +5 -1
- package/dist/components/command-menu/command-menu.types.d.ts +2 -0
- package/dist/components/command-menu/index.js +48 -19
- package/dist/components/command-palette/index.js +40 -14
- package/dist/components/event-stream-viewer/index.js +44 -44
- package/dist/components/experimental/json-viewer/index.js +44 -44
- package/dist/components/json-schema-editor/index.js +5 -2
- package/dist/components/json-viewer/index.js +44 -44
- package/dist/components/json-viewer/json-viewer.css +10 -6
- package/dist/components/navigation-bar/index.js +44 -6
- package/dist/components/payload-inspector/index.d.ts +1 -1
- package/dist/components/payload-inspector/index.js +306 -1422
- package/dist/components/payload-inspector/payload-inspector.css +15 -75
- package/dist/components/payload-inspector/payload-inspector.schema.js +5 -41
- package/dist/components/payload-inspector/payload-inspector.svelte.d.ts +5 -5
- package/dist/components/payload-inspector/payload-inspector.types.d.ts +10 -56
- package/dist/components/sidebar/index.js +6 -3
- package/dist/components/sidebar/sidebar.css +4 -0
- package/dist/components/tab/index.js +5 -2
- package/dist/components/tab/tab.schema.js +7 -3
- package/dist/components/tab/tab.svelte.d.ts +2 -1
- package/dist/components/tab/tab.types.d.ts +8 -2
- package/dist/components/tabs/index.js +5 -2
- package/dist/components/team-section/index.js +2 -1
- package/dist/components/testimonial-section/index.js +2 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +24169 -27821
- package/dist/server/components/access-gate/index.js +2 -1
- package/dist/server/components/accordion/index.js +2 -2
- package/dist/server/components/alert-dialog/index.js +2 -2
- package/dist/server/components/approval-card/index.js +15 -19
- package/dist/server/components/autocomplete/index.js +7 -7
- package/dist/server/components/avatar-group/index.js +5 -5
- package/dist/server/components/button-group/index.js +3 -5
- package/dist/server/components/card/index.js +2 -2
- package/dist/server/components/chat/index.js +14 -11
- package/dist/server/components/chat-composer-popover/index.js +26 -0
- package/dist/server/components/chat-conversation-header/index.js +9 -10
- package/dist/server/components/chat-conversation-list/index.js +4 -5
- package/dist/server/components/checkbox/index.js +3 -3
- package/dist/server/components/choice-grid/index.js +2 -2
- package/dist/server/components/code-block/index.js +2 -2
- package/dist/server/components/color-field/index.js +3 -3
- package/dist/server/components/combobox/index.js +6 -6
- package/dist/server/components/command-item/index.js +5 -3
- package/dist/server/components/command-menu/index.js +6 -4
- package/dist/server/components/command-palette/index.js +2 -2
- package/dist/server/components/confirm-dialog/index.js +2 -2
- package/dist/server/components/context-menu/index.js +5 -5
- package/dist/server/components/data-table/index.js +5 -5
- package/dist/server/components/date-picker/index.js +6 -6
- package/dist/server/components/date-range-field/index.js +7 -7
- package/dist/server/components/description-list/index.js +3 -5
- package/dist/server/components/diff-viewer/index.js +7 -7
- package/dist/server/components/drawer/index.js +3 -3
- package/dist/server/components/dropdown/index.js +4 -4
- package/dist/server/components/event-stream-viewer/index.js +2 -2
- package/dist/server/components/experimental/json-viewer/index.js +2 -2
- package/dist/server/components/faceted-filter-bar/index.js +1 -1
- package/dist/server/components/hover-card/index.js +1 -1
- package/dist/server/components/input/index.js +3 -3
- package/dist/server/components/json-schema-editor/index.js +22 -22
- package/dist/server/components/json-viewer/index.js +2 -2
- package/dist/server/components/markdown-editor/index.js +13 -13
- package/dist/server/components/modal/index.js +1 -1
- package/dist/server/components/multi-select/index.js +1 -1
- package/dist/server/components/navigation-bar/index.js +1 -1
- package/dist/server/components/newsletter-section/index.js +3 -3
- package/dist/server/components/payload-inspector/index.js +4 -16
- package/dist/server/components/popover/index.js +5 -5
- package/dist/server/components/review-editor/index.js +25 -25
- package/dist/server/components/run-step-timeline/index.js +2 -2
- package/dist/server/components/schema-form/index.js +4 -4
- package/dist/server/components/secret-value-field/index.js +3 -5
- package/dist/server/components/segment/index.js +3 -3
- package/dist/server/components/segmented-control/index.js +4 -4
- package/dist/server/components/selection-popover/index.js +4 -4
- package/dist/server/components/sheet/index.js +2 -2
- package/dist/server/components/sidebar/index.js +3 -3
- package/dist/server/components/tab/index.js +2 -2
- package/dist/server/components/table/index.js +3 -3
- package/dist/server/components/tabs/index.js +4 -4
- package/dist/server/components/tag-input/index.js +3 -3
- package/dist/server/components/team-section/index.js +8 -8
- package/dist/server/components/testimonial-section/index.js +2 -2
- package/dist/server/components/toggle/index.js +2 -2
- package/dist/server/components/tooltip/index.js +1 -1
- package/dist/server/index.js +160 -149
- package/dist/server/{index.server-cbtg8rq5.js → index.server-0atyznp7.js} +5 -5
- package/dist/server/{index.server-20y4mdhm.js → index.server-0chhpkg7.js} +40 -14
- package/dist/server/{index.server-ecm1vs3g.js → index.server-1nq7z1qw.js} +1 -1
- package/dist/server/{index.server-jync915v.js → index.server-2dga5yzr.js} +25 -25
- package/dist/server/index.server-2hqrv7ca.js +9 -0
- package/dist/server/{index.server-qwknp759.js → index.server-2qj6s2mh.js} +7 -4
- package/dist/server/{index.server-pt8b65mt.js → index.server-38aywdk1.js} +1 -1
- package/dist/server/{index.server-rermas0k.js → index.server-47v2fhp4.js} +4 -4
- package/dist/server/{index.server-9j5sym59.js → index.server-4x91gzy1.js} +2 -2
- package/dist/server/{index.server-q48q15g7.js → index.server-4y2jtvv1.js} +4 -2
- package/dist/server/{index.server-zeqv7nrz.js → index.server-5tf22d6e.js} +43 -6
- package/dist/server/index.server-67qgdypc.js +9 -0
- package/dist/server/{index.server-9jete4xx.js → index.server-6sh11ap6.js} +4 -4
- package/dist/server/{index.server-4ztq565m.js → index.server-85p4ydph.js} +1 -1
- package/dist/server/{index.server-4nk7gy0q.js → index.server-894t97kv.js} +1 -1
- package/dist/server/{index.server-1vscnped.js → index.server-8dt36sdm.js} +2 -1
- package/dist/server/{index.server-bfsbp9dz.js → index.server-8xvc73zh.js} +4 -4
- package/dist/server/{index.server-cvnw3hw9.js → index.server-9kz37z89.js} +1 -1
- package/dist/server/{index.server-kc1k02tk.js → index.server-9ykk1kbg.js} +1 -1
- package/dist/server/{index.server-g789yep6.js → index.server-aqethy0w.js} +2 -2
- package/dist/server/{index.server-wc9aggfz.js → index.server-bmxbsk4y.js} +7 -7
- package/dist/server/{index.server-j3ddzcaa.js → index.server-c6pe4kaf.js} +6 -6
- package/dist/server/{index.server-q89dz8h1.js → index.server-d3pqthtp.js} +4 -3
- package/dist/server/{index.server-qfa2rxzx.js → index.server-dg83ke3k.js} +3 -5
- package/dist/server/{index.server-jk4rx4aa.js → index.server-dmmvwy6p.js} +1 -1
- package/dist/server/{index.server-hcfnae5y.js → index.server-dwwqssey.js} +4 -4
- package/dist/server/{index.server-e8x1hgw6.js → index.server-dz1r9xw5.js} +4 -4
- package/dist/server/{index.server-wm7mk5kw.js → index.server-ez5hp0ya.js} +1 -1
- package/dist/server/{index.server-ejyf7e48.js → index.server-fy068yne.js} +1 -1
- package/dist/server/{index.server-wc8dbm5e.js → index.server-g95bk8rc.js} +4 -2
- package/dist/server/index.server-gkazv439.js +576 -0
- package/dist/server/{index.server-dp9j2kkr.js → index.server-h0cvwvhy.js} +1 -1
- package/dist/server/{index.server-pacrqvyz.js → index.server-h90pjrez.js} +1 -1
- package/dist/server/{index.server-p8d04em5.js → index.server-hcsd5gdb.js} +6 -2
- package/dist/server/{index.server-n39drzes.js → index.server-hpeavvnq.js} +1 -1
- package/dist/server/{index.server-1p3patnj.js → index.server-hx91ng7z.js} +1 -1
- package/dist/server/{index.server-jtj3r53y.js → index.server-jgb8yh5k.js} +1 -1
- package/dist/server/{index.server-w1g5q9j9.js → index.server-jtgw9d23.js} +4 -2
- package/dist/server/{index.server-mehav5vs.js → index.server-jxg42jpz.js} +4 -4
- package/dist/server/{index.server-hd8gpehd.js → index.server-jxseyx33.js} +1 -1
- package/dist/server/{index.server-kg2sepsr.js → index.server-krqvnt6p.js} +14 -15
- package/dist/server/{index.server-0e1m3agz.js → index.server-ks49bprh.js} +1 -1
- package/dist/server/{index.server-f0hma3jp.js → index.server-kt0ncrqs.js} +1 -1
- package/dist/server/index.server-m0ezemav.js +170 -0
- package/dist/server/index.server-m191rm44.js +79 -0
- package/dist/server/{index.server-f23vtaw4.js → index.server-marjz8ps.js} +6 -6
- package/dist/server/index.server-mqt1ngqw.js +250 -0
- package/dist/server/{index.server-s9khh4ry.js → index.server-mzzb7dnm.js} +3 -5
- package/dist/server/{index.server-z721a5gp.js → index.server-n82rcv0m.js} +4 -4
- package/dist/server/{index.server-rhhmdxtz.js → index.server-np3c7kx0.js} +4 -4
- package/dist/server/{index.server-hpcs7tmh.js → index.server-p56xxef1.js} +1 -1
- package/dist/server/{index.server-w83kmcrx.js → index.server-pag862vz.js} +10 -10
- package/dist/server/{index.server-gxf0d1p5.js → index.server-q7w4jw89.js} +2 -2
- package/dist/server/{index.server-bvmwnjx6.js → index.server-qh9qzd5t.js} +186 -23
- package/dist/server/{index.server-pxg74pyp.js → index.server-qk1h0n02.js} +4 -4
- package/dist/server/{index.server-sh2rxejg.js → index.server-qke3ekjt.js} +1 -1
- package/dist/server/{index.server-73x2d3j3.js → index.server-rbpvcrr3.js} +1 -1
- package/dist/server/{index.server-8cxs4kya.js → index.server-rga8sc7j.js} +41 -44
- package/dist/server/{index.server-e3fnv1g6.js → index.server-sedjxt36.js} +5 -5
- package/dist/server/{index.server-pen9pxt6.js → index.server-sf3nk3j2.js} +2 -2
- package/dist/server/{index.server-7fp0epev.js → index.server-veastatv.js} +4 -4
- package/dist/server/{index.server-jeqg2d22.js → index.server-xeqtpv61.js} +1 -1
- package/dist/server/{index.server-9s4na701.js → index.server-xjnge1yw.js} +4 -4
- package/dist/server/index.server-xtjjmsyq.js +315 -0
- package/dist/server/{index.server-hhxjaeen.js → index.server-xz99aed4.js} +4 -4
- package/dist/server/{index.server-vne4rzfa.js → index.server-y4n8vc08.js} +1 -1
- package/dist/server/{index.server-5d01cn4f.js → index.server-y83kqayt.js} +4 -4
- package/dist/server/{index.server-1nh09ck7.js → index.server-yhzydqxe.js} +5 -5
- package/dist/server/{index.server-atjc1qcq.js → index.server-yz4k36cw.js} +1 -1
- package/dist/server/{index.server-w6k62afr.js → index.server-ze1ymmbw.js} +2 -2
- package/dist/server/{index.server-914v805w.js → index.server-zgd1g8mk.js} +1 -1
- package/dist/server/{index.server-aeexcxdp.js → index.server-zh3r8vfd.js} +1 -1
- package/dist/server/{index.server-10jb2jzm.js → index.server-zsjf8enc.js} +4 -4
- package/package.json +42 -6
- package/src/components/_internal/command-list-context.ts +3 -3
- package/src/components/_internal/create-command-list-state.svelte.ts +39 -13
- package/src/components/approval-card/approval-card-actions.svelte +168 -0
- package/src/components/approval-card/approval-card-state.ts +152 -1
- package/src/components/approval-card/approval-card.css +269 -92
- package/src/components/approval-card/approval-card.examples.json +3 -3
- package/src/components/approval-card/approval-card.schema.json +9 -30
- package/src/components/approval-card/approval-card.schema.ts +13 -31
- package/src/components/approval-card/approval-card.svelte +176 -470
- package/src/components/approval-card/approval-card.types.ts +15 -28
- package/src/components/approval-card/index.ts +1 -0
- package/src/components/card/card.css +5 -0
- package/src/components/card/card.schema.json +1 -1
- package/src/components/card/card.schema.ts +1 -1
- package/src/components/card/card.svelte +1 -0
- package/src/components/card/card.types.ts +2 -2
- package/src/components/chat/chat.schema.json +40 -0
- package/src/components/chat/chat.schema.ts +49 -0
- package/src/components/chat/chat.svelte +20 -0
- package/src/components/chat/chat.types.ts +38 -0
- package/src/components/chat/container/chat.svelte +82 -3
- package/src/components/chat/index.ts +15 -3
- package/src/components/chat/input/chat-attachment-serialization.ts +63 -0
- package/src/components/chat/input/chat-input.svelte +30 -3
- package/src/components/chat/input/index.ts +5 -0
- package/src/components/chat-composer-popover/chat-composer-popover-filter.ts +68 -0
- package/src/components/chat-composer-popover/chat-composer-popover.css +7 -0
- package/src/components/chat-composer-popover/chat-composer-popover.examples.json +13 -0
- package/src/components/chat-composer-popover/chat-composer-popover.schema.json +90 -0
- package/src/components/chat-composer-popover/chat-composer-popover.schema.ts +95 -0
- package/src/components/chat-composer-popover/chat-composer-popover.svelte +234 -0
- package/src/components/chat-composer-popover/chat-composer-popover.types.ts +88 -0
- package/src/components/chat-composer-popover/chat-composer-popover.variables.json +1 -0
- package/src/components/chat-composer-popover/chat-composer-popover.variables.ts +3 -0
- package/src/components/chat-composer-popover/index.ts +19 -0
- package/src/components/code-block/code-block.schema.json +4 -0
- package/src/components/code-block/code-block.schema.ts +5 -0
- package/src/components/code-block/code-block.svelte +3 -3
- package/src/components/code-block/code-block.types.ts +6 -0
- package/src/components/command-item/command-item.svelte +7 -6
- package/src/components/command-menu/command-menu.schema.json +4 -0
- package/src/components/command-menu/command-menu.schema.ts +4 -0
- package/src/components/command-menu/command-menu.svelte +16 -5
- package/src/components/command-menu/command-menu.types.ts +2 -0
- package/src/components/json-viewer/_json-viewer-node.svelte +15 -1
- package/src/components/json-viewer/json-viewer.css +10 -6
- package/src/components/navigation-bar/navigation-bar.svelte +49 -7
- package/src/components/payload-inspector/index.ts +0 -2
- package/src/components/payload-inspector/payload-inspector.css +15 -75
- package/src/components/payload-inspector/payload-inspector.examples.json +5 -5
- package/src/components/payload-inspector/payload-inspector.schema.json +3 -31
- package/src/components/payload-inspector/payload-inspector.schema.ts +3 -36
- package/src/components/payload-inspector/payload-inspector.svelte +46 -239
- package/src/components/payload-inspector/payload-inspector.types.ts +10 -58
- package/src/components/sidebar/sidebar.css +4 -0
- package/src/components/sidebar/sidebar.svelte +6 -3
- package/src/components/tab/tab.schema.json +6 -2
- package/src/components/tab/tab.schema.ts +8 -2
- package/src/components/tab/tab.svelte +9 -5
- package/src/components/tab/tab.types.ts +8 -2
- package/src/index.ts +18 -5
- package/src/styles/components.css +1 -0
- package/dist/server/index-49we2xfs.js +0 -344
- package/dist/server/index-8fhvxk30.js +0 -265
- package/dist/server/index-x2ysg8ds.js +0 -388
- package/dist/server/index.server-20j0jh30.js +0 -9
- package/dist/server/index.server-dc35kh7d.js +0 -1835
- package/dist/server/index.server-kd4b0342.js +0 -607
- package/dist/server/index.server-n5cdmsz4.js +0 -30
- package/dist/server/index.server-rjap4k7y.js +0 -1389
- package/dist/server/index.server-vt6sn9y4.js +0 -447
- package/dist/server/index.server-w63n618v.js +0 -9
- package/dist/server/index.server-y2pa1k46.js +0 -9
|
@@ -2,6 +2,9 @@ import type { HTMLAttributes } from 'svelte/elements';
|
|
|
2
2
|
|
|
3
3
|
export type ApprovalToolRisk = 'low' | 'medium' | 'high';
|
|
4
4
|
|
|
5
|
+
/** Heading level rendered for the card title. Section headings render one level deeper. */
|
|
6
|
+
export type ApprovalCardHeadingLevel = 2 | 3 | 4 | 5 | 6;
|
|
7
|
+
|
|
5
8
|
/** @schemaObject */
|
|
6
9
|
export type ApprovalTool = {
|
|
7
10
|
/** Human-readable tool name requesting approval. */
|
|
@@ -28,7 +31,7 @@ export type ApprovalCommandOperation = {
|
|
|
28
31
|
kind: 'command';
|
|
29
32
|
/** Shell command for command approvals. */
|
|
30
33
|
command: string;
|
|
31
|
-
/** File paths that the operation may read or write. */
|
|
34
|
+
/** File paths that the operation may read or write. Duplicate paths are collapsed for display. */
|
|
32
35
|
filesTouched?: string[];
|
|
33
36
|
/**
|
|
34
37
|
* JSON-like argument preview shown to the approver.
|
|
@@ -42,7 +45,7 @@ export type ApprovalCommandOperation = {
|
|
|
42
45
|
export type ApprovalFileWriteOperation = {
|
|
43
46
|
/** Operation family being approved. */
|
|
44
47
|
kind: 'file-write';
|
|
45
|
-
/** File paths that the operation may read or write. File-write approvals require at least one path. */
|
|
48
|
+
/** File paths that the operation may read or write. File-write approvals require at least one path. Duplicate paths are collapsed for display. */
|
|
46
49
|
filesTouched: string[];
|
|
47
50
|
/**
|
|
48
51
|
* JSON-like argument preview shown to the approver.
|
|
@@ -56,7 +59,7 @@ export type ApprovalFileWriteOperation = {
|
|
|
56
59
|
export type ApprovalPatchOperation = {
|
|
57
60
|
/** Operation family being approved. */
|
|
58
61
|
kind: 'patch';
|
|
59
|
-
/** File paths that the operation may read or write. */
|
|
62
|
+
/** File paths that the operation may read or write. Duplicate paths are collapsed for display. */
|
|
60
63
|
filesTouched?: string[];
|
|
61
64
|
/**
|
|
62
65
|
* JSON-like argument preview shown to the approver.
|
|
@@ -72,7 +75,7 @@ export type ApprovalPatchOperation = {
|
|
|
72
75
|
export type ApprovalOtherOperation = {
|
|
73
76
|
/** Operation family being approved. */
|
|
74
77
|
kind: 'other';
|
|
75
|
-
/** File paths that the operation may read or write. */
|
|
78
|
+
/** File paths that the operation may read or write. Duplicate paths are collapsed for display. */
|
|
76
79
|
filesTouched?: string[];
|
|
77
80
|
/**
|
|
78
81
|
* JSON-like argument preview shown to the approver.
|
|
@@ -117,18 +120,8 @@ export type ApprovalResolution = {
|
|
|
117
120
|
};
|
|
118
121
|
|
|
119
122
|
export type ApprovalCardCallbacks = {
|
|
120
|
-
/** Called for approve, approve-with-edits, deny, and
|
|
123
|
+
/** Called for approve, approve-with-edits, deny, and dismiss with the complete resolution payload. */
|
|
121
124
|
onresolve?: (resolution: ApprovalResolution) => void;
|
|
122
|
-
/** Called when the approver accepts the operation as presented. */
|
|
123
|
-
onapprove?: () => void;
|
|
124
|
-
/** Called with parsed JSON arguments when the approver accepts edited arguments. */
|
|
125
|
-
onapprovewithedits?: (editedArgs: unknown) => void;
|
|
126
|
-
/** Called when the approver denies the operation. */
|
|
127
|
-
ondeny?: () => void;
|
|
128
|
-
/** Called when the approver asks the host application to remember the decision. */
|
|
129
|
-
onremember?: () => void;
|
|
130
|
-
/** Called when the approver cancels the approval prompt. */
|
|
131
|
-
oncancel?: () => void;
|
|
132
125
|
};
|
|
133
126
|
|
|
134
127
|
/** Props for the ApprovalCard component. */
|
|
@@ -154,6 +147,8 @@ export type ApprovalCardProps = Omit<HTMLAttributes<HTMLElement>, 'class' | 'chi
|
|
|
154
147
|
state: ApprovalState;
|
|
155
148
|
/** Whether approving with edited JSON arguments is available. Default `false`. */
|
|
156
149
|
editableArgs?: boolean;
|
|
150
|
+
/** Heading level for the card title; section headings render one level deeper. Default `3`. */
|
|
151
|
+
headingLevel?: ApprovalCardHeadingLevel;
|
|
157
152
|
/** Additional CSS classes applied to the root element. */
|
|
158
153
|
class?: string;
|
|
159
154
|
};
|
|
@@ -161,8 +156,8 @@ export type ApprovalCardProps = Omit<HTMLAttributes<HTMLElement>, 'class' | 'chi
|
|
|
161
156
|
/**
|
|
162
157
|
* Cinder-specific schema surface for ApprovalCard.
|
|
163
158
|
*
|
|
164
|
-
*
|
|
165
|
-
* be represented as JSON Schema controls.
|
|
159
|
+
* The resolution callback is documented but marked unsupported because
|
|
160
|
+
* functions cannot be represented as JSON Schema controls.
|
|
166
161
|
*/
|
|
167
162
|
export type ApprovalCardSchemaProps = {
|
|
168
163
|
/** Tool requesting approval. */
|
|
@@ -185,18 +180,10 @@ export type ApprovalCardSchemaProps = {
|
|
|
185
180
|
state: ApprovalState;
|
|
186
181
|
/** Whether approving with edited JSON arguments is available. Default `false`. */
|
|
187
182
|
editableArgs?: boolean;
|
|
188
|
-
/**
|
|
189
|
-
|
|
190
|
-
/** Called for approve, approve-with-edits, deny, and
|
|
183
|
+
/** Heading level for the card title; section headings render one level deeper. Default `3`. */
|
|
184
|
+
headingLevel?: ApprovalCardHeadingLevel;
|
|
185
|
+
/** Called for approve, approve-with-edits, deny, and dismiss with the complete resolution payload. */
|
|
191
186
|
onresolve?: (resolution: ApprovalResolution) => void;
|
|
192
|
-
/** Called with parsed JSON arguments when the approver accepts edited arguments. */
|
|
193
|
-
onapprovewithedits?: (editedArgs: unknown) => void;
|
|
194
|
-
/** Called when the approver denies the operation. */
|
|
195
|
-
ondeny?: () => void;
|
|
196
|
-
/** Called when the approver asks the host application to remember the decision. */
|
|
197
|
-
onremember?: () => void;
|
|
198
|
-
/** Called when the approver cancels the approval prompt. */
|
|
199
|
-
oncancel?: () => void;
|
|
200
187
|
/** Additional CSS classes applied to the root element. */
|
|
201
188
|
class?: string;
|
|
202
189
|
};
|
|
@@ -95,6 +95,11 @@
|
|
|
95
95
|
padding: 0;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
.cinder-card[data-cinder-padding='none'] > .cinder-card__header,
|
|
99
|
+
.cinder-card[data-cinder-padding='none'] > .cinder-card__footer {
|
|
100
|
+
padding: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
98
103
|
.cinder-card[data-cinder-variant='well'] > .cinder-card__body {
|
|
99
104
|
background: var(--cinder-surface-inset);
|
|
100
105
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"padding": {
|
|
30
30
|
"enum": ["none", "default"],
|
|
31
|
-
"description": "
|
|
31
|
+
"description": "Region padding. `none` removes body, header, and footer padding for flush or full-bleed content (e.g. an image)."
|
|
32
32
|
},
|
|
33
33
|
"headingLevel": {
|
|
34
34
|
"enum": [2, 3, 4, 5, 6],
|
|
@@ -32,7 +32,7 @@ const schema = {
|
|
|
32
32
|
padding: {
|
|
33
33
|
enum: ['none', 'default'],
|
|
34
34
|
description:
|
|
35
|
-
'
|
|
35
|
+
'Region padding. `none` removes body, header, and footer padding for flush or full-bleed content (e.g. an image).',
|
|
36
36
|
},
|
|
37
37
|
headingLevel: {
|
|
38
38
|
enum: [2, 3, 4, 5, 6],
|
|
@@ -37,6 +37,7 @@ const labelAttributes = $derived(hasGeneratedHeader
|
|
|
37
37
|
data-cinder-variant={variant}
|
|
38
38
|
data-cinder-tone={tone}
|
|
39
39
|
data-cinder-edge-to-edge-mobile={edgeToEdgeOnMobile ? '' : undefined}
|
|
40
|
+
data-cinder-padding={padding}
|
|
40
41
|
{...labelAttributes}
|
|
41
42
|
>
|
|
42
43
|
{#if header}
|
|
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'svelte/elements';
|
|
|
3
3
|
export type CardVariant = 'card' | 'well';
|
|
4
4
|
export type CardTone = 'default' | 'muted';
|
|
5
5
|
export type CardSurfaceTone = 'default' | 'danger';
|
|
6
|
-
/** Controls
|
|
6
|
+
/** Controls region padding. `none` removes body, header, and footer padding for flush/full-bleed content. Future values like `compact` may be added. */
|
|
7
7
|
export type CardPadding = 'default' | 'none';
|
|
8
8
|
/** Heading level for the generated card title, so the document outline stays correct. */
|
|
9
9
|
export type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;
|
|
@@ -19,7 +19,7 @@ type CardBase = HTMLAttributes<HTMLDivElement> & {
|
|
|
19
19
|
footerTone?: CardTone;
|
|
20
20
|
/** Remove side borders/radius and bleed to the viewport edge on narrow screens. */
|
|
21
21
|
edgeToEdgeOnMobile?: boolean;
|
|
22
|
-
/**
|
|
22
|
+
/** Region padding. `none` removes body, header, and footer padding for flush or full-bleed content (e.g. an image). */
|
|
23
23
|
padding?: CardPadding;
|
|
24
24
|
};
|
|
25
25
|
/** Basic card with no generated header. */
|
|
@@ -50,6 +50,26 @@
|
|
|
50
50
|
"type": "string",
|
|
51
51
|
"description": "Optional status label displayed in the typing indicator while `streaming` is `true` and no streaming content has arrived yet (e.g. `\"Thinking…\"` or `\"Analyzing file…\"`). When omitted, three animated dots are shown."
|
|
52
52
|
},
|
|
53
|
+
"composerRole": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"description": "Explicit role for the composer textarea, for overlay patterns such as ARIA comboboxes."
|
|
56
|
+
},
|
|
57
|
+
"composerAriaExpanded": {
|
|
58
|
+
"enum": [false, true, "true", "false"],
|
|
59
|
+
"description": "`aria-expanded` passed to the composer textarea for overlays such as slash-command menus."
|
|
60
|
+
},
|
|
61
|
+
"composerAriaControls": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "`aria-controls` passed to the composer textarea for overlays such as slash-command menus."
|
|
64
|
+
},
|
|
65
|
+
"composerAriaActiveDescendant": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"description": "`aria-activedescendant` passed to the composer textarea for overlays such as slash-command menus."
|
|
68
|
+
},
|
|
69
|
+
"composerAriaAutocomplete": {
|
|
70
|
+
"enum": ["none", "inline", "list", "both"],
|
|
71
|
+
"description": "`aria-autocomplete` passed to the composer textarea for overlays such as slash-command menus."
|
|
72
|
+
},
|
|
53
73
|
"virtualized": {
|
|
54
74
|
"type": "boolean",
|
|
55
75
|
"description": "Use the virtualized message render path for long transcripts. The complete `ConversationHistory` remains unchanged; only the DOM window is reduced. Default `false`."
|
|
@@ -164,6 +184,26 @@
|
|
|
164
184
|
"name": "onattachmentremove",
|
|
165
185
|
"reason": "function-or-snippet"
|
|
166
186
|
},
|
|
187
|
+
{
|
|
188
|
+
"name": "oncomposerblur",
|
|
189
|
+
"reason": "function-or-snippet",
|
|
190
|
+
"description": "Called when focus leaves the composer textarea. Overlay primitives can use\nthis to dismiss without preventing native focus movement."
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "oncomposerinput",
|
|
194
|
+
"reason": "function-or-snippet",
|
|
195
|
+
"description": "Called with the composer's current plain-text value on every composer\ninput event. The optional event exposes the textarea for composer-bound\noverlays without reaching into `.chat-input-editor` DOM directly."
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"name": "oncomposerkeydown",
|
|
199
|
+
"reason": "function-or-snippet",
|
|
200
|
+
"description": "Called before Chat's internal composer key handling when a keydown\noriginates from the composer textarea. Call `event.preventDefault()` to\nlet an overlay consume Arrow keys, Enter, or Escape before Enter-to-send.\nChat does not call this hook during IME composition, so Enter can still\nconfirm the active candidate instead of sending."
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"name": "oncomposerselectionchange",
|
|
204
|
+
"reason": "function-or-snippet",
|
|
205
|
+
"description": "Called after pointer or selection activity may have moved the composer\ncaret without changing text. Overlay primitives can resync their active\ntoken from the textarea selection."
|
|
206
|
+
},
|
|
167
207
|
{
|
|
168
208
|
"name": "ondeny",
|
|
169
209
|
"reason": "function-or-snippet",
|
|
@@ -63,6 +63,31 @@ const schema = {
|
|
|
63
63
|
description:
|
|
64
64
|
'Optional status label displayed in the typing indicator while `streaming` is `true` and no streaming content has arrived yet (e.g. `"Thinking…"` or `"Analyzing file…"`). When omitted, three animated dots are shown.',
|
|
65
65
|
},
|
|
66
|
+
composerRole: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description:
|
|
69
|
+
'Explicit role for the composer textarea, for overlay patterns such as ARIA comboboxes.',
|
|
70
|
+
},
|
|
71
|
+
composerAriaExpanded: {
|
|
72
|
+
enum: [false, true, 'true', 'false'],
|
|
73
|
+
description:
|
|
74
|
+
'`aria-expanded` passed to the composer textarea for overlays such as slash-command menus.',
|
|
75
|
+
},
|
|
76
|
+
composerAriaControls: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description:
|
|
79
|
+
'`aria-controls` passed to the composer textarea for overlays such as slash-command menus.',
|
|
80
|
+
},
|
|
81
|
+
composerAriaActiveDescendant: {
|
|
82
|
+
type: 'string',
|
|
83
|
+
description:
|
|
84
|
+
'`aria-activedescendant` passed to the composer textarea for overlays such as slash-command menus.',
|
|
85
|
+
},
|
|
86
|
+
composerAriaAutocomplete: {
|
|
87
|
+
enum: ['none', 'inline', 'list', 'both'],
|
|
88
|
+
description:
|
|
89
|
+
'`aria-autocomplete` passed to the composer textarea for overlays such as slash-command menus.',
|
|
90
|
+
},
|
|
66
91
|
virtualized: {
|
|
67
92
|
type: 'boolean',
|
|
68
93
|
description:
|
|
@@ -191,6 +216,30 @@ const schema = {
|
|
|
191
216
|
name: 'onattachmentremove',
|
|
192
217
|
reason: 'function-or-snippet',
|
|
193
218
|
},
|
|
219
|
+
{
|
|
220
|
+
name: 'oncomposerblur',
|
|
221
|
+
reason: 'function-or-snippet',
|
|
222
|
+
description:
|
|
223
|
+
'Called when focus leaves the composer textarea. Overlay primitives can use\nthis to dismiss without preventing native focus movement.',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: 'oncomposerinput',
|
|
227
|
+
reason: 'function-or-snippet',
|
|
228
|
+
description:
|
|
229
|
+
"Called with the composer's current plain-text value on every composer\ninput event. The optional event exposes the textarea for composer-bound\noverlays without reaching into `.chat-input-editor` DOM directly.",
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'oncomposerkeydown',
|
|
233
|
+
reason: 'function-or-snippet',
|
|
234
|
+
description:
|
|
235
|
+
"Called before Chat's internal composer key handling when a keydown\noriginates from the composer textarea. Call `event.preventDefault()` to\nlet an overlay consume Arrow keys, Enter, or Escape before Enter-to-send.\nChat does not call this hook during IME composition, so Enter can still\nconfirm the active candidate instead of sending.",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: 'oncomposerselectionchange',
|
|
239
|
+
reason: 'function-or-snippet',
|
|
240
|
+
description:
|
|
241
|
+
'Called after pointer or selection activity may have moved the composer\ncaret without changing text. Overlay primitives can resync their active\ntoken from the textarea selection.',
|
|
242
|
+
},
|
|
194
243
|
{
|
|
195
244
|
name: 'ondeny',
|
|
196
245
|
reason: 'function-or-snippet',
|
|
@@ -30,6 +30,14 @@ export function pushToken(token) {
|
|
|
30
30
|
export function endStreaming() {
|
|
31
31
|
impl?.endStreaming();
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Announce consumer-rendered status text through Chat's existing live regions.
|
|
35
|
+
* No-op until mounted. Built-in tool-approval announcements take precedence
|
|
36
|
+
* over consumer assertive announcements to avoid duplicate urgent output.
|
|
37
|
+
*/
|
|
38
|
+
export function announce(message, level = 'polite') {
|
|
39
|
+
impl?.announce(message, level);
|
|
40
|
+
}
|
|
33
41
|
/** Scroll the message viewport to the bottom. No-op until mounted. */
|
|
34
42
|
export function scrollToBottom() {
|
|
35
43
|
impl?.scrollToBottom();
|
|
@@ -42,6 +50,18 @@ export function scrollToTop() {
|
|
|
42
50
|
export function focusInput() {
|
|
43
51
|
impl?.focusInput();
|
|
44
52
|
}
|
|
53
|
+
/** Clear the composer's current content. No-op until mounted. */
|
|
54
|
+
export function clearInput() {
|
|
55
|
+
impl?.clearInput();
|
|
56
|
+
}
|
|
57
|
+
/** Read the composer's current plain-text value. Returns '' until mounted. */
|
|
58
|
+
export function getComposerValue() {
|
|
59
|
+
return impl?.getComposerValue() ?? '';
|
|
60
|
+
}
|
|
61
|
+
/** Read the composer textarea element. Returns null until mounted. */
|
|
62
|
+
export function getEditorElement() {
|
|
63
|
+
return impl?.getEditorElement() ?? null;
|
|
64
|
+
}
|
|
45
65
|
</script>
|
|
46
66
|
|
|
47
67
|
<ChatImplementation bind:this={impl} class={mergedClassName} {...rest} />
|
|
@@ -49,6 +49,9 @@ export type ReadReceipt = {
|
|
|
49
49
|
readBy?: string[];
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
/** Live-region channel for imperative Chat announcements. */
|
|
53
|
+
export type ChatAnnounceLevel = 'polite' | 'assertive';
|
|
54
|
+
|
|
52
55
|
/**
|
|
53
56
|
* Full-row override snippet. Inversion of control: receives the message AND a
|
|
54
57
|
* `renderDefault` snippet that renders the built-in row, so a consumer can wrap
|
|
@@ -127,6 +130,16 @@ export type ChatProps = Omit<HTMLAttributes<HTMLElement>, 'class' | 'onsubmit'>
|
|
|
127
130
|
* rather than as five separate boolean props.
|
|
128
131
|
*/
|
|
129
132
|
capabilities?: ChatCapabilities;
|
|
133
|
+
/** Explicit role for the composer textarea, for overlay patterns such as ARIA comboboxes. */
|
|
134
|
+
composerRole?: string | undefined;
|
|
135
|
+
/** `aria-expanded` passed to the composer textarea for overlays such as slash-command menus. */
|
|
136
|
+
composerAriaExpanded?: boolean | 'true' | 'false' | undefined;
|
|
137
|
+
/** `aria-controls` passed to the composer textarea for overlays such as slash-command menus. */
|
|
138
|
+
composerAriaControls?: string | undefined;
|
|
139
|
+
/** `aria-activedescendant` passed to the composer textarea for overlays such as slash-command menus. */
|
|
140
|
+
composerAriaActiveDescendant?: string | undefined;
|
|
141
|
+
/** `aria-autocomplete` passed to the composer textarea for overlays such as slash-command menus. */
|
|
142
|
+
composerAriaAutocomplete?: 'none' | 'inline' | 'list' | 'both' | undefined;
|
|
130
143
|
/** Use the virtualized message render path for long transcripts. The complete `ConversationHistory` remains unchanged; only the DOM window is reduced. Default `false`. */
|
|
131
144
|
virtualized?: boolean;
|
|
132
145
|
/** Estimated row height in pixels for virtualized message rows. Default `88`. */
|
|
@@ -243,4 +256,29 @@ export type ChatProps = Omit<HTMLAttributes<HTMLElement>, 'class' | 'onsubmit'>
|
|
|
243
256
|
onattachmentadd?: (attachment: ChatAttachment) => void;
|
|
244
257
|
onattachmentremove?: (attachment: ChatAttachment) => void;
|
|
245
258
|
onattachmentfailure?: (file: File, error: string) => void;
|
|
259
|
+
/**
|
|
260
|
+
* Called with the composer's current plain-text value on every composer
|
|
261
|
+
* input event. The optional event exposes the textarea for composer-bound
|
|
262
|
+
* overlays without reaching into `.chat-input-editor` DOM directly.
|
|
263
|
+
*/
|
|
264
|
+
oncomposerinput?: (value: string, event?: Event) => void;
|
|
265
|
+
/**
|
|
266
|
+
* Called before Chat's internal composer key handling when a keydown
|
|
267
|
+
* originates from the composer textarea. Call `event.preventDefault()` to
|
|
268
|
+
* let an overlay consume Arrow keys, Enter, or Escape before Enter-to-send.
|
|
269
|
+
* Chat does not call this hook during IME composition, so Enter can still
|
|
270
|
+
* confirm the active candidate instead of sending.
|
|
271
|
+
*/
|
|
272
|
+
oncomposerkeydown?: (event: KeyboardEvent) => void;
|
|
273
|
+
/**
|
|
274
|
+
* Called after pointer or selection activity may have moved the composer
|
|
275
|
+
* caret without changing text. Overlay primitives can resync their active
|
|
276
|
+
* token from the textarea selection.
|
|
277
|
+
*/
|
|
278
|
+
oncomposerselectionchange?: (event: Event) => void;
|
|
279
|
+
/**
|
|
280
|
+
* Called when focus leaves the composer textarea. Overlay primitives can use
|
|
281
|
+
* this to dismiss without preventing native focus movement.
|
|
282
|
+
*/
|
|
283
|
+
oncomposerblur?: (event: FocusEvent) => void;
|
|
246
284
|
};
|
|
@@ -26,7 +26,8 @@ import { useChatReadReceipts } from './use-chat-read-receipts.svelte.ts';
|
|
|
26
26
|
import ChatParticipantTyping from './chat-participant-typing.svelte';
|
|
27
27
|
import ChatReadReceipt from '../message/chat-read-receipt.svelte';
|
|
28
28
|
const noopAttachment = () => { };
|
|
29
|
-
|
|
29
|
+
const CONSUMER_ANNOUNCEMENT_CLEAR_DELAY_MS = 1000;
|
|
30
|
+
let { id, conversation, atBottom = $bindable(true), unreadCount = $bindable(0), newMessageIndicatorVisible = $bindable(false), class: className, surfaceMode = 'default', density = 'comfortable', variant = 'bubble', bottomThreshold = DEFAULT_SCROLL_CONFIGURATION.bottomThreshold, jumpThreshold = DEFAULT_SCROLL_CONFIGURATION.jumpThreshold, streaming = false, streamingStatus, capabilities, virtualized = false, virtualizationEstimatedRowHeight = 88, virtualizationOverscan = 3, virtualizationInitialHeight = 640, moreHistoryAvailable = true, loadEarlierLabel = 'Load earlier messages', loadingEarlierLabel = 'Loading earlier messages', header, empty, emptyPrompts, messageActions, messageStatus, row, messagePart, viewportAttachment, typingParticipants, readReceipts, adapter, onadaptererror, onpushmessage, ontypingchange, onreadreceipt, onsubmit, onretry, onedit, onapprove, ondeny, messageReasoning, messageSteps, messageSuggestions, onsuggestionselect, onloadhistory, onstopgenerating, onjumptolatest, onscrollstatechange, onunreadindicatorchange, onexpandedchange, onattachmentadd, onattachmentremove, onattachmentfailure, oncomposerinput, oncomposerkeydown, oncomposerselectionchange, oncomposerblur, composerRole, composerAriaExpanded, composerAriaControls, composerAriaActiveDescendant, composerAriaAutocomplete, ...rest } = $props();
|
|
30
31
|
// ==========================================================================
|
|
31
32
|
// Refs and Internal State
|
|
32
33
|
// ==========================================================================
|
|
@@ -84,10 +85,15 @@ $effect(() => {
|
|
|
84
85
|
toolCallState.reset();
|
|
85
86
|
typingIndicatorState.reset();
|
|
86
87
|
readReceiptsState.reset();
|
|
88
|
+
clearConsumerAnnouncements();
|
|
87
89
|
});
|
|
88
90
|
let isLoadingHistory = $state(false);
|
|
89
91
|
let adapterHasMoreHistory = $state(undefined);
|
|
90
92
|
let historyAnnouncement = $state('');
|
|
93
|
+
let consumerPoliteAnnouncement = $state('');
|
|
94
|
+
let consumerAssertiveAnnouncement = $state('');
|
|
95
|
+
let consumerPoliteAnnouncementTimeout;
|
|
96
|
+
let consumerAssertiveAnnouncementTimeout;
|
|
91
97
|
let pendingHistoryScroll = $state(null);
|
|
92
98
|
let deferredAdapterHasMoreHistory = null;
|
|
93
99
|
let historyAnchorMessageId = $state(null);
|
|
@@ -325,6 +331,13 @@ const toolApprovalAssertiveMessage = $derived.by(() => {
|
|
|
325
331
|
}
|
|
326
332
|
return '';
|
|
327
333
|
});
|
|
334
|
+
const assertiveAnnouncement = $derived(toolApprovalAssertiveMessage || consumerAssertiveAnnouncement);
|
|
335
|
+
const politeAnnouncement = $derived(consumerPoliteAnnouncement || historyAnnouncement || unreadState.announcerMessage);
|
|
336
|
+
$effect(() => {
|
|
337
|
+
if (toolApprovalAssertiveMessage && consumerAssertiveAnnouncement) {
|
|
338
|
+
clearConsumerAssertiveAnnouncement();
|
|
339
|
+
}
|
|
340
|
+
});
|
|
328
341
|
// ==========================================================================
|
|
329
342
|
// Scroll Anchoring via $effect.pre
|
|
330
343
|
// ==========================================================================
|
|
@@ -516,6 +529,7 @@ $effect(() => {
|
|
|
516
529
|
cancelAnimationFrame(streamingScrollRaf);
|
|
517
530
|
streamingScrollRaf = undefined;
|
|
518
531
|
}
|
|
532
|
+
clearConsumerAnnouncements();
|
|
519
533
|
};
|
|
520
534
|
});
|
|
521
535
|
// ==========================================================================
|
|
@@ -588,6 +602,50 @@ const historyAnchorScrollAttachment = $derived(historyAnchorMessageId === null |
|
|
|
588
602
|
// ==========================================================================
|
|
589
603
|
// Actions
|
|
590
604
|
// ==========================================================================
|
|
605
|
+
export function announce(message, level = 'polite') {
|
|
606
|
+
const trimmedMessage = message.trim();
|
|
607
|
+
if (!trimmedMessage)
|
|
608
|
+
return;
|
|
609
|
+
if (level === 'assertive') {
|
|
610
|
+
if (toolApprovalAssertiveMessage)
|
|
611
|
+
return;
|
|
612
|
+
setConsumerAssertiveAnnouncement(trimmedMessage);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
setConsumerPoliteAnnouncement(trimmedMessage);
|
|
616
|
+
}
|
|
617
|
+
function setConsumerPoliteAnnouncement(message) {
|
|
618
|
+
clearTimeout(consumerPoliteAnnouncementTimeout);
|
|
619
|
+
consumerPoliteAnnouncement = message;
|
|
620
|
+
consumerPoliteAnnouncementTimeout = setTimeout(() => {
|
|
621
|
+
if (consumerPoliteAnnouncement === message)
|
|
622
|
+
consumerPoliteAnnouncement = '';
|
|
623
|
+
consumerPoliteAnnouncementTimeout = undefined;
|
|
624
|
+
}, CONSUMER_ANNOUNCEMENT_CLEAR_DELAY_MS);
|
|
625
|
+
}
|
|
626
|
+
function setConsumerAssertiveAnnouncement(message) {
|
|
627
|
+
clearTimeout(consumerAssertiveAnnouncementTimeout);
|
|
628
|
+
consumerAssertiveAnnouncement = message;
|
|
629
|
+
consumerAssertiveAnnouncementTimeout = setTimeout(() => {
|
|
630
|
+
if (consumerAssertiveAnnouncement === message)
|
|
631
|
+
consumerAssertiveAnnouncement = '';
|
|
632
|
+
consumerAssertiveAnnouncementTimeout = undefined;
|
|
633
|
+
}, CONSUMER_ANNOUNCEMENT_CLEAR_DELAY_MS);
|
|
634
|
+
}
|
|
635
|
+
function clearConsumerPoliteAnnouncement() {
|
|
636
|
+
clearTimeout(consumerPoliteAnnouncementTimeout);
|
|
637
|
+
consumerPoliteAnnouncementTimeout = undefined;
|
|
638
|
+
consumerPoliteAnnouncement = '';
|
|
639
|
+
}
|
|
640
|
+
function clearConsumerAssertiveAnnouncement() {
|
|
641
|
+
clearTimeout(consumerAssertiveAnnouncementTimeout);
|
|
642
|
+
consumerAssertiveAnnouncementTimeout = undefined;
|
|
643
|
+
consumerAssertiveAnnouncement = '';
|
|
644
|
+
}
|
|
645
|
+
function clearConsumerAnnouncements() {
|
|
646
|
+
clearConsumerPoliteAnnouncement();
|
|
647
|
+
clearConsumerAssertiveAnnouncement();
|
|
648
|
+
}
|
|
591
649
|
function handleJumpToLatest() {
|
|
592
650
|
if (isVirtualized) {
|
|
593
651
|
chatVirtualizer.scrollToIndex(Math.max(0, renderRows.length - 1), {
|
|
@@ -1061,6 +1119,18 @@ export function scrollToTop() {
|
|
|
1061
1119
|
export function focusInput() {
|
|
1062
1120
|
inputRef?.focus();
|
|
1063
1121
|
}
|
|
1122
|
+
/** Clear the composer's current content. */
|
|
1123
|
+
export function clearInput() {
|
|
1124
|
+
inputRef?.clear();
|
|
1125
|
+
}
|
|
1126
|
+
/** Read the composer's current plain-text value. */
|
|
1127
|
+
export function getComposerValue() {
|
|
1128
|
+
return inputRef?.getValue() ?? '';
|
|
1129
|
+
}
|
|
1130
|
+
/** Read the composer textarea element. Returns null until mounted. */
|
|
1131
|
+
export function getEditorElement() {
|
|
1132
|
+
return inputRef?.getEditorElement() ?? null;
|
|
1133
|
+
}
|
|
1064
1134
|
/**
|
|
1065
1135
|
* Begin streaming content for a specific message.
|
|
1066
1136
|
* The message should already exist in the conversation.
|
|
@@ -1405,6 +1475,15 @@ function virtualRowAttachment(row) {
|
|
|
1405
1475
|
sending={streaming}
|
|
1406
1476
|
{allowAttachments}
|
|
1407
1477
|
onstop={streaming ? handleStopGenerating : undefined}
|
|
1478
|
+
{oncomposerinput}
|
|
1479
|
+
{oncomposerkeydown}
|
|
1480
|
+
{oncomposerselectionchange}
|
|
1481
|
+
{oncomposerblur}
|
|
1482
|
+
{composerRole}
|
|
1483
|
+
{composerAriaExpanded}
|
|
1484
|
+
{composerAriaControls}
|
|
1485
|
+
{composerAriaActiveDescendant}
|
|
1486
|
+
{composerAriaAutocomplete}
|
|
1408
1487
|
{onattachmentadd}
|
|
1409
1488
|
{onattachmentremove}
|
|
1410
1489
|
{onattachmentfailure}
|
|
@@ -1415,8 +1494,8 @@ function virtualRowAttachment(row) {
|
|
|
1415
1494
|
<ChatStatusAnnouncer
|
|
1416
1495
|
{statusId}
|
|
1417
1496
|
messageCount={messages.length}
|
|
1418
|
-
announcerMessage={
|
|
1419
|
-
assertiveMessage={
|
|
1497
|
+
announcerMessage={politeAnnouncement}
|
|
1498
|
+
assertiveMessage={assertiveAnnouncement}
|
|
1420
1499
|
/>
|
|
1421
1500
|
|
|
1422
1501
|
<!-- Typing-participant live region: outside role="log" to avoid double announcement.
|
|
@@ -13,7 +13,13 @@ import './chat.css';
|
|
|
13
13
|
import Chat from './chat.svelte';
|
|
14
14
|
|
|
15
15
|
export default Chat;
|
|
16
|
-
export type {
|
|
16
|
+
export type {
|
|
17
|
+
ChatAnnounceLevel,
|
|
18
|
+
ChatCapabilities,
|
|
19
|
+
ChatProps,
|
|
20
|
+
ReadReceipt,
|
|
21
|
+
TypingParticipant,
|
|
22
|
+
} from './chat.types.ts';
|
|
17
23
|
export { Chat };
|
|
18
24
|
|
|
19
25
|
// Adapter seam — the optional event/transport boundary around <Chat>. Type-only.
|
|
@@ -80,8 +86,14 @@ export {
|
|
|
80
86
|
} from './utilities';
|
|
81
87
|
|
|
82
88
|
// Input
|
|
83
|
-
export {
|
|
84
|
-
|
|
89
|
+
export {
|
|
90
|
+
ChatAttachmentPreview,
|
|
91
|
+
ChatInput,
|
|
92
|
+
deriveAttachmentKind,
|
|
93
|
+
serializeChatAttachment,
|
|
94
|
+
serializeChatAttachments,
|
|
95
|
+
} from './input';
|
|
96
|
+
export type { AttachmentKind, ChatAttachment, SerializedChatAttachment } from './input';
|
|
85
97
|
|
|
86
98
|
// Message
|
|
87
99
|
export {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ChatAttachment } from './chat-attachment.ts';
|
|
2
|
+
|
|
3
|
+
const BASE64_CHUNK_SIZE = 0x8000;
|
|
4
|
+
|
|
5
|
+
type Base64Runtime = typeof globalThis & {
|
|
6
|
+
btoa?: (data: string) => string;
|
|
7
|
+
Buffer?: {
|
|
8
|
+
from: (data: Uint8Array) => { toString: (encoding: 'base64') => string };
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export interface SerializedChatAttachment {
|
|
13
|
+
name: string;
|
|
14
|
+
mimeType: string;
|
|
15
|
+
kind: ChatAttachment['kind'];
|
|
16
|
+
content: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function bytesToBase64(bytes: Uint8Array): string {
|
|
20
|
+
const runtime = globalThis as Base64Runtime;
|
|
21
|
+
|
|
22
|
+
if (typeof runtime.btoa === 'function') {
|
|
23
|
+
let binary = '';
|
|
24
|
+
|
|
25
|
+
for (let start = 0; start < bytes.length; start += BASE64_CHUNK_SIZE) {
|
|
26
|
+
const chunk = bytes.subarray(start, start + BASE64_CHUNK_SIZE);
|
|
27
|
+
binary += String.fromCharCode(...chunk);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return runtime.btoa(binary);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof runtime.Buffer?.from === 'function') {
|
|
34
|
+
return runtime.Buffer.from(bytes).toString('base64');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
throw new Error('serializeChatAttachment requires btoa or Buffer for base64 encoding.');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function serializeChatAttachment(
|
|
41
|
+
attachment: ChatAttachment,
|
|
42
|
+
): Promise<SerializedChatAttachment> {
|
|
43
|
+
const bytes = new Uint8Array(await attachment.file.arrayBuffer());
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
name: attachment.file.name,
|
|
47
|
+
mimeType: attachment.file.type,
|
|
48
|
+
kind: attachment.kind,
|
|
49
|
+
content: bytesToBase64(bytes),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function serializeChatAttachments(
|
|
54
|
+
attachments: readonly ChatAttachment[],
|
|
55
|
+
): Promise<SerializedChatAttachment[]> {
|
|
56
|
+
const serializedAttachments: SerializedChatAttachment[] = [];
|
|
57
|
+
|
|
58
|
+
for (const attachment of attachments) {
|
|
59
|
+
serializedAttachments.push(await serializeChatAttachment(attachment));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return serializedAttachments;
|
|
63
|
+
}
|