@aparte/core 0.19.2 → 0.20.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 (151) hide show
  1. package/README.md +6 -1
  2. package/dist/client/aparte-client.d.ts +76 -97
  3. package/dist/client/aparte-client.d.ts.map +1 -1
  4. package/dist/client/stream-adapter.d.ts +7 -13
  5. package/dist/client/stream-adapter.d.ts.map +1 -1
  6. package/dist/client/wire-history.d.ts +4 -5
  7. package/dist/client/wire-history.d.ts.map +1 -1
  8. package/dist/components/bubble/aparte-chat-bubble.d.ts +89 -58
  9. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
  10. package/dist/components/bubble/bubble-sync.d.ts +1 -1
  11. package/dist/components/chat/aparte-chat.d.ts +15 -13
  12. package/dist/components/chat/aparte-chat.d.ts.map +1 -1
  13. package/dist/components/chat/glide-gate.d.ts +13 -0
  14. package/dist/components/chat/glide-gate.d.ts.map +1 -0
  15. package/dist/components/composer/aparte-composer-action.d.ts +3 -3
  16. package/dist/components/composer/aparte-composer-add-attachment.d.ts +2 -2
  17. package/dist/components/composer/aparte-composer-cancel.d.ts +1 -1
  18. package/dist/components/composer/aparte-composer-input.d.ts +4 -7
  19. package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
  20. package/dist/components/composer/aparte-composer-send.d.ts +9 -11
  21. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  22. package/dist/components/composer/aparte-composer.d.ts +50 -80
  23. package/dist/components/composer/aparte-composer.d.ts.map +1 -1
  24. package/dist/components/context/aparte-context.d.ts +13 -7
  25. package/dist/components/context/aparte-context.d.ts.map +1 -1
  26. package/dist/components/conversation-list/aparte-conversation-list.d.ts +25 -13
  27. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
  28. package/dist/components/elicitation/aparte-elicitation.d.ts +15 -22
  29. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  30. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts +10 -11
  31. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts.map +1 -1
  32. package/dist/components/sidebar/aparte-sidebar.d.ts +16 -3
  33. package/dist/components/sidebar/aparte-sidebar.d.ts.map +1 -1
  34. package/dist/components/split/aparte-split.d.ts +12 -3
  35. package/dist/components/split/aparte-split.d.ts.map +1 -1
  36. package/dist/components/status/aparte-chat-status.d.ts +5 -3
  37. package/dist/components/status/aparte-chat-status.d.ts.map +1 -1
  38. package/dist/components/suggestions/aparte-suggestions.d.ts +6 -9
  39. package/dist/components/suggestions/aparte-suggestions.d.ts.map +1 -1
  40. package/dist/components/viewport/aparte-chat-viewport.d.ts +76 -69
  41. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  42. package/dist/config/aparte-config.d.ts +169 -141
  43. package/dist/config/aparte-config.d.ts.map +1 -1
  44. package/dist/config/icon-provider.d.ts +19 -2
  45. package/dist/config/icon-provider.d.ts.map +1 -1
  46. package/dist/config/index.d.ts +1 -1
  47. package/dist/config/index.d.ts.map +1 -1
  48. package/dist/config/locale.d.ts +61 -89
  49. package/dist/config/locale.d.ts.map +1 -1
  50. package/dist/config/sanitize.d.ts.map +1 -1
  51. package/dist/conversations/conversation-controller.d.ts +18 -3
  52. package/dist/conversations/conversation-controller.d.ts.map +1 -1
  53. package/dist/conversations/conversation-manager.d.ts +6 -6
  54. package/dist/conversations/conversation-manager.d.ts.map +1 -1
  55. package/dist/conversations/index.d.ts +1 -1
  56. package/dist/conversations/index.d.ts.map +1 -1
  57. package/dist/custom-elements.json +5656 -4759
  58. package/dist/{dialog-triggers-CEazY76J.js → dialog-triggers-3Rk7PuZa.js} +555 -375
  59. package/dist/dialog-triggers-3Rk7PuZa.js.map +1 -0
  60. package/dist/elicitation/approval-panel.d.ts.map +1 -1
  61. package/dist/elicitation/index.d.ts +6 -1
  62. package/dist/elicitation/index.d.ts.map +1 -1
  63. package/dist/elicitation/panel.d.ts +11 -21
  64. package/dist/elicitation/panel.d.ts.map +1 -1
  65. package/dist/elicitation/types.d.ts +19 -27
  66. package/dist/elicitation/types.d.ts.map +1 -1
  67. package/dist/generated/element-attributes.d.ts +16 -10
  68. package/dist/generated/element-attributes.d.ts.map +1 -1
  69. package/dist/host/aparte-chat-host.d.ts +17 -32
  70. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  71. package/dist/icons/extended.d.ts +1 -2
  72. package/dist/icons/extended.d.ts.map +1 -1
  73. package/dist/icons.d.ts +6 -8
  74. package/dist/icons.d.ts.map +1 -1
  75. package/dist/icons.js.map +1 -1
  76. package/dist/index.css +1 -1
  77. package/dist/index.d.ts +13 -10
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +775 -337
  80. package/dist/index.js.map +1 -1
  81. package/dist/index.node.d.ts +7 -4
  82. package/dist/index.node.d.ts.map +1 -1
  83. package/dist/index.node.js +2 -2
  84. package/dist/index.node.js.map +1 -1
  85. package/dist/interop/dialog-triggers.d.ts +2 -2
  86. package/dist/interop/element-props.d.ts +16 -27
  87. package/dist/interop/element-props.d.ts.map +1 -1
  88. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  89. package/dist/primitives/icon/aparte-icon.d.ts.map +1 -1
  90. package/dist/primitives/select/aparte-option.d.ts +3 -2
  91. package/dist/primitives/select/aparte-option.d.ts.map +1 -1
  92. package/dist/primitives/select/aparte-select.d.ts +24 -21
  93. package/dist/primitives/select/aparte-select.d.ts.map +1 -1
  94. package/dist/renderers/markdown-stream.d.ts.map +1 -1
  95. package/dist/renderers/segment-renderers.d.ts +11 -17
  96. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  97. package/dist/renderers/segments/code.d.ts.map +1 -1
  98. package/dist/renderers/segments/error.d.ts.map +1 -1
  99. package/dist/renderers/segments/text.d.ts.map +1 -1
  100. package/dist/renderers/segments/thinking.d.ts.map +1 -1
  101. package/dist/renderers/segments/tool-call.d.ts.map +1 -1
  102. package/dist/runtime/message-repository.d.ts +8 -15
  103. package/dist/runtime/message-repository.d.ts.map +1 -1
  104. package/dist/transport/agent-handler.d.ts +2 -0
  105. package/dist/transport/agent-handler.d.ts.map +1 -1
  106. package/dist/transport/backend-handler.d.ts +4 -6
  107. package/dist/transport/backend-handler.d.ts.map +1 -1
  108. package/dist/transport/backend-transport.d.ts +15 -1
  109. package/dist/transport/backend-transport.d.ts.map +1 -1
  110. package/dist/transport/types.d.ts +7 -10
  111. package/dist/transport/types.d.ts.map +1 -1
  112. package/dist/types/chat.d.ts +10 -18
  113. package/dist/types/chat.d.ts.map +1 -1
  114. package/dist/types/element-attributes.d.ts +6 -12
  115. package/dist/types/element-attributes.d.ts.map +1 -1
  116. package/dist/types/element-map.d.ts +6 -19
  117. package/dist/types/element-map.d.ts.map +1 -1
  118. package/dist/types/event-map.d.ts +11 -17
  119. package/dist/types/event-map.d.ts.map +1 -1
  120. package/dist/types/events.d.ts +5 -14
  121. package/dist/types/events.d.ts.map +1 -1
  122. package/dist/types/imperative-api.d.ts +3 -1
  123. package/dist/types/imperative-api.d.ts.map +1 -1
  124. package/dist/types/index.d.ts +4 -4
  125. package/dist/types/index.d.ts.map +1 -1
  126. package/dist/types/model-provider.d.ts +7 -9
  127. package/dist/types/model-provider.d.ts.map +1 -1
  128. package/dist/types/segments.d.ts +29 -13
  129. package/dist/types/segments.d.ts.map +1 -1
  130. package/dist/types/tools.d.ts +21 -23
  131. package/dist/types/tools.d.ts.map +1 -1
  132. package/dist/utils/copy-text.d.ts +1 -2
  133. package/dist/utils/copy-text.d.ts.map +1 -1
  134. package/dist/utils/css-escape.d.ts +1 -1
  135. package/dist/utils/escape.d.ts +4 -19
  136. package/dist/utils/escape.d.ts.map +1 -1
  137. package/dist/utils/files-to-attachments.d.ts +2 -2
  138. package/dist/utils/fold-text.d.ts +13 -0
  139. package/dist/utils/fold-text.d.ts.map +1 -0
  140. package/dist/utils/is-awaiting-reply.d.ts +2 -5
  141. package/dist/utils/is-awaiting-reply.d.ts.map +1 -1
  142. package/dist/utils/presence.d.ts +5 -5
  143. package/dist/utils/segments.d.ts +54 -78
  144. package/dist/utils/segments.d.ts.map +1 -1
  145. package/dist/utils/tool-input.d.ts +1 -1
  146. package/dist/utils/tool-input.d.ts.map +1 -1
  147. package/dist/utils/transcript.d.ts +2 -2
  148. package/dist/utils/uuid.d.ts +0 -11
  149. package/dist/utils/uuid.d.ts.map +1 -1
  150. package/package.json +30 -4
  151. package/dist/dialog-triggers-CEazY76J.js.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from '../../types/index.js';
