@kitn.ai/ui 0.25.2 → 0.27.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/README.md +17 -6
- package/bin/mcp.js +16 -3
- package/bin/route.js +23 -0
- package/bin/route.test.js +58 -0
- package/dist/{elements/chunks/Icon-b5A8hlHs.js → Icon-BnFKqqtY.js} +1 -1
- package/dist/action-icons-CBskfBMz.js +1 -0
- package/dist/arrow-down-Br0qtpsz.js +1 -0
- package/dist/arrow-left-Dj7xgE12.js +1 -0
- package/dist/artifact-CvXEm1lS.js +1 -0
- package/dist/assets/dev-5XzXYR21.js +91 -0
- package/dist/attachments-C43ZegEq.js +1 -0
- package/dist/audio-visualizer-B-79y1Tj.js +1 -0
- package/dist/badge-BpUbq8c0.js +1 -0
- package/dist/bash-InADTalH.js +1 -6
- package/dist/bell-sn17Ip9v.js +1 -0
- package/dist/{elements/chunks/button-B9okqG73.js → button-BH6rN0U-.js} +1 -1
- package/dist/card-renderer-Cb1gQmth.js +1 -0
- package/dist/card-routing-DifQgS7n.js +1 -0
- package/dist/check-DPeeMUYx.js +1 -0
- package/dist/checkbox-Dc9Yov_B.js +1 -0
- package/dist/checkbox-group-B1kDLLYk.js +1 -0
- package/dist/chevron-down-CHSWk7ZT.js +1 -0
- package/dist/chevron-right-B7l_fMgx.js +1 -0
- package/dist/choice-card-BT3c1S8g.js +1 -0
- package/dist/circle-Bb0yOpqM.js +1 -0
- package/dist/circle-check-BGZpCiz7.js +1 -0
- package/dist/circle-x-wobWkoSx.js +1 -0
- package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
- package/dist/code-block-CUQ5mtv0.js +1 -0
- package/dist/collapsible-CPJbf6FM.js +1 -0
- package/dist/components/attachment-types.d.ts +53 -1
- package/dist/components/attachments.d.ts +31 -0
- package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
- package/dist/components/audio-visualizer/index.d.ts +15 -1
- package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
- package/dist/components/card-renderer.d.ts +13 -0
- package/dist/components/card.d.ts +4 -0
- package/dist/components/chat-thread.d.ts +49 -42
- package/dist/components/code-block.d.ts +22 -0
- package/dist/components/conversation-item.d.ts +66 -1
- package/dist/components/conversation-list.d.ts +77 -0
- package/dist/components/form-widgets.d.ts +67 -2
- package/dist/components/form.d.ts +89 -0
- package/dist/components/message.d.ts +29 -0
- package/dist/components/reasoning.d.ts +6 -0
- package/dist/components/scroll-button.d.ts +11 -0
- package/dist/components/thread.d.ts +5 -0
- package/dist/components/toast.d.ts +2 -1
- package/dist/components/tool-types.d.ts +9 -0
- package/dist/components/voice-input.d.ts +8 -0
- package/dist/components/voice-output.d.ts +12 -1
- package/dist/components/workspace-shell.d.ts +87 -0
- package/dist/composer-CjngLzal.js +106 -0
- package/dist/confirm-card-DCx_A4bU.js +1 -0
- package/dist/construct-cli.es.js +1169 -0
- package/dist/context-BY8V-Nlp.js +1 -0
- package/dist/controllable-D43BKmtX.js +1 -0
- package/dist/conversation-list-D4lLU_yS.js +1 -0
- package/dist/copy-B6DO4PqB.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -5874
- package/dist/{create-tween-CUzOlaMS.js → create-tween-BPzaefTp.js} +1 -1
- package/dist/{create-tween-B5Y4Im8G.js → create-tween-CnMHviKB.js} +1 -1
- package/dist/{create-tween-4z1XYLkR.js → create-tween-D1aiGZZh.js} +1 -1
- package/dist/{elements/chunks/create-tween-CUrM6D_o.js → create-tween-DUSQUKpr.js} +2 -2
- package/dist/css-M7EaDHN_.js +1 -6
- package/dist/custom-elements.json +3468 -1927
- package/dist/default-input-CucQEOqH.js +1 -0
- package/dist/define-CGGX-7Vg.js +1 -0
- package/dist/define.d.ts +4 -0
- package/dist/define.js +510 -0
- package/dist/define.server.d.ts +5 -0
- package/dist/define.server.js +506 -0
- package/dist/diagnostics/hook.d.ts +81 -0
- package/dist/diagnostics/index.d.ts +7 -0
- package/dist/diagnostics/report-request.d.ts +61 -0
- package/dist/diagnostics.d.ts +5 -0
- package/dist/diagnostics.js +209 -0
- package/dist/disclosure-CbLtajUQ.js +1 -0
- package/dist/dropdown-BwhViJFd.js +1 -0
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- 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-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.d.ts +1 -0
- package/dist/elements/checkbox-group.js +1 -0
- package/dist/elements/checkbox.d.ts +1 -0
- package/dist/elements/checkbox.js +1 -0
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.d.ts +1 -0
- package/dist/elements/conversation-item.js +1 -0
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/default-input.d.ts +3 -3
- package/dist/elements/define-entry.d.ts +12 -0
- package/dist/elements/define.d.ts +27 -0
- package/dist/elements/diagnostic-events.d.ts +74 -0
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.d.ts +1 -0
- package/dist/elements/dock.js +243 -0
- package/dist/elements/dropdown.d.ts +1 -0
- package/dist/elements/dropdown.js +1 -0
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/element-data-types.d.ts +37 -0
- package/dist/elements/element-diagnostics.d.ts +81 -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.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- 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.js +1 -1
- 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.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.d.ts +1 -0
- package/dist/elements/pane-grid.js +1 -0
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.d.ts +1 -0
- package/dist/elements/radio-group.js +1 -0
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/register.d.ts +2 -0
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +3 -3
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.d.ts +1 -0
- package/dist/elements/select.js +1 -0
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.d.ts +1 -0
- package/dist/elements/slider.js +1 -0
- package/dist/elements/slots.d.ts +36 -4
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- 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/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +589 -167
- package/dist/{elements/chunks/ellipsis-CVxqfsDZ.js → ellipsis-DFr4Vqr3.js} +1 -1
- package/dist/embed-5s_vU4J0.js +1 -0
- package/dist/engine-javascript-vq0WuIJl.js +14 -2516
- package/dist/{elements/chunks/external-link-DG2sRdQL.js → external-link-u9d85ORQ.js} +1 -1
- package/dist/file-text-CX7_x42o.js +1 -0
- package/dist/{elements/chunks/file-tree-yGWNK0Js.js → file-tree-D3kBjXI5.js} +1 -1
- package/dist/folder-V-YdIL8f.js +1 -0
- package/dist/form-BRNUMCN2.js +1 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -4
- package/dist/github-light-JYsPkUQd.js +1 -4
- package/dist/hover-card-DaeiYrTA.js +1 -0
- package/dist/html-CPZ3oZQ7.js +1 -10
- package/dist/icon-BpixdZNq.js +1 -0
- package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +8473 -6470
- package/dist/index.server.js +6495 -4958
- package/dist/info-8mFsIjS3.js +1 -0
- package/dist/input-d1Yuu-hz.js +1 -0
- package/dist/javascript-C25yR2R2.js +1 -6
- package/dist/json-DxJze_jm.js +1 -6
- package/dist/kai-provider.es.js +40 -40
- package/dist/kai.es.js +1 -1
- package/dist/kbd-961zMPFB.js +1 -0
- package/dist/link-DlZZBGaR.js +1 -0
- package/dist/{elements/chunks/link-preview-Cf5KOP-i.js → link-preview-DIIbV2Sd.js} +1 -1
- package/dist/loader-YQszHFaW.js +1 -0
- package/dist/{elements/chunks/markdown-DbozyYqa.js → markdown-CVk1MPsj.js} +1 -1
- package/dist/mcp.es.js +3873 -544
- package/dist/message-CwKVEdZg.js +1 -0
- package/dist/message-DS8lzHc1.js +1 -0
- package/dist/message-circle-Xf8Q-vZp.js +1 -0
- package/dist/message-square-Cxnwgkns.js +1 -0
- package/dist/{elements/chunks/minimize-2-SegJ_oku.js → minimize-2-UEZmP2QT.js} +1 -1
- package/dist/{elements/chunks/model-switcher-D7JrFFHp.js → model-switcher-Kk1jEQ5t.js} +1 -1
- package/dist/{elements/chunks/overlay-CV7z2YuX.js → overlay-C1od6LOz.js} +1 -1
- package/dist/panel-right-ryET0yyn.js +1 -0
- package/dist/paperclip-BDNoZFJP.js +1 -0
- package/dist/play-OFIvYXUQ.js +1 -0
- package/dist/primitives/card-data-types.d.ts +49 -0
- package/dist/primitives/card-routing.d.ts +1 -33
- package/dist/primitives/card-validate.d.ts +2 -2
- package/dist/primitives/chat-config.d.ts +29 -2
- package/dist/primitives/field-mask.d.ts +96 -0
- package/dist/primitives/field-semantics.d.ts +36 -0
- package/dist/primitives/input-mask.d.ts +46 -0
- package/dist/primitives/url-scheme-policy.d.ts +34 -0
- package/dist/primitives/use-resize-observer.d.ts +23 -0
- package/dist/primitives/use-speech-recognition.d.ts +8 -0
- package/dist/primitives/use-text-stream.d.ts +5 -0
- package/dist/progress-bar-BvYX0aoy.js +1 -0
- package/dist/prompt-suggestion-BRFu2lcu.js +1 -0
- package/dist/radio-DcL23cNJ.js +1 -0
- package/dist/react/index.d.ts +306 -283
- package/dist/react.js +309 -247
- package/dist/reasoning-Cackq4Rh.js +1 -0
- package/dist/register-impl-C7rENvPK.js +424 -0
- package/dist/{elements/chunks/resizable-Dpzjlvp4.js → resizable-Cp9HUYih.js} +1 -1
- package/dist/rotate-ccw-0DLRDHH5.js +1 -0
- package/dist/rotate-cw-DOB9IGcU.js +1 -0
- package/dist/schemas/form.schema.json +21 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/tool-defs.d.ts +45 -0
- package/dist/schemas.js +398 -305
- package/dist/scroll-area-emVmWP4K.js +1 -0
- package/dist/scroll-button-CeP_gv1x.js +1 -0
- package/dist/select-CWmu00tS.js +1 -0
- package/dist/{elements/chunks/separator-DH2r_ZSZ.js → separator-CE6vly6z.js} +1 -1
- package/dist/{elements/chunks/settings-BFMOd6yB.js → settings-CE-78SvZ.js} +1 -1
- package/dist/{elements/chunks/settings-group-B3VZKIcz.js → settings-group-ZFWNxFQR.js} +1 -1
- package/dist/{elements/chunks/skeleton-N8BuWYmf.js → skeleton-BebdP4mf.js} +1 -1
- package/dist/slider-BAKRYUlz.js +1 -0
- package/dist/slots-DaNjX0rc.js +1 -0
- package/dist/{solid-BMuDmFo_.js → solid-BE5ui6sy.js} +10672 -8116
- package/dist/{solid-CGYNdLRR.js → solid-DFhsce3O.js} +8137 -6056
- package/dist/solid.d.ts +15 -0
- package/dist/solid.js +248 -235
- package/dist/solid.server.js +248 -235
- package/dist/source-B0FlguSx.js +1 -0
- package/dist/star-CBMZvLuN.js +1 -0
- package/dist/state/index.d.ts +5 -1
- package/dist/state/mock.d.ts +32 -2
- package/dist/state/persistence.d.ts +51 -0
- package/dist/state/stream.d.ts +50 -0
- package/dist/state/threads.d.ts +71 -0
- package/dist/state.js +297 -172
- package/dist/store-7eoadydQ.js +1 -0
- package/dist/svelte--5p79yCD.js +1 -15
- package/dist/switch-CViARZCy.js +1 -0
- package/dist/tasks-card-MjCcOhR_.js +1 -0
- package/dist/text-shimmer-DKlwRF2G.js +1 -0
- package/dist/textarea-3ay2Me2-.js +1 -0
- package/dist/theme.tokens.css +82 -13
- package/dist/{elements/chunks/thumbs-up-DQe0hvkZ.js → thumbs-up-DQcu2HMO.js} +1 -1
- package/dist/toast-store-C6yKOhbk.js +1 -0
- package/dist/{elements/chunks/tool-C1YtxwPu.js → tool-BCYNlfKy.js} +1 -1
- package/dist/{elements/chunks/tooltip-BqwnFWhn.js → tooltip-05zI4hjs.js} +1 -1
- package/dist/trash-2-BR1RxGky.js +1 -0
- package/dist/{elements/chunks/triangle-alert-B6or7F5u.js → triangle-alert-DHohDOCy.js} +1 -1
- package/dist/tsx-B8rCNbgL.js +1 -6
- package/dist/types.d.ts +4 -2
- package/dist/typescript-RycA9KXf.js +1 -6
- package/dist/ui/checkbox-group.d.ts +83 -0
- package/dist/ui/checkbox.d.ts +40 -0
- package/dist/ui/dock.d.ts +131 -0
- package/dist/ui/hover-card.d.ts +44 -0
- package/dist/ui/icon.d.ts +3 -0
- package/dist/ui/input.d.ts +48 -2
- package/dist/ui/radio.d.ts +85 -0
- package/dist/ui/select.d.ts +71 -0
- package/dist/ui/slider.d.ts +65 -0
- package/dist/ui/switch.d.ts +9 -2
- package/dist/upload-BbGW6A_u.js +1 -0
- package/dist/url-scheme-policy-DHpoTJwB.js +1 -0
- package/dist/use-card-resolution-CJW4grFa.js +1 -0
- package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-BUOVgPOB.js} +27 -27
- package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CUsUJvFI.js} +28 -28
- package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CW2i4bfr.js} +2 -2
- package/dist/{elements/chunks/variant-aurora-QXTZPyST.js → variant-aurora-xiMPty8f.js} +2 -2
- package/dist/variant-custom-BQtOnmeO.js +1 -0
- package/dist/{variant-custom-BhS9wIpU.js → variant-custom-CAm9L-E5.js} +65 -65
- package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-CAnzzppW.js} +40 -40
- package/dist/variant-custom-D91HjAKz.js +1 -0
- package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-Ca1Ls4_y.js} +21 -21
- package/dist/{variant-wave-CbVsmgwT.js → variant-wave-CxX39DKd.js} +25 -25
- package/dist/{variant-wave-BwzrHD1s.js → variant-wave-DYyzIIZv.js} +2 -2
- package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-uY5crU_K.js} +2 -2
- package/dist/vue-BmIZj4XD.js +1 -33
- package/dist/wire/chunk.d.ts +47 -0
- package/dist/wire/diagnostics.d.ts +575 -0
- package/dist/wire/encode-probe.d.ts +70 -0
- package/dist/wire/encode.d.ts +24 -0
- package/dist/wire/index.d.ts +2 -0
- package/dist/wire/sse.d.ts +10 -2
- package/dist/wire.js +917 -480
- package/dist/x-C5m1JFgi.js +1 -0
- package/frameworks/react/index.tsx +325 -108
- package/llms-full.txt +1354 -82
- package/llms.txt +6 -3
- package/package.json +39 -6
- package/src/agent-tooling/archetypes.ts +41 -9
- package/src/agent-tooling/catalog/README.md +676 -0
- package/src/agent-tooling/catalog/catalog-types.ts +231 -0
- package/src/agent-tooling/catalog/fabrications.ts +96 -0
- package/src/agent-tooling/catalog/invariants.ts +284 -0
- package/src/agent-tooling/catalog/labs-titles.ts +114 -0
- package/src/agent-tooling/catalog/scenarios.ts +87 -0
- package/src/agent-tooling/catalog/surfaces.ts +347 -0
- package/src/agent-tooling/construct/cli-entry.ts +8 -0
- package/src/agent-tooling/construct/cli.ts +131 -0
- package/src/agent-tooling/construct/codegen.ts +1353 -0
- package/src/agent-tooling/construct/construct.v1.schema.json +250 -0
- package/src/agent-tooling/construct/dev.ts +148 -0
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +23 -0
- package/src/agent-tooling/construct/schema.ts +371 -0
- package/src/agent-tooling/integrations/anthropic.ts +7 -1
- package/src/agent-tooling/integrations/cloudflare.ts +43 -2
- package/src/agent-tooling/integrations/langgraph.ts +7 -1
- package/src/agent-tooling/integrations/mastra.ts +7 -1
- package/src/agent-tooling/integrations/mock.ts +92 -17
- package/src/agent-tooling/integrations/ollama.ts +7 -1
- package/src/agent-tooling/integrations/openai.ts +7 -1
- package/src/agent-tooling/integrations/openrouter.ts +7 -1
- package/src/agent-tooling/integrations/pi.ts +56 -1
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
- package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
- package/src/agent-tooling/mcp/manifest.ts +100 -1
- package/src/agent-tooling/mcp/server.ts +63 -6
- package/src/agent-tooling/mcp/tools/construct.ts +130 -0
- package/src/agent-tooling/mcp/tools/debug.ts +126 -4
- package/src/agent-tooling/mcp/tools/reference.ts +542 -5
- package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
- package/src/agent-tooling/mcp/tools/theme.ts +146 -30
- package/src/agent-tooling/mcp/validate-args.ts +141 -0
- package/src/agent-tooling/recipes/composed-thread.ts +714 -0
- package/src/agent-tooling/recipes/index.ts +22 -0
- package/src/agent-tooling/recipes/types.ts +32 -0
- package/src/agent-tooling/registry.ts +24 -7
- package/src/agent-tooling/route-emit.ts +26 -2
- package/src/components/attachment-types.ts +54 -1
- package/src/components/attachments.tsx +169 -22
- package/src/components/audio-visualizer/fit-scale.ts +112 -0
- package/src/components/audio-visualizer/index.tsx +80 -3
- package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
- package/src/components/audio-visualizer/variant-bar.tsx +38 -6
- package/src/components/audio-visualizer/variant-custom.tsx +8 -2
- package/src/components/audio-visualizer/variant-grid.tsx +16 -11
- package/src/components/audio-visualizer/variant-radial.tsx +15 -10
- package/src/components/audio-visualizer/variant-wave.tsx +7 -2
- package/src/components/card-renderer.tsx +39 -8
- package/src/components/card.tsx +10 -2
- package/src/components/chat-container.tsx +4 -1
- package/src/components/chat-scope-picker.tsx +2 -2
- package/src/components/chat-thread.tsx +105 -13
- package/src/components/choice-card.tsx +102 -37
- package/src/components/coachmark.tsx +1 -1
- package/src/components/code-block.tsx +81 -5
- package/src/components/composer.tsx +89 -8
- package/src/components/confirm-card.tsx +20 -4
- package/src/components/conversation-item.tsx +138 -4
- package/src/components/conversation-list.tsx +230 -15
- package/src/components/embed.tsx +4 -0
- package/src/components/empty.tsx +14 -3
- package/src/components/file-tree.tsx +5 -1
- package/src/components/form-widgets.tsx +257 -195
- package/src/components/form.tsx +336 -21
- package/src/components/loader.tsx +12 -5
- package/src/components/message-skills.tsx +1 -1
- package/src/components/message.tsx +142 -12
- package/src/components/prompt-input.tsx +7 -1
- package/src/components/prompt-suggestion.tsx +4 -1
- package/src/components/reasoning.tsx +30 -3
- package/src/components/response-compare.tsx +2 -2
- package/src/components/response-stream.tsx +13 -7
- package/src/components/screen.tsx +5 -0
- package/src/components/scroll-button.tsx +63 -4
- package/src/components/source.tsx +6 -1
- package/src/components/tasks-card.tsx +58 -16
- package/src/components/thread.tsx +10 -1
- package/src/components/toast.tsx +11 -5
- package/src/components/tool-types.ts +9 -0
- package/src/components/voice-input.tsx +35 -3
- package/src/components/voice-output.tsx +46 -6
- package/src/components/workspace-shell.tsx +285 -0
- package/src/diagnostics/hook.ts +352 -0
- package/src/diagnostics/index.ts +82 -0
- package/src/diagnostics/report-request.ts +296 -0
- package/src/elements/attachments.tsx +9 -8
- package/src/elements/audio-visualizer.tsx +48 -4
- package/src/elements/chat-workspace.tsx +159 -287
- package/src/elements/chat.tsx +31 -10
- package/src/elements/checkbox-group.tsx +164 -0
- package/src/elements/checkbox.tsx +134 -0
- package/src/elements/code-block.tsx +19 -1
- package/src/elements/command.tsx +4 -1
- package/src/elements/compiled.css +1 -1
- package/src/elements/composer.tsx +12 -1
- package/src/elements/conversation-item.tsx +120 -0
- package/src/elements/conversation-list.tsx +60 -11
- package/src/elements/default-input.tsx +5 -5
- package/src/elements/define-entry.ts +12 -0
- package/src/elements/define.tsx +168 -8
- package/src/elements/diagnostic-events.ts +114 -0
- package/src/elements/dialog.tsx +47 -0
- package/src/elements/disclosure.ts +34 -12
- package/src/elements/dock.tsx +215 -0
- package/src/elements/dropdown.tsx +123 -0
- package/src/elements/element-data-types.ts +40 -0
- package/src/elements/element-diagnostics.ts +392 -0
- package/src/elements/element-manifest.json +36 -0
- package/src/elements/element-meta.json +1483 -560
- package/src/elements/element-nonscalar.json +185 -0
- package/src/elements/element-types.d.ts +589 -167
- package/src/elements/feedback-bar.tsx +5 -0
- package/src/elements/icon-names.json +29 -0
- package/src/elements/input.tsx +312 -23
- package/src/elements/menu.tsx +13 -0
- package/src/elements/message.tsx +2 -0
- package/src/elements/pane-grid.tsx +111 -0
- package/src/elements/prompt-dock.tsx +2 -1
- package/src/elements/prompt-input.tsx +16 -10
- package/src/elements/radio-group.tsx +129 -0
- package/src/elements/register-impl.ts +52 -0
- package/src/elements/register.ts +28 -0
- package/src/elements/resizable.tsx +52 -25
- package/src/elements/scroll-button.tsx +59 -6
- package/src/elements/select.tsx +165 -0
- package/src/elements/slider.tsx +171 -0
- package/src/elements/slots.ts +108 -13
- package/src/elements/styles.css +119 -9
- package/src/elements/thinking-bar.tsx +16 -7
- package/src/elements/thread.tsx +2 -0
- package/src/elements/toast.tsx +17 -1
- package/src/elements/tool.tsx +26 -5
- package/src/elements/voice-input.tsx +11 -2
- package/src/elements/voice-output.tsx +16 -3
- package/src/index.ts +4 -1
- package/src/primitives/card-data-types.ts +49 -0
- package/src/primitives/card-host.tsx +4 -2
- package/src/primitives/card-routing.ts +7 -56
- package/src/primitives/card-schemas/form.schema.json +21 -1
- package/src/primitives/card-validate.ts +10 -2
- package/src/primitives/chat-config.tsx +33 -6
- package/src/primitives/field-mask.ts +256 -0
- package/src/primitives/field-semantics.ts +115 -0
- package/src/primitives/input-mask.ts +853 -0
- package/src/primitives/toast-store.ts +66 -4
- package/src/primitives/url-scheme-policy.ts +70 -0
- package/src/primitives/use-resize-observer.ts +33 -0
- package/src/primitives/use-speech-recognition.ts +12 -1
- package/src/primitives/use-stick-to-bottom.ts +34 -2
- package/src/primitives/use-text-stream.ts +33 -2
- package/src/remote/provider-runtime.ts +6 -3
- package/src/schemas/index.ts +1 -0
- package/src/schemas/tool-defs.ts +307 -6
- package/src/solid.ts +15 -0
- package/src/state/index.ts +13 -1
- package/src/state/mock.ts +92 -6
- package/src/state/persistence.ts +180 -0
- package/src/state/stream.ts +71 -4
- package/src/state/threads.ts +142 -0
- package/src/types.ts +4 -2
- package/src/ui/agent-card.tsx +2 -2
- package/src/ui/avatar.tsx +1 -1
- package/src/ui/checkbox-group.tsx +153 -0
- package/src/ui/checkbox.tsx +63 -0
- package/src/ui/dialog.tsx +6 -0
- package/src/ui/dock.tsx +584 -0
- package/src/ui/dropdown.tsx +67 -23
- package/src/ui/hover-card.tsx +156 -6
- package/src/ui/icon.tsx +53 -0
- package/src/ui/input.tsx +275 -16
- package/src/ui/kbd.tsx +1 -1
- package/src/ui/nav.tsx +1 -1
- package/src/ui/pane-group.tsx +2 -2
- package/src/ui/radio.tsx +150 -0
- package/src/ui/resizable.tsx +11 -0
- package/src/ui/select.tsx +168 -0
- package/src/ui/slider.tsx +178 -0
- package/src/ui/switch.tsx +49 -18
- package/src/utils/cn.ts +11 -5
- package/src/wire/chunk.ts +47 -0
- package/src/wire/consume.ts +185 -26
- package/src/wire/diagnostics.ts +727 -0
- package/src/wire/encode-probe.ts +214 -0
- package/src/wire/encode.ts +267 -14
- package/src/wire/formats/anthropic.ts +8 -1
- package/src/wire/formats/openai.ts +5 -0
- package/src/wire/index.ts +22 -0
- package/src/wire/read.ts +250 -6
- package/src/wire/sse.ts +16 -3
- package/theme.css +84 -13
- package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
- package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
- package/dist/elements/chunks/artifact-BSuPYFHY.js +0 -1
- package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
- package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
- package/dist/elements/chunks/badge-TIMiJFKc.js +0 -1
- package/dist/elements/chunks/bash-InADTalH.js +0 -1
- package/dist/elements/chunks/card-renderer-CSoTL_e1.js +0 -1
- package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
- package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
- package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
- package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
- package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
- package/dist/elements/chunks/choice-card-CGMc3kek.js +0 -1
- package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
- package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
- package/dist/elements/chunks/circle-x-mhH7pOK2.js +0 -1
- package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
- package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
- package/dist/elements/chunks/composer-CZZmtYOT.js +0 -69
- package/dist/elements/chunks/confirm-card-BWjf2-xo.js +0 -1
- package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
- package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
- package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
- package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
- package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
- package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
- package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
- package/dist/elements/chunks/download-DnCyWFJE.js +0 -1
- package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
- package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
- package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
- package/dist/elements/chunks/file-text-D0J9F6M7.js +0 -1
- package/dist/elements/chunks/folder-NV1pi_ud.js +0 -1
- package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
- package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
- package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
- package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
- package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
- package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
- package/dist/elements/chunks/info-C8r5Q6cc.js +0 -1
- package/dist/elements/chunks/input-DrseEjhp.js +0 -1
- package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
- package/dist/elements/chunks/json-DxJze_jm.js +0 -1
- package/dist/elements/chunks/kbd-OGJDUT-O.js +0 -1
- package/dist/elements/chunks/link-BdsfLB7b.js +0 -1
- package/dist/elements/chunks/loader-B5QzK_8_.js +0 -1
- package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
- package/dist/elements/chunks/message-DtXKPqiR.js +0 -1
- package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
- package/dist/elements/chunks/paperclip-Bg0ITU3b.js +0 -1
- package/dist/elements/chunks/progress-bar-D1_rzt6N.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-D5Sm8xF1.js +0 -1
- package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
- package/dist/elements/chunks/rotate-cw-DzVDJOA1.js +0 -1
- package/dist/elements/chunks/scroll-area-93A1bbeG.js +0 -1
- package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
- package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
- package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
- package/dist/elements/chunks/source-w9V0NnBn.js +0 -1
- package/dist/elements/chunks/star-DHvACxtm.js +0 -1
- package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
- package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
- package/dist/elements/chunks/tasks-card-lPxoodlA.js +0 -1
- package/dist/elements/chunks/text-shimmer-BY_rI3s5.js +0 -1
- package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
- package/dist/elements/chunks/toast-store-VUZZBhzH.js +0 -1
- package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
- package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
- package/dist/elements/chunks/use-card-resolution-DJg32jGH.js +0 -1
- package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
- package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
- package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
- package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
- package/dist/llms/llms-full.txt +0 -2834
- package/dist/llms/llms.txt +0 -156
- package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
- package/dist/register-impl-DGmGzrEM.js +0 -145
- package/dist/ui/stat.d.ts +0 -16
- package/dist/variant-custom-MkTNTycd.js +0 -1
- package/src/primitives/card-validate-generator.testlib.ts +0 -38
- package/src/ui/stat.tsx +0 -41
- /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
- /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
// element, so it carries its own shadow root + the shared kit stylesheet — it's
|
|
10
10
|
// viewport-positioned AND fully kit-styled, never a raw div.
|
|
11
11
|
//
|
|
12
|
+
// ADOPTS, else creates: `ensureMounted` first
|
|
13
|
+
// looks for a connected `<kai-toast-region>` already in the document and binds
|
|
14
|
+
// the store to it, so an app that placed its own region and also calls
|
|
15
|
+
// `toast()` gets ONE region, not two overlapping ones. It creates a region only
|
|
16
|
+
// when none exists. With two or more candidate regions the choice is genuinely
|
|
17
|
+
// ambiguous — the first in document order wins, and a one-time console.warn
|
|
18
|
+
// says so (decide loudly).
|
|
19
|
+
//
|
|
12
20
|
// SSR-safe: every DOM touch is guarded by `typeof document`. On the server,
|
|
13
21
|
// raising a toast is an inert no-op (the store updates, nothing mounts).
|
|
14
22
|
|
|
@@ -156,21 +164,75 @@ function resolveDuration(item: Pick<ToastItem, 'duration' | 'action'>): number {
|
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
/**
|
|
159
|
-
* Lazily
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
167
|
+
* Lazily resolve the single `<kai-toast-region>` host for a target and bind the
|
|
168
|
+
* store to its `toasts` property. Idempotent + SSR-safe. The element upgrade
|
|
169
|
+
* (its `defineWebComponent` registration) happens when the elements bundle
|
|
170
|
+
* loads; setting the property before/after upgrade both work because
|
|
163
171
|
* `customElement` reflects late-set properties.
|
|
172
|
+
*
|
|
173
|
+
* ADOPT-IF-PRESENT: a connected
|
|
174
|
+
* `<kai-toast-region>` already in the document (same `target`, not already
|
|
175
|
+
* claimed for another target) is adopted — the store binds to IT, and no
|
|
176
|
+
* second region mounts. Adoption respects the region's authored attributes
|
|
177
|
+
* (position/stack/…): config from `configureToasts()` is not stamped onto an
|
|
178
|
+
* adopted region here, though an explicit `configureToasts()` call still
|
|
179
|
+
* updates every region, adopted included. Binding the store REPLACES a
|
|
180
|
+
* `toasts` array the app set as data — after the first `toast()` call the
|
|
181
|
+
* imperative store owns the adopted region's list. Only when no candidate
|
|
182
|
+
* exists is a fresh region created on `document.body`. Two or more candidates
|
|
183
|
+
* for the same target are genuinely ambiguous: the first in document order
|
|
184
|
+
* wins, with a one-time console.warn (decide loudly).
|
|
185
|
+
*
|
|
186
|
+
* If an adopted (or created) region later leaves the DOM, the cache entry is
|
|
187
|
+
* dropped and the next call resolves fresh — adopt again if a region exists,
|
|
188
|
+
* else create — so a removed region never becomes a dead cache entry that
|
|
189
|
+
* swallows toasts.
|
|
164
190
|
*/
|
|
165
191
|
// One region per distinct target (the `null` key = the global / viewport region).
|
|
166
192
|
// Every region binds the SAME store proxy and filters to its own target, so a
|
|
167
193
|
// toast routes to the region for its `target`.
|
|
168
194
|
const regions = new Map<HTMLElement | null, HTMLElement>();
|
|
169
195
|
|
|
196
|
+
// Decide-loudly, once: ambiguity between 2+ candidate regions is warned about a
|
|
197
|
+
// single time per page, not on every toast.
|
|
198
|
+
let warnedAmbiguousRegions = false;
|
|
199
|
+
|
|
200
|
+
/** Read a region element's `target` property (undefined pre-upgrade → null =
|
|
201
|
+
* the global region). */
|
|
202
|
+
function regionTarget(el: HTMLElement): HTMLElement | null {
|
|
203
|
+
return (el as unknown as { target?: HTMLElement }).target ?? null;
|
|
204
|
+
}
|
|
205
|
+
|
|
170
206
|
export function ensureMounted(target: HTMLElement | null = null): HTMLElement | undefined {
|
|
171
207
|
if (typeof document === 'undefined') return undefined;
|
|
172
208
|
const cached = regions.get(target);
|
|
173
209
|
if (cached && cached.isConnected) return cached;
|
|
210
|
+
// The region this key resolved to left the DOM — drop the dead entry so it
|
|
211
|
+
// can never swallow toasts, and resolve fresh below.
|
|
212
|
+
if (cached) regions.delete(target);
|
|
213
|
+
|
|
214
|
+
// Adopt a region the app already placed. Regions this store already
|
|
215
|
+
// claimed for OTHER targets are not candidates.
|
|
216
|
+
const claimed = new Set(regions.values());
|
|
217
|
+
const candidates = Array.from(
|
|
218
|
+
document.querySelectorAll<HTMLElement>('kai-toast-region'),
|
|
219
|
+
).filter((el) => el.isConnected && !claimed.has(el) && regionTarget(el) === target);
|
|
220
|
+
if (candidates.length > 1 && !warnedAmbiguousRegions) {
|
|
221
|
+
warnedAmbiguousRegions = true;
|
|
222
|
+
console.warn(
|
|
223
|
+
`[kitn] toast(): ${candidates.length} candidate <kai-toast-region> elements are in the ` +
|
|
224
|
+
'document; adopting the first in document order. Keep one region per target so the ' +
|
|
225
|
+
'imperative toast() API has an unambiguous home.',
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const adopted = candidates[0];
|
|
229
|
+
if (adopted) {
|
|
230
|
+
(adopted as unknown as { toasts: ToastItem[] }).toasts = toasts as ToastItem[];
|
|
231
|
+
regions.set(target, adopted);
|
|
232
|
+
setMounted(true);
|
|
233
|
+
return adopted;
|
|
234
|
+
}
|
|
235
|
+
|
|
174
236
|
const el = document.createElement('kai-toast-region') as HTMLElement;
|
|
175
237
|
// Append FIRST so the element upgrades, THEN bind. Setting a property before
|
|
176
238
|
// upgrade loses it: component-register resets every prop in the constructor on
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/primitives/url-scheme-policy.ts
|
|
2
|
+
// The kit's one URL-scheme allow/deny policy, split out of card-routing.ts so it
|
|
3
|
+
// has NO DOM dependency (`URL` is a global in both the browser and Node — the
|
|
4
|
+
// rest of card-routing.ts uses HTMLElement/window/CustomEvent, which aren't).
|
|
5
|
+
// That split matters beyond tidiness: this schema.ts (agent-tooling/construct)
|
|
6
|
+
// runs under tsconfig.mcp.json's Node-only, no-DOM-lib pass (it's imported
|
|
7
|
+
// transitively via mcp/tools/construct.ts), and importing anything from
|
|
8
|
+
// card-routing.ts there drags its HTMLElement/window/Document/CustomEvent
|
|
9
|
+
// references into that compile and breaks it — even though only isSafeUrl is
|
|
10
|
+
// used. card-routing.ts re-exports everything here so its own public surface
|
|
11
|
+
// (isSafeUrl/isScriptUrl, used by markdown.tsx/artifact.tsx/source.tsx) is
|
|
12
|
+
// unchanged; this is a location split, not a second policy.
|
|
13
|
+
|
|
14
|
+
const SAFE_SCHEMES = ['http:', 'https:', 'mailto:'];
|
|
15
|
+
const SCRIPT_SCHEMES = ['javascript:', 'vbscript:'];
|
|
16
|
+
|
|
17
|
+
/** The scheme the WHATWG parser reads out of `url`, resolved against a base so a
|
|
18
|
+
* relative input inherits `http:`. `undefined` when it will not parse at all.
|
|
19
|
+
*
|
|
20
|
+
* ONE parser for the two questions below, deliberately: the parsing is where
|
|
21
|
+
* the subtlety lives (it strips embedded tabs/newlines and trims surrounding
|
|
22
|
+
* whitespace before reading the scheme, so `java\nscript:` and
|
|
23
|
+
* ` javascript:... ` are both read as `javascript:` -- which a regex over the
|
|
24
|
+
* raw string would miss). Two predicates over one parse cannot drift on that;
|
|
25
|
+
* two hand-rolled parsers would. */
|
|
26
|
+
function schemeOf(url: string): string | undefined {
|
|
27
|
+
try { return new URL(url, 'http://_invalid_base').protocol; } catch { return undefined; }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** True when `url` is safe to put in an href / hand to `window.open` / an `<img src>`.
|
|
31
|
+
*
|
|
32
|
+
* Exported so the MARKDOWN renderer, the ARTIFACT viewer and the construct
|
|
33
|
+
* format's `widget.launcherIcon` reuse this exact guard rather than growing a
|
|
34
|
+
* second scheme list that can drift from this one.
|
|
35
|
+
*
|
|
36
|
+
* Resolving against a base is deliberate and is what makes it correct for
|
|
37
|
+
* markdown: a relative or fragment link (`/docs`, `#section`, `./rel`) is
|
|
38
|
+
* ordinary markdown, and resolving it inherits the base's `http:` so it
|
|
39
|
+
* passes, while `javascript:`/`data:`/`vbscript:` keep their own protocol and
|
|
40
|
+
* fail. It is correct for the artifact viewer for the same reason: a file with
|
|
41
|
+
* no `src` to resolve against yields a bare relative path (`docs/report.pdf`),
|
|
42
|
+
* which is a legitimate artifact address. Contrast `isRenderableLink` in
|
|
43
|
+
* `primitives/link-preview.ts`, which takes NO base and so demands an absolute
|
|
44
|
+
* http(s) URL: that is the right guard for a model-supplied citation -- a
|
|
45
|
+
* reference to a page on the public web -- this one for markdown body links,
|
|
46
|
+
* artifact file addresses, and a construct's launcher icon. */
|
|
47
|
+
export function isSafeUrl(url: string): boolean {
|
|
48
|
+
const scheme = schemeOf(url);
|
|
49
|
+
return scheme !== undefined && SAFE_SCHEMES.includes(scheme);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** True when navigating to `url` would EXECUTE it as script in the initiating
|
|
53
|
+
* document's origin.
|
|
54
|
+
*
|
|
55
|
+
* Strictly narrower than `!isSafeUrl(url)`, and not a competing policy: it
|
|
56
|
+
* answers a different question, for the one sink where the allowlist is the
|
|
57
|
+
* wrong tool. An `<iframe src>` legitimately takes `data:` and `blob:` (a
|
|
58
|
+
* `data:` blob artifact is a documented `<kai-artifact>` use -- it is what
|
|
59
|
+
* `displayUrl` exists for) and both get an OPAQUE origin in every modern
|
|
60
|
+
* browser, so neither can reach the host page. `javascript:`/`vbscript:` are
|
|
61
|
+
* the schemes that run in the EMBEDDER's origin, and they are the whole risk:
|
|
62
|
+
* the default sandbox (no `allow-same-origin`) already makes the browser refuse
|
|
63
|
+
* them, but a consumer who sets `allow-same-origin` turns a model-supplied
|
|
64
|
+
* `src` into host-origin script execution. The artifact viewer used to suggest
|
|
65
|
+
* that setting for "an artifact you trust"; it no longer does, and this guard
|
|
66
|
+
* is what protects the consumers who took the old advice. */
|
|
67
|
+
export function isScriptUrl(url: string): boolean {
|
|
68
|
+
const scheme = schemeOf(url);
|
|
69
|
+
return scheme !== undefined && SCRIPT_SCHEMES.includes(scheme);
|
|
70
|
+
}
|
|
@@ -10,3 +10,36 @@ export function observeContentHeight(el: Element, onHeight: (height: number) =>
|
|
|
10
10
|
ro.observe(el);
|
|
11
11
|
return () => ro.disconnect();
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
/** Observe an element's resizes but report the FULL rendered document height (not the
|
|
15
|
+
* observed element's own content-box) — `document.body.scrollHeight`.
|
|
16
|
+
*
|
|
17
|
+
* Used by the remote-card provider runtime to size the host iframe:
|
|
18
|
+
* `observeContentHeight` reports the ResizeObserver content-box of
|
|
19
|
+
* the observed root, which drops that root's OWN padding/border and any ancestor
|
|
20
|
+
* (e.g. `<body>`) padding above it — the host then clips the bottom of the card by
|
|
21
|
+
* exactly those lost pixels. `scrollHeight` is the full padding-box height as actually
|
|
22
|
+
* rendered, so it stays correct no matter which element in the ancestor chain carries
|
|
23
|
+
* the padding/border, including if the provider page's own styles change later —
|
|
24
|
+
* reading contentRect off one fixed element, or hand-summing computed padding/border
|
|
25
|
+
* off a fixed list of ancestors, would both need updating every time that chain does.
|
|
26
|
+
*
|
|
27
|
+
* Deliberately `document.body.scrollHeight`, NOT `document.documentElement.scrollHeight`
|
|
28
|
+
* (N1, task-10-report.md "Fix-wave re-review"): the CSSOM View spec special-cases the
|
|
29
|
+
* scrollHeight of the ROOT element to be `max(viewport scrolling area, viewport
|
|
30
|
+
* height)` — and the host sets the iframe's viewport FROM this very measurement
|
|
31
|
+
* (`host-embed.ts` `sizeIframe`), so `documentElement.scrollHeight` can only grow for
|
|
32
|
+
* the life of the frame: once the iframe is tall, the root's own scrollHeight is
|
|
33
|
+
* floored at that height even after the card's content shrinks. `<body>` carries no
|
|
34
|
+
* such floor — its scrollHeight is a plain padding-box measurement of body's own
|
|
35
|
+
* content, so it shrinks along with the card. */
|
|
36
|
+
export function observeDocumentHeight(el: Element, onHeight: (height: number) => void): () => void {
|
|
37
|
+
let last = -1;
|
|
38
|
+
const ro = new ResizeObserver(() => {
|
|
39
|
+
const doc = el.ownerDocument;
|
|
40
|
+
const h = doc?.body?.scrollHeight ?? doc?.documentElement?.scrollHeight ?? el.getBoundingClientRect().height;
|
|
41
|
+
if (last < 0 || Math.abs(h - last) > THRESHOLD) { last = h; onHeight(h); }
|
|
42
|
+
});
|
|
43
|
+
ro.observe(el);
|
|
44
|
+
return () => ro.disconnect();
|
|
45
|
+
}
|
|
@@ -51,6 +51,14 @@ export interface SpeechRecognitionStartOptions {
|
|
|
51
51
|
lang?: string;
|
|
52
52
|
/** Called with each interim (non-final) transcript when `interim` is enabled. */
|
|
53
53
|
onInterim?: (text: string) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Called when the recognition session hits a runtime error (`recognition.onerror`),
|
|
56
|
+
* with the platform's error code (`network`, `not-allowed`, `no-speech`, ...) and a
|
|
57
|
+
* human-readable message. The session still ends through `onend`, so `start()` still
|
|
58
|
+
* resolves (with whatever text was captured before the error). Without this callback
|
|
59
|
+
* a runtime failure is invisible: the `error` signal is state, not a notification.
|
|
60
|
+
*/
|
|
61
|
+
onError?: (error: string, message: string) => void;
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
/**
|
|
@@ -102,7 +110,10 @@ export function useSpeechRecognition(options: UseSpeechRecognitionOptions = {})
|
|
|
102
110
|
};
|
|
103
111
|
|
|
104
112
|
recognition.onerror = (event) => {
|
|
105
|
-
|
|
113
|
+
const code = event.error ?? 'unknown';
|
|
114
|
+
const message = `Speech recognition error: ${code}`;
|
|
115
|
+
setError(message);
|
|
116
|
+
opts.onError?.(code, message);
|
|
106
117
|
};
|
|
107
118
|
|
|
108
119
|
recognition.onend = () => {
|
|
@@ -17,14 +17,42 @@ export function useStickToBottom() {
|
|
|
17
17
|
|
|
18
18
|
function scrollToBottom(behavior: ScrollBehavior = 'smooth') {
|
|
19
19
|
if (!containerEl) return;
|
|
20
|
-
|
|
20
|
+
if (typeof containerEl.scrollTo === 'function') {
|
|
21
|
+
containerEl.scrollTo({ top: containerEl.scrollHeight, behavior });
|
|
22
|
+
} else {
|
|
23
|
+
containerEl.scrollTop = containerEl.scrollHeight;
|
|
24
|
+
}
|
|
21
25
|
shouldStick = true;
|
|
22
26
|
setIsAtBottom(true);
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
let pendingFrame: number | undefined;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* `cancelAnimationFrame`, captured at SETUP -- not called bare at cleanup.
|
|
33
|
+
*
|
|
34
|
+
* Cleanup is not guaranteed to run while the page that mounted this
|
|
35
|
+
* primitive is still standing: a host can tear its DOM globals down first
|
|
36
|
+
* (`component-register`'s `disconnectedCallback` defers a microtask; a
|
|
37
|
+
* test environment deletes the globals synchronously right after
|
|
38
|
+
* detaching). A bare `cancelAnimationFrame` there throws, surfacing as an
|
|
39
|
+
* unhandled rejection that fails a run in which every test passed --
|
|
40
|
+
* see tests/components/teardown-without-dom-globals.test.tsx, and the
|
|
41
|
+
* same pattern in create-tween.ts.
|
|
42
|
+
*
|
|
43
|
+
* Guarded because "setup" here is the component body, and a server render
|
|
44
|
+
* executes component bodies too; Node has neither global.
|
|
45
|
+
*/
|
|
46
|
+
const cancelFrame = typeof cancelAnimationFrame === 'function'
|
|
47
|
+
? cancelAnimationFrame.bind(globalThis)
|
|
48
|
+
: () => {};
|
|
49
|
+
|
|
25
50
|
function onNewContent() {
|
|
26
51
|
if (shouldStick) {
|
|
27
|
-
requestAnimationFrame(() =>
|
|
52
|
+
pendingFrame = requestAnimationFrame(() => {
|
|
53
|
+
pendingFrame = undefined;
|
|
54
|
+
scrollToBottom('instant');
|
|
55
|
+
});
|
|
28
56
|
}
|
|
29
57
|
}
|
|
30
58
|
|
|
@@ -36,6 +64,10 @@ export function useStickToBottom() {
|
|
|
36
64
|
onCleanup(() => {
|
|
37
65
|
el.removeEventListener('scroll', checkIfAtBottom);
|
|
38
66
|
observer.disconnect();
|
|
67
|
+
if (pendingFrame !== undefined) {
|
|
68
|
+
cancelFrame(pendingFrame);
|
|
69
|
+
pendingFrame = undefined;
|
|
70
|
+
}
|
|
39
71
|
});
|
|
40
72
|
}
|
|
41
73
|
|
|
@@ -5,6 +5,19 @@ export interface UseTextStreamOptions {
|
|
|
5
5
|
speed?: number;
|
|
6
6
|
characterChunkSize?: number;
|
|
7
7
|
fadeDuration?: number;
|
|
8
|
+
segmentDelay?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Default fade-in duration for a given speed (ms) — shared with ResponseStream. */
|
|
12
|
+
export function defaultFadeDuration(speed: number): number {
|
|
13
|
+
const s = Math.min(100, Math.max(1, speed));
|
|
14
|
+
return Math.round(1000 / Math.sqrt(s));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Default per-segment stagger for a given speed (ms) — shared with ResponseStream. */
|
|
18
|
+
export function defaultSegmentDelay(speed: number): number {
|
|
19
|
+
const s = Math.min(100, Math.max(1, speed));
|
|
20
|
+
return Math.max(1, Math.round(100 / Math.sqrt(s)));
|
|
8
21
|
}
|
|
9
22
|
|
|
10
23
|
export interface TextStreamSegment {
|
|
@@ -23,6 +36,7 @@ export function useTextStream(options: UseTextStreamOptions) {
|
|
|
23
36
|
let fullText = '';
|
|
24
37
|
let charIndex = 0;
|
|
25
38
|
let intervalId: ReturnType<typeof setInterval> | undefined;
|
|
39
|
+
let completeTimeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
26
40
|
let isPaused = false;
|
|
27
41
|
let asyncIterator: AsyncIterator<string> | undefined;
|
|
28
42
|
|
|
@@ -31,6 +45,10 @@ export function useTextStream(options: UseTextStreamOptions) {
|
|
|
31
45
|
clearInterval(intervalId);
|
|
32
46
|
intervalId = undefined;
|
|
33
47
|
}
|
|
48
|
+
if (completeTimeoutId !== undefined) {
|
|
49
|
+
clearTimeout(completeTimeoutId);
|
|
50
|
+
completeTimeoutId = undefined;
|
|
51
|
+
}
|
|
34
52
|
}
|
|
35
53
|
|
|
36
54
|
function typewriterTick() {
|
|
@@ -76,8 +94,21 @@ export function useTextStream(options: UseTextStreamOptions) {
|
|
|
76
94
|
const words = source.split(/(\s+)/).filter(Boolean);
|
|
77
95
|
setSegments(words.map((text, index) => ({ text, index })));
|
|
78
96
|
setDisplayedText(source);
|
|
79
|
-
//
|
|
80
|
-
//
|
|
97
|
+
// Completion announces after the staggered animation has had time to
|
|
98
|
+
// play: segments * per-segment delay + one fade duration — the promise
|
|
99
|
+
// the comment here used to make with no code behind it (nothing on this
|
|
100
|
+
// path ever called setIsComplete(true), so kai-complete never fired for
|
|
101
|
+
// a fade-mode string). A timer, not a synchronous write: the consumer
|
|
102
|
+
// attaches its kai-complete listener a beat after mount, and a
|
|
103
|
+
// same-tick fire races past it.
|
|
104
|
+
const segDelay = typeof options.segmentDelay === 'number'
|
|
105
|
+
? Math.max(0, options.segmentDelay)
|
|
106
|
+
: defaultSegmentDelay(speed);
|
|
107
|
+
const fadeDur = options.fadeDuration ?? defaultFadeDuration(speed);
|
|
108
|
+
completeTimeoutId = setTimeout(() => {
|
|
109
|
+
completeTimeoutId = undefined;
|
|
110
|
+
setIsComplete(true);
|
|
111
|
+
}, words.length * segDelay + fadeDur);
|
|
81
112
|
}
|
|
82
113
|
} else {
|
|
83
114
|
if (options.mode === 'typewriter') {
|
|
@@ -14,7 +14,7 @@ import { createPacker, isCardWireFrame, type WireMessage } from './wire';
|
|
|
14
14
|
import { assertOrigin, redactFrame } from './origin';
|
|
15
15
|
import { negotiateVersion } from './version';
|
|
16
16
|
import { hasPollutionKey } from './validate';
|
|
17
|
-
import {
|
|
17
|
+
import { observeDocumentHeight } from '../primitives/use-resize-observer';
|
|
18
18
|
import { validateAgainstSchema, type JsonSchema } from '../primitives/card-validate';
|
|
19
19
|
|
|
20
20
|
/** A provider-side renderer for one card `type`. Renamed (was CardRenderer) per H-K
|
|
@@ -105,10 +105,13 @@ export function createCardBridge(options: CreateCardBridgeOptions): CardBridge {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function startObserver(): void {
|
|
108
|
-
// Tear down any existing observer so
|
|
108
|
+
// Tear down any existing observer so observeDocumentHeight's internal `last` baseline
|
|
109
109
|
// re-initializes to -1 and the newly-mounted card always emits its initial height.
|
|
110
|
+
// observeDocumentHeight (not observeContentHeight) so the reported height covers
|
|
111
|
+
// the FULL rendered document — root's own padding/border AND the provider page's
|
|
112
|
+
// body padding above it — not just root's ResizeObserver content-box (D1).
|
|
110
113
|
stopObserver?.(); stopObserver = null;
|
|
111
|
-
stopObserver =
|
|
114
|
+
stopObserver = observeDocumentHeight(root, (height) => {
|
|
112
115
|
if (!currentId) return;
|
|
113
116
|
cardHost.emit({ kind: 'resize', cardId: currentId, height });
|
|
114
117
|
});
|