@aparte/core 0.7.1 → 0.9.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 (175) 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/bubble/bubble-sync.d.ts.map +1 -1
  13. package/dist/components/chat/aparte-chat.d.ts +0 -6
  14. package/dist/components/chat/aparte-chat.d.ts.map +1 -1
  15. package/dist/components/composer/aparte-composer-action.d.ts +18 -3
  16. package/dist/components/composer/aparte-composer-action.d.ts.map +1 -1
  17. package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -1
  18. package/dist/components/composer/aparte-composer-attachments.d.ts +1 -1
  19. package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
  20. package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -1
  21. package/dist/components/composer/aparte-composer-input.d.ts +0 -2
  22. package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
  23. package/dist/components/composer/aparte-composer-send.d.ts +5 -0
  24. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  25. package/dist/components/composer/aparte-composer-toolbar.d.ts +4 -0
  26. package/dist/components/composer/aparte-composer-toolbar.d.ts.map +1 -1
  27. package/dist/components/composer/aparte-composer.d.ts +64 -6
  28. package/dist/components/composer/aparte-composer.d.ts.map +1 -1
  29. package/dist/components/composer/index.d.ts +1 -1
  30. package/dist/components/composer/index.d.ts.map +1 -1
  31. package/dist/components/conversation-list/aparte-conversation-list.d.ts +2 -5
  32. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
  33. package/dist/components/conversation-list/index.d.ts +1 -1
  34. package/dist/components/conversation-list/index.d.ts.map +1 -1
  35. package/dist/components/elicitation/aparte-elicitation.d.ts +63 -3
  36. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  37. package/dist/components/index.d.ts +2 -2
  38. package/dist/components/index.d.ts.map +1 -1
  39. package/dist/components/status/aparte-chat-status.d.ts +8 -6
  40. package/dist/components/status/aparte-chat-status.d.ts.map +1 -1
  41. package/dist/components/viewport/aparte-chat-viewport.d.ts +45 -9
  42. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  43. package/dist/config/action-provider.d.ts +4 -4
  44. package/dist/config/aparte-config.d.ts +124 -41
  45. package/dist/config/aparte-config.d.ts.map +1 -1
  46. package/dist/config/attachment-renderer.d.ts +1 -1
  47. package/dist/config/avatar-provider.d.ts +1 -1
  48. package/dist/config/config-context.d.ts +66 -11
  49. package/dist/config/config-context.d.ts.map +1 -1
  50. package/dist/config/elicitation-field-renderer.d.ts +73 -0
  51. package/dist/config/elicitation-field-renderer.d.ts.map +1 -0
  52. package/dist/config/error-renderer.d.ts +1 -1
  53. package/dist/config/icon-provider.d.ts +2 -2
  54. package/dist/config/icon-provider.d.ts.map +1 -1
  55. package/dist/config/index.d.ts +7 -5
  56. package/dist/config/index.d.ts.map +1 -1
  57. package/dist/config/locale.d.ts +43 -2
  58. package/dist/config/locale.d.ts.map +1 -1
  59. package/dist/config/sanitize.d.ts +1 -7
  60. package/dist/config/sanitize.d.ts.map +1 -1
  61. package/dist/config/sibling-nav-renderer.d.ts +1 -1
  62. package/dist/config/skeleton-provider.d.ts +2 -2
  63. package/dist/config/skeleton-provider.d.ts.map +1 -1
  64. package/dist/config/status-renderer.d.ts +1 -1
  65. package/dist/conversations/conversation-controller.d.ts +19 -5
  66. package/dist/conversations/conversation-controller.d.ts.map +1 -1
  67. package/dist/conversations/conversation-manager.d.ts +2 -2
  68. package/dist/conversations/conversation-manager.d.ts.map +1 -1
  69. package/dist/conversations/index.d.ts +1 -1
  70. package/dist/conversations/index.d.ts.map +1 -1
  71. package/dist/conversations/types.d.ts +1 -1
  72. package/dist/custom-elements.json +8418 -6295
  73. package/dist/elicitation/index.d.ts +1 -1
  74. package/dist/elicitation/panel.d.ts +32 -0
  75. package/dist/elicitation/panel.d.ts.map +1 -1
  76. package/dist/elicitation/types.d.ts +29 -2
  77. package/dist/elicitation/types.d.ts.map +1 -1
  78. package/dist/host/aparte-chat-host.d.ts +3 -3
  79. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  80. package/dist/{index-Dn7TH14G.js → index-hQQljwfX.js} +1890 -1222
  81. package/dist/index-hQQljwfX.js.map +1 -0
  82. package/dist/index.css +299 -21
  83. package/dist/index.d.ts +22 -13
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +485 -210
  86. package/dist/index.js.map +1 -1
  87. package/dist/index.node.d.ts +23 -13
  88. package/dist/index.node.d.ts.map +1 -1
  89. package/dist/index.node.js +56 -46
  90. package/dist/index.node.js.map +1 -1
  91. package/dist/interop/element-props.d.ts +1 -1
  92. package/dist/interop/element-props.d.ts.map +1 -1
  93. package/dist/parsers/aparte-stream-parser.d.ts +25 -0
  94. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  95. package/dist/primitives/index.d.ts +1 -1
  96. package/dist/primitives/index.d.ts.map +1 -1
  97. package/dist/primitives/select/aparte-optgroup.d.ts +15 -4
  98. package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -1
  99. package/dist/primitives/select/aparte-option.d.ts +0 -5
  100. package/dist/primitives/select/aparte-option.d.ts.map +1 -1
  101. package/dist/primitives/select/aparte-select.d.ts +17 -5
  102. package/dist/primitives/select/aparte-select.d.ts.map +1 -1
  103. package/dist/primitives/select/index.d.ts +1 -1
  104. package/dist/primitives/select/index.d.ts.map +1 -1
  105. package/dist/renderers/markdown-stream.d.ts +42 -0
  106. package/dist/renderers/markdown-stream.d.ts.map +1 -0
  107. package/dist/renderers/segment-renderers.d.ts +20 -14
  108. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  109. package/dist/renderers/segments/artifact/binary-file.d.ts +45 -0
  110. package/dist/renderers/segments/artifact/binary-file.d.ts.map +1 -0
  111. package/dist/renderers/segments/artifact/card.d.ts +3 -0
  112. package/dist/renderers/segments/artifact/card.d.ts.map +1 -0
  113. package/dist/renderers/segments/artifact/preview-document.d.ts +27 -0
  114. package/dist/renderers/segments/artifact/preview-document.d.ts.map +1 -0
  115. package/dist/renderers/segments/artifact/shared.d.ts +12 -0
  116. package/dist/renderers/segments/artifact/shared.d.ts.map +1 -0
  117. package/dist/renderers/segments/code.d.ts +3 -0
  118. package/dist/renderers/segments/code.d.ts.map +1 -0
  119. package/dist/renderers/segments/error.d.ts +3 -0
  120. package/dist/renderers/segments/error.d.ts.map +1 -0
  121. package/dist/renderers/segments/file-tree.d.ts +3 -0
  122. package/dist/renderers/segments/file-tree.d.ts.map +1 -0
  123. package/dist/renderers/segments/pipeline-waiting.d.ts +3 -0
  124. package/dist/renderers/segments/pipeline-waiting.d.ts.map +1 -0
  125. package/dist/renderers/segments/progress.d.ts +3 -0
  126. package/dist/renderers/segments/progress.d.ts.map +1 -0
  127. package/dist/renderers/segments/terminal.d.ts +3 -0
  128. package/dist/renderers/segments/terminal.d.ts.map +1 -0
  129. package/dist/renderers/segments/text.d.ts +10 -0
  130. package/dist/renderers/segments/text.d.ts.map +1 -0
  131. package/dist/renderers/segments/thinking.d.ts +3 -0
  132. package/dist/renderers/segments/thinking.d.ts.map +1 -0
  133. package/dist/renderers/segments/tool-call.d.ts +3 -0
  134. package/dist/renderers/segments/tool-call.d.ts.map +1 -0
  135. package/dist/runtime/message-repository.d.ts +3 -3
  136. package/dist/runtime/message-repository.d.ts.map +1 -1
  137. package/dist/transport/backend-handler.d.ts +19 -7
  138. package/dist/transport/backend-handler.d.ts.map +1 -1
  139. package/dist/transport/backend-transport.d.ts +1 -1
  140. package/dist/transport/backend-transport.d.ts.map +1 -1
  141. package/dist/transport/direct-transport.d.ts +4 -4
  142. package/dist/transport/direct-transport.d.ts.map +1 -1
  143. package/dist/transport/index.d.ts +2 -2
  144. package/dist/transport/index.d.ts.map +1 -1
  145. package/dist/transport/types.d.ts +3 -3
  146. package/dist/types/element-map.d.ts +69 -0
  147. package/dist/types/element-map.d.ts.map +1 -0
  148. package/dist/types/event-map.d.ts +84 -23
  149. package/dist/types/event-map.d.ts.map +1 -1
  150. package/dist/types/events.d.ts +212 -64
  151. package/dist/types/events.d.ts.map +1 -1
  152. package/dist/types/index.d.ts +4 -5
  153. package/dist/types/index.d.ts.map +1 -1
  154. package/dist/types/model-provider.d.ts +100 -54
  155. package/dist/types/model-provider.d.ts.map +1 -1
  156. package/dist/types/models.d.ts +29 -7
  157. package/dist/types/models.d.ts.map +1 -1
  158. package/dist/types/segments.d.ts +33 -8
  159. package/dist/types/segments.d.ts.map +1 -1
  160. package/dist/types/theming.d.ts +25 -37
  161. package/dist/types/theming.d.ts.map +1 -1
  162. package/dist/types/tools.d.ts +60 -15
  163. package/dist/types/tools.d.ts.map +1 -1
  164. package/dist/utils/escape.d.ts +46 -0
  165. package/dist/utils/escape.d.ts.map +1 -0
  166. package/dist/utils/files-to-attachments.d.ts +18 -1
  167. package/dist/utils/files-to-attachments.d.ts.map +1 -1
  168. package/dist/utils/segments.d.ts +174 -0
  169. package/dist/utils/segments.d.ts.map +1 -0
  170. package/dist/utils/uuid.d.ts +26 -0
  171. package/dist/utils/uuid.d.ts.map +1 -0
  172. package/package.json +3 -5
  173. package/dist/index-Dn7TH14G.js.map +0 -1
  174. package/dist/types/providers.d.ts +0 -93
  175. package/dist/types/providers.d.ts.map +0 -1
