@aparte/core 0.7.0 → 0.8.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 (171) hide show
  1. package/README.md +20 -6
  2. package/dist/client/aparte-client.d.ts +113 -47
  3. package/dist/client/aparte-client.d.ts.map +1 -1
  4. package/dist/client/lifecycle-events.d.ts +55 -0
  5. package/dist/client/lifecycle-events.d.ts.map +1 -0
  6. package/dist/client/stream-adapter.d.ts +11 -5
  7. package/dist/client/stream-adapter.d.ts.map +1 -1
  8. package/dist/client/xml-artifact-feed.d.ts +76 -0
  9. package/dist/client/xml-artifact-feed.d.ts.map +1 -0
  10. package/dist/components/bubble/aparte-chat-bubble.d.ts +35 -8
  11. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
  12. package/dist/components/chat/aparte-chat.d.ts +0 -6
  13. package/dist/components/chat/aparte-chat.d.ts.map +1 -1
  14. package/dist/components/composer/aparte-composer-action.d.ts +18 -3
  15. package/dist/components/composer/aparte-composer-action.d.ts.map +1 -1
  16. package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -1
  17. package/dist/components/composer/aparte-composer-attachments.d.ts +1 -1
  18. package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
  19. package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -1
  20. package/dist/components/composer/aparte-composer-input.d.ts +0 -2
  21. package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
  22. package/dist/components/composer/aparte-composer-send.d.ts +5 -0
  23. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  24. package/dist/components/composer/aparte-composer-toolbar.d.ts +4 -0
  25. package/dist/components/composer/aparte-composer-toolbar.d.ts.map +1 -1
  26. package/dist/components/composer/aparte-composer.d.ts +64 -6
  27. package/dist/components/composer/aparte-composer.d.ts.map +1 -1
  28. package/dist/components/composer/index.d.ts +1 -1
  29. package/dist/components/composer/index.d.ts.map +1 -1
  30. package/dist/components/conversation-list/aparte-conversation-list.d.ts +2 -5
  31. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
  32. package/dist/components/conversation-list/index.d.ts +1 -1
  33. package/dist/components/conversation-list/index.d.ts.map +1 -1
  34. package/dist/components/elicitation/aparte-elicitation.d.ts +63 -3
  35. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  36. package/dist/components/index.d.ts +2 -2
  37. package/dist/components/index.d.ts.map +1 -1
  38. package/dist/components/status/aparte-chat-status.d.ts +8 -6
  39. package/dist/components/status/aparte-chat-status.d.ts.map +1 -1
  40. package/dist/components/viewport/aparte-chat-viewport.d.ts +35 -9
  41. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  42. package/dist/config/action-provider.d.ts +4 -4
  43. package/dist/config/aparte-config.d.ts +124 -41
  44. package/dist/config/aparte-config.d.ts.map +1 -1
  45. package/dist/config/attachment-renderer.d.ts +1 -1
  46. package/dist/config/avatar-provider.d.ts +1 -1
  47. package/dist/config/config-context.d.ts +66 -11
  48. package/dist/config/config-context.d.ts.map +1 -1
  49. package/dist/config/elicitation-field-renderer.d.ts +73 -0
  50. package/dist/config/elicitation-field-renderer.d.ts.map +1 -0
  51. package/dist/config/error-renderer.d.ts +1 -1
  52. package/dist/config/icon-provider.d.ts +2 -2
  53. package/dist/config/icon-provider.d.ts.map +1 -1
  54. package/dist/config/index.d.ts +7 -5
  55. package/dist/config/index.d.ts.map +1 -1
  56. package/dist/config/locale.d.ts +43 -2
  57. package/dist/config/locale.d.ts.map +1 -1
  58. package/dist/config/sanitize.d.ts +1 -7
  59. package/dist/config/sanitize.d.ts.map +1 -1
  60. package/dist/config/sibling-nav-renderer.d.ts +1 -1
  61. package/dist/config/skeleton-provider.d.ts +2 -2
  62. package/dist/config/skeleton-provider.d.ts.map +1 -1
  63. package/dist/config/status-renderer.d.ts +1 -1
  64. package/dist/conversations/conversation-controller.d.ts +19 -5
  65. package/dist/conversations/conversation-controller.d.ts.map +1 -1
  66. package/dist/conversations/conversation-manager.d.ts +2 -2
  67. package/dist/conversations/conversation-manager.d.ts.map +1 -1
  68. package/dist/conversations/index.d.ts +1 -1
  69. package/dist/conversations/index.d.ts.map +1 -1
  70. package/dist/conversations/types.d.ts +1 -1
  71. package/dist/custom-elements.json +7962 -6175
  72. package/dist/elicitation/index.d.ts +1 -1
  73. package/dist/elicitation/panel.d.ts +32 -0
  74. package/dist/elicitation/panel.d.ts.map +1 -1
  75. package/dist/elicitation/types.d.ts +29 -2
  76. package/dist/elicitation/types.d.ts.map +1 -1
  77. package/dist/host/aparte-chat-host.d.ts +3 -3
  78. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  79. package/dist/{index-Dn7TH14G.js → index-BieFbKeW.js} +1795 -1238
  80. package/dist/index-BieFbKeW.js.map +1 -0
  81. package/dist/index.css +311 -21
  82. package/dist/index.d.ts +21 -13
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +447 -200
  85. package/dist/index.js.map +1 -1
  86. package/dist/index.node.d.ts +22 -13
  87. package/dist/index.node.d.ts.map +1 -1
  88. package/dist/index.node.js +54 -46
  89. package/dist/index.node.js.map +1 -1
  90. package/dist/interop/element-props.d.ts +1 -1
  91. package/dist/interop/element-props.d.ts.map +1 -1
  92. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  93. package/dist/primitives/index.d.ts +1 -1
  94. package/dist/primitives/index.d.ts.map +1 -1
  95. package/dist/primitives/select/aparte-optgroup.d.ts +15 -4
  96. package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -1
  97. package/dist/primitives/select/aparte-option.d.ts +0 -5
  98. package/dist/primitives/select/aparte-option.d.ts.map +1 -1
  99. package/dist/primitives/select/aparte-select.d.ts +17 -5
  100. package/dist/primitives/select/aparte-select.d.ts.map +1 -1
  101. package/dist/primitives/select/index.d.ts +1 -1
  102. package/dist/primitives/select/index.d.ts.map +1 -1
  103. package/dist/renderers/markdown-stream.d.ts +42 -0
  104. package/dist/renderers/markdown-stream.d.ts.map +1 -0
  105. package/dist/renderers/segment-renderers.d.ts +20 -14
  106. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  107. package/dist/renderers/segments/artifact/binary-file.d.ts +45 -0
  108. package/dist/renderers/segments/artifact/binary-file.d.ts.map +1 -0
  109. package/dist/renderers/segments/artifact/card.d.ts +3 -0
  110. package/dist/renderers/segments/artifact/card.d.ts.map +1 -0
  111. package/dist/renderers/segments/artifact/preview-document.d.ts +27 -0
  112. package/dist/renderers/segments/artifact/preview-document.d.ts.map +1 -0
  113. package/dist/renderers/segments/artifact/shared.d.ts +12 -0
  114. package/dist/renderers/segments/artifact/shared.d.ts.map +1 -0
  115. package/dist/renderers/segments/code.d.ts +3 -0
  116. package/dist/renderers/segments/code.d.ts.map +1 -0
  117. package/dist/renderers/segments/error.d.ts +3 -0
  118. package/dist/renderers/segments/error.d.ts.map +1 -0
  119. package/dist/renderers/segments/file-tree.d.ts +3 -0
  120. package/dist/renderers/segments/file-tree.d.ts.map +1 -0
  121. package/dist/renderers/segments/pipeline-waiting.d.ts +3 -0
  122. package/dist/renderers/segments/pipeline-waiting.d.ts.map +1 -0
  123. package/dist/renderers/segments/progress.d.ts +3 -0
  124. package/dist/renderers/segments/progress.d.ts.map +1 -0
  125. package/dist/renderers/segments/terminal.d.ts +3 -0
  126. package/dist/renderers/segments/terminal.d.ts.map +1 -0
  127. package/dist/renderers/segments/text.d.ts +10 -0
  128. package/dist/renderers/segments/text.d.ts.map +1 -0
  129. package/dist/renderers/segments/thinking.d.ts +3 -0
  130. package/dist/renderers/segments/thinking.d.ts.map +1 -0
  131. package/dist/renderers/segments/tool-call.d.ts +3 -0
  132. package/dist/renderers/segments/tool-call.d.ts.map +1 -0
  133. package/dist/runtime/message-repository.d.ts +3 -3
  134. package/dist/runtime/message-repository.d.ts.map +1 -1
  135. package/dist/transport/backend-handler.d.ts +19 -7
  136. package/dist/transport/backend-handler.d.ts.map +1 -1
  137. package/dist/transport/backend-transport.d.ts +1 -1
  138. package/dist/transport/backend-transport.d.ts.map +1 -1
  139. package/dist/transport/direct-transport.d.ts +4 -4
  140. package/dist/transport/direct-transport.d.ts.map +1 -1
  141. package/dist/transport/index.d.ts +2 -2
  142. package/dist/transport/index.d.ts.map +1 -1
  143. package/dist/transport/types.d.ts +3 -3
  144. package/dist/types/element-map.d.ts +69 -0
  145. package/dist/types/element-map.d.ts.map +1 -0
  146. package/dist/types/event-map.d.ts +84 -23
  147. package/dist/types/event-map.d.ts.map +1 -1
  148. package/dist/types/events.d.ts +206 -64
  149. package/dist/types/events.d.ts.map +1 -1
  150. package/dist/types/index.d.ts +4 -5
  151. package/dist/types/index.d.ts.map +1 -1
  152. package/dist/types/model-provider.d.ts +100 -54
  153. package/dist/types/model-provider.d.ts.map +1 -1
  154. package/dist/types/models.d.ts +29 -7
  155. package/dist/types/models.d.ts.map +1 -1
  156. package/dist/types/segments.d.ts +1 -8
  157. package/dist/types/segments.d.ts.map +1 -1
  158. package/dist/types/theming.d.ts +25 -37
  159. package/dist/types/theming.d.ts.map +1 -1
  160. package/dist/types/tools.d.ts +60 -15
  161. package/dist/types/tools.d.ts.map +1 -1
  162. package/dist/utils/escape.d.ts +46 -0
  163. package/dist/utils/escape.d.ts.map +1 -0
  164. package/dist/utils/files-to-attachments.d.ts +18 -1
  165. package/dist/utils/files-to-attachments.d.ts.map +1 -1
  166. package/dist/utils/uuid.d.ts +26 -0
  167. package/dist/utils/uuid.d.ts.map +1 -0
  168. package/package.json +3 -5
  169. package/dist/index-Dn7TH14G.js.map +0 -1
  170. package/dist/types/providers.d.ts +0 -93
  171. package/dist/types/providers.d.ts.map +0 -1
