@kitn.ai/ui 0.30.0 → 0.31.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 +1 -1
- package/dist/{Icon-BzBET3E-.js → Icon-DJDuE_-x.js} +1 -1
- package/dist/action-icons-xkBBVKkF.js +1 -0
- package/dist/agent-tooling/construct/schema-url.d.ts +9 -0
- package/dist/agent-tooling/construct/schema.d.ts +76 -1
- package/dist/agent-tooling/construct/templates.d.ts +45 -0
- package/dist/arrow-down-DU6wOl-h.js +1 -0
- package/dist/arrow-left-DD46kN17.js +1 -0
- package/dist/{artifact-DGjzHYUT.js → artifact-DoUAr1Fd.js} +1 -1
- package/dist/assets/dev-DwzHsqYD.js +553 -0
- package/dist/{attachments-YvXHlg88.js → attachments-BLWPDiLH.js} +1 -1
- package/dist/{audio-visualizer-9lz5IHsL.js → audio-visualizer-DhHicYvV.js} +1 -1
- package/dist/{badge-Dh_vp8A5.js → badge-BGm7pcwi.js} +1 -1
- package/dist/{bell-CT7_WUwS.js → bell-CMEdSo7A.js} +1 -1
- package/dist/builder-app/App.d.ts +1 -0
- package/dist/builder-app/edit-guard.d.ts +8 -0
- package/dist/builder-app/main.d.ts +0 -0
- package/dist/builder-page/assets/index-C10OF-ur.js +72 -0
- package/dist/builder-page/assets/index-CFyKLBlu.css +1 -0
- package/dist/builder-page/index.html +20 -0
- package/dist/button-BM0YTTDQ.js +1 -0
- package/dist/{card-renderer-DZVaGH2e.js → card-renderer-Ds-wXc6_.js} +1 -1
- package/dist/check-BG1VfYjm.js +1 -0
- package/dist/{checkbox-group-BiryEXPQ.js → checkbox-group-CqXj8ehz.js} +1 -1
- package/dist/{checkbox-Bu2T2e0U.js → checkbox-np_5mKxM.js} +1 -1
- package/dist/chevron-down-CZ4W0hy6.js +1 -0
- package/dist/chevron-right-5gdxkCTF.js +1 -0
- package/dist/{choice-card-CM6IjkmL.js → choice-card-BYBmPAT5.js} +1 -1
- package/dist/circle-C0lwjD2A.js +1 -0
- package/dist/circle-check-BfT1cxQU.js +1 -0
- package/dist/{circle-x-Bk-dA5Wf.js → circle-x-DzUfvRqr.js} +1 -1
- package/dist/{code-block-B26t-Q7q.js → code-block-H6E5Eurc.js} +1 -1
- package/dist/{collapsible-Bhc636Cf.js → collapsible-CBq1Tj6y.js} +1 -1
- package/dist/components/builder-message-actions.d.ts +9 -18
- package/dist/components/builder-panel-derived.d.ts +18 -0
- package/dist/components/builder-panel.d.ts +51 -0
- package/dist/components/builder-start.d.ts +14 -10
- package/dist/components/chat-thread.d.ts +27 -1
- package/dist/components/construct-form-paths.d.ts +54 -0
- package/dist/components/message.d.ts +5 -0
- package/dist/{composer-DMI85B6j.js → composer-B5IvgxAF.js} +1 -1
- package/dist/{confirm-card-B0YIAwXp.js → confirm-card-B63pZIfG.js} +1 -1
- package/dist/construct-cli.es.js +469 -125
- package/dist/construct-templates.d.ts +5 -0
- package/dist/construct-templates.js +266 -0
- package/dist/construct.js +269 -86
- package/dist/{context-DWgfhqWp.js → context-Byqor78j.js} +1 -1
- package/dist/controllable-C4BSt73s.js +1 -0
- package/dist/{conversation-item-BsOsVGmT.js → conversation-item-piXZFRWa.js} +1 -1
- package/dist/{conversation-list-aX3Vtc7L.js → conversation-list-B5yu9cPg.js} +1 -1
- package/dist/{copy-BmEwsNhJ.js → copy-DfI2NYEX.js} +1 -1
- package/dist/{create-tween-CNOAU3Fx.js → create-tween-C4j96_Aj.js} +1 -1
- package/dist/{create-tween-WfqiENls.js → create-tween-CHleHI8m.js} +1 -1
- package/dist/{create-tween-wlFtW9Kh.js → create-tween-DQ6lOhdl.js} +1 -1
- package/dist/{create-tween-zt79ba32.js → create-tween-DyjTgkJi.js} +1 -1
- package/dist/custom-elements.json +40 -5
- package/dist/{default-input-DMV5Eaze.js → default-input-Bwmt8Lai.js} +1 -1
- package/dist/define-B3OpsIDE.js +1 -0
- package/dist/define.js +2 -2
- package/dist/define.server.js +2 -2
- package/dist/{disclosure-NnACBxsC.js → disclosure-ZSAlD4wg.js} +1 -1
- package/dist/{dropdown-DT7G0RGR.js → dropdown-CSRhiMN2.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-actions.d.ts +12 -0
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-types.d.ts +7 -2
- 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/elements.d.ts +22 -10
- package/dist/{ellipsis-6pJ7SxYT.js → ellipsis-CJ5QIjWo.js} +1 -1
- package/dist/{embed-BMje-nxj.js → embed-6Vji0PfS.js} +1 -1
- package/dist/{external-link-Beh9DKeR.js → external-link-BPTtTdet.js} +1 -1
- package/dist/{file-text-D1GPfZ8Q.js → file-text-eVjcFDrK.js} +1 -1
- package/dist/{file-tree-Dwj2lqg-.js → file-tree-a9tfWYmg.js} +1 -1
- package/dist/{folder-b6D8x1DY.js → folder-DN6Ilq6d.js} +1 -1
- package/dist/{form-DWgdxDXu.js → form-U1cwhcQx.js} +1 -1
- package/dist/{hover-card-CWRkqm40.js → hover-card-C5ptzZOZ.js} +1 -1
- package/dist/{icon-CL0jdhsf.js → icon-BOMrFp0D.js} +1 -1
- package/dist/index.js +1991 -1989
- package/dist/index.server.js +1886 -1884
- package/dist/{info-0cOUherQ.js → info-DxzKsIHn.js} +1 -1
- package/dist/{input-BH6Ru91Q.js → input-aW72PACH.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-DRAnVtNX.js → kbd-BP-6MwUs.js} +1 -1
- package/dist/{link-preview-DODgRyV9.js → link-preview-CZaDilMG.js} +1 -1
- package/dist/{link-Dlr0vssB.js → link-rlN11N0B.js} +1 -1
- package/dist/{loader-KvJB6NrT.js → loader-BdFK70fF.js} +1 -1
- package/dist/{markdown-DX9tuJVj.js → markdown-DjEaoNz-.js} +1 -1
- package/dist/mcp.es.js +579 -107
- package/dist/message--Nlbemtp.js +1 -0
- package/dist/message-C88yTu2A.js +1 -0
- package/dist/message-circle-CZeVDN1f.js +1 -0
- package/dist/message-square-BXNBKC6i.js +1 -0
- package/dist/{minimize-2-CyOHJwcN.js → minimize-2-BxLOOSEf.js} +1 -1
- package/dist/{model-switcher-0hrKDiK2.js → model-switcher-BxRvub2A.js} +1 -1
- package/dist/{overlay-DBMFXie6.js → overlay-CDwKJtHN.js} +1 -1
- package/dist/{panel-right-t8SWJL6e.js → panel-right-BovedCwW.js} +1 -1
- package/dist/{paperclip-CdzuOjbU.js → paperclip-D0Xyjja2.js} +1 -1
- package/dist/play-DGJ4MgB2.js +1 -0
- package/dist/primitives/speech.d.ts +35 -0
- package/dist/{progress-bar-CiBtxMWT.js → progress-bar-D-aQfy5h.js} +1 -1
- package/dist/{prompt-suggestion-I_DHP21i.js → prompt-suggestion-C6qLjMEQ.js} +1 -1
- package/dist/{radio-C_p3n39l.js → radio-D1CkXISc.js} +1 -1
- package/dist/react/index.d.ts +22 -6
- package/dist/react.js +13 -13
- package/dist/{reasoning-BDwy_tIe.js → reasoning-DARmbgmE.js} +1 -1
- package/dist/register-impl-WcrdIihK.js +424 -0
- package/dist/{resizable-SYC-fStM.js → resizable-Da6oSO2z.js} +1 -1
- package/dist/{rotate-ccw-B1nwmwuY.js → rotate-ccw-31ed1xK_.js} +1 -1
- package/dist/{rotate-cw-CLAnBcm1.js → rotate-cw-qkl39dw3.js} +1 -1
- package/dist/{scroll-area-zRyXoLhI.js → scroll-area-RrKnLYlA.js} +1 -1
- package/dist/{scroll-button-jzrbYCG9.js → scroll-button--QeNjobK.js} +1 -1
- package/dist/{select-DM-0nEe0.js → select-CS_0mWW3.js} +1 -1
- package/dist/{separator-BToOOoOt.js → separator-fT-zBypW.js} +1 -1
- package/dist/{settings-PaGo_S4U.js → settings-dfkV_WDm.js} +1 -1
- package/dist/{settings-group-BFXGIfXq.js → settings-group-CX694npG.js} +1 -1
- package/dist/{skeleton-DYpmFnnm.js → skeleton-BsqKD9TV.js} +1 -1
- package/dist/{slider-ebutAmkQ.js → slider-_EWfTH9H.js} +1 -1
- package/dist/{solid-15v_3WVL.js → solid-BITWG_VE.js} +3073 -3006
- package/dist/{solid-5P-otgdi.js → solid-CRFYWlBw.js} +3865 -3797
- package/dist/solid.js +1 -1
- package/dist/solid.server.js +1 -1
- package/dist/{source-c1gpRl9h.js → source-Da1TFiuj.js} +1 -1
- package/dist/speech-CjbWuqG2.js +1 -0
- package/dist/{star-pcV_3LqF.js → star-ZvSbbXS6.js} +1 -1
- package/dist/{store-CSgbFFCg.js → store-DE5lcr9q.js} +1 -1
- package/dist/{switch-Bh2OdLV2.js → switch-P_fsHqv3.js} +1 -1
- package/dist/{tasks-card-CbqQAn2S.js → tasks-card-B86qqyZm.js} +1 -1
- package/dist/{text-shimmer-BSzgEnDH.js → text-shimmer-BAkw_65G.js} +1 -1
- package/dist/{textarea-DrYNt_0z.js → textarea-Bkinatpi.js} +1 -1
- package/dist/{thumbs-up-BL3-NenK.js → thumbs-up-CDGW7a4o.js} +1 -1
- package/dist/{toast-store-DkOlYczt.js → toast-store-B94I50AO.js} +1 -1
- package/dist/{tool-CeIWUVUe.js → tool-CUiCeyi1.js} +1 -1
- package/dist/{tooltip-GA-nmg06.js → tooltip-B3wlQSPh.js} +1 -1
- package/dist/{trash-2-CT66QWlm.js → trash-2-Cu8yZmFQ.js} +1 -1
- package/dist/{triangle-alert-CeHLWxhD.js → triangle-alert-CCtDUUmn.js} +1 -1
- package/dist/ui/button-variant-names.d.ts +12 -0
- package/dist/ui/button.d.ts +6 -0
- package/dist/{upload-9Csb0F0J.js → upload-CxotJlLv.js} +1 -1
- package/dist/{use-card-resolution-Zg0a08Z-.js → use-card-resolution-DILUvNyj.js} +1 -1
- package/dist/{variant-aurora-4VBQHIKV.js → variant-aurora-BGaXBBGf.js} +1 -1
- package/dist/{variant-aurora-LE3fqxgw.js → variant-aurora-BLcQmvkd.js} +1 -1
- package/dist/{variant-aurora-DBeCAQNk.js → variant-aurora-DZIfAtx1.js} +2 -2
- package/dist/{variant-aurora-FzHVXHby.js → variant-aurora-DpoIW4ZX.js} +2 -2
- package/dist/{variant-custom-DI5R0rln.js → variant-custom-BhtWdAxE.js} +1 -1
- package/dist/{variant-custom-WWnrrRHS.js → variant-custom-BtApuSyr.js} +2 -2
- package/dist/{variant-custom-BQkNuPpE.js → variant-custom-C-zS4ZtE.js} +2 -2
- package/dist/{variant-custom-AFRGcOBS.js → variant-custom-swi9PXxU.js} +1 -1
- package/dist/{variant-wave-wTP5v_jU.js → variant-wave-7JCIwhpb.js} +1 -1
- package/dist/{variant-wave-nSI2sfII.js → variant-wave-BG4nGr6x.js} +1 -1
- package/dist/{variant-wave-DuQV7DhQ.js → variant-wave-C32lM9G2.js} +2 -2
- package/dist/{variant-wave-DUCbH5oI.js → variant-wave-Dl6jOiK3.js} +2 -2
- package/dist/x-C4niw05N.js +1 -0
- package/frameworks/react/index.tsx +12 -6
- package/llms-full.txt +9 -6
- package/llms.txt +1 -1
- package/package.json +7 -3
- package/solid.css +17 -2
- package/src/elements/element-meta.json +39 -14
- package/dist/action-icons-DaW2pU6m.js +0 -1
- package/dist/arrow-down-D783iMJj.js +0 -1
- package/dist/arrow-left-0VLM5kyg.js +0 -1
- package/dist/assets/dev-5XzXYR21.js +0 -91
- package/dist/button-C_3te6fm.js +0 -1
- package/dist/check-CiEOVnEN.js +0 -1
- package/dist/chevron-down-CSobuZRG.js +0 -1
- package/dist/chevron-right-DR9ZAP-2.js +0 -1
- package/dist/circle-BC66EYF7.js +0 -1
- package/dist/circle-check-BqmahW0O.js +0 -1
- package/dist/controllable-BagRpyHv.js +0 -1
- package/dist/define-CI0y3eE4.js +0 -1
- package/dist/message-BqQ7Ot5q.js +0 -1
- package/dist/message-DkaGfBd8.js +0 -1
- package/dist/message-circle-BPpp5QKv.js +0 -1
- package/dist/message-square-BLbsd9BJ.js +0 -1
- package/dist/play-BXy1u7rW.js +0 -1
- package/dist/register-impl-DvEnhIxx.js +0 -424
- package/dist/x-eiO9V6J6.js +0 -1
package/dist/mcp.es.js
CHANGED
|
@@ -9505,8 +9505,15 @@ function isSafeUrl(url) {
|
|
|
9505
9505
|
const scheme = schemeOf(url);
|
|
9506
9506
|
return scheme !== void 0 && SAFE_SCHEMES.includes(scheme);
|
|
9507
9507
|
}
|
|
9508
|
+
const CHAT_MESSAGE_ACTIONS = ["copy", "like", "dislike", "regenerate", "edit", "speak"];
|
|
9509
|
+
const BUTTON_VARIANT_NAMES = ["default", "ghost", "subtle", "outline", "destructive"];
|
|
9508
9510
|
const CONSTRUCT_SCHEMA_URL = "https://ui.kitn.ai/schemas/construct/v1.json";
|
|
9509
9511
|
const TAG_RE = /^[a-z][a-z0-9]*-[a-z0-9-]+$/;
|
|
9512
|
+
const TriggerEntrySchema = z$1.object({
|
|
9513
|
+
id: z$1.string().min(1),
|
|
9514
|
+
label: z$1.string().min(1),
|
|
9515
|
+
description: z$1.string().min(1).optional()
|
|
9516
|
+
}).strict();
|
|
9510
9517
|
const ProviderSchema = z$1.discriminatedUnion("mode", [
|
|
9511
9518
|
z$1.object({ mode: z$1.literal("mock") }).strict(),
|
|
9512
9519
|
z$1.object({
|
|
@@ -9575,7 +9582,26 @@ const ConstructSchema = z$1.object({
|
|
|
9575
9582
|
/** Rendered in ChatThread's built-in header bar (left side). Construct-
|
|
9576
9583
|
* authored/untrusted text, like theme.accent/provider.url — JSON.stringify'd
|
|
9577
9584
|
* at its one emit site, never a raw JSX attribute string. */
|
|
9578
|
-
title: z$1.string().min(1).optional()
|
|
9585
|
+
title: z$1.string().min(1).optional(),
|
|
9586
|
+
/** Renders a theme-toggle Button in ChatThread's header-end region,
|
|
9587
|
+
* flipping the host's `theme` attribute (the attribute
|
|
9588
|
+
* defineWebComponent already owns) via the facade's ctx.element —
|
|
9589
|
+
* codegen work, no new kit surface (B-10). */
|
|
9590
|
+
themeToggle: z$1.boolean().optional(),
|
|
9591
|
+
/** Header action buttons (label + kit Button variant), rendered in
|
|
9592
|
+
* the header-end region. Vocabulary-never-logic: the construct
|
|
9593
|
+
* cannot say what an action DOES, so each click dispatches a
|
|
9594
|
+
* non-bubbling `kai-header-action` CustomEvent on the host with
|
|
9595
|
+
* `detail: { label }` — the consumer's listening seam (B-10).
|
|
9596
|
+
* `variant` derives from the kit Button's own list
|
|
9597
|
+
* (BUTTON_VARIANT_NAMES — B-6a), never restated. `label` is
|
|
9598
|
+
* construct-authored untrusted text, JSON.stringify'd at emit. */
|
|
9599
|
+
actions: z$1.array(
|
|
9600
|
+
z$1.object({
|
|
9601
|
+
label: z$1.string().min(1),
|
|
9602
|
+
variant: z$1.enum(BUTTON_VARIANT_NAMES).optional()
|
|
9603
|
+
}).strict()
|
|
9604
|
+
).min(1).optional()
|
|
9579
9605
|
}).strict().optional(),
|
|
9580
9606
|
/** Greeting shown while the thread is empty (no messages yet) — the
|
|
9581
9607
|
* proven "welcome screen" pattern (Intercom-class): title + optional
|
|
@@ -9684,7 +9710,28 @@ const ConstructSchema = z$1.object({
|
|
|
9684
9710
|
* vocabulary; HOW it persists (the ConversationStore adapter,
|
|
9685
9711
|
* localStorage vs. a fetch endpoint) is codegen's call, never
|
|
9686
9712
|
* vocabulary here (C-3 — no transport-layer vocabulary). */
|
|
9687
|
-
conversations: z$1.literal(true).optional()
|
|
9713
|
+
conversations: z$1.literal(true).optional(),
|
|
9714
|
+
/** Role-scoped default action bars, threaded onto ChatThread's
|
|
9715
|
+
* `userActions`/`assistantActions` props (B-3/B-7b). Ordered
|
|
9716
|
+
* arrays; enum ids ONLY, read off the ONE const
|
|
9717
|
+
* (CHAT_MESSAGE_ACTIONS — B-6): a CustomAction is an id the APP
|
|
9718
|
+
* must handle, a construct has no app code, so emitting one is a
|
|
9719
|
+
* dead affordance. Duplicates within one array rejected below
|
|
9720
|
+
* (superRefine, the slots pattern). min(1): an empty list IS the
|
|
9721
|
+
* absent key. */
|
|
9722
|
+
messageActions: z$1.object({
|
|
9723
|
+
user: z$1.array(z$1.enum(CHAT_MESSAGE_ACTIONS)).min(1).optional(),
|
|
9724
|
+
assistant: z$1.array(z$1.enum(CHAT_MESSAGE_ACTIONS)).min(1).optional()
|
|
9725
|
+
}).strict().optional(),
|
|
9726
|
+
/** The citations STRIP (the `part="citations"` row consecutive
|
|
9727
|
+
* `source` parts already collapse into — message.tsx). `strip:
|
|
9728
|
+
* false` hides it (emits ChatThread's `hideSources`); `strip:
|
|
9729
|
+
* true` or the key absent emits NOTHING — the row already renders,
|
|
9730
|
+
* the kit default IS the on state, the same anchored-on-the-
|
|
9731
|
+
* default convention as `reasoning: 'full'` (B-4). */
|
|
9732
|
+
sources: z$1.object({
|
|
9733
|
+
strip: z$1.boolean().optional()
|
|
9734
|
+
}).strict().optional()
|
|
9688
9735
|
}).strict().optional(),
|
|
9689
9736
|
/** Named generative-UI card definitions the model can emit as tool calls,
|
|
9690
9737
|
* rendered in the thread. Top-level (not a capability): a card is
|
|
@@ -9731,109 +9778,245 @@ const ConstructSchema = z$1.object({
|
|
|
9731
9778
|
/** Seed Dock's open state at mount. Uncontrolled — never steals focus (Dock's
|
|
9732
9779
|
* own focus contract, dock.tsx). Omitted keeps Dock's own default (closed). */
|
|
9733
9780
|
defaultOpen: z$1.boolean().optional()
|
|
9781
|
+
}).strict().optional(),
|
|
9782
|
+
/** Layout-scoped aside geometry, `layout: 'aside'` only (superRefine
|
|
9783
|
+
* below, mirroring `widget`'s scoping exactly). `position` picks the
|
|
9784
|
+
* docked inline edge (default 'end', today's hardcoded behavior);
|
|
9785
|
+
* `width` overrides codegen's 380px default. `width` is construct-
|
|
9786
|
+
* authored untrusted text: it lands as a JSON.stringify'd VALUE inside
|
|
9787
|
+
* the emitted Solid `style={{ }}` object — property assignment, the
|
|
9788
|
+
* same no-CSS-text-interpolation guarantee as setProperty — never
|
|
9789
|
+
* concatenated into a CSS string (B-2). */
|
|
9790
|
+
aside: z$1.object({
|
|
9791
|
+
position: z$1.enum(["start", "end"]).optional(),
|
|
9792
|
+
width: z$1.string().min(1).optional()
|
|
9793
|
+
}).strict().optional(),
|
|
9794
|
+
/** Construct-wide shell chrome (10a): both members reuse REAL kit
|
|
9795
|
+
* pieces — command.tsx's CommandList behind a codegen-emitted overlay
|
|
9796
|
+
* (opened on Mod+K; entries DERIVE from what this construct enables —
|
|
9797
|
+
* menu-honesty against dead entries), and the documented Dropdown+
|
|
9798
|
+
* Avatar user-menu recipe. `name`/`plan` are construct-authored
|
|
9799
|
+
* untrusted text, JSON.stringify'd at emit like every sibling.
|
|
9800
|
+
* `commandPalette` is presence-only `z.literal(true)`, matching
|
|
9801
|
+
* `conversations`' pattern. */
|
|
9802
|
+
shell: z$1.object({
|
|
9803
|
+
commandPalette: z$1.literal(true).optional(),
|
|
9804
|
+
userMenu: z$1.object({
|
|
9805
|
+
name: z$1.string().min(1),
|
|
9806
|
+
plan: z$1.string().min(1).optional()
|
|
9807
|
+
}).strict().optional()
|
|
9808
|
+
}).strict().optional(),
|
|
9809
|
+
/** Composer chrome — NOT a capability: chrome on the medium, like
|
|
9810
|
+
* `header` (B-5). `triggers` maps onto ChatThread's real, shipped
|
|
9811
|
+
* `triggers` prop: `slash` → `{ char: '/', kind: 'command', items }`,
|
|
9812
|
+
* `mention` → `{ char: '@', kind: 'mention', items }` at emit. */
|
|
9813
|
+
composer: z$1.object({
|
|
9814
|
+
triggers: z$1.object({
|
|
9815
|
+
slash: z$1.array(TriggerEntrySchema).min(1).optional(),
|
|
9816
|
+
mention: z$1.array(TriggerEntrySchema).min(1).optional()
|
|
9817
|
+
}).strict().optional()
|
|
9734
9818
|
}).strict().optional()
|
|
9735
9819
|
}).strict().superRefine((construct, ctx) => {
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9820
|
+
for (const rule of CROSS_FIELD_RULES) rule.check(construct, ctx);
|
|
9821
|
+
});
|
|
9822
|
+
const CROSS_FIELD_RULES = [
|
|
9823
|
+
{
|
|
9824
|
+
id: "slots-unique",
|
|
9825
|
+
paths: ["slots"],
|
|
9826
|
+
check: (construct, ctx) => {
|
|
9827
|
+
if (!construct.slots) return;
|
|
9828
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9829
|
+
construct.slots.forEach((name, i) => {
|
|
9830
|
+
if (seen.has(name)) {
|
|
9831
|
+
ctx.addIssue({
|
|
9832
|
+
code: z$1.ZodIssueCode.custom,
|
|
9833
|
+
path: ["slots", i],
|
|
9834
|
+
message: `duplicate slot name "${name}"`
|
|
9835
|
+
});
|
|
9836
|
+
}
|
|
9837
|
+
seen.add(name);
|
|
9838
|
+
});
|
|
9839
|
+
}
|
|
9840
|
+
},
|
|
9841
|
+
{
|
|
9842
|
+
id: "custom-layout-needs-slots",
|
|
9843
|
+
paths: ["layout", "slots"],
|
|
9844
|
+
check: (construct, ctx) => {
|
|
9845
|
+
if (construct.layout === "custom" && (!construct.slots || construct.slots.length === 0)) {
|
|
9740
9846
|
ctx.addIssue({
|
|
9741
9847
|
code: z$1.ZodIssueCode.custom,
|
|
9742
|
-
path: ["slots"
|
|
9743
|
-
message:
|
|
9848
|
+
path: ["slots"],
|
|
9849
|
+
message: '"custom" layout requires at least one declared slot — custom IS the slots grain'
|
|
9744
9850
|
});
|
|
9745
9851
|
}
|
|
9746
|
-
seen.add(name);
|
|
9747
|
-
});
|
|
9748
|
-
}
|
|
9749
|
-
if (construct.layout === "custom" && (!construct.slots || construct.slots.length === 0)) {
|
|
9750
|
-
ctx.addIssue({
|
|
9751
|
-
code: z$1.ZodIssueCode.custom,
|
|
9752
|
-
path: ["slots"],
|
|
9753
|
-
message: '"custom" layout requires at least one declared slot — custom IS the slots grain'
|
|
9754
|
-
});
|
|
9755
|
-
}
|
|
9756
|
-
if (construct.layout === "split" && construct.slots) {
|
|
9757
|
-
const i = construct.slots.indexOf("pane");
|
|
9758
|
-
if (i !== -1) {
|
|
9759
|
-
ctx.addIssue({
|
|
9760
|
-
code: z$1.ZodIssueCode.custom,
|
|
9761
|
-
path: ["slots", i],
|
|
9762
|
-
message: `"pane" collides with the "split" layout's own fixed <slot name="pane"> — choose a different slot name`
|
|
9763
|
-
});
|
|
9764
9852
|
}
|
|
9765
|
-
}
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
if (construct.empty?.icon && !isSafeUrl(construct.empty.icon)) {
|
|
9781
|
-
ctx.addIssue({
|
|
9782
|
-
code: z$1.ZodIssueCode.custom,
|
|
9783
|
-
path: ["empty", "icon"],
|
|
9784
|
-
message: "icon must be an http(s)/mailto or relative URL — no javascript:/data: schemes"
|
|
9785
|
-
});
|
|
9786
|
-
}
|
|
9787
|
-
const reasoning = construct.capabilities?.reasoning;
|
|
9788
|
-
const reasoningOpen = construct.capabilities?.reasoningOpen;
|
|
9789
|
-
if (reasoningOpen !== void 0 && (reasoning === "compact" || reasoning === "off")) {
|
|
9790
|
-
ctx.addIssue({
|
|
9791
|
-
code: z$1.ZodIssueCode.custom,
|
|
9792
|
-
path: ["capabilities", "reasoningOpen"],
|
|
9793
|
-
message: '"reasoningOpen" only applies when reasoning is "full" or omitted — "compact"/"off" have no disclosure to open'
|
|
9794
|
-
});
|
|
9795
|
-
}
|
|
9796
|
-
const history = construct.capabilities?.history;
|
|
9797
|
-
if (construct.capabilities?.conversations && (!history || history.persistence === "none")) {
|
|
9798
|
-
ctx.addIssue({
|
|
9799
|
-
code: z$1.ZodIssueCode.custom,
|
|
9800
|
-
path: ["capabilities", "conversations"],
|
|
9801
|
-
message: '"conversations" requires capabilities.history.persistence to be "local" or "endpoint" — a conversation list needs somewhere to persist conversations'
|
|
9802
|
-
});
|
|
9803
|
-
}
|
|
9804
|
-
const URL_SHAPED = /^[a-zA-Z][a-zA-Z0-9+.-]*:|^\/\//;
|
|
9805
|
-
for (const [i, link] of (construct.home?.links ?? []).entries()) {
|
|
9806
|
-
if (link.href && !isSafeUrl(link.href)) {
|
|
9807
|
-
ctx.addIssue({
|
|
9808
|
-
code: z$1.ZodIssueCode.custom,
|
|
9809
|
-
path: ["home", "links", i, "href"],
|
|
9810
|
-
message: "href must be an http(s)/mailto or relative URL — no javascript:/data: schemes"
|
|
9811
|
-
});
|
|
9853
|
+
},
|
|
9854
|
+
{
|
|
9855
|
+
id: "split-pane-slot-collision",
|
|
9856
|
+
paths: ["layout", "slots"],
|
|
9857
|
+
check: (construct, ctx) => {
|
|
9858
|
+
if (construct.layout === "split" && construct.slots) {
|
|
9859
|
+
const i = construct.slots.indexOf("pane");
|
|
9860
|
+
if (i !== -1) {
|
|
9861
|
+
ctx.addIssue({
|
|
9862
|
+
code: z$1.ZodIssueCode.custom,
|
|
9863
|
+
path: ["slots", i],
|
|
9864
|
+
message: `"pane" collides with the "split" layout's own fixed <slot name="pane"> — choose a different slot name`
|
|
9865
|
+
});
|
|
9866
|
+
}
|
|
9867
|
+
}
|
|
9812
9868
|
}
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9869
|
+
},
|
|
9870
|
+
{
|
|
9871
|
+
id: "widget-layout-scope",
|
|
9872
|
+
paths: ["layout", "widget"],
|
|
9873
|
+
check: (construct, ctx) => {
|
|
9874
|
+
if (construct.widget && construct.layout !== "widget") {
|
|
9875
|
+
ctx.addIssue({
|
|
9876
|
+
code: z$1.ZodIssueCode.custom,
|
|
9877
|
+
path: ["widget"],
|
|
9878
|
+
message: '"widget" is only valid on layout: "widget"'
|
|
9879
|
+
});
|
|
9880
|
+
}
|
|
9881
|
+
}
|
|
9882
|
+
},
|
|
9883
|
+
{
|
|
9884
|
+
id: "aside-layout-scope",
|
|
9885
|
+
paths: ["layout", "aside"],
|
|
9886
|
+
check: (construct, ctx) => {
|
|
9887
|
+
if (construct.aside && construct.layout !== "aside") {
|
|
9888
|
+
ctx.addIssue({
|
|
9889
|
+
code: z$1.ZodIssueCode.custom,
|
|
9890
|
+
path: ["aside"],
|
|
9891
|
+
message: '"aside" is only valid on layout: "aside"'
|
|
9892
|
+
});
|
|
9893
|
+
}
|
|
9894
|
+
}
|
|
9895
|
+
},
|
|
9896
|
+
{
|
|
9897
|
+
id: "message-actions-unique",
|
|
9898
|
+
paths: ["capabilities.messageActions.user", "capabilities.messageActions.assistant"],
|
|
9899
|
+
check: (construct, ctx) => {
|
|
9900
|
+
const messageActions = construct.capabilities?.messageActions;
|
|
9901
|
+
if (!messageActions) return;
|
|
9902
|
+
for (const role of ["user", "assistant"]) {
|
|
9903
|
+
const list = messageActions[role];
|
|
9904
|
+
if (!list) continue;
|
|
9905
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9906
|
+
list.forEach((id, i) => {
|
|
9907
|
+
if (seen.has(id)) {
|
|
9908
|
+
ctx.addIssue({
|
|
9909
|
+
code: z$1.ZodIssueCode.custom,
|
|
9910
|
+
path: ["capabilities", "messageActions", role, i],
|
|
9911
|
+
message: `duplicate action id "${id}"`
|
|
9912
|
+
});
|
|
9913
|
+
}
|
|
9914
|
+
seen.add(id);
|
|
9915
|
+
});
|
|
9916
|
+
}
|
|
9917
|
+
}
|
|
9918
|
+
},
|
|
9919
|
+
{
|
|
9920
|
+
id: "launcher-icon-url",
|
|
9921
|
+
paths: ["widget.launcherIcon"],
|
|
9922
|
+
check: (construct, ctx) => {
|
|
9923
|
+
if (construct.widget?.launcherIcon && !isSafeUrl(construct.widget.launcherIcon)) {
|
|
9924
|
+
ctx.addIssue({
|
|
9925
|
+
code: z$1.ZodIssueCode.custom,
|
|
9926
|
+
path: ["widget", "launcherIcon"],
|
|
9927
|
+
message: "launcherIcon must be an http(s)/mailto or relative URL — no javascript:/data: schemes"
|
|
9928
|
+
});
|
|
9929
|
+
}
|
|
9930
|
+
}
|
|
9931
|
+
},
|
|
9932
|
+
{
|
|
9933
|
+
id: "empty-icon-url",
|
|
9934
|
+
paths: ["empty.icon"],
|
|
9935
|
+
check: (construct, ctx) => {
|
|
9936
|
+
if (construct.empty?.icon && !isSafeUrl(construct.empty.icon)) {
|
|
9937
|
+
ctx.addIssue({
|
|
9938
|
+
code: z$1.ZodIssueCode.custom,
|
|
9939
|
+
path: ["empty", "icon"],
|
|
9940
|
+
message: "icon must be an http(s)/mailto or relative URL — no javascript:/data: schemes"
|
|
9941
|
+
});
|
|
9942
|
+
}
|
|
9943
|
+
}
|
|
9944
|
+
},
|
|
9945
|
+
{
|
|
9946
|
+
id: "reasoning-open-scope",
|
|
9947
|
+
paths: ["capabilities.reasoning", "capabilities.reasoningOpen"],
|
|
9948
|
+
check: (construct, ctx) => {
|
|
9949
|
+
const reasoning = construct.capabilities?.reasoning;
|
|
9950
|
+
const reasoningOpen = construct.capabilities?.reasoningOpen;
|
|
9951
|
+
if (reasoningOpen !== void 0 && (reasoning === "compact" || reasoning === "off")) {
|
|
9952
|
+
ctx.addIssue({
|
|
9953
|
+
code: z$1.ZodIssueCode.custom,
|
|
9954
|
+
path: ["capabilities", "reasoningOpen"],
|
|
9955
|
+
message: '"reasoningOpen" only applies when reasoning is "full" or omitted — "compact"/"off" have no disclosure to open'
|
|
9956
|
+
});
|
|
9957
|
+
}
|
|
9958
|
+
}
|
|
9959
|
+
},
|
|
9960
|
+
{
|
|
9961
|
+
id: "conversations-need-history",
|
|
9962
|
+
paths: ["capabilities.conversations", "capabilities.history"],
|
|
9963
|
+
check: (construct, ctx) => {
|
|
9964
|
+
const history = construct.capabilities?.history;
|
|
9965
|
+
if (construct.capabilities?.conversations && (!history || history.persistence === "none")) {
|
|
9966
|
+
ctx.addIssue({
|
|
9967
|
+
code: z$1.ZodIssueCode.custom,
|
|
9968
|
+
path: ["capabilities", "conversations"],
|
|
9969
|
+
message: '"conversations" requires capabilities.history.persistence to be "local" or "endpoint" — a conversation list needs somewhere to persist conversations'
|
|
9970
|
+
});
|
|
9971
|
+
}
|
|
9972
|
+
}
|
|
9973
|
+
},
|
|
9974
|
+
{
|
|
9975
|
+
id: "home-link-urls",
|
|
9976
|
+
paths: ["home.links"],
|
|
9977
|
+
check: (construct, ctx) => {
|
|
9978
|
+
const URL_SHAPED = /^[a-zA-Z][a-zA-Z0-9+.-]*:|^\/\//;
|
|
9979
|
+
for (const [i, link] of (construct.home?.links ?? []).entries()) {
|
|
9980
|
+
if (link.href && !isSafeUrl(link.href)) {
|
|
9981
|
+
ctx.addIssue({
|
|
9982
|
+
code: z$1.ZodIssueCode.custom,
|
|
9983
|
+
path: ["home", "links", i, "href"],
|
|
9984
|
+
message: "href must be an http(s)/mailto or relative URL — no javascript:/data: schemes"
|
|
9985
|
+
});
|
|
9986
|
+
}
|
|
9987
|
+
if (link.icon && URL_SHAPED.test(link.icon) && !isSafeUrl(link.icon)) {
|
|
9988
|
+
ctx.addIssue({
|
|
9989
|
+
code: z$1.ZodIssueCode.custom,
|
|
9990
|
+
path: ["home", "links", i, "icon"],
|
|
9991
|
+
message: "icon must be a kit icon name or an http(s)/relative URL — no javascript:/data: schemes"
|
|
9992
|
+
});
|
|
9993
|
+
}
|
|
9994
|
+
}
|
|
9995
|
+
}
|
|
9996
|
+
},
|
|
9997
|
+
{
|
|
9998
|
+
id: "history-endpoint-url",
|
|
9999
|
+
paths: ["capabilities.history.persistence", "capabilities.history.url"],
|
|
10000
|
+
check: (construct, ctx) => {
|
|
10001
|
+
const history = construct.capabilities?.history;
|
|
10002
|
+
if (!history) return;
|
|
10003
|
+
if (history.persistence === "endpoint" && !history.url) {
|
|
10004
|
+
ctx.addIssue({
|
|
10005
|
+
code: z$1.ZodIssueCode.custom,
|
|
10006
|
+
path: ["capabilities", "history", "url"],
|
|
10007
|
+
message: '"endpoint" persistence requires a url'
|
|
10008
|
+
});
|
|
10009
|
+
}
|
|
10010
|
+
if (history.persistence !== "endpoint" && history.url !== void 0) {
|
|
10011
|
+
ctx.addIssue({
|
|
10012
|
+
code: z$1.ZodIssueCode.custom,
|
|
10013
|
+
path: ["capabilities", "history", "url"],
|
|
10014
|
+
message: 'url is only valid with "endpoint" persistence'
|
|
10015
|
+
});
|
|
10016
|
+
}
|
|
9819
10017
|
}
|
|
9820
10018
|
}
|
|
9821
|
-
|
|
9822
|
-
if (history.persistence === "endpoint" && !history.url) {
|
|
9823
|
-
ctx.addIssue({
|
|
9824
|
-
code: z$1.ZodIssueCode.custom,
|
|
9825
|
-
path: ["capabilities", "history", "url"],
|
|
9826
|
-
message: '"endpoint" persistence requires a url'
|
|
9827
|
-
});
|
|
9828
|
-
}
|
|
9829
|
-
if (history.persistence !== "endpoint" && history.url !== void 0) {
|
|
9830
|
-
ctx.addIssue({
|
|
9831
|
-
code: z$1.ZodIssueCode.custom,
|
|
9832
|
-
path: ["capabilities", "history", "url"],
|
|
9833
|
-
message: 'url is only valid with "endpoint" persistence'
|
|
9834
|
-
});
|
|
9835
|
-
}
|
|
9836
|
-
});
|
|
10019
|
+
];
|
|
9837
10020
|
function validateConstruct(input) {
|
|
9838
10021
|
const parsed = ConstructSchema.safeParse(input);
|
|
9839
10022
|
if (parsed.success) return { ok: true, construct: parsed.data };
|
|
@@ -9855,25 +10038,314 @@ function validateConstruct(input) {
|
|
|
9855
10038
|
})
|
|
9856
10039
|
};
|
|
9857
10040
|
}
|
|
10041
|
+
const IDENTITY = { id: "identity", paths: ["name"] };
|
|
10042
|
+
const THEME = { id: "theme", paths: ["theme.accent", "theme.mode", "theme.unreadColor"] };
|
|
10043
|
+
const HEADER = { id: "header", paths: ["header.title"] };
|
|
10044
|
+
const HEADER_CHROME = {
|
|
10045
|
+
id: "header",
|
|
10046
|
+
paths: ["header.title", "header.themeToggle", "header.actions"]
|
|
10047
|
+
};
|
|
10048
|
+
const EMPTY = { id: "empty", paths: ["empty.title", "empty.description", "empty.icon"] };
|
|
10049
|
+
const HOME = { id: "home", paths: ["home"] };
|
|
10050
|
+
const CAPABILITIES = {
|
|
10051
|
+
id: "capabilities",
|
|
10052
|
+
paths: [
|
|
10053
|
+
"capabilities.starters",
|
|
10054
|
+
"capabilities.attachments",
|
|
10055
|
+
"capabilities.history",
|
|
10056
|
+
"capabilities.conversations",
|
|
10057
|
+
"capabilities.reasoning",
|
|
10058
|
+
"capabilities.reasoningOpen"
|
|
10059
|
+
]
|
|
10060
|
+
};
|
|
10061
|
+
const MESSAGE_ACTIONS = {
|
|
10062
|
+
id: "messageActions",
|
|
10063
|
+
paths: ["capabilities.messageActions.user", "capabilities.messageActions.assistant"]
|
|
10064
|
+
};
|
|
10065
|
+
const SOURCES = { id: "sources", paths: ["capabilities.sources.strip"] };
|
|
10066
|
+
const WIDGET_CHROME = {
|
|
10067
|
+
id: "widget",
|
|
10068
|
+
paths: ["widget.position", "widget.launcherIcon", "widget.defaultOpen"]
|
|
10069
|
+
};
|
|
10070
|
+
const ASIDE = { id: "aside", paths: ["aside.position", "aside.width"] };
|
|
10071
|
+
const COMPOSER_TRIGGERS = {
|
|
10072
|
+
id: "composerTriggers",
|
|
10073
|
+
paths: ["composer.triggers.slash", "composer.triggers.mention"]
|
|
10074
|
+
};
|
|
10075
|
+
const SHELL = { id: "shell", paths: ["shell.commandPalette", "shell.userMenu"] };
|
|
10076
|
+
const CARDS = { id: "cards", paths: ["cards"] };
|
|
10077
|
+
const PROVIDER = { id: "provider", paths: ["provider"] };
|
|
10078
|
+
const widgetStarter = {
|
|
10079
|
+
$schema: CONSTRUCT_SCHEMA_URL,
|
|
10080
|
+
name: "support-widget",
|
|
10081
|
+
layout: "widget",
|
|
10082
|
+
provider: { mode: "mock" },
|
|
10083
|
+
header: { title: "Support" },
|
|
10084
|
+
theme: { unreadColor: "#38BDF8", mode: "system" },
|
|
10085
|
+
empty: {
|
|
10086
|
+
title: "Hi, we're here to help",
|
|
10087
|
+
description: "Ask us about orders, refunds, and more."
|
|
10088
|
+
},
|
|
10089
|
+
home: {
|
|
10090
|
+
greeting: { title: "How can we help? 👋", subtitle: "Orders, refunds, anything." },
|
|
10091
|
+
recentConversation: true,
|
|
10092
|
+
links: [
|
|
10093
|
+
{ label: "Help center", href: "https://ui.kitn.ai", description: "Guides and FAQs", icon: "book-open" }
|
|
10094
|
+
]
|
|
10095
|
+
},
|
|
10096
|
+
// States the kit default loudly (the anchored-on-the-default convention,
|
|
10097
|
+
// same as research's sources.strip) so the template's chrome fact is
|
|
10098
|
+
// visible/editable in its own JSON.
|
|
10099
|
+
widget: { position: "bottom-end" },
|
|
10100
|
+
capabilities: {
|
|
10101
|
+
starters: ["Where's my order?", "Request a refund"],
|
|
10102
|
+
attachments: { accept: ["image/*", "application/pdf"] },
|
|
10103
|
+
history: { persistence: "local" },
|
|
10104
|
+
conversations: true
|
|
10105
|
+
}
|
|
10106
|
+
};
|
|
10107
|
+
const inAppAssistantStarter = {
|
|
10108
|
+
$schema: CONSTRUCT_SCHEMA_URL,
|
|
10109
|
+
name: "in-app-assistant",
|
|
10110
|
+
layout: "aside",
|
|
10111
|
+
provider: { mode: "mock" },
|
|
10112
|
+
header: { title: "Assistant" },
|
|
10113
|
+
// Dark-by-default (owner ruling, dark round): every buildable starter
|
|
10114
|
+
// EXCEPT widget ships mode: 'dark' — widget is embedded in a host site and
|
|
10115
|
+
// follows IT, not its own preference (T-3: this is registry data, not a
|
|
10116
|
+
// schema default; 'system' stays the schema's own default for anyone
|
|
10117
|
+
// hand-authoring a construct).
|
|
10118
|
+
theme: { accent: "#0ea5e9", mode: "dark" },
|
|
10119
|
+
// codegen's own defaults, stated so the geometry is visible/editable.
|
|
10120
|
+
aside: { position: "end", width: "380px" },
|
|
10121
|
+
capabilities: {
|
|
10122
|
+
starters: ["Deploy payments to production", "Check the canary status"],
|
|
10123
|
+
attachments: { accept: ["image/*", "application/pdf"] },
|
|
10124
|
+
history: { persistence: "local" }
|
|
10125
|
+
}
|
|
10126
|
+
};
|
|
10127
|
+
const assistantStarter = {
|
|
10128
|
+
$schema: CONSTRUCT_SCHEMA_URL,
|
|
10129
|
+
name: "daily-assistant",
|
|
10130
|
+
layout: "fullscreen",
|
|
10131
|
+
provider: { mode: "mock" },
|
|
10132
|
+
header: { title: "Assistant" },
|
|
10133
|
+
// Dark-by-default (owner ruling, dark round) — see inAppAssistantStarter's
|
|
10134
|
+
// note above.
|
|
10135
|
+
theme: { accent: "#7c3aed", mode: "dark" },
|
|
10136
|
+
empty: {
|
|
10137
|
+
title: "What can I help with?",
|
|
10138
|
+
description: "Ask anything, or start from a suggestion below."
|
|
10139
|
+
},
|
|
10140
|
+
capabilities: {
|
|
10141
|
+
starters: ["Draft the Q3 board update", "Summarize a document", "Compare two options"],
|
|
10142
|
+
attachments: { accept: ["image/*", "application/pdf"] },
|
|
10143
|
+
history: { persistence: "local" },
|
|
10144
|
+
conversations: true
|
|
10145
|
+
}
|
|
10146
|
+
};
|
|
10147
|
+
const researchStarter = {
|
|
10148
|
+
$schema: CONSTRUCT_SCHEMA_URL,
|
|
10149
|
+
name: "research-assistant",
|
|
10150
|
+
layout: "fullscreen",
|
|
10151
|
+
provider: { mode: "mock" },
|
|
10152
|
+
header: { title: "Research" },
|
|
10153
|
+
// Dark-by-default (owner ruling, dark round) — see inAppAssistantStarter's
|
|
10154
|
+
// note above.
|
|
10155
|
+
theme: { accent: "#0f766e", mode: "dark" },
|
|
10156
|
+
capabilities: {
|
|
10157
|
+
starters: ["How does the wire adapter work?", "What are message parts?"],
|
|
10158
|
+
attachments: { accept: ["application/pdf"] },
|
|
10159
|
+
history: { persistence: "local" },
|
|
10160
|
+
// The template's defining fact, stated even though it matches the emit
|
|
10161
|
+
// default (B-4): the row already renders; strip: true is the visible
|
|
10162
|
+
// switch this template exists around.
|
|
10163
|
+
sources: { strip: true },
|
|
10164
|
+
// "assistant-style actions" (B-13) — the owner's A3 default matrix
|
|
10165
|
+
// (builder-message-actions.tsx: user Edit on; assistant
|
|
10166
|
+
// Copy/Like/Dislike on).
|
|
10167
|
+
messageActions: { user: ["edit"], assistant: ["copy", "like", "dislike"] }
|
|
10168
|
+
}
|
|
10169
|
+
};
|
|
10170
|
+
const workspaceTriggers = {
|
|
10171
|
+
triggers: {
|
|
10172
|
+
slash: [
|
|
10173
|
+
{ id: "summarize", label: "summarize", description: "Summarize the thread so far" },
|
|
10174
|
+
{ id: "translate", label: "translate", description: "Translate the last message" }
|
|
10175
|
+
],
|
|
10176
|
+
mention: [
|
|
10177
|
+
{ id: "researcher", label: "researcher", description: "Hands off to the research agent" },
|
|
10178
|
+
{ id: "coder", label: "coder", description: "Hands off to the coding agent" }
|
|
10179
|
+
]
|
|
10180
|
+
}
|
|
10181
|
+
};
|
|
10182
|
+
const workspaceBase = {
|
|
10183
|
+
$schema: CONSTRUCT_SCHEMA_URL,
|
|
10184
|
+
name: "build-workspace",
|
|
10185
|
+
layout: "split",
|
|
10186
|
+
provider: { mode: "mock" },
|
|
10187
|
+
header: {
|
|
10188
|
+
title: "Workspace",
|
|
10189
|
+
themeToggle: true,
|
|
10190
|
+
// The story's Share/Deploy rows, mapped onto the kit Button's real
|
|
10191
|
+
// variant names (B-6a's enum): 'secondary' → outline, 'primary' → default.
|
|
10192
|
+
actions: [
|
|
10193
|
+
{ label: "Share", variant: "outline" },
|
|
10194
|
+
{ label: "Deploy", variant: "default" }
|
|
10195
|
+
]
|
|
10196
|
+
},
|
|
10197
|
+
// Dark-by-default (owner ruling, dark round) — see inAppAssistantStarter's
|
|
10198
|
+
// note above. Both variants below spread ...workspaceBase without
|
|
10199
|
+
// overriding theme, so this covers artifactPreview and appPreview too.
|
|
10200
|
+
theme: { accent: "#ea580c", mode: "dark" },
|
|
10201
|
+
shell: { commandPalette: true, userMenu: { name: "Ada", plan: "Pro" } },
|
|
10202
|
+
composer: workspaceTriggers,
|
|
10203
|
+
capabilities: {
|
|
10204
|
+
starters: ["Build a pricing table", "Add a dark mode toggle"],
|
|
10205
|
+
attachments: { accept: ["image/*"] },
|
|
10206
|
+
history: { persistence: "local" }
|
|
10207
|
+
}
|
|
10208
|
+
};
|
|
10209
|
+
const workspaceArtifactPreview = {
|
|
10210
|
+
...workspaceBase,
|
|
10211
|
+
name: "artifact-workspace"
|
|
10212
|
+
};
|
|
10213
|
+
const workspaceAppPreview = {
|
|
10214
|
+
...workspaceBase,
|
|
10215
|
+
name: "app-workspace",
|
|
10216
|
+
capabilities: {
|
|
10217
|
+
...workspaceBase.capabilities,
|
|
10218
|
+
starters: ["Build a landing page for a coffee shop", "Make the hero work on mobile"]
|
|
10219
|
+
}
|
|
10220
|
+
};
|
|
10221
|
+
const TEMPLATES = [
|
|
10222
|
+
{
|
|
10223
|
+
id: "widget",
|
|
10224
|
+
name: "Support widget",
|
|
10225
|
+
description: "A floating chat that lives in the corner of your site.",
|
|
10226
|
+
availability: "buildable",
|
|
10227
|
+
starter: widgetStarter,
|
|
10228
|
+
controls: [IDENTITY, THEME, HEADER, HOME, CAPABILITIES, WIDGET_CHROME, PROVIDER]
|
|
10229
|
+
},
|
|
10230
|
+
{
|
|
10231
|
+
id: "inAppAssistant",
|
|
10232
|
+
name: "In-app assistant",
|
|
10233
|
+
description: "An assistant docked inside your existing app.",
|
|
10234
|
+
availability: "buildable",
|
|
10235
|
+
starter: inAppAssistantStarter,
|
|
10236
|
+
// Design-parity fix wave (2026-08-29 audit): the story's In-app
|
|
10237
|
+
// assistant panel shows Composer triggers, Message actions and a
|
|
10238
|
+
// read-only Cards list, none of which were wired here even though the
|
|
10239
|
+
// vocabulary and the panel machinery both already exist (proven working
|
|
10240
|
+
// on Workspace/Assistant/Research). Voice/Reveal-mode/Rail-placement
|
|
10241
|
+
// stay absent — those are the story's own labeled preview-only,
|
|
10242
|
+
// T-5-deferred fields with no construct vocabulary at all.
|
|
10243
|
+
controls: [IDENTITY, THEME, HEADER, ASIDE, COMPOSER_TRIGGERS, CAPABILITIES, MESSAGE_ACTIONS, CARDS, PROVIDER]
|
|
10244
|
+
},
|
|
10245
|
+
{
|
|
10246
|
+
id: "assistant",
|
|
10247
|
+
name: "Assistant",
|
|
10248
|
+
description: "A full-page assistant with a history of past conversations.",
|
|
10249
|
+
availability: "buildable",
|
|
10250
|
+
starter: assistantStarter,
|
|
10251
|
+
// Design-parity fix wave: the story's Assistant panel shows an App
|
|
10252
|
+
// chrome / Shell section (Command palette toggle, User menu) that
|
|
10253
|
+
// wasn't wired here — same already-working vocabulary as Workspace's
|
|
10254
|
+
// SHELL section.
|
|
10255
|
+
controls: [IDENTITY, THEME, HEADER, SHELL, EMPTY, CAPABILITIES, MESSAGE_ACTIONS, PROVIDER]
|
|
10256
|
+
},
|
|
10257
|
+
{
|
|
10258
|
+
id: "research",
|
|
10259
|
+
name: "Research",
|
|
10260
|
+
description: "Search-first answers with cited sources.",
|
|
10261
|
+
availability: "buildable",
|
|
10262
|
+
starter: researchStarter,
|
|
10263
|
+
controls: [IDENTITY, THEME, HEADER, CAPABILITIES, SOURCES, MESSAGE_ACTIONS, PROVIDER]
|
|
10264
|
+
},
|
|
10265
|
+
{
|
|
10266
|
+
id: "workspace",
|
|
10267
|
+
name: "Workspace",
|
|
10268
|
+
description: "Chat drives a live work surface: previews, code, and artifacts build beside the conversation.",
|
|
10269
|
+
availability: "buildable",
|
|
10270
|
+
starter: workspaceBase,
|
|
10271
|
+
variants: [
|
|
10272
|
+
{
|
|
10273
|
+
id: "artifactPreview",
|
|
10274
|
+
name: "Artifact preview beside chat",
|
|
10275
|
+
description: "A code or rendered-output pane grows beside the conversation as you build.",
|
|
10276
|
+
starter: workspaceArtifactPreview
|
|
10277
|
+
},
|
|
10278
|
+
{
|
|
10279
|
+
id: "appPreview",
|
|
10280
|
+
name: "App preview with device toggles",
|
|
10281
|
+
description: "A full browser-chrome preview of the running app, with desktop, tablet, and mobile views.",
|
|
10282
|
+
starter: workspaceAppPreview
|
|
10283
|
+
}
|
|
10284
|
+
],
|
|
10285
|
+
controls: [
|
|
10286
|
+
IDENTITY,
|
|
10287
|
+
THEME,
|
|
10288
|
+
HEADER_CHROME,
|
|
10289
|
+
SHELL,
|
|
10290
|
+
COMPOSER_TRIGGERS,
|
|
10291
|
+
CAPABILITIES,
|
|
10292
|
+
MESSAGE_ACTIONS,
|
|
10293
|
+
PROVIDER
|
|
10294
|
+
]
|
|
10295
|
+
},
|
|
10296
|
+
{
|
|
10297
|
+
id: "voice",
|
|
10298
|
+
name: "Voice",
|
|
10299
|
+
description: "A voice-first assistant you talk to, push-to-talk and all.",
|
|
10300
|
+
availability: "story-only"
|
|
10301
|
+
}
|
|
10302
|
+
];
|
|
10303
|
+
function buildableTemplates() {
|
|
10304
|
+
return TEMPLATES.filter((t) => t.availability === "buildable");
|
|
10305
|
+
}
|
|
9858
10306
|
const inputSchema = z$1.object({
|
|
9859
10307
|
intent: z$1.string().min(1).optional().describe("What the author wants, in their words. Alone: returns a starter construct."),
|
|
9860
10308
|
construct: z$1.record(z$1.string(), z$1.unknown()).optional().describe("The FULL construct JSON for this turn. The harness owns the file; send all of it every turn.")
|
|
9861
10309
|
}).strict();
|
|
10310
|
+
const INTENT_PATTERNS = [
|
|
10311
|
+
{ id: "widget", re: /\b(?:widget|embed|bubble|corner|launcher)\b/i },
|
|
10312
|
+
{ id: "research", re: /\b(?:research|search|cite|citation|sources?)\b/i },
|
|
10313
|
+
{ id: "workspace", re: /\b(?:workspace|split|pane|artifact|side.?by.?side|preview)\b/i },
|
|
10314
|
+
{ id: "inAppAssistant", re: /\b(?:aside|dock|in.?app|copilot|console|sidebar)\b/i },
|
|
10315
|
+
{ id: "assistant", re: /\b(?:assistant|chat\s*(?:app|bot)|full.?screen)\b/i }
|
|
10316
|
+
];
|
|
9862
10317
|
function starterFor(intent) {
|
|
9863
|
-
const
|
|
10318
|
+
const templates = buildableTemplates();
|
|
9864
10319
|
const name = "my-chat";
|
|
10320
|
+
const tagQuestion = `What should the element tag be? (kebab-case, e.g. "acme-support"; using "${name}" until you say)`;
|
|
10321
|
+
const match = INTENT_PATTERNS.find((p) => p.re.test(intent));
|
|
10322
|
+
const template = match ? templates.find((t) => t.id === match.id) : void 0;
|
|
10323
|
+
if (!template) {
|
|
10324
|
+
return {
|
|
10325
|
+
construct: {
|
|
10326
|
+
$schema: CONSTRUCT_SCHEMA_URL,
|
|
10327
|
+
name,
|
|
10328
|
+
layout: "fullscreen",
|
|
10329
|
+
provider: { mode: "mock" }
|
|
10330
|
+
},
|
|
10331
|
+
stated: [
|
|
10332
|
+
"no template implied — starting from a bare fullscreen construct. Templates available:",
|
|
10333
|
+
...templates.map((t) => ` · ${t.id} — ${t.name}: ${t.description}`)
|
|
10334
|
+
],
|
|
10335
|
+
questions: [
|
|
10336
|
+
tagQuestion,
|
|
10337
|
+
"Which template fits? (name one of the ids above, or keep the bare construct)"
|
|
10338
|
+
]
|
|
10339
|
+
};
|
|
10340
|
+
}
|
|
10341
|
+
const construct = structuredClone(template.starter);
|
|
10342
|
+
construct.name = name;
|
|
9865
10343
|
return {
|
|
9866
|
-
construct
|
|
9867
|
-
|
|
9868
|
-
name
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
},
|
|
9872
|
-
stated: impliesWidget ? ["layout: widget (implied by your request)"] : [],
|
|
9873
|
-
questions: [
|
|
9874
|
-
`What should the element tag be? (kebab-case, e.g. "acme-support"; using "${name}" until you say)`,
|
|
9875
|
-
...impliesWidget ? [] : ["Layout: widget, fullscreen, aside, split, or custom?"]
|
|
9876
|
-
]
|
|
10344
|
+
construct,
|
|
10345
|
+
stated: [
|
|
10346
|
+
`template: ${template.id} (${template.name}) — implied by your request; every field below is yours to edit`
|
|
10347
|
+
],
|
|
10348
|
+
questions: [tagQuestion]
|
|
9877
10349
|
};
|
|
9878
10350
|
}
|
|
9879
10351
|
const constructTool = {
|