@aparte/core 0.15.1 → 0.16.1

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 (143) hide show
  1. package/dist/client/aparte-client.d.ts +53 -51
  2. package/dist/client/aparte-client.d.ts.map +1 -1
  3. package/dist/client/lifecycle-events.d.ts +0 -12
  4. package/dist/client/lifecycle-events.d.ts.map +1 -1
  5. package/dist/client/stream-adapter.d.ts +2 -12
  6. package/dist/client/stream-adapter.d.ts.map +1 -1
  7. package/dist/components/bubble/aparte-chat-bubble.d.ts +45 -1
  8. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
  9. package/dist/components/chat/aparte-chat.d.ts +1 -1
  10. package/dist/components/composer/aparte-composer-action.d.ts +1 -1
  11. package/dist/components/composer/aparte-composer-add-attachment.d.ts +1 -1
  12. package/dist/components/composer/aparte-composer-attachments.d.ts +1 -2
  13. package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
  14. package/dist/components/composer/aparte-composer-cancel.d.ts +1 -1
  15. package/dist/components/composer/aparte-composer-input.d.ts +1 -1
  16. package/dist/components/composer/aparte-composer-send.d.ts +12 -12
  17. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  18. package/dist/components/composer/aparte-composer.d.ts +29 -12
  19. package/dist/components/composer/aparte-composer.d.ts.map +1 -1
  20. package/dist/components/context/aparte-context.d.ts +31 -8
  21. package/dist/components/context/aparte-context.d.ts.map +1 -1
  22. package/dist/components/conversation-list/aparte-conversation-list.d.ts +93 -36
  23. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
  24. package/dist/components/conversation-list/index.d.ts +1 -1
  25. package/dist/components/conversation-list/index.d.ts.map +1 -1
  26. package/dist/components/elicitation/aparte-elicitation.d.ts +20 -2
  27. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  28. package/dist/components/index.d.ts +7 -1
  29. package/dist/components/index.d.ts.map +1 -1
  30. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts +105 -0
  31. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts.map +1 -0
  32. package/dist/components/scroll-rail/index.d.ts +3 -0
  33. package/dist/components/scroll-rail/index.d.ts.map +1 -0
  34. package/dist/components/sidebar/aparte-sidebar.d.ts +186 -0
  35. package/dist/components/sidebar/aparte-sidebar.d.ts.map +1 -0
  36. package/dist/components/sidebar/index.d.ts +3 -0
  37. package/dist/components/sidebar/index.d.ts.map +1 -0
  38. package/dist/components/split/aparte-split.d.ts +354 -0
  39. package/dist/components/split/aparte-split.d.ts.map +1 -0
  40. package/dist/components/split/geometry.d.ts +65 -0
  41. package/dist/components/split/geometry.d.ts.map +1 -0
  42. package/dist/components/split/index.d.ts +3 -0
  43. package/dist/components/split/index.d.ts.map +1 -0
  44. package/dist/components/suggestions/aparte-suggestions.d.ts +7 -1
  45. package/dist/components/suggestions/aparte-suggestions.d.ts.map +1 -1
  46. package/dist/components/viewport/aparte-chat-viewport.d.ts +52 -2
  47. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  48. package/dist/config/aparte-config.d.ts +95 -33
  49. package/dist/config/aparte-config.d.ts.map +1 -1
  50. package/dist/config/icon-provider.d.ts +6 -0
  51. package/dist/config/icon-provider.d.ts.map +1 -1
  52. package/dist/config/index.d.ts +2 -2
  53. package/dist/config/index.d.ts.map +1 -1
  54. package/dist/config/locale.d.ts +140 -27
  55. package/dist/config/locale.d.ts.map +1 -1
  56. package/dist/config/sanitize.d.ts +9 -0
  57. package/dist/config/sanitize.d.ts.map +1 -1
  58. package/dist/conversations/conversation-controller.d.ts +13 -1
  59. package/dist/conversations/conversation-controller.d.ts.map +1 -1
  60. package/dist/conversations/conversation-manager.d.ts +9 -0
  61. package/dist/conversations/conversation-manager.d.ts.map +1 -1
  62. package/dist/custom-elements.json +10278 -7784
  63. package/dist/{is-awaiting-reply-BZ_iJ3s3.js → dialog-triggers-CVCxqKg3.js} +718 -1182
  64. package/dist/dialog-triggers-CVCxqKg3.js.map +1 -0
  65. package/dist/elicitation/approval-panel.d.ts +1 -1
  66. package/dist/elicitation/approval-panel.d.ts.map +1 -1
  67. package/dist/elicitation/panel.d.ts +24 -16
  68. package/dist/elicitation/panel.d.ts.map +1 -1
  69. package/dist/elicitation/types.d.ts +31 -0
  70. package/dist/elicitation/types.d.ts.map +1 -1
  71. package/dist/generated/element-attributes.d.ts +47 -1
  72. package/dist/generated/element-attributes.d.ts.map +1 -1
  73. package/dist/{glyphs-B3BZ2TIb.js → glyphs-DQTeOj4w.js} +22 -13
  74. package/dist/{glyphs-B3BZ2TIb.js.map → glyphs-DQTeOj4w.js.map} +1 -1
  75. package/dist/host/aparte-chat-host.d.ts +10 -2
  76. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  77. package/dist/icons/extended.d.ts +4 -2
  78. package/dist/icons/extended.d.ts.map +1 -1
  79. package/dist/icons/glyphs.d.ts +9 -0
  80. package/dist/icons/glyphs.d.ts.map +1 -1
  81. package/dist/icons.js +16 -15
  82. package/dist/icons.js.map +1 -1
  83. package/dist/index.css +1284 -397
  84. package/dist/index.d.ts +26 -15
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +2099 -296
  87. package/dist/index.js.map +1 -1
  88. package/dist/index.node.d.ts +21 -5
  89. package/dist/index.node.d.ts.map +1 -1
  90. package/dist/index.node.js +39 -34
  91. package/dist/index.node.js.map +1 -1
  92. package/dist/interop/dialog-triggers.d.ts +27 -0
  93. package/dist/interop/dialog-triggers.d.ts.map +1 -0
  94. package/dist/interop/element-props.d.ts +16 -8
  95. package/dist/interop/element-props.d.ts.map +1 -1
  96. package/dist/parsers/aparte-stream-parser.d.ts +52 -22
  97. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  98. package/dist/parsers/index.d.ts +1 -1
  99. package/dist/parsers/index.d.ts.map +1 -1
  100. package/dist/primitives/select/aparte-select.d.ts.map +1 -1
  101. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  102. package/dist/renderers/segments/code.d.ts.map +1 -1
  103. package/dist/renderers/segments/tool-call.d.ts.map +1 -1
  104. package/dist/runtime/message-repository.d.ts.map +1 -1
  105. package/dist/transport/backend-handler.d.ts.map +1 -1
  106. package/dist/transport/backend-transport.d.ts +6 -1
  107. package/dist/transport/backend-transport.d.ts.map +1 -1
  108. package/dist/types/chat.d.ts +8 -14
  109. package/dist/types/chat.d.ts.map +1 -1
  110. package/dist/types/element-map.d.ts +54 -4
  111. package/dist/types/element-map.d.ts.map +1 -1
  112. package/dist/types/event-map.d.ts +16 -10
  113. package/dist/types/event-map.d.ts.map +1 -1
  114. package/dist/types/events.d.ts +59 -117
  115. package/dist/types/events.d.ts.map +1 -1
  116. package/dist/types/imperative-api.d.ts +3 -1
  117. package/dist/types/imperative-api.d.ts.map +1 -1
  118. package/dist/types/index.d.ts +5 -4
  119. package/dist/types/index.d.ts.map +1 -1
  120. package/dist/types/models.d.ts +11 -31
  121. package/dist/types/models.d.ts.map +1 -1
  122. package/dist/types/segments.d.ts +11 -47
  123. package/dist/types/segments.d.ts.map +1 -1
  124. package/dist/types/stream-blocks.d.ts +57 -0
  125. package/dist/types/stream-blocks.d.ts.map +1 -0
  126. package/dist/types/tools.d.ts +57 -0
  127. package/dist/types/tools.d.ts.map +1 -1
  128. package/dist/utils/copy-text.d.ts +24 -0
  129. package/dist/utils/copy-text.d.ts.map +1 -0
  130. package/dist/utils/css-escape.d.ts +5 -0
  131. package/dist/utils/css-escape.d.ts.map +1 -1
  132. package/dist/utils/tool-input.d.ts +20 -0
  133. package/dist/utils/tool-input.d.ts.map +1 -0
  134. package/package.json +10 -3
  135. package/dist/is-awaiting-reply-BZ_iJ3s3.js.map +0 -1
  136. package/dist/renderers/segments/artifact/binary-file.d.ts +0 -45
  137. package/dist/renderers/segments/artifact/binary-file.d.ts.map +0 -1
  138. package/dist/renderers/segments/artifact/card.d.ts +0 -3
  139. package/dist/renderers/segments/artifact/card.d.ts.map +0 -1
  140. package/dist/renderers/segments/artifact/preview-document.d.ts +0 -27
  141. package/dist/renderers/segments/artifact/preview-document.d.ts.map +0 -1
  142. package/dist/renderers/segments/artifact/shared.d.ts +0 -29
  143. package/dist/renderers/segments/artifact/shared.d.ts.map +0 -1