package/README.md CHANGED
@@ -19,7 +19,7 @@ npm install @aparte/core
19
19
  ```ts
20
20
  import '@aparte/core'; // registers the <aparte-*> custom elements
21
21
  import '@aparte/core/styles.css'; // theme variables + component styles
22
- import { AparteConfig, AparteClient } from '@aparte/core';
22
+ import { aparteGlobalConfig, AparteClient } from '@aparte/core';
23
23
 
24
24
  // Drop the shell in your HTML: <aparte-chat placeholder="Ask anything…"></aparte-chat>
25
25
 
@@ -30,7 +30,7 @@ new AparteClient().start();
30
30
 
31
31
  // The retry / edit buttons only do something with a host like the client above, so
32
32
  // core ships them off. One line turns them on:
33
- AparteConfig.setBubbleActions({ retry: true, edit: true });
33
+ aparteGlobalConfig.setBubbleActions({ retry: true, edit: true });
34
34
  ```
35
35
 
36
36
  The built-in segment renderers install themselves the first time a segment needs one, so
@@ -66,11 +66,11 @@ every CI run.
66
66
  and the host that makes the retry / edit buttons real: retry forks the conversation into a
67
67
  **branch** (with a built-in `‹ 1/2 ›` picker), edit rewrites the message in place. Both