@@ -41,7 +41,7 @@ export interface AparteAttachment {
41
41
  /**
42
42
  * A single branch (alternative response) within an assistant message.
43
43
  *
44
- * @deprecated The active branching system is tree-based via `MessageRepository`
44
+ * @deprecated The active branching system is tree-based via `AparteMessageRepository`
45
45
  * (siblings under the same parent node). This in-message versioning struct is
46
46
  * kept only for backwards compatibility with existing serialised payloads.
47
47
  * New code should rely on viewport methods `addSiblingOf` / `navigateBranch`
@@ -66,7 +66,7 @@ export interface AparteMessageBranch {
66
66
  export type AparteBubbleActionName = 'copy' | 'edit' | 'retry' | 'thumbUp' | 'thumbDown' | 'info';
67
67
  /**
68
68
  * Controls which action buttons are rendered in message bubbles.
69
- * Pass to `AparteConfig.setBubbleActions()` to customise or disable actions.
69
+ * Pass to `aparteGlobalConfig.setBubbleActions()` to customise or disable actions.
70
70
  *
71
71
  * **Only `copy` is on by default.** Core can copy text on its own; every other
72
72
  * button needs someone outside core to honor it — `AparteClient` (retry, edit) or
@@ -74,7 +74,7 @@ export type AparteBubbleActionName = 'copy' | 'edit' | 'retry' | 'thumbUp' | 'th
74
74
  * user, so aparté ships them off and you turn on what you handle:
75
75
  *
76
76
  * ```ts
77
- * AparteConfig.setBubbleActions({ retry: true, edit: true }); // you run AparteClient
77
+ * aparteGlobalConfig.setBubbleActions({ retry: true, edit: true }); // you run AparteClient
78
78
  * ```
79
79
  *
80
80
  * Two ways to configure:
@@ -107,11 +107,11 @@ export interface AparteBubbleActionsConfig {
107
107
  /**
108
108
  * The affordances core RENDERS but cannot COMPLETE — each one only asks, through a
109
109
  * DOM event, and the app does the work. Declare what your app actually handles
110
- * with `AparteConfig.setHostHandlers()`; everything else stays out of the UI
110
+ * with `aparteGlobalConfig.setHostHandlers()`; everything else stays out of the UI
111
111
  * rather than showing a control that answers to nobody.
112
112
  *
113
113
  * ```ts
114
- * AparteConfig.setHostHandlers({ attachmentPreview: true }); // you open a lightbox
114
+ * aparteGlobalConfig.setHostHandlers({ attachmentPreview: true }); // you open a lightbox
115
115
  * ```
116
116
  *
117
117
  * These are declarations, not callbacks: the events (`aparte-attachment-preview`,
@@ -136,6 +136,28 @@ export interface AparteHostHandlersConfig {
136
136
  * their button: core writes those out itself. Default: false
137
137
  */
138
138
  artifactRedownload?: boolean;
139
+ /**
140
+ * Re-running the generation of a **persisted binary artifact** when a saved
141
+ * conversation is re-opened (`aparte-artifact-ready`, dispatched from
142
+ * `setup()` rather than from a stream). Default: false
143
+ *
144
+ * Why this is off unless declared, and why it is separate from
145
+ * `artifactRedownload`: that flag guards a BUTTON, and a button is a request.
146
+ * This guards an automatic dispatch on mount — nobody asked for it, and the
147
+ * payload is model-authored content the receiving app is expected to run in a
148
+ * sandbox. Reloading a conversation would therefore re-execute whatever a
149
+ * prompt injection had persuaded the model to emit, on every reload, forever.
150
+ *
151
+ * Core cannot honour it end to end either: it owns no sandbox and no file
152
+ * generator, so a dispatch with nothing listening leaves the card stuck at
153
+ * "generating" — the same reasoning that made the artifact preview require a
154
+ * click. Declare it when your app really does listen for
155
+ * `aparte-artifact-ready` and can regenerate the file safely.
156
+ *
157
+ * Not affected: the dispatch at the END of a live stream, which follows a turn
158
+ * the user asked for. This flag is only about mount-time rehydration.
159
+ */
160
+ artifactRehydrate?: boolean;
139
161
  }
