@aparte/core 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/client/aparte-client.d.ts.map +1 -1
  2. package/dist/client/stream-adapter.d.ts.map +1 -1
  3. package/dist/client/xml-artifact-feed.d.ts.map +1 -1
  4. package/dist/components/bubble/aparte-chat-bubble.d.ts +24 -3
  5. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
  6. package/dist/components/bubble/bubble-sync.d.ts.map +1 -1
  7. package/dist/components/composer/aparte-composer-action.d.ts.map +1 -1
  8. package/dist/components/composer/aparte-composer-add-attachment.d.ts +11 -0
  9. package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -1
  10. package/dist/components/composer/aparte-composer-cancel.d.ts +8 -0
  11. package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -1
  12. package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
  13. package/dist/components/composer/aparte-composer-send.d.ts +32 -0
  14. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  15. package/dist/components/elicitation/aparte-elicitation.d.ts +10 -0
  16. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  17. package/dist/components/viewport/aparte-chat-viewport.d.ts +13 -1
  18. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  19. package/dist/config/aparte-config.d.ts +34 -1
  20. package/dist/config/aparte-config.d.ts.map +1 -1
  21. package/dist/config/config-subscribe.d.ts +4 -0
  22. package/dist/config/config-subscribe.d.ts.map +1 -0
  23. package/dist/config/index.d.ts +1 -0
  24. package/dist/config/index.d.ts.map +1 -1
  25. package/dist/config/locale.d.ts +98 -0
  26. package/dist/config/locale.d.ts.map +1 -1
  27. package/dist/config/sanitize.d.ts.map +1 -1
  28. package/dist/custom-elements.json +7590 -6959
  29. package/dist/elicitation/panel.d.ts +13 -0
  30. package/dist/elicitation/panel.d.ts.map +1 -1
  31. package/dist/host/aparte-chat-host.d.ts +3 -1
  32. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  33. package/dist/{index-BieFbKeW.js → index-BnKBciDG.js} +642 -248
  34. package/dist/index-BnKBciDG.js.map +1 -0
  35. package/dist/index.css +147 -310
  36. package/dist/index.d.ts +3 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +281 -92
  39. package/dist/index.js.map +1 -1
  40. package/dist/index.node.d.ts +3 -1
  41. package/dist/index.node.d.ts.map +1 -1
  42. package/dist/index.node.js +60 -55
  43. package/dist/index.node.js.map +1 -1
  44. package/dist/parsers/aparte-stream-parser.d.ts +25 -0
  45. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  46. package/dist/renderers/highlight-stream.d.ts +17 -0
  47. package/dist/renderers/highlight-stream.d.ts.map +1 -0
  48. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  49. package/dist/renderers/segments/artifact/binary-file.d.ts.map +1 -1
  50. package/dist/renderers/segments/artifact/card.d.ts.map +1 -1
  51. package/dist/renderers/segments/artifact/shared.d.ts +19 -2
  52. package/dist/renderers/segments/artifact/shared.d.ts.map +1 -1
  53. package/dist/renderers/segments/code.d.ts.map +1 -1
  54. package/dist/renderers/segments/error.d.ts.map +1 -1
  55. package/dist/renderers/segments/pipeline-waiting.d.ts.map +1 -1
  56. package/dist/renderers/segments/thinking.d.ts.map +1 -1
  57. package/dist/renderers/segments/tool-call.d.ts.map +1 -1
  58. package/dist/types/event-map.d.ts +1 -2
  59. package/dist/types/event-map.d.ts.map +1 -1
  60. package/dist/types/events.d.ts +0 -16
  61. package/dist/types/events.d.ts.map +1 -1
  62. package/dist/types/index.d.ts +2 -2
  63. package/dist/types/index.d.ts.map +1 -1
  64. package/dist/types/models.d.ts +1 -6
  65. package/dist/types/models.d.ts.map +1 -1
  66. package/dist/types/segments.d.ts +103 -51
  67. package/dist/types/segments.d.ts.map +1 -1
  68. package/dist/utils/segments.d.ts +244 -0
  69. package/dist/utils/segments.d.ts.map +1 -0
  70. package/package.json +1 -1
  71. package/dist/index-BieFbKeW.js.map +0 -1
  72. package/dist/renderers/segments/file-tree.d.ts +0 -3
  73. package/dist/renderers/segments/file-tree.d.ts.map +0 -1
  74. package/dist/renderers/segments/terminal.d.ts +0 -3
  75. package/dist/renderers/segments/terminal.d.ts.map +0 -1
