@kitn.ai/ui 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
- package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.js} +1 -1
- package/dist/arrow-down-D783iMJj.js +1 -0
- package/dist/arrow-left-0VLM5kyg.js +1 -0
- package/dist/artifact-DGjzHYUT.js +1 -0
- package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
- package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
- package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
- package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
- package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
- package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
- package/dist/check-CiEOVnEN.js +1 -0
- package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
- package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
- package/dist/chevron-down-CSobuZRG.js +1 -0
- package/dist/chevron-right-DR9ZAP-2.js +1 -0
- package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
- package/dist/circle-BC66EYF7.js +1 -0
- package/dist/circle-check-BqmahW0O.js +1 -0
- package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
- package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
- package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
- package/dist/components/builder-composer-triggers.d.ts +62 -0
- package/dist/components/builder-layout.d.ts +54 -0
- package/dist/components/builder-message-actions.d.ts +72 -0
- package/dist/components/builder-panel.d.ts +189 -0
- package/dist/components/builder-preview.d.ts +11 -0
- package/dist/components/builder-shell-controls.d.ts +69 -0
- package/dist/components/builder-skeleton.d.ts +58 -0
- package/dist/components/builder-start.d.ts +75 -0
- package/dist/components/builder-workspace-variants.d.ts +23 -0
- package/dist/components/captions.d.ts +66 -0
- package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
- package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
- package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
- package/dist/controllable-BagRpyHv.js +1 -0
- package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
- package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
- package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
- package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
- package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
- package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
- package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
- package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
- package/dist/define-CI0y3eE4.js +1 -0
- package/dist/define.js +40 -40
- package/dist/define.server.js +45 -45
- package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
- package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.js} +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +1 -1
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.js +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
- package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
- package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
- package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
- package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
- package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
- package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
- package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
- package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
- package/dist/index.js +1741 -1725
- package/dist/index.server.js +1582 -1566
- package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
- package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
- package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
- package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
- package/dist/loader-KvJB6NrT.js +1 -0
- package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
- package/dist/mcp.es.js +8 -4
- package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
- package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
- package/dist/message-circle-BPpp5QKv.js +1 -0
- package/dist/message-square-BLbsd9BJ.js +1 -0
- package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
- package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
- package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
- package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
- package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
- package/dist/play-BXy1u7rW.js +1 -0
- package/dist/primitives/use-auto-resize.d.ts +11 -0
- package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
- package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
- package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
- package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
- package/dist/register-impl-DvEnhIxx.js +424 -0
- package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
- package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
- package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
- package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
- package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
- package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
- package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
- package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
- package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
- package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
- package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
- package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
- package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
- package/dist/solid.d.ts +6 -0
- package/dist/solid.js +259 -254
- package/dist/solid.server.js +259 -254
- package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
- package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
- package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
- package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
- package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
- package/dist/text-shimmer-BSzgEnDH.js +1 -0
- package/dist/textarea-DrYNt_0z.js +1 -0
- package/dist/theme.tokens.css +22 -21
- package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
- package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
- package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
- package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
- package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
- package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
- package/dist/ui/color-field.d.ts +48 -0
- package/dist/ui/textarea.d.ts +4 -0
- package/dist/ui/toggle-chip.d.ts +40 -0
- package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
- package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
- package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
- package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
- package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
- package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
- package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
- package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
- package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
- package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
- package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
- package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
- package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
- package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
- package/dist/x-eiO9V6J6.js +1 -0
- package/kit-base.css +311 -0
- package/package.json +17 -2
- package/solid.css +33 -0
- package/theme.css +39 -23
- package/dist/arrow-down-CjRU3JgV.js +0 -1
- package/dist/arrow-left-Bnpb1UEW.js +0 -1
- package/dist/artifact-Bwt7OgcR.js +0 -1
- package/dist/check-njkVdZu2.js +0 -1
- package/dist/chevron-down-B72s6PXR.js +0 -1
- package/dist/chevron-right-BatuHzUm.js +0 -1
- package/dist/circle-check-B62pODB3.js +0 -1
- package/dist/circle-zx0ByzY9.js +0 -1
- package/dist/controllable-CnGpMF6r.js +0 -1
- package/dist/define-By-uL588.js +0 -1
- package/dist/loader-BM4CEz4G.js +0 -1
- package/dist/message-circle-DruwObfX.js +0 -1
- package/dist/message-square-BG6q6mlm.js +0 -1
- package/dist/play-BvKKq3fX.js +0 -1
- package/dist/register-impl-B1hLkrI8.js +0 -424
- package/dist/text-shimmer-Dcj1MHuq.js +0 -1
- package/dist/textarea-Dpvbngbg.js +0 -1
- package/dist/x-Z5UntkIJ.js +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
export type BuilderViewport = 'desktop' | 'tablet' | 'mobile';
|
|
3
|
+
export interface BuilderLayoutProps {
|
|
4
|
+
/** The construct's display name, shown in the toolbar. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** The inspector panel content — typically `<BuilderPanel>`. */
|
|
7
|
+
panel: JSX.Element;
|
|
8
|
+
/** The preview content — typically a device frame wrapping `<ChatThread>`.
|
|
9
|
+
* Callers that need to reflow their OWN preview at narrower widths (e.g.
|
|
10
|
+
* a docked-rail template collapsing to full-bleed on `mobile`, matching
|
|
11
|
+
* `ui/dock.tsx`'s own <=480px takeover) should read `viewport`/
|
|
12
|
+
* `defaultViewport`/`onViewportChange` below and drive their preview's
|
|
13
|
+
* shape from the same signal they hand this component — see
|
|
14
|
+
* `builder-in-app-assistant.stories.tsx` and `builder.stories.tsx` for
|
|
15
|
+
* the pattern. */
|
|
16
|
+
preview: JSX.Element;
|
|
17
|
+
/** Controlled viewport selection. Omit for uncontrolled (internal) state,
|
|
18
|
+
* same controlled/uncontrolled convention as `Switch`'s
|
|
19
|
+
* `checked`/`defaultChecked` and `ToggleChip`'s `pressed`/
|
|
20
|
+
* `defaultPressed`. A caller that needs to reflow its own `preview` JSX
|
|
21
|
+
* per viewport (see the doc comment on `preview`) should lift this to a
|
|
22
|
+
* signal of its own and pass both this and `onViewportChange`. */
|
|
23
|
+
viewport?: BuilderViewport;
|
|
24
|
+
/** Initial viewport when uncontrolled. Defaults to `'desktop'`. */
|
|
25
|
+
defaultViewport?: BuilderViewport;
|
|
26
|
+
/** Fires with the next viewport on chip selection (controlled or not). */
|
|
27
|
+
onViewportChange?: (viewport: BuilderViewport) => void;
|
|
28
|
+
/** Stub export/save action; the real seam (a file write, per the spike) isn't
|
|
29
|
+
* built here. */
|
|
30
|
+
onSave?: () => void;
|
|
31
|
+
class?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `BuilderLayout` — the two-pane builder shell: a fixed-width scrollable
|
|
35
|
+
* inspector on the left, a live preview on the right over a dotted canvas
|
|
36
|
+
* background (a deliberate "this is a design tool" cue, not a real device
|
|
37
|
+
* emulator). A thin toolbar strip carries the construct name, a viewport
|
|
38
|
+
* toggle, and a stub Export action.
|
|
39
|
+
*
|
|
40
|
+
* The viewport toggle (Round A4 — was a round-1 visual stub) constrains the
|
|
41
|
+
* PREVIEW FRAME's width: `desktop` fills the pane exactly as before (no
|
|
42
|
+
* wrapper, no width style — the historical "stub" behavior for that one
|
|
43
|
+
* case); `tablet`/`mobile` wrap `preview` in a centered frame sized to
|
|
44
|
+
* `FRAME_WIDTH` above (768px / 390px), letting whatever `preview` renders
|
|
45
|
+
* reflow inside it. This is still not a real device emulator — no bezel,
|
|
46
|
+
* no user-agent spoofing, no touch simulation — just a width constraint,
|
|
47
|
+
* consistent with the doc comment this replaced.
|
|
48
|
+
*
|
|
49
|
+
* Pure shell: `panel` and `preview` are handed in as JSX so this component
|
|
50
|
+
* carries no opinion about what fills them; reflowing the CONTENT of
|
|
51
|
+
* `preview` at a given width (rather than just its outer box) is the
|
|
52
|
+
* caller's job — see the `preview` prop's own doc comment.
|
|
53
|
+
*/
|
|
54
|
+
export declare function BuilderLayout(props: BuilderLayoutProps): JSX.Element;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { JSX, Component } from 'solid-js';
|
|
2
|
+
import { ChatMessageAction, CustomAction } from '../elements/chat-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The role-scoped, ordered message-action picker — extracted from
|
|
5
|
+
* `builder-in-app-assistant.stories.tsx` (Round A3) into this standalone
|
|
6
|
+
* module during the T-1 build-out so the Assistant and Research templates
|
|
7
|
+
* (both asked for a "message actions, role-scoped picker, reuse" section)
|
|
8
|
+
* share one definition instead of forking it. `builder-in-app-assistant.
|
|
9
|
+
* stories.tsx` was retrofitted to import from here in the same round; its
|
|
10
|
+
* rendered output and behavior are unchanged — this is a pure extraction.
|
|
11
|
+
*
|
|
12
|
+
* Model: `ChatMessage.actions` (`elements/chat-types.ts`) is `(ChatMessage
|
|
13
|
+
* Action | CustomAction)[]` — an ORDERED array, not a set — and role-scoped
|
|
14
|
+
* only by caller curation (checked against `message.tsx`/`chat-thread.tsx`:
|
|
15
|
+
* neither hard-couples any built-in id to a role). This picker enforces
|
|
16
|
+
* role-appropriateness via two independent catalogs, one per role, each
|
|
17
|
+
* independently ordered and toggled.
|
|
18
|
+
*
|
|
19
|
+
* `'speak'` (read-aloud) is a kit-tier PROPOSAL, not a real
|
|
20
|
+
* `ChatMessageAction` value — voice OUTPUT exists as a separate element
|
|
21
|
+
* (`kai-voice-output`), not as a message-action id. When the row is
|
|
22
|
+
* enabled, callers should append `SPEAK_CUSTOM_ACTION` (a real, clickable,
|
|
23
|
+
* no-op `CustomAction`) rather than inventing a fake `ChatMessageAction`.
|
|
24
|
+
*/
|
|
25
|
+
export type UserActionId = Extract<ChatMessageAction, 'edit' | 'copy'>;
|
|
26
|
+
export type AssistantActionId = ChatMessageAction | 'speak';
|
|
27
|
+
export interface ActionRowDef<TId extends string> {
|
|
28
|
+
id: TId;
|
|
29
|
+
label: string;
|
|
30
|
+
/** A curated icon — same components `ui/action-icons.ts`'s registry maps
|
|
31
|
+
* each built-in id to, so the picker's icons match what the real action
|
|
32
|
+
* bar renders. */
|
|
33
|
+
icon: Component<{
|
|
34
|
+
class?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** Not a real `ChatMessageAction` today — see the module doc comment. */
|
|
37
|
+
proposed?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface ActionRowState<TId extends string> {
|
|
40
|
+
id: TId;
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare const USER_ACTION_CATALOG: readonly ActionRowDef<UserActionId>[];
|
|
44
|
+
export declare const ASSISTANT_ACTION_CATALOG: readonly ActionRowDef<AssistantActionId>[];
|
|
45
|
+
/** Owner defaults (Round A3): "Your messages" starts with only Edit on;
|
|
46
|
+
* "Assistant messages" starts with Copy/Like/Dislike on, Regenerate and
|
|
47
|
+
* the proposed Speak row off. Row ORDER here is also the default
|
|
48
|
+
* enabled-action order. */
|
|
49
|
+
export declare const DEFAULT_USER_ACTION_ROWS: ActionRowState<UserActionId>[];
|
|
50
|
+
export declare const DEFAULT_ASSISTANT_ACTION_ROWS: ActionRowState<AssistantActionId>[];
|
|
51
|
+
/** The real `CustomAction` a preview should append when the proposed Speak
|
|
52
|
+
* row is enabled — a genuine, clickable (no-op) button, never faked
|
|
53
|
+
* audio. `volume-2` is already a curated icon in `ui/action-icons.ts`'s
|
|
54
|
+
* registry. */
|
|
55
|
+
export declare const SPEAK_CUSTOM_ACTION: CustomAction;
|
|
56
|
+
/**
|
|
57
|
+
* One role's ordered, toggleable action list — a vertical list of rows
|
|
58
|
+
* (icon + label + a "Proposed" tag when the row is one + up/down reorder
|
|
59
|
+
* buttons + an enable switch). Row ORDER is the array order, and doubles
|
|
60
|
+
* as the enabled-action order once filtered — no separate "priority"
|
|
61
|
+
* field, because the component tier has no separate concept either.
|
|
62
|
+
*
|
|
63
|
+
* Up/down buttons over drag-and-drop: keyboard- and screen-reader-operable
|
|
64
|
+
* for free, which a bare drag handle is not, without extra work a design
|
|
65
|
+
* round doesn't need to do to prove the model (T-6).
|
|
66
|
+
*/
|
|
67
|
+
export declare function ActionRowPicker<TId extends string>(props: {
|
|
68
|
+
legend: string;
|
|
69
|
+
catalog: readonly ActionRowDef<TId>[];
|
|
70
|
+
rows: ActionRowState<TId>[];
|
|
71
|
+
onChange: (next: ActionRowState<TId>[]) => void;
|
|
72
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
export type BuilderLayoutKind = 'widget' | 'fullscreen' | 'aside' | 'split' | 'custom';
|
|
3
|
+
export type BuilderThemeMode = 'light' | 'dark' | 'system';
|
|
4
|
+
export type BuilderHistoryPersistence = 'none' | 'local' | 'endpoint';
|
|
5
|
+
export interface BuilderHomeLink {
|
|
6
|
+
label: string;
|
|
7
|
+
href?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
icon?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface BuilderHome {
|
|
12
|
+
greeting?: {
|
|
13
|
+
title?: string;
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
};
|
|
16
|
+
links?: BuilderHomeLink[];
|
|
17
|
+
}
|
|
18
|
+
export interface BuilderCapabilities {
|
|
19
|
+
starters?: string[];
|
|
20
|
+
attachments?: {
|
|
21
|
+
accept?: string[];
|
|
22
|
+
};
|
|
23
|
+
history?: {
|
|
24
|
+
persistence: BuilderHistoryPersistence;
|
|
25
|
+
};
|
|
26
|
+
conversations?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type BuilderWidgetPosition = 'bottom-end' | 'bottom-start' | 'top-end' | 'top-start';
|
|
29
|
+
/** `layout: 'widget'`-scoped FAB chrome — mirrors `construct.v1`'s own
|
|
30
|
+
* `widget` block. Meaningless on any other layout, which is exactly why
|
|
31
|
+
* the panel section it drives is HIDDEN, not just disabled, on any other
|
|
32
|
+
* layout (see the Layout section's own doc comment for that distinction). */
|
|
33
|
+
export interface BuilderWidget {
|
|
34
|
+
position?: BuilderWidgetPosition;
|
|
35
|
+
launcherIcon?: string;
|
|
36
|
+
defaultOpen?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export type BuilderProviderMode = 'mock' | 'endpoint';
|
|
39
|
+
export type BuilderProviderWire = 'openai' | 'anthropic';
|
|
40
|
+
/** Mirrors `construct.v1`'s own `provider` discriminated union
|
|
41
|
+
* (`agent-tooling/construct/schema.ts`'s `ProviderSchema`) — `mock` needs
|
|
42
|
+
* nothing else; `endpoint` needs the consumer's own chat route + wire
|
|
43
|
+
* format. A DISPLAY/edit stub, not a real one: no dev-server exists for
|
|
44
|
+
* this design round to actually call, so there's nothing to validate the
|
|
45
|
+
* URL against — the field exists so a template's panel shows the whole
|
|
46
|
+
* construct shape, not because this round wires it to anything. */
|
|
47
|
+
export interface BuilderProvider {
|
|
48
|
+
mode: BuilderProviderMode;
|
|
49
|
+
url?: string;
|
|
50
|
+
wire?: BuilderProviderWire;
|
|
51
|
+
}
|
|
52
|
+
/** Mirrors `construct.v1`'s own `cards` entry shape (`schema.ts`'s
|
|
53
|
+
* `cards` array): a tool-facing `name` plus the kit's card-schema JSON.
|
|
54
|
+
* `schema` is `Record<string, unknown>` here too — deep card validation
|
|
55
|
+
* (incl. `x-kai-format` mask hints) is the kit's own card contract at
|
|
56
|
+
* render time, not this stub panel's job; this stub only ever READS
|
|
57
|
+
* `schema.title` for a display label (Round A's read-only Cards section —
|
|
58
|
+
* see `BuilderPanelSections.cards`). */
|
|
59
|
+
export interface BuilderCard {
|
|
60
|
+
name: string;
|
|
61
|
+
schema?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
export interface BuilderConstruct {
|
|
64
|
+
name: string;
|
|
65
|
+
layout: BuilderLayoutKind;
|
|
66
|
+
provider?: BuilderProvider;
|
|
67
|
+
header?: {
|
|
68
|
+
title?: string;
|
|
69
|
+
};
|
|
70
|
+
theme?: {
|
|
71
|
+
accent?: string;
|
|
72
|
+
unreadColor?: string;
|
|
73
|
+
mode?: BuilderThemeMode;
|
|
74
|
+
};
|
|
75
|
+
home?: BuilderHome;
|
|
76
|
+
capabilities?: BuilderCapabilities;
|
|
77
|
+
widget?: BuilderWidget;
|
|
78
|
+
cards?: BuilderCard[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A template-scoped section configuration (Round W, T-2/T-6): a template
|
|
82
|
+
* FIXES its layout internally (no layout radio) and owns which of the
|
|
83
|
+
* layout-scoped sections apply — a widget template shows Widget chrome
|
|
84
|
+
* unconditionally (it IS the widget template, not merely "currently set to
|
|
85
|
+
* widget"), where the old layout-driven panel showed it only when the
|
|
86
|
+
* layout radio happened to be on "Widget". Omit this prop entirely to get
|
|
87
|
+
* the original, generic, layout-driven panel (every existing test above
|
|
88
|
+
* exercises that default) — a template panel opts INTO the narrower set
|
|
89
|
+
* rather than the generic panel opting out.
|
|
90
|
+
*/
|
|
91
|
+
export interface BuilderPanelSections {
|
|
92
|
+
/** Show the Layout radio section. Default `true` (the generic panel).
|
|
93
|
+
* A template panel sets this `false` — T-2: the template fixes the
|
|
94
|
+
* layout, so there is nothing left to choose here. */
|
|
95
|
+
layout?: boolean;
|
|
96
|
+
/** The Widget-chrome section's visibility. `'auto'` (default) follows
|
|
97
|
+
* `value.layout === 'widget'`, the original cross-field-visibility
|
|
98
|
+
* behavior. `'always'` shows it unconditionally — what a Support widget
|
|
99
|
+
* template panel wants, since for THAT template the section is never
|
|
100
|
+
* conditional, it's simply always this template's own controls.
|
|
101
|
+
* `'never'` hides it — what every non-widget template wants once each
|
|
102
|
+
* gets its own `Labs/Builder/<Template>` story. */
|
|
103
|
+
widget?: 'auto' | 'always' | 'never';
|
|
104
|
+
/** Show the Provider section (mode + endpoint URL/wire when applicable).
|
|
105
|
+
* Default `false` — the generic panel predates `provider` existing on
|
|
106
|
+
* `BuilderConstruct` at all; a template panel opts in. */
|
|
107
|
+
provider?: boolean;
|
|
108
|
+
/** Show the Home section (greeting/links tab). Default `true` (the
|
|
109
|
+
* generic panel). A template with no Home concept at all — In-app
|
|
110
|
+
* assistant (Round A): widget-only chrome, no Home/Messages tab bar in
|
|
111
|
+
* its own construct basis (`fixtures/ops-console.construct.json` has no
|
|
112
|
+
* `home` key) — sets this `false` to remove the section outright,
|
|
113
|
+
* rather than leaving a switch that would only ever read "off". */
|
|
114
|
+
home?: boolean;
|
|
115
|
+
/** Show a READ-ONLY Cards section: the construct's declared card names
|
|
116
|
+
* (Round A's `cards` addition to `BuilderConstruct`), with a muted note
|
|
117
|
+
* that editing them is a later round. Default `false`. Deliberately not
|
|
118
|
+
* an editor — a template whose construct basis carries `cards` (like
|
|
119
|
+
* `ops-console.construct.json`'s `deployment_parameters` form) still
|
|
120
|
+
* needs the panel to acknowledge them exist rather than silently
|
|
121
|
+
* dropping them from view, without this design round faking a card-
|
|
122
|
+
* schema editor it doesn't have (decide loudly, per CLAUDE.md). */
|
|
123
|
+
cards?: boolean;
|
|
124
|
+
}
|
|
125
|
+
export interface BuilderPanelProps {
|
|
126
|
+
/** The construct being edited. Controlled — the panel never holds its own copy. */
|
|
127
|
+
value: BuilderConstruct;
|
|
128
|
+
/** Fires with the next construct on every edit. */
|
|
129
|
+
onChange: (next: BuilderConstruct) => void;
|
|
130
|
+
/** Which sections render — see `BuilderPanelSections`. Omit for the
|
|
131
|
+
* original generic, layout-driven panel. */
|
|
132
|
+
sections?: BuilderPanelSections;
|
|
133
|
+
class?: string;
|
|
134
|
+
}
|
|
135
|
+
/** One "common case" chip for `capabilities.attachments.accept`: a human label
|
|
136
|
+
* over one or more raw MIME patterns. Owner feedback (design round 2):
|
|
137
|
+
* raw MIME types are hostile to the audience this panel is for, so the
|
|
138
|
+
* common cases get a toggle chip and the raw list is a secondary, visible
|
|
139
|
+
* ("Advanced") affordance rather than the primary input. */
|
|
140
|
+
export interface AcceptChip {
|
|
141
|
+
id: string;
|
|
142
|
+
label: string;
|
|
143
|
+
patterns: readonly string[];
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The chip → MIME-pattern map for the attachments accept editor below.
|
|
147
|
+
*
|
|
148
|
+
* Exported (not module-local) because it's exactly the vocabulary a future
|
|
149
|
+
* schema-driven wizard or capability menu (RECOMMENDATION.md's "real build")
|
|
150
|
+
* will also want — one place to widen the common-case list rather than a
|
|
151
|
+
* second one growing beside it.
|
|
152
|
+
*/
|
|
153
|
+
export declare const ACCEPT_CHIPS: readonly AcceptChip[];
|
|
154
|
+
/**
|
|
155
|
+
* `BuilderPanel` — the visual construct builder's inspector: identity, layout,
|
|
156
|
+
* theme, an optional Home tab, and capabilities. Pure props/callbacks, stub-
|
|
157
|
+
* friendly (no dev-server seam, no schema derivation) — a STORY-FIRST design
|
|
158
|
+
* surface for the panel's look, per RECOMMENDATION.md. Composed entirely from
|
|
159
|
+
* the kit's own controls (`Input`/`Textarea`/`Switch`/`RadioGroup`/`Select`/
|
|
160
|
+
* `Button`/`ColorField`/`ToggleChip`); no `part=` attributes — this component is not
|
|
161
|
+
* yet wired to a `kai-*` facade.
|
|
162
|
+
*
|
|
163
|
+
* Round W (T-2/T-6) added `sections` (`BuilderPanelSections`): omit it for
|
|
164
|
+
* the original generic, layout-driven panel this doc comment otherwise
|
|
165
|
+
* describes unchanged; pass it to scope the panel to ONE template's control
|
|
166
|
+
* set — no Layout radio, Widget chrome shown unconditionally rather than
|
|
167
|
+
* `layout`-conditionally, a Provider section — the shape `Labs/Builder/
|
|
168
|
+
* Support widget` (`src/elements/builder.stories.tsx`) actually uses.
|
|
169
|
+
*
|
|
170
|
+
* Three patterns from the spike (plus the owner's own round-8 ruling) get
|
|
171
|
+
* real design treatment here rather than being hand-waved:
|
|
172
|
+
* - **presence-as-boolean**: `home` and `capabilities.attachments` are each
|
|
173
|
+
* driven by ONE switch that adds/removes the whole sub-object, with its
|
|
174
|
+
* revealed fields directly below (no second "enabled" flag living beside
|
|
175
|
+
* the object it toggles).
|
|
176
|
+
* - **cross-field visibility, field-level**: `capabilities.conversations`
|
|
177
|
+
* requires `capabilities.history.persistence` to be `local`/`endpoint`
|
|
178
|
+
* (the schema's own `superRefine` rule) — shown as a disabled switch with
|
|
179
|
+
* the reason spelled out in muted text right below it, not a validation
|
|
180
|
+
* error surfaced after the fact.
|
|
181
|
+
* - **cross-field visibility, section-level**: the whole "Widget" section
|
|
182
|
+
* (position/launcher icon/open-by-default) is meaningless outside
|
|
183
|
+
* `layout: 'widget'`, and unlike the single Conversations toggle above, a
|
|
184
|
+
* disabled-and-explained SECTION would just be three greyed-out rows for
|
|
185
|
+
* one sentence's worth of reason — so it's hidden entirely, not disabled,
|
|
186
|
+
* whenever `layout` isn't `'widget'` (owner ruling, design round 8; see
|
|
187
|
+
* that section's own comment for the full distinction).
|
|
188
|
+
*/
|
|
189
|
+
export declare function BuilderPanel(props: BuilderPanelProps): JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BuilderConstruct } from './builder-panel.js';
|
|
2
|
+
/**
|
|
3
|
+
* The inline style object a stub preview's wrapper needs so a construct's
|
|
4
|
+
* `theme.accent` actually retints its descendants: both the public
|
|
5
|
+
* (`--kai-color-primary`) and internal (`--color-primary`) tokens, plus
|
|
6
|
+
* their paired foreground when the accent resolves to concrete RGB — see
|
|
7
|
+
* the module doc comment above for why both are required. Returns `{}` for
|
|
8
|
+
* no accent (the kit's own neutral default applies, same as omitting the
|
|
9
|
+
* property entirely).
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveAccentWrapperStyle(theme: BuilderConstruct['theme']): Record<string, string>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* "App chrome" — the Command palette and User menu shell knobs (owner
|
|
4
|
+
* discovery round), factored as a shared module so every shell-bearing
|
|
5
|
+
* template (`Labs/Builder/Assistant`, `.../Workspace`, `.../Multi-mode`)
|
|
6
|
+
* reuses the same real pieces instead of forking a fourth copy —
|
|
7
|
+
* consistent with `builder-composer-triggers.tsx`'s own rule-of-three
|
|
8
|
+
* extraction earlier this round.
|
|
9
|
+
*
|
|
10
|
+
* COMMAND PALETTE: composes the kit's real `CommandList` (`ui/command.tsx`)
|
|
11
|
+
* — a presentational grouped listbox — inside a hand-built overlay
|
|
12
|
+
* (backdrop + centered panel + Escape/backdrop-click to close), the SAME
|
|
13
|
+
* shape `elements/claude-code.stories.tsx`'s own command-center overlay
|
|
14
|
+
* uses around `kai-command` (read before building this — `CommandList` is
|
|
15
|
+
* that facade's underlying Solid piece; the facade adds the search input's
|
|
16
|
+
* filtering behavior itself, which `CommandList` does not own). A plain
|
|
17
|
+
* `Input` above the list does the filtering here, client-side over a stub
|
|
18
|
+
* catalog, matching claude-code's own placeholder copy style ("Search
|
|
19
|
+
* commands...").
|
|
20
|
+
*
|
|
21
|
+
* USER MENU: `elements/user-menu.stories.tsx`'s own doc comment states it
|
|
22
|
+
* plainly — "the user menu is a RECIPE, not an element... kai-menu with a
|
|
23
|
+
* slotted trigger (kai-avatar + name + plan + a chevron + a kai-status
|
|
24
|
+
* dot)". Reused here as the Solid-tier equivalent: `Dropdown`/
|
|
25
|
+
* `DropdownTrigger`/`DropdownContent`/`DropdownItem` (the same primitives
|
|
26
|
+
* `components/model-switcher.tsx` and the Workspace composer menu already
|
|
27
|
+
* compose) with an `Avatar` + name/plan trigger.
|
|
28
|
+
*/
|
|
29
|
+
export interface ShellControlsState {
|
|
30
|
+
commandPalette: boolean;
|
|
31
|
+
userMenu: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** The command palette overlay — mounted only while `open`. Filters the
|
|
34
|
+
* stub catalog client-side; selecting a row or pressing Escape closes it. */
|
|
35
|
+
export declare function CommandPaletteOverlay(props: {
|
|
36
|
+
open: boolean;
|
|
37
|
+
onClose: () => void;
|
|
38
|
+
}): JSX.Element;
|
|
39
|
+
/** The command palette's TRIGGER — a plain search-icon button, matching
|
|
40
|
+
* claude-code's own rail-header search affordance. Rendering the overlay
|
|
41
|
+
* itself is the caller's job (`CommandPaletteOverlay`), so a template can
|
|
42
|
+
* place the trigger inside its own rail/header chrome while the overlay
|
|
43
|
+
* mounts at the frame root. */
|
|
44
|
+
export declare function CommandPaletteTrigger(props: {
|
|
45
|
+
onOpen: () => void;
|
|
46
|
+
}): JSX.Element;
|
|
47
|
+
/** The user-menu recipe itself — avatar + name/plan trigger, real Dropdown
|
|
48
|
+
* primitives, a stub items list (Settings/Help/Log out). `compact` (owner
|
|
49
|
+
* feedback round, Workspace's app-header rework) drops the name/plan text
|
|
50
|
+
* entirely, rendering avatar + chevron only — for a header utility cluster
|
|
51
|
+
* where the full name/plan reads as too much next to icon-only siblings.
|
|
52
|
+
* `name`/`plan` still feed the avatar initials and the accessible name
|
|
53
|
+
* (`aria-label`) even when compact, so the control never loses its name to
|
|
54
|
+
* assistive tech just because the text is hidden visually. */
|
|
55
|
+
export declare function UserMenu(props: {
|
|
56
|
+
name: string;
|
|
57
|
+
plan?: string;
|
|
58
|
+
class?: string;
|
|
59
|
+
compact?: boolean;
|
|
60
|
+
}): JSX.Element;
|
|
61
|
+
/** The panel section every shell-bearing template reuses: two toggles,
|
|
62
|
+
* "Command palette" and "User menu." Preview-only — see each template's
|
|
63
|
+
* own module doc comment for how the toggles wire into ITS OWN chrome
|
|
64
|
+
* (the trigger/overlay/menu placement differs per template's real
|
|
65
|
+
* anatomy, so this section only owns the on/off state, not the layout). */
|
|
66
|
+
export declare function ShellSection(props: {
|
|
67
|
+
state: ShellControlsState;
|
|
68
|
+
onChange: (v: ShellControlsState) => void;
|
|
69
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* Shared wordless-skeleton language for `Labs/Builder/<Template>` preview
|
|
4
|
+
* hosts (docs/superpowers/specs/2026-08-28-template-builder-design.md).
|
|
5
|
+
*
|
|
6
|
+
* Extracted from `builder-in-app-assistant.stories.tsx` (Round A2) into this
|
|
7
|
+
* standalone module during the T-1 build-out (Assistant/Research/Workspace/
|
|
8
|
+
* Voice) so every template's "the rest of your app" skeleton chrome shares
|
|
9
|
+
* one definition instead of four copies drifting apart — the cross-cutting
|
|
10
|
+
* mandate the design spec's Process step names ("as shared needs emerge,
|
|
11
|
+
* refactor the shared components ONCE"). `builder-in-app-assistant.stories.tsx`
|
|
12
|
+
* was retrofitted to import from here in the same round; nothing about its
|
|
13
|
+
* rendered output changed.
|
|
14
|
+
*
|
|
15
|
+
* PLAIN inline CSS (`color-mix`), not a Tailwind opacity-modifier class
|
|
16
|
+
* on a color utility or an arbitrary-bracket width value — see the
|
|
17
|
+
* original Round A2 note in git blame: this Storybook dev server's
|
|
18
|
+
* Tailwind JIT pass proved non-deterministic for FRESH combinations
|
|
19
|
+
* introduced by a single file (a class would show correctly in the rendered
|
|
20
|
+
* `className` while `getComputedStyle` reported the rule simply wasn't
|
|
21
|
+
* compiled). `color-mix()` is real CSS with no compile step to race, and
|
|
22
|
+
* matches what Tailwind's own `/NN` opacity modifier generates.
|
|
23
|
+
*/
|
|
24
|
+
export declare function mix(colorVar: string, pct: number): string;
|
|
25
|
+
/** One skeleton bar/pill. `widthClass` for a standard-scale Tailwind width
|
|
26
|
+
* utility (proven reliable); `width` for an inline CSS width (a
|
|
27
|
+
* percentage, or anything arbitrary); `flex` to grow and fill instead of
|
|
28
|
+
* taking either. Height is always a standard-scale utility unless
|
|
29
|
+
* overridden. */
|
|
30
|
+
export declare function SkeletonBar(props: {
|
|
31
|
+
widthClass?: string;
|
|
32
|
+
width?: string;
|
|
33
|
+
heightClass?: string;
|
|
34
|
+
pct: number;
|
|
35
|
+
flex?: boolean;
|
|
36
|
+
}): JSX.Element;
|
|
37
|
+
/** A grayscale/muted skeleton stat tile: a label bar over a bigger number
|
|
38
|
+
* bar. Deliberately toneless (muted-foreground tints only, never
|
|
39
|
+
* `bg-primary`/accent) so the host reads as chrome around the product
|
|
40
|
+
* rather than product itself. */
|
|
41
|
+
export declare function StubStatTile(props: {
|
|
42
|
+
class?: string;
|
|
43
|
+
}): JSX.Element;
|
|
44
|
+
/** A single stub nav-rail row: an icon-ish dot plus a label bar. `active`
|
|
45
|
+
* lights the row the way a real nav's current-page item would. */
|
|
46
|
+
export declare function StubNavRow(props: {
|
|
47
|
+
active?: boolean;
|
|
48
|
+
}): JSX.Element;
|
|
49
|
+
/** A single stub table row: a handful of column bars at staggered widths,
|
|
50
|
+
* so the row reads as data rather than one flat block. */
|
|
51
|
+
export declare function StubTableRow(): JSX.Element;
|
|
52
|
+
/** A wordless skeleton code/text block: a stack of bars at staggered
|
|
53
|
+
* widths, monospace rhythm (shorter, denser bars) rather than prose
|
|
54
|
+
* rhythm — for the Workspace template's artifact/code pane. */
|
|
55
|
+
export declare function StubCodeBlock(props: {
|
|
56
|
+
lines?: number;
|
|
57
|
+
class?: string;
|
|
58
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
export type BuilderTemplateId = 'widget' | 'inAppAssistant' | 'assistant' | 'research' | 'workspace' | 'voice' | 'scratch';
|
|
3
|
+
/** The template ids that DO have a card — every `BuilderTemplateId` except
|
|
4
|
+
* `'scratch'`, which has no illustration and never appears in
|
|
5
|
+
* `BUILDER_TEMPLATES`. */
|
|
6
|
+
export type BuilderCardTemplateId = Exclude<BuilderTemplateId, 'scratch'>;
|
|
7
|
+
export interface BuilderTemplate {
|
|
8
|
+
id: BuilderCardTemplateId;
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
/** V1 templates, in build order (T-1: easiest to hardest, so controls
|
|
13
|
+
* accumulate template to template). Names and one-liners are the T-4/T-7
|
|
14
|
+
* copy this round exists to force into existence. Round P2 grows the set
|
|
15
|
+
* from four to six (In-app assistant, Voice) and sharpens the four
|
|
16
|
+
* existing one-liners for instant recognition. */
|
|
17
|
+
export declare const BUILDER_TEMPLATES: readonly BuilderTemplate[];
|
|
18
|
+
export interface BuilderStartProps {
|
|
19
|
+
/** The currently selected template id, or unset for none yet. Controlled —
|
|
20
|
+
* this component holds no selection state of its own. */
|
|
21
|
+
value?: BuilderTemplateId;
|
|
22
|
+
/**
|
|
23
|
+
* Fires with a template's id when its card is chosen. Click-to-advance
|
|
24
|
+
* (design choice, this round): T-7 says "selection advances to that
|
|
25
|
+
* template's builder", and there is nothing a second "Continue" step
|
|
26
|
+
* would add here that the click itself doesn't already mean — a
|
|
27
|
+
* disambiguating confirm step belongs to T-2's SWITCHING-template case
|
|
28
|
+
* (control set changes, so a re-pick needs a confirm), not to picking a
|
|
29
|
+
* template for the first time. So `onSelect` fires on the same click that
|
|
30
|
+
* shows the selected ring; the story's Continue readout below just proves
|
|
31
|
+
* the callback fired, since there's no template builder screen yet to
|
|
32
|
+
* navigate to.
|
|
33
|
+
*/
|
|
34
|
+
onSelect: (id: BuilderTemplateId) => void;
|
|
35
|
+
class?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const BLUEPRINT_BG: {
|
|
38
|
+
readonly 'background-image': "radial-gradient(circle, var(--color-border) 1px, transparent 1px)";
|
|
39
|
+
readonly 'background-size': "14px 14px";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* `BuilderStart` — the builder's opening screen: six selectable template
|
|
43
|
+
* cards (T-7, grown from four in Round P2). Each card is a real
|
|
44
|
+
* `ui/card.tsx` `Card` (`clickable`,
|
|
45
|
+
* `media` for the illustration, `header` for the name), not a hand-rolled
|
|
46
|
+
* button — the kit's own primitive already gives a `role="button"` with
|
|
47
|
+
* Enter/Space activation, which settles this screen's keyboard-semantics
|
|
48
|
+
* question: a `radiogroup` was the other defensible reading (this IS a
|
|
49
|
+
* single choice among six), but `Card` already implements exactly the
|
|
50
|
+
* button-per-card pattern with no extra wiring, and reusing it beats
|
|
51
|
+
* building a second selection primitive for one screen.
|
|
52
|
+
*
|
|
53
|
+
* Brand alignment (T-7): the kit's own tokens throughout — no new color, no
|
|
54
|
+
* new radius, no new type stack. The illustrations are the one genuinely new
|
|
55
|
+
* visual element this round adds; see `TEMPLATE_ILLUSTRATIONS` below for
|
|
56
|
+
* their shared style rules.
|
|
57
|
+
*/
|
|
58
|
+
export declare function BuilderStart(props: BuilderStartProps): JSX.Element;
|
|
59
|
+
export declare const STROKE = 1.5;
|
|
60
|
+
export declare const LINE: {
|
|
61
|
+
stroke: string;
|
|
62
|
+
fill: string;
|
|
63
|
+
};
|
|
64
|
+
export declare const BORDER: {
|
|
65
|
+
stroke: string;
|
|
66
|
+
fill: string;
|
|
67
|
+
};
|
|
68
|
+
export declare const ACCENT: {
|
|
69
|
+
stroke: string;
|
|
70
|
+
fill: string;
|
|
71
|
+
};
|
|
72
|
+
export declare const ACCENT_FILL: {
|
|
73
|
+
stroke: string;
|
|
74
|
+
fill: string;
|
|
75
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
export type WorkspaceVariantId = 'artifactPreview' | 'appPreview';
|
|
3
|
+
export interface WorkspaceVariant {
|
|
4
|
+
id: WorkspaceVariantId;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const WORKSPACE_VARIANTS: readonly WorkspaceVariant[];
|
|
9
|
+
export interface WorkspaceVariantPickerProps {
|
|
10
|
+
value?: WorkspaceVariantId;
|
|
11
|
+
onSelect: (id: WorkspaceVariantId) => void;
|
|
12
|
+
onBack: () => void;
|
|
13
|
+
class?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* `WorkspaceVariantPicker` — the Workspace family's second screen: two
|
|
17
|
+
* function-named variant cards (smaller-scale `Card`s, reusing `Builder
|
|
18
|
+
* Start`'s own pattern) plus a back affordance to the template picker.
|
|
19
|
+
* Selection fires `onSelect` with the variant id the same click-to-advance
|
|
20
|
+
* shape `BuilderStart` itself uses (T-7's own reasoning: nothing a second
|
|
21
|
+
* "Continue" step would add here that the click doesn't already mean).
|
|
22
|
+
*/
|
|
23
|
+
export declare function WorkspaceVariantPicker(props: WorkspaceVariantPickerProps): JSX.Element;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* `Captions` — live closed-captioning: the text shown WHILE someone (the
|
|
4
|
+
* user or the agent) is speaking, distinct from a scrollback transcript.
|
|
5
|
+
* Built for the Voice template (`elements/builder-voice.stories.tsx`) but
|
|
6
|
+
* kept generic — any voice surface that wants a caption line can use this
|
|
7
|
+
* directly.
|
|
8
|
+
*
|
|
9
|
+
* - Driven by `segments`, oldest first — the LAST entry is the current
|
|
10
|
+
* line. Everything else is history, only rendered by `stacked`.
|
|
11
|
+
* - `variant` picks the chrome: `'lower-third'` (a semi-opaque bar, the
|
|
12
|
+
* broadcast-caption look), `'floating'` (a card that floats above a
|
|
13
|
+
* visualizer, `kai-elevation`), `'minimal'` (bare text, no chrome — the
|
|
14
|
+
* original shape this component shipped with), `'stacked'` (the last two
|
|
15
|
+
* lines of history fade in behind the current line, which stays full
|
|
16
|
+
* strength). Default `'minimal'`.
|
|
17
|
+
* - Speaker-aware via `data-speaker` + a small uppercase label ("You" /
|
|
18
|
+
* "Assistant") — NOT a color swap. Accent stays reserved for the
|
|
19
|
+
* visualizer per the owner's Voice-round instruction, so the distinction
|
|
20
|
+
* lives in the label and a subtle weight difference, both drawn from the
|
|
21
|
+
* muted/foreground tiers, never `text-primary`.
|
|
22
|
+
* - Interim (`final: false`) text renders `text-muted-foreground` / a hair
|
|
23
|
+
* lighter than a finalized line's `text-foreground`, so a caption visibly
|
|
24
|
+
* "settles" the moment the model (or the ASR) commits it.
|
|
25
|
+
* - Undefined/empty `segments`, or a current segment whose `text` is empty
|
|
26
|
+
* or whitespace-only, renders NOTHING — a real `<Show>` around a presence
|
|
27
|
+
* gate, not a hidden/zero-opacity node left in the DOM.
|
|
28
|
+
* - One `role="status"`/`aria-live="polite"` region, wrapping ONLY the
|
|
29
|
+
* current line — `stacked`'s history lines sit outside it
|
|
30
|
+
* (`aria-hidden="true"`) so they don't get re-announced every time the
|
|
31
|
+
* region's content changes. This mirrors `toast.tsx`'s
|
|
32
|
+
* `role="region"`/`aria-live="polite"` pattern (the kit's other
|
|
33
|
+
* speech-adjacent live region) rather than inventing a second policy, and
|
|
34
|
+
* is the ONLY live region this component renders — it says nothing about
|
|
35
|
+
* history, so it can't double-announce anything a transcript component
|
|
36
|
+
* elsewhere on the page is already announcing.
|
|
37
|
+
* - Appear/update reuses the kit's real exit-animation primitive,
|
|
38
|
+
* `createPresence` (`ui/overlay.tsx`), for the whole component's
|
|
39
|
+
* mount/unmount, and a keyed `<For>` around the current line so a NEW
|
|
40
|
+
* segment object (the same "new object per changed item" contract the
|
|
41
|
+
* rest of the kit's reactive props follow) retriggers its own
|
|
42
|
+
* `animate-in` rather than being silently patched in place. Both use the
|
|
43
|
+
* same already-compiled `animate-in ... data-[closed]:animate-out ...`
|
|
44
|
+
* Tailwind-animate classes `DropdownContent`/`DialogContent`/
|
|
45
|
+
* `HoverCardContent` use, and both carry `motion-reduce:animate-none` (the
|
|
46
|
+
* same pattern `screen.tsx`/`dialog.tsx` use) so `prefers-reduced-motion:
|
|
47
|
+
* reduce` turns the animation off entirely — the text still appears,
|
|
48
|
+
* updates and disappears, just without motion.
|
|
49
|
+
*/
|
|
50
|
+
export interface CaptionSegment {
|
|
51
|
+
/** Whose speech this line represents. */
|
|
52
|
+
speaker: 'user' | 'assistant';
|
|
53
|
+
/** The line's text. Empty/whitespace on the CURRENT segment renders nothing. */
|
|
54
|
+
text: string;
|
|
55
|
+
/** Whether ASR/the model has committed this line. Default `true`. */
|
|
56
|
+
final?: boolean;
|
|
57
|
+
}
|
|
58
|
+
export type CaptionsVariant = 'lower-third' | 'floating' | 'minimal' | 'stacked';
|
|
59
|
+
export interface CaptionsProps {
|
|
60
|
+
/** Caption lines, oldest first. The last entry is the current line. */
|
|
61
|
+
segments?: CaptionSegment[];
|
|
62
|
+
/** Which visual treatment to render. Default `'minimal'`. */
|
|
63
|
+
variant?: CaptionsVariant;
|
|
64
|
+
class?: string;
|
|
65
|
+
}
|
|
66
|
+
export declare function Captions(props: CaptionsProps): JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as Ye,g as z,w as Je,k as Q,j as de,o as ue,x as De,h as Qe,i as N,u as Ne,a as H,d as O,b as Z,l as ee,c as $,F as Oe,S as G,t as S,Q as Ze,e as et}from"./define-
|
|
1
|
+
import{A as Ye,g as z,w as Je,k as Q,j as de,o as ue,x as De,h as Qe,i as N,u as Ne,a as H,d as O,b as Z,l as ee,c as $,F as Oe,S as G,t as S,Q as Ze,e as et}from"./define-CI0y3eE4.js";import{c as P}from"./cn-DN5AWfiS.js";import{u as tt,c as nt,a as rt}from"./overlay-DBMFXie6.js";function M(n){if(n==null)return[];if(typeof n=="string")return n.length?[{type:"text",text:n}]:[];const l=[];for(const t of n)if(t.type==="text"){if(!t.text)continue;const i=l[l.length-1];i&&i.type==="text"?l[l.length-1]={type:"text",text:i.text+t.text}:l.push({type:"text",text:t.text})}else l.push({type:"entity",entity:t.entity});return l}function te(n,l){let t="";for(const i of n)i.type==="text"?t+=i.text:t+=i.entity.promptText??i.entity.label;return t}function he(n){return n.filter(l=>l.type==="entity").map(l=>l.entity)}function ne(n){return n.every(l=>l.type==="text"&&l.text.length===0)}const C="\u200B",pe="data-kai-entity",fe=new WeakMap;function U(n){return!!n&&n.nodeType===1&&n.hasAttribute(pe)}function re(n){return n.ownerDocument.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode(l){let t=l.parentElement;for(;t&&t!==n;){if(t.hasAttribute(pe))return NodeFilter.FILTER_REJECT;t=t.parentElement}return NodeFilter.FILTER_ACCEPT}})}function ot(n){switch(n){case"skill":return"/";case"agent":return"@";default:return""}}function Le(n){const l=t=>`<svg viewBox="0 0 24 24" width="1em" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${t}</svg>`;switch(n){case"agent":return l('<rect x="4" y="8" width="16" height="12" rx="3"/><path d="M12 4.5V8M9.5 13.5v1.5M14.5 13.5v1.5"/><circle cx="12" cy="3" r="1.2"/>');case"plugin":return l('<path d="M9 2v4M15 2v4M6 6h12v5a6 6 0 0 1-12 0zM12 17v5"/>');default:return""}}function Ie(n,l,t){const i=n.createElement("span");i.setAttribute(pe,""),i.setAttribute("contenteditable","false"),i.dataset.kind=l.kind,i.dataset.id=l.id,i.className="kai-composer-pill";const u=ot(l.kind);if(u){const s=n.createElement("span");s.className="kai-composer-pill-sigil",s.setAttribute("aria-hidden","true"),s.textContent=u,i.appendChild(s)}else{const s=l.icon??t?.[l.kind];if(s){const h=n.createElement("img");h.src=s,h.alt="",h.className="kai-composer-pill-icon",i.appendChild(h)}else{const h=Le(l.kind);if(h){const f=n.createElement("span");f.className="kai-composer-pill-icon kai-composer-pill-glyph",f.setAttribute("aria-hidden","true"),f.innerHTML=h,i.appendChild(f)}}}return i.appendChild(n.createTextNode(l.label)),fe.set(i,l),i}function L(n){const l=[],t=n.childNodes;return t.forEach((i,u)=>{if(U(i)){const s=fe.get(i),h=i;l.push({type:"entity",entity:s??{kind:h.dataset.kind??"",id:h.dataset.id??"",label:h.textContent??""}})}else if(i.nodeType===1&&i.tagName==="BR"){if(u===t.length-1)return;l.push({type:"text",text:`
|
|
2
2
|
`})}else i.nodeType===3&&l.push({type:"text",text:(i.textContent??"").split(C).join("")})}),M(l)}function oe(n,l,t=document,i){n.textContent="";for(const u of l)u.type==="text"?n.appendChild(t.createTextNode(u.text)):(n.appendChild(Ie(t,u.entity,i)),n.appendChild(t.createTextNode(C)))}function it(n,l,t){if(l<0||l>n.length)return null;for(let i=l-1;i>=0;i--){const u=n[i];if(/\s/.test(u))return null;if(t.includes(u))return i===0||/\s/.test(n[i-1])?{char:u,query:n.slice(i+1,l),start:i}:null}return null}function at(n,l,t){if(!t.length)return null;const i=t.map(h=>h.char),u=it(n,l,i);if(!u)return null;const s=t.find(h=>h.char===u.char);return s?{def:s,query:u.query,start:u.start}:null}function lt(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function st(n,l){const t=[];for(const s of l){let h,f;typeof s=="string"?(h=new RegExp(lt(s),"gi"),f=void 0):(h=new RegExp(s.pattern,s.flags??"gi"),f=s.class),h.lastIndex=0;let k;for(;(k=h.exec(n))!==null;){const x=k.index,w=x+k[0].length;if(w===x){h.lastIndex=x+1;continue}t.push({start:x,end:w,class:f})}}t.sort((s,h)=>s.start-h.start);const i=[];let u=-1;for(const s of t)s.start>=u&&(i.push(s),u=s.end);return i}function ct(){try{return typeof CSS<"u"&&typeof CSS.highlights<"u"&&typeof Highlight<"u"}catch{return!1}}const dt="kai-composer-highlight";function ut(n,l,t,i=dt){if(!ct())return;const u=CSS.highlights;if(l.length===0){u.delete(i);return}const s=[];let h=0;const f=n.ownerDocument,k=re(n);let x=k.nextNode();for(;x;){const v=x.textContent??"",b=[];for(let p=0;p<v.length;p++)v[p]!==t&&b.push(p);if(b.length>0){const p=new Int32Array(b.length);for(let m=0;m<b.length;m++)p[m]=b[m];s.push({node:x,strippedStart:h,strippedToRaw:p}),h+=b.length}x=k.nextNode()}function w(v){let b=0,p=s.length-1;for(;b<=p;){const m=b+p>>1,T=s[m],q=T.strippedStart+T.strippedToRaw.length;if(v<T.strippedStart)p=m-1;else if(v>=q)b=m+1;else{const R=v-T.strippedStart;return{node:T.node,rawOffset:T.strippedToRaw[R]}}}if(s.length>0){const m=s[s.length-1];if(v-m.strippedStart===m.strippedToRaw.length)return{node:m.node,rawOffset:m.strippedToRaw[m.strippedToRaw.length-1]+1}}return null}const y=[];for(const v of l){const b=w(v.start),p=w(v.end);if(!b||!p)continue;const m=f.createRange();m.setStart(b.node,b.rawOffset),m.setEnd(p.node,p.rawOffset),y.push(m)}if(y.length===0){u.delete(i);return}const A=new Highlight(...y);u.set(i,A)}function ht(n,l=200){let t=[n],i=0;return{record(u,s){if(s&&i===t.length-1){t[i]=u;return}t=t.slice(0,i+1),t.push(u),t.length>l?t.shift():i++},undo(){return i===0?null:(i--,t[i])},redo(){return i>=t.length-1?null:(i++,t[i])},reset(u){t=[u],i=0},canUndo(){return i>0},canRedo(){return i<t.length-1},size(){return t.length}}}var pt=S("<style>"),ft=S(`<style>
|
|
3
3
|
.kai-composer-pill {
|
|
4
4
|
display: inline-flex; align-items: center; gap: 0.2rem;
|