140
162
  /**
141
163
  * Core message structure for the chat
@@ -169,7 +191,7 @@ export interface AparteMessage {
169
191
  /**
170
192
  * Alternative responses generated by retrying.
171
193
  *
172
- * @deprecated Use the tree-based branching exposed by `MessageRepository`
194
+ * @deprecated Use the tree-based branching exposed by `AparteMessageRepository`
173
195
  * (siblings under the same parent). The bubble no longer reads this field
174
196
  * — sibling counts come from `aparte-path-changed` event metadata.
175
197
  */
@@ -197,7 +219,7 @@ export interface AparteViewportConfig {
197
219
  * @deprecated Renamed to {@link maxRenderedBubbles}. This used to silently
198
220
  * evict messages from the conversation model (data loss); it now only caps
199
221
  * rendered bubbles. For real history retention, configure it on your
200
- * ConversationManager instead.
222
+ * AparteConversationManager instead.
201
223
  */
202
224
  maxMessages?: number;
203
225
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/types/models.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/types/models.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,38 @@ export interface AparteSegmentBase {
10
10
  type: string;
11
11
  /** Whether segment is currently being streamed */
12
12
  isStreaming?: boolean;
13
+ /** Id of the message this segment belongs to. Stamped on insertion. */
14
+ messageId?: string;
15
+ /**
16
+ * Position in the owning message's `segments[]`, maintained across
17
+ * insertions and removals.
18
+ */
19
+ index?: number;
20
+ /** Epoch ms when the segment entered the transcript. */
21
+ startedAt?: number;
22
+ /**
23
+ * Epoch ms when content last arrived on this segment.
24
+ *
25
+ * It ADVANCES while the segment streams and freezes when the segment settles,
26
+ * so `endedAt - startedAt` is a live duration during a turn and a final one
27
+ * after it — ask `isSegmentSettled(segment)` which you are looking at. Core
28
+ * never renders either.
29
+ *
30
+ * Why not simply "when it finished": the two obvious rules are both wrong, and
31
+ * measurably. Closing at the end of the turn makes a reasoning block span the
32
+ * whole answer that followed it (2s of thinking before a 20s reply reads
33
+ * "22s"). Closing when the next segment opens is the same error, smaller — a
34
+ * gap of ten seconds before the next segment is counted as thinking, while the
35
+ * person watching knows nothing happened. The last delta is the only moment
36
+ * the segment itself can vouch for.
37
+ */
38
+ endedAt?: number;
39
+ /**
40
+ * Extras only the producer of the segment can know — token counts, cost,
41
+ * compute device. Core writes nothing here: fill it from an app with
42
+ * `updateSegment(segmentId, { meta })`. Mirrors `AparteMessage.metadata`.
43
+ */
44
+ meta?: Record<string, unknown>;
13
45
  }
14
46
  /** Text segment - plain text content */
15
47
  export interface AparteTextSegment extends AparteSegmentBase {
@@ -204,15 +236,8 @@ export interface AparteSegmentRenderer<T extends AparteSegmentBase = AparteSegme
204
236
  */
205
237
  cleanup?(element: HTMLElement): void;
206
238
  }
207
- /** Event when a segment action is triggered (e.g., "Run", "Copy") */
208
- export interface AparteSegmentActionEvent {
209
- messageId: string;
210
- segmentId: string;
211
- action: string;
212
- payload?: unknown;
213
- }
214
239
  /** Event when segment content is updated during streaming */
215
- export interface AparteSegmentUpdateEvent {
240
+ export interface AparteSegmentUpdateEventDetail {
216
241
  messageId: string;
217
242
  segmentId: string;
218
243
  content: string;
@@ -1 +1 @@
1
- {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/types/segments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/types/segments.ts"],"names":[],"mappings":"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"}
@@ -3,42 +3,30 @@
3
3
  * CSS Custom Properties interfaces for theming
4
4
  */
5
5
  /**
6
- * CSS Custom Properties available for theming
7
- * All properties are optional - defaults are applied in components
6
+ * Any aparté CSS custom property, for typing a theme object or a `style` record:
7
+ *
8
+ * ```ts
9
+ * const brand: AparteThemeVariables = {
10
+ * '--aparte-primary': '#b45309',
11
+ * '--aparte-surface-1': '#ffffff',
12
+ * };
13
+ * ```
14
+ *
15
+ * This was a hand-written list of 33 named properties, and it could not work. Ten
16
+ * of the 33 named variables were neither declared nor read anywhere in aparté —
17
+ * so the type autocompleted ten knobs that did nothing — while the real surface is
18
+ * 254 tokens, meaning even the 23 live members were an arbitrary slice presented as
19
+ * the whole. A hand-maintained mirror of a stylesheet that size is wrong the day
20
+ * after it is written, and nothing could tell you.
21
+ *
22
+ * What this trades away, stated rather than glossed: autocomplete, and catching a
23
+ * typo in the part after `--aparte-`. What it buys is that the type cannot lie. The
24
+ * discoverable list is the generated
25
+ * [CSS variables reference](https://apartejs.dev/reference/css-variables/), which
26
+ * is swept from the source on every build and marks which tokens aparté actually
27
+ * reads.
8
28
  */
9
- export interface AparteThemeVariables {
10
- '--aparte-primary'?: string;
11
- '--aparte-primary-hover'?: string;
12
- '--aparte-secondary'?: string;
13
- '--aparte-neutral'?: string;
14
- '--aparte-message-content-bg-user'?: string;
15
- '--aparte-message-content-bg-assistant'?: string;
16
- '--aparte-message-content-text-user'?: string;
17
- '--aparte-message-content-text-assistant'?: string;
18
- '--aparte-message-content-radius'?: string;
19
- '--aparte-message-content-radius-corner'?: string;
20
- '--aparte-message-content-padding'?: string;
21
- '--aparte-message-content-max-width'?: string;
22
- '--aparte-message-content-font-size'?: string;
23
- '--aparte-input-bg'?: string;
24
- '--aparte-input-border'?: string;
25
- '--aparte-input-text'?: string;
26
- '--aparte-input-placeholder'?: string;
27
- '--aparte-input-focus-border'?: string;
28
- '--aparte-input-focus-ring'?: string;
29
- '--aparte-input-radius'?: string;
30
- '--aparte-input-font-size'?: string;
31
- '--aparte-input-disabled-bg'?: string;
32
- '--aparte-viewport-padding'?: string;
33
- '--aparte-message-gap'?: string;
34
- '--aparte-input-padding'?: string;
35
- '--aparte-font-family'?: string;
36
- '--aparte-timestamp-font-size'?: string;
37
- '--aparte-status-color'?: string;
38
- '--aparte-status-font-size'?: string;
39
- '--aparte-status-dot-size'?: string;
40
- '--aparte-status-padding'?: string;
41
- '--aparte-button-radius'?: string;
42
- '--aparte-button-text'?: string;
43
- }
29
+ export type AparteThemeVariables = {
30
+ [K in `--aparte-${string}`]?: string;
31
+ };
44
32
  //# sourceMappingURL=theming.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theming.d.ts","sourceRoot":"","sources":["../../src/types/theming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IAEjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAG5B,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAC5C,uCAAuC,CAAC,EAAE,MAAM,CAAC;IACjD,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAC9C,yCAAyC,CAAC,EAAE,MAAM,CAAC;IACnD,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,wCAAwC,CAAC,EAAE,MAAM,CAAC;IAClD,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAC5C,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAC9C,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAG9C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,4BAA4B,CAAC,EAAE,MAAM,CAAC;IAGtC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAGlC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IAGxC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAGnC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACnC"}
1
+ {"version":3,"file":"theming.d.ts","sourceRoot":"","sources":["../../src/types/theming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,oBAAoB,GAAG;KAAG,CAAC,IAAI,YAAY,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM;CAAE,CAAC"}
@@ -52,16 +52,6 @@ export interface AparteToolApprovalRequestDetail {
52
52
  toolName: string;
53
53
  input: Record<string, unknown>;
54
54
  }
55
- /**
56
- * Detail for `aparte-tool-action` — a generic callback channel so any rendered
57
- * tool UI (via {@link AparteToolRenderer.setup}) can post an interactive action
58
- * back toward the host/loop (e.g. a custom confirm/choose/retry button).
59
- */
60
- export interface AparteToolActionDetail {
61
- toolCallId: string;
62
- action: string;
63
- payload?: unknown;
64
- }
65
55
  /** A tool call emitted by the AI during streaming */
66
56
  export interface AparteToolCall {
67
57
  id: string;
@@ -78,18 +68,73 @@ export interface AparteToolResult {
78
68
  * Receives the tool call and an AbortSignal (fires after timeout or on cancellation).
79
69
  * Must resolve with a AparteToolResult.
80
70
  */
81
- export type AparteToolHandler = (call: AparteToolCall, signal: AbortSignal) => Promise<AparteToolResult>;
71
+ export type AparteToolHandler = (call: AparteToolCall, signal: AbortSignal, context?: AparteToolContext) => Promise<AparteToolResult>;
72
+ /**
73
+ * Which chat a tool handler is running for.
74
+ *
75
+ * Optional and third, so every existing handler keeps compiling and working —
76
+ * nothing has to be rewritten to ignore it.
77
+ *
78
+ * It exists because a handler had NO way to know. `@aparte/plugin-ask-user`
79
+ * calls `requestUserInput({ message, schema, signal })` with no `target`, and
80
+ * `requestUserInput` resolves its presenter with `resolveConfig(request.target ??
81
+ * null)` — so with an instance config carrying the presenter, the call resolved
82
+ * against the GLOBAL config, found nothing, and returned `{ action: 'cancel' }`.
83
+ * The model was told the user refused a question the user was never shown.
84
+ *
85
+ * That failure is described in `AparteConfig.requestUserInput` as "a lie told
86
+ * quietly", and the plugin walked straight into it because the handler signature
87
+ * gave it nothing to walk around with.
88
+ *
89
+ * Both loops supply it — core's inline loop and the injected `runStreamAgent` — so
90
+ * a handler behaves the same whichever one is running.
91
+ */
92
+ export interface AparteToolContext {
93
+ /**
94
+ * The chat element this turn belongs to. Pass it as `target` to
95
+ * `requestUserInput` (or to anything else that resolves a config from the DOM)
96
+ * and the right instance answers.
97
+ */
98
+ target?: HTMLElement;
99
+ /**
100
+ * The resolved config for this chat, for a handler that needs it without going
101
+ * through the DOM — a handler running in a worker, or one reading a provider.
102
+ */
103
+ config?: unknown;
104
+ }
82
105
  /**
83
106
  * Per-tool segment renderer.
84
- * Registered via AparteConfig.registerToolRenderer(toolName, renderer).
107
+ * Registered via aparteGlobalConfig.registerToolRenderer(toolName, renderer).
85
108
  * When the AI calls a tool, this renderer controls what appears in the bubble
86
109
  * for that specific tool instead of the generic tool_call renderer.
87
110
  *
88
- * Return an empty string from render() to render nothing (e.g. for UI-only tools like ask_question).
111
+ * Return an empty string from render() to render nothing (e.g. for UI-only tools like ask_user).
89
112
  */
90
113
  export interface AparteToolRenderer {
91
- /** HTML to render for the tool call segment. Return empty string to hide. */
92
- render: (segment: AparteToolCallSegment) => string;
114
+ /**
115
+ * Render the tool-call segment, as an HTML string or a ready DOM element.
116
+ *
117
+ * **The segment carries model-chosen data.** `segment.toolCall.input` is
118
+ * whatever the model decided to pass, and `segment.result` is whatever the tool
119
+ * returned — on the SEGMENT, because `AparteToolCall` is `{ id, name, input }`
120
+ * and nothing else. This line used to say `segment.toolCall.result`, which does
121
+ * not compile; the first renderer written against it found out.
122
+ * Both values are untrusted.
123
+ *
124
+ * Return an **HTMLElement** and there is no innerHTML surface at all — set
125
+ * `textContent`, attach listeners, insert framework nodes. That is the safe
126
+ * default and the reason this arm exists.
127
+ *
128
+ * Return a **string** and core inserts it with `innerHTML`, so every
129
+ * interpolated value must go through `escapeHtml` (text position) or
130
+ * `escapeAttr` (inside an attribute). The natural first thing to write here is
131
+ * `\`<div>Searching for ${s.toolCall.input.query}</div>\``, and that is a direct
132
+ * model-to-DOM XSS in the host page's origin.
133
+ *
134
+ * Return an empty string to render nothing (e.g. a UI-only tool like
135
+ * `ask_user`).
136
+ */
137
+ render: (segment: AparteToolCallSegment) => string | HTMLElement;
93
138
  /** Optional DOM setup (event listeners etc.) called after HTML is injected */
94
139
  setup?: (element: HTMLElement, segment: AparteToolCallSegment) => void;
95
140
  /** Optional CSS to inject once into document.head */
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,8GAA8G;IAC9G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,+BAA+B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,oDAAoD;AACpD,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC5B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,KAClB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IAC/B,6EAA6E;IAC7E,MAAM,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,MAAM,CAAC;IACnD,8EAA8E;IAC9E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACvE,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,8GAA8G;IAC9G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,+BAA+B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,oDAAoD;AACpD,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC5B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE,iBAAiB,KAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,MAAM,GAAG,WAAW,CAAC;IACjE,8EAA8E;IAC9E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACvE,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * HTML escaping — one implementation, for every interpolation core makes.
3
+ *
4
+ * There used to be SEVEN copies of this across the package (`_escapeHtml` in the
5
+ * bubble and in the config, `_escapeAttr` in the chat shell, the composer action
6
+ * and the composer input, plus `escapeHtml` and `escapeAttr` in the segment
7
+ * renderers). They had already drifted: the chat shell's copy escaped only `&`,
8
+ * `"` and `<`, leaving `'` and `>` through, so it was strictly weaker than its
9
+ * six siblings while looking identical at the call site. That is the failure mode
10
+ * a duplicated security helper always ends in — one of them stops matching, and
11
+ * nothing tells you which.
12
+ *
13
+ * Escapes all five characters that matter, which makes the result safe in BOTH
14
+ * text position and quoted-attribute position (single or double quotes). Callers
15
+ * that read better saying "attribute" use {@link escapeAttr}, which is this same
16
+ * function under a second name — an alias, deliberately not a second body.
17
+ *
18
+ * PUBLIC. Both names are exported from the barrel and documented in the
19
+ * customization guide, because a render hook that returns a string needs them and
20
+ * telling an author to "escape it yourself" without naming the function is how a
21
+ * capability becomes invisible. An earlier version of this comment claimed the
22
+ * opposite ("not exported from the package barrel… not a public API") while
23
+ * `index.ts` exported both — the export was real, the comment was not.
24
+ */
25
+ export declare function escapeHtml(value: string): string;
26
+ /**
27
+ * The same escaping as {@link escapeHtml}, named for the position it guards.
28
+ *
29
+ * An attribute value needs exactly the same five characters escaped as a text
30
+ * node — quotes to keep the value from ending early, angle brackets so a broken
31
+ * value cannot start a tag, and the ampersand so none of it can be smuggled back
32
+ * in as an entity. Two names, one body.
33
+ *
34
+ * REQUIRES A QUOTED ATTRIBUTE. `title="${escapeAttr(v)}"` and `title='…'` are
35
+ * both safe; bare `title=${escapeAttr(v)}` is NOT, because a space, tab, newline
36
+ * or backtick in the value ends an unquoted attribute and starts the next one —
37
+ * and none of those five escaped characters is one of them. An audit raised this
38
+ * as a latent gap (no unquoted interpolation exists in the library today).
39
+ *
40
+ * The fix is to quote the attribute, not to escape harder: encoding spaces would
41
+ * make every legitimate `title="Hello world"` read `Hello&#32;world`. So
42
+ * `pnpm check:attr-escaping` now rejects an unquoted attribute interpolation
43
+ * outright rather than trusting this function to cover a position it cannot.
44
+ */
45
+ export declare const escapeAttr: typeof escapeHtml;
46
+ //# sourceMappingURL=escape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/utils/escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,UAAU,mBAAa,CAAC"}
@@ -13,7 +13,7 @@ import type { AparteAttachment } from '../types/models.js';
13
13
  * chat.addEventListener('aparte-send', (e) => {
14
14
  * const { content, files } = e.detail;
15
15
  * chat.viewport?.appendMessage({
16
- * id: crypto.randomUUID(), role: 'user', content, timestamp: Date.now(),
16
+ * id: uuid(), role: 'user', content, timestamp: Date.now(),
17
17
  * ...(files?.length ? { attachments: filesToAttachments(files) } : {}),
18
18
  * });
19
19
  * });
@@ -22,6 +22,23 @@ import type { AparteAttachment } from '../types/models.js';
22
22
  * The `url` comes from `URL.createObjectURL`, so it lives as long as the
23
23
  * document; the raw `File` rides along on `blob` for storage adapters that
24
24
  * persist attachments and rebuild the url on reload.
25
+ *
26
+ * That lifetime is deliberate for a rendered attachment — but it is also a leak
27
+ * once the attachment is gone: a long session that sends many files retains every
28
+ * `File` for the life of the page. Call {@link revokeAttachmentUrls} when you know
29
+ * they are no longer rendered; core does it on `clearAll()`.
25
30
  */
26
31
  export declare function filesToAttachments(files: readonly File[]): AparteAttachment[];
32
+ /**
33
+ * Release the object URLs of attachments that are no longer on screen.
34
+ *
35
+ * Nothing revoked them, so every `File` a session sent stayed reachable until the
36
+ * page went away. Only the caller knows when an attachment stops being rendered —
37
+ * a persisted conversation may re-render one much later — so this is a function
38
+ * rather than something `filesToAttachments` could schedule.
39
+ *
40
+ * Safe to call twice: revoking an already-revoked or foreign URL is a no-op, and a
41
+ * `blob` is left in place so a storage adapter can still rebuild the url.
42
+ */
43
+ export declare function revokeAttachmentUrls(attachments: readonly AparteAttachment[] | undefined): void;
27
44
  //# sourceMappingURL=files-to-attachments.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"files-to-attachments.d.ts","sourceRoot":"","sources":["../../src/utils/files-to-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAS3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,gBAAgB,EAAE,CAS7E"}
1
+ {"version":3,"file":"files-to-attachments.d.ts","sourceRoot":"","sources":["../../src/utils/files-to-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAK3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,gBAAgB,EAAE,CAS7E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,SAAS,GAAG,IAAI,CAM/F"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * What a segment knows about itself — stamped in one place.
3
+ *
4
+ * A segment carried `id`, `type` and `isStreaming` and nothing else, while the
5
+ * message one level up already had a `timestamp`, a `usage` and a `metadata` bag.
6
+ * Three places in this repo paid for the gap: `render(segment)` takes one argument
7
+ * so a custom renderer could not learn its message, `aparte-terminal-run` shipped a
8
+ * `segmentId` nobody could resolve, and the artifact renderer fabricated a message
9
+ * id to slip past a consumer dedupe keyed on a pair it did not have.
10
+ *
11
+ * **Why the stamp lives here and not in `AparteStreamParser`.** The parser looked
12
+ * like the right owner — both agent loops share it, so parity would be free. It is
13
+ * the wrong one. `tool_call` segments are built by the client and the stream
14
+ * adapter (three sites), `pipeline-waiting` by two more, and `prefixSegments` by the
15
+ * app itself: stamping in the parser would have left a TOOL CALL — the single most
16
+ * useful duration in the whole transcript — with no measurement at all. Worse, the
17
+ * parser's own `segmentCounter` would have produced a wrong index: it is recreated
18
+ * on every `turn-start`, while a tool round-trip appends to the SAME message across
19
+ * turns, so one message would hold two segments at index 0, silently.
20
+ *
21
+ * A segment can only reach a transcript one way — through `addSegment` — and there
22
+ * are exactly two owners of the array behind it: `aparte-chat-viewport` (native) and
23
+ * `aparte-chat-host` (framework-managed). Both call these functions; nothing else
24
+ * writes those fields. `pnpm check:segment-stamp` keeps it that way, because two
25
+ * owners is exactly the shape of the forgotten-sibling bug this repo keeps finding.
26
+ *
27
+ * Everything here is pure and DOM-free, so a consumer can test their own wiring in
28
+ * Node — the introspectability half of the reachability rule.
29
+ */
30
+ import type { AparteSegment } from '../types/index.js';
31
+ /**
32
+ * Stamp identity and start time on a segment joining `segments` at the tail.
33
+ *
34
+ * Returns a new object; the caller's segment is never mutated — the viewport hands
35
+ * the same segment object to the repository AND to the bubble, so mutating one is
36
+ * action at a distance (a bug this repo has already paid for in `appendToSegment`).
37
+ *
38
+ * A value already present is never overwritten, so a segment rehydrated from a
39
+ * consumer's storage keeps the numbers it was persisted with.
40
+ */
41
+ export declare function stampSegmentOnInsert(segments: readonly AparteSegment[], segment: AparteSegment, messageId: string): AparteSegment;
42
+ /**
43
+ * Has this segment settled? The trigger for `endedAt`.
44
+ *
45
+ * Exported on purpose: a consumer rendering its own "thought for 8 s" line needs
46
+ * the same predicate, and a rule buried inside a component method is a rule that
47
+ * gets re-derived slightly differently somewhere else.
48
+ *
49
+ * A segment with no streaming flag at all is NOT settled. That is deliberate: a
50
+ * reply that arrived whole never had a span to measure, and stamping an `endedAt`
51
+ * equal to its `startedAt` would dress a zero up as a measurement.
52
+ */
53
+ export declare function isSegmentSettled(segment: AparteSegment): boolean;
54
+ /**
55
+ * Move `endedAt` to now while the segment is open; freeze it once it settles.
56
+ *
57
+ * `endedAt` is **the moment content last arrived**, and that is the only honest
58
+ * signal available. Two simpler rules were tried and are wrong, both measurably:
59
+ *
60
+ * - *"ends when the turn ends"* — a reasoning block would then span the whole
61
+ * answer that followed it. 2s of thinking before a 20s reply reads "22s". A
62
+ * mocked stream hides this (it moves from reasoning to text in milliseconds); a
63
+ * real model does not.
64
+ * - *"ends when the next segment starts"* — the same error, smaller: if the next
65
+ * segment opens ten seconds later, those ten seconds are counted as thinking,
66
+ * while the person watching the screen knows perfectly well nothing happened.
67
+ *
68
+ * So every update nudges it forward, and the settling update keeps whatever the
69
+ * last delta left rather than stamping its own arrival time. A segment that settles
70
+ * having never received an update gets its end then — nothing else is knowable
71
+ * about it.
72
+ *
73
+ * The consequence, stated because it is a contract: `endedAt` is present WHILE a
74
+ * segment streams, and `endedAt - startedAt` is a live duration that grows. Ask
75
+ * {@link isSegmentSettled} whether it is final. That is also what a UI wants — the
76
+ * counter that ticks while a model reasons is the same number, read earlier.
77
+ */
78
+ export declare function stampSegmentOnUpdate(segment: AparteSegment, updates: Partial<AparteSegment>): Partial<AparteSegment>;
79
+ /**
80
+ * How long this segment took, or `undefined` when that is not knowable yet.
81
+ *
82
+ * The five identity/measurement fields are optional because they describe a
83
+ * LIFECYCLE: a segment built by hand or freshly emitted by the parser has not been
84
+ * inserted yet, so it has no start, and an open segment has no end. Making them
85
+ * required would either force every creation site to stamp — six of them, which is
86
+ * the forgotten-sibling shape this seam exists to prevent — or force a hand-written
87
+ * literal to invent values the owner then refuses to overwrite.
88
+ *
89
+ * The cost of that optionality lands on the reader, and this is what removes it. The
90
+ * guard it replaces was written three times in this repo before it earned a function:
91
+ *
92
+ * if (!isSegmentSettled(seg) || !seg.startedAt || !seg.endedAt) return;
93
+ *
94
+ * — three conditions to get right, and the last two are wrong at epoch 0, where a
95
+ * valid timestamp is falsy. Nobody streams in 1970, but the test suite sets the clock
96
+ * to 0 routinely, so the trap was already in the repo waiting for its first victim.
97
+ *
98
+ * It deliberately does NOT ask whether the segment is finished: during a turn a
99
+ * growing duration is exactly what a "thinking…" counter shows. Pair it with
100
+ * {@link isSegmentSettled} when you need the final number.
101
+ */
102
+ export declare function segmentDuration(segment: AparteSegment): number | undefined;
103
+ /**
104
+ * The patch that records "content just arrived on this segment".
105
+ *
106
+ * The append paths do not go through {@link stampSegmentOnUpdate} — they rebuild
107
+ * the segment themselves, for reasons that predate this (the viewport must not
108
+ * mutate an object the bubble shares; the host coalesces a frame's chunks into one
109
+ * absolute write). They still have to move `endedAt`, because content arriving IS
110
+ * the activity it measures. So they spread this in, and the rule stays in one file
111
+ * — which is not a style preference: `pnpm check:segment-stamp` refused the two
112
+ * inline `endedAt: Date.now()` this replaced, and it was right to.
113
+ *
114
+ * Empty once the segment has settled, so a late write cannot move a final end.
115
+ */
116
+ export declare function stampSegmentActivity(segment: AparteSegment): {
117
+ endedAt?: number;
118
+ };
119
+ /**
120
+ * The update that forwards a parser-emitted segment's content — carrying the fact
121
+ * that it CLOSED, when it did.
122
+ *
123
+ * The parser marks the segments it closes (`</think>`, a closing fence,
124
+ * `</artifact>`, the opening of the next block). That mark reached nobody: every
125
+ * forwarding site sent `{ content }` alone, so a finished segment arrived at the
126
+ * owner looking exactly like a streaming one. The end then had to be inferred from
127
+ * the end of the TURN, which is what kept a reasoning block reading "Thinking" for
128
+ * as long as the answer took to stream.
129
+ *
130
+ * Five sites forward this way across the two agent loops, which is four too many to
131
+ * patch by hand — that is how the same rule ends up spelled three different ways.
132
+ */
133
+ export declare function segmentContentUpdate(segment: AparteSegment): Partial<AparteSegment>;
134
+ /**
135
+ * Statuses that mean the turn is over, whatever the outcome.
136
+ *
137
+ * `error` and `aborted` count: a stopped stream still produced what it produced,
138
+ * and refusing to close its segments would leave every one of them measuring
139
+ * forever. `undefined` does NOT count — a message with no status yet has not
140
+ * finished, and treating "unknown" as "done" would end a segment on its first
141
+ * render.
142
+ */
143
+ export declare function isTerminalStatus(status: string | null | undefined): boolean;
144
+ /**
145
+ * Ids of the segments a finished turn still has to close.
146
+ *
147
+ * Where `endedAt` comes from for everything that is not a tool call. Nothing in the
148
+ * stream says "this thinking block is over": the parser closes its active segment
149
+ * silently, and both agent loops report the end on the MESSAGE
150
+ * (`updateMessage({ status: 'completed' })`). So the message's end is the segments'
151
+ * end, and this says which ones are still waiting for it.
152
+ *
153
+ * It returns ids rather than settling the array itself, and that is the point. The
154
+ * first version did mutate in place — and the browser proved it half-broken: the
155
+ * model gained its `endedAt` while the RENDERER never learned the segment had
156
+ * settled, because a silent mutation notifies nobody. Routing each close through
157
+ * the owner's own `updateSegment` gives one path that stamps the model AND repaints
158
+ * the bubble, which is also the path `update()` and the incremental Markdown flush
159
+ * already depend on.
160
+ *
161
+ * Already-closed segments are skipped, so reporting a turn finished twice — a
162
+ * re-render, a branch switch, a reloaded conversation — cannot move an end.
163
+ */
164
+ export declare function openSegmentIds(segments: readonly AparteSegment[]): string[];
165
+ /**
166
+ * Close the gap a removal left, in place.
167
+ *
168
+ * The single place `index` is maintained after the array changes shape. Entries are
169
+ * REPLACED rather than mutated, for the same shared-object reason as
170
+ * {@link stampSegmentOnInsert}; a segment already at its correct position is left
171
+ * alone, so a renumber after an append-only sequence allocates nothing.
172
+ */
173
+ export declare function renumberSegments(segments: AparteSegment[]): void;
174
+ //# sourceMappingURL=segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/utils/segments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA6BvD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,GAClB,aAAa,CAOf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAGhE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CAaxB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAEjF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAMnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE3E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,EAAE,CAE3E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAMhE"}