@@ -10,16 +10,95 @@ 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
+ /**
21
+ * Extras the producer of the segment knows — token counts, cost, compute
22
+ * device — plus `aparte`, the one sub-object core writes.
23
+ *
24
+ * Everything except `meta.aparte` is yours: fill it with
25
+ * `updateSegment(segmentId, { meta })`, which MERGES rather than replaces.
26
+ * Mirrors `AparteMessage.metadata`.
27
+ */
28
+ meta?: Record<string, unknown> & {
29
+ aparte?: AparteSegmentTiming;
30
+ };
31
+ }
32
+ /**
33
+ * What core measured about a segment. Lives in `meta.aparte`, not on the segment.
34
+ *
35
+ * These two were first-class fields, and moving them is not tidying. **No protocol
36
+ * carries a timestamp on a content block** — verified rather than assumed: Anthropic's
37
+ * blocks have none (and neither does the message), OpenAI's `output_text` part is
38
+ * `{annotations, logprobs, text, type}` with `created_at` on the item above it, and the
39
+ * AI SDK's `UIMessage.parts` have none either. What the AI SDK does have is a metadata
40
+ * bag whose canonical example is literally `{ createdAt, model, totalTokens }` — at the
41
+ * message level. A per-block `id` has industry precedent; per-block time has none.
42
+ *
43
+ * So this is a **local measurement**, and the shape says so. It stays typed — the bag is
44
+ * where it belongs, opacity is not part of the deal — and it is namespaced under
45
+ * `aparte` because `meta` is the consumer's: a flat `startedAt` there would collide
46
+ * with a key of their own.
47
+ *
48
+ * Core reads it through {@link segmentDuration} and {@link isSegmentSettled}; it never
49
+ * renders either number.
50
+ */
51
+ export interface AparteSegmentTiming {
52
+ /** Epoch ms when the segment entered a LIVE transcript. Absent for history. */
53
+ startedAt?: number;
54
+ /**
55
+ * Epoch ms when content last arrived on this segment.
56
+ *
57
+ * It ADVANCES while the segment streams and freezes when the segment settles, so
58
+ * `endedAt - startedAt` is a live duration during a turn and a final one after it
59
+ * — ask `isSegmentSettled(segment)` which you are looking at.
60
+ *
61
+ * Why not simply "when it finished": the two obvious rules are both wrong, and
62
+ * measurably. Closing at the end of the turn makes a reasoning block span the
63
+ * whole answer that followed it (2s of thinking before a 20s reply reads "22s").
64
+ * Closing when the next segment opens is the same error, smaller — a gap of ten
65
+ * seconds before the next segment is counted as thinking, while the person
66
+ * watching knows nothing happened. The last delta is the only moment the segment
67
+ * itself can vouch for.
68
+ */
69
+ endedAt?: number;
13
70
  }
14
71
  /** Text segment - plain text content */
15
72
  export interface AparteTextSegment extends AparteSegmentBase {
16
73
  type: 'text';
17
74
  content: string;
18
75
  }
76
+ /**
77
+ * Field defaults for one segment TYPE, merged when a segment enters a message.
78
+ *
79
+ * A record and not a `Partial<AparteSegment>` on purpose: the type key is a string,
80
+ * a consumer's own segment type is as valid as a built-in one, and its fields cannot
81
+ * be known here. What CANNOT be defaulted is identity — `id`, `type`, `messageId`,
82
+ * `index`, `startedAt`, `endedAt` are refused, because a default `id` would give
83
+ * every segment in a conversation the same one.
84
+ */
85
+ export type AparteSegmentDefaults = Readonly<Record<string, unknown>>;
19
86
  /** Thinking/reasoning segment - collapsible */
20
87
  export interface AparteThinkingSegment extends AparteSegmentBase {
21
88
  type: 'thinking';
22
89
  content: string;
90
+ /**
91
+ * Open the block. **Absent means CLOSED** — a reasoning block is a disclosure,
92
+ * and the reader opens it.
93
+ *
94
+ * It used to be the other way round: absent meant open, and core's own parser
95
+ * emitted `collapsed: false` on every block it produced, so a reasoning block
96
+ * stayed unfolded for the whole conversation and buried the answer under it. No
97
+ * assistant on the market does that — the content is behind a click, streaming
98
+ * or settled.
99
+ *
100
+ * `false` is still how you open one on purpose. Only ABSENT changed meaning.
101
+ */
23
102
  collapsed?: boolean;
24
103
  label?: string;
25
104
  }