@@ -25,12 +25,16 @@ export interface AparteContextThresholdEventDetail {
25
25
  * Two thresholds turn it `warn` then `danger` (`data-level`), and crossing one fires
26
26
  * `aparte-context-threshold`. With `auto-compact`, reaching `danger` dispatches
27
27
  * `aparte-compact` for its chat — once, until the level drops again — which is what
28
- * a gauge that turns red and then does nothing was missing. `AparteClient.compact()`
29
- * summarises the whole history by default; give the client `@aparte/engine`'s
30
- * `createCompactionSelector` and only what no longer fits the window is summarised.
28
+ * a gauge that turns red and then does nothing was missing. What answers the command
29
+ * is `@aparte/plugin-compaction` (`setupCompaction()`): it summarises what no longer
30
+ * fits the window and keeps the recent turns. Core itself does not compact — the
31
+ * gauge asks, the plugin does, and a page without the plugin gets a gauge that only
32
+ * measures.
31
33
  *
32
- * The bar wears the `aparte-progress` recipe; this element declares no custom
33
- * property of its own.
34
+ * The bar wears the `aparte-progress` recipe. `variant="ring"` draws the same reading
35
+ * as a ring with the percentage beside it — for a toolbar, where a bar wants a width
36
+ * and a ring wants none; the full reading is the ring's `title`. The two share the
37
+ * levels, the events and the accessible name; only the drawing differs.
34
38
  *
35
39
  * @element aparte-context
36
40
  *
@@ -39,15 +43,31 @@ export interface AparteContextThresholdEventDetail {
39
43
  * @attr {number} danger - Fraction at which it turns `danger`. Default `0.9`.
40
44
  * @attr {boolean} auto-compact - Dispatch `aparte-compact` on reaching `danger` (once per crossing).
41
45
  * @attr {string} target - The id of the `<aparte-chat>` to watch, when the element is not under it.
46
+ * @attr {string} variant - `bar` (default) or `ring`: a progress bar with the reading beside it, or a ring with the percentage.
42
47
  * @attr {string} data-level - Reflected BY the element: `ok`, `warn` or `danger`. Read-only.
43
48
  * @attr {boolean} data-empty - Reflected BY the element while it has nothing to show. Read-only.
44
49
  *
45
50
  * @fires {CustomEvent<AparteContextThresholdEventDetail>} aparte-context-threshold - The level changed. Bubbles.
51
+ * @fires {CustomEvent<AparteCompactEventDetail>} aparte-compact - Dispatched on `window` when `auto-compact` is set and the gauge first reaches `danger`: compact this target's transcript. Once per crossing, and only while the attribute is present. `@aparte/plugin-compaction` answers it; with no listener nothing happens.
52
+ *
53
+ * @cssprop [--aparte-context-ring-size=22px] - Diameter of the ring variant.
54
+ * @cssprop [--aparte-context-ring-stroke=4] - Thickness of the ring, in its own units (the ring is drawn on a 36-unit box).
46
55
  *
47
56
  * @example
57
+ * <!-- The same gauge twice: the bar takes the room it is given, the ring takes none. -->
48
58
  * <aparte-composer-toolbar>
49
- * <aparte-context auto-compact style="flex: 1"></aparte-context>
59
+ * <aparte-context window="128000" auto-compact style="flex: 1"></aparte-context>
60
+ * <aparte-context window="128000" variant="ring"></aparte-context>
50
61
  * </aparte-composer-toolbar>
62
+ *
63
+ * <script>
64
+ * // The gauge reads what each turn reports; it draws nothing before the first one.
65
+ * // This is a provider's usage after a long conversation: 78% of a 128k window,
66
+ * // past the `warn` threshold.
67
+ * window.dispatchEvent(new CustomEvent('aparte-message-done', {
68
+ * detail: { usage: { inputTokens: 99400, outputTokens: 600 } },
69
+ * }));
70
+ * </script>
51
71
  */
52
72
  export declare class AparteContext extends HTMLElement {
53
73
  static get observedAttributes(): string[];
@@ -58,10 +78,13 @@ export declare class AparteContext extends HTMLElement {
58
78
  /**
59
79
  * After a real compaction the context is smaller by an amount nobody has measured
60
80
  * yet — the next turn's usage will say. Until then the gauge shows nothing rather
61
- * than a number it knows to be wrong. (`aparte-compact-done` names no chat: on a
62
- * multi-chat page every gauge resets, and each is right again one turn later.)
81
+ * than a number it knows to be wrong. The event names the chat it compacted, so on a
82
+ * multi-chat page only that chat's gauge resets; an unnamed one resets every gauge,
83
+ * and each is right again one turn later.
63
84
  */
64
85
  private _onCompacted;
86
+ /** A failed compaction spends the request too; the next `danger` asks again. */
87
+ private _onCompactError;
65
88
  private _onRerender;
66
89
  /** Tokens the last turn reported, or `null` before the first turn. */
67
90
  get used(): number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-context.d.ts","sourceRoot":"","sources":["../../../src/components/context/aparte-context.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1D,+FAA+F;AAC/F,MAAM,WAAW,iCAAiC;IAC9C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC1C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,OAAO,CAMb;IAEF;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAMlB;IAEF,OAAO,CAAC,WAAW,CAA8B;IAEjD,sEAAsE;IACtE,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,qEAAqE;IACrE,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,2DAA2D;IAC3D,IAAI,KAAK,IAAI,kBAAkB,GAAG,IAAI,CAErC;IAED,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAM5B,wBAAwB,IAAI,IAAI;IAIhC,OAAO,CAAC,OAAO;IAOf,gGAAgG;IAChG,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;CAmDlB"}
1
+ {"version":3,"file":"aparte-context.d.ts","sourceRoot":"","sources":["../../../src/components/context/aparte-context.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1D,+FAA+F;AAC/F,MAAM,WAAW,iCAAiC;IAC9C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAoCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC1C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,OAAO,CAMb;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,YAAY,CAWlB;IAEF,gFAAgF;IAChF,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,WAAW,CAA8B;IAEjD,sEAAsE;IACtE,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,qEAAqE;IACrE,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,2DAA2D;IAC3D,IAAI,KAAK,IAAI,kBAAkB,GAAG,IAAI,CAErC;IAED,iBAAiB,IAAI,IAAI;IAUzB,oBAAoB,IAAI,IAAI;IAO5B,wBAAwB,IAAI,IAAI;IAIhC,OAAO,CAAC,OAAO;IAOf,gGAAgG;IAChG,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;CA2FlB"}
@@ -1,9 +1,12 @@
1
1
  export interface AparteConversationListItem {
2
2
  id: string;
3
3
  title: string;
4
+ /** Drives the date groups. A list where no item carries one renders flat. */
4
5
  updatedAt?: number;
5
- /** When set, the item renders the unarchive action instead of archive. */
6
+ /** When set, the row is italic and its menu offers unarchive instead of archive. */
6
7
  archivedAt?: number;
8
+ /** When set, the row sits in the "Pinned" group first, and its menu offers unpin. */
9
+ pinnedAt?: number;
7
10
  }
8
11
  export interface AparteConversationSelectDetail {
9
12
  id: string;
@@ -14,10 +17,27 @@ export interface AparteConversationDeleteDetail {
14
17
  export interface AparteConversationArchiveDetail {
15
18
  id: string;
16
19
  }
20
+ export interface AparteConversationPinDetail {
21
+ id: string;
22
+ }
23
+ export interface AparteConversationRenameDetail {
24
+ id: string;
25
+ /** The new title, trimmed and non-empty — an unchanged or emptied title fires nothing. */
26
+ title: string;
27
+ }
17
28
  /**
18
29
  * Conversation-history sidebar — a framework-agnostic web component. The host sets
19
30
  * the `conversations` JS property and the `active-id` attribute; this renders the
20
- * list and fires the user's intent, never acting on it itself.
31
+ * rows and fires the user's intent, never acting on it itself.
32
+ *
33
+ * A row is two real buttons: the title, which selects, and a `⋯` that opens the row's
34
+ * menu — rename, pin or unpin, archive or unarchive, delete. Every item fires an event
35
+ * and stops; the one exception is delete, which asks first, inline in the menu,
36
+ * because it is the one action the host cannot undo. Rename swaps the title for an
37
+ * input: Enter or leaving the field commits, Escape cancels, and an unchanged or
38
+ * emptied title fires nothing. The rows are grouped by date — Pinned, Today,
39
+ * Yesterday, Previous 7 days, Previous 30 days, then one heading per month — as soon
40
+ * as any item carries `updatedAt`; set `no-groups` to render them flat.
21
41
  *
22
42
  * Children are not a composition point: `_render()` assigns `innerHTML` from the
23
43
  * `conversations` array, so any light-DOM child a host writes inside the element is
@@ -25,29 +45,33 @@ export interface AparteConversationArchiveDetail {
25
45
  * enough to trigger one. Compose around the element, not inside it: it renders rows
26
46
  * and nothing else, with no header, no new-conversation button and no search field.
27
47
  *
28
- * What it is not: a store. Clicking a row selects nothing, and the two row actions
29
- * delete and archive nothing — the four events carry an id and stop. A row's text
30
- * comes from the array, so it changes when the host assigns `conversations` again;
31
- * the exception is an empty title, which falls back to the locale's new-chat label
32
- * and therefore follows a locale switch. An archived item is still rendered (it gains
33
- * `aparte-conv-item--archived` and swaps its action's icon and event name); filtering
34
- * archived conversations out of the list is the host's decision, not this element's.
35
- * The asymmetry between the two inputs is deliberate: `active-id` is an attribute
36
- * because moving the selection patches the rendered rows in place, while
37
- * `conversations` is a JS property because it is structured data an attribute cannot
38
- * carry, and setting it re-renders the whole list.
48
+ * What it is not: a store. Selecting, renaming, pinning, archiving and deleting all
49
+ * leave the array untouched — the events carry an id (and, for rename, the title) and
50
+ * stop. A row's text comes from the array, so it changes when the host assigns
51
+ * `conversations` again; the exception is an empty title, which falls back to the
52
+ * locale's new-chat label and therefore follows a locale switch. An archived item is
53
+ * still rendered (it gains `aparte-conv-item--archived`); filtering archived
54
+ * conversations out of the list is the host's decision, not this element's. The
55
+ * asymmetry between the two inputs is deliberate: `active-id` is an attribute because
56
+ * moving the selection patches the rendered rows in place, while `conversations` is a
57
+ * JS property because it is structured data an attribute cannot carry, and setting it
58
+ * re-renders the whole list.
39
59
  *
40
60
  * @element aparte-conversation-list
41
61
  * @attr {string} active-id - The id of the conversation to render as selected.
62
+ * @attr {boolean} no-groups - Render the rows flat, in host order, with no date headings.
42
63
  *
43
- * @fires {CustomEvent<AparteConversationSelectDetail>} aparte-select-conversation - A row was activated; the host loads that conversation.
44
- * @fires {CustomEvent<AparteConversationDeleteDetail>} aparte-delete-conversation - The delete action was pressed. Nothing is removed here.
45
- * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-archive-conversation - The archive action was pressed on a live conversation.
46
- * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-unarchive-conversation - The same action on an already-archived one; same detail shape, opposite intent.
64
+ * @fires {CustomEvent<AparteConversationSelectDetail>} aparte-select-conversation - A row's title was activated; the host loads that conversation.
65
+ * @fires {CustomEvent<AparteConversationRenameDetail>} aparte-rename-conversation - A rename was committed with a new, non-empty title. Nothing is renamed here.
66
+ * @fires {CustomEvent<AparteConversationPinDetail>} aparte-pin-conversation - The pin item was chosen on an unpinned row.
67
+ * @fires {CustomEvent<AparteConversationPinDetail>} aparte-unpin-conversation - The same item on a pinned row; same detail shape, opposite intent.
68
+ * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-archive-conversation - The archive item was chosen on a live conversation.
69
+ * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-unarchive-conversation - The same item on an already-archived one; same detail shape, opposite intent.
70
+ * @fires {CustomEvent<AparteConversationDeleteDetail>} aparte-delete-conversation - The delete was confirmed. Nothing is removed here.
47
71
  *
48
- * @cssprop [--aparte-conv-list-gap=2px] - Vertical gap between rows. The element itself is the flex column, so this is its `gap`.
49
- * @cssprop [--aparte-conv-item-padding=7px 10px] - Padding of a row.
50
- * @cssprop [--aparte-conv-item-gap=6px] - Gap between a row's title and its two action buttons.
72
+ * @cssprop [--aparte-conv-list-gap=2px] - Vertical gap between rows, and between a group's heading and its rows.
73
+ * @cssprop [--aparte-conv-item-padding=7px 10px] - Padding of a row's title button.
74
+ * @cssprop [--aparte-conv-item-gap=6px] - Gap between a row's title and its `⋯` button.
51
75
  * @cssprop [--aparte-conv-item-radius=var(--aparte-radius-md)] - Corner radius of a row.
52
76
  * @cssprop [--aparte-conv-item-font-size=0.8125rem] - Font size of a row's title.
53
77
  * @cssprop [--aparte-conv-item-color=var(--aparte-text-muted)] - Title colour of an inactive row.
@@ -55,15 +79,7 @@ export interface AparteConversationArchiveDetail {
55
79
  * @cssprop [--aparte-conv-item-bg-active=var(--aparte-surface-3)] - Background of the row matching `active-id`.
56
80
  * @cssprop [--aparte-conv-item-color-active=var(--aparte-text)] - Title colour of the active row.
57
81
  * @cssprop [--aparte-conv-item-font-weight-active=var(--aparte-font-weight-medium, 500)] - Title weight of the active row.
58
- * @cssprop [--aparte-conv-action-btn-size=20px] - Square size of both action buttons. Under `(pointer: coarse)` the stylesheet redeclares it as 28px on the buttons themselves, so a value set on the element does not reach them there; the buttons also stay visible instead of appearing on hover.
59
- * @cssprop [--aparte-conv-delete-color=var(--aparte-text-muted)] - Icon colour of the delete button.
60
- * @cssprop [--aparte-conv-delete-bg-hover=var(--aparte-error)] - Delete button background on hover.
61
- * @cssprop [--aparte-conv-delete-color-hover=var(--aparte-text-inverse)] - Delete button icon colour on hover.
62
- * @cssprop [--aparte-conv-delete-radius=var(--aparte-radius-sm)] - Corner radius of the delete button.
63
- * @cssprop [--aparte-conv-archive-color=var(--aparte-text-muted)] - Icon colour of the archive/unarchive button.
64
- * @cssprop [--aparte-conv-archive-bg-hover=var(--aparte-surface-4, var(--aparte-surface-3))] - Archive button background on hover. Core declares no `--aparte-surface-4`, so unset it resolves to `--aparte-surface-3`.
65
- * @cssprop [--aparte-conv-archive-color-hover=var(--aparte-text)] - Archive button icon colour on hover.
66
- * @cssprop [--aparte-conv-archive-radius=var(--aparte-radius-sm)] - Corner radius of the archive button.
82
+ * @cssprop [--aparte-conv-action-btn-size=20px] - Square size of the `⋯` button. Under `(pointer: coarse)` the stylesheet redeclares it as 28px on the button itself, so a value set on the element does not reach it there; the button also stays visible instead of appearing on hover.
67
83
  *
68
84
  * @example
69
85
  * <!-- It stores nothing and fetches nothing: an empty tag renders the empty state, and
@@ -71,9 +87,12 @@ export interface AparteConversationArchiveDetail {
71
87
  * <aparte-conversation-list active-id="c1" style="max-width: 20rem"></aparte-conversation-list>
72
88
  *
73
89
  * <script>
90
+ * const day = 864e5;
74
91
  * document.querySelector('aparte-conversation-list').conversations = [
92
+ * { id: 'c0', title: 'Release checklist', updatedAt: Date.now() - 3 * day, pinnedAt: Date.now() },
75
93
  * { id: 'c1', title: 'Deploy checklist', updatedAt: Date.now() },
76
- * { id: 'c2', title: 'Rename the segment types', updatedAt: Date.now() - 864e5 },
94
+ * { id: 'c2', title: 'Rename the segment types', updatedAt: Date.now() - day },
95
+ * { id: 'c3', title: 'Tokens, not selectors', updatedAt: Date.now() - 4 * day },
77
96
  * ];
78
97
  * </script>
79
98
  *
@@ -87,31 +106,69 @@ export interface AparteConversationArchiveDetail {
87
106
  * list.setAttribute('active-id', 'c1');
88
107
  *
89
108
  * list.addEventListener('aparte-select-conversation', (e) => load(e.detail.id));
90
- * list.addEventListener('aparte-delete-conversation', (e) => remove(e.detail.id));
109
+ * list.addEventListener('aparte-rename-conversation', (e) => manager.updateTitle(e.detail.id, e.detail.title));
110
+ * list.addEventListener('aparte-pin-conversation', (e) => manager.pin(e.detail.id));
111
+ * list.addEventListener('aparte-delete-conversation', (e) => manager.delete(e.detail.id));
91
112
  */
92
113
  export declare class AparteConversationList extends HTMLElement {
93
114
  private _conversations;
94
115
  private _activeId;
116
+ private _open;
117
+ private _renaming;
95
118
  static get observedAttributes(): string[];
96
119
  connectedCallback(): void;
97
120
  disconnectedCallback(): void;
98
121
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
99
122
  /**
100
- * Re-render on a locale switch: every row's title fallback and both button
101
- * labels come from the locale, so without this the list stayed in the previous
102
- * language until something else happened to re-render it. Only OUR config.
123
+ * Re-render on a locale switch: every row's title fallback, the `⋯` button's name
124
+ * and the group headings come from the locale, so without this the list stayed in
125
+ * the previous language until something else happened to re-render it. Only OUR
126
+ * config.
103
127
  */
104
128
  private _onConfigChange;
105
129
  /** Set the list of conversations to display. Triggers a re-render. */
106
130
  set conversations(items: AparteConversationListItem[]);
107
131
  get conversations(): AparteConversationListItem[];
108
132
  private _render;
133
+ private _t;
134
+ /**
135
+ * Pinned first, then the calendar buckets every chat product uses, then a heading
136
+ * per month (newest first), then whatever carries no date. Flat when nothing is
137
+ * dated or the host asked for `no-groups`: a heading over the only group would say
138
+ * nothing.
139
+ */
140
+ private _groups;
141
+ private _renderGroup;
109
142
  private _renderItem;
110
- private _bindEvents;
143
+ private _menuMarkup;
144
+ private _confirmMarkup;
145
+ private _openMenu;
146
+ /**
147
+ * Fixed, below the button's end edge, flipped above it when the viewport ends
148
+ * first. Fixed rather than absolute because a sidebar scrolls: an absolute menu on
149
+ * the last rows would be clipped by the list's own overflow. No anchoring library —
150
+ * the menu closes on any scroll or resize, which is what makes the arithmetic
151
+ * safe to do once.
152
+ */
153
+ private _placeMenu;
154
+ private _closeMenu;
155
+ private _onDocumentPointerDown;
156
+ private _onWindowScroll;
157
+ private _onFocusOut;
158
+ private _onMenuAction;
159
+ private _menuFocusables;
160
+ private _onMenuKeydown;
161
+ private _startRename;
162
+ /**
163
+ * One exit for the three ways out (Enter, Escape, leaving the field), guarded so
164
+ * the blur a removal causes cannot commit a second time. The row is re-rendered
165
+ * from the array either way: the list shows data, and the host's re-assignment is
166
+ * what makes the new title appear.
167
+ */
168
+ private _finishRename;
111
169
  private _onClick;
112
170
  private _onKeydown;
113
171
  /** Update active class without full re-render (perf optimisation). */
114
172
  private _updateActiveState;
115
- private _esc;
116
173
  }
117
174
  //# sourceMappingURL=aparte-conversation-list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-conversation-list.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/aparte-conversation-list.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,0BAA0B;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,+BAA+B;IAC5C,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,qBAAa,sBAAuB,SAAQ,WAAW;IACnD,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,SAAS,CAAuB;IAExC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAID,iBAAiB,IAAI,IAAI;IAWzB,oBAAoB,IAAI,IAAI;IAI5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAQ9F;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAIrB;IAIF,sEAAsE;IACtE,IAAI,aAAa,CAAC,KAAK,EAAE,0BAA0B,EAAE,EAGpD;IAED,IAAI,aAAa,IAAI,0BAA0B,EAAE,CAEhD;IAID,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,WAAW;IA8CnB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,QAAQ,CAkCd;IAEF,OAAO,CAAC,UAAU,CAoBhB;IAEF,sEAAsE;IACtE,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,IAAI;CAQf"}
1
+ {"version":3,"file":"aparte-conversation-list.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/aparte-conversation-list.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,0BAA0B;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,+BAA+B;IAC5C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,2BAA2B;IACxC,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;CACjB;AA6BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,qBAAa,sBAAuB,SAAQ,WAAW;IACnD,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,SAAS,CAAuE;IAExF,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAID,iBAAiB,IAAI,IAAI;IAczB,oBAAoB,IAAI,IAAI;IAQ5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAU9F;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAIrB;IAIF,sEAAsE;IACtE,IAAI,aAAa,CAAC,KAAK,EAAE,0BAA0B,EAAE,EAGpD;IAED,IAAI,aAAa,IAAI,0BAA0B,EAAE,CAEhD;IAID,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,EAAE;IAKV;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IA6Cf,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,WAAW;IAoCnB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,SAAS;IAoBjB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,sBAAsB,CAO5B;IAEF,OAAO,CAAC,eAAe,CAErB;IAEF,OAAO,CAAC,WAAW,CAQjB;IAEF,OAAO,CAAC,aAAa;IA8DrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,YAAY;IAgBpB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,QAAQ,CA2Bd;IAEF,OAAO,CAAC,UAAU,CAYhB;IAEF,sEAAsE;IACtE,OAAO,CAAC,kBAAkB;CAQ7B"}
@@ -1,2 +1,2 @@
1
- export { AparteConversationList, type AparteConversationListItem, type AparteConversationSelectDetail, type AparteConversationDeleteDetail, type AparteConversationArchiveDetail, } from './aparte-conversation-list.js';
1
+ export { AparteConversationList, type AparteConversationListItem, type AparteConversationSelectDetail, type AparteConversationDeleteDetail, type AparteConversationArchiveDetail, type AparteConversationPinDetail, type AparteConversationRenameDetail, } from './aparte-conversation-list.js';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,GACvC,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,GACtC,MAAM,+BAA+B,CAAC"}
@@ -79,20 +79,38 @@ import type { AparteConfig } from '../../config/aparte-config.js';
79
79
  * @cssprop [--aparte-approval-option-size=0.85rem] - Font size of an approval option button.
80
80
  * @cssprop [--aparte-approval-option-padding=8px 10px] - Padding of an approval option button.
81
81
  * @cssprop [--aparte-approval-option-radius=8px] - Corner radius of an approval option button.
82
+ * @cssprop [--aparte-approval-args-max-height=8.5rem] - Height cap of the arguments block before it scrolls.
83
+ * @cssprop [--aparte-approval-args-size=var(--aparte-font-size-sm)] - Font size of the arguments block.
82
84
  *
83
85
  * @example
84
86
  * <!-- Renders nothing by itself: it registers as the presenter for its subtree, so a
85
87
  * tool handler calling requestUserInput() gets its panel mounted in the composer. -->
86
- * <aparte-chat>
88
+ * <aparte-chat style="height: 20rem">
87
89
  * <aparte-chat-viewport></aparte-chat-viewport>
88
90
  * <aparte-elicitation></aparte-elicitation>
89
91
  * <aparte-composer>
90
92
  * <div class="aparte-composer-row">
91
- * <aparte-composer-input style="flex: 1"></aparte-composer-input>
93
+ * <aparte-composer-input></aparte-composer-input>
92
94
  * <aparte-composer-send></aparte-composer-send>
93
95
  * </div>
94
96
  * </aparte-composer>
95
97
  * </aparte-chat>
98
+ *
99
+ * <script>
100
+ * // `aparte` is the `@aparte/core` module the frame exposes; in your app this line is
101
+ * // `import { requestUserInput } from '@aparte/core'`. A tool handler asks; the panel
102
+ * // mounts in the composer of the chat whose presenter this element is.
103
+ * aparte.requestUserInput({
104
+ * message: 'Which environment should I deploy to?',
105
+ * schema: {
106
+ * type: 'enum',
107
+ * options: [
108
+ * { value: 'staging', label: 'Staging', recommended: true },
109
+ * { value: 'prod', label: 'Production', description: 'Live traffic' },
110
+ * ],
111
+ * },
112
+ * });
113
+ * </script>
96
114
  */
97
115
  export declare class AparteElicitation extends HTMLElement implements AparteConfigAware {
98
116
  private _pending;
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-elicitation.d.ts","sourceRoot":"","sources":["../../../src/components/elicitation/aparte-elicitation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgC,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBAAa,iBAAkB,SAAQ,WAAY,YAAW,iBAAiB;IAC3E,OAAO,CAAC,QAAQ,CAAwB;IACxC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,kBAAkB,CAA6B;IAEvD,iBAAiB,IAAI,IAAI;IAiBzB;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAQrE,oBAAoB,IAAI,IAAI;IAY5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,QAAQ,CA0Md;IAEF,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;CAwBvB"}
1
+ {"version":3,"file":"aparte-elicitation.d.ts","sourceRoot":"","sources":["../../../src/components/elicitation/aparte-elicitation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgC,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,qBAAa,iBAAkB,SAAQ,WAAY,YAAW,iBAAiB;IAC3E,OAAO,CAAC,QAAQ,CAAwB;IACxC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,kBAAkB,CAA6B;IAEvD,iBAAiB,IAAI,IAAI;IAiBzB;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAQrE,oBAAoB,IAAI,IAAI;IAY5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,QAAQ,CAoMd;IAEF,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;CAwBvB"}
@@ -6,9 +6,15 @@ export { AparteChatViewport } from './viewport/index.js';
6
6
  export { AparteComposer, AparteComposerInput, AparteComposerSend, AparteComposerCancel, AparteComposerAttachments, AparteComposerAddAttachment, AparteComposerAction, AparteComposerToolbar } from './composer/index.js';
7
7
  export type { AparteComposerEventMap, AparteComposerEventType, AparteComposerState, AparteComposerChangeEventDetail, AparteComposerPanelMode, AparteActionClickEventDetail } from './composer/index.js';
8
8
  export { AparteConversationList } from './conversation-list/index.js';
9
- export type { AparteConversationListItem, AparteConversationSelectDetail, AparteConversationDeleteDetail, AparteConversationArchiveDetail } from './conversation-list/index.js';
9
+ export type { AparteConversationListItem, AparteConversationSelectDetail, AparteConversationDeleteDetail, AparteConversationArchiveDetail, AparteConversationPinDetail, AparteConversationRenameDetail } from './conversation-list/index.js';
10
10
  export { AparteSuggestions } from './suggestions/index.js';
11
11
  export type { AparteSuggestion, AparteSuggestionEventDetail } from './suggestions/index.js';
12
12
  export { AparteContext } from './context/index.js';
13
13
  export type { AparteContextLevel, AparteContextThresholdEventDetail } from './context/index.js';
14
+ export { AparteScrollRail } from './scroll-rail/index.js';
15
+ export type { AparteScrollRailJumpDetail, AparteScrollRailEvery } from './scroll-rail/index.js';
16
+ export { AparteSidebar } from './sidebar/index.js';
17
+ export type { AparteSidebarToggleDetail } from './sidebar/index.js';
18
+ export { AparteSplit } from './split/index.js';
19
+ export type { AparteSplitResizeDetail } from './split/index.js';
14
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACzN,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAGxM,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAGhL,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACzN,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAGxM,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAG7O,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AAGhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAGhG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,105 @@
1
+ /** Detail of `aparte-scroll-rail-jump`: the message a tick points at. */
2
+ export interface AparteScrollRailJumpDetail {
3
+ messageId: string;
4
+ }
5
+ /** What a tick is drawn for: one per user turn (the default), or one per message. */
6
+ export type AparteScrollRailEvery = 'user' | 'message';
7
+ /**
8
+ * A rail of ticks beside the transcript — one per turn — that shows where you are in a
9
+ * long conversation and jumps back to any message on a click.
10
+ *
11
+ * The thing every long chat is missing and no product ships natively: the scrollbar says
12
+ * how far down you are, not which question you are under. This is the minimap of a code
13
+ * editor reduced to its ticks, the search marks of a browser's scrollbar, the scrollspy
14
+ * of a documentation site — the same ancestry, applied to turns. A tick per USER message
15
+ * by default, because a user's turns are the questions and a rail with a tick per reply
16
+ * is unreadable on a long thread; `every="message"` marks each one.
17
+ *
18
+ * It owns nothing of the transcript: the viewport keeps its scroll, the bubbles keep
19
+ * their markup, and the rail only READS them — which bubbles exist (a mutation observer
20
+ * on the chat), which one is under the reader (an intersection observer on the scroll
21
+ * surface, never scroll arithmetic), and the first few words of each for the tick's
22
+ * name. A click is a `scrollIntoView` on the bubble, announced first by a cancelable
23
+ * `aparte-scroll-rail-jump` so a host that pages history in can load it before the
24
+ * jump. Honoured by core alone, so it is live by default (ratified decision #8, tier a).
25
+ *
26
+ * Place it as a direct child of `<aparte-chat>` (or the wrapper's `[data-aparte-chat]`
27
+ * host): the stylesheet floats it on the transcript's end edge, vertically centred, and
28
+ * hides it under a coarse pointer, where a 2px tick is not a target. Under two ticks it
29
+ * renders nothing — a rail with one mark says nothing.
30
+ *
31
+ * @element aparte-scroll-rail
32
+ *
33
+ * @attr {string} target - The id of the `<aparte-chat>` to follow, when the element is not inside it.
34
+ * @attr {string} every - `user` (default): one tick per user turn. `message`: one per message.
35
+ * @attr {boolean} data-empty - Reflected BY the element while it has fewer than two ticks. Read-only.
36
+ *
37
+ * @fires {CustomEvent<AparteScrollRailJumpDetail>} aparte-scroll-rail-jump - A tick was activated. Bubbles, cancelable: `preventDefault()` leaves the transcript where it is.
38
+ *
39
+ * @cssprop [--aparte-scroll-rail-width=20px] - The rail's column, the ticks right-aligned in it.
40
+ * @cssprop [--aparte-scroll-rail-tick-size=14px] - Length of a tick; the current one is 1.6× that.
41
+ * @cssprop [--aparte-scroll-rail-tick-thickness=2px] - Thickness of a tick.
42
+ * @cssprop [--aparte-scroll-rail-gap=8px] - Space between ticks.
43
+ *
44
+ * @example
45
+ * <aparte-chat style="height: 18rem">
46
+ * <aparte-chat-viewport>
47
+ * <aparte-chat-bubble message-id="u1" data-role="user" content="What is a web component?"></aparte-chat-bubble>
48
+ * <aparte-chat-bubble message-id="a1" data-role="assistant" name="Assistant" content="A custom element: a tag the browser upgrades to a class you wrote. It carries its own markup, behaviour and, if you want, its own styles — and it works in any framework, or none, because it is the platform's own component model."></aparte-chat-bubble>
49
+ * <aparte-chat-bubble message-id="u2" data-role="user" content="And a light-DOM one?"></aparte-chat-bubble>
50
+ * <aparte-chat-bubble message-id="a2" data-role="assistant" name="Assistant" content="One that renders its children into the page rather than into a shadow root, so the page's CSS reaches inside it. aparté is light DOM on purpose: a theme is a stylesheet, not an API."></aparte-chat-bubble>
51
+ * <aparte-chat-bubble message-id="u3" data-role="user" content="Which one is this rail?"></aparte-chat-bubble>
52
+ * <aparte-chat-bubble message-id="a3" data-role="assistant" name="Assistant" content="Light DOM, like everything else here. Its ticks are plain buttons in a list; scroll the transcript and watch the current one move."></aparte-chat-bubble>
53
+ * </aparte-chat-viewport>
54
+ * <aparte-scroll-rail></aparte-scroll-rail>
55
+ * <aparte-composer></aparte-composer>
56
+ * </aparte-chat>
57
+ */
58
+ export declare class AparteScrollRail extends HTMLElement {
59
+ static get observedAttributes(): string[];
60
+ private _host;
61
+ private _mutations;
62
+ private _intersections;
63
+ private _rebuildQueued;
64
+ private _currentId;
65
+ /** Visible ratio per message id, from the intersection observer. */
66
+ private _visible;
67
+ private _onConfigChange;
68
+ /** The id of the message the rail currently marks, or `null`. */
69
+ get currentMessageId(): string | null;
70
+ connectedCallback(): void;
71
+ disconnectedCallback(): void;
72
+ attributeChangedCallback(name: string): void;
73
+ /** The chat this rail follows: `target`, else the host above it — the gauge's rule. */
74
+ private _findHost;
75
+ private _attach;
76
+ private _detach;
77
+ /** Coalesce a burst of mutations (a streaming reply is one per token) into one rebuild. */
78
+ private _queueRebuild;
79
+ private _viewport;
80
+ /** The element that scrolls: the vanilla container, or the viewport itself under a wrapper. */
81
+ private _scrollSurface;
82
+ private _bubbles;
83
+ /** The first words of a message, for the tick's name. An excerpt, never a summary. */
84
+ private _excerpt;
85
+ private _tickLabel;
86
+ private _rebuild;
87
+ /**
88
+ * Which tick is current is read, not computed: the scroll surface is the root, and
89
+ * the bubble with the largest visible share of a reading band near the top wins.
90
+ * Scroll arithmetic was the alternative, and every scroll-position rule in the
91
+ * viewport carries a regression note — this one has none to carry.
92
+ */
93
+ private _observe;
94
+ private _pickCurrent;
95
+ private _setCurrent;
96
+ private _onClick;
97
+ /** The ticks are buttons; the arrows walk them, as in any toolbar. */
98
+ private _onKeydown;
99
+ /**
100
+ * Scroll the transcript to a message. Announced first, cancelable; then a
101
+ * `scrollIntoView` on the bubble, smooth unless the reader prefers reduced motion.
102
+ */
103
+ jumpTo(messageId: string): void;
104
+ }
105
+ //# sourceMappingURL=aparte-scroll-rail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aparte-scroll-rail.d.ts","sourceRoot":"","sources":["../../../src/components/scroll-rail/aparte-scroll-rail.ts"],"names":[],"mappings":"AAGA,yEAAyE;AACzE,MAAM,WAAW,0BAA0B;IACvC,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAAC;AAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;IAC7C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,UAAU,CAAuB;IACzC,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAA6B;IAE7C,OAAO,CAAC,eAAe,CAA+B;IAEtD,iEAAiE;IACjE,IAAI,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEpC;IAED,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAO5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ5C,uFAAuF;IACvF,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,OAAO;IASf,2FAA2F;IAC3F,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,SAAS;IAIjB,+FAA+F;IAC/F,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,QAAQ;IAUhB,sFAAsF;IACtF,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,QAAQ;IAwChB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,QAAQ,CAMd;IAEF,sEAAsE;IACtE,OAAO,CAAC,UAAU,CAWhB;IAEF;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAelC"}
@@ -0,0 +1,3 @@
1
+ export { AparteScrollRail } from './aparte-scroll-rail.js';
2
+ export type { AparteScrollRailJumpDetail, AparteScrollRailEvery } from './aparte-scroll-rail.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/scroll-rail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}