@kitn.ai/ui 0.17.0 → 0.18.1
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/README.md +28 -5
- package/dist/components/artifact.d.ts +39 -1
- package/dist/components/attachment-types.d.ts +12 -0
- package/dist/components/attachments.d.ts +2 -10
- package/dist/components/card.d.ts +27 -0
- package/dist/components/chain-of-thought.d.ts +78 -2
- package/dist/components/chat-scope-picker.d.ts +7 -0
- package/dist/components/chat-thread.d.ts +37 -12
- package/dist/components/choice-card.d.ts +26 -0
- package/dist/components/coachmark.d.ts +49 -0
- package/dist/components/composer-dom.d.ts +35 -0
- package/dist/components/composer-highlight.d.ts +48 -0
- package/dist/components/composer-history.d.ts +34 -0
- package/dist/components/composer.d.ts +86 -0
- package/dist/components/confirm-card.d.ts +17 -0
- package/dist/components/conversation-item.d.ts +9 -0
- package/dist/components/conversation-list.d.ts +36 -1
- package/dist/components/file-tree.d.ts +15 -0
- package/dist/components/form.d.ts +34 -0
- package/dist/components/markdown.d.ts +3 -0
- package/dist/components/message.d.ts +12 -0
- package/dist/components/model-switcher.d.ts +7 -0
- package/dist/components/prompt-input.d.ts +13 -4
- package/dist/components/prompt-suggestion.d.ts +9 -1
- package/dist/components/reasoning.d.ts +14 -1
- package/dist/components/response-compare.d.ts +14 -0
- package/dist/components/screen.d.ts +46 -0
- package/dist/components/tasks-card.d.ts +49 -1
- package/dist/components/toast.d.ts +12 -2
- package/dist/components/tool-types.d.ts +10 -0
- package/dist/components/tool.d.ts +8 -8
- package/dist/components/voice-input.d.ts +27 -0
- package/dist/components/voice-output.d.ts +33 -0
- package/dist/core-C8fzo39E.js +12 -0
- package/dist/custom-elements.json +8392 -1860
- package/dist/elements/agent-card.d.ts +1 -0
- package/dist/elements/agent-card.js +1 -0
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.d.ts +1 -0
- package/dist/elements/avatar.js +1 -0
- package/dist/elements/badge.d.ts +1 -0
- package/dist/elements/badge.js +1 -0
- package/dist/elements/button.d.ts +1 -0
- package/dist/elements/button.js +1 -0
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-types.d.ts +47 -0
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/chunks/Icon-C2LTALdM.js +1 -0
- package/dist/elements/chunks/action-icons-Dtl8Ox5D.js +1 -0
- package/dist/elements/chunks/arrow-left-GbBceGBE.js +1 -0
- package/dist/elements/chunks/attachments-DLJcWCDV.js +1 -0
- package/dist/elements/chunks/badge-BTNZTODL.js +1 -0
- package/dist/elements/chunks/button-DBDZebGr.js +1 -0
- package/dist/elements/chunks/card-YfCyI4fH.js +1 -0
- package/dist/elements/chunks/chat-thread-Dz2qbzvI.js +1 -0
- package/dist/elements/chunks/check-fhmRksq_.js +1 -0
- package/dist/elements/chunks/chevron-down-DcRg1aRU.js +1 -0
- package/dist/elements/chunks/chevron-right-ChzBcNJ-.js +1 -0
- package/dist/elements/chunks/circle-B4fTe9v6.js +1 -0
- package/dist/elements/chunks/circle-check-CJV-3Rem.js +1 -0
- package/dist/elements/chunks/circle-x-pDtzlghQ.js +1 -0
- package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
- package/dist/elements/chunks/code-block-DZ6mz6vs.js +1 -0
- package/dist/elements/chunks/collapsible-CWUAShMC.js +1 -0
- package/dist/elements/chunks/composer-BZyPU6gD.js +65 -0
- package/dist/elements/chunks/context-Cx6eQA_G.js +1 -0
- package/dist/elements/chunks/conversation-list-C4xTQSpT.js +1 -0
- package/dist/elements/chunks/default-input-BZcwyKcP.js +1 -0
- package/dist/elements/chunks/define-CNSKFZCd.js +1 -0
- package/dist/elements/chunks/disclosure-BcBs--Jf.js +1 -0
- package/dist/elements/chunks/download-BDQwcFav.js +1 -0
- package/dist/elements/chunks/dropdown-wgs8xCJZ.js +1 -0
- package/dist/elements/chunks/ellipsis-CUiEJ6R1.js +1 -0
- package/dist/elements/chunks/external-link-DJUmC7g2.js +1 -0
- package/dist/elements/chunks/file-text-DOYfYvrh.js +1 -0
- package/dist/elements/chunks/file-tree-DQzNQrbr.js +1 -0
- package/dist/elements/chunks/folder-DBDUBANz.js +1 -0
- package/dist/elements/chunks/hover-card-BQGdGAQ3.js +1 -0
- package/dist/elements/chunks/icon-CAyRqVrg.js +1 -0
- package/dist/elements/chunks/{index-CTBEJeo6.js → index-BCRhi84a.js} +1 -1
- package/dist/elements/chunks/info-DBQl-m6e.js +1 -0
- package/dist/elements/chunks/input-DZD67EvW.js +1 -0
- package/dist/elements/chunks/kbd-DbyVrlnU.js +1 -0
- package/dist/elements/chunks/link-vko7AttA.js +1 -0
- package/dist/elements/chunks/loader-Cg6rO8tQ.js +1 -0
- package/dist/elements/chunks/{markdown-CMTGx9r8.js → markdown-n3Xbj3PR.js} +9 -9
- package/dist/elements/chunks/message-CgKytiSB.js +1 -0
- package/dist/elements/chunks/message-feedback-Ds3-US0e.js +1 -0
- package/dist/elements/chunks/message-square-MmRkvc-M.js +1 -0
- package/dist/elements/chunks/minimize-2-3kCdE0q3.js +1 -0
- package/dist/elements/chunks/model-switcher-BMtXGwLU.js +1 -0
- package/dist/elements/chunks/overlay-B1-MBI6h.js +1 -0
- package/dist/elements/chunks/paperclip-DDEfmkHc.js +1 -0
- package/dist/elements/chunks/progress-bar-Dwbiyv3s.js +1 -0
- package/dist/elements/chunks/prompt-suggestion-9lvgFcEa.js +1 -0
- package/dist/elements/chunks/reasoning-DzHWsdAJ.js +1 -0
- package/dist/elements/chunks/resizable-Bq_eHxUm.js +1 -0
- package/dist/elements/chunks/rotate-cw-jpisOdOV.js +1 -0
- package/dist/elements/chunks/scroll-area-g5Ze3K6f.js +1 -0
- package/dist/elements/chunks/separator-Bmjc5XyX.js +1 -0
- package/dist/elements/chunks/settings-Cz1bMJP9.js +1 -0
- package/dist/elements/chunks/settings-group-9imY3kRA.js +1 -0
- package/dist/elements/chunks/share-BdenF0wQ.js +1 -0
- package/dist/elements/chunks/skeleton-Pjc5jiaY.js +1 -0
- package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
- package/dist/elements/chunks/star-DY6z1UUH.js +1 -0
- package/dist/elements/chunks/store-th4VyJXM.js +1 -0
- package/dist/elements/chunks/text-shimmer-CEi-tlXr.js +1 -0
- package/dist/elements/chunks/textarea-CboigarR.js +1 -0
- package/dist/elements/chunks/thumbs-up-BR33KLfA.js +1 -0
- package/dist/elements/chunks/toast-store-BEMda0fv.js +1 -0
- package/dist/elements/chunks/tool-TMued3WO.js +1 -0
- package/dist/elements/chunks/tooltip-Cft_Rxiw.js +1 -0
- package/dist/elements/chunks/triangle-alert-B07fX3Q8.js +1 -0
- package/dist/elements/chunks/use-card-resolution-M36zVciB.js +1 -0
- package/dist/elements/chunks/video-MKp3LmNT.js +1 -0
- package/dist/elements/chunks/x-Ckwicf6g.js +1 -0
- package/dist/elements/coachmark.d.ts +1 -0
- package/dist/elements/coachmark.js +1 -0
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.d.ts +1 -0
- package/dist/elements/command.js +1 -0
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.d.ts +1 -0
- package/dist/elements/composer.js +1 -0
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/css.d.ts +1 -0
- package/dist/elements/default-input.d.ts +51 -0
- package/dist/elements/define.d.ts +53 -0
- package/dist/elements/dialog.d.ts +1 -0
- package/dist/elements/dialog.js +1 -0
- package/dist/elements/disclosure.d.ts +37 -0
- package/dist/elements/editable-label.d.ts +1 -0
- package/dist/elements/editable-label.js +1 -0
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.d.ts +1 -0
- package/dist/elements/hover-card.js +1 -0
- package/dist/elements/icon.d.ts +1 -0
- package/dist/elements/icon.js +1 -0
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.d.ts +1 -0
- package/dist/elements/input.js +1 -0
- package/dist/elements/kbd.d.ts +1 -0
- package/dist/elements/kbd.js +1 -0
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.d.ts +1 -0
- package/dist/elements/menu.js +1 -0
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.d.ts +1 -0
- package/dist/elements/nav.js +1 -0
- package/dist/elements/notice.d.ts +1 -0
- package/dist/elements/notice.js +1 -0
- package/dist/elements/pane-group.d.ts +1 -0
- package/dist/elements/pane-group.js +1 -0
- package/dist/elements/pane.d.ts +1 -0
- package/dist/elements/pane.js +1 -0
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.d.ts +1 -0
- package/dist/elements/progress-bar.js +1 -0
- package/dist/elements/prompt-dock.d.ts +1 -0
- package/dist/elements/prompt-dock.js +1 -0
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/register-impl.d.ts +0 -0
- package/dist/elements/register.d.ts +13 -0
- package/dist/elements/remote.d.ts +1 -0
- package/dist/elements/remote.js +1 -0
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +2 -2
- package/dist/elements/screen.d.ts +1 -0
- package/dist/elements/screen.js +1 -0
- package/dist/elements/scroll-area.d.ts +1 -0
- package/dist/elements/scroll-area.js +1 -0
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.d.ts +1 -0
- package/dist/elements/search.js +1 -0
- package/dist/elements/segmented.d.ts +1 -0
- package/dist/elements/segmented.js +1 -0
- package/dist/elements/separator.d.ts +1 -0
- package/dist/elements/separator.js +1 -0
- package/dist/elements/setting-item.d.ts +1 -0
- package/dist/elements/setting-item.js +1 -0
- package/dist/elements/settings-group.d.ts +1 -0
- package/dist/elements/settings-group.js +1 -0
- package/dist/elements/skeleton.d.ts +1 -0
- package/dist/elements/skeleton.js +1 -0
- package/dist/elements/slots.d.ts +176 -0
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.d.ts +1 -0
- package/dist/elements/status.js +1 -0
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.d.ts +1 -0
- package/dist/elements/tabs.js +1 -0
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.d.ts +1 -0
- package/dist/elements/tooltip.js +1 -0
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.d.ts +1 -0
- package/dist/elements/voice-output.js +1 -0
- package/dist/elements.d.ts +733 -58
- package/dist/engine-javascript-C1x7zo1_.js +141 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +8255 -5703
- package/dist/kai.es.js +1 -0
- package/dist/llms/llms-full.txt +1146 -64
- package/dist/llms/llms.txt +4 -4
- package/dist/mcp.es.js +62 -7
- package/dist/primitives/composer-model.d.ts +22 -0
- package/dist/primitives/composer-triggers.d.ts +19 -0
- package/dist/primitives/create-kai-chat.d.ts +38 -0
- package/dist/primitives/toast-store.d.ts +32 -2
- package/dist/primitives/use-speech-recognition.d.ts +26 -0
- package/dist/react/index.d.ts +1085 -97
- package/dist/react/runtime.d.ts +9 -2
- package/dist/react/use-kai-chat.d.ts +41 -0
- package/dist/react.js +572 -193
- package/dist/register-impl-cKscku5m.js +141 -0
- package/dist/schemas/tasks.schema.json +2 -2
- package/dist/state/index.d.ts +4 -0
- package/dist/state/messages.d.ts +11 -0
- package/dist/state/stream.d.ts +22 -0
- package/dist/state/suggestions.d.ts +4 -0
- package/dist/state.js +117 -0
- package/dist/theme.tokens.css +87 -0
- package/dist/types.d.ts +4 -0
- package/dist/ui/agent-card.d.ts +61 -0
- package/dist/ui/button.d.ts +5 -2
- package/dist/ui/card.d.ts +61 -0
- package/dist/ui/collapsible.d.ts +15 -1
- package/dist/ui/command.d.ts +33 -0
- package/dist/ui/dialog.d.ts +42 -0
- package/dist/ui/dropdown.d.ts +95 -1
- package/dist/ui/editable-label.d.ts +26 -0
- package/dist/ui/hover-card.d.ts +13 -1
- package/dist/ui/icon.d.ts +18 -0
- package/dist/ui/input.d.ts +33 -0
- package/dist/ui/kbd.d.ts +21 -0
- package/dist/ui/nav.d.ts +62 -0
- package/dist/ui/notice.d.ts +31 -0
- package/dist/ui/overlay.d.ts +12 -0
- package/dist/ui/pane-grid.d.ts +58 -0
- package/dist/ui/pane-group.d.ts +77 -0
- package/dist/ui/pane.d.ts +78 -0
- package/dist/ui/popover.d.ts +11 -1
- package/dist/ui/progress-bar.d.ts +23 -0
- package/dist/ui/prompt-dock.d.ts +96 -0
- package/dist/ui/resizable.d.ts +12 -0
- package/dist/ui/scroll-area.d.ts +4 -0
- package/dist/ui/segmented.d.ts +28 -0
- package/dist/ui/settings-group.d.ts +32 -0
- package/dist/ui/skeleton.d.ts +12 -0
- package/dist/ui/stat.d.ts +16 -0
- package/dist/ui/status.d.ts +13 -0
- package/dist/ui/switch.d.ts +8 -1
- package/dist/ui/tabs.d.ts +35 -0
- package/dist/ui/tooltip.d.ts +19 -1
- package/frameworks/react/index.tsx +1042 -157
- package/frameworks/react/runtime.tsx +30 -1
- package/frameworks/react/use-kai-chat.tsx +87 -0
- package/llms-full.txt +1146 -64
- package/llms.txt +4 -4
- package/package.json +31 -10
- package/src/agent-tooling/mcp/manifest.ts +14 -0
- package/src/agent-tooling/mcp/tools/debug.ts +11 -7
- package/src/agent-tooling/mcp/tools/reference.ts +32 -0
- package/src/agent-tooling/mcp/tools/scaffold.ts +30 -1
- package/src/components/artifact.tsx +98 -13
- package/src/components/attachment-types.ts +13 -0
- package/src/components/attachments.tsx +4 -14
- package/src/components/card.tsx +109 -15
- package/src/components/chain-of-thought.tsx +210 -1
- package/src/components/chat-scope-picker.tsx +13 -3
- package/src/components/chat-thread.tsx +225 -116
- package/src/components/choice-card.tsx +103 -11
- package/src/components/coachmark.tsx +249 -0
- package/src/components/component-meta.json +699 -110
- package/src/components/composer-dom.ts +159 -0
- package/src/components/composer-highlight.ts +242 -0
- package/src/components/composer-history.ts +82 -0
- package/src/components/composer.tsx +979 -0
- package/src/components/confirm-card.tsx +54 -1
- package/src/components/conversation-item.tsx +69 -7
- package/src/components/conversation-list.tsx +134 -37
- package/src/components/file-tree.tsx +197 -47
- package/src/components/form-widgets.tsx +9 -7
- package/src/components/form.tsx +140 -17
- package/src/components/image.tsx +3 -5
- package/src/components/link-preview.tsx +5 -4
- package/src/components/markdown.tsx +5 -2
- package/src/components/message.tsx +23 -4
- package/src/components/model-switcher.tsx +19 -4
- package/src/components/prompt-input.tsx +46 -75
- package/src/components/prompt-suggestion.tsx +48 -16
- package/src/components/reasoning.tsx +29 -6
- package/src/components/response-compare.tsx +31 -2
- package/src/components/screen.tsx +176 -0
- package/src/components/tasks-card.tsx +341 -21
- package/src/components/toast.tsx +119 -31
- package/src/components/tool-types.ts +10 -0
- package/src/components/tool.tsx +22 -16
- package/src/components/voice-input.tsx +102 -19
- package/src/components/voice-output.tsx +202 -0
- package/src/elements/agent-card.tsx +67 -0
- package/src/elements/artifact.tsx +53 -4
- package/src/elements/attachments.tsx +1 -0
- package/src/elements/avatar.tsx +33 -0
- package/src/elements/badge.tsx +32 -0
- package/src/elements/button.tsx +126 -0
- package/src/elements/card-media.jpg +0 -0
- package/src/elements/card.tsx +124 -31
- package/src/elements/cards.tsx +81 -7
- package/src/elements/chain-of-thought.tsx +77 -32
- package/src/elements/chat-scope-picker.tsx +35 -8
- package/src/elements/chat-types.ts +2 -2
- package/src/elements/chat-workspace.tsx +153 -41
- package/src/elements/chat.tsx +45 -23
- package/src/elements/choice.tsx +71 -19
- package/src/elements/coachmark.tsx +90 -0
- package/src/elements/command.tsx +209 -0
- package/src/elements/compare.tsx +24 -2
- package/src/elements/compiled.css +2 -2
- package/src/elements/composer.tsx +151 -0
- package/src/elements/confirm-card.tsx +36 -11
- package/src/elements/conversation-list.tsx +80 -11
- package/src/elements/default-input.tsx +75 -53
- package/src/elements/define.tsx +87 -7
- package/src/elements/dialog.tsx +98 -0
- package/src/elements/disclosure.ts +73 -0
- package/src/elements/editable-label.tsx +125 -0
- package/src/elements/element-manifest.json +129 -1
- package/src/elements/element-meta.json +5562 -1336
- package/src/elements/element-types.d.ts +732 -57
- package/src/elements/file-tree.tsx +12 -2
- package/src/elements/file-upload.tsx +1 -1
- package/src/elements/form.tsx +54 -11
- package/src/elements/hover-card.tsx +80 -0
- package/src/elements/icon-names.json +48 -0
- package/src/elements/icon.tsx +41 -0
- package/src/elements/input.tsx +203 -0
- package/src/elements/kbd.tsx +45 -0
- package/src/elements/menu.tsx +217 -0
- package/src/elements/message.tsx +58 -11
- package/src/elements/model-switcher.tsx +27 -1
- package/src/elements/nav.tsx +87 -0
- package/src/elements/notice.tsx +53 -0
- package/src/elements/pane-group.tsx +119 -0
- package/src/elements/pane.tsx +129 -0
- package/src/elements/popover.tsx +39 -17
- package/src/elements/progress-bar.tsx +39 -0
- package/src/elements/prompt-dock.tsx +81 -0
- package/src/elements/prompt-input.tsx +112 -63
- package/src/elements/prompt-suggestions.tsx +25 -9
- package/src/elements/reasoning.tsx +30 -9
- package/src/elements/register-impl.ts +38 -3
- package/src/elements/register.ts +11 -3
- package/src/elements/resizable.tsx +48 -11
- package/src/elements/screen.tsx +90 -0
- package/src/elements/scroll-area.tsx +33 -0
- package/src/elements/search.tsx +180 -0
- package/src/elements/segmented.tsx +135 -0
- package/src/elements/separator.tsx +36 -0
- package/src/elements/setting-item.tsx +50 -0
- package/src/elements/settings-group.tsx +37 -0
- package/src/elements/skeleton.tsx +45 -0
- package/src/elements/slots.ts +607 -0
- package/src/elements/source.tsx +13 -6
- package/src/elements/status.tsx +42 -0
- package/src/elements/switch.tsx +89 -14
- package/src/elements/tabs.tsx +95 -0
- package/src/elements/tasks.tsx +70 -14
- package/src/elements/toast.tsx +17 -2
- package/src/elements/tool.tsx +43 -9
- package/src/elements/tooltip.tsx +85 -0
- package/src/elements/video-poster.jpg +0 -0
- package/src/elements/voice-input.tsx +66 -16
- package/src/elements/voice-output.tsx +69 -0
- package/src/index.ts +5 -2
- package/src/primitives/card-schemas/tasks.schema.json +2 -2
- package/src/primitives/composer-model.ts +49 -0
- package/src/primitives/composer-triggers.ts +35 -0
- package/src/primitives/create-kai-chat.ts +66 -0
- package/src/primitives/toast-store.ts +43 -2
- package/src/primitives/use-speech-recognition.ts +135 -0
- package/src/state/index.ts +6 -0
- package/src/state/messages.ts +36 -0
- package/src/state/stream.ts +92 -0
- package/src/state/suggestions.ts +9 -0
- package/src/types.ts +4 -0
- package/src/ui/agent-card.tsx +218 -0
- package/src/ui/button.tsx +16 -5
- package/src/ui/card.tsx +245 -0
- package/src/ui/collapsible.tsx +30 -4
- package/src/ui/command.tsx +99 -0
- package/src/ui/dialog.tsx +217 -0
- package/src/ui/dropdown.tsx +375 -13
- package/src/ui/editable-label.tsx +112 -0
- package/src/ui/hover-card.tsx +28 -5
- package/src/ui/icon.tsx +110 -0
- package/src/ui/input.tsx +132 -0
- package/src/ui/kbd.tsx +118 -0
- package/src/ui/nav.tsx +282 -0
- package/src/ui/notice.tsx +84 -0
- package/src/ui/overlay.tsx +108 -2
- package/src/ui/pane-grid.tsx +117 -0
- package/src/ui/pane-group.tsx +291 -0
- package/src/ui/pane.tsx +193 -0
- package/src/ui/popover.tsx +16 -2
- package/src/ui/progress-bar.tsx +83 -0
- package/src/ui/prompt-dock.tsx +145 -0
- package/src/ui/resizable.tsx +69 -1
- package/src/ui/scroll-area.tsx +14 -3
- package/src/ui/segmented.tsx +109 -0
- package/src/ui/settings-group.tsx +67 -0
- package/src/ui/skeleton.tsx +62 -5
- package/src/ui/stat.tsx +41 -0
- package/src/ui/status.tsx +48 -0
- package/src/ui/switch.tsx +49 -23
- package/src/ui/tabs.tsx +168 -0
- package/src/ui/tooltip.tsx +52 -8
- package/theme.css +113 -0
- package/dist/components/slash-command.d.ts +0 -15
- package/dist/elements/chunks/Icon-D_Zmwmwh.js +0 -1
- package/dist/elements/chunks/action-icons-PVfIvcuG.js +0 -1
- package/dist/elements/chunks/attachments-Dp6vqtrc.js +0 -1
- package/dist/elements/chunks/button-CKyYD9G4.js +0 -1
- package/dist/elements/chunks/card-Cjho-PYk.js +0 -1
- package/dist/elements/chunks/chat-thread-RT808iPf.js +0 -1
- package/dist/elements/chunks/check-CDYaMYrM.js +0 -1
- package/dist/elements/chunks/chevron-down-3SBiq8HF.js +0 -1
- package/dist/elements/chunks/chevron-right-k2UFlIVK.js +0 -1
- package/dist/elements/chunks/cn-Dogu6PbV.js +0 -1
- package/dist/elements/chunks/code-block-BYUmfFSd.js +0 -1
- package/dist/elements/chunks/collapsible-BiNwdOn6.js +0 -1
- package/dist/elements/chunks/context-18g6oi4J.js +0 -1
- package/dist/elements/chunks/conversation-list-D9Y0NVdo.js +0 -1
- package/dist/elements/chunks/default-input-CSAoYYMd.js +0 -1
- package/dist/elements/chunks/download-D8K0Je8r.js +0 -1
- package/dist/elements/chunks/dropdown-bUs2iTia.js +0 -1
- package/dist/elements/chunks/external-link-6mA0wxab.js +0 -1
- package/dist/elements/chunks/file-text-DnaYk3Dm.js +0 -1
- package/dist/elements/chunks/file-tree-CgtRLlxK.js +0 -1
- package/dist/elements/chunks/hover-card-CIGw62gP.js +0 -1
- package/dist/elements/chunks/link-BlGSeoPy.js +0 -1
- package/dist/elements/chunks/loader-DvhR4qa0.js +0 -1
- package/dist/elements/chunks/message-CDZwXjhL.js +0 -1
- package/dist/elements/chunks/message-feedback-CYx81QiA.js +0 -1
- package/dist/elements/chunks/model-switcher-O_tUhoOT.js +0 -1
- package/dist/elements/chunks/overlay-DydXYMQW.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-ldlWV5kd.js +0 -1
- package/dist/elements/chunks/reasoning-2PUnHlmr.js +0 -1
- package/dist/elements/chunks/resizable-B5WNbSeb.js +0 -1
- package/dist/elements/chunks/star-t9tI-P0q.js +0 -1
- package/dist/elements/chunks/store-C6rIooZz.js +0 -1
- package/dist/elements/chunks/text-shimmer-uh9V_KUh.js +0 -1
- package/dist/elements/chunks/textarea-3nm6Ia9U.js +0 -1
- package/dist/elements/chunks/thumbs-up-BBtguGld.js +0 -1
- package/dist/elements/chunks/toast-store-D8cL3fWl.js +0 -1
- package/dist/elements/chunks/tool-GJ3vwp1U.js +0 -1
- package/dist/elements/chunks/tooltip-DwKAz4XR.js +0 -1
- package/dist/elements/chunks/triangle-alert-Ct1zt2JL.js +0 -1
- package/dist/elements/chunks/use-card-resolution-D-_0Alzy.js +0 -1
- package/dist/elements/chunks/video-mVYiM99-.js +0 -1
- package/dist/elements/chunks/x-CzxL27Ch.js +0 -1
- package/dist/kitn-chat.es.js +0 -1
- package/dist/register-JyTglR6m.js +0 -1
- package/dist/register-impl-C6wlSsts.js +0 -77
- package/src/components/slash-command.tsx +0 -232
- package/src/elements/framework-usage.json +0 -588
- /package/dist/{kitn-chat-provider.d.ts → kai-provider.d.ts} +0 -0
- /package/dist/{kitn-chat-provider.es.js → kai-provider.es.js} +0 -0
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
|
|
2
2
|
# @kitn.ai/ui
|
|
3
3
|
|
|
4
|
-
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML.
|
|
4
|
+
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 78 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ npm install solid-js
|
|
|
13
13
|
|
|
14
14
|
## #1 rule: array/object data goes on JS PROPERTIES, not HTML attributes
|
|
15
15
|
|
|
16
|
-
This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `
|
|
16
|
+
This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `triggers`, …) MUST be assigned as JavaScript properties on the element. They CANNOT be passed as HTML attributes — an HTML attribute is always a string and will be ignored or mis-parsed.
|
|
17
17
|
|
|
18
18
|
```js
|
|
19
19
|
const chat = document.querySelector('kai-chat');
|
|
@@ -35,7 +35,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
|
|
|
35
35
|
- `<kai-prompt-input>` — standalone composer with send button.
|
|
36
36
|
|
|
37
37
|
**Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
|
|
38
|
-
All
|
|
38
|
+
All 78 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
|
|
39
39
|
|
|
40
40
|
## Key rules for the web components
|
|
41
41
|
|
|
@@ -97,7 +97,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
|
|
|
97
97
|
|
|
98
98
|
## Docs
|
|
99
99
|
|
|
100
|
-
- Full element reference (all
|
|
100
|
+
- Full element reference (all 78 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
|
|
101
101
|
- Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
|
|
102
102
|
- Working examples: https://github.com/kitn-ai/ui/tree/main/examples
|
|
103
103
|
- Storybook: https://storybook.kitn.dev
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitn.ai/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
|
+
"nx": {
|
|
5
|
+
"name": "ui"
|
|
6
|
+
},
|
|
4
7
|
"type": "module",
|
|
8
|
+
"sideEffects": [
|
|
9
|
+
"**/*.css",
|
|
10
|
+
"./dist/kai.es.js",
|
|
11
|
+
"./dist/elements/*.js"
|
|
12
|
+
],
|
|
5
13
|
"description": "Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.",
|
|
6
14
|
"keywords": [
|
|
7
15
|
"web-components",
|
|
@@ -33,8 +41,8 @@
|
|
|
33
41
|
"main": "./dist/index.js",
|
|
34
42
|
"module": "./dist/index.js",
|
|
35
43
|
"types": "./dist/index.d.ts",
|
|
36
|
-
"unpkg": "./dist/
|
|
37
|
-
"jsdelivr": "./dist/
|
|
44
|
+
"unpkg": "./dist/kai.es.js",
|
|
45
|
+
"jsdelivr": "./dist/kai.es.js",
|
|
38
46
|
"customElements": "dist/custom-elements.json",
|
|
39
47
|
"bin": {
|
|
40
48
|
"kai-mcp": "./bin/mcp.js"
|
|
@@ -46,7 +54,7 @@
|
|
|
46
54
|
},
|
|
47
55
|
"./elements": {
|
|
48
56
|
"types": "./dist/elements.d.ts",
|
|
49
|
-
"default": "./dist/
|
|
57
|
+
"default": "./dist/kai.es.js"
|
|
50
58
|
},
|
|
51
59
|
"./elements/*": {
|
|
52
60
|
"types": "./dist/elements/*.d.ts",
|
|
@@ -58,13 +66,20 @@
|
|
|
58
66
|
},
|
|
59
67
|
"./theme.css": "./theme.css",
|
|
60
68
|
"./theme.tokens.css": "./dist/theme.tokens.css",
|
|
69
|
+
"./element-meta.json": "./src/elements/element-meta.json",
|
|
70
|
+
"./icon-names.json": "./src/elements/icon-names.json",
|
|
71
|
+
"./package.json": "./package.json",
|
|
61
72
|
"./react": {
|
|
62
73
|
"types": "./dist/react/index.d.ts",
|
|
63
74
|
"default": "./dist/react.js"
|
|
64
75
|
},
|
|
76
|
+
"./state": {
|
|
77
|
+
"types": "./dist/state/index.d.ts",
|
|
78
|
+
"default": "./dist/state.js"
|
|
79
|
+
},
|
|
65
80
|
"./provider": {
|
|
66
|
-
"types": "./dist/
|
|
67
|
-
"default": "./dist/
|
|
81
|
+
"types": "./dist/kai-provider.d.ts",
|
|
82
|
+
"default": "./dist/kai-provider.es.js"
|
|
68
83
|
}
|
|
69
84
|
},
|
|
70
85
|
"files": [
|
|
@@ -76,6 +91,7 @@
|
|
|
76
91
|
"!src/**/*.test.tsx",
|
|
77
92
|
"!src/**/*.mdx",
|
|
78
93
|
"!src/stories",
|
|
94
|
+
"!src/elements/logos",
|
|
79
95
|
"frameworks",
|
|
80
96
|
"theme.css",
|
|
81
97
|
"llms.txt",
|
|
@@ -84,7 +100,7 @@
|
|
|
84
100
|
"scripts": {
|
|
85
101
|
"prepublishOnly": "npm run build",
|
|
86
102
|
"prebuild": "npm run build:css",
|
|
87
|
-
"build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.mcp.ts && npm run build:elements",
|
|
103
|
+
"build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts && vite build --config vite.config.react.ts && vite build --config vite.config.barrel.ts && vite build --config vite.config.state.ts && vite build --config vite.config.mcp.ts && npm run build:elements && node scripts/verify-elements-bundle.mjs && node scripts/verify-react-wrappers.mjs",
|
|
88
104
|
"build:elements": "node scripts/gen-elements-manifest.mjs && vite build --config vite.config.elements.ts && node scripts/gen-element-dts.mjs",
|
|
89
105
|
"postbuild": "npm run build:theme && npm run build:api && npm run build:schemas",
|
|
90
106
|
"build:theme": "node scripts/build-theme-tokens.mjs",
|
|
@@ -93,6 +109,7 @@
|
|
|
93
109
|
"test": "vitest run",
|
|
94
110
|
"test:react": "vitest run --config vitest.react.config.ts",
|
|
95
111
|
"test:storybook": "vitest run --project=storybook",
|
|
112
|
+
"test:storybook:ci": "node scripts/run-storybook-tests.mjs",
|
|
96
113
|
"test:watch": "vitest",
|
|
97
114
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.react.json && tsc --noEmit -p tsconfig.react.test.json && tsc --noEmit -p tsconfig.mcp.json",
|
|
98
115
|
"examples": "echo 'Serving repo root on http://localhost:8000 — open http://localhost:8000/examples/composable/index.html' && python3 -m http.server 8000",
|
|
@@ -101,9 +118,13 @@
|
|
|
101
118
|
"build-storybook": "npm run build:css && storybook build",
|
|
102
119
|
"build:css": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --minify",
|
|
103
120
|
"build:css:watch": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --watch",
|
|
104
|
-
"dev:provider": "vite examples/remote-provider --port 6007 --strictPort",
|
|
105
|
-
"dev:host": "vite examples/remote-host --port 6006 --strictPort",
|
|
106
|
-
"test:e2e": "playwright test"
|
|
121
|
+
"dev:provider": "vite ../../examples/remote-provider --port 6007 --strictPort",
|
|
122
|
+
"dev:host": "vite ../../examples/remote-host --port 6006 --strictPort",
|
|
123
|
+
"test:e2e": "playwright test",
|
|
124
|
+
"test:composer-ivp": "playwright test --config playwright.composer.config.ts",
|
|
125
|
+
"test:slots-ivp": "playwright test --config playwright.slots.config.ts",
|
|
126
|
+
"test:menu-ivp": "playwright test --config playwright.menu.config.ts",
|
|
127
|
+
"test:command-ivp": "playwright test --config playwright.command.config.ts"
|
|
107
128
|
},
|
|
108
129
|
"dependencies": {
|
|
109
130
|
"@floating-ui/dom": "^1.7.6",
|
|
@@ -46,6 +46,18 @@ export interface CemCssProperty {
|
|
|
46
46
|
default?: string;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export interface CemSlot {
|
|
50
|
+
name: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface CemCssPart {
|
|
55
|
+
name: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
/** Our extension: a copy-paste styling example. */
|
|
58
|
+
recipe?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
49
61
|
export interface Declaration {
|
|
50
62
|
tagName?: string;
|
|
51
63
|
name: string;
|
|
@@ -55,6 +67,8 @@ export interface Declaration {
|
|
|
55
67
|
attributes?: CemAttribute[];
|
|
56
68
|
events?: CemEvent[];
|
|
57
69
|
cssProperties?: CemCssProperty[];
|
|
70
|
+
slots?: CemSlot[];
|
|
71
|
+
cssParts?: CemCssPart[];
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
interface CemModule {
|
|
@@ -9,7 +9,7 @@ import type { Tool } from './types';
|
|
|
9
9
|
* self-correct without a human in the loop.
|
|
10
10
|
*
|
|
11
11
|
* Rule set sourced from:
|
|
12
|
-
* - docs
|
|
12
|
+
* - apps/docs/src/content/docs/guides/for-ai-agents.mdx §"What agents most commonly get wrong"
|
|
13
13
|
* - context7.json `rules` array (5 contract rules)
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -27,11 +27,11 @@ const RULES: Rule[] = [
|
|
|
27
27
|
// Source: for-ai-agents.mdx §1; context7.json rule 2
|
|
28
28
|
id: 'array-as-attribute',
|
|
29
29
|
test: (t) =>
|
|
30
|
-
/\b(messages|models|context|suggestions|
|
|
30
|
+
/\b(messages|models|context|suggestions|triggers)\s*=\s*["']/.test(t),
|
|
31
31
|
title: 'Array/object prop set as an HTML attribute (silent failure)',
|
|
32
32
|
cause:
|
|
33
33
|
'An HTML attribute is always a string. Passing `messages`, `models`, `context`, ' +
|
|
34
|
-
'`suggestions`, or `
|
|
34
|
+
'`suggestions`, or `triggers` as an HTML attribute silently fails — ' +
|
|
35
35
|
'the element receives a stringified value it cannot parse.',
|
|
36
36
|
fix:
|
|
37
37
|
'Set the property in JavaScript, not as an HTML attribute. ' +
|
|
@@ -72,7 +72,11 @@ const RULES: Rule[] = [
|
|
|
72
72
|
'// ❌ Does NOT trigger re-render\n' +
|
|
73
73
|
'chat.messages.push(newMsg);\n' +
|
|
74
74
|
'chat.messages[i].content = accumulated;\n' +
|
|
75
|
-
'
|
|
75
|
+
'```\n\n' +
|
|
76
|
+
'The ergonomic path: helpers in `@kitn.ai/ui/state` (`appendMessage`, `updateMessage`, `appendContent`) ' +
|
|
77
|
+
'and `createAssistantStream` handle the new-reference contract for you. ' +
|
|
78
|
+
'`useKaiChat` (React) and `createKaiChat` (Solid) own state entirely so mutation is never an option.\n\n' +
|
|
79
|
+
'// setMessages((m) => appendMessage(m, msg)) // new array, no footgun',
|
|
76
80
|
},
|
|
77
81
|
{
|
|
78
82
|
// Rule 3 — listening for events on a parent / wrong element
|
|
@@ -108,15 +112,15 @@ const RULES: Rule[] = [
|
|
|
108
112
|
title: 'Wrong element prefix `kitn-` (should be `kai-`)',
|
|
109
113
|
cause:
|
|
110
114
|
'The custom element prefix is `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`). ' +
|
|
111
|
-
'`kitn
|
|
112
|
-
'Using `<kitn-chat>` results in an unknown element that renders nothing.',
|
|
115
|
+
'`kitn-` is a legacy name (the register-all bundle is `kai.es.js`) — it is not a ' +
|
|
116
|
+
'registered element name. Using `<kitn-chat>` results in an unknown element that renders nothing.',
|
|
113
117
|
fix:
|
|
114
118
|
'Replace the `kitn-` prefix with `kai-` everywhere.\n\n' +
|
|
115
119
|
'```html\n' +
|
|
116
120
|
'<!-- ✅ Correct element prefix -->\n' +
|
|
117
121
|
'<kai-chat></kai-chat>\n' +
|
|
118
122
|
'<kai-artifact></kai-artifact>\n\n' +
|
|
119
|
-
'<!-- ❌ Wrong — kitn-chat is
|
|
123
|
+
'<!-- ❌ Wrong — kitn-chat is not an element (the bundle is kai.es.js) -->\n' +
|
|
120
124
|
'<kitn-chat></kitn-chat>\n' +
|
|
121
125
|
'```',
|
|
122
126
|
},
|
|
@@ -104,6 +104,38 @@ function formatReference(tag: string): string {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
// ── Composition slots ──────────────────────────────────────────────────────
|
|
108
|
+
const slots = el.slots ?? [];
|
|
109
|
+
if (slots.length > 0) {
|
|
110
|
+
lines.push(
|
|
111
|
+
'',
|
|
112
|
+
'### Composition slots',
|
|
113
|
+
'Project your own markup into these named regions — add a light-DOM child ' +
|
|
114
|
+
'with a `slot="…"` attribute (e.g. `<div slot="sidebar">…</div>`).',
|
|
115
|
+
);
|
|
116
|
+
for (const slot of slots) {
|
|
117
|
+
const desc = slot.description?.trim() ?? '';
|
|
118
|
+
lines.push(`- **${slot.name}**${desc ? ` — ${desc}` : ''}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ── Styleable parts (::part) ───────────────────────────────────────────────
|
|
123
|
+
const parts = el.cssParts ?? [];
|
|
124
|
+
if (parts.length > 0) {
|
|
125
|
+
lines.push(
|
|
126
|
+
'',
|
|
127
|
+
'### Styleable parts (`::part`)',
|
|
128
|
+
'Restyle these from outside the Shadow DOM via `' + tag + '::part(name) { … }`.',
|
|
129
|
+
);
|
|
130
|
+
for (const part of parts) {
|
|
131
|
+
const desc = part.description?.trim() ?? '';
|
|
132
|
+
lines.push(`- **${part.name}**${desc ? ` — ${desc}` : ''}`);
|
|
133
|
+
if (part.recipe) {
|
|
134
|
+
lines.push(' ```css', ` ${part.recipe}`, ' ```');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
107
139
|
return lines.join('\n');
|
|
108
140
|
}
|
|
109
141
|
|
|
@@ -1651,10 +1651,37 @@ function interactionPatternsBlock(): string {
|
|
|
1651
1651
|
`});`,
|
|
1652
1652
|
].join('\n');
|
|
1653
1653
|
|
|
1654
|
+
const statePattern = [
|
|
1655
|
+
`--- Pattern: State helpers + streaming (new-array contract) ---`,
|
|
1656
|
+
`// Setter contract: always (prev) => next — every helper returns a new array.`,
|
|
1657
|
+
`// Vanilla adapter (works with any element ref):`,
|
|
1658
|
+
`// const set = (fn) => { el.messages = fn(el.messages ?? []); };`,
|
|
1659
|
+
``,
|
|
1660
|
+
`// Low-level helpers from @kitn.ai/ui/state:`,
|
|
1661
|
+
`// import { appendMessage, updateMessage, appendContent, createAssistantStream } from '@kitn.ai/ui/state';`,
|
|
1662
|
+
``,
|
|
1663
|
+
`// Streaming loop (framework-agnostic):`,
|
|
1664
|
+
`// const stream = createAssistantStream(set);`,
|
|
1665
|
+
`// stream.appendText(chunk); // text delta`,
|
|
1666
|
+
`// stream.appendReasoning(chunk); // reasoning delta`,
|
|
1667
|
+
`// stream.upsertTool(toolCall); // tool call delta`,
|
|
1668
|
+
`// stream.done(); // seal the message`,
|
|
1669
|
+
``,
|
|
1670
|
+
`// One-liner for React (batteries-included):`,
|
|
1671
|
+
`// import { useKaiChat } from '@kitn.ai/ui/react';`,
|
|
1672
|
+
`// const chat = useKaiChat();`,
|
|
1673
|
+
`// <Chat {...chat.bind} />`,
|
|
1674
|
+
``,
|
|
1675
|
+
`// One-liner for Solid (batteries-included):`,
|
|
1676
|
+
`// import { createKaiChat } from '@kitn.ai/ui';`,
|
|
1677
|
+
`// const chat = createKaiChat();`,
|
|
1678
|
+
`// <kai-chat {...chat.bind} on:kai-submit={chat.handleSubmit} />`,
|
|
1679
|
+
].join('\n');
|
|
1680
|
+
|
|
1654
1681
|
return [
|
|
1655
1682
|
`=== INTERACTION PATTERNS ===`,
|
|
1656
1683
|
``,
|
|
1657
|
-
`Optional snippets for confirmations, card recovery, and
|
|
1684
|
+
`Optional snippets for confirmations, card recovery, preference capture, and state/streaming helpers.`,
|
|
1658
1685
|
`Drop in the one(s) you need; all imports resolve from @kitn.ai/ui.`,
|
|
1659
1686
|
``,
|
|
1660
1687
|
toastPattern,
|
|
@@ -1662,6 +1689,8 @@ function interactionPatternsBlock(): string {
|
|
|
1662
1689
|
recoveryPattern,
|
|
1663
1690
|
``,
|
|
1664
1691
|
preferencePattern,
|
|
1692
|
+
``,
|
|
1693
|
+
statePattern,
|
|
1665
1694
|
].join('\n');
|
|
1666
1695
|
}
|
|
1667
1696
|
|
|
@@ -35,13 +35,43 @@ export type ArtifactTab = 'preview' | 'code';
|
|
|
35
35
|
/** A file the artifact can preview + show source for. */
|
|
36
36
|
export type ArtifactFile = FileTreeFile;
|
|
37
37
|
|
|
38
|
+
/** Imperative handle exposed via `controllerRef` — surfaces the artifact's latent
|
|
39
|
+
* toolbar capabilities (history back/forward/reload/home, programmatic navigate,
|
|
40
|
+
* file selection, open-in-new-tab, maximize/restore) so the `<kai-artifact>`
|
|
41
|
+
* facade can forward them as instance methods. Each delegates to the SAME internal
|
|
42
|
+
* handler the toolbar buttons use, so every existing event still fires. */
|
|
43
|
+
export interface ArtifactController {
|
|
44
|
+
/** Go back in the artifact's own history stack (no-op when there's no prior entry). */
|
|
45
|
+
back(): void;
|
|
46
|
+
/** Go forward in the history stack (no-op when there's no forward entry). */
|
|
47
|
+
forward(): void;
|
|
48
|
+
/** Force-reload the current preview url (also re-renders an inline PDF). */
|
|
49
|
+
reload(): void;
|
|
50
|
+
/** Navigate to the `src` home url (no-op when there's no `src`). */
|
|
51
|
+
home(): void;
|
|
52
|
+
/** Push + load a url in the preview (the path-field submit path). */
|
|
53
|
+
navigate(url: string): void;
|
|
54
|
+
/** Select a file by path: highlights the tree, shows its source, navigates the preview. */
|
|
55
|
+
selectFile(path: string): void;
|
|
56
|
+
/** Open the current url in a new browser tab (no-op when there's no concrete url). */
|
|
57
|
+
openExternal(): void;
|
|
58
|
+
/** Enter the maximized view-state (fires onMaximizeChange/kai-maximize-change). */
|
|
59
|
+
maximize(): void;
|
|
60
|
+
/** Exit the maximized view-state. */
|
|
61
|
+
restore(): void;
|
|
62
|
+
}
|
|
63
|
+
|
|
38
64
|
export interface ArtifactProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'onSelect'> {
|
|
39
65
|
/** URL the preview iframe frames. */
|
|
40
66
|
src?: string;
|
|
41
67
|
/** Files for the Code tab's tree (+ each file's preview `url`). */
|
|
42
68
|
files?: ArtifactFile[];
|
|
43
|
-
/**
|
|
69
|
+
/** Controlled active tab — when set, the artifact follows it (re-asserted on
|
|
70
|
+
* every change). When undefined the tab is uncontrolled (see `defaultTab`). */
|
|
44
71
|
tab?: ArtifactTab;
|
|
72
|
+
/** Uncontrolled INITIAL tab (used only when `tab` is undefined). The user can
|
|
73
|
+
* then freely switch tabs; defaults to `preview`. */
|
|
74
|
+
defaultTab?: ArtifactTab;
|
|
45
75
|
/** Selected file path (syncs tree highlight + Code source + preview). */
|
|
46
76
|
activeFile?: string;
|
|
47
77
|
/** iframe `sandbox` override. Default `allow-scripts allow-forms`. */
|
|
@@ -80,6 +110,15 @@ export interface ArtifactProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>,
|
|
|
80
110
|
standalone?: boolean;
|
|
81
111
|
/** Make the path field read-only (visible, nav-tracking, non-editable). */
|
|
82
112
|
readonlyPath?: boolean;
|
|
113
|
+
/** Friendly address shown in the path field INSTEAD of the real current url
|
|
114
|
+
* (read-only, non-navigable). Use when the framed url is not consumer-facing
|
|
115
|
+
* (e.g. a `data:` blob) so a clean address is shown instead of leaking it.
|
|
116
|
+
* Unset = show the real url (editable per `readonlyPath`). */
|
|
117
|
+
displayUrl?: string;
|
|
118
|
+
/** Receive the imperative controller once mounted. The `<kai-artifact>` facade
|
|
119
|
+
* forwards these as element methods (back/forward/reload/home/navigate/
|
|
120
|
+
* selectFile/openExternal/maximize/restore). */
|
|
121
|
+
controllerRef?: (controller: ArtifactController) => void;
|
|
83
122
|
}
|
|
84
123
|
|
|
85
124
|
const DEFAULT_SANDBOX = 'allow-scripts allow-forms';
|
|
@@ -116,7 +155,9 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
116
155
|
const merged = mergeProps(
|
|
117
156
|
{
|
|
118
157
|
files: [] as ArtifactFile[],
|
|
119
|
-
tab:
|
|
158
|
+
// No `tab` default: a present `tab` means controlled. The uncontrolled
|
|
159
|
+
// initial tab comes from `defaultTab` (seeded into the internal signal below).
|
|
160
|
+
defaultTab: 'preview' as ArtifactTab,
|
|
120
161
|
sandbox: DEFAULT_SANDBOX,
|
|
121
162
|
showNav: true,
|
|
122
163
|
showReload: true,
|
|
@@ -135,6 +176,7 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
135
176
|
'src',
|
|
136
177
|
'files',
|
|
137
178
|
'tab',
|
|
179
|
+
'defaultTab',
|
|
138
180
|
'activeFile',
|
|
139
181
|
'sandbox',
|
|
140
182
|
'iframeTitle',
|
|
@@ -152,6 +194,8 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
152
194
|
'openInTab',
|
|
153
195
|
'standalone',
|
|
154
196
|
'readonlyPath',
|
|
197
|
+
'displayUrl',
|
|
198
|
+
'controllerRef',
|
|
155
199
|
'class',
|
|
156
200
|
]);
|
|
157
201
|
|
|
@@ -169,7 +213,11 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
169
213
|
const canBack = () => cursor() > 0;
|
|
170
214
|
const canForward = () => cursor() < history().length - 1;
|
|
171
215
|
|
|
172
|
-
|
|
216
|
+
// Seed the internal tab: a present `tab` (controlled) wins; otherwise the
|
|
217
|
+
// uncontrolled `defaultTab` (which merges to 'preview'). The user can then
|
|
218
|
+
// switch freely unless `tab` is set (the effect below re-asserts the controlled
|
|
219
|
+
// value on each change).
|
|
220
|
+
const [tab, setTab] = createSignal<ArtifactTab>(local.tab ?? local.defaultTab);
|
|
173
221
|
const [activeFile, setActiveFile] = createSignal<string | undefined>(local.activeFile);
|
|
174
222
|
const [reloadKey, setReloadKey] = createSignal(0);
|
|
175
223
|
|
|
@@ -208,8 +256,12 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
208
256
|
|
|
209
257
|
let iframeEl: HTMLIFrameElement | undefined;
|
|
210
258
|
|
|
211
|
-
// Controlled syncing: when the consumer changes the props, follow them.
|
|
212
|
-
|
|
259
|
+
// Controlled syncing: when the consumer changes the props, follow them. `tab` is
|
|
260
|
+
// followed ONLY when it's actually set — an undefined `tab` means uncontrolled,
|
|
261
|
+
// so the internal signal (seeded from defaultTab) is left for the user to drive.
|
|
262
|
+
createEffect(() => {
|
|
263
|
+
if (local.tab !== undefined) setTab(local.tab);
|
|
264
|
+
});
|
|
213
265
|
createEffect(() => setActiveFile(local.activeFile));
|
|
214
266
|
// `src` change → navigate. Use `on(local.src, …)` so the effect tracks ONLY
|
|
215
267
|
// the `src` prop — NOT `currentUrl()` — otherwise navigating away (file click,
|
|
@@ -290,6 +342,38 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
290
342
|
if (local.src) navigate(local.src);
|
|
291
343
|
};
|
|
292
344
|
|
|
345
|
+
// Explicitly drive the maximize view-state to a target (the imperative twin of
|
|
346
|
+
// the toggle button). Fires onMaximizeChange only when the value actually flips,
|
|
347
|
+
// matching toggleMaximize's "report on change" contract.
|
|
348
|
+
const setMaximizeState = (next: boolean) => {
|
|
349
|
+
if (maximized() === next) return;
|
|
350
|
+
setMaximized(next);
|
|
351
|
+
local.onMaximizeChange?.(next);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
// --- Imperative controller (Pattern C): hand the facade a handle over the
|
|
355
|
+
// artifact's latent toolbar capabilities. Every method delegates to the
|
|
356
|
+
// SAME internal handler the toolbar buttons use, so navigate/tab-change/
|
|
357
|
+
// file-select/maximize-change all still fire. ---
|
|
358
|
+
onMount(() => {
|
|
359
|
+
local.controllerRef?.({
|
|
360
|
+
back: () => goBack(),
|
|
361
|
+
forward: () => goForward(),
|
|
362
|
+
reload: () => reload(),
|
|
363
|
+
home: () => goHome(),
|
|
364
|
+
navigate: (url) => navigate(url),
|
|
365
|
+
// Resolve the file for the path so highlight + source + preview all sync;
|
|
366
|
+
// a path with no matching file entry is a no-op (nothing to show).
|
|
367
|
+
selectFile: (path) => {
|
|
368
|
+
const file = fileFor(path);
|
|
369
|
+
if (file) selectFile(path, file);
|
|
370
|
+
},
|
|
371
|
+
openExternal: () => openInNewTab(),
|
|
372
|
+
maximize: () => setMaximizeState(true),
|
|
373
|
+
restore: () => setMaximizeState(false),
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
293
377
|
// Best-effort: if the consumer opted into `allow-same-origin`, keep the path
|
|
294
378
|
// field truthful as the framed doc navigates itself. Cross-origin (the secure
|
|
295
379
|
// default) throws and we keep our own stack.
|
|
@@ -311,9 +395,10 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
311
395
|
const input = (e.currentTarget as HTMLFormElement).elements.namedItem(
|
|
312
396
|
'kai-artifact-path',
|
|
313
397
|
) as HTMLInputElement | null;
|
|
314
|
-
if (local.readonlyPath) {
|
|
315
|
-
// Submit is a no-op while read-only
|
|
316
|
-
|
|
398
|
+
if (local.readonlyPath || local.displayUrl != null) {
|
|
399
|
+
// Submit is a no-op while read-only or showing a friendly displayUrl; keep
|
|
400
|
+
// the field reflecting the shown value (never push the real, possibly data:, url).
|
|
401
|
+
if (input) input.value = local.displayUrl ?? currentUrl();
|
|
317
402
|
return;
|
|
318
403
|
}
|
|
319
404
|
if (input && input.value) navigate(input.value);
|
|
@@ -330,7 +415,7 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
330
415
|
>
|
|
331
416
|
<Show when={showAnyToolbar()}>
|
|
332
417
|
<ArtifactToolbar
|
|
333
|
-
url={currentUrl}
|
|
418
|
+
url={() => local.displayUrl ?? currentUrl()}
|
|
334
419
|
tab={tab}
|
|
335
420
|
canBack={canBack}
|
|
336
421
|
canForward={canForward}
|
|
@@ -352,7 +437,7 @@ export function Artifact(props: ArtifactProps): JSX.Element {
|
|
|
352
437
|
onToggleMaximize={toggleMaximize}
|
|
353
438
|
canOpenInTab={canOpenInTab}
|
|
354
439
|
onOpenInTab={openInNewTab}
|
|
355
|
-
readonlyPath={() => local.readonlyPath}
|
|
440
|
+
readonlyPath={() => local.readonlyPath || local.displayUrl != null}
|
|
356
441
|
/>
|
|
357
442
|
</Show>
|
|
358
443
|
<div class="relative min-h-0 flex-1">
|
|
@@ -420,7 +505,7 @@ function ArtifactToolbar(props: ToolbarProps): JSX.Element {
|
|
|
420
505
|
return (
|
|
421
506
|
<div
|
|
422
507
|
data-artifact-toolbar
|
|
423
|
-
class="flex shrink-0 items-center gap-1.5 border-b border-border bg-
|
|
508
|
+
class="flex shrink-0 items-center gap-1.5 border-b border-border bg-surface px-2 py-1.5"
|
|
424
509
|
>
|
|
425
510
|
<Show when={props.showNav()}>
|
|
426
511
|
<Button
|
|
@@ -595,7 +680,7 @@ interface CodeProps {
|
|
|
595
680
|
function ArtifactCode(props: CodeProps): JSX.Element {
|
|
596
681
|
return (
|
|
597
682
|
<div class="absolute inset-0 flex">
|
|
598
|
-
<div class="w-56 shrink-0 overflow-auto border-r border-border bg-
|
|
683
|
+
<div class="w-56 shrink-0 overflow-auto border-r border-border bg-surface-sunken py-1.5 scrollbar-thin">
|
|
599
684
|
<FileTree
|
|
600
685
|
files={props.files}
|
|
601
686
|
activeFile={props.activeFile()}
|
|
@@ -728,7 +813,7 @@ function ArtifactPdfPreview(props: { url: string; reloadKey: number }): JSX.Elem
|
|
|
728
813
|
aria-label="PDF preview"
|
|
729
814
|
aria-busy={state() === 'loading'}
|
|
730
815
|
tabindex="0"
|
|
731
|
-
class="absolute inset-0 flex flex-col items-center gap-3 overflow-auto bg-
|
|
816
|
+
class="absolute inset-0 flex flex-col items-center gap-3 overflow-auto bg-surface-sunken p-3 scrollbar-thin focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset"
|
|
732
817
|
/>
|
|
733
818
|
<Show when={isPdfPreviewEnabled() && state() === 'loading'}>
|
|
734
819
|
<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** A message attachment descriptor. Pure type — kept JSX-free for the
|
|
2
|
+
* framework-neutral consumers (state core, React hook typecheck). */
|
|
3
|
+
export interface AttachmentData {
|
|
4
|
+
id: string;
|
|
5
|
+
type: 'file' | 'source-document';
|
|
6
|
+
filename?: string;
|
|
7
|
+
mediaType?: string;
|
|
8
|
+
url?: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type AttachmentMediaCategory = 'image' | 'video' | 'audio' | 'document' | 'source' | 'unknown';
|
|
13
|
+
export type AttachmentVariant = 'grid' | 'inline' | 'list';
|
|
@@ -11,23 +11,13 @@ import {
|
|
|
11
11
|
Video,
|
|
12
12
|
X,
|
|
13
13
|
} from 'lucide-solid';
|
|
14
|
+
import type { AttachmentData, AttachmentMediaCategory, AttachmentVariant } from './attachment-types';
|
|
15
|
+
export type { AttachmentData, AttachmentMediaCategory, AttachmentVariant } from './attachment-types';
|
|
14
16
|
|
|
15
17
|
// ============================================================================
|
|
16
18
|
// Types
|
|
17
19
|
// ============================================================================
|
|
18
20
|
|
|
19
|
-
export interface AttachmentData {
|
|
20
|
-
id: string;
|
|
21
|
-
type: 'file' | 'source-document';
|
|
22
|
-
filename?: string;
|
|
23
|
-
mediaType?: string;
|
|
24
|
-
url?: string;
|
|
25
|
-
title?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type AttachmentMediaCategory = 'image' | 'video' | 'audio' | 'document' | 'source' | 'unknown';
|
|
29
|
-
export type AttachmentVariant = 'grid' | 'inline' | 'list';
|
|
30
|
-
|
|
31
21
|
const mediaCategoryIcons: Record<AttachmentMediaCategory, typeof ImageIcon> = {
|
|
32
22
|
audio: Music2,
|
|
33
23
|
document: FileText,
|
|
@@ -159,12 +149,12 @@ function Attachment(props: AttachmentProps) {
|
|
|
159
149
|
ctx.variant === 'grid' && 'size-24 overflow-hidden rounded-lg',
|
|
160
150
|
ctx.variant === 'inline' && [
|
|
161
151
|
'flex h-8 cursor-pointer select-none items-center gap-1.5',
|
|
162
|
-
'rounded-md bg-
|
|
152
|
+
'rounded-md bg-surface-strong px-1.5 text-foreground',
|
|
163
153
|
'font-medium text-sm transition-all',
|
|
164
154
|
'hover:bg-muted',
|
|
165
155
|
],
|
|
166
156
|
ctx.variant === 'list' && [
|
|
167
|
-
'flex w-full items-center gap-3 rounded-lg bg-
|
|
157
|
+
'flex w-full items-center gap-3 rounded-lg bg-surface p-3 text-foreground',
|
|
168
158
|
'hover:bg-muted/50',
|
|
169
159
|
],
|
|
170
160
|
local.class,
|