@kitn.ai/ui 0.15.1 → 0.17.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 +37 -13
- package/bin/mcp.js +22 -0
- package/dist/bash-InADTalH.js +6 -1
- package/dist/components/artifact.d.ts +58 -0
- package/dist/components/attachments.d.ts +67 -0
- package/dist/components/card-fallback.d.ts +10 -0
- package/dist/components/card-renderer.d.ts +13 -0
- package/dist/components/card.d.ts +28 -0
- package/dist/components/chain-of-thought.d.ts +29 -0
- package/dist/components/chat-container.d.ts +19 -0
- package/dist/components/chat-scope-picker.d.ts +9 -0
- package/dist/components/chat-thread.d.ts +91 -0
- package/dist/components/checkpoint.d.ts +20 -0
- package/dist/components/choice-card.d.ts +78 -0
- package/dist/components/code-block.d.ts +16 -0
- package/dist/components/confirm-card.d.ts +57 -0
- package/dist/components/context.d.ts +65 -0
- package/dist/components/conversation-item.d.ts +8 -0
- package/dist/components/conversation-list.d.ts +11 -0
- package/dist/components/dismissed-stub.d.ts +22 -0
- package/dist/components/embed.d.ts +21 -0
- package/dist/components/empty.d.ts +43 -0
- package/dist/components/feedback-bar.d.ts +45 -0
- package/dist/components/file-tree.d.ts +57 -0
- package/dist/components/file-upload.d.ts +16 -0
- package/dist/components/form-widgets.d.ts +31 -0
- package/dist/components/form.d.ts +103 -0
- package/dist/components/image.d.ts +12 -0
- package/dist/components/link-preview.d.ts +23 -0
- package/dist/components/loader.d.ts +60 -0
- package/dist/components/markdown.d.ts +8 -0
- package/dist/components/message-skills.d.ts +15 -0
- package/dist/components/message.d.ts +111 -0
- package/dist/components/model-switcher.d.ts +8 -0
- package/dist/components/prompt-input.d.ts +38 -0
- package/dist/components/prompt-suggestion.d.ts +13 -0
- package/dist/components/reasoning.d.ts +20 -0
- package/dist/components/response-compare-types.d.ts +66 -0
- package/dist/components/response-compare.d.ts +51 -0
- package/dist/components/response-stream.d.ts +14 -0
- package/dist/components/scroll-button.d.ts +7 -0
- package/dist/components/slash-command.d.ts +15 -0
- package/dist/components/source.d.ts +23 -0
- package/dist/components/tasks-card.d.ts +72 -0
- package/dist/components/text-shimmer.d.ts +9 -0
- package/dist/components/thinking-bar.d.ts +10 -0
- package/dist/components/toast.d.ts +48 -0
- package/dist/components/tool.d.ts +16 -0
- package/dist/components/use-card-resolution.d.ts +16 -0
- package/dist/components/voice-input.d.ts +7 -0
- package/dist/core-AYMC6_lb.js +5874 -12
- package/dist/css-M7EaDHN_.js +6 -1
- package/dist/custom-elements.json +260 -11
- package/dist/elements/artifact.d.ts +1 -0
- package/dist/elements/artifact.js +1 -0
- package/dist/elements/attachments.d.ts +1 -0
- package/dist/elements/attachments.js +1 -0
- package/dist/elements/autoloader.d.ts +2 -0
- package/dist/elements/autoloader.js +1 -0
- package/dist/elements/card.d.ts +1 -0
- package/dist/elements/card.js +1 -0
- package/dist/elements/cards.d.ts +1 -0
- package/dist/elements/cards.js +1 -0
- package/dist/elements/chain-of-thought.d.ts +1 -0
- package/dist/elements/chain-of-thought.js +1 -0
- package/dist/elements/chat-scope-picker.d.ts +1 -0
- package/dist/elements/chat-scope-picker.js +1 -0
- package/dist/elements/chat-workspace.d.ts +1 -0
- package/dist/elements/chat-workspace.js +1 -0
- package/dist/elements/chat.d.ts +1 -0
- package/dist/elements/chat.js +1 -0
- package/dist/elements/checkpoint.d.ts +1 -0
- package/dist/elements/checkpoint.js +1 -0
- package/dist/elements/choice.d.ts +1 -0
- package/dist/elements/choice.js +1 -0
- package/dist/elements/chunks/Icon-D_Zmwmwh.js +1 -0
- package/dist/elements/chunks/action-icons-PVfIvcuG.js +1 -0
- package/dist/elements/chunks/attachments-Dp6vqtrc.js +1 -0
- package/dist/elements/chunks/bash-InADTalH.js +1 -0
- package/dist/elements/chunks/button-CKyYD9G4.js +1 -0
- package/dist/elements/chunks/card-Cjho-PYk.js +1 -0
- package/dist/elements/chunks/card-routing-C986KuUA.js +1 -0
- package/dist/elements/chunks/chat-thread-RT808iPf.js +1 -0
- package/dist/elements/chunks/check-CDYaMYrM.js +1 -0
- package/dist/elements/chunks/chevron-down-3SBiq8HF.js +1 -0
- package/dist/elements/chunks/chevron-right-k2UFlIVK.js +1 -0
- package/dist/elements/chunks/cn-Dogu6PbV.js +1 -0
- package/dist/elements/chunks/code-block-BYUmfFSd.js +1 -0
- package/dist/elements/chunks/collapsible-BiNwdOn6.js +1 -0
- package/dist/elements/chunks/context-18g6oi4J.js +1 -0
- package/dist/elements/chunks/conversation-list-D9Y0NVdo.js +1 -0
- package/dist/elements/chunks/core-AYMC6_lb.js +12 -0
- package/dist/elements/chunks/css-M7EaDHN_.js +1 -0
- package/dist/elements/chunks/default-input-CSAoYYMd.js +1 -0
- package/dist/elements/chunks/download-D8K0Je8r.js +1 -0
- package/dist/elements/chunks/dropdown-bUs2iTia.js +1 -0
- package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +141 -0
- package/dist/elements/chunks/external-link-6mA0wxab.js +1 -0
- package/dist/elements/chunks/file-text-DnaYk3Dm.js +1 -0
- package/dist/elements/chunks/file-tree-CgtRLlxK.js +1 -0
- package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +1 -0
- package/dist/elements/chunks/github-light-JYsPkUQd.js +1 -0
- package/dist/elements/chunks/hover-card-CIGw62gP.js +1 -0
- package/dist/elements/chunks/html-CPZ3oZQ7.js +1 -0
- package/dist/elements/chunks/index-CTBEJeo6.js +1 -0
- package/dist/elements/chunks/javascript-C25yR2R2.js +1 -0
- package/dist/elements/chunks/json-DxJze_jm.js +1 -0
- package/dist/elements/chunks/link-BlGSeoPy.js +1 -0
- package/dist/elements/chunks/loader-DvhR4qa0.js +1 -0
- package/dist/elements/chunks/markdown-CMTGx9r8.js +64 -0
- package/dist/elements/chunks/message-CDZwXjhL.js +1 -0
- package/dist/elements/chunks/message-feedback-CYx81QiA.js +1 -0
- package/dist/elements/chunks/model-switcher-O_tUhoOT.js +1 -0
- package/dist/elements/chunks/overlay-DydXYMQW.js +1 -0
- package/dist/elements/chunks/prompt-suggestion-ldlWV5kd.js +1 -0
- package/dist/elements/chunks/reasoning-2PUnHlmr.js +1 -0
- package/dist/elements/chunks/resizable-B5WNbSeb.js +1 -0
- package/dist/elements/chunks/star-t9tI-P0q.js +1 -0
- package/dist/elements/chunks/store-C6rIooZz.js +1 -0
- package/dist/elements/chunks/svelte--5p79yCD.js +1 -0
- package/dist/elements/chunks/text-shimmer-uh9V_KUh.js +1 -0
- package/dist/elements/chunks/textarea-3nm6Ia9U.js +1 -0
- package/dist/elements/chunks/thumbs-up-BBtguGld.js +1 -0
- package/dist/elements/chunks/toast-store-D8cL3fWl.js +1 -0
- package/dist/elements/chunks/tool-GJ3vwp1U.js +1 -0
- package/dist/elements/chunks/tooltip-DwKAz4XR.js +1 -0
- package/dist/elements/chunks/triangle-alert-Ct1zt2JL.js +1 -0
- package/dist/elements/chunks/tsx-B8rCNbgL.js +1 -0
- package/dist/elements/chunks/typescript-RycA9KXf.js +1 -0
- package/dist/elements/chunks/use-card-resolution-D-_0Alzy.js +1 -0
- package/dist/elements/chunks/video-mVYiM99-.js +1 -0
- package/dist/elements/chunks/vue-BmIZj4XD.js +1 -0
- package/dist/elements/chunks/x-CzxL27Ch.js +1 -0
- package/dist/elements/code-block.d.ts +1 -0
- package/dist/elements/code-block.js +1 -0
- package/dist/elements/compare.d.ts +1 -0
- package/dist/elements/compare.js +1 -0
- package/dist/elements/confirm-card.d.ts +1 -0
- package/dist/elements/confirm-card.js +1 -0
- package/dist/elements/context-meter.d.ts +1 -0
- package/dist/elements/context-meter.js +1 -0
- package/dist/elements/conversation-list.d.ts +1 -0
- package/dist/elements/conversation-list.js +1 -0
- package/dist/elements/embed.d.ts +1 -0
- package/dist/elements/embed.js +1 -0
- package/dist/elements/empty.d.ts +1 -0
- package/dist/elements/empty.js +1 -0
- package/dist/elements/feedback-bar.d.ts +1 -0
- package/dist/elements/feedback-bar.js +1 -0
- package/dist/elements/file-tree.d.ts +1 -0
- package/dist/elements/file-tree.js +1 -0
- package/dist/elements/file-upload.d.ts +1 -0
- package/dist/elements/file-upload.js +1 -0
- package/dist/elements/form.d.ts +1 -0
- package/dist/elements/form.js +1 -0
- package/dist/elements/image.d.ts +1 -0
- package/dist/elements/image.js +1 -0
- package/dist/elements/link-preview.d.ts +1 -0
- package/dist/elements/link-preview.js +1 -0
- package/dist/elements/loader.d.ts +1 -0
- package/dist/elements/loader.js +1 -0
- package/dist/elements/markdown.d.ts +1 -0
- package/dist/elements/markdown.js +1 -0
- package/dist/elements/message-skills.d.ts +1 -0
- package/dist/elements/message-skills.js +1 -0
- package/dist/elements/message.d.ts +1 -0
- package/dist/elements/message.js +1 -0
- package/dist/elements/model-switcher.d.ts +1 -0
- package/dist/elements/model-switcher.js +1 -0
- package/dist/elements/popover.d.ts +1 -0
- package/dist/elements/popover.js +1 -0
- package/dist/elements/prompt-input.d.ts +1 -0
- package/dist/elements/prompt-input.js +1 -0
- package/dist/elements/prompt-suggestions.d.ts +1 -0
- package/dist/elements/prompt-suggestions.js +1 -0
- package/dist/elements/reasoning.d.ts +1 -0
- package/dist/elements/reasoning.js +1 -0
- package/dist/elements/resizable.d.ts +1 -0
- package/dist/elements/resizable.js +1 -0
- package/dist/elements/response-stream.d.ts +1 -0
- package/dist/elements/response-stream.js +14 -0
- package/dist/elements/scroll-button.d.ts +1 -0
- package/dist/elements/scroll-button.js +1 -0
- package/dist/elements/source.d.ts +1 -0
- package/dist/elements/source.js +1 -0
- package/dist/elements/switch.d.ts +1 -0
- package/dist/elements/switch.js +1 -0
- package/dist/elements/tasks.d.ts +1 -0
- package/dist/elements/tasks.js +1 -0
- package/dist/elements/text-shimmer.d.ts +1 -0
- package/dist/elements/text-shimmer.js +1 -0
- package/dist/elements/thinking-bar.d.ts +1 -0
- package/dist/elements/thinking-bar.js +1 -0
- package/dist/elements/toast.d.ts +1 -0
- package/dist/elements/toast.js +1 -0
- package/dist/elements/tool.d.ts +1 -0
- package/dist/elements/tool.js +1 -0
- package/dist/elements/voice-input.d.ts +1 -0
- package/dist/elements/voice-input.js +1 -0
- package/dist/elements.d.ts +768 -0
- package/dist/engine-javascript-vq0WuIJl.js +2516 -14
- package/dist/github-dark-dimmed-DUshB20C.js +4 -1
- package/dist/github-light-JYsPkUQd.js +4 -1
- package/dist/html-CPZ3oZQ7.js +10 -1
- package/dist/index.d.ts +124 -2
- package/dist/index.js +15593 -0
- package/dist/javascript-C25yR2R2.js +6 -1
- package/dist/json-DxJze_jm.js +6 -1
- package/dist/kitn-chat.es.js +1 -77
- package/dist/llms/llms-full.txt +57 -12
- package/dist/llms/llms.txt +3 -3
- package/dist/mcp.es.js +2296 -0
- package/dist/primitives/card-contract.d.ts +119 -0
- package/dist/primitives/card-host.d.ts +12 -0
- package/dist/primitives/card-recovery.d.ts +55 -0
- package/dist/primitives/card-registry.d.ts +17 -0
- package/dist/primitives/card-resolution.d.ts +8 -0
- package/dist/primitives/card-routing.d.ts +12 -0
- package/dist/primitives/card-validate.d.ts +25 -0
- package/dist/primitives/chat-config.d.ts +31 -0
- package/dist/primitives/controllable.d.ts +13 -0
- package/dist/primitives/embed-providers.d.ts +65 -0
- package/dist/primitives/highlighter.d.ts +23 -0
- package/dist/primitives/link-preview.d.ts +47 -0
- package/dist/primitives/message-feedback.d.ts +35 -0
- package/dist/primitives/pdf-preview.d.ts +50 -0
- package/dist/primitives/toast-store.d.ts +88 -0
- package/dist/primitives/use-auto-resize.d.ts +8 -0
- package/dist/primitives/use-resize-observer.d.ts +1 -0
- package/dist/primitives/use-stick-to-bottom.d.ts +5 -0
- package/dist/primitives/use-text-stream.d.ts +19 -0
- package/dist/primitives/use-voice-recorder.d.ts +9 -0
- package/dist/react/index.d.ts +1198 -0
- package/dist/react/runtime.d.ts +15 -0
- package/dist/react.js +275 -0
- package/dist/register-JyTglR6m.js +1 -0
- package/dist/register-impl-C6wlSsts.js +77 -0
- package/dist/remote/host-embed.d.ts +33 -0
- package/dist/remote/index.d.ts +2 -0
- package/dist/remote/origin.d.ts +5 -0
- package/dist/remote/provider-runtime.d.ts +27 -0
- package/dist/remote/provider.d.ts +2 -0
- package/dist/remote/validate.d.ts +4 -0
- package/dist/remote/version.d.ts +4 -0
- package/dist/remote/wire.d.ts +53 -0
- package/dist/schemas/choice.schema.json +5 -0
- package/dist/schemas/tasks.schema.json +5 -0
- package/dist/svelte--5p79yCD.js +15 -1
- package/dist/tsx-B8rCNbgL.js +6 -1
- package/dist/types.d.ts +42 -0
- package/dist/typescript-RycA9KXf.js +6 -1
- package/dist/ui/action-icons.d.ts +11 -0
- package/dist/ui/avatar.d.ts +8 -0
- package/dist/ui/badge.d.ts +9 -0
- package/dist/ui/button.d.ts +10 -0
- package/dist/ui/collapsible.d.ts +27 -0
- package/dist/ui/dropdown.d.ts +20 -0
- package/dist/ui/hover-card.d.ts +28 -0
- package/dist/ui/overlay.d.ts +67 -0
- package/dist/ui/popover.d.ts +32 -0
- package/dist/ui/resizable.d.ts +76 -0
- package/dist/ui/scroll-area.d.ts +5 -0
- package/dist/ui/separator.d.ts +5 -0
- package/dist/ui/skeleton.d.ts +5 -0
- package/dist/ui/switch.d.ts +19 -0
- package/dist/ui/textarea.d.ts +6 -0
- package/dist/ui/tooltip.d.ts +9 -0
- package/dist/utils/cn.d.ts +2 -0
- package/dist/vue-BmIZj4XD.js +33 -1
- package/frameworks/react/index.tsx +67 -11
- package/frameworks/react/runtime.tsx +16 -2
- package/llms-full.txt +57 -12
- package/llms.txt +3 -3
- package/package.json +36 -14
- package/src/agent-tooling/archetypes.ts +46 -0
- package/src/agent-tooling/integrations/cloudflare.ts +88 -0
- package/src/agent-tooling/integrations/langgraph.ts +60 -0
- package/src/agent-tooling/integrations/mastra.ts +27 -0
- package/src/agent-tooling/integrations/mock.ts +34 -0
- package/src/agent-tooling/integrations/ollama.ts +47 -0
- package/src/agent-tooling/integrations/openrouter.ts +26 -0
- package/src/agent-tooling/integrations/pi.ts +40 -0
- package/src/agent-tooling/integrations/pydantic-ai.ts +52 -0
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +44 -0
- package/src/agent-tooling/mcp/manifest.ts +128 -0
- package/src/agent-tooling/mcp/server.ts +59 -0
- package/src/agent-tooling/mcp/stdio.ts +18 -0
- package/src/agent-tooling/mcp/tools/debug.ts +489 -0
- package/src/agent-tooling/mcp/tools/reference.ts +132 -0
- package/src/agent-tooling/mcp/tools/scaffold.ts +1759 -0
- package/src/agent-tooling/mcp/tools/theme.ts +340 -0
- package/src/agent-tooling/mcp/tools/types.ts +14 -0
- package/src/agent-tooling/registry.ts +41 -0
- package/src/agent-tooling/types.ts +30 -0
- package/src/components/chat-thread.tsx +27 -35
- package/src/components/choice-card.tsx +33 -4
- package/src/components/component-meta.json +250 -26
- package/src/components/confirm-card.tsx +15 -1
- package/src/components/dismissed-stub.tsx +80 -0
- package/src/components/form.tsx +21 -3
- package/src/components/message.tsx +151 -10
- package/src/components/response-compare-types.ts +127 -0
- package/src/components/response-compare.tsx +431 -0
- package/src/components/tasks-card.tsx +33 -3
- package/src/components/toast.tsx +398 -0
- package/src/components/use-card-resolution.ts +24 -8
- package/src/elements/autoloader.ts +89 -0
- package/src/elements/chat-types.ts +7 -0
- package/src/elements/chat-workspace.tsx +4 -2
- package/src/elements/chat.tsx +4 -2
- package/src/elements/compare.tsx +88 -0
- package/src/elements/compiled.css +1 -1
- package/src/elements/define.tsx +7 -1
- package/src/elements/element-manifest.json +182 -0
- package/src/elements/element-meta.json +191 -68
- package/src/elements/element-types.d.ts +43 -6
- package/src/elements/framework-usage.json +25 -0
- package/src/elements/message.tsx +27 -45
- package/src/elements/register-impl.ts +58 -0
- package/src/elements/register.ts +26 -51
- package/src/elements/remote.tsx +4 -0
- package/src/elements/styles.css +19 -0
- package/src/elements/toast.tsx +74 -0
- package/src/index.ts +30 -0
- package/src/primitives/card-contract.ts +14 -5
- package/src/primitives/card-recovery.ts +149 -0
- package/src/primitives/card-routing.ts +3 -0
- package/src/primitives/card-schemas/choice.schema.json +5 -0
- package/src/primitives/card-schemas/tasks.schema.json +5 -0
- package/src/primitives/message-feedback.ts +123 -0
- package/src/primitives/toast-store.ts +235 -0
- package/src/ui/tooltip.tsx +8 -2
- package/theme.css +4 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** Bumped on any BREAKING change to the shapes below. Additive/optional fields do not bump it. */
|
|
2
|
+
export declare const CARD_CONTRACT_VERSION: "1";
|
|
3
|
+
/** A card the agent/server asks the chat to render. `data` conforms to the card
|
|
4
|
+
* type's own published JSON Schema (one schema per `type`). */
|
|
5
|
+
export interface CardEnvelope<TType extends string = string, TData = unknown> {
|
|
6
|
+
type: TType;
|
|
7
|
+
id: string;
|
|
8
|
+
data: TData;
|
|
9
|
+
title?: string;
|
|
10
|
+
/** Set when the user has resolved this card; renders the chromed read-only view. */
|
|
11
|
+
resolution?: CardResolution;
|
|
12
|
+
}
|
|
13
|
+
/** Context the host pushes to every card; updated when it changes (theme, etc.). */
|
|
14
|
+
export interface CardContext {
|
|
15
|
+
theme: {
|
|
16
|
+
mode: 'light' | 'dark';
|
|
17
|
+
tokens?: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
locale: string;
|
|
20
|
+
conversationId?: string;
|
|
21
|
+
/** Remote (iframe) cards only: short-lived signed token. Never long-lived. */
|
|
22
|
+
authToken?: string;
|
|
23
|
+
/** Host-resolved a11y prefs (e.g. reduced-motion, which doesn't cross the iframe). */
|
|
24
|
+
a11y?: {
|
|
25
|
+
reducedMotion?: boolean;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Everything a card can ask the host to do. The host authorizes + routes each. */
|
|
29
|
+
export type CardEvent = {
|
|
30
|
+
kind: 'ready';
|
|
31
|
+
cardId: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'submit';
|
|
34
|
+
cardId: string;
|
|
35
|
+
data: unknown;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'action';
|
|
38
|
+
cardId: string;
|
|
39
|
+
action: string;
|
|
40
|
+
payload?: unknown;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'send-prompt';
|
|
43
|
+
cardId: string;
|
|
44
|
+
text: string;
|
|
45
|
+
mode?: 'compose' | 'send';
|
|
46
|
+
context?: unknown;
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'open';
|
|
49
|
+
cardId: string;
|
|
50
|
+
url: string;
|
|
51
|
+
target?: 'tab' | 'artifact';
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'resize';
|
|
54
|
+
cardId: string;
|
|
55
|
+
height: number;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'state';
|
|
58
|
+
cardId: string;
|
|
59
|
+
patch: unknown;
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'dismiss';
|
|
62
|
+
cardId: string;
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'reopen';
|
|
65
|
+
cardId: string;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'error';
|
|
68
|
+
cardId: string;
|
|
69
|
+
message: string;
|
|
70
|
+
};
|
|
71
|
+
export type CardEventKind = CardEvent['kind'];
|
|
72
|
+
/** How a card was resolved by the user — the re-hydration channel for the chromed
|
|
73
|
+
* read-only state. The terminal kinds (`action`/`submit`) mirror the two terminal
|
|
74
|
+
* CardEvents (minus `cardId`): the resolution is just the event that resolved the
|
|
75
|
+
* card. `dismissed` is a DEFERRED (non-terminal) state — the user set the card
|
|
76
|
+
* aside; it can be re-opened. `expired` is terminal — a dismissed card the host
|
|
77
|
+
* decided can no longer be re-opened (e.g. the agent proceeded, or it went stale).
|
|
78
|
+
* `at` is optional ISO-8601 provenance (data only; never rendered). Additive —
|
|
79
|
+
* does not bump the contract version. */
|
|
80
|
+
export type CardResolution = {
|
|
81
|
+
kind: 'action';
|
|
82
|
+
action: string;
|
|
83
|
+
payload?: unknown;
|
|
84
|
+
at?: string;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'submit';
|
|
87
|
+
data: unknown;
|
|
88
|
+
at?: string;
|
|
89
|
+
} | {
|
|
90
|
+
kind: 'dismissed';
|
|
91
|
+
at?: string;
|
|
92
|
+
} | {
|
|
93
|
+
kind: 'expired';
|
|
94
|
+
reason?: string;
|
|
95
|
+
at?: string;
|
|
96
|
+
};
|
|
97
|
+
/** What every card is handed (via native context or the iframe bridge). */
|
|
98
|
+
export interface CardHost {
|
|
99
|
+
context(): CardContext;
|
|
100
|
+
emit(event: CardEvent): void;
|
|
101
|
+
}
|
|
102
|
+
/** How the host routes each verb. Consumers supply handlers; defaults applied otherwise. */
|
|
103
|
+
export interface CardPolicy {
|
|
104
|
+
onSubmit?: (cardId: string, data: unknown) => void;
|
|
105
|
+
onAction?: (cardId: string, action: string, payload?: unknown) => void;
|
|
106
|
+
onSendPrompt?: (text: string, opts: {
|
|
107
|
+
mode: 'compose' | 'send';
|
|
108
|
+
context?: unknown;
|
|
109
|
+
}) => void;
|
|
110
|
+
onOpen?: (url: string, target: 'tab' | 'artifact') => void;
|
|
111
|
+
onState?: (cardId: string, patch: unknown) => void;
|
|
112
|
+
onDismiss?: (cardId: string) => void;
|
|
113
|
+
/** A dismissed card asked to be re-opened. The host decides whether it can come
|
|
114
|
+
* back (clear the resolution → live again) or has expired (stamp `expired`). */
|
|
115
|
+
onReopen?: (cardId: string) => void;
|
|
116
|
+
onError?: (cardId: string, message: string) => void;
|
|
117
|
+
/** Cap on send-prompt: 'compose' (default) forbids silent sends. 'send' to allow. */
|
|
118
|
+
maxSendPromptMode?: 'compose' | 'send';
|
|
119
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
import { CardContext, CardHost, CardPolicy } from './card-contract';
|
|
3
|
+
export interface CardProviderProps {
|
|
4
|
+
/** Ambient context, static or a reactive getter. */
|
|
5
|
+
context: CardContext | (() => CardContext);
|
|
6
|
+
/** Routing policy applied to every emitted event. */
|
|
7
|
+
policy?: CardPolicy;
|
|
8
|
+
children: JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
export declare function CardProvider(props: CardProviderProps): JSX.Element;
|
|
11
|
+
/** Read the current CardHost. `undefined` when no provider is present (bare card). */
|
|
12
|
+
export declare function useCardHost(): CardHost | undefined;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CardEnvelope, CardPolicy, CardResolution } from './card-contract';
|
|
2
|
+
/** The minimal toast surface this helper needs. Inject a real adapter (e.g. one
|
|
3
|
+
* backed by `kai-toast-region`) — this module never imports the toast itself. */
|
|
4
|
+
export interface RecoveryToast {
|
|
5
|
+
show(opts: {
|
|
6
|
+
message: string;
|
|
7
|
+
action?: {
|
|
8
|
+
label: string;
|
|
9
|
+
onClick: () => void;
|
|
10
|
+
};
|
|
11
|
+
durationMs?: number;
|
|
12
|
+
}): {
|
|
13
|
+
dismiss(): void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** Context handed to a custom `isReopenable` predicate. */
|
|
17
|
+
export interface ReopenEnv {
|
|
18
|
+
cardId: string;
|
|
19
|
+
/** The card's current resolution at reopen time (should be `dismissed`). */
|
|
20
|
+
resolution: CardResolution | undefined;
|
|
21
|
+
/** `Date.now()` at reopen time (injected for testability). */
|
|
22
|
+
now: number;
|
|
23
|
+
}
|
|
24
|
+
export interface DismissRecoveryOptions {
|
|
25
|
+
/** Read the current cards array. */
|
|
26
|
+
get: () => CardEnvelope[];
|
|
27
|
+
/** Write the next cards array (a NEW reference). */
|
|
28
|
+
set: (next: CardEnvelope[]) => void;
|
|
29
|
+
/** Optional injected toast adapter for the "Dismissed · Undo" affordance. */
|
|
30
|
+
toast?: RecoveryToast;
|
|
31
|
+
/** Override the default re-openable rule. Return false to expire instead. */
|
|
32
|
+
isReopenable?: (env: ReopenEnv) => boolean;
|
|
33
|
+
/** A dismissed card older than this (ms since `dismissed.at`) is no longer
|
|
34
|
+
* re-openable (→ expired). Omit/Infinity = never stale. */
|
|
35
|
+
staleAfterMs?: number;
|
|
36
|
+
/** Auto-dismiss the Undo toast after this long. Default 6000ms. */
|
|
37
|
+
undoMs?: number;
|
|
38
|
+
/** Injected clock (defaults to Date.now); keeps the helper testable. */
|
|
39
|
+
now?: () => number;
|
|
40
|
+
}
|
|
41
|
+
/** Default re-openable rule: a card can come back unless it carries a terminal
|
|
42
|
+
* resolution OR it has gone stale (`staleAfterMs` elapsed since `dismissed.at`).
|
|
43
|
+
* A `dismissed` card with no/invalid `at` is always re-openable. */
|
|
44
|
+
export declare function defaultIsReopenable(env: ReopenEnv, staleAfterMs?: number): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Build the `{ onDismiss, onReopen }` policy handlers for the card dismiss/recovery
|
|
47
|
+
* flow over a host store (`get`/`set`).
|
|
48
|
+
*
|
|
49
|
+
* - `onDismiss(cardId)` — stamps `{ kind:'dismissed', at }` immutably and, when a
|
|
50
|
+
* `toast` is injected, shows "Dismissed" with an Undo that restores the card's
|
|
51
|
+
* prior resolution (live again when there was none).
|
|
52
|
+
* - `onReopen(cardId)` — clears the resolution (live) when `isReopenable`, else
|
|
53
|
+
* stamps `{ kind:'expired', at }`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function dismissRecovery(opts: DismissRecoveryOptions): Pick<CardPolicy, 'onDismiss' | 'onReopen'>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component } from 'solid-js';
|
|
2
|
+
import { CardEnvelope, CardHost } from './card-contract';
|
|
3
|
+
/** Solid renderer for one envelope. `host` is the resolved CardHost so each wrapper
|
|
4
|
+
* can bridge its card's emit convention (form/confirm/tasks take `host`;
|
|
5
|
+
* link/embed take `onEmit`). */
|
|
6
|
+
export type CardComponent = Component<{
|
|
7
|
+
envelope: CardEnvelope;
|
|
8
|
+
host?: CardHost;
|
|
9
|
+
}>;
|
|
10
|
+
export type CardComponentMap = Record<string, CardComponent>;
|
|
11
|
+
/** Web-component layer: envelope type → kai-* tag name. */
|
|
12
|
+
export type CardTagMap = Record<string, string>;
|
|
13
|
+
export declare const BUILTIN_CARD_TAGS: CardTagMap;
|
|
14
|
+
export declare const BUILTIN_CARD_COMPONENTS: CardComponentMap;
|
|
15
|
+
/** Built-ins with the consumer's overrides merged on top (consumer wins). */
|
|
16
|
+
export declare function mergeCardComponents(types?: CardComponentMap): CardComponentMap;
|
|
17
|
+
export declare function mergeCardTags(types?: CardTagMap): CardTagMap;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CardEnvelope, CardEvent, CardResolution } from './card-contract';
|
|
2
|
+
/** Map a terminal CardEvent (`action` | `submit`) to a CardResolution.
|
|
3
|
+
* Returns undefined for every non-terminal verb (ready/error/resize/state/…). */
|
|
4
|
+
export declare function resolutionFromEvent(event: CardEvent): CardResolution | undefined;
|
|
5
|
+
/** Return a new cards array with the envelope matching `event.cardId` stamped with its
|
|
6
|
+
* resolution. Non-terminal events or an unknown cardId return the SAME array reference
|
|
7
|
+
* (cheap no-op; safe to call on every event). Never mutates the input. */
|
|
8
|
+
export declare function applyResolution(cards: CardEnvelope[], event: CardEvent): CardEnvelope[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CardEvent, CardPolicy } from './card-contract';
|
|
2
|
+
/** The single contract event name. */
|
|
3
|
+
export declare const CARD_EVENT_NAME = "kai-card";
|
|
4
|
+
/** Dispatch a CardEvent as the bubbling, composed `kai-card` event a host listener
|
|
5
|
+
* routes. NB: this is deliberately different from defineWebComponent's built-in
|
|
6
|
+
* non-bubbling dispatch. */
|
|
7
|
+
export declare function emitCardEvent(element: HTMLElement, event: CardEvent): void;
|
|
8
|
+
/** Apply the contract's policy to one event. The ONE place routing lives. */
|
|
9
|
+
export declare function routeCardEvent(policy: CardPolicy | undefined, event: CardEvent): void;
|
|
10
|
+
/** Attach a host-level `kai-card` listener that routes every bubbling card event
|
|
11
|
+
* through `policy`. Returns an unsubscribe fn. For the bare-element path. */
|
|
12
|
+
export declare function listenForCardEvents(root: HTMLElement | Document, policy: CardPolicy): () => void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface JsonSchema {
|
|
2
|
+
type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';
|
|
3
|
+
const?: unknown;
|
|
4
|
+
enum?: unknown[];
|
|
5
|
+
required?: string[];
|
|
6
|
+
properties?: Record<string, JsonSchema>;
|
|
7
|
+
items?: JsonSchema;
|
|
8
|
+
minimum?: number;
|
|
9
|
+
maximum?: number;
|
|
10
|
+
exclusiveMinimum?: number;
|
|
11
|
+
exclusiveMaximum?: number;
|
|
12
|
+
minLength?: number;
|
|
13
|
+
maxLength?: number;
|
|
14
|
+
pattern?: string;
|
|
15
|
+
minItems?: number;
|
|
16
|
+
maxItems?: number;
|
|
17
|
+
uniqueItems?: boolean;
|
|
18
|
+
[key: `x-${string}`]: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface ValidationResult {
|
|
21
|
+
valid: boolean;
|
|
22
|
+
errors: string[];
|
|
23
|
+
}
|
|
24
|
+
/** Validate `value` against the lean JSON-Schema subset. */
|
|
25
|
+
export declare function validateAgainstSchema(schema: JsonSchema, value: unknown): ValidationResult;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Accessor, JSX } from 'solid-js';
|
|
2
|
+
export type ProseSize = 'xs' | 'sm' | 'base' | 'lg';
|
|
3
|
+
export interface ChatConfigValue {
|
|
4
|
+
/** Prose/text size for messages, markdown, and UI elements */
|
|
5
|
+
proseSize: Accessor<ProseSize>;
|
|
6
|
+
/** Shiki theme for code blocks */
|
|
7
|
+
codeTheme: Accessor<string>;
|
|
8
|
+
/** Node the kit's overlays portal into; undefined → document.body */
|
|
9
|
+
portalMount: Accessor<HTMLElement | undefined>;
|
|
10
|
+
/** Whether code blocks are syntax-highlighted; false → plain text, no Shiki loaded */
|
|
11
|
+
codeHighlight: Accessor<boolean>;
|
|
12
|
+
}
|
|
13
|
+
export interface ChatConfigProps {
|
|
14
|
+
proseSize?: ProseSize;
|
|
15
|
+
codeTheme?: string;
|
|
16
|
+
portalMount?: HTMLElement;
|
|
17
|
+
codeHighlight?: boolean;
|
|
18
|
+
children: JSX.Element;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Provides chat-wide appearance settings to all child components.
|
|
22
|
+
* Set once at the top level — MessageContent, Markdown, CodeBlock,
|
|
23
|
+
* ConversationList, and PromptInput all read from this.
|
|
24
|
+
*/
|
|
25
|
+
export declare function ChatConfig(props: ChatConfigProps): JSX.Element;
|
|
26
|
+
/** Read the current chat config. Returns defaults if no provider is present. */
|
|
27
|
+
export declare function useChatConfig(): ChatConfigValue;
|
|
28
|
+
/** Maps prose size to Tailwind prose class */
|
|
29
|
+
export declare function proseClass(size: ProseSize): string;
|
|
30
|
+
/** Maps prose size to a text class for non-prose elements (sidebar, input) */
|
|
31
|
+
export declare function textClass(size: ProseSize): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Accessor } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* The controlled/uncontrolled state pattern, as a reusable signal.
|
|
4
|
+
*
|
|
5
|
+
* `controlled` is an accessor for the controlling prop: when it returns a value,
|
|
6
|
+
* that value wins (controlled mode); when it returns `undefined`, the component
|
|
7
|
+
* manages its own state seeded from `initial` (uncontrolled mode). The returned
|
|
8
|
+
* setter always writes the internal value — harmless (masked) while controlled,
|
|
9
|
+
* authoritative while uncontrolled — so a single call site works in both modes.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors `props.value ?? internal()` used elsewhere in the kit, without effects.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createControllableSignal(controlled: Accessor<boolean | undefined>, initial: boolean): [Accessor<boolean>, (value: boolean) => void];
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CardEnvelope } from './card-contract';
|
|
2
|
+
/** Media provider for an embed card. */
|
|
3
|
+
export type EmbedProvider = 'youtube' | 'vimeo' | 'generic';
|
|
4
|
+
/** Lazy media-embed payload (YouTube / Vimeo / generic player URL). */
|
|
5
|
+
export interface EmbedCardData {
|
|
6
|
+
/** Media provider. 'generic' frames `url` directly. */
|
|
7
|
+
provider: EmbedProvider;
|
|
8
|
+
/** Provider video id (youtube/vimeo) when not parsing from `url`. */
|
|
9
|
+
id?: string;
|
|
10
|
+
/** Full media/watch/embed URL. */
|
|
11
|
+
url?: string;
|
|
12
|
+
/** Accessible iframe title + poster label. */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Thumbnail before play; derived for youtube/vimeo when omitted. */
|
|
15
|
+
poster?: string;
|
|
16
|
+
/** Start offset, seconds. */
|
|
17
|
+
start?: number;
|
|
18
|
+
/** Player aspect ratio. Default '16:9'. */
|
|
19
|
+
aspectRatio?: '16:9' | '4:3' | '1:1' | '9:16';
|
|
20
|
+
}
|
|
21
|
+
/** The full envelope an agent/server emits for an embed card. */
|
|
22
|
+
export type EmbedCardEnvelope = CardEnvelope<'embed', EmbedCardData>;
|
|
23
|
+
/** The `type` discriminator for embed cards. */
|
|
24
|
+
export declare const EMBED_CARD_TYPE: "embed";
|
|
25
|
+
export interface ResolvedEmbed {
|
|
26
|
+
/** The iframe src loaded on play (already including autoplay/start params). */
|
|
27
|
+
embedUrl: string;
|
|
28
|
+
/** Poster/thumbnail to show before play (derived when not supplied). */
|
|
29
|
+
posterUrl?: string;
|
|
30
|
+
/** sandbox attribute for the player iframe. */
|
|
31
|
+
sandbox: string;
|
|
32
|
+
/** allow attribute (fullscreen, encrypted-media, picture-in-picture, …). */
|
|
33
|
+
allow: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* App opt-in: allow `generic` embeds whose origin is in this list. Origins are
|
|
37
|
+
* normalized via the URL parser (scheme + host + port). Only https origins are
|
|
38
|
+
* accepted (a non-https origin is ignored). Call once at app startup.
|
|
39
|
+
*/
|
|
40
|
+
export declare function configureEmbedAllowlist(origins: string[]): void;
|
|
41
|
+
/** True when `url`'s origin has been allowlisted for `generic` embeds. */
|
|
42
|
+
export declare function isGenericOriginAllowed(url: string): boolean;
|
|
43
|
+
/** Test-only: clear the generic allowlist so tests stay isolated. */
|
|
44
|
+
export declare function __resetEmbedAllowlistForTests(): void;
|
|
45
|
+
/** Extract a YouTube id from a watch / youtu.be / shorts / embed URL. */
|
|
46
|
+
export declare function parseYouTubeId(url: string): string | undefined;
|
|
47
|
+
/** Extract a Vimeo id from a vimeo.com/<id> (or player.vimeo.com/video/<id>) URL. */
|
|
48
|
+
export declare function parseVimeoId(url: string): string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve an EmbedCardData to an embeddable player URL + poster + sandbox/allow.
|
|
51
|
+
* Throws (with a human message) on a missing/invalid provider id, a non-https
|
|
52
|
+
* generic URL, or a generic origin not in the app allowlist — the card turns these
|
|
53
|
+
* into an inline error + an `error` event.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveEmbed(data: EmbedCardData): ResolvedEmbed;
|
|
56
|
+
/**
|
|
57
|
+
* The canonical "watch on the provider" URL for the optional fallback affordance
|
|
58
|
+
* (emitted as `open`/target:'tab' when an embed is blocked). Returns `undefined`
|
|
59
|
+
* when there is nothing useful to link to.
|
|
60
|
+
*/
|
|
61
|
+
export declare function watchUrl(data: EmbedCardData): string | undefined;
|
|
62
|
+
/** Human-readable provider label for the fallback affordance ("Open on YouTube"). */
|
|
63
|
+
export declare function providerLabel(provider: EmbedProvider): string;
|
|
64
|
+
/** CSS aspect-ratio value for a card's aspectRatio (default 16:9). */
|
|
65
|
+
export declare function aspectRatioValue(aspectRatio: EmbedCardData['aspectRatio']): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type Loader = () => Promise<unknown>;
|
|
2
|
+
export interface CodeHighlightingOptions {
|
|
3
|
+
/** Turn highlighting on/off globally. When false, code renders as plain text. */
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
/** Register/override language loaders, e.g. `{ ruby: () => import('@shikijs/langs/ruby') }`. */
|
|
6
|
+
languages?: Record<string, Loader>;
|
|
7
|
+
/** Register/override theme loaders. */
|
|
8
|
+
themes?: Record<string, Loader>;
|
|
9
|
+
/** Map short names to canonical language keys, e.g. `{ vue: 'html' }`. */
|
|
10
|
+
aliases?: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Highlight `code` as `lang` with `theme`, returning HTML. Loads only what's
|
|
14
|
+
* needed, on demand. Falls back to escaped plain `<pre><code>` when highlighting
|
|
15
|
+
* is disabled, the language has no registered loader, or anything fails.
|
|
16
|
+
*/
|
|
17
|
+
export declare function highlight(code: string, lang: string, theme: string): Promise<string>;
|
|
18
|
+
/** Register additional languages/themes/aliases, or disable highlighting entirely. */
|
|
19
|
+
export declare function configureCodeHighlighting(options: CodeHighlightingOptions): void;
|
|
20
|
+
export declare function isCodeHighlightingEnabled(): boolean;
|
|
21
|
+
/** Test helper — reset the singleton and registries to defaults. */
|
|
22
|
+
export declare function __resetCodeHighlightingForTests(): void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { CardEnvelope } from './card-contract';
|
|
2
|
+
/** Rich link / Open-Graph preview payload. The card renders from this; it never fetches. */
|
|
3
|
+
export interface LinkPreviewData {
|
|
4
|
+
/** Canonical destination; opened via the contract `open` verb. */
|
|
5
|
+
url: string;
|
|
6
|
+
/** og:title — falls back to the domain. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** og:description — clamped to 3 lines. */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** og:image — degrades gracefully when missing/broken. */
|
|
11
|
+
image?: string;
|
|
12
|
+
/** Alt for the preview image (defaults to title / decorative). */
|
|
13
|
+
imageAlt?: string;
|
|
14
|
+
/** Site favicon. */
|
|
15
|
+
favicon?: string;
|
|
16
|
+
/** Display domain; derived from `url` when omitted. */
|
|
17
|
+
domain?: string;
|
|
18
|
+
/** og:site_name; preferred over `domain` when present. */
|
|
19
|
+
siteName?: string;
|
|
20
|
+
}
|
|
21
|
+
/** The full envelope an agent/server emits for a link preview card. */
|
|
22
|
+
export type LinkPreviewEnvelope = CardEnvelope<'link', LinkPreviewData>;
|
|
23
|
+
/** The `type` discriminator for link preview cards. */
|
|
24
|
+
export declare const LINK_PREVIEW_TYPE: "link";
|
|
25
|
+
/** App-supplied resolver: a bare URL → (partial) OG metadata. Usually hits YOUR backend. */
|
|
26
|
+
export type LinkMetadataFetcher = (url: string) => Promise<Partial<LinkPreviewData>>;
|
|
27
|
+
/**
|
|
28
|
+
* App opt-in: supply a function (usually hitting YOUR backend/proxy) that resolves
|
|
29
|
+
* a bare URL to OG metadata. CORS forbids reading cross-origin HTML in the browser,
|
|
30
|
+
* so there is intentionally NO default network implementation.
|
|
31
|
+
*/
|
|
32
|
+
export declare function configureLinkPreview(opts: {
|
|
33
|
+
fetchMetadata: LinkMetadataFetcher;
|
|
34
|
+
}): void;
|
|
35
|
+
/** True when an app has registered a fetcher (the bare-URL path is available). */
|
|
36
|
+
export declare function hasLinkPreviewFetcher(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Used by LinkPreview ONLY when the envelope lacks metadata AND a fetcher is set.
|
|
39
|
+
* Returns the merged metadata or throws (card shows its fallback/error state).
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveLinkMetadata(url: string): Promise<Partial<LinkPreviewData>>;
|
|
42
|
+
/** Test-only: clear the configured fetcher so tests stay isolated. */
|
|
43
|
+
export declare function __resetLinkPreviewForTests(): void;
|
|
44
|
+
/** Derive a clean display domain from a URL (strips a leading `www.`). `undefined` if unparseable. */
|
|
45
|
+
export declare function deriveDomain(url: string): string | undefined;
|
|
46
|
+
/** True when `url` is a syntactically valid http(s) URL (the only renderable link schemes). */
|
|
47
|
+
export declare function isRenderableLink(url: string): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ChatMessage, FeedbackVote } from '../elements/chat-types';
|
|
2
|
+
/** Detail shape emitted by the action row. `state` is present only for the
|
|
3
|
+
* toggleable feedback votes: `'on'` when a vote is set, `'off'` when cleared.
|
|
4
|
+
* Copy / regenerate / edit / custom actions omit it. */
|
|
5
|
+
export interface MessageActionDetail {
|
|
6
|
+
messageId: string;
|
|
7
|
+
action: string;
|
|
8
|
+
state?: 'on' | 'off';
|
|
9
|
+
}
|
|
10
|
+
export interface MessageFeedbackOptions {
|
|
11
|
+
/** Emit the `kai-message-action` detail (facade maps this to `dispatch` /
|
|
12
|
+
* `onMessageAction`). */
|
|
13
|
+
emit: (detail: MessageActionDetail) => void;
|
|
14
|
+
/** How long the copy check stays before auto-clearing. Defaults to 2000ms. */
|
|
15
|
+
copiedDuration?: number;
|
|
16
|
+
/** Container the copy/feedback toasts should be scoped to (the chat, by
|
|
17
|
+
* default) so they appear in-chat rather than at the page top. */
|
|
18
|
+
target?: () => HTMLElement | undefined;
|
|
19
|
+
}
|
|
20
|
+
export interface MessageFeedback {
|
|
21
|
+
/** Resolve the active vote for a message: a controlled `m.feedback` wins,
|
|
22
|
+
* else the facade's own optimistic map. */
|
|
23
|
+
resolveFeedback: (m: Pick<ChatMessage, 'id' | 'feedback'>) => FeedbackVote | undefined;
|
|
24
|
+
/** Whether a message's copy button should currently show its check. */
|
|
25
|
+
isCopied: (id: string) => boolean;
|
|
26
|
+
/** Route a clicked action through copy / vote / passthrough handling. */
|
|
27
|
+
handleAction: (m: Pick<ChatMessage, 'id' | 'content' | 'feedback'>, action: string) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create the action-row feedback controller for one message list (or one
|
|
31
|
+
* standalone message). Owns the optimistic `feedbackMap` + transient
|
|
32
|
+
* `copiedIds`, resolves the controlled-wins vote, and turns clicks into
|
|
33
|
+
* clipboard writes, toasts, and `kai-message-action` emissions.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createMessageFeedback(opts: MessageFeedbackOptions): MessageFeedback;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Minimal shape of the pdf.js module + objects we rely on. */
|
|
2
|
+
export interface PdfViewportLike {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
}
|
|
6
|
+
export interface PdfPageLike {
|
|
7
|
+
getViewport(opts: {
|
|
8
|
+
scale: number;
|
|
9
|
+
}): PdfViewportLike;
|
|
10
|
+
render(opts: {
|
|
11
|
+
canvasContext: CanvasRenderingContext2D | null;
|
|
12
|
+
viewport: PdfViewportLike;
|
|
13
|
+
}): {
|
|
14
|
+
promise: Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface PdfDocumentLike {
|
|
18
|
+
numPages: number;
|
|
19
|
+
getPage(n: number): Promise<PdfPageLike>;
|
|
20
|
+
}
|
|
21
|
+
export interface PdfjsLike {
|
|
22
|
+
getDocument(src: {
|
|
23
|
+
url: string;
|
|
24
|
+
}): {
|
|
25
|
+
promise: Promise<PdfDocumentLike>;
|
|
26
|
+
};
|
|
27
|
+
GlobalWorkerOptions: {
|
|
28
|
+
workerSrc: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface PdfPreviewOptions {
|
|
32
|
+
/** Turn inline PDF rendering on/off globally. When false, always show the card. */
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
/** Override the pdf.js module loader (self-host / CSP / version pin). */
|
|
35
|
+
load?: () => Promise<PdfjsLike>;
|
|
36
|
+
/** Worker URL. Default = the matching jsDelivr worker for the pinned version. */
|
|
37
|
+
workerSrc?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function configurePdfPreview(options: PdfPreviewOptions): void;
|
|
40
|
+
export declare function isPdfPreviewEnabled(): boolean;
|
|
41
|
+
export declare function __resetPdfPreviewForTests(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Render EVERY page of the PDF at `url` into `container` as stacked <canvas>
|
|
44
|
+
* elements fit to `pxWidth` CSS pixels (rendered at devicePixelRatio for
|
|
45
|
+
* crispness). Clears `container` first. Resolves `{ pages }`. THROWS on
|
|
46
|
+
* load / CORS / parse failure — the caller catches and shows the fallback card.
|
|
47
|
+
*/
|
|
48
|
+
export declare function renderPdfInto(url: string, container: HTMLElement, pxWidth: number): Promise<{
|
|
49
|
+
pages: number;
|
|
50
|
+
}>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ToastPosition } from '../components/toast';
|
|
2
|
+
export type ToastVariant = 'neutral' | 'success';
|
|
3
|
+
export interface ToastConfig {
|
|
4
|
+
stack?: 'expanded' | 'collapsed';
|
|
5
|
+
position?: ToastPosition;
|
|
6
|
+
max?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Configure the imperative `toast()` singleton — call once at app start.
|
|
10
|
+
* `toast.success('…')` has no element to set a prop on, so this is how you opt
|
|
11
|
+
* the auto-mounted region into collapsed stacking / a position / a max. Updates
|
|
12
|
+
* any already-mounted regions too, so call order doesn't matter.
|
|
13
|
+
*/
|
|
14
|
+
export declare function configureToasts(config: ToastConfig): void;
|
|
15
|
+
/** An action button rendered inside the toast. Returning `false` from
|
|
16
|
+
* `onAction` keeps the toast open (e.g. to show a follow-up); any other
|
|
17
|
+
* return value dismisses it. */
|
|
18
|
+
export interface ToastAction {
|
|
19
|
+
label: string;
|
|
20
|
+
onAction: () => void | false;
|
|
21
|
+
}
|
|
22
|
+
export interface ToastItem {
|
|
23
|
+
id: string;
|
|
24
|
+
message: string;
|
|
25
|
+
variant?: ToastVariant;
|
|
26
|
+
action?: ToastAction;
|
|
27
|
+
/** Auto-dismiss delay in ms. `0` = sticky (never auto-dismisses). When an
|
|
28
|
+
* `action` is present the effective floor is 4000ms so it stays long enough
|
|
29
|
+
* to act on. Defaults to 2000ms. */
|
|
30
|
+
duration?: number;
|
|
31
|
+
/** Whether the × close affordance is shown. Defaults to `true`. */
|
|
32
|
+
dismissible?: boolean;
|
|
33
|
+
/** Container to scope this toast WITHIN — it floats anchored to that element's
|
|
34
|
+
* bounds instead of the viewport. Omit for a global, viewport-anchored toast.
|
|
35
|
+
* The chat targets itself by default so its copy/feedback toasts stay in-chat. */
|
|
36
|
+
target?: HTMLElement;
|
|
37
|
+
}
|
|
38
|
+
/** Options accepted by `toast()` — everything but the message. Pass `id` to
|
|
39
|
+
* update an existing toast in place. */
|
|
40
|
+
export interface ToastOptions {
|
|
41
|
+
id?: string;
|
|
42
|
+
variant?: ToastVariant;
|
|
43
|
+
action?: ToastAction;
|
|
44
|
+
duration?: number;
|
|
45
|
+
dismissible?: boolean;
|
|
46
|
+
/** Scope this toast to a container's bounds (e.g. a chat) instead of the
|
|
47
|
+
* viewport. Omit for a global, viewport-anchored toast. */
|
|
48
|
+
target?: HTMLElement;
|
|
49
|
+
}
|
|
50
|
+
/** Handle returned from `toast()` for imperative control. */
|
|
51
|
+
export interface ToastHandle {
|
|
52
|
+
id: string;
|
|
53
|
+
dismiss: () => void;
|
|
54
|
+
update: (patch: Partial<Omit<ToastItem, 'id'>>) => void;
|
|
55
|
+
}
|
|
56
|
+
/** Default auto-dismiss delay. Long enough to read + reach before it leaves. */
|
|
57
|
+
export declare const DEFAULT_TOAST_DURATION = 5000;
|
|
58
|
+
/** Minimum auto-dismiss delay when the toast carries an action (e.g. Undo) — it
|
|
59
|
+
* has to stay up long enough to actually act on. */
|
|
60
|
+
export declare const ACTION_TOAST_FLOOR = 7000;
|
|
61
|
+
/** The live toast list (reactive). The region facade binds to this. */
|
|
62
|
+
export declare function getToasts(): ToastItem[];
|
|
63
|
+
/** Resolve the effective duration, applying the action floor. */
|
|
64
|
+
declare function resolveDuration(item: Pick<ToastItem, 'duration' | 'action'>): number;
|
|
65
|
+
export declare function ensureMounted(target?: HTMLElement | null): HTMLElement | undefined;
|
|
66
|
+
/** Test-only: whether `ensureMounted` has run. */
|
|
67
|
+
export declare function isToastRegionMounted(): boolean;
|
|
68
|
+
export interface ToastFn {
|
|
69
|
+
(message: string, opts?: ToastOptions): ToastHandle;
|
|
70
|
+
/** Raise a success (emerald check) toast. */
|
|
71
|
+
success: (message: string, opts?: ToastOptions) => ToastHandle;
|
|
72
|
+
/** Dismiss a toast by id. */
|
|
73
|
+
dismiss: (id: string) => void;
|
|
74
|
+
/** Dismiss every active toast. */
|
|
75
|
+
clear: () => void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Raise a transient toast. Returns a `{ id, dismiss, update }` handle.
|
|
79
|
+
*
|
|
80
|
+
* ```ts
|
|
81
|
+
* toast('Copied to clipboard');
|
|
82
|
+
* toast.success('Saved');
|
|
83
|
+
* const t = toast('Working…', { duration: 0 });
|
|
84
|
+
* t.update({ message: 'Done', variant: 'success', duration: 2000 });
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare const toast: ToastFn;
|
|
88
|
+
export { resolveDuration };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function observeContentHeight(el: Element, onHeight: (height: number) => void): () => void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface UseTextStreamOptions {
|
|
2
|
+
mode: 'typewriter' | 'fade';
|
|
3
|
+
speed?: number;
|
|
4
|
+
characterChunkSize?: number;
|
|
5
|
+
fadeDuration?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface TextStreamSegment {
|
|
8
|
+
text: string;
|
|
9
|
+
index: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function useTextStream(options: UseTextStreamOptions): {
|
|
12
|
+
displayedText: import('solid-js').Accessor<string>;
|
|
13
|
+
isComplete: import('solid-js').Accessor<boolean>;
|
|
14
|
+
segments: import('solid-js').Accessor<TextStreamSegment[]>;
|
|
15
|
+
startStreaming: (source: string | AsyncIterable<string>) => void;
|
|
16
|
+
pause: () => void;
|
|
17
|
+
resume: () => void;
|
|
18
|
+
reset: () => void;
|
|
19
|
+
};
|