@kitn.ai/ui 0.28.0 → 0.30.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 +11 -7
- package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
- package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.js} +1 -1
- package/dist/agent-tooling/construct/public.d.ts +15 -0
- package/dist/agent-tooling/construct/schema.d.ts +111 -0
- package/dist/arrow-down-D783iMJj.js +1 -0
- package/dist/arrow-left-0VLM5kyg.js +1 -0
- package/dist/artifact-DGjzHYUT.js +1 -0
- package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
- package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
- package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
- package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
- package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
- package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
- package/dist/check-CiEOVnEN.js +1 -0
- package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
- package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
- package/dist/chevron-down-CSobuZRG.js +1 -0
- package/dist/chevron-right-DR9ZAP-2.js +1 -0
- package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
- package/dist/circle-BC66EYF7.js +1 -0
- package/dist/circle-check-BqmahW0O.js +1 -0
- package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
- package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
- package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
- package/dist/components/builder-composer-triggers.d.ts +62 -0
- package/dist/components/builder-layout.d.ts +54 -0
- package/dist/components/builder-message-actions.d.ts +72 -0
- package/dist/components/builder-panel.d.ts +189 -0
- package/dist/components/builder-preview.d.ts +11 -0
- package/dist/components/builder-shell-controls.d.ts +69 -0
- package/dist/components/builder-skeleton.d.ts +58 -0
- package/dist/components/builder-start.d.ts +75 -0
- package/dist/components/builder-workspace-variants.d.ts +23 -0
- package/dist/components/captions.d.ts +66 -0
- package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
- package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
- package/dist/construct-cli.es.js +3 -3
- package/dist/construct.d.ts +5 -0
- package/dist/construct.js +327 -0
- package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
- package/dist/controllable-BagRpyHv.js +1 -0
- package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
- package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
- package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
- package/dist/core-C8fzo39E.js +1 -12
- package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
- package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
- package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
- package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
- package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
- package/dist/define-CI0y3eE4.js +1 -0
- package/dist/define.js +40 -40
- package/dist/define.server.js +45 -45
- package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
- package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.js} +1 -1
- 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/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.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- 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.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +1 -1
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- 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.js +1 -1
- 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.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- 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.js +1 -1
- 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.js +1 -1
- 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/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
- package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
- package/dist/engine-javascript-C1x7zo1_.js +1 -141
- package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
- package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
- package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
- package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
- package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
- package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
- package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
- package/dist/index.js +1741 -1725
- package/dist/index.server.js +1582 -1566
- package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
- package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
- package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
- package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
- package/dist/loader-KvJB6NrT.js +1 -0
- package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
- package/dist/mcp.es.js +9 -5
- package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
- package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
- package/dist/message-circle-BPpp5QKv.js +1 -0
- package/dist/message-square-BLbsd9BJ.js +1 -0
- package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
- package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
- package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
- package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
- package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
- package/dist/play-BXy1u7rW.js +1 -0
- package/dist/primitives/use-auto-resize.d.ts +11 -0
- package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
- package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
- package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
- package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
- package/dist/register-impl-DvEnhIxx.js +424 -0
- package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
- package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
- package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
- package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
- package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
- package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
- package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
- package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
- package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
- package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
- package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
- package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
- package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
- package/dist/solid.d.ts +6 -0
- package/dist/solid.js +259 -254
- package/dist/solid.server.js +259 -254
- package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
- package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
- package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
- package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
- package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
- package/dist/text-shimmer-BSzgEnDH.js +1 -0
- package/dist/textarea-DrYNt_0z.js +1 -0
- package/dist/theme.tokens.css +22 -21
- package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
- package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
- package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
- package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
- package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
- package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
- package/dist/ui/color-field.d.ts +48 -0
- package/dist/ui/textarea.d.ts +4 -0
- package/dist/ui/toggle-chip.d.ts +40 -0
- package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
- package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
- package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
- package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
- package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
- package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
- package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
- package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
- package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
- package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
- package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
- package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
- package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
- package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
- package/dist/x-eiO9V6J6.js +1 -0
- package/{src/elements/styles.css → kit-base.css} +27 -44
- package/package.json +32 -17
- package/solid.css +33 -0
- package/theme.css +39 -23
- package/bin/route.test.js +0 -58
- package/dist/arrow-down-CjRU3JgV.js +0 -1
- package/dist/arrow-left-Bnpb1UEW.js +0 -1
- package/dist/artifact-Bwt7OgcR.js +0 -1
- package/dist/check-njkVdZu2.js +0 -1
- package/dist/chevron-down-B72s6PXR.js +0 -1
- package/dist/chevron-right-BatuHzUm.js +0 -1
- package/dist/circle-check-B62pODB3.js +0 -1
- package/dist/circle-zx0ByzY9.js +0 -1
- package/dist/controllable-CnGpMF6r.js +0 -1
- package/dist/define-By-uL588.js +0 -1
- package/dist/loader-BM4CEz4G.js +0 -1
- package/dist/message-circle-DruwObfX.js +0 -1
- package/dist/message-square-BG6q6mlm.js +0 -1
- package/dist/play-BvKKq3fX.js +0 -1
- package/dist/register-impl-B1hLkrI8.js +0 -424
- package/dist/text-shimmer-Dcj1MHuq.js +0 -1
- package/dist/textarea-Dpvbngbg.js +0 -1
- package/dist/x-Z5UntkIJ.js +0 -1
- package/src/agent-tooling/README.md +0 -192
- package/src/agent-tooling/archetypes.ts +0 -205
- package/src/agent-tooling/catalog/README.md +0 -676
- package/src/agent-tooling/catalog/catalog-types.ts +0 -231
- package/src/agent-tooling/catalog/fabrications.ts +0 -96
- package/src/agent-tooling/catalog/invariants.ts +0 -284
- package/src/agent-tooling/catalog/labs-titles.ts +0 -114
- package/src/agent-tooling/catalog/scenarios.ts +0 -87
- package/src/agent-tooling/catalog/surfaces.ts +0 -347
- package/src/agent-tooling/construct/cli-entry.ts +0 -8
- package/src/agent-tooling/construct/cli.ts +0 -147
- package/src/agent-tooling/construct/codegen.ts +0 -1635
- package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
- package/src/agent-tooling/construct/dev.ts +0 -148
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -32
- package/src/agent-tooling/construct/schema.ts +0 -452
- package/src/agent-tooling/integrations/anthropic.ts +0 -442
- package/src/agent-tooling/integrations/cloudflare.ts +0 -218
- package/src/agent-tooling/integrations/langgraph.ts +0 -133
- package/src/agent-tooling/integrations/mastra.ts +0 -182
- package/src/agent-tooling/integrations/mock.ts +0 -148
- package/src/agent-tooling/integrations/ollama.ts +0 -97
- package/src/agent-tooling/integrations/openai.ts +0 -95
- package/src/agent-tooling/integrations/openrouter.ts +0 -82
- package/src/agent-tooling/integrations/pi.ts +0 -176
- package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
- package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
- package/src/agent-tooling/mcp/manifest.ts +0 -422
- package/src/agent-tooling/mcp/server.ts +0 -116
- package/src/agent-tooling/mcp/stdio.ts +0 -18
- package/src/agent-tooling/mcp/tools/construct.ts +0 -130
- package/src/agent-tooling/mcp/tools/debug.ts +0 -621
- package/src/agent-tooling/mcp/tools/reference.ts +0 -980
- package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
- package/src/agent-tooling/mcp/tools/theme.ts +0 -456
- package/src/agent-tooling/mcp/tools/types.ts +0 -14
- package/src/agent-tooling/mcp/validate-args.ts +0 -141
- package/src/agent-tooling/recipes/composed-thread.ts +0 -714
- package/src/agent-tooling/recipes/index.ts +0 -22
- package/src/agent-tooling/recipes/types.ts +0 -32
- package/src/agent-tooling/registry.ts +0 -132
- package/src/agent-tooling/route-emit.ts +0 -305
- package/src/agent-tooling/types.ts +0 -390
- package/src/components/artifact-card.tsx +0 -120
- package/src/components/artifact.tsx +0 -914
- package/src/components/attachment-types.ts +0 -66
- package/src/components/attachments.tsx +0 -536
- package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
- package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
- package/src/components/audio-visualizer/fit-scale.ts +0 -112
- package/src/components/audio-visualizer/index.tsx +0 -528
- package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
- package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
- package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
- package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
- package/src/components/audio-visualizer/sizes.ts +0 -54
- package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
- package/src/components/audio-visualizer/variant-bar.tsx +0 -175
- package/src/components/audio-visualizer/variant-custom.tsx +0 -344
- package/src/components/audio-visualizer/variant-grid.tsx +0 -175
- package/src/components/audio-visualizer/variant-radial.tsx +0 -163
- package/src/components/audio-visualizer/variant-wave.tsx +0 -130
- package/src/components/audio-visualizer/wave.glsl.ts +0 -130
- package/src/components/card-fallback.tsx +0 -60
- package/src/components/card-renderer.tsx +0 -220
- package/src/components/card.tsx +0 -212
- package/src/components/chain-of-thought.tsx +0 -348
- package/src/components/chat-container.tsx +0 -89
- package/src/components/chat-scope-picker.tsx +0 -57
- package/src/components/chat-thread.tsx +0 -1014
- package/src/components/checkpoint.tsx +0 -88
- package/src/components/choice-card.tsx +0 -743
- package/src/components/coachmark.tsx +0 -249
- package/src/components/code-block.tsx +0 -181
- package/src/components/composer-dom.ts +0 -159
- package/src/components/composer-highlight.ts +0 -242
- package/src/components/composer-history.ts +0 -82
- package/src/components/composer.tsx +0 -1075
- package/src/components/confirm-card.tsx +0 -402
- package/src/components/context.tsx +0 -377
- package/src/components/conversation-item.tsx +0 -241
- package/src/components/conversation-list.tsx +0 -429
- package/src/components/conversation-panel.tsx +0 -118
- package/src/components/dismissed-stub.tsx +0 -80
- package/src/components/embed.tsx +0 -200
- package/src/components/empty.tsx +0 -177
- package/src/components/feedback-bar.tsx +0 -166
- package/src/components/file-tree.tsx +0 -530
- package/src/components/file-upload.tsx +0 -167
- package/src/components/form-widgets.tsx +0 -525
- package/src/components/form.tsx +0 -1296
- package/src/components/home-panel.tsx +0 -159
- package/src/components/image.tsx +0 -65
- package/src/components/link-preview.tsx +0 -195
- package/src/components/loader.tsx +0 -367
- package/src/components/markdown.tsx +0 -162
- package/src/components/message-skills.tsx +0 -40
- package/src/components/message.tsx +0 -765
- package/src/components/model-switcher.tsx +0 -132
- package/src/components/prompt-input.tsx +0 -188
- package/src/components/prompt-suggestion.tsx +0 -150
- package/src/components/reasoning.tsx +0 -293
- package/src/components/response-compare-types.ts +0 -152
- package/src/components/response-compare.tsx +0 -455
- package/src/components/response-stream.tsx +0 -109
- package/src/components/screen.tsx +0 -181
- package/src/components/scroll-button.tsx +0 -93
- package/src/components/source.tsx +0 -192
- package/src/components/tasks-card.tsx +0 -801
- package/src/components/text-shimmer.tsx +0 -37
- package/src/components/thinking-bar.tsx +0 -50
- package/src/components/thread.tsx +0 -228
- package/src/components/toast.tsx +0 -503
- package/src/components/tool-classify.ts +0 -26
- package/src/components/tool-types.ts +0 -49
- package/src/components/tool.tsx +0 -190
- package/src/components/use-card-resolution.ts +0 -44
- package/src/components/voice-input.tsx +0 -222
- package/src/components/voice-output.tsx +0 -242
- package/src/components/widget-tab-bar.tsx +0 -73
- package/src/components/workspace-shell.tsx +0 -285
- package/src/diagnostics/hook.ts +0 -352
- package/src/diagnostics/index.ts +0 -82
- package/src/diagnostics/report-request.ts +0 -296
- package/src/elements/agent-card.tsx +0 -67
- package/src/elements/artifact.tsx +0 -194
- package/src/elements/attachments.tsx +0 -140
- package/src/elements/audio-visualizer.tsx +0 -227
- package/src/elements/autoloader.ts +0 -89
- package/src/elements/avatar.tsx +0 -33
- package/src/elements/badge.tsx +0 -32
- package/src/elements/button.tsx +0 -149
- package/src/elements/card.tsx +0 -133
- package/src/elements/cards.tsx +0 -266
- package/src/elements/chain-of-thought.tsx +0 -141
- package/src/elements/chat-scope-picker.tsx +0 -65
- package/src/elements/chat-types.ts +0 -102
- package/src/elements/chat-workspace.tsx +0 -188
- package/src/elements/chat.tsx +0 -304
- package/src/elements/checkbox-group.tsx +0 -164
- package/src/elements/checkbox.tsx +0 -134
- package/src/elements/checkpoint.tsx +0 -47
- package/src/elements/choice.tsx +0 -100
- package/src/elements/coachmark.tsx +0 -90
- package/src/elements/code-block.tsx +0 -60
- package/src/elements/command.tsx +0 -197
- package/src/elements/compare.tsx +0 -111
- package/src/elements/compiled.css +0 -2
- package/src/elements/composer.tsx +0 -162
- package/src/elements/confirm-card.tsx +0 -76
- package/src/elements/context-meter.tsx +0 -107
- package/src/elements/conversation-item.tsx +0 -120
- package/src/elements/conversation-list.tsx +0 -203
- package/src/elements/css.ts +0 -5
- package/src/elements/default-input.tsx +0 -392
- package/src/elements/define-entry.ts +0 -12
- package/src/elements/define.tsx +0 -563
- package/src/elements/diagnostic-events.ts +0 -114
- package/src/elements/dialog.tsx +0 -145
- package/src/elements/disclosure.ts +0 -95
- package/src/elements/dock.tsx +0 -215
- package/src/elements/dropdown.tsx +0 -123
- package/src/elements/editable-label.tsx +0 -140
- package/src/elements/element-data-types.ts +0 -152
- package/src/elements/element-diagnostics.ts +0 -392
- package/src/elements/element-manifest.json +0 -354
- package/src/elements/element-nonscalar.json +0 -187
- package/src/elements/element-types.d.ts +0 -4353
- package/src/elements/embed.tsx +0 -35
- package/src/elements/empty.tsx +0 -29
- package/src/elements/feedback-bar.tsx +0 -66
- package/src/elements/file-tree.tsx +0 -62
- package/src/elements/file-upload.tsx +0 -44
- package/src/elements/form.tsx +0 -94
- package/src/elements/hover-card.tsx +0 -80
- package/src/elements/icon.tsx +0 -41
- package/src/elements/image.tsx +0 -32
- package/src/elements/input.tsx +0 -492
- package/src/elements/kbd.tsx +0 -45
- package/src/elements/link-preview.tsx +0 -34
- package/src/elements/loader.tsx +0 -25
- package/src/elements/markdown.tsx +0 -38
- package/src/elements/menu.tsx +0 -241
- package/src/elements/message-skills.tsx +0 -83
- package/src/elements/message.tsx +0 -361
- package/src/elements/model-switcher.tsx +0 -121
- package/src/elements/nav.tsx +0 -87
- package/src/elements/notice.tsx +0 -53
- package/src/elements/pane-grid.tsx +0 -111
- package/src/elements/pane-group.tsx +0 -119
- package/src/elements/pane.tsx +0 -129
- package/src/elements/popover.tsx +0 -81
- package/src/elements/progress-bar.tsx +0 -39
- package/src/elements/prompt-dock.tsx +0 -82
- package/src/elements/prompt-input.tsx +0 -240
- package/src/elements/prompt-suggestions.tsx +0 -113
- package/src/elements/radio-group.tsx +0 -129
- package/src/elements/reasoning.tsx +0 -71
- package/src/elements/register-impl.ts +0 -148
- package/src/elements/register.ts +0 -76
- package/src/elements/remote.tsx +0 -225
- package/src/elements/resizable.globals.d.ts +0 -36
- package/src/elements/resizable.tsx +0 -704
- package/src/elements/response-stream.tsx +0 -40
- package/src/elements/screen.tsx +0 -90
- package/src/elements/scroll-area.tsx +0 -33
- package/src/elements/scroll-button.tsx +0 -179
- package/src/elements/search.tsx +0 -185
- package/src/elements/segmented.tsx +0 -129
- package/src/elements/select.tsx +0 -165
- package/src/elements/separator.tsx +0 -36
- package/src/elements/setting-item.tsx +0 -50
- package/src/elements/settings-group.tsx +0 -37
- package/src/elements/skeleton.tsx +0 -45
- package/src/elements/slider.tsx +0 -171
- package/src/elements/slot-text.ts +0 -73
- package/src/elements/slots.ts +0 -787
- package/src/elements/source.tsx +0 -126
- package/src/elements/status.tsx +0 -42
- package/src/elements/switch.tsx +0 -118
- package/src/elements/tabs.tsx +0 -95
- package/src/elements/tasks.tsx +0 -103
- package/src/elements/text-shimmer.tsx +0 -28
- package/src/elements/thinking-bar.tsx +0 -43
- package/src/elements/thread.tsx +0 -139
- package/src/elements/toast.tsx +0 -106
- package/src/elements/tool.tsx +0 -78
- package/src/elements/tooltip.tsx +0 -85
- package/src/elements/validate-messages.ts +0 -76
- package/src/elements/voice-input.tsx +0 -100
- package/src/elements/voice-output.tsx +0 -82
- package/src/index.ts +0 -430
- package/src/primitives/audio-bands.ts +0 -174
- package/src/primitives/card-component-types.ts +0 -63
- package/src/primitives/card-contract.ts +0 -80
- package/src/primitives/card-data-types.ts +0 -361
- package/src/primitives/card-host.tsx +0 -37
- package/src/primitives/card-recovery.ts +0 -160
- package/src/primitives/card-registry.tsx +0 -78
- package/src/primitives/card-resolution.ts +0 -36
- package/src/primitives/card-routing.ts +0 -85
- package/src/primitives/card-schemas/artifact.schema.json +0 -92
- package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
- package/src/primitives/card-schemas/card-event.schema.json +0 -12
- package/src/primitives/card-schemas/choice.schema.json +0 -75
- package/src/primitives/card-schemas/confirm.schema.json +0 -65
- package/src/primitives/card-schemas/embed.schema.json +0 -63
- package/src/primitives/card-schemas/form.result.schema.json +0 -7
- package/src/primitives/card-schemas/form.schema.json +0 -53
- package/src/primitives/card-schemas/link.schema.json +0 -54
- package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
- package/src/primitives/card-schemas/tasks.schema.json +0 -83
- package/src/primitives/card-tags.ts +0 -61
- package/src/primitives/card-validate-cards.ts +0 -255
- package/src/primitives/card-validate-schemas.ts +0 -58
- package/src/primitives/card-validate.ts +0 -131
- package/src/primitives/chat-config.tsx +0 -103
- package/src/primitives/composer-model.ts +0 -49
- package/src/primitives/composer-triggers.ts +0 -35
- package/src/primitives/controllable.ts +0 -21
- package/src/primitives/conversation-store.ts +0 -248
- package/src/primitives/create-kai-chat.ts +0 -66
- package/src/primitives/create-tween.ts +0 -266
- package/src/primitives/embed-providers.ts +0 -254
- package/src/primitives/field-mask.ts +0 -256
- package/src/primitives/field-semantics.ts +0 -115
- package/src/primitives/highlighter.ts +0 -157
- package/src/primitives/input-mask.ts +0 -853
- package/src/primitives/link-preview.ts +0 -87
- package/src/primitives/message-feedback.ts +0 -124
- package/src/primitives/pdf-preview.ts +0 -121
- package/src/primitives/toast-store.ts +0 -338
- package/src/primitives/url-scheme-policy.ts +0 -70
- package/src/primitives/use-audio-analysis.ts +0 -340
- package/src/primitives/use-auto-resize.ts +0 -31
- package/src/primitives/use-resize-observer.ts +0 -45
- package/src/primitives/use-sequencer.ts +0 -72
- package/src/primitives/use-speech-recognition.ts +0 -146
- package/src/primitives/use-stick-to-bottom.ts +0 -75
- package/src/primitives/use-text-stream.ts +0 -143
- package/src/primitives/use-voice-recorder.ts +0 -62
- package/src/primitives/visualizer-sequences.ts +0 -350
- package/src/remote/host-embed.ts +0 -345
- package/src/remote/index.ts +0 -2
- package/src/remote/origin.ts +0 -30
- package/src/remote/provider-runtime.ts +0 -262
- package/src/remote/provider.ts +0 -2
- package/src/remote/validate.ts +0 -22
- package/src/remote/version.ts +0 -12
- package/src/remote/wire.ts +0 -48
- package/src/schemas/from-tool-call.ts +0 -151
- package/src/schemas/index.ts +0 -341
- package/src/schemas/provider-subsets.ts +0 -538
- package/src/schemas/registry.ts +0 -355
- package/src/schemas/tool-defs.ts +0 -793
- package/src/solid.ts +0 -173
- package/src/state/index.ts +0 -44
- package/src/state/messages.ts +0 -53
- package/src/state/mock.ts +0 -297
- package/src/state/parts.ts +0 -295
- package/src/state/persistence.ts +0 -180
- package/src/state/stream.ts +0 -246
- package/src/state/suggestions.ts +0 -9
- package/src/state/threads.ts +0 -142
- package/src/test-utils/fake-clock.ts +0 -88
- package/src/types.ts +0 -95
- package/src/ui/action-icons.ts +0 -53
- package/src/ui/agent-card.tsx +0 -218
- package/src/ui/avatar.tsx +0 -23
- package/src/ui/badge.tsx +0 -21
- package/src/ui/button.tsx +0 -49
- package/src/ui/card.tsx +0 -245
- package/src/ui/checkbox-group.tsx +0 -153
- package/src/ui/checkbox.tsx +0 -63
- package/src/ui/collapsible.tsx +0 -163
- package/src/ui/command.tsx +0 -103
- package/src/ui/dialog.tsx +0 -223
- package/src/ui/dock.tsx +0 -630
- package/src/ui/dropdown.tsx +0 -636
- package/src/ui/editable-label.tsx +0 -112
- package/src/ui/hover-card.tsx +0 -345
- package/src/ui/icon.tsx +0 -167
- package/src/ui/input.tsx +0 -391
- package/src/ui/kbd.tsx +0 -118
- package/src/ui/nav.tsx +0 -282
- package/src/ui/notice.tsx +0 -84
- package/src/ui/overlay.tsx +0 -277
- package/src/ui/pane-grid.tsx +0 -117
- package/src/ui/pane-group.tsx +0 -291
- package/src/ui/pane.tsx +0 -193
- package/src/ui/popover.tsx +0 -106
- package/src/ui/progress-bar.tsx +0 -83
- package/src/ui/prompt-dock.tsx +0 -145
- package/src/ui/radio.tsx +0 -150
- package/src/ui/resizable.tsx +0 -693
- package/src/ui/scroll-area.tsx +0 -26
- package/src/ui/segmented.tsx +0 -109
- package/src/ui/select.tsx +0 -168
- package/src/ui/separator.tsx +0 -10
- package/src/ui/settings-group.tsx +0 -67
- package/src/ui/skeleton.tsx +0 -73
- package/src/ui/slider.tsx +0 -178
- package/src/ui/status.tsx +0 -48
- package/src/ui/switch.tsx +0 -119
- package/src/ui/tabs.tsx +0 -168
- package/src/ui/textarea.tsx +0 -21
- package/src/ui/tooltip.tsx +0 -118
- package/src/utils/cn.ts +0 -30
- package/src/wire/chunk.ts +0 -248
- package/src/wire/consume.ts +0 -599
- package/src/wire/diagnostics.ts +0 -727
- package/src/wire/encode-probe.ts +0 -214
- package/src/wire/encode.ts +0 -947
- package/src/wire/files.ts +0 -342
- package/src/wire/formats/anthropic.ts +0 -274
- package/src/wire/formats/openai.ts +0 -228
- package/src/wire/index.ts +0 -95
- package/src/wire/media-types.ts +0 -344
- package/src/wire/read.ts +0 -396
- package/src/wire/sink-helpers.ts +0 -50
- package/src/wire/sse.ts +0 -153
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
import { createSignal, onCleanup, untrack, type Accessor } from 'solid-js';
|
|
2
|
-
|
|
3
|
-
export type Transition =
|
|
4
|
-
| { duration: number; ease?: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' }
|
|
5
|
-
| { type: 'spring'; duration: number; bounce: number };
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Builds an easing function from a CSS-style cubic bezier. The curve's
|
|
9
|
-
* endpoints are fixed at (0, 0) and (1, 1); (x1, y1) and (x2, y2) are the
|
|
10
|
-
* two control points. Given a progress value `t` used as the curve's `x`,
|
|
11
|
-
* solves `X(s) === t` for the curve parameter `s` via Newton-Raphson (a
|
|
12
|
-
* handful of iterations converges for these curves), falls back to
|
|
13
|
-
* bisection if the derivative gets too small or a step would leave
|
|
14
|
-
* [0, 1], then returns `Y(s)`.
|
|
15
|
-
*/
|
|
16
|
-
function cubicBezier(x1: number, y1: number, x2: number, y2: number): (t: number) => number {
|
|
17
|
-
const x = (s: number) => 3 * (1 - s) * (1 - s) * s * x1 + 3 * (1 - s) * s * s * x2 + s * s * s;
|
|
18
|
-
const y = (s: number) => 3 * (1 - s) * (1 - s) * s * y1 + 3 * (1 - s) * s * s * y2 + s * s * s;
|
|
19
|
-
const xDerivative = (s: number) =>
|
|
20
|
-
3 * (1 - s) * (1 - s) * x1 + 6 * (1 - s) * s * (x2 - x1) + 3 * s * s * (1 - x2);
|
|
21
|
-
|
|
22
|
-
function bisect(t: number): number {
|
|
23
|
-
let lo = 0;
|
|
24
|
-
let hi = 1;
|
|
25
|
-
for (let i = 0; i < 30; i++) {
|
|
26
|
-
const mid = (lo + hi) / 2;
|
|
27
|
-
if (x(mid) < t) lo = mid;
|
|
28
|
-
else hi = mid;
|
|
29
|
-
}
|
|
30
|
-
return (lo + hi) / 2;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return (t: number) => {
|
|
34
|
-
if (t <= 0) return 0;
|
|
35
|
-
if (t >= 1) return 1;
|
|
36
|
-
|
|
37
|
-
let s = t;
|
|
38
|
-
for (let i = 0; i < 8; i++) {
|
|
39
|
-
const derivative = xDerivative(s);
|
|
40
|
-
if (Math.abs(derivative) < 1e-6) return y(bisect(t));
|
|
41
|
-
|
|
42
|
-
const next = s - (x(s) - t) / derivative;
|
|
43
|
-
if (next <= 0 || next >= 1) return y(bisect(t));
|
|
44
|
-
|
|
45
|
-
s = next;
|
|
46
|
-
}
|
|
47
|
-
return y(s);
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Matches motion's named curves so the visualizers feel like their LiveKit
|
|
52
|
-
// counterparts rather than a plausible-looking approximation.
|
|
53
|
-
//
|
|
54
|
-
// Every easing here is TOTAL: it clamps `t` into [0, 1] itself rather than
|
|
55
|
-
// trusting its caller. `cubicBezier` already did (its Newton solve needs `t`
|
|
56
|
-
// in range to converge); `linear` was the bare identity and passed anything
|
|
57
|
-
// straight through. `step()` below clamps the top but not the bottom, so a
|
|
58
|
-
// frame timestamp EARLIER than the origin `to()` captured yields a negative
|
|
59
|
-
// `t` and, through an unclamped easing, a tween that runs backwards.
|
|
60
|
-
//
|
|
61
|
-
// That timestamp cannot occur in a browser -- requestAnimationFrame's
|
|
62
|
-
// timestamp and `performance.now()` share a time origin per spec -- so this is
|
|
63
|
-
// robustness, not a live bug. It does occur under vitest + jsdom, where the
|
|
64
|
-
// two do not share an origin. The clamp lives in the easings rather than at
|
|
65
|
-
// the `step()` call site so the tests can drive a negative `t` through each
|
|
66
|
-
// curve individually and prove which ones guard.
|
|
67
|
-
const EASINGS = {
|
|
68
|
-
linear: (t: number) => Math.min(1, Math.max(0, t)),
|
|
69
|
-
easeIn: cubicBezier(0.42, 0, 1, 1),
|
|
70
|
-
easeOut: cubicBezier(0, 0, 0.58, 1),
|
|
71
|
-
easeInOut: cubicBezier(0.42, 0, 0.58, 1),
|
|
72
|
-
} as const;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Damped-spring position at normalized time `t` (0..1), settling at 1.
|
|
76
|
-
*
|
|
77
|
-
* `bounce` maps to the damping ratio: 0 is critically damped (no overshoot),
|
|
78
|
-
* higher values overshoot more. Matches the feel of motion's spring defaults
|
|
79
|
-
* closely enough for shader uniforms, without the dependency.
|
|
80
|
-
*
|
|
81
|
-
* `t` is clamped at 0 for the same reason the named easings are (see EASINGS),
|
|
82
|
-
* and the failure here is far louder than theirs: the decay term is
|
|
83
|
-
* `Math.exp(-zeta * omega * t)`, so a negative `t` makes it GROW rather than
|
|
84
|
-
* decay. At t = -0.25 with bounce 0.4 this returned ~5.9 instead of something
|
|
85
|
-
* in [0, ~1.3]. No top clamp: overshooting past 1 is what a spring is for.
|
|
86
|
-
*/
|
|
87
|
-
function spring(t: number, bounce: number): number {
|
|
88
|
-
t = Math.max(0, t);
|
|
89
|
-
const zeta = Math.max(0.05, 1 - Math.min(0.95, bounce));
|
|
90
|
-
const omega = 10;
|
|
91
|
-
const damped = omega * Math.sqrt(Math.max(0, 1 - zeta * zeta));
|
|
92
|
-
return (
|
|
93
|
-
1 -
|
|
94
|
-
Math.exp(-zeta * omega * t) *
|
|
95
|
-
(Math.cos(damped * t) + ((zeta * omega) / (damped || 1)) * Math.sin(damped * t))
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function isSpring(tr: Transition): tr is { type: 'spring'; duration: number; bounce: number } {
|
|
100
|
-
return 'type' in tr && tr.type === 'spring';
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* A tweened number driven by requestAnimationFrame.
|
|
105
|
-
*
|
|
106
|
-
* Exists so shader uniforms can animate without pulling in a motion library.
|
|
107
|
-
* CSS transitions cannot help here: uniforms are plain JS numbers handed to
|
|
108
|
-
* WebGL every frame.
|
|
109
|
-
*
|
|
110
|
-
* `to()` interrupts whatever is in flight. An array target ping-pongs between
|
|
111
|
-
* its two values forever, which is how the listening and thinking pulses read.
|
|
112
|
-
* `duration: 0` (or no transition) sets instantly, which live volume needs so
|
|
113
|
-
* the picture never lags the audio.
|
|
114
|
-
*
|
|
115
|
-
* `animating` is true exactly while a frame loop is armed: from an animated
|
|
116
|
-
* `to()` until it lands (a ping-pong never lands, so it stays true), false
|
|
117
|
-
* for instant sets and after dispose. It is a real signal on purpose -- the
|
|
118
|
-
* aurora variant's volume-override effect reads it as its upstream-parity
|
|
119
|
-
* "scale tween idle" guard, and being reactive means that effect re-runs
|
|
120
|
-
* the moment a landing settles instead of waiting for the next volume tick.
|
|
121
|
-
*/
|
|
122
|
-
export function createTween(initial: number): {
|
|
123
|
-
value: Accessor<number>;
|
|
124
|
-
animating: Accessor<boolean>;
|
|
125
|
-
to(target: number | [number, number], transition?: Transition): void;
|
|
126
|
-
} {
|
|
127
|
-
const [value, setValue] = createSignal(initial);
|
|
128
|
-
const [animating, setAnimating] = createSignal(false);
|
|
129
|
-
let raf = 0;
|
|
130
|
-
let disposed = false;
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* `cancelAnimationFrame`, captured at SETUP.
|
|
134
|
-
*
|
|
135
|
-
* `stop()` below runs at dispose, and dispose is not guaranteed to happen
|
|
136
|
-
* while the page that mounted this tween is still standing -- a host can tear
|
|
137
|
-
* its DOM globals down in between (`component-register`'s
|
|
138
|
-
* `disconnectedCallback` defers a microtask; a test environment deletes the
|
|
139
|
-
* globals synchronously right after detaching). A bare `cancelAnimationFrame`
|
|
140
|
-
* there throws from a promise nobody holds, so it surfaces as an unhandled
|
|
141
|
-
* rejection that fails a run in which every test passed. See
|
|
142
|
-
* tests/components/teardown-without-dom-globals.test.tsx.
|
|
143
|
-
*
|
|
144
|
-
* The FUNCTION, not the view. The `const win = window` capture that fixes a
|
|
145
|
-
* bare `document` does nothing here: `window === globalThis` -- measured, in
|
|
146
|
-
* jsdom and in real Chromium/WebKit alike -- and the teardown deletes these
|
|
147
|
-
* keys off that very object, so `win.cancelAnimationFrame` is undefined by
|
|
148
|
-
* the time cleanup runs. It only trades the ReferenceError for a TypeError.
|
|
149
|
-
* `.bind` pins the receiver the WebIDL operation is specified on; Chromium
|
|
150
|
-
* and WebKit both accept a detached call (measured), so the bind is belt and
|
|
151
|
-
* braces against an engine that does not, at zero cost.
|
|
152
|
-
*
|
|
153
|
-
* GUARDED because "setup" for this primitive is the component body, and a
|
|
154
|
-
* server render executes component bodies. Node has no `cancelAnimationFrame`
|
|
155
|
-
* at all, so an unguarded capture here would trade the disposal crash for an
|
|
156
|
-
* SSR crash -- measured, not hypothesised. Nothing can be scheduled without
|
|
157
|
-
* `requestAnimationFrame` either, so the no-op fallback is exactly right.
|
|
158
|
-
*/
|
|
159
|
-
const cancelFrame = typeof cancelAnimationFrame === 'function'
|
|
160
|
-
? cancelAnimationFrame.bind(globalThis)
|
|
161
|
-
: () => {};
|
|
162
|
-
|
|
163
|
-
const stop = () => {
|
|
164
|
-
if (raf) cancelFrame(raf);
|
|
165
|
-
raf = 0;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
onCleanup(() => {
|
|
169
|
-
disposed = true;
|
|
170
|
-
stop();
|
|
171
|
-
setAnimating(false);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
function to(target: number | [number, number], transition?: Transition) {
|
|
175
|
-
stop();
|
|
176
|
-
if (disposed) return;
|
|
177
|
-
|
|
178
|
-
const pingPong = Array.isArray(target);
|
|
179
|
-
// Untracked: `.to()` is an imperative command ("animate to this
|
|
180
|
-
// target"), not a reactive read. Its normal caller is a createEffect
|
|
181
|
-
// reacting to some OTHER signal (e.g. state changing); reading this
|
|
182
|
-
// tween's own `value()` here without untrack() would make that effect
|
|
183
|
-
// implicitly depend on the tween's own signal too. That is invisible
|
|
184
|
-
// for a single tween (it would just restart itself every frame and
|
|
185
|
-
// still crawl toward the target) but is fatal the moment a caller
|
|
186
|
-
// creates a SECOND tween and `.to()`'s both from the same effect (see
|
|
187
|
-
// the wave shader variant, which does exactly this for amplitude and
|
|
188
|
-
// frequency): a browser fires one frame's queued
|
|
189
|
-
// requestAnimationFrame callbacks in the order they were registered, so
|
|
190
|
-
// the FIRST tween's step -- which runs first, and whose `setValue`
|
|
191
|
-
// synchronously re-triggers the (now-dependent) effect -- cancels the
|
|
192
|
-
// SECOND tween's already-queued step before the browser ever reaches
|
|
193
|
-
// it. That repeats identically every single frame, so the second
|
|
194
|
-
// tween's `step` never fires even once and its value never leaves its
|
|
195
|
-
// initial one, permanently, no matter how long the effect keeps
|
|
196
|
-
// "restarting" it.
|
|
197
|
-
const [a, b] = pingPong ? target : [untrack(value), target];
|
|
198
|
-
|
|
199
|
-
if (!transition || (!isSpring(transition) && transition.duration === 0)) {
|
|
200
|
-
setAnimating(false);
|
|
201
|
-
setValue(pingPong ? a : b);
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const durationMs = transition.duration * 1000;
|
|
206
|
-
if (durationMs <= 0) {
|
|
207
|
-
setAnimating(false);
|
|
208
|
-
setValue(b);
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (typeof requestAnimationFrame === 'undefined') {
|
|
213
|
-
setAnimating(false);
|
|
214
|
-
setValue(b);
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const ease = isSpring(transition)
|
|
219
|
-
? (t: number) => spring(t, transition.bounce)
|
|
220
|
-
: EASINGS[transition.ease ?? 'easeOut'];
|
|
221
|
-
|
|
222
|
-
// A ping-pong starts from its first value rather than wherever it was, so
|
|
223
|
-
// the pulse reads the same every time it restarts. `a` is already an
|
|
224
|
-
// untracked read of the current value (or the ping-pong's first target
|
|
225
|
-
// value) from above -- reused here instead of reading `value()` again.
|
|
226
|
-
let from = a;
|
|
227
|
-
let to_ = b;
|
|
228
|
-
if (pingPong) setValue(a);
|
|
229
|
-
|
|
230
|
-
// requestAnimationFrame's timestamp and performance.now() share a time
|
|
231
|
-
// origin per spec, so capturing the origin here, at the moment to() is
|
|
232
|
-
// called, is directly comparable to the `now` a later frame reports.
|
|
233
|
-
// That means elapsed time is measured from when this leg actually
|
|
234
|
-
// started, correct on the very first frame with no lazy-capture dance
|
|
235
|
-
// and no risk of an idle gap since the last tween being charged against
|
|
236
|
-
// this one.
|
|
237
|
-
let legStart = performance.now();
|
|
238
|
-
const step = (now: number) => {
|
|
239
|
-
const t = Math.min(1, (now - legStart) / durationMs);
|
|
240
|
-
setValue(from + (to_ - from) * ease(t));
|
|
241
|
-
|
|
242
|
-
if (t < 1) {
|
|
243
|
-
raf = requestAnimationFrame(step);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (!pingPong) {
|
|
248
|
-
setValue(to_);
|
|
249
|
-
raf = 0;
|
|
250
|
-
setAnimating(false);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Reverse and run again, from a fresh origin for the new leg.
|
|
255
|
-
setValue(to_);
|
|
256
|
-
[from, to_] = [to_, from];
|
|
257
|
-
legStart = performance.now();
|
|
258
|
-
raf = requestAnimationFrame(step);
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
setAnimating(true);
|
|
262
|
-
raf = requestAnimationFrame(step);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return { value, animating, to };
|
|
266
|
-
}
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
// src/primitives/embed-providers.ts
|
|
2
|
-
// Pure provider resolution for <kai-embed>: map an EmbedCardData → an embeddable
|
|
3
|
-
// player URL + poster + iframe sandbox/allow. Covers youtube (privacy-enhanced
|
|
4
|
-
// youtube-nocookie), vimeo (dnt=1), and generic (https-only, ORIGIN-ALLOWLISTED).
|
|
5
|
-
// No network, no DOM. See docs/superpowers/specs/2026-06-13-kc-link-embed-cards-design.md.
|
|
6
|
-
import type { CardEnvelope } from './card-contract';
|
|
7
|
-
|
|
8
|
-
/** Media provider for an embed card. */
|
|
9
|
-
export type EmbedProvider = 'youtube' | 'vimeo' | 'generic';
|
|
10
|
-
|
|
11
|
-
/** Lazy media-embed payload (YouTube / Vimeo / generic player URL). */
|
|
12
|
-
export interface EmbedCardData {
|
|
13
|
-
/** Media provider. 'generic' frames `url` directly. */
|
|
14
|
-
provider: EmbedProvider;
|
|
15
|
-
/** Provider video id (youtube/vimeo) when not parsing from `url`. */
|
|
16
|
-
id?: string;
|
|
17
|
-
/** Full media/watch/embed URL. */
|
|
18
|
-
url?: string;
|
|
19
|
-
/** Accessible iframe title + poster label. */
|
|
20
|
-
title?: string;
|
|
21
|
-
/** Thumbnail before play; derived for youtube/vimeo when omitted. */
|
|
22
|
-
poster?: string;
|
|
23
|
-
/** Start offset, seconds. */
|
|
24
|
-
start?: number;
|
|
25
|
-
/** Player aspect ratio. Default '16:9'. */
|
|
26
|
-
aspectRatio?: '16:9' | '4:3' | '1:1' | '9:16';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** The full envelope an agent/server emits for an embed card. */
|
|
30
|
-
export type EmbedCardEnvelope = CardEnvelope<'embed', EmbedCardData>;
|
|
31
|
-
|
|
32
|
-
/** The `type` discriminator for embed cards. */
|
|
33
|
-
export const EMBED_CARD_TYPE = 'embed' as const;
|
|
34
|
-
|
|
35
|
-
export interface ResolvedEmbed {
|
|
36
|
-
/** The iframe src loaded on play (already including autoplay/start params). */
|
|
37
|
-
embedUrl: string;
|
|
38
|
-
/** Poster/thumbnail to show before play (derived when not supplied). */
|
|
39
|
-
posterUrl?: string;
|
|
40
|
-
/** sandbox attribute for the player iframe. */
|
|
41
|
-
sandbox: string;
|
|
42
|
-
/** allow attribute (fullscreen, encrypted-media, picture-in-picture, …). */
|
|
43
|
-
allow: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// A provider player NEEDS allow-scripts + allow-same-origin (its OWN origin) to run.
|
|
47
|
-
// That is safe here because the framed origin is a KNOWN, trusted video provider on a
|
|
48
|
-
// DIFFERENT origin than the host — same-origin policy still isolates the host page from
|
|
49
|
-
// the provider. allow-popups(-to-escape-sandbox) lets "watch on YouTube" work. The
|
|
50
|
-
// `allow` attribute (not sandbox) governs autoplay/fullscreen/encrypted-media.
|
|
51
|
-
// Contrast <kai-artifact> (allow-scripts allow-forms, NO allow-same-origin) which frames
|
|
52
|
-
// arbitrary consumer HTML and so trusts nothing.
|
|
53
|
-
const PLAYER_SANDBOX =
|
|
54
|
-
'allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox';
|
|
55
|
-
const PLAYER_ALLOW =
|
|
56
|
-
'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen';
|
|
57
|
-
|
|
58
|
-
// --- generic origin allowlist (security decision) -------------------------
|
|
59
|
-
//
|
|
60
|
-
// A `generic` embed frames an ARBITRARY https URL. An agent-supplied generic URL is a
|
|
61
|
-
// supply-chain risk, so it is REJECTED unless the app has explicitly allowlisted its
|
|
62
|
-
// origin. The allowlist defaults to EMPTY: out of the box, `generic` embeds are blocked.
|
|
63
|
-
const allowedGenericOrigins = new Set<string>();
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* App opt-in: allow `generic` embeds whose origin is in this list. Origins are
|
|
67
|
-
* normalized via the URL parser (scheme + host + port). Only https origins are
|
|
68
|
-
* accepted (a non-https origin is ignored). Call once at app startup.
|
|
69
|
-
*/
|
|
70
|
-
export function configureEmbedAllowlist(origins: string[]): void {
|
|
71
|
-
for (const o of origins) {
|
|
72
|
-
const origin = normalizeOrigin(o);
|
|
73
|
-
if (origin) allowedGenericOrigins.add(origin);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** True when `url`'s origin has been allowlisted for `generic` embeds. */
|
|
78
|
-
export function isGenericOriginAllowed(url: string): boolean {
|
|
79
|
-
const origin = originOf(url);
|
|
80
|
-
return origin !== undefined && allowedGenericOrigins.has(origin);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Test-only: clear the generic allowlist so tests stay isolated. */
|
|
84
|
-
export function __resetEmbedAllowlistForTests(): void {
|
|
85
|
-
allowedGenericOrigins.clear();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Normalize an allowlist entry (a URL or bare origin) to a canonical https origin, or undefined. */
|
|
89
|
-
function normalizeOrigin(input: string): string | undefined {
|
|
90
|
-
const origin = originOf(input) ?? originOf(`https://${input}`);
|
|
91
|
-
if (!origin) return undefined;
|
|
92
|
-
return origin.startsWith('https://') ? origin : undefined;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** The `scheme://host[:port]` origin of a URL, or undefined when unparseable. */
|
|
96
|
-
function originOf(url: string): string | undefined {
|
|
97
|
-
try {
|
|
98
|
-
return new URL(url).origin;
|
|
99
|
-
} catch {
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// --- id parsing -----------------------------------------------------------
|
|
105
|
-
|
|
106
|
-
/** Extract a YouTube id from a watch / youtu.be / shorts / embed URL. */
|
|
107
|
-
export function parseYouTubeId(url: string): string | undefined {
|
|
108
|
-
let parsed: URL;
|
|
109
|
-
try {
|
|
110
|
-
parsed = new URL(url);
|
|
111
|
-
} catch {
|
|
112
|
-
return undefined;
|
|
113
|
-
}
|
|
114
|
-
const host = parsed.hostname.replace(/^www\./, '');
|
|
115
|
-
if (host === 'youtu.be') {
|
|
116
|
-
return cleanId(parsed.pathname.slice(1));
|
|
117
|
-
}
|
|
118
|
-
if (host === 'youtube.com' || host === 'm.youtube.com' || host === 'youtube-nocookie.com') {
|
|
119
|
-
const v = parsed.searchParams.get('v');
|
|
120
|
-
if (v) return cleanId(v);
|
|
121
|
-
// /shorts/<id>, /embed/<id>, /v/<id>
|
|
122
|
-
const m = parsed.pathname.match(/^\/(?:shorts|embed|v)\/([^/?#]+)/);
|
|
123
|
-
if (m) return cleanId(m[1]);
|
|
124
|
-
}
|
|
125
|
-
return undefined;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** Extract a Vimeo id from a vimeo.com/<id> (or player.vimeo.com/video/<id>) URL. */
|
|
129
|
-
export function parseVimeoId(url: string): string | undefined {
|
|
130
|
-
let parsed: URL;
|
|
131
|
-
try {
|
|
132
|
-
parsed = new URL(url);
|
|
133
|
-
} catch {
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
const host = parsed.hostname.replace(/^www\./, '');
|
|
137
|
-
if (host !== 'vimeo.com' && host !== 'player.vimeo.com') return undefined;
|
|
138
|
-
const m = parsed.pathname.match(/(?:^|\/)(\d+)(?:\/|$)/);
|
|
139
|
-
return m ? m[1] : undefined;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** A provider video id must be the [A-Za-z0-9_-] alphabet (matches the schema pattern). */
|
|
143
|
-
function cleanId(id: string): string | undefined {
|
|
144
|
-
return /^[A-Za-z0-9_-]+$/.test(id) ? id : undefined;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// --- resolution -----------------------------------------------------------
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Resolve an EmbedCardData to an embeddable player URL + poster + sandbox/allow.
|
|
151
|
-
* Throws (with a human message) on a missing/invalid provider id, a non-https
|
|
152
|
-
* generic URL, or a generic origin not in the app allowlist — the card turns these
|
|
153
|
-
* into an inline error + an `error` event.
|
|
154
|
-
*/
|
|
155
|
-
export function resolveEmbed(data: EmbedCardData): ResolvedEmbed {
|
|
156
|
-
const start = data.start ? `&start=${data.start}` : '';
|
|
157
|
-
switch (data.provider) {
|
|
158
|
-
case 'youtube': {
|
|
159
|
-
const id = data.id ?? (data.url ? parseYouTubeId(data.url) : undefined);
|
|
160
|
-
if (!id) throw new Error('youtube embed: missing or unparseable id/url');
|
|
161
|
-
return {
|
|
162
|
-
embedUrl: `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&rel=0${start}`,
|
|
163
|
-
posterUrl: data.poster ?? `https://i.ytimg.com/vi/${id}/hqdefault.jpg`,
|
|
164
|
-
sandbox: PLAYER_SANDBOX,
|
|
165
|
-
allow: PLAYER_ALLOW,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
case 'vimeo': {
|
|
169
|
-
const id = data.id ?? (data.url ? parseVimeoId(data.url) : undefined);
|
|
170
|
-
if (!id) throw new Error('vimeo embed: missing or unparseable id/url');
|
|
171
|
-
return {
|
|
172
|
-
embedUrl: `https://player.vimeo.com/video/${id}?autoplay=1&dnt=1${
|
|
173
|
-
data.start ? `#t=${data.start}s` : ''
|
|
174
|
-
}`,
|
|
175
|
-
// Vimeo has no static thumbnail URL; rely on a supplied poster (or placeholder).
|
|
176
|
-
posterUrl: data.poster,
|
|
177
|
-
sandbox: PLAYER_SANDBOX,
|
|
178
|
-
allow: PLAYER_ALLOW,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
case 'generic': {
|
|
182
|
-
if (!data.url) throw new Error('generic embed: missing url');
|
|
183
|
-
assertHttpsEmbeddable(data.url);
|
|
184
|
-
if (!isGenericOriginAllowed(data.url)) {
|
|
185
|
-
throw new Error(
|
|
186
|
-
`generic embed: origin not allowlisted — call configureEmbedAllowlist([...]) to permit ${
|
|
187
|
-
originOf(data.url) ?? data.url
|
|
188
|
-
}`,
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
return { embedUrl: data.url, posterUrl: data.poster, sandbox: PLAYER_SANDBOX, allow: PLAYER_ALLOW };
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** Reject non-https or javascript:/data: player URLs (defense in depth). */
|
|
197
|
-
function assertHttpsEmbeddable(url: string): void {
|
|
198
|
-
let protocol: string;
|
|
199
|
-
try {
|
|
200
|
-
protocol = new URL(url).protocol;
|
|
201
|
-
} catch {
|
|
202
|
-
throw new Error(`generic embed: invalid url "${url}"`);
|
|
203
|
-
}
|
|
204
|
-
if (protocol !== 'https:') {
|
|
205
|
-
throw new Error(`generic embed: only https player URLs are allowed (got ${protocol})`);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* The canonical "watch on the provider" URL for the optional fallback affordance
|
|
211
|
-
* (emitted as `open`/target:'tab' when an embed is blocked). Returns `undefined`
|
|
212
|
-
* when there is nothing useful to link to.
|
|
213
|
-
*/
|
|
214
|
-
export function watchUrl(data: EmbedCardData): string | undefined {
|
|
215
|
-
switch (data.provider) {
|
|
216
|
-
case 'youtube': {
|
|
217
|
-
const id = data.id ?? (data.url ? parseYouTubeId(data.url) : undefined);
|
|
218
|
-
return id ? `https://www.youtube.com/watch?v=${id}` : data.url;
|
|
219
|
-
}
|
|
220
|
-
case 'vimeo': {
|
|
221
|
-
const id = data.id ?? (data.url ? parseVimeoId(data.url) : undefined);
|
|
222
|
-
return id ? `https://vimeo.com/${id}` : data.url;
|
|
223
|
-
}
|
|
224
|
-
case 'generic':
|
|
225
|
-
return data.url;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/** Human-readable provider label for the fallback affordance ("Open on YouTube"). */
|
|
230
|
-
export function providerLabel(provider: EmbedProvider): string {
|
|
231
|
-
switch (provider) {
|
|
232
|
-
case 'youtube':
|
|
233
|
-
return 'YouTube';
|
|
234
|
-
case 'vimeo':
|
|
235
|
-
return 'Vimeo';
|
|
236
|
-
case 'generic':
|
|
237
|
-
return 'site';
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/** CSS aspect-ratio value for a card's aspectRatio (default 16:9). */
|
|
242
|
-
export function aspectRatioValue(aspectRatio: EmbedCardData['aspectRatio']): string {
|
|
243
|
-
switch (aspectRatio) {
|
|
244
|
-
case '4:3':
|
|
245
|
-
return '4 / 3';
|
|
246
|
-
case '1:1':
|
|
247
|
-
return '1 / 1';
|
|
248
|
-
case '9:16':
|
|
249
|
-
return '9 / 16';
|
|
250
|
-
case '16:9':
|
|
251
|
-
default:
|
|
252
|
-
return '16 / 9';
|
|
253
|
-
}
|
|
254
|
-
}
|