2
+ import { type AparteConfigAware } from '../../config/config-context.js';
2
3
  /**
3
4
  * One message: plain content or a list of rich segments, in light DOM.
4
5
  *
@@ -36,14 +37,10 @@ import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from
36
37
  * on `.aparte-message`), never from a status attribute, so it behaves identically in
37
38
  * vanilla and in every wrapper.
38
39
  *
39
- * All seven events are declared by hand rather than left to the analyser, which
40
- * found six. `aparte-branch-navigate` is dispatched from the `_onBranchPickerClick`
41
- * arrow class field, and the auto-detection visits `ts.isMethodDeclaration` only —
42
- * so the one event belonging to the branch picker was the one missing from the
43
- * manifest, and from the generated reference, for as long as both existed.
40
+ * All eight events are declared by hand rather than left to the analyser.
44
41
  *
45
42
  * The bubble element is `content-visibility: auto` for its streaming/scroll performance
46
- * (measured, not assumed — see `bubble.css`), and that containment makes the bubble
43
+ * (see `bubble.css`), and that containment makes the bubble
47
44
  * the containing block for `position: fixed` descendants: a popover mounted inside it
48
45
  * (an `<aparte-select>` from a `registerToolRenderer` renderer, say) is clipped to the
49
46
  * bubble's own box, not the window. Mount it outside instead — [Custom tool
@@ -51,12 +48,12 @@ import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from
51
48
  *
52
49
  * @element aparte-chat-bubble
53
50
  *
54
- * @attr {string} data-role - The message role, `user` or `assistant` — the one channel for it, and what the CSS keys off. (`role` is ARIA's attribute; this element sets it to `article` itself and no longer reads a message role from it.)
51
+ * @attr {string} data-role - The message role, `user` or `assistant` — the one channel for it, and what the CSS keys off. (`role` is ARIA's attribute; this element sets it to `article` itself and does not read a message role from it.)
55
52
  * @attr {string} content - Plain text content, for a bubble with no segments.
56
- * @attr {number | string} timestamp - Epoch milliseconds OR a date string: `_updateTimestamp` accepts either and only coerces when the value is numeric.
53
+ * @attr {number | string} timestamp - Epoch milliseconds or a date string; a numeric string is read as milliseconds.
57
54
  * @attr {string} message-id - How streaming and the action bar address this bubble.
58
55
  * @attr {boolean} streaming - Hides the action bar and shows the caret while a reply is in flight.
59
- * @attr {string} name - The display name in the header.
56
+ * @attr {string} name - Who wrote the message: shown in the header, and the message's accessible name ("Message from {name}"). Leave it out for the reader and the assistant, whose names come from the locale.
60
57
  *
61
58
  * @fires {CustomEvent<AparteActionEventDetail>} aparte-action - A custom action-bar button was pressed.
62
59
  * @fires {CustomEvent<AparteRetryEventDetail>} aparte-retry - Retry was pressed; the host forks the turn.
@@ -68,25 +65,26 @@ import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from
68
65
  * @fires {CustomEvent<AparteLinkClickEventDetail>} aparte-link-click - A link in the message body is about to be followed. Cancelable: `preventDefault()` keeps the browser from navigating, so a host can route the link itself.
69
66
  *
70
67
  * @cssprop [--aparte-message-gap=var(--aparte-space-6)] - Gap between the avatar column and the body (the viewport reuses it between messages).
71
- * @cssprop [--aparte-message-padding-block=var(--aparte-space-8)] - Vertical padding of one message row. (The composite `--aparte-message-padding` is gone: joined on `:root`, it froze both parts, and the narrow-container override of them never reached the row.)
68
+ * @cssprop [--aparte-message-padding-block=var(--aparte-space-8)] - Vertical padding of one message row.
72
69
  * @cssprop [--aparte-message-padding-inline=var(--aparte-space-6)] - Horizontal padding of one message row.
73
70
  * @cssprop [--aparte-message-max-width=800px] - Width of the centred message row.
74
71
  *
75
72
  * @cssprop [--aparte-message-content-radius=var(--aparte-radius-bubble)] - Radius of the painted content box.
76
- * @cssprop [--aparte-message-content-padding=var(--aparte-space-5) var(--aparte-space-7)] - Padding of the USER box only; the assistant's content is plain full-width prose.
73
+ * @cssprop [--aparte-message-content-padding=var(--aparte-space-5) var(--aparte-space-7)] - Padding of the user's box.
74
+ * @cssprop [--aparte-message-content-padding-assistant=0] - Padding of the assistant's box, none by default: its reply is plain prose across the column.
77
75
  * @cssprop --aparte-message-content-bg-user - Background of the user box: a wash of `--aparte-primary` over `--aparte-surface-1`, derived in `theme.css` so a rebrand moves it (declare it to override).
78
76
  * @cssprop [--aparte-message-content-bg-assistant=transparent] - Background of the assistant box — transparent on purpose (AI-chat convention, not messaging).
79
- * @cssprop [--aparte-message-content-text-user=var(--aparte-text)] - Text colour inside the user box.
80
- * @cssprop [--aparte-message-content-text-assistant=var(--aparte-text)] - Text colour inside the assistant box.
77
+ * @cssprop --aparte-message-content-text-user - Colour of the user's words. Unset by default: they keep `--aparte-content-color`.
78
+ * @cssprop --aparte-message-content-text-assistant - Colour of the assistant's words. Unset by default: they keep `--aparte-content-color`.
81
79
  *
82
80
  * @cssprop [--aparte-avatar-size=32px] - Square size of the avatar slot.
83
- * @cssprop [--aparte-avatar-radius-ratio=0.28] - Avatar corner radius, as a fraction of its size (the corner follows the ramp; 0.28 × 32px is the 9px it used to be).
81
+ * @cssprop [--aparte-avatar-radius-ratio=0.28] - Avatar corner radius, as a fraction of its size (the corner follows the ramp).
84
82
  * @cssprop [--aparte-avatar-initials-ratio=0.34] - Size of the initial, as a fraction of the avatar's size.
85
83
  * @cssprop [--aparte-avatar-bg-user=var(--aparte-primary)] - Avatar background, user role.
86
84
  * @cssprop [--aparte-avatar-text-user=var(--aparte-text-inverse)] - Avatar text colour, user role.
87
85
  * @cssprop [--aparte-avatar-bg-assistant=var(--aparte-surface-3)] - Avatar background, assistant role.
88
86
  * @cssprop [--aparte-avatar-text-assistant=var(--aparte-text)] - Avatar text colour, assistant role.
89
- * @cssprop [--aparte-avatar-image-user=none] - `background-image` for the user avatar — a logo with no AvatarProvider and no JS.
87
+ * @cssprop [--aparte-avatar-image-user=none] - `background-image` for the user avatar — a logo with no AvatarProvider: the slot shows when it names an image.
90
88
  * @cssprop [--aparte-avatar-image-assistant=none] - `background-image` for the assistant avatar.
91
89
  * @cssprop [--aparte-avatar-image-size=90%] - `background-size` for both avatar images.
92
90
  *
@@ -131,7 +129,6 @@ import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from
131
129
  * <aparte-chat-bubble
132
130
  * message-id="a1"
133
131
  * data-role="assistant"
134
- * name="Assistant"
135
132
  * content="Hello."
136
133
  * ></aparte-chat-bubble>
137
134
  *
@@ -147,7 +144,6 @@ import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from
147
144
  * <aparte-chat-bubble
148
145
  * message-id="a3"
149
146
  * data-role="assistant"
150
- * name="Assistant"
151
147
  * content="A second take on the same question."
152
148
  * ></aparte-chat-bubble>
153
149
  *
@@ -155,7 +151,7 @@ import type { AparteSegment, AparteAttachment, AparteUsage, AparteMessage } from
155
151
  * document.querySelector('aparte-chat-bubble[message-id="a3"]').setSiblings(2, 0);
156
152
  * </script>
157
153
  */
