@runtypelabs/persona 4.8.0 → 4.10.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.
Files changed (130) hide show
  1. package/README.md +14 -1
  2. package/dist/animations/glyph-cycle.d.cts +1 -1
  3. package/dist/animations/glyph-cycle.d.ts +1 -1
  4. package/dist/animations/{types-BsZtXPKK.d.cts → types-4ROVJ1gA.d.cts} +42 -0
  5. package/dist/animations/{types-BsZtXPKK.d.ts → types-4ROVJ1gA.d.ts} +42 -0
  6. package/dist/animations/wipe.d.cts +1 -1
  7. package/dist/animations/wipe.d.ts +1 -1
  8. package/dist/chunk-IO5VVUKP.js +3 -0
  9. package/dist/chunk-IPVK3KOM.js +1 -0
  10. package/dist/chunk-UPO4GUFC.js +1 -0
  11. package/dist/codegen.cjs +6 -6
  12. package/dist/codegen.js +8 -8
  13. package/dist/context-mentions-7S5KVUTG.js +169 -0
  14. package/dist/context-mentions-inline-TTCN7ZM2.js +4 -0
  15. package/dist/context-mentions-inline.cjs +4 -0
  16. package/dist/context-mentions-inline.d.cts +203 -0
  17. package/dist/context-mentions-inline.d.ts +203 -0
  18. package/dist/context-mentions-inline.js +4 -0
  19. package/dist/context-mentions.cjs +295 -0
  20. package/dist/context-mentions.d.cts +7025 -0
  21. package/dist/context-mentions.d.ts +7025 -0
  22. package/dist/context-mentions.js +295 -0
  23. package/dist/index.cjs +72 -64
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +634 -3
  26. package/dist/index.d.ts +634 -3
  27. package/dist/index.global.js +59 -51
  28. package/dist/index.global.js.map +1 -1
  29. package/dist/index.js +64 -56
  30. package/dist/index.js.map +1 -1
  31. package/dist/launcher.global.js +2 -2
  32. package/dist/launcher.global.js.map +1 -1
  33. package/dist/plugin-kit.cjs +1 -1
  34. package/dist/plugin-kit.d.cts +17 -0
  35. package/dist/plugin-kit.d.ts +17 -0
  36. package/dist/plugin-kit.js +1 -1
  37. package/dist/smart-dom-reader.cjs +17 -16
  38. package/dist/smart-dom-reader.d.cts +507 -1
  39. package/dist/smart-dom-reader.d.ts +507 -1
  40. package/dist/smart-dom-reader.js +17 -16
  41. package/dist/theme-editor-preview.cjs +236 -57
  42. package/dist/theme-editor-preview.d.cts +485 -1
  43. package/dist/theme-editor-preview.d.ts +485 -1
  44. package/dist/theme-editor-preview.js +53 -47
  45. package/dist/theme-editor.cjs +7 -7
  46. package/dist/theme-editor.d.cts +473 -0
  47. package/dist/theme-editor.d.ts +473 -0
  48. package/dist/theme-editor.js +5 -5
  49. package/dist/theme-reference.cjs +1 -1
  50. package/dist/theme-reference.d.cts +2 -0
  51. package/dist/theme-reference.d.ts +2 -0
  52. package/dist/widget.css +1 -1
  53. package/package.json +15 -3
  54. package/src/client.test.ts +69 -0
  55. package/src/client.ts +65 -51
  56. package/src/components/artifact-pane.test.ts +47 -0
  57. package/src/components/artifact-pane.ts +25 -2
  58. package/src/components/composer-parts.ts +3 -12
  59. package/src/components/context-mention-button.test.ts +70 -0
  60. package/src/components/context-mention-button.ts +82 -0
  61. package/src/components/context-mention-chip.ts +134 -0
  62. package/src/components/context-mention-menu.test.ts +508 -0
  63. package/src/components/context-mention-menu.ts +0 -0
  64. package/src/components/message-bubble.test.ts +175 -0
  65. package/src/components/message-bubble.ts +177 -19
  66. package/src/components/panel.ts +7 -10
  67. package/src/context-mentions-bundle.test.ts +163 -0
  68. package/src/context-mentions-entry.ts +185 -0
  69. package/src/context-mentions-inline-entry.test.ts +136 -0
  70. package/src/context-mentions-inline-entry.ts +226 -0
  71. package/src/context-mentions-inline-loader.test.ts +30 -0
  72. package/src/context-mentions-inline-loader.ts +36 -0
  73. package/src/context-mentions-inline.ts +15 -0
  74. package/src/context-mentions-loader.ts +32 -0
  75. package/src/context-mentions.ts +16 -0
  76. package/src/index-core.ts +27 -0
  77. package/src/index-global.ts +51 -0
  78. package/src/markdown-parsers-loader.ts +35 -44
  79. package/src/plugin-kit.test.ts +40 -0
  80. package/src/plugin-kit.ts +39 -5
  81. package/src/runtime/init-update-reset.test.ts +81 -0
  82. package/src/runtime/init.test.ts +62 -0
  83. package/src/runtime/init.ts +7 -14
  84. package/src/session.mentions.test.ts +175 -0
  85. package/src/session.test.ts +52 -4
  86. package/src/session.ts +121 -5
  87. package/src/smart-dom-reader.test.ts +129 -2
  88. package/src/smart-dom-reader.ts +127 -1
  89. package/src/styles/context-mention-menu-css.ts +176 -0
  90. package/src/styles/widget.css +243 -126
  91. package/src/theme-editor/sections.ts +3 -3
  92. package/src/types/theme.ts +2 -0
  93. package/src/types.ts +542 -0
  94. package/src/ui.artifact-pane-gating.test.ts +11 -1
  95. package/src/ui.attachments-drop.test.ts +90 -0
  96. package/src/ui.header-update-stability.test.ts +149 -0
  97. package/src/ui.launcher-update-merge.test.ts +83 -0
  98. package/src/ui.mention-submit.test.ts +235 -0
  99. package/src/ui.send-button-stream-update.test.ts +69 -0
  100. package/src/ui.ts +379 -84
  101. package/src/utils/chunk-loader.test.ts +97 -0
  102. package/src/utils/chunk-loader.ts +88 -0
  103. package/src/utils/composer-contenteditable.test.ts +507 -0
  104. package/src/utils/composer-contenteditable.ts +626 -0
  105. package/src/utils/composer-document.test.ts +280 -0
  106. package/src/utils/composer-document.ts +293 -0
  107. package/src/utils/composer-history.test.ts +35 -7
  108. package/src/utils/composer-history.ts +30 -20
  109. package/src/utils/composer-input.ts +159 -0
  110. package/src/utils/config-merge.test.ts +131 -0
  111. package/src/utils/config-merge.ts +61 -0
  112. package/src/utils/context-mention-controller.test.ts +1215 -0
  113. package/src/utils/context-mention-controller.ts +1186 -0
  114. package/src/utils/context-mention-manager.test.ts +422 -0
  115. package/src/utils/context-mention-manager.ts +410 -0
  116. package/src/utils/context-mention-orchestrator.test.ts +538 -0
  117. package/src/utils/context-mention-orchestrator.ts +348 -0
  118. package/src/utils/live-region.test.ts +108 -0
  119. package/src/utils/live-region.ts +94 -0
  120. package/src/utils/mention-channels.ts +63 -0
  121. package/src/utils/mention-llm-format.test.ts +91 -0
  122. package/src/utils/mention-llm-format.ts +79 -0
  123. package/src/utils/mention-matcher.test.ts +86 -0
  124. package/src/utils/mention-matcher.ts +221 -0
  125. package/src/utils/mention-token.ts +72 -0
  126. package/src/utils/mention-trigger.test.ts +155 -0
  127. package/src/utils/mention-trigger.ts +156 -0
  128. package/src/utils/theme.test.ts +54 -4
  129. package/src/utils/theme.ts +6 -3
  130. package/src/utils/tokens.ts +27 -11