68
68
  buttons are **off by default** — without a host they would answer to nobody — so switch
69
- them on next to the client: `AparteConfig.setBubbleActions({ retry: true, edit: true })`.
70
- - **Transports** — `DirectTransport` (browser → provider, BYOK / local model) or
71
- `BackendTransport` (browser → your endpoint, API key stays server-side).
69
+ them on next to the client: `aparteGlobalConfig.setBubbleActions({ retry: true, edit: true })`.
70
+ - **Transports** — `AparteDirectTransport` (browser → provider, BYOK / local model) or
71
+ `AparteBackendTransport` (browser → your endpoint, API key stays server-side).
72
72
  - **Theming** — restyle everything through `--aparte-*` CSS variables (Light DOM, no forking).
73
- - **Customization** — icons, render hooks, and a zoned action registry via `AparteConfig`.
73
+ - **Customization** — icons, render hooks, and a zoned action registry via `aparteGlobalConfig`.
74
74
 
75
75
  Zero runtime dependencies: Markdown, syntax highlighting, etc. are **opt-in** providers you inject.
76
76
  ESM-only (CJS consumers use `await import()`).
@@ -83,6 +83,20 @@ Attachments, Conversations & branching, Tools, Backend transport, Bring your own
83
83
  The agent engine, and Troubleshooting. Source under