158
- export declare class AparteChatBubble extends HTMLElement {
154
+ export declare class AparteChatBubble extends HTMLElement implements AparteConfigAware {
159
155
  private _contentEl;
160
156
  private _segmentsEl;
161
157
  private _attachmentsEl;
@@ -170,8 +166,20 @@ export declare class AparteChatBubble extends HTMLElement {
170
166
  private _usage;
171
167
  /** Cleanup returned by the avatar provider — called on disconnect/re-render. */
172
168
  private _avatarCleanup;
169
+ /** Whether the avatar slot holds what a provider drew, which goes when the provider does. */
170
+ private _avatarFromProvider;
173
171
  /** Sibling count for tree-based branch navigation (set by setSiblings()) */
174
172
  private _siblingCount;
173
+ /**
174
+ * Which accessible names the bubble wrote itself, and so may refresh on a language switch
175
+ * or a name change. A custom shell's own are its author's: refreshed, a root's or a bar's
176
+ * label of their own became "Assistant response" or "Message actions" at the first notify.
177
+ */
178
+ private _wroteRootLabel;
179
+ private _wroteBarLabel;
180
+ private _wroteArrowLabels;
181
+ /** The shell renderer the bubble was last drawn with (`null`: the default frame). */
182
+ private _drawnShell;
175
183
  /** Sibling index for tree-based branch navigation (set by setSiblings()) */
176
184
  private _siblingIndex;
177
185
  /** True while the user-message inline editor is open. */
@@ -187,6 +195,17 @@ export declare class AparteChatBubble extends HTMLElement {
187
195
  static get observedAttributes(): string[];
188
196
  constructor();
189
197
  private _onConfigChange;
198
+ /** A {@link _redrawIfStale} is queued for the end of the current task. */
199
+ private _redrawQueued;
200
+ /** The {@link renderingVersionOf} count the content was last drawn with. */
201
+ private _drawnWithVersion;
202
+ /**
203
+ * A Markdown or highlight provider set after this message was drawn: draw it again.
204
+ * Not mid-stream — the stream reads the providers as it goes, and its end redraws — and
205
+ * not mid-edit, where the drawn message is hidden behind the editor and drawing it would
206
+ * show it again beside the editor; leaving the edit calls this.
207
+ */
208
+ private _redrawIfStale;
190
209
  /**
191
210
  * Ask every rendered segment to re-read its config-derived text.
192
211
  *
@@ -218,6 +237,20 @@ export declare class AparteChatBubble extends HTMLElement {
218
237
  */
219
238
  private get _cfg();
220
239
  connectedCallback(): void;
240
+ /**
241
+ * The boundary above this bubble changed — under every wrapper the chat's own config is
242
+ * attached AFTER the first messages are drawn. When that brings another frame
243
+ * (`setBubbleShellRenderer`), the bubble is drawn again in it and its content put back,
244
+ * so every message wears the chat's frame.
245
+ *
246
+ * Deferred to a microtask: a wrapper detaches the boundary as it unmounts (Vue's
247
+ * `onBeforeUnmount`, Svelte's `onDestroy`), while the bubbles are still in the page, and
248
+ * redrawing every one of them just before their removal would cost a frame per message.
249
+ * After the microtask a removed bubble is no longer connected, and repeated notices fold
250
+ * into one.
251
+ */
252
+ aparteConfigChanged(): void;
253
+ private _redrawFrameIfChanged;
221
254
  disconnectedCallback(): void;
222
255
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
223
256
  /** Append a token chunk (for streaming) */
@@ -251,11 +284,11 @@ export declare class AparteChatBubble extends HTMLElement {
251
284
  * query returns the first match in document order — and sanitized model
252
285
  * markdown renders inside that same container, with `data-*` attributes
253
286
  * deliberately preserved (they are inert). So a decoy `data-segment-id` planted
254
- * in an earlier segment's prose used to win over the real segment element.
287
+ * in an earlier segment's prose would win over the real segment element.
255
288
  *
256
289
  * Parser ids are unguessable UUIDs, but a tool segment is `tool-${toolCallId}`
257
- * and the MODEL chooses that id — so this was reachable, and pointing an update
258
- * at a decoy left a rejected tool rendering as still-running: a spoof against
290
+ * and the MODEL chooses that id — so a decoy could point an update at the wrong
291
+ * element and leave a rejected tool rendering as still-running: a spoof against
259
292
  * the human-in-the-loop control.
260
293
  */
261
294
  removeSegment(segmentId: string): void;
@@ -289,8 +322,7 @@ export declare class AparteChatBubble extends HTMLElement {
289
322
  private _render;
290
323
  /**
291
324
  * Show the built-in waiting indicator while this bubble is in flight and has
292
- * nothing to show yet — the gap between "user sends" and the first token, which
293
- * used to be a bubble with a name and an empty body.
325
+ * nothing to show yet — the gap between "user sends" and the first token.
294
326
  *
295
327
  * The dots are CSS (no per-token work, themable, honours reduced-motion); the
296
328
  * accessible name is `locale.typing`, next to the `aria-busy` the streaming state
@@ -301,13 +333,19 @@ export declare class AparteChatBubble extends HTMLElement {
301
333
  /**
302
334
  * Hand the avatar host element off to the registered AvatarProvider, if any.
303
335
  *
304
- * With no provider the slot is left exactly as the shell rendered it — which for
305
- * the default shell means EMPTY, and hidden by `.aparte-avatar:empty`. This used
306
- * to claim it "falls back to the default initial rendered by `_render()`"; there
307
- * is no such initial, and believing there was is what made `_updateRole` write
308
- * one.
336
+ * With no provider the slot keeps what the shell rendered — for the default shell,
337
+ * nothing, hidden while empty — and loses what a provider drew there before. An empty
338
+ * slot still shows when the stylesheet names a picture for its role
339
+ * (`--aparte-avatar-image-user` / `-assistant`): see `_markAvatarImage`.
309
340
  */
310
341
  private _renderAvatar;
342
+ /**
343
+ * A picture from the stylesheet alone: an empty slot whose role's `--aparte-avatar-image-*`
344
+ * names an image gets `data-image`, which lifts the rule that hides an empty slot. Hidden
345
+ * while empty, the token painted nothing. Read when the message is drawn and on every
346
+ * config change, in a batch with the other bubbles' (see `pendingAvatarMarks`).
347
+ */
348
+ private _markAvatarImage;
311
349
  private _updateRole;
312
350
  private _updateName;
313
351
  private _updateContent;
@@ -329,6 +367,12 @@ export declare class AparteChatBubble extends HTMLElement {
329
367
  */
330
368
  private _reflectError;
331
369
  private _updateTimestamp;
370
+ /**
371
+ * Named after its author when it has one: a `name` on the bubble is who wrote it (a human
372
+ * agent answering on the assistant's side, a second assistant), and naming every one of
373
+ * them "Assistant response" told a screen-reader user the opposite of what the page shows.
374
+ * Without a name, the role names it.
375
+ */
332
376
  private _getAriaLabel;
333
377
  private _updateAttachments;
334
378
  /** Uppercased file extension (≤4 chars), or 'FILE' when there is none. */
@@ -337,9 +381,9 @@ export declare class AparteChatBubble extends HTMLElement {
337
381
  *
338
382
  * An attachment's `url` is documented as "URL or data URI" and a storage adapter
339
383
  * re-mints it when a conversation is restored, so it is the app's value, not the
340
- * composer's — it was escaped and written, where every other URL core emits is
341
- * asked whether its SCHEME is allowed at all. A picture whose URL is refused is
342
- * not half-rendered: it falls back to the file chip, which still names the file.
384
+ * composer's — and, like every other URL core emits, it is asked whether its SCHEME
385
+ * is allowed at all. A picture whose URL is refused is not half-rendered: it falls
386
+ * back to the file chip, which still names the file.
343
387
  *
344
388
  * `blob:` is added because it is the shape core itself mints — `filesToAttachments`
345
389
  * calls `URL.createObjectURL`, and `AparteMessage.attachments` documents the same
@@ -351,27 +395,18 @@ export declare class AparteChatBubble extends HTMLElement {
351
395
  /**
352
396
  * The branch arrows are handled by DELEGATION, on this element, bound once.
353
397
  *
354
- * They used to get a fresh listener each, attached by `_render()` to the buttons
355
- * `_render()` had just created. So a click that landed while a re-render was
356
- * swapping those nodes hit an element about to be discarded, and did nothing at
357
- * all — not late, nothing. Invisible on a fast machine; reproducible on
358
- * WebKit-Linux in CI, where `‹` left the picker on "2 / 2" and a 20-second
359
- * assertion watched it stay there.
360
- *
361
- * Delegation makes `_render()` irrelevant to it: the listener lives on the host,
362
- * which is never replaced, and `closest()` finds whichever button exists at the
363
- * moment of the click. It is also less work — one listener per bubble instead of
364
- * two per bubble per render.
398
+ * The listener lives on the host, which is never replaced, and `closest()` finds
399
+ * whichever button exists at the moment of the click — so a click that lands while
400
+ * a re-render is swapping the buttons is not lost.
365
401
  *
366
402
  * Bound in `connectedCallback` and removed in `disconnectedCallback` as a stable
367
- * field, because an inline arrow re-added on every re-connect is how this repo has
368
- * stacked listeners twice before (the viewport, and `aparte-select`).
403
+ * field, so a re-connect never stacks listeners.
369
404
  */
370
405
  private _onBranchPickerClick;
371
406
  /**
372
407
  * A link the MODEL wrote is about to be followed. Announced as a cancelable event
373
408
  * before the browser acts, so a host can route it — an external browser, a
374
- * confirmation, an embedded view — without intercepting the DOM (issue #38). With
409
+ * confirmation, an embedded view — without intercepting the DOM. With
375
410
  * no listener the browser follows it, which the sanitizer has already made open in
376
411
  * a new tab for an external URL; `preventDefault()` on the event cancels the click.
377
412
  *
@@ -409,18 +444,14 @@ export declare class AparteChatBubble extends HTMLElement {
409
444
  /**
410
445
  * `role="toolbar"` promises a keyboard model. This is it.
411
446
  *
412
- * The bar has announced itself as a toolbar since it existed, and a toolbar is ONE
413
- * tab stop whose members are reached with the arrow keys — that is the whole of what
414
- * the role means to a screen-reader user. What shipped was five independent tab
415
- * stops per message, so the role described a behaviour that did not exist: a reader
416
- * told to press Right heard nothing move, and tabbing through a long transcript
417
- * walked every button of every message.
447
+ * A toolbar is ONE tab stop whose members are reached with the arrow keys — that is
448
+ * the whole of what the role means to a screen-reader user. Without it, tabbing
449
+ * through a long transcript would walk every button of every message.
418
450
  *
419
451
  * The roving index is re-applied from `_syncFooterVisibility`, which is the single
420
- * funnel all three build paths already run through (the flag-driven bar, the edit
421
- * bar, and the branch picker's own visibility pass). Re-deriving it there rather
422
- * than in each builder is what keeps the invariant true after a `setBubbleActions`
423
- * rebuild — the drift this pattern usually dies of.
452
+ * funnel all three build paths run through (the flag-driven bar, the edit bar, and
453
+ * the branch picker's own visibility pass). Re-deriving it there rather than in each
454
+ * builder keeps the invariant true after a `setBubbleActions` rebuild.
424
455
  *
425
456
  * DISABLED buttons are skipped, not merely un-tabbable: while the transcript is busy
426
457
  * retry and edit are disabled, and a toolbar whose arrows stop on a dead control
@@ -439,9 +470,9 @@ export declare class AparteChatBubble extends HTMLElement {
439
470
  */
440
471
  private _onActionBarKeydown;
441
472
  /**
442
- * An empty action bar is not a bar: with every action off it was still a
443
- * `role="toolbar"` with nothing in it (announced as such), and it still reserved
444
- * its fixed height plus the footer's under every bubble. So both follow their
473
+ * An empty action bar is not a bar: with every action off it would be a
474
+ * `role="toolbar"` with nothing in it (announced as such) that still reserves its
475
+ * fixed height plus the footer's under every bubble. So both follow their
445
476
  * contents — the footer stays as long as the branch picker or the bar has
446
477
  * something to show.
447
478
  */
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-chat-bubble.d.ts","sourceRoot":"","sources":["../../../src/components/bubble/aparte-chat-bubble.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aparte-chat-bubble.d.ts","sourceRoot":"","sources":["../../../src/components/bubble/aparte-chat-bubble.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,7 @@ export interface SyncableBubble {
30
30
  *
31
31
  * Idempotent. Safe to call on every render. Segment count drives the strategy:
32
32
  * - same count → reconcile content per segment (cheap, preserves user-toggled
33
- * <details> open/closed state on thinking blocks, etc.)
33
+ * `<details>` open/closed state on thinking blocks, etc.)
34
34
  * - count changed (new segment streamed, branch switched, etc.) → full rebuild
35
35
  * via setSegments
36
36
  *
@@ -78,6 +78,9 @@ import '../elicitation/aparte-elicitation.js';
78
78
  * With or without `center-empty`: the stylesheet centers the composer through
79
79
  * `aparte-chat[center-empty][data-empty]`, and an app styles or scripts its own empty state
80
80
  * against `aparte-chat[data-empty]`. Read-only.
81
+ * @attr {boolean} data-glide - Reflected BY the element at the first key or pointer in the page, or
82
+ * the first send: from then on `center-empty` slides the composer between the welcome and the
83
+ * conversation. Before it, a conversation a script restores on load lands in one frame. Read-only.
81
84
  * @attr {boolean} overlay-composer - The ChatGPT anatomy, opt-in: the transcript's scroll
82
85
  * surface spans the whole column and the composer (with the rest of the bottom stack)
83
86
  * floats over it, so the scrollbar runs edge to edge instead of stopping at the
@@ -118,6 +121,7 @@ export declare class AparteChat extends HTMLElement {
118
121
  static get observedAttributes(): string[];
119
122
  private _observer;
120
123
  private _loadingObserver;
124
+ private _offGlide;
121
125
  /** Waits for a `<aparte-chat-viewport>` child to appear — see `_watchForViewport`. */
122
126
  private _childObserver;
123
127
  /** The viewport is loading and the gate is on — see `_applyLoadingGate`. */
@@ -149,11 +153,10 @@ export declare class AparteChat extends HTMLElement {
149
153
  /**
150
154
  * Watch the viewport so `data-empty` follows the conversation.
151
155
  *
152
- * It used to run only under `center-empty`, which made the chat's one statement of
153
- * "this conversation is empty" a by-product of a layout option: an app that wanted
154
- * starters on an empty thread, or a welcome of its own, had to count messages itself.
155
- * Every selector core writes against it still requires `[center-empty]`, so reflecting
156
- * it everywhere moves no layout.
156
+ * Runs whether or not `center-empty` is set, so an app that wants starters on an
157
+ * empty thread, or a welcome of its own, can read `data-empty` instead of counting
158
+ * messages itself. Every selector core writes against it requires `[center-empty]`,
159
+ * so reflecting it everywhere moves no layout.
157
160
  */
158
161
  private _syncEmptyWatch;
159
162
  /**
@@ -164,12 +167,11 @@ export declare class AparteChat extends HTMLElement {
164
167
  */
165
168
  private _syncLoadingWatch;
166
169
  /**
167
- * Both watches above need a viewport to observe, and they were installed once, at
168
- * connect, when there might not be one yet: `<aparte-chat framework-managed>` IS
169
- * Angular's host element — upgraded on insert, filled by the template afterwards — and
170
- * hand-written markup upgrades before its children are parsed. Neither ever got its
171
- * observer, so the documented "every chat gates" was inert on exactly the chats whose
172
- * transcript is fetched. This waits for the child to arrive, installs them, and stops.
170
+ * Both watches above need a viewport to observe, and there might not be one at
171
+ * connect: `<aparte-chat framework-managed>` IS Angular's host element — upgraded on
172
+ * insert, filled by the template afterwards — and hand-written markup upgrades before
173
+ * its children are parsed. This waits for the child to arrive, installs them, and
174
+ * stops, so every chat gates, including those whose transcript is fetched.
173
175
  */
174
176
  private _watchForViewport;
175
177
  /**
@@ -179,8 +181,8 @@ export declare class AparteChat extends HTMLElement {
179
181
  private _applyLoadingGate;
180
182
  /**
181
183
  * Empty means no message AND none on its way. A viewport that says `loading` holds
182
- * no bubble yet, and it used to count as empty: the welcome and the centred composer
183
- * showed while a conversation was being fetched.
184
+ * no bubble yet but does not count as empty, so the welcome and the centred composer
185
+ * stay hidden while a conversation is being fetched.
184
186
  */
185
187
  private _updateEmpty;
186
188
  }
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-chat.d.ts","sourceRoot":"","sources":["../../../src/components/chat/aparte-chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAIrE,OAAO,sCAAsC,CAAC;AAI9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AACH,qBAAa,UAAW,SAAQ,WAAW;IACzC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,sFAAsF;IACtF,OAAO,CAAC,cAAc,CAAiC;IACvD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;IACvB,mFAAmF;IACnF,OAAO,CAAC,SAAS,CAAS;IAE1B;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B,iBAAiB,IAAI,IAAI;IAUzB,oBAAoB,IAAI,IAAI;IAS5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAoB9F,6EAA6E;IAC7E,IAAI,QAAQ,IAAI,kBAAkB,GAAG,IAAI,CAExC;IAED,qEAAqE;IACrE,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;IAED,OAAO,CAAC,OAAO;IAsDf;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuBxB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IAKpB;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAcvB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAKrB"}
1
+ {"version":3,"file":"aparte-chat.d.ts","sourceRoot":"","sources":["../../../src/components/chat/aparte-chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAIrE,OAAO,sCAAsC,CAAC;AAK9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmHG;AACH,qBAAa,UAAW,SAAQ,WAAW;IACzC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,SAAS,CAA6B;IAC9C,sFAAsF;IACtF,OAAO,CAAC,cAAc,CAAiC;IACvD,4EAA4E;IAC5E,OAAO,CAAC,MAAM,CAAS;IACvB,mFAAmF;IACnF,OAAO,CAAC,SAAS,CAAS;IAE1B;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B,iBAAiB,IAAI,IAAI;IAYzB,oBAAoB,IAAI,IAAI;IAW5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAoB9F,6EAA6E;IAC7E,IAAI,QAAQ,IAAI,kBAAkB,GAAG,IAAI,CAExC;IAED,qEAAqE;IACrE,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;IAED,OAAO,CAAC,OAAO;IAoDf;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuBxB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IAKpB;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAcvB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAKrB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `data-glide` on a centring chat once a person is there: the first key or pointer in the page,
3
+ * or a send from inside the chat.
4
+ *
5
+ * The composer's slide between the welcome state and a conversation reads it (shell.css). A
6
+ * conversation a script restores on load therefore lands in one frame — sliding it there, before
7
+ * anyone had touched the page, was a layout shift the reader never caused (CLS 0.14 on a phone).
8
+ * Every change after that, a send, an opened conversation, a new chat, still glides.
9
+ *
10
+ * Returns the teardown. Used by `<aparte-chat>` on itself and by the framework hosts on their root.
11
+ */
12
+ export declare function gateGlide(el: HTMLElement): () => void;
13
+ //# sourceMappingURL=glide-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glide-gate.d.ts","sourceRoot":"","sources":["../../../src/components/chat/glide-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,IAAI,CAgBrD"}
@@ -1,6 +1,6 @@
1
1
  import type { AparteComposer } from './aparte-composer.js';
2
2
  /**
3
- * Generic action button primitive for <aparte-composer>.
3
+ * Generic action button primitive for `<aparte-composer>`.
4
4
  *
5
5
  * The consumer declares it directly in markup — no global registration needed.
6
6
  *
@@ -28,8 +28,8 @@ import type { AparteComposer } from './aparte-composer.js';
28
28
  * @element aparte-composer-action
29
29
  *
30
30
  * @attr {string} icon - Icon key for aparteGlobalConfig.getIcon(), or raw SVG/HTML starting with `<`.
31
- * A key core's glyph set does not hold renders AS TEXT (`icon="star"` draws the word
32
- * *star*), so bring your own set through `setIconProvider` or pass the SVG.
31
+ * A key the icon set does not hold renders AS TEXT (`icon="star"` draws the word
32
+ * *star*), so add it with `registerIcons` or pass the SVG.
33
33
  * @attr {string} label - Accessible label (also used as tooltip)
34
34
  * @attr {boolean} disabled - Disables the button
35
35
  * @attr {string} action-id - Identifies WHICH button fired; carried as
@@ -1,5 +1,5 @@
1
1
  /**
2
- * File picker button for <aparte-composer>.
2
+ * File picker button for `<aparte-composer>`.
3
3
  *
4
4
  * Opens a native file picker on click, then pushes picked files to root.addAttachments().
5
5
  * Also sets up drag & drop on the nearest <aparte-composer> root.
@@ -8,7 +8,7 @@
8
8
  * `<aparte-composer-attachments>` draws the pending strip, and sending is the host's job
9
9
  * (`event.detail.files` on `aparte-send`) — which is why the default `<aparte-chat>` shell
10
10
  * only includes this button when the `attachments` attribute is set. With nothing reading
11
- * the files, an attach button is an affordance core cannot honour (ratified decision #8).
11
+ * the files, an attach button is an affordance core cannot honour.
12
12
  *
13
13
  * Drag & drop is installed on the composer ROOT, not on this button, so a drop anywhere
14
14
  * over the composer attaches and the root carries `aparte-is-dragover` while a drag is
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Cancel/stop streaming button primitive for <aparte-composer>.
2
+ * Cancel/stop streaming button primitive for `<aparte-composer>`.
3
3
  *
4
4
  * Most composers should not use this element. `<aparte-composer-send>` already becomes
5
5
  * the stop button while a reply streams, so adding this one gives you a second, equally
@@ -43,12 +43,13 @@
43
43
  * Inside the `.aparte-composer-row` layout helper the composer's buttons read
44
44
  * the same token, so one value resizes that whole control set and the row stays
45
45
  * aligned.
46
- * @cssprop [--aparte-input-padding-y=calc((var(--aparte-composer-control-size) - 1lh) / 2)] - Vertical padding inside the editor.
46
+ * @cssprop [--aparte-input-padding-y=calc((var(--aparte-composer-control-size) - var(--aparte-input-line-height) * 1em) / 2)] - Vertical padding inside the editor: half of what the control size leaves once one line is taken out (`1lh` where the browser has it).
47
47
  * @cssprop [--aparte-input-padding-x=var(--aparte-space-6)] - Horizontal padding inside the editor.
48
48
  * @cssprop [--aparte-input-font-size=var(--aparte-font-size-base)] - Editor font size.
49
49
  * @cssprop [--aparte-input-line-height=var(--aparte-line-height-normal)] - Editor line height — also what the
50
50
  * auto-expand measures, so changing it changes the height the editor settles at
51
- * (until `max-height` clamps it).
51
+ * (until `max-height` clamps it). Keep it unitless (`1.5`, not `24px`): the editor's
52
+ * padding reads it as a multiple of `1em` where the browser has no `lh` unit.
52
53
  * @cssprop --aparte-text - Text and caret colour of the editor.
53
54
  * @cssprop --aparte-input-placeholder - Colour of the placeholder drawn by
54
55
  * `:empty::before` (falls back to `--aparte-text-muted`).
@@ -75,11 +76,7 @@ export declare class AparteComposerInput extends HTMLElement {
75
76
  private _maxHeight;
76
77
  private _minHeight;
77
78
  /**
78
- * Re-measures the editor when its WIDTH changes (#55). The three fixed instants
79
- * (connect, next frame, fonts.ready) all miss the same case: a box not yet laid
80
- * out — the placeholder wraps in a 0 px column, `scrollHeight` reads ~300 px, and
81
- * that became the inline height until the first keystroke. Width is the variable
82
- * none of them watched.
79
+ * Re-measures the editor when its WIDTH changes.
83
80
  */
84
81
  private _resizeObserver;
85
82
  private _unsubscribes;
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-composer-input.d.ts","sourceRoot":"","sources":["../../../src/components/composer/aparte-composer-input.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAChD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,UAAU,CAAM;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,aAAa,CAAsB;IAG3C,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,iBAAiB,IAAI,IAAI;IA2BzB,oBAAoB,IAAI,IAAI;IAY5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IASvF;;;OAGG;IACH,QAAQ,IAAI,MAAM;IAkBlB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ7B,4EAA4E;IAC5E,KAAK,IAAI,IAAI;IAQb;;;;OAIG;IACH,eAAe,IAAI,IAAI;IAIvB,oEAAoE;IAC3D,KAAK,IAAI,IAAI;IACtB,mEAAmE;IAC1D,IAAI,IAAI,IAAI;IAErB,2EAA2E;IAC3E,QAAQ,IAAI,IAAI;IAchB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,cAAc;IAqCtB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,aAAa;IAmBrB;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,4BAA4B;IAIpC,OAAO,CAAC,eAAe;CAW1B"}
1
+ {"version":3,"file":"aparte-composer-input.d.ts","sourceRoot":"","sources":["../../../src/components/composer/aparte-composer-input.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAChD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,UAAU,CAAM;IACxB;;OAEG;IACH,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,aAAa,CAAsB;IAG3C,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,iBAAiB,IAAI,IAAI;IA+BzB,oBAAoB,IAAI,IAAI;IAY5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IASvF;;;OAGG;IACH,QAAQ,IAAI,MAAM;IAkBlB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ7B,4EAA4E;IAC5E,KAAK,IAAI,IAAI;IAQb;;;;OAIG;IACH,eAAe,IAAI,IAAI;IAIvB,oEAAoE;IAC3D,KAAK,IAAI,IAAI;IACtB,mEAAmE;IAC1D,IAAI,IAAI,IAAI;IAErB,2EAA2E;IAC3E,QAAQ,IAAI,IAAI;IAchB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,cAAc;IAqCtB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,aAAa;IAmBrB;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,4BAA4B;IAIpC,OAAO,CAAC,eAAe;CAW1B"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Submit button primitive for <aparte-composer>.
2
+ * Submit button primitive for `<aparte-composer>`.
3
3
  *
4
4
  * One control, three meanings: **send**, **stop** while the root is streaming, and — when
5
5
  * an elicitation panel is open — **submit** the answer; a panel whose mode is `'none'`
@@ -68,9 +68,8 @@ export declare class AparteComposerSend extends HTMLElement {
68
68
  *
69
69
  * This button has four meanings — send, stop, submit an answer, advance to the
70
70
  * next question — and three of them are decided by state it does not own: the
71
- * root's `streaming`, and this payload. It was read straight out of the event's
72
- * arguments and thrown away, so nothing could recompute the button's chrome
73
- * afterwards; a config change had no way to know which of the four to write.
71
+ * root's `streaming`, and this payload. It is kept so the button's chrome can be
72
+ * recomputed after the event, for example on a config change.
74
73
  */
75
74
  private _panel;
76
75
  private _onClick;
@@ -91,14 +90,13 @@ export declare class AparteComposerSend extends HTMLElement {
91
90
  */
92
91
  private _refreshChrome;
93
92
  /**
94
- * Panel open: this one button now means "submit the answer".
93
+ * Panel open: this one button means "submit the answer".
95
94
  *
96
- * The icon has to move with the meaning: it drew a paper plane while the label
97
- * already said "Submit", so it read as "send a message" while it meant "answer
98
- * this question". It used to draw a chevron too, while a form had questions
99
- * ahead, and turn into a "Next" — a second way to do what the panel's chips do,
100
- * and a button whose meaning changed under the pointer. It is disabled instead
101
- * until every question has an answer, which is what the chips' marks explain.
95
+ * The icon moves with the meaning: a paper plane would read as "send a message"
96
+ * while the label says "Submit". The button never turns into a "Next" while a form
97
+ * has questions ahead (the panel's chips do that, and a button whose meaning
98
+ * changed under the pointer would be a second way to do it). It is disabled
99
+ * instead until every question has an answer, which is what the chips' marks explain.
102
100
  */
103
101
  private _syncPanelState;
104
102
  private _handleClick;
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-composer-send.d.ts","sourceRoot":"","sources":["../../../src/components/composer/aparte-composer-send.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;IAC/C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,aAAa,CAAsB;IAC3C;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAA2F;IAGzG,OAAO,CAAC,QAAQ,CAAgC;IAEhD,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAQ5B,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,cAAc;IAgCtB;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,mBAAmB;IAiB3B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;CAGvB"}
1
+ {"version":3,"file":"aparte-composer-send.d.ts","sourceRoot":"","sources":["../../../src/components/composer/aparte-composer-send.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;IAC/C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,aAAa,CAAsB;IAC3C;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAA2F;IAGzG,OAAO,CAAC,QAAQ,CAAgC;IAEhD,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAQ5B,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,cAAc;IAgCtB;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,mBAAmB;IAiB3B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;CAGvB"}