@@ -31,56 +110,6 @@ export interface AparteCodeSegment extends AparteSegmentBase {
31
110
  filename?: string;
32
111
  showLineNumbers?: boolean;
33
112
  }
34
- /** Diff segment - before/after code comparison */
35
- export interface AparteDiffSegment extends AparteSegmentBase {
36
- type: 'diff';
37
- filename?: string;
38
- hunks: AparteDiffHunk[];
39
- }
40
- export interface AparteDiffHunk {
41
- oldStart: number;
42
- newStart: number;
43
- lines: AparteDiffLine[];
44
- }
45
- export interface AparteDiffLine {
46
- type: 'add' | 'remove' | 'context';
47
- content: string;
48
- }
49
- /** Terminal/console segment - command execution */
50
- export interface AparteTerminalSegment extends AparteSegmentBase {
51
- type: 'terminal';
52
- command?: string;
53
- output?: string;
54
- exitCode?: number;
55
- isRunning?: boolean;
56
- }
57
- /** File tree segment - directory structure */
58
- export interface AparteFileTreeSegment extends AparteSegmentBase {
59
- type: 'file-tree';
60
- files: AparteFileNode[];
61
- title?: string;
62
- }
63
- export interface AparteFileNode {
64
- name: string;
65
- path: string;
66
- type: 'file' | 'directory';
67
- children?: AparteFileNode[];
68
- status?: 'added' | 'modified' | 'deleted';
69
- }
70
- /** Image segment */
71
- export interface AparteImageSegment extends AparteSegmentBase {
72
- type: 'image';
73
- url: string;
74
- alt?: string;
75
- caption?: string;
76
- }
77
- /** Preview/iframe segment */
78
- export interface ApartePreviewSegment extends AparteSegmentBase {
79
- type: 'preview';
80
- url: string;
81
- title?: string;
82
- height?: number;
83
- }
84
113
  /** Error segment */