@@ -423,6 +423,8 @@ interface ComponentTokenSet {
423
423
  margin?: TokenReference<'spacing'>;
424
424
  shadow?: TokenReference<'shadow'>;
425
425
  opacity?: number;
426
+ /** Hover background — used by transparent variants like `button.ghost`. */
427
+ hoverBackground?: TokenReference<'color'>;
426
428
  }
427
429
  interface ButtonTokens extends ComponentTokenSet {
428
430
  primary: ComponentTokenSet;
@@ -1739,6 +1741,446 @@ type AgentWidgetContextProviderContext = {
1739
1741
  config: AgentWidgetConfig;
1740
1742
  };
1741
1743
  type AgentWidgetContextProvider = (context: AgentWidgetContextProviderContext) => Record<string, unknown> | void | Promise<Record<string, unknown> | void>;
1744
+ /** A single selectable item in the mention menu (host-provided). */
1745
+ type AgentWidgetContextMentionItem = {
1746
+ /** Stable key within its source. */
1747
+ id: string;
1748
+ /** Shown in the menu and on the chip (e.g. "App.tsx"). */
1749
+ label: string;
1750
+ /** Subtitle line in the menu. */
1751
+ description?: string;
1752
+ /** Lucide icon name. */
1753
+ iconName?: string;
1754
+ /**
1755
+ * Accent color for this item's inline token (`display: "inline"`), any CSS
1756
+ * color. Sets `--persona-mention-token-accent` on the token, tinting its pill
1757
+ * background + icon/label — the per-item/per-type color knob (Slack/Linear
1758
+ * style). Prefer setting the same color across a source's items for a "color
1759
+ * per type" look, or theme by `[data-mention-source]` in CSS instead. Ignored
1760
+ * in chip mode.
1761
+ */
1762
+ color?: string;
1763
+ /** Group header override; defaults to the source's `label`. */
1764
+ group?: string;
1765
+ /** Optional recency/popularity hint the default matcher boosts on. */
1766
+ recencyScore?: number;
1767
+ /**
1768
+ * SKILLS / SLASH-COMMANDS. When set, this item is a COMMAND (a verb) rather
1769
+ * than a context mention (a noun), so selecting it dispatches a behavior
1770
+ * instead of adding a context chip. Absent for ordinary mentions.
1771
+ *
1772
+ * - `"prompt"`: a prompt macro. `resolve()` returns `insertText` (or
1773
+ * `llmAppend`) which is written into the composer (see `insertMode`);
1774
+ * `submitOnSelect` optionally sends it immediately. No chip.
1775
+ * - `"action"`: a client action. `action()` runs in the browser; no resolve,
1776
+ * no chip, no message sent (e.g. `/clear`, `/theme dark`).
1777
+ * - `"server"`: a server-invoked skill. Routed like a `resolveOn:"submit"`
1778
+ * mention whose `resolve().context` reaches the backend via request
1779
+ * `context.mentions.<sourceId>.<itemId>` (a flow/agent reads it).
1780
+ */
1781
+ command?: "prompt" | "action" | "server";
1782
+ /**
1783
+ * `command:"action"` handler. Receives the parsed `args` (text after the
1784
+ * command name), plus a small `composer` capability + `config`/`messages`.
1785
+ * Short-circuits the mention flow (no chip, no send). Ignored otherwise.
1786
+ */
1787
+ action?: (ctx: AgentWidgetContextMentionCommandContext) => void | Promise<void>;
1788
+ /**
1789
+ * `command:"prompt"` insertion mode. `"replace"` (default) swaps the whole
1790
+ * composer value for the resolved text; `"insert-at-caret"` replaces only the
1791
+ * `/token` span, keeping surrounding prose. Ignored otherwise.
1792
+ */
1793
+ insertMode?: "replace" | "insert-at-caret";
1794
+ /**
1795
+ * When true, a `command:"prompt"` submits the composer immediately after
1796
+ * inserting its text (a one-shot macro). Ignored for other kinds.
1797
+ */
1798
+ submitOnSelect?: boolean;
1799
+ /**
1800
+ * COMMANDS only. Ghost hint for a free-text argument (e.g. "order id" →
1801
+ * `/lookup ‹order id›` in the menu). Its presence switches the command to
1802
+ * INLINE COMPLETION (Slack-style): selecting it fills `/name ` into the
1803
+ * composer for inline arg entry instead of dispatching on select, and the
1804
+ * command is executed at SUBMIT with the typed args. `command:"server"` items
1805
+ * always use inline completion (their chip had no way to add an argument);
1806
+ * for `"prompt"`/`"action"` items this is opt-in. Ignored for non-commands.
1807
+ */
1808
+ commandArgsPlaceholder?: string;
1809
+ };
1810
+ /**
1811
+ * Capability object handed to a `command:"action"` handler. The widget exposes
1812
+ * only composer-local operations; broader actions (clear the transcript, change
1813
+ * theme) are wired by the host via closures over its own controller.
1814
+ */
1815
+ type AgentWidgetContextMentionComposerCapability = {
1816
+ /** Current composer text. */
1817
+ getValue: () => string;
1818
+ /** Replace composer text (fires `input`, moves caret to end, refocuses). */
1819
+ setValue: (value: string) => void;
1820
+ /** Submit the composer (same path as pressing send). */
1821
+ submit: () => void;
1822
+ };
1823
+ /** Context passed to a `command:"action"` handler. */
1824
+ type AgentWidgetContextMentionCommandContext = {
1825
+ /** Text typed after the command name (e.g. `staging` for `/deploy staging`). */
1826
+ args: string;
1827
+ config: AgentWidgetConfig;
1828
+ messages: AgentWidgetMessage[];
1829
+ composer: AgentWidgetContextMentionComposerCapability;
1830
+ };
1831
+ /** Reference stored on a sent message for transcript fidelity + chip rendering. */
1832
+ type AgentWidgetContextMentionRef = {
1833
+ sourceId: string;
1834
+ itemId: string;
1835
+ label: string;
1836
+ iconName?: string;
1837
+ /** Accent color for the inline token (see `AgentWidgetContextMentionItem.color`). */
1838
+ color?: string;
1839
+ };
1840
+ /**
1841
+ * One ordered segment of a sent message's prose, for inline mention rendering
1842
+ * (`contextMentions.display: "inline"`). Text runs and atomic mention tokens
1843
+ * interleave in document order so the sent bubble re-renders `@tokens` in place
1844
+ * and composer history can round-trip them. Display/transcript concern only —
1845
+ * the model still sees resolved bodies via `llmContent`/`contentParts`.
1846
+ */
1847
+ type AgentWidgetContentSegment = {
1848
+ kind: "text";
1849
+ text: string;
1850
+ } | {
1851
+ kind: "mention";
1852
+ ref: AgentWidgetContextMentionRef;
1853
+ };
1854
+ /**
1855
+ * The payload a source returns from `resolve()` for one selected item.
1856
+ * Lead with `llmAppend` — it is the only channel guaranteed to reach the model
1857
+ * with no backend changes.
1858
+ */
1859
+ type AgentWidgetContextMentionPayload = {
1860
+ /**
1861
+ * PRIMARY, model-visible channel. Appended to this user message's LLM content
1862
+ * so the model actually sees the context with no backend changes.
1863
+ */
1864
+ llmAppend?: string;
1865
+ /**
1866
+ * `command:"prompt"` macros only. Text written into the COMPOSER on select
1867
+ * (see `AgentWidgetContextMentionItem.insertMode`) — distinct from the hidden
1868
+ * `llmAppend` context channel. Falls back to `llmAppend` when omitted.
1869
+ */
1870
+ insertText?: string;
1871
+ /** Extra content parts (e.g. file text / image) via the multi-modal path. */
1872
+ contentParts?: ContentPart[];
1873
+ /**
1874
+ * OPT-IN structured channel. Merged into request `context` under
1875
+ * `mentions.<sourceId>.<itemId>` for flows/agents that read it. NOTE: ambient
1876
+ * `context` is NOT guaranteed to reach the model — use `llmAppend` if you need
1877
+ * the model to see it.
1878
+ */
1879
+ context?: Record<string, unknown>;
1880
+ };
1881
+ /**
1882
+ * One resolved mention, handed to `contextMentions.llmFormat` to build the
1883
+ * model-visible block. `text` is the source's `llmAppend`; `ref`/`item` carry
1884
+ * the selection identity/metadata for a custom formatter (e.g. a source-specific
1885
+ * wrapper or a path from `item`).
1886
+ */
1887
+ type AgentWidgetMentionLlmEntry = {
1888
+ /** The mention's display label (from `ref.label`). */
1889
+ label: string;
1890
+ /** The resolved model-visible body (the source's `llmAppend`). */
1891
+ text: string;
1892
+ ref: AgentWidgetContextMentionRef;
1893
+ item: AgentWidgetContextMentionItem;
1894
+ };
1895
+ type AgentWidgetContextMentionSearchContext = {
1896
+ messages: AgentWidgetMessage[];
1897
+ config: AgentWidgetConfig;
1898
+ /** Aborts when the next keystroke supersedes this in-flight search. */
1899
+ signal: AbortSignal;
1900
+ };
1901
+ type AgentWidgetContextMentionResolveContext = AgentWidgetContextMentionSearchContext & {
1902
+ /** Plain-text composer value at resolve time. */
1903
+ composerText: string;
1904
+ /**
1905
+ * For `command` items: the text typed after the command name (e.g.
1906
+ * `"123"` for `/lookup 123`). Empty string for ordinary mentions.
1907
+ */
1908
+ args: string;
1909
+ };
1910
+ type AgentWidgetContextMentionSource = {
1911
+ id: string;
1912
+ /** Group header shown in the menu. */
1913
+ label: string;
1914
+ /**
1915
+ * Filter items for the current `@query` (empty query → recent/popular).
1916
+ * Implement server-side search for large/remote sets, or return all items and
1917
+ * let the widget rank them with `defaultMentionFilter`
1918
+ * (see `createStaticMentionSource` for the common case).
1919
+ */
1920
+ search: (query: string, ctx: AgentWidgetContextMentionSearchContext) => AgentWidgetContextMentionItem[] | Promise<AgentWidgetContextMentionItem[]>;
1921
+ /**
1922
+ * Fetch the payload for dispatch. Called once when the user SELECTS the item
1923
+ * (eagerly, cached on the chip, abortable on removal) unless `resolveOn` is
1924
+ * `"submit"`. A throw/abort drops the mention via `onMentionResolveError`.
1925
+ */
1926
+ resolve: (item: AgentWidgetContextMentionItem, ctx: AgentWidgetContextMentionResolveContext) => AgentWidgetContextMentionPayload | Promise<AgentWidgetContextMentionPayload>;
1927
+ /**
1928
+ * When to call `resolve()`:
1929
+ * - `"select"` (default): eager on pick; parallelizes the fetch with the user
1930
+ * finishing their sentence so submit stays instant.
1931
+ * - `"submit"`: defer to send time, for time-sensitive sources (e.g. current
1932
+ * page state that may change between select and send).
1933
+ * @default "select"
1934
+ */
1935
+ resolveOn?: "select" | "submit";
1936
+ /**
1937
+ * COMMAND sources only. Resolve a `/name` (the first token of a command line)
1938
+ * to its menu item, for submit-time inline-command dispatch and the menu's
1939
+ * "typing args now" suppression. `createSlashCommandsSource` sets this; plain
1940
+ * `@`-mention sources leave it undefined.
1941
+ */
1942
+ matchCommand?: (name: string) => AgentWidgetContextMentionItem | undefined;
1943
+ };
1944
+ /** Context passed to the optional `renderMentionMenu` override. */
1945
+ type AgentWidgetContextMentionMenuRenderContext = {
1946
+ /** Current trigger query ("" when freshly opened). */
1947
+ query: string;
1948
+ /** Grouped, ranked, capped results ready to paint. */
1949
+ groups: {
1950
+ source: AgentWidgetContextMentionSource;
1951
+ items: AgentWidgetContextMentionItem[];
1952
+ }[];
1953
+ /** Per-source async state for loading/empty/error rendering, keyed by source id. */
1954
+ status: Record<string, "loading" | "ready" | "empty" | "error">;
1955
+ /** Index into the flat keyboard-traversal order. */
1956
+ activeIndex: number;
1957
+ /** Commit a selection (strips `@query`, adds chip, resolves on select). */
1958
+ select: (item: AgentWidgetContextMentionItem) => void;
1959
+ /** Close the menu, keeping a literal `@`. */
1960
+ close: () => void;
1961
+ };
1962
+ /** Context passed to the optional `renderMentionItem` per-row override. */
1963
+ type AgentWidgetContextMentionItemRenderContext = {
1964
+ /** The item to render. */
1965
+ item: AgentWidgetContextMentionItem;
1966
+ /** The source this item came from (its group). */
1967
+ source: AgentWidgetContextMentionSource;
1968
+ /** Current trigger query, for highlighting matches. */
1969
+ query: string;
1970
+ /** True when this row is the keyboard-highlighted one at render time. */
1971
+ active: boolean;
1972
+ /** Position in the flat keyboard-traversal order. */
1973
+ index: number;
1974
+ };
1975
+ /** Context passed to the optional `renderMentionChip` override. */
1976
+ type AgentWidgetContextMentionChipRenderContext = {
1977
+ ref: AgentWidgetContextMentionRef;
1978
+ /** Resolve-on-select lifecycle for spinner→ready→error UI. */
1979
+ status: "resolving" | "ready" | "error";
1980
+ /**
1981
+ * The resolved payload, once available (select-resolved sources only). Use it
1982
+ * to preview already-fetched content on hover. Undefined while `status` is
1983
+ * `"resolving"`, on `"error"`, and for `resolveOn:"submit"` sources (which
1984
+ * resolve at send time, not while the chip sits in the composer — for those,
1985
+ * `ref.itemId` carries the source key you can re-read on demand, e.g. a CSS
1986
+ * selector for the smart-dom source).
1987
+ */
1988
+ payload?: AgentWidgetContextMentionPayload;
1989
+ /** Remove the chip; aborts any in-flight resolve. */
1990
+ remove: () => void;
1991
+ };
1992
+ /**
1993
+ * Where a trigger char is allowed to open the menu:
1994
+ * - `"anywhere"` (default): after any whitespace or start (the `@` rule).
1995
+ * - `"line-start"`: only when the char before the trigger is a newline or the
1996
+ * start of input — the natural rule for `/` slash-commands.
1997
+ * - `"input-start"`: only at index 0 of the composer.
1998
+ */
1999
+ type AgentWidgetMentionTriggerPosition = "anywhere" | "line-start" | "input-start";
2000
+ /**
2001
+ * A SECOND (or Nth) trigger channel sharing the same menu engine — e.g. `/` for
2002
+ * slash-commands alongside `@` for context. The legacy `trigger`/`sources`
2003
+ * fields form the implicit first channel; `triggers[]` adds more. At any caret
2004
+ * at most one channel is active, so all channels drive one menu/controller.
2005
+ */
2006
+ type AgentWidgetMentionTriggerChannel = {
2007
+ /** Trigger character (e.g. "/"). */
2008
+ trigger: string;
2009
+ /** Sources for this channel (searched only when this trigger is active). */
2010
+ sources: AgentWidgetContextMentionSource[];
2011
+ /** Where the trigger may open. @default "anywhere" */
2012
+ triggerPosition?: AgentWidgetMentionTriggerPosition;
2013
+ /**
2014
+ * Let the query span spaces so a command can take ARGS (`/deploy staging`).
2015
+ * A newline still ends it. Pair with `triggerPosition: "line-start"` for
2016
+ * slash-commands. @default false
2017
+ */
2018
+ allowSpaces?: boolean;
2019
+ /** Show a composer affordance button for this channel. @default false */
2020
+ showButton?: boolean;
2021
+ /** Icon for this channel's affordance button. */
2022
+ buttonIconName?: string;
2023
+ /** Tooltip / aria-label for this channel's affordance button. */
2024
+ buttonTooltipText?: string;
2025
+ /** Placeholder for this channel's picker search field. */
2026
+ searchPlaceholder?: string;
2027
+ };
2028
+ type AgentWidgetContextMentionConfig = {
2029
+ /** @default false */
2030
+ enabled?: boolean;
2031
+ /**
2032
+ * Show the visible composer affordance button (the discoverable entry point).
2033
+ * Strongly recommended; the bare `@` trigger alone is hard to discover for
2034
+ * non-technical users. @default true
2035
+ */
2036
+ showButton?: boolean;
2037
+ /**
2038
+ * Icon for the affordance button (any registered Lucide name). Defaults to a
2039
+ * "+" signifier — the consumer-recognized "add context" affordance — rather
2040
+ * than an "@" glyph, which reads as power-user. Use `"at-sign"` on a
2041
+ * developer/power-user surface. @default "plus"
2042
+ */
2043
+ buttonIconName?: string;
2044
+ /** Tooltip / aria-label for the affordance button. @default "Add context" */
2045
+ buttonTooltipText?: string;
2046
+ /**
2047
+ * Placeholder for the picker's search field, shown when the menu is opened
2048
+ * from the affordance button (a Cursor/Copilot-style picker that inserts no
2049
+ * trigger character). The typed-trigger path keeps its query in the textarea
2050
+ * and never shows this field. @default "Search context…"
2051
+ */
2052
+ searchPlaceholder?: string;
2053
+ /** Trigger character. @default "@" */
2054
+ trigger?: string;
2055
+ /**
2056
+ * Where the primary `trigger` may open the menu. @default "anywhere"
2057
+ */
2058
+ triggerPosition?: AgentWidgetMentionTriggerPosition;
2059
+ /**
2060
+ * ADDITIONAL trigger channels sharing this engine — e.g. a `/` slash-command
2061
+ * channel next to `@` context. Each channel has its own trigger char,
2062
+ * sources, and position rule. See `AgentWidgetMentionTriggerChannel`.
2063
+ */
2064
+ triggers?: AgentWidgetMentionTriggerChannel[];
2065
+ /** Max mentions per message. @default 8 */
2066
+ maxMentions?: number;
2067
+ /** Max items shown per source group before "keep typing to narrow". @default 6 */
2068
+ maxItemsPerGroup?: number;
2069
+ /**
2070
+ * Debounce for ASYNC source search only (ms). Synchronous sources and the
2071
+ * menu's first paint are never debounced. @default 150
2072
+ */
2073
+ searchDebounceMs?: number;
2074
+ /** Registered mention sources (search + resolve). */
2075
+ sources: AgentWidgetContextMentionSource[];
2076
+ /** Chip icon fallback when a source/item omits one. @default "at-sign" */
2077
+ chipIconName?: string;
2078
+ /**
2079
+ * How each resolved mention's `llmAppend` text is wrapped into a delimited
2080
+ * block before it is prepended to the model-visible message content. Blocks
2081
+ * are joined with a blank line and the typed prose follows last.
2082
+ *
2083
+ * - `"fenced"` (default): a fenced code block with the label in the info
2084
+ * string, e.g. selecting `App.tsx` emits:
2085
+ * ```text
2086
+ * ```App.tsx
2087
+ * <file body>
2088
+ * ```
2089
+ * ```
2090
+ * The fence auto-escalates (four+ backticks) when the body itself contains a
2091
+ * fence, so a body can never terminate its own wrapper.
2092
+ * - `"document"`: Anthropic's long-context document shape, e.g.:
2093
+ * ```text
2094
+ * <document index="1">
2095
+ * <source>App.tsx</source>
2096
+ * <document_content>
2097
+ * <file body>
2098
+ * </document_content>
2099
+ * </document>
2100
+ * ```
2101
+ * Prefer this for prose/document-shaped sources per Anthropic's long-context
2102
+ * guidance (indexed `<document>` blocks improve grounding and citation). A
2103
+ * body containing the literal `</document_content>` closing tag falls back to
2104
+ * the fenced block for that entry to avoid a broken XML boundary.
2105
+ * - function form: fully owns the block for one mention — its return string is
2106
+ * used verbatim (no extra wrapping), joined with the other blocks. `index` is
2107
+ * the 0-based position among the message's mention blocks.
2108
+ *
2109
+ * @default "fenced"
2110
+ */
2111
+ llmFormat?: "fenced" | "document" | ((entry: AgentWidgetMentionLlmEntry, index: number) => string);
2112
+ /**
2113
+ * How `@` selections appear in the composer and sent user bubble.
2114
+ *
2115
+ * - `"chip"` (default): strip `@query` on select; show a compact pill in the
2116
+ * composer context row; `content` is prose-only.
2117
+ * - `"inline"`: insert an atomic styled token in the sentence (Slack/Linear/
2118
+ * Cursor style), backed by a contenteditable composer. Slash-command channels
2119
+ * (`triggers[]` with `/`) stay inline-text regardless — they already use the
2120
+ * `/name args` model, not chips. `renderMentionChip` is ignored for `@`
2121
+ * mentions in this mode.
2122
+ *
2123
+ * The resolved-context channel (`llmContent`/`contentParts`) is unchanged
2124
+ * across both modes — inline tokens are a display concern.
2125
+ *
2126
+ * @default "chip"
2127
+ */
2128
+ display?: "chip" | "inline";
2129
+ /**
2130
+ * Fired when a pick is rejected: it duplicates an existing chip in chip display
2131
+ * (`"duplicate"` — inline display allows the same item as multiple tokens, so it
2132
+ * never rejects for this reason), hits `maxMentions` (`"limit"`), or (inline
2133
+ * display) the composer text changed between parse and commit so the token could
2134
+ * not be inserted (`"stale"`).
2135
+ */
2136
+ onMentionRejected?: (item: AgentWidgetContextMentionItem, reason: "duplicate" | "limit" | "stale") => void;
2137
+ /**
2138
+ * A `resolve()` that throws/aborts: the mention is dropped and the message
2139
+ * still sends. Surface a non-blocking notice here if desired.
2140
+ */
2141
+ onMentionResolveError?: (item: AgentWidgetContextMentionItem, error: unknown) => void;
2142
+ /**
2143
+ * MID-LEVEL render override for the autocomplete menu. The widget still owns
2144
+ * trigger detection, search, debounce/abort, keyboard nav, and positioning;
2145
+ * you only supply the menu markup and drive selection through `ctx`. Omit to
2146
+ * use the built-in grouped menu. @default built-in
2147
+ */
2148
+ renderMentionMenu?: (ctx: AgentWidgetContextMentionMenuRenderContext) => HTMLElement;
2149
+ /**
2150
+ * NARROW render override for a single result row's INNER content, keeping the
2151
+ * built-in menu chrome (group headers, loading/empty/error, keyboard nav, the
2152
+ * "keep typing" hint). The widget keeps the `role="option"` wrapper and its
2153
+ * click/hover wiring; you return only the row's contents. For full menu
2154
+ * control use `renderMentionMenu` instead. Highlight is CSS-driven via the
2155
+ * wrapper's `[data-active]` attribute, so this is called once per render, not
2156
+ * on every arrow key. Ignored when `renderMentionMenu` is set. @default built-in
2157
+ */
2158
+ renderMentionItem?: (ctx: AgentWidgetContextMentionItemRenderContext) => HTMLElement;
2159
+ /**
2160
+ * MID-LEVEL render override for a single context chip. Return your own pill
2161
+ * (must include an accessible remove control wired to `ctx.remove`); reflect
2162
+ * `ctx.status` for resolve-on-select. Omit to use the built-in compact pill.
2163
+ * @default built-in
2164
+ */
2165
+ renderMentionChip?: (ctx: AgentWidgetContextMentionChipRenderContext) => HTMLElement;
2166
+ /**
2167
+ * INLINE display only (`display: "inline"`). Render override for a single inline
2168
+ * mention TOKEN — the atomic styled node that sits in the sentence, in both the
2169
+ * contenteditable composer and the read-only sent bubble. Return your own
2170
+ * element (e.g. a fully custom colored pill); the composer marks it
2171
+ * `contenteditable="false"` and stamps `data-mention-id` so it stays atomic.
2172
+ * Omit to use the built-in pill (icon + `@label`, tinted by
2173
+ * `--persona-mention-token-accent` / `ref.color`, themeable per source via the
2174
+ * `[data-mention-source]` attribute). Ignored in chip mode.
2175
+ * @default built-in
2176
+ */
2177
+ renderMentionToken?: (ctx: AgentWidgetContextMentionTokenRenderContext) => HTMLElement;
2178
+ };
2179
+ /** Render context for `renderMentionToken`. `readonly` is true in the sent bubble. */
2180
+ type AgentWidgetContextMentionTokenRenderContext = {
2181
+ ref: AgentWidgetContextMentionRef;
2182
+ readonly: boolean;
2183
+ };
1742
2184
  type AgentWidgetRequestPayloadMessage = {
1743
2185
  role: AgentWidgetMessageRole;
1744
2186
  content: MessageContent;
@@ -5757,6 +6199,18 @@ type AgentWidgetConfig = {
5757
6199
  }) => string;
5758
6200
  plugins?: AgentWidgetPlugin[];
5759
6201
  contextProviders?: AgentWidgetContextProvider[];
6202
+ /**
6203
+ * Context mentions: let users explicitly pull external context into a turn by
6204
+ * typing `@` or clicking a visible composer button, both opening one shared
6205
+ * searchable menu of host-provided sources. Selecting a mention adds a
6206
+ * removable pill chip; resolved content reaches the model via `llmAppend`
6207
+ * (default) or the opt-in structured `context` channel.
6208
+ *
6209
+ * Disabled by default. When enabled, the mention runtime is lazy-loaded from a
6210
+ * sibling chunk on first use, so sites that leave it off pay no bundle cost.
6211
+ * See `docs/context-mentions-plan.md`.
6212
+ */
6213
+ contextMentions?: AgentWidgetContextMentionConfig;
5760
6214
  requestMiddleware?: AgentWidgetRequestMiddleware;
5761
6215
  actionParsers?: AgentWidgetActionParser[];
5762
6216
  actionHandlers?: AgentWidgetActionHandler[];
@@ -6206,6 +6660,17 @@ type AgentWidgetConfig = {
6206
6660
  */
6207
6661
  loadingIndicator?: AgentWidgetLoadingIndicatorConfig;
6208
6662
  };
6663
+ /**
6664
+ * Patch-aware deep-partial of {@link AgentWidgetConfig} accepted by `update()`.
6665
+ * Function types and arrays are preserved whole (not mapped over); plain-object
6666
+ * leaves recurse so a partial patch merges into the live config. See the merge
6667
+ * policy in utils/config-merge.ts (some plain-object fields still replace
6668
+ * wholesale at runtime; that is not encoded at the type level).
6669
+ */
6670
+ type AgentWidgetConfigPatch = ConfigPatch<AgentWidgetConfig>;
6671
+ type ConfigPatch<T> = T extends (...args: never[]) => unknown ? T : T extends readonly unknown[] ? T : T extends object ? {
6672
+ [K in keyof T]?: ConfigPatch<T[K]>;
6673
+ } : T;
6209
6674
  type AgentWidgetMessageRole = "user" | "assistant" | "system";
6210
6675
  type AgentWidgetReasoning = {
6211
6676
  id: string;
@@ -6299,6 +6764,25 @@ type AgentWidgetMessage = {
6299
6764
  * The `content` field contains the text-only representation for display.
6300
6765
  */
6301
6766
  contentParts?: ContentPart[];
6767
+ /**
6768
+ * Context mentions attached to this (user) message, for transcript fidelity +
6769
+ * chip rendering in the sent bubble. Refs only — the resolved payloads are
6770
+ * merged into `llmContent`/`contentParts` (model-visible) at send time.
6771
+ */
6772
+ contextMentions?: AgentWidgetContextMentionRef[];
6773
+ /**
6774
+ * Ordered prose + mention blocks for inline-mode rendering and composer history
6775
+ * recall (`contextMentions.display: "inline"`). Present only on inline-mode user
6776
+ * messages; when omitted the sent bubble falls back to the chip row derived from
6777
+ * `contextMentions`. Display/transcript concern only — not the model channel.
6778
+ */
6779
+ contentSegments?: AgentWidgetContentSegment[];
6780
+ /**
6781
+ * Resolved opt-in structured mention context for this (user) message, merged
6782
+ * into the request `context` under `mentions.<sourceId>.<itemId>` by the
6783
+ * client. Internal: set at send time from each source's `resolve().context`.
6784
+ */
6785
+ mentionContext?: Record<string, unknown>;
6302
6786
  streaming?: boolean;
6303
6787
  variant?: AgentWidgetMessageVariant;
6304
6788
  sequence?: number;
@@ -6662,7 +7146,7 @@ type NPSFeedbackOptions = {
6662
7146
  };
6663
7147
 
6664
7148
  type Controller = {
6665
- update: (config: AgentWidgetConfig) => void;
7149
+ update: (config: AgentWidgetConfigPatch) => void;
6666
7150
  destroy: () => void;
6667
7151
  open: () => void;
6668
7152
  close: () => void;