84
84
  [`apps/docs`](https://github.com/apartejs/aparte/tree/main/apps/docs).
85
85
 
86
+ The two most-asked-for pages, directly:
87
+
88
+ - **[Customization](https://apartejs.dev/guides/customization/)** — every render
89
+ hook, the action registry, the composer toolbar.
90
+ - **[CSS variables](https://apartejs.dev/reference/css-variables/)** — the full
91
+ token catalogue, GENERATED from the stylesheet, so it cannot drift from it.
92
+
93
+ (This package used to carry `CUSTOMIZATION.md` and `THEMING.md` alongside these.
94
+ They were never published — `files` is `dist`, `README.md`, `LICENSE` — nothing
95
+ linked to them, and both had drifted: one taught a `registerBubbleAction` that does
96
+ not exist, the other listed six `--aparte-bubble-*` variables that the stylesheet
97
+ never defined. A wrong orphan a coding agent finds by grepping the repo is worse
98
+ than no orphan, so they are gone rather than fixed twice.)
99
+
86
100
  ## License
87
101
 
88
102
  MIT
@@ -1,4 +1,4 @@
1
- import { AparteConfigClass } from '../config/aparte-config.js';
1
+ import { AparteConfig } from '../config/aparte-config.js';
2
2
  import type { AparteStreamRunner } from './stream-adapter.js';
3
3
  import type { AparteMessage } from '../types/index.js';
4
4
  import { AparteChatRequest, AparteChatMessage } from '../types/chat.js';
@@ -109,6 +109,12 @@ export interface AparteClientOptions {
109
109
  * @default 10
110
110
  */
111
111
  maxTurns?: number;
112
+ /**
113
+ * Per-call ceiling (ms) for a tool handler to resolve before its signal is
114
+ * aborted. Defaults to 5 minutes — the same default, and the same option name,
115
+ * as `runStreamAgent`, so the value means one thing whichever loop runs.
116
+ */
117
+ toolTimeoutMs?: number;
112
118
  /**
113
119
  * Controls which files attached by the user are injected as raw content
114
120
  * parts in the LLM request.
@@ -142,32 +148,12 @@ export interface AparteClientOptions {
142
148
  fileInjectFilter?: (file: File) => boolean;
143
149
  /**
144
150
  * Config this client reads (providers, model selection, tools, system
145
- * prompt). Defaults to the global `AparteConfig` singleton. Pass a host's
151
+ * prompt). Defaults to `aparteGlobalConfig`. Pass a host's
146
152
  * instance config when scoping a client to one chat among several
147
153
  * (pairs with `scopeToTargetId`).
148
154
  */
149
- config?: AparteConfigClass;
155
+ config?: AparteConfig;
150
156
  }
151
- /**
152
- * AparteClient
153
- *
154
- * The "Automatic Transmission" for Aparte.
155
- * Connects the UI events (aparte-send) to the AI Providers (chat).
156
- * Handles:
157
- * - Listening to send events
158
- * - Resolving API keys
159
- * - Calling the appropriate Provider
160
- * - Streaming the response back to the UI
161
- * - Tool use: awaiting handlers and re-calling the provider
162
- *
163
- * @example
164
- * ```typescript
165
- * const client = new AparteClient({
166
- * keyResolver: (providerId) => process.env[providerId.toUpperCase() + '_KEY']
167
- * });
168
- * client.start();
169
- * ```
170
- */
171
157
  export declare class AparteClient {
172
158
  private _boundHandler;
173
159
  private _boundAbortHandler;
@@ -176,6 +162,20 @@ export declare class AparteClient {
176
162
  private _boundEditHandler;
177
163
  private _activeToolControllers;
178
164
  private _isAborted;
165
+ /**
166
+ * Does this window event belong to this client?
167
+ *
168
+ * One rule for all five handlers, because it used to be four near-copies and
169
+ * one omission: `aparte-compact` had no guard at all, so in the two-client
170
+ * layout the JSDoc documents, a single compact event made BOTH clients run —
171
+ * two paid summarisation calls against whichever chat the DOM scan found
172
+ * first, and a global reset that wiped the other conversation.
173
+ *
174
+ * A scoped client also answers only events ADDRESSED to it. The old guard let
175
+ * an untargeted event through to every scoped client, which turned one
176
+ * broadcast into an action on every chat on the page.
177
+ */
178
+ private _isForThisInstance;
179
179
  /** Aborts the in-flight vendor/transport fetch when the user stops a stream. */
180
180
  private _streamController;
181
181
  private options;
@@ -211,10 +211,30 @@ export declare class AparteClient {
211
211
  * approval to `{ approved: false }` — there is no timeout, since a human may
212
212
  * take any amount of time to decide.
213
213
  */
214
+ /**
215
+ * Await the human's Approve/Reject for one tool call.
216
+ *
217
+ * `target` is not decoration: it is the scope of the consent. The listener sits
218
+ * on `document` and used to accept any `aparte-tool-decision` whose
219
+ * `detail.toolCallId` matched — and that id is the tool-call id the MODEL chose.
220
+ * The built-in buttons dispatch with `bubbles: true, composed: true`, so on a
221
+ * page with two chats a click aimed at one tool could satisfy the gate awaiting
222
+ * a different tool in a different conversation. The consented action and the
223
+ * executed action came apart, which is the entire failure mode an approval gate
224
+ * exists to prevent — and the handler behind it is arbitrary consumer code.
225
+ *
226
+ * The check is DOM CONTAINMENT rather than a `targetId` string comparison. A
227
+ * model can choose an id; it cannot choose where in the tree the click happened.
228
+ * It also needs no change on the dispatch side, so a consumer's own Approve
229
+ * button keeps working as long as it fires from inside its own chat.
230
+ *
231
+ * The request half of this handshake was hardened with `targetId` for exactly
232
+ * this hazard. This is its sibling, and it was missed.
233
+ */
214
234
  private _awaitToolDecision;
215
235
  /**
216
236
  * Resolve the auth for a provider: `options.keyResolver` takes precedence,
217
- * then the AparteConfig key channel (`setKeyProvider`) so a key registered
237
+ * then the aparteGlobalConfig key channel (`setKeyProvider`) so a key registered
218
238
  * there reaches the request. One key source on the happy path.
219
239
  */
220
240
  private _resolveAuth;
@@ -237,16 +257,38 @@ export declare class AparteClient {
237
257
  * Triggered programmatically or by dispatching `window.dispatchEvent(new CustomEvent('aparte-compact'))`.
238
258
  * Dispatches `aparte-compact-done` on window when complete, or `aparte-compact-error` on failure.
239
259
  */
240
- compact(): Promise<void>;
260
+ compact(targetId?: string): Promise<void>;
241
261
  /**
242
262
  * Handle aparte-retry — add a sibling branch to the assistant message and re-stream
243
263
  * using the same conversation history minus the retried reply.
244
264
  */
245
265
  /**
246
- * Registered tools, gated by capability: only returned when the current model
247
- * declares `function_calling` support (else `[]`). Single source for the gate so
248
- * send / retry / edit can't drift — the drift is exactly what shipped `tools` on
249
- * the initial send while retry/edit correctly omitted them.
266
+ * The registered tools, unless the current model says it cannot call one.
267
+ *
268
+ * Single source for the gate, so send / retry / edit cannot drift — that drift
269
+ * is what once shipped `tools` on the initial send while retry and edit omitted
270
+ * them.
271
+ *
272
+ * The gate used to be "the model DECLARES function_calling", defaulting to
273
+ * stripping — and that made the whole tool surface unreachable on the primary
274
+ * documented path. Three things had to line up for a tool to be sent, and one
275
+ * never did: the app sets a model id by hand (`setModelConfig`) or a selector
276
+ * sets it from a fetched list, and in both cases the model's declared
277
+ * capabilities are commonly unknown. `undefined` capabilities then read as "no
278
+ * function calling", so `tools: []` went on the wire while `getTools()` held
279
+ * the tool the app had explicitly registered. The model answered, correctly,
280
+ * that it had no such tool, and nothing anywhere said why.
281
+ *
282
+ * So the question is now "did this model say it cannot", not "did it say it
283
+ * can". Registering a tool is an explicit act by the app; silently dropping it
284
+ * because a `/models` listing is terse is the library second-guessing the
285
+ * developer. A model that declares its capabilities and omits function calling
286
+ * is still honoured — that is a statement, and it is respected.
287
+ *
288
+ * Failure modes, both ways round: over-sending means a model that cannot use
289
+ * tools does not call one, or its own endpoint rejects the array with an error
290
+ * the developer can read. Under-sending was silent, total, and looked like a
291
+ * lying model.
250
292
  */
251
293
  private _toolsForCurrentModel;
252
294
  private _handleRetry;
@@ -277,7 +319,42 @@ export declare class AparteClient {
277
319
  */
278
320
  private _buildMessages;
279
321
  private _toHistoryMessages;
322
+ /**
323
+ * What the model is told it said last turn — reconstructed from what was
324
+ * RENDERED, not from the raw-text field.
325
+ *
326
+ * The order used to be the other way round, and it silently corrupted the
327
+ * context on the most common opening in a coding chat: a reply starting with a
328
+ * code fence was sent back as three backticks and nothing else. Three
329
+ * correct-in-isolation decisions composed into it:
330
+ *
331
+ * 1. the parser withholds an ambiguous prefix (``` ``` ```, `` ` ``, `<`)
332
+ * waiting for the next delta, and creates no active segment while it waits;
333
+ * 2. so `_streamLoop` sees zero segments, concludes the parser produced
334
+ * nothing, and appends the raw delta straight to `message.content`;
335
+ * 3. and this method preferred `content`.
336
+ *
337
+ * The bubble hides its content element as soon as segments exist, so the UI was
338
+ * perfect and only the NEXT request showed it. No unit test, no example and
339
+ * no browser test could see it.
340
+ *
341
+ * `content` stays as the fallback, and that is not vestigial: a non-streaming
342
+ * transport writes the whole reply there and creates no segments at all.
343
+ */
280
344
  private _extractText;
345
+ /**
346
+ * Segments → the text a model can read back.
347
+ *
348
+ * Fences and the language tag are kept. Without them the model re-reads its own
349
+ * code as prose — which is how it starts explaining a snippet it believes it
350
+ * wrote in English. Artifacts are included for the same reason: dropping them
351
+ * made an artifact the model had just produced invisible on the very next turn,
352
+ * so it could not be asked to change the thing it had built.
353
+ *
354
+ * `thinking` stays out on purpose — it is the model's own scratchpad, and most
355
+ * APIs neither want it back nor bill for it kindly.
356
+ */
357
+ private _segmentsToText;
281
358
  /**
282
359
  * Which of the send's pending files get inlined into the request: the
283
360
  * `rawFileInject` mode first —
@@ -295,17 +372,6 @@ export declare class AparteClient {
295
372
  * - Other binary files → silently ignored.
296
373
  */
297
374
  private _filesToContentParts;
298
- /**
299
- * Stream loop: runs one provider.chat() call and repeats if a tool was called.
300
- * Maintains a running messages array to inject tool_call / tool_result turns.
301
- */
302
- /**
303
- * Feed one text delta to the Claude-style `<artifact>` XML streamer. Scans for
304
- * `<artifact …>` / `</artifact>`, routing chat text through the text parser and
305
- * artifact content into a dedicated artifact segment (handling tags split across
306
- * deltas). Mutates `xml` in place. Extracted from _streamLoop.
307
- */
308
- private _feedXmlArtifactDelta;
309
375
  /**
310
376
  * Turn-1 forced tool call. When `toolChoice = { name, input }`
311
377
  * (orchestrator-driven), execute the handler directly instead of consulting
@@ -323,6 +389,10 @@ export declare class AparteClient {
323
389
  * returns whether the agentic loop should keep going.
324
390
  */
325
391
  private _handleToolUseEvent;
392
+ /**
393
+ * Stream loop: runs one provider.chat() call and repeats if a tool was called.
394
+ * Maintains a running messages array to inject tool_call / tool_result turns.
395
+ */
326
396
  private _streamLoop;
327
397
  /**
328
398
  * Delegate `_streamLoop`'s agentic loop to an injected {@link AparteStreamRunner},
@@ -342,12 +412,8 @@ export declare class AparteClient {
342
412
  * Gracefully handles errors by updating the current message instead of duplicating it
343
413
  */
344
414
  private _handleLifecycleError;
345
- private _dispatchLifecycleEvent;
346
- /**
347
- * Dispatch the artifact lifecycle (`aparte-artifact-start` / `delta` / `ready`)
348
- * on the host bubble element. Idempotent for `start` (fires once per segment id)
349
- * and emits `delta` only when the body actually grew. `isFinal=true` fires `ready`.
350
- */
351
- private _dispatchArtifactLifecycle;
415
+ /** Warn once per client for an unrecognised stream event, then carry on. */
416
+ private _warnedUnknownEvents;
417
+ private _warnUnknownStreamEvent;
352
418
  }
353
419
  //# sourceMappingURL=aparte-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-client.d.ts","sourceRoot":"","sources":["../../src/client/aparte-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aparte-client.d.ts","sourceRoot":"","sources":["../../src/client/aparte-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQ9E,OAAO,KAAK,EAAE,kBAAkB,EAAuB,MAAM,qBAAqB,CAAC;AACnF,OAAO,KAAK,EAAoC,aAAa,EAAsB,MAAM,mBAAmB,CAAC;AAK7G,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAoE,MAAM,kBAAkB,CAAC;AAoC1I;;;GAGG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,KAClB,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACnC,QAAQ,EAAE,aAAa,EAAE,KACxB;IAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAAC,IAAI,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC;IAEvJ;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAE9C;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAE9C;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAElC;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEpG;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,gBAAgB,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,CAAC,CAAC;IAE7F;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAE1C;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;;;;;;;;;;;OAiBG;IACH,aAAa,CAAC,EAAE,KAAK,GAAG,aAAa,GAAG,MAAM,CAAC;IAE/C;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACzB;AAwDD,qBAAa,YAAY;IACrB,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,sBAAsB,CAAmC;IACjE,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,kBAAkB;IA4C1B,gFAAgF;IAChF,OAAO,CAAC,iBAAiB,CAAgC;IAEzD,OAAO,CAAC,OAAO,CAAsB;IACrC,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;gBAE3B,OAAO,GAAE,mBAAwB;IAuB7C;;;OAGG;IACH,OAAO,CAAC,eAAe;IAmBvB;;OAEG;IACH,KAAK,IAAI,IAAI;IA2Cb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiCZ;;;OAGG;IACH,KAAK,IAAI,IAAI;IASb;;;;;;;;;;OAUG;IACH;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;;;OAIG;YACW,YAAY;IAS1B;;;;;;;;;;OAUG;YACW,WAAW;IAmEzB;;;;;;OAMG;IACG,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmJ/C;;;OAGG;IACH;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,OAAO,CAAC,qBAAqB;YAMf,YAAY;IAiE1B;;;OAGG;YACW,WAAW;IAuEzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,OAAO,CAAC,uBAAuB;YAYjB,WAAW;IA0JzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,kBAAkB;IA2B1B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,eAAe;IAoBvB;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;;;;;OAMG;YACW,oBAAoB;IAsClC;;;;;;;OAOG;YACW,sBAAsB;IAiEpC;;;;;;OAMG;YACW,mBAAmB;IAmNjC;;;OAGG;YACW,WAAW;IAmdzB;;;;;;;;OAQG;YACW,mBAAmB;IAwEjC;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8C7B,4EAA4E;IAC5E,OAAO,CAAC,oBAAoB,CAAqB;IACjD,OAAO,CAAC,uBAAuB;CAUlC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The DOM lifecycle dispatchers, once.
3
+ *
4
+ * These two functions existed TWICE — as private methods on `AparteClient` and as
5
+ * module-level copies in `stream-adapter.ts` — one per streaming loop. That is not a
6
+ * size problem, it is a correctness problem the repo has already paid for, and the
7
+ * adapter copy's own JSDoc recorded the bill:
8
+ *
9
+ * the `targetId` stamp was missing from the adapter copy, and `aparte-composer`'s
10
+ * `_isForThisComposer` treats an ABSENT `targetId` as "for me" — deliberately, so a
11
+ * single-chat page needs no wiring. So on a two-chat page the engine path made
12
+ * stopping chat A reset chat B's composer as well. Core's inline path had always
13
+ * stamped it. The parity suite could not see it, because its recorder element has
14
+ * no `id`: both paths produced `targetId: undefined` and agreed.
15
+ *
16
+ * A duplicate that has already drifted once will drift again, and the suite that
17
+ * exists to catch divergence between the two loops is structurally blind to this
18
+ * one. So there is one copy now, and both loops call it.
19
+ *
20
+ * ## Why the target is declared here
21
+ *
22
+ * `stream-adapter.ts` must import this module, so importing its `StreamAdapterTarget`
23
+ * back would close a real cycle. The structural type below is the intersection both
24
+ * callers satisfy: core's client passes an `HTMLElement`, the adapter passes its
25
+ * duck-typed target, and neither needs anything else.
26
+ */
27
+ import type { AparteArtifactSegment } from '../types/segments.js';
28
+ /** Anything that can receive a DOM event and may carry an id. */
29
+ export interface AparteLifecycleTarget {
30
+ readonly id?: string;
31
+ dispatchEvent(event: Event): boolean;
32
+ }
33
+ /**
34
+ * Dispatch one bubbling, composed lifecycle event, stamped with the target's id so
35
+ * several chats on one page stay isolated — a composer reacts only to its own host's
36
+ * turn, while an id-less single-instance page still broadcasts.
37
+ *
38
+ * The `typeof detail === 'object'` guard comes from the adapter copy and is kept
39
+ * deliberately: it is a superset of the client copy's unconditional spread, so
40
+ * unifying on it cannot change any existing call, and it is the only difference
41
+ * between the two versions that was ever load-bearing.
42
+ */
43
+ export declare function dispatchLifecycleEvent(target: AparteLifecycleTarget, name: string, detail: unknown): void;
44
+ /**
45
+ * Dispatch the artifact lifecycle: `aparte-artifact-start` once per segment id,
46
+ * `aparte-artifact-delta` when the body actually grew, and `aparte-artifact-ready`
47
+ * when `isFinal`. `progress` tracks the per-id length already broadcast, so a
48
+ * re-render cannot replay a delta.
49
+ *
50
+ * The segment parameter is structural rather than `AparteArtifactSegment` because the
51
+ * adapter builds its segments from stream events and never constructs the full type;
52
+ * the import above keeps the two documented as the same thing.
53
+ */
54
+ export declare function dispatchArtifactLifecycle(target: AparteLifecycleTarget, messageId: string, segment: Pick<AparteArtifactSegment, 'id'> & Partial<Pick<AparteArtifactSegment, 'content' | 'mimeType' | 'artifactType' | 'title'>>, progress: Map<string, number>, isFinal: boolean): void;
55
+ //# sourceMappingURL=lifecycle-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-events.d.ts","sourceRoot":"","sources":["../../src/client/lifecycle-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,iEAAiE;AACjE,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,GAChB,IAAI,CAMN;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,UAAU,GAAG,cAAc,GAAG,OAAO,CAAC,CAAC,EACpI,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,OAAO,EAAE,OAAO,GACjB,IAAI,CA2CN"}
@@ -17,7 +17,7 @@
17
17
  * `AparteClientOptions.streamRunner` seam — the same pattern as `approvalResolver`
18
18
  * (HITL) and `compactionSelector`. Keep the two unions in sync by hand.
19
19
  */
20
- import type { AparteConfigClass } from '../config/aparte-config.js';
20
+ import type { AparteConfig } from '../config/aparte-config.js';
21
21
  import type { AparteSegment, AparteMessage, AparteStreamEvent } from '../types/index.js';
22
22
  import type { AparteUsage, AparteChatRequest } from '../types/chat.js';
23
23
  /**
@@ -112,7 +112,7 @@ export interface AparteStreamRunOptions {
112
112
  baseRequest: AparteChatRequest;
113
113
  /** Calls the transport; returns the structured stream or a plain string. */
114
114
  transportCall: (request: AparteChatRequest) => Promise<AsyncIterable<AparteStreamEvent> | string>;
115
- /** Resolves a tool's handler by name (mirrors `AparteConfig.getToolHandler`). */
115
+ /** Resolves a tool's handler by name (mirrors `aparteGlobalConfig.getToolHandler`). */
116
116
  toolLookup: (name: string) => ((call: {
117
117
  id: string;
118
118
  name: string;
@@ -142,8 +142,14 @@ export interface AparteStreamRunOptions {
142
142
  * A headless structured-stream loop injected via `AparteClientOptions.streamRunner`
143
143
  * — the seam by which a consumer swaps `_streamLoop`'s inline loop for
144
144
  * `@aparte/engine`'s `runStreamAgent` (core stays the zero-dep leaf; it never
145
- * imports engine). Structurally identical to `runStreamAgent`; wire it with a
146
- * cast at the injection site if the duck-typed shapes don't line up exactly.
145
+ * imports engine).
146
+ *
147
+ * `runStreamAgent` is directly assignable to this type — pass it, do not cast it.
148
+ * An earlier version of this comment advised a cast "if the duck-typed shapes
149
+ * don't line up", which is how the two packages' message types drifted apart
150
+ * unnoticed and shipped a `streamRunner: runStreamAgent` that did not compile on
151
+ * five docs pages and a README. A cast here hides exactly the drift that
152
+ * `stream-events.contract.ts` now exists to fail on.
147
153
  */
148
154
  export type AparteStreamRunner = (opts: AparteStreamRunOptions) => Promise<AparteUsage | undefined>;
149
155
  /**
@@ -165,7 +171,7 @@ export interface CreateStreamAdapterOptions {
165
171
  /** The chat target element the events are rendered onto. */
166
172
  target: StreamAdapterTarget;
167
173
  /** Config for tool-renderer lookup + per-tool style injection. */
168
- config: AparteConfigClass;
174
+ config: AparteConfig;
169
175
  /** The streamed assistant message id (carried in run/artifact events). */
170
176
  messageId: string;
171
177
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"stream-adapter.d.ts","sourceRoot":"","sources":["../../src/client/stream-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream-adapter.d.ts","sourceRoot":"","sources":["../../src/client/stream-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOzF,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAIvE;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC1B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpF;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACpF;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7F;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAEhD,6EAA6E;AAC7E,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,4EAA4E;IAC5E,aAAa,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,aAAa,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAC;IAClG,uFAAuF;IACvF,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAC;IACtK,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IAChG,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClH,0DAA0D;IAC1D,OAAO,EAAE,sBAAsB,CAAC;IAChC,+EAA+E;IAC/E,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACtC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;AAEpG;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,aAAa,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAClE,iBAAiB,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1E,UAAU,CAAC,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IACzE,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,0BAA0B;IACvC,4DAA4D;IAC5D,MAAM,EAAE,mBAAmB,CAAC;IAC5B,kEAAkE;IAClE,MAAM,EAAE,YAAY,CAAC;IACrB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,0BAA0B,GAAG,sBAAsB,CAqS5F;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACnC,MAAM,EAAE,cAAc,CAAC,iBAAiB,CAAC,EACzC,MAAM,EAAE,WAAW,GACpB,aAAa,CAAC,iBAAiB,CAAC,CA4BlC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The Claude-style `<artifact>` XML streamer: scans one text delta for
3
+ * `<artifact …>` / `</artifact>`, routes chat text through the text parser and
4
+ * artifact content into a dedicated artifact segment, and holds back a tag split
5
+ * across deltas.
6
+ *
7
+ * TWIN: `packages/engine/src/agent/parsers/artifact-xml-state-machine.ts`. Core
8
+ * cannot import engine's copy — engine peer-depends on core — so the two are
9
+ * maintained by hand, and the parity suite asserts the same cases on both sides.
10
+ * A fix applied to one twin and not the other is this repo's most repeated bug,
11
+ * which is the reason this is a file: the two used to cite each other by line
12
+ * number into a 2324-line module, and four of those citations had rotted onto
13
+ * unrelated code — one of them in the published docs.
14
+ *
15
+ * It sits outside `AparteClient` because it never belonged inside it. It touches
16
+ * `this` zero times: the state it mutates is owned by its caller and passed in.
17
+ */
18
+ import { AparteStreamParser } from '../parsers/aparte-stream-parser.js';
19
+ import { type AparteLifecycleTarget } from './lifecycle-events.js';
20
+ import type { AparteSegment } from '../types/index.js';
21
+ import type { AparteArtifactHint } from '../types/chat.js';
22
+ export type XmlArtifactFeedTarget = AparteLifecycleTarget & {
23
+ addSegment?(segment: AparteSegment): void;
24
+ updateSegment?(segmentId: string, updates: Partial<AparteSegment>): void;
25
+ };
26
+ /** Mutable state for streaming a Claude-style `<artifact>` XML block out of the
27
+ * text stream — owned by the caller's stream loop, fed one delta at a time. */
28
+ export interface XmlArtifactStreamState {
29
+ state: 'normal' | 'scanning' | 'in-artifact';
30
+ scanBuf: string;
31
+ closeBuf: string;
32
+ segId: string | null;
33
+ content: string;
34
+ mime: string;
35
+ kind: string;
36
+ title: string;
37
+ }
38
+ /**
39
+ * Feed one text delta to the Claude-style `<artifact>` XML streamer. Scans for
40
+ * `<artifact …>` / `</artifact>`, routing chat text through the text parser and
41
+ * artifact content into a dedicated artifact segment (handling tags split across
42
+ * deltas). Mutates `xml` in place.
43
+ */
44
+ export declare function feedXmlArtifactDelta(delta: string, xml: XmlArtifactStreamState, ctx: {
45
+ targetElement: XmlArtifactFeedTarget;
46
+ messageId: string;
47
+ textParser: AparteStreamParser;
48
+ streamingSegmentIds: Set<string>;
49
+ artifactProgress: Map<string, number>;
50
+ artifactXmlHint: AparteArtifactHint;
51
+ }): void;
52
+ /**
53
+ * Flush a truncated artifact: a stream that ended mid-body (the model cut off
54
+ * before `</artifact>`) still has to render what arrived.
55
+ *
56
+ * The twin of engine's `XmlArtifactStateMachine.finalize()`, and it lives here for
57
+ * the same reason the feeder does — engine's copy is ONE file holding both halves,
58
+ * so splitting them across files in core is precisely the drift the pairing exists
59
+ * to prevent. It also puts the `scanning` note in the feeder next to the state test
60
+ * that makes it true.
61
+ */
62
+ export declare function finalizeXmlArtifact(xml: XmlArtifactStreamState, ctx: {
63
+ targetElement: XmlArtifactFeedTarget;
64
+ messageId: string;
65
+ artifactProgress: Map<string, number>;
66
+ /** Absent when the turn was not in XML-artifact mode — then there is nothing to flush. */
67
+ artifactXmlHint: AparteArtifactHint | undefined;
68
+ /**
69
+ * The turn's text parser. The `scanning` branch pushes held text into it, so
70
+ * the caller MUST call this before `textParser.finalize()`.
71
+ */
72
+ textParser: AparteStreamParser;
73
+ /** So the held-text render does not re-add a segment already on screen. */
74
+ streamingSegmentIds: Set<string>;
75
+ }): void;
76
+ //# sourceMappingURL=xml-artifact-feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-artifact-feed.d.ts","sourceRoot":"","sources":["../../src/client/xml-artifact-feed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,kBAAkB,EAAsB,MAAM,oCAAoC,CAAC;AAC5F,OAAO,EAA6B,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9F,OAAO,KAAK,EAAE,aAAa,EAAyB,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAsB3D,MAAM,MAAM,qBAAqB,GAAG,qBAAqB,GAAG;IACxD,UAAU,CAAC,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;CAC5E,CAAC;AAoBF;gFACgF;AAChF,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,sBAAsB,EAC3B,GAAG,EAAE;IACD,aAAa,EAAE,qBAAqB,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,EAAE,kBAAkB,CAAC;CACvC,GACF,IAAI,CAoKN;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAC/B,GAAG,EAAE,sBAAsB,EAC3B,GAAG,EAAE;IACD,aAAa,EAAE,qBAAqB,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,0FAA0F;IAC1F,eAAe,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAChD;;;OAGG;IACH,UAAU,EAAE,kBAAkB,CAAC;IAC/B,2EAA2E;IAC3E,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACpC,GACF,IAAI,CAqEN"}
@@ -77,6 +77,20 @@ export declare class AparteChatBubble extends HTMLElement {
77
77
  /** Get all segments */
78
78
  getSegments(): AparteSegment[];
79
79
  /** Remove a segment by id (e.g. to discard a transient waiting indicator) */
80
+ /**
81
+ * Scoped to DIRECT children on purpose.
82
+ *
83
+ * Segments are appended as direct children of the container, but a descendant
84
+ * query returns the first match in document order — and sanitized model
85
+ * markdown renders inside that same container, with `data-*` attributes
86
+ * deliberately preserved (they are inert). So a decoy `data-segment-id` planted
87
+ * in an earlier segment's prose used to win over the real segment element.
88
+ *
89
+ * Parser ids are unguessable UUIDs, but a tool segment is `tool-${toolCallId}`
90
+ * and the MODEL chooses that id — so this was reachable, and pointing an update
91
+ * at a decoy left a rejected tool rendering as still-running: a spoof against
92
+ * the human-in-the-loop control.
93
+ */
80
94
  removeSegment(segmentId: string): void;
81
95
  /** Set attachments (chips shown above message content, user role only) */
82
96
  setAttachments(attachments: AparteAttachment[]): void;
@@ -85,7 +99,7 @@ export declare class AparteChatBubble extends HTMLElement {
85
99
  *
86
100
  * This is the *precondition* for the info ("i") action, not the trigger: the
87
101
  * button appears only if the app also declared it wants it —
88
- * `AparteConfig.setBubbleActions({ info: true })` — because the stats popover it
102
+ * `aparteGlobalConfig.setBubbleActions({ info: true })` — because the stats popover it
89
103
  * opens (`aparte-message-info`) is the app's, and core has none. Without usage
90
104
  * there is nothing to show, so the button never renders either way.
91
105
  */
@@ -148,7 +162,26 @@ export declare class AparteChatBubble extends HTMLElement {
148
162
  private _updateAttachments;
149
163
  /** Uppercased file extension (≤4 chars), or 'FILE' when there is none. */
150
164
  private _fileExt;
151
- private _setupBranchPickerListeners;
165
+ /**
166
+ * The branch arrows are handled by DELEGATION, on this element, bound once.
167
+ *
168
+ * They used to get a fresh listener each, attached by `_render()` to the buttons
169
+ * `_render()` had just created. So a click that landed while a re-render was
170
+ * swapping those nodes hit an element about to be discarded, and did nothing at
171
+ * all — not late, nothing. Invisible on a fast machine; reproducible on
172
+ * WebKit-Linux in CI, where `‹` left the picker on "2 / 2" and a 20-second
173
+ * assertion watched it stay there.
174
+ *
175
+ * Delegation makes `_render()` irrelevant to it: the listener lives on the host,
176
+ * which is never replaced, and `closest()` finds whichever button exists at the
177
+ * moment of the click. It is also less work — one listener per bubble instead of
178
+ * two per bubble per render.
179
+ *
180
+ * Bound in `connectedCallback` and removed in `disconnectedCallback` as a stable
181
+ * field, because an inline arrow re-added on every re-connect is how this repo has
182
+ * stacked listeners twice before (the viewport, and `aparte-select`).
183
+ */
184
+ private _onBranchPickerClick;
152
185
  private _updateBranchPicker;
153
186
  private _updateActionBar;
154
187
  /**
@@ -184,12 +217,6 @@ export declare class AparteChatBubble extends HTMLElement {
184
217
  */
185
218
  private _exitEditMode;
186
219
  private _resolveTargetId;
187
- private _escapeHtml;
188
220
  private _updateStreaming;
189
221
  }
190
- declare global {
191
- interface HTMLElementTagNameMap {
192
- 'aparte-chat-bubble': AparteChatBubble;
193
- }
194
- }
195
222
  //# sourceMappingURL=aparte-chat-bubble.d.ts.map
@@ -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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"}
@@ -69,11 +69,5 @@ export declare class AparteChat extends HTMLElement {
69
69
  /** Start/stop watching the viewport so `center-empty` toggles itself. */
70
70
  private _syncEmptyWatch;
71
71
  private _updateEmpty;
72
- private _escapeAttr;
73
- }
74
- declare global {
75
- interface HTMLElementTagNameMap {
76
- 'aparte-chat': AparteChat;
77
- }
78
72
  }
79
73
  //# sourceMappingURL=aparte-chat.d.ts.map
@@ -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;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,UAAW,SAAQ,WAAW;IACzC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,SAAS,CAAiC;IAElD;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B,iBAAiB,IAAI,IAAI;IAOzB,oBAAoB,IAAI,IAAI;IAK5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAmB9F,6EAA6E;IAC7E,IAAI,QAAQ,IAAI,kBAAkB,GAAG,IAAI,CAExC;IAED,qEAAqE;IACrE,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;IAED,OAAO,CAAC,OAAO;IA0Cf;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuBxB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IAKpB,yEAAyE;IACzE,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;CAGpB;AAOD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
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;AAGrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,UAAW,SAAQ,WAAW;IACzC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,SAAS,CAAiC;IAElD;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B,iBAAiB,IAAI,IAAI;IAOzB,oBAAoB,IAAI,IAAI;IAK5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAmB9F,6EAA6E;IAC7E,IAAI,QAAQ,IAAI,kBAAkB,GAAG,IAAI,CAExC;IAED,qEAAqE;IACrE,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;IAED,OAAO,CAAC,OAAO;IA0Cf;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuBxB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IAKpB,yEAAyE;IACzE,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,YAAY;CAMrB"}