85
114
  export interface AparteErrorSegment extends AparteSegmentBase {
86
115
  type: 'error';
@@ -155,7 +184,7 @@ export interface ApartePipelineWaitingSegment extends AparteSegmentBase {
155
184
  type: 'pipeline-waiting';
156
185
  }
157
186
  /** All built-in segment types */
158
- export type AparteSegment = AparteTextSegment | AparteThinkingSegment | AparteCodeSegment | AparteDiffSegment | AparteTerminalSegment | AparteFileTreeSegment | AparteImageSegment | ApartePreviewSegment | AparteErrorSegment | AparteProgressSegment | AparteCustomSegment | AparteToolCallSegment | AparteArtifactSegment | ApartePipelineWaitingSegment;
187
+ export type AparteSegment = AparteTextSegment | AparteThinkingSegment | AparteCodeSegment | AparteErrorSegment | AparteProgressSegment | AparteCustomSegment | AparteToolCallSegment | AparteArtifactSegment | ApartePipelineWaitingSegment;
159
188
  /** Segment type discriminator values */
160
189
  export type AparteSegmentType = AparteSegment['type'];
161
190
  /**
@@ -198,6 +227,29 @@ export interface AparteSegmentRenderer<T extends AparteSegmentBase = AparteSegme
198
227
  * so the MutationObserver (childList) doesn't fire and scroll stays stable.
199
228
  */
200
229
  update?(element: HTMLElement, segment: T): void;
230
+ /**
231
+ * Optional: re-read the CONFIG-DERIVED text of an already-rendered segment —
232
+ * an icon from the icon provider, a label from the locale.
233
+ *
234
+ * Called when the config changes (a language switch, a new icon set), on every
235
+ * segment already on screen. Bound by the same rule as `update()`: **must not
236
+ * add or remove child nodes** — only attributes and textContent — so the
237
+ * viewport's childList observer stays quiet and scroll does not move.
238
+ *
239
+ * This exists because the obvious alternative does not work. Re-rendering the
240
+ * segments container to pick up a new locale destroys state the DOM owns and the
241
+ * segment data does not: a mounted sandboxed artifact preview, a reasoning block
242
+ * the reader expanded by clicking `<summary>` (which never writes back to
243
+ * `collapsed`), scroll position inside a long terminal, the focus on an
244
+ * Approve/Reject gate, and the buffered lookahead of the incremental Markdown
245
+ * parser mid-stream. It also fires container-wide childList mutations, which is
246
+ * exactly what the rule above forbids.
247
+ *
248
+ * Implement it only if the rendered output contains text or icons that came from
249
+ * the config. A renderer whose chrome is entirely its own data — `progress`,
250
+ * `text` — correctly does not, exactly as it does not implement `update()`.
251
+ */
252
+ relabel?(element: HTMLElement, segment: T): void;
201
253
  /**
202
254
  * Optional: Cleanup when segment is removed
203
255
  * @param element - The DOM element being removed
@@ -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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"}
@@ -0,0 +1,244 @@
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 { AparteSegmentDefaults, AparteSegmentTiming, 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, defaults?: AparteSegmentDefaults): AparteSegment;
42
+ /**
43
+ * A segment arriving from STORAGE or a server, rather than starting now.
44
+ *
45
+ * The counterpart of {@link stampSegmentOnInsert}, and the reason it exists: the two
46
+ * are not the same act, and treating them as one made the library invent history.
47
+ * `stampSegmentOnInsert` ran on every arrival path including a reload, so a
48
+ * conversation from three weeks ago came back claiming each of its segments had
49
+ * started this second — while THREE other load paths did not stamp at all, so the same
50
+ * stored conversation produced different numbers depending on the mode and on whether
51
+ * a branch tree had been saved. Not a lie so much as an incoherence.
52
+ *
53
+ * What it writes, and why each:
54
+ *
55
+ * - `messageId` and `index` are **recomputed**, not preserved. They are derivable
56
+ * facts about the array this segment is joining, so a stored value can only
57
+ * contradict it — and no protocol persists either (Anthropic's block `index` exists
58
+ * only in the streaming envelope, as a position).
59
+ * - **no time, ever.** A measurement nobody took is absent, not zero and not now.
60
+ * `segmentDuration` already answers `undefined` for that, so a consumer reading
61
+ * through the helper degrades correctly.
62
+ * - `isStreaming: false`, unconditionally. A persisted stream is dead: restoring one
63
+ * with `isStreaming: true` would render a caret forever, and — through
64
+ * `openSegmentIds`, which reads exactly this flag — would have the next turn-close
65
+ * stamp it a brand-new `endedAt`.
66
+ */
67
+ export declare function adoptSegment(segments: readonly AparteSegment[], segment: AparteSegment, messageId: string): AparteSegment;
68
+ /**
69
+ * Read core's own measurements off a segment.
70
+ *
71
+ * A function rather than a property access because it is read from six places, and
72
+ * `segment.meta?.aparte` spelled six times is six chances to spell it differently —
73
+ * which is exactly how this repo's recurring bug starts.
74
+ */
75
+ export declare function segmentTiming(segment: Pick<AparteSegment, 'meta'>): AparteSegmentTiming | undefined;
76
+ /**
77
+ * Has this segment settled? The trigger for `endedAt`.
78
+ *
79
+ * Exported on purpose: a consumer rendering its own "thought for 8 s" line needs
80
+ * the same predicate, and a rule buried inside a component method is a rule that
81
+ * gets re-derived slightly differently somewhere else.
82
+ *
83
+ * A segment with no streaming flag at all is NOT settled. That is deliberate: a
84
+ * reply that arrived whole never had a span to measure, and stamping an `endedAt`
85
+ * equal to its `startedAt` would dress a zero up as a measurement.
86
+ */
87
+ export declare function isSegmentSettled(segment: AparteSegment): boolean;
88
+ /**
89
+ * Move `endedAt` to now while the segment is open; freeze it once it settles.
90
+ *
91
+ * `endedAt` is **the moment content last arrived**, and that is the only honest
92
+ * signal available. Two simpler rules were tried and are wrong, both measurably:
93
+ *
94
+ * - *"ends when the turn ends"* — a reasoning block would then span the whole
95
+ * answer that followed it. 2s of thinking before a 20s reply reads "22s". A
96
+ * mocked stream hides this (it moves from reasoning to text in milliseconds); a
97
+ * real model does not.
98
+ * - *"ends when the next segment starts"* — the same error, smaller: if the next
99
+ * segment opens ten seconds later, those ten seconds are counted as thinking,
100
+ * while the person watching the screen knows perfectly well nothing happened.
101
+ *
102
+ * So every update nudges it forward, and the settling update keeps whatever the
103
+ * last delta left rather than stamping its own arrival time. A segment that settles
104
+ * having never received an update gets its end then — nothing else is knowable
105
+ * about it.
106
+ *
107
+ * The consequence, stated because it is a contract: `endedAt` is present WHILE a
108
+ * segment streams, and `endedAt - startedAt` is a live duration that grows. Ask
109
+ * {@link isSegmentSettled} whether it is final. That is also what a UI wants — the
110
+ * counter that ticks while a model reasons is the same number, read earlier.
111
+ */
112
+ export declare function stampSegmentOnUpdate(segment: AparteSegment, updates: Partial<AparteSegment>): Partial<AparteSegment>;
113
+ /**
114
+ * Merge an update into a segment without one writer erasing the other's `meta`.
115
+ *
116
+ * `{ ...segment, ...updates }` is wrong now that `meta` has two writers. A consumer's
117
+ * `updateSegment(id, { meta: { cost } })` is presentation, not activity, so it passes
118
+ * through {@link stampSegmentOnUpdate} untouched — and a plain spread would then
119
+ * replace the whole bag and take `meta.aparte` with it. The measurement would vanish
120
+ * the first time an app wrote a token count, which is precisely when it matters.
121
+ *
122
+ * So the bag is merged one level, and `aparte` inside it merged again. Every site that
123
+ * folds an update into a segment goes through here — the viewport, the host and the
124
+ * bubble each had their own spread, which is three chances to fix this twice and miss
125
+ * once.
126
+ */
127
+ export declare function mergeSegmentUpdate(segment: AparteSegment, updates: Partial<AparteSegment>): AparteSegment;
128
+ /**
129
+ * How long this segment took, or `undefined` when that is not knowable yet.
130
+ *
131
+ * The five identity/measurement fields are optional because they describe a
132
+ * LIFECYCLE: a segment built by hand or freshly emitted by the parser has not been
133
+ * inserted yet, so it has no start, and an open segment has no end. Making them
134
+ * required would either force every creation site to stamp — six of them, which is
135
+ * the forgotten-sibling shape this seam exists to prevent — or force a hand-written
136
+ * literal to invent values the owner then refuses to overwrite.
137
+ *
138
+ * The cost of that optionality lands on the reader, and this is what removes it. The
139
+ * guard it replaces was written three times in this repo before it earned a function:
140
+ *
141
+ * if (!isSegmentSettled(seg) || !seg.startedAt || !seg.endedAt) return;
142
+ *
143
+ * — three conditions to get right, and the last two are wrong at epoch 0, where a
144
+ * valid timestamp is falsy. Nobody streams in 1970, but the test suite sets the clock
145
+ * to 0 routinely, so the trap was already in the repo waiting for its first victim.
146
+ *
147
+ * It deliberately does NOT ask whether the segment is finished: during a turn a
148
+ * growing duration is exactly what a "thinking…" counter shows. Pair it with
149
+ * {@link isSegmentSettled} when you need the final number.
150
+ */
151
+ export declare function segmentDuration(segment: AparteSegment): number | undefined;
152
+ /**
153
+ * The patch that records "content just arrived on this segment".
154
+ *
155
+ * The append paths do not go through {@link stampSegmentOnUpdate} — they rebuild
156
+ * the segment themselves, for reasons that predate this (the viewport must not
157
+ * mutate an object the bubble shares; the host coalesces a frame's chunks into one
158
+ * absolute write). They still have to move `endedAt`, because content arriving IS
159
+ * the activity it measures. So they spread this in, and the rule stays in one file
160
+ * — which is not a style preference: `pnpm check:segment-stamp` refused the two
161
+ * inline `endedAt: Date.now()` this replaced, and it was right to.
162
+ *
163
+ * Empty once the segment has settled, so a late write cannot move a final end.
164
+ */
165
+ export declare function stampSegmentActivity(segment: AparteSegment): Partial<AparteSegment>;
166
+ /**
167
+ * The update that forwards a parser-emitted segment's content — carrying the fact
168
+ * that it CLOSED, when it did.
169
+ *
170
+ * The parser marks the segments it closes (`</think>`, a closing fence,
171
+ * `</artifact>`, the opening of the next block). That mark reached nobody: every
172
+ * forwarding site sent `{ content }` alone, so a finished segment arrived at the
173
+ * owner looking exactly like a streaming one. The end then had to be inferred from
174
+ * the end of the TURN, which is what kept a reasoning block reading "Thinking" for
175
+ * as long as the answer took to stream.
176
+ *
177
+ * Five sites forward this way across the two agent loops, which is four too many to
178
+ * patch by hand — that is how the same rule ends up spelled three different ways.
179
+ */
180
+ export declare function segmentContentUpdate(segment: AparteSegment): Partial<AparteSegment>;
181
+ /**
182
+ * Statuses that mean the turn is over, whatever the outcome.
183
+ *
184
+ * `error` and `aborted` count: a stopped stream still produced what it produced,
185
+ * and refusing to close its segments would leave every one of them measuring
186
+ * forever. `undefined` does NOT count — a message with no status yet has not
187
+ * finished, and treating "unknown" as "done" would end a segment on its first
188
+ * render.
189
+ */
190
+ export declare function isTerminalStatus(status: string | null | undefined): boolean;
191
+ /**
192
+ * Ids of the segments a finished turn still has to close.
193
+ *
194
+ * Where `endedAt` comes from for everything that is not a tool call. Nothing in the
195
+ * stream says "this thinking block is over": the parser closes its active segment
196
+ * silently, and both agent loops report the end on the MESSAGE
197
+ * (`updateMessage({ status: 'completed' })`). So the message's end is the segments'
198
+ * end, and this says which ones are still waiting for it.
199
+ *
200
+ * It returns ids rather than settling the array itself, and that is the point. The
201
+ * first version did mutate in place — and the browser proved it half-broken: the
202
+ * model gained its `endedAt` while the RENDERER never learned the segment had
203
+ * settled, because a silent mutation notifies nobody. Routing each close through
204
+ * the owner's own `updateSegment` gives one path that stamps the model AND repaints
205
+ * the bubble, which is also the path `update()` and the incremental Markdown flush
206
+ * already depend on.
207
+ *
208
+ * Already-closed segments are skipped, so reporting a turn finished twice — a
209
+ * re-render, a branch switch, a reloaded conversation — cannot move an end.
210
+ */
211
+ export declare function openSegmentIds(segments: readonly AparteSegment[]): string[];
212
+ /**
213
+ * Adopt every segment of a message arriving from storage or a server.
214
+ *
215
+ * The message-level counterpart of {@link adoptSegment}, and the reason it exists as a
216
+ * function rather than a loop written four times: there are FOUR entry paths for
217
+ * historical data (`setMessages`, `importTree`, `addMessage`, and the framework host's
218
+ * own list setter) and they disagreed. One stamped and invented a start, one wrote
219
+ * straight to the repository, one did nothing, and the host's `appendMessage` — same
220
+ * name as the viewport's, opposite behaviour — did nothing either. The same stored
221
+ * conversation therefore produced different numbers depending on the mode and on
222
+ * whether a branch tree had been saved.
223
+ *
224
+ * Always returns a NEW object, even for a message with no segments. That looks like a
225
+ * missed optimisation and is the invariant of this whole file: the viewport hands the
226
+ * same object to the repository AND to the framework's list, so sharing one makes the
227
+ * immediate paint and the coalesced write land on the same string twice. Returning the
228
+ * caller's message here doubled every streamed reply — caught by the suite that exists
229
+ * for exactly that bug, within minutes of my writing the shortcut.
230
+ */
231
+ export declare function adoptMessageSegments<T extends {
232
+ id: string;
233
+ segments?: AparteSegment[];
234
+ }>(message: T): T;
235
+ /**
236
+ * Close the gap a removal left, in place.
237
+ *
238
+ * The single place `index` is maintained after the array changes shape. Entries are
239
+ * REPLACED rather than mutated, for the same shared-object reason as
240
+ * {@link stampSegmentOnInsert}; a segment already at its correct position is left
241
+ * alone, so a renumber after an append-only sequence allocates nothing.
242
+ */
243
+ export declare function renumberSegments(segments: AparteSegment[]): void;
244
+ //# 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,qBAAqB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA6BnG;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,qBAAqB,GACjC,aAAa,CAWf;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CACxB,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,GAClB,aAAa,CAOf;AASD;;;;;;GAMG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GACrC,mBAAmB,GAAG,SAAS,CAEjC;AA6CD;;;;;;;;;;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,CAgBxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAChC,aAAa,CAef;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAEnF;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;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;CAAE,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CASxG;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAMhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aparte/core",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "High-performance AI conversation engine - Zero-dependency Web Components",
5
5
  "type": "module",
6
6
  "//sideEffects": "The BROWSER entry defines the custom elements and imports CSS at module scope, so it must never be tree-shaken; the Node entry (`index.node`) and every other module are pure. Listing them explicitly is what lets a bundler drop the rest — the whole package was implicitly side-effectful before, the only one of the 14 without this field.",