@tetherto/mdk-ui-agent 0.0.0 → 0.12.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 (217) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +310 -0
  3. package/dist/branding.d.ts +36 -0
  4. package/dist/branding.d.ts.map +1 -0
  5. package/dist/branding.js +37 -0
  6. package/dist/branding.js.map +1 -0
  7. package/dist/components/approval-card.d.ts +46 -0
  8. package/dist/components/approval-card.d.ts.map +1 -0
  9. package/dist/components/approval-card.js +84 -0
  10. package/dist/components/approval-card.js.map +1 -0
  11. package/dist/components/assistant-message.d.ts +25 -0
  12. package/dist/components/assistant-message.d.ts.map +1 -0
  13. package/dist/components/assistant-message.js +49 -0
  14. package/dist/components/assistant-message.js.map +1 -0
  15. package/dist/components/co-pilot-panel.d.ts +17 -0
  16. package/dist/components/co-pilot-panel.d.ts.map +1 -0
  17. package/dist/components/co-pilot-panel.js +33 -0
  18. package/dist/components/co-pilot-panel.js.map +1 -0
  19. package/dist/components/code-block.d.ts +17 -0
  20. package/dist/components/code-block.d.ts.map +1 -0
  21. package/dist/components/code-block.js +40 -0
  22. package/dist/components/code-block.js.map +1 -0
  23. package/dist/components/collapsible-answer.d.ts +26 -0
  24. package/dist/components/collapsible-answer.d.ts.map +1 -0
  25. package/dist/components/collapsible-answer.js +30 -0
  26. package/dist/components/collapsible-answer.js.map +1 -0
  27. package/dist/components/composer.d.ts +31 -0
  28. package/dist/components/composer.d.ts.map +1 -0
  29. package/dist/components/composer.js +82 -0
  30. package/dist/components/composer.js.map +1 -0
  31. package/dist/components/conversation-list.d.ts +21 -0
  32. package/dist/components/conversation-list.d.ts.map +1 -0
  33. package/dist/components/conversation-list.js +42 -0
  34. package/dist/components/conversation-list.js.map +1 -0
  35. package/dist/components/icons.d.ts +88 -0
  36. package/dist/components/icons.d.ts.map +1 -0
  37. package/dist/components/icons.js +112 -0
  38. package/dist/components/icons.js.map +1 -0
  39. package/dist/components/launcher-fab.d.ts +8 -0
  40. package/dist/components/launcher-fab.d.ts.map +1 -0
  41. package/dist/components/launcher-fab.js +6 -0
  42. package/dist/components/launcher-fab.js.map +1 -0
  43. package/dist/components/leaked-tool-call-notice.d.ts +18 -0
  44. package/dist/components/leaked-tool-call-notice.d.ts.map +1 -0
  45. package/dist/components/leaked-tool-call-notice.js +14 -0
  46. package/dist/components/leaked-tool-call-notice.js.map +1 -0
  47. package/dist/components/markdown-link.d.ts +17 -0
  48. package/dist/components/markdown-link.d.ts.map +1 -0
  49. package/dist/components/markdown-link.js +18 -0
  50. package/dist/components/markdown-link.js.map +1 -0
  51. package/dist/components/markdown-text.d.ts +26 -0
  52. package/dist/components/markdown-text.d.ts.map +1 -0
  53. package/dist/components/markdown-text.js +32 -0
  54. package/dist/components/markdown-text.js.map +1 -0
  55. package/dist/components/message-list.d.ts +24 -0
  56. package/dist/components/message-list.d.ts.map +1 -0
  57. package/dist/components/message-list.js +92 -0
  58. package/dist/components/message-list.js.map +1 -0
  59. package/dist/components/no-tools-note.d.ts +26 -0
  60. package/dist/components/no-tools-note.d.ts.map +1 -0
  61. package/dist/components/no-tools-note.js +27 -0
  62. package/dist/components/no-tools-note.js.map +1 -0
  63. package/dist/components/panel-header.d.ts +26 -0
  64. package/dist/components/panel-header.d.ts.map +1 -0
  65. package/dist/components/panel-header.js +13 -0
  66. package/dist/components/panel-header.js.map +1 -0
  67. package/dist/components/rehype-highlight-subset.d.ts +17 -0
  68. package/dist/components/rehype-highlight-subset.d.ts.map +1 -0
  69. package/dist/components/rehype-highlight-subset.js +77 -0
  70. package/dist/components/rehype-highlight-subset.js.map +1 -0
  71. package/dist/components/system-message.d.ts +15 -0
  72. package/dist/components/system-message.d.ts.map +1 -0
  73. package/dist/components/system-message.js +12 -0
  74. package/dist/components/system-message.js.map +1 -0
  75. package/dist/components/tool-chip.d.ts +19 -0
  76. package/dist/components/tool-chip.d.ts.map +1 -0
  77. package/dist/components/tool-chip.js +32 -0
  78. package/dist/components/tool-chip.js.map +1 -0
  79. package/dist/components/user-message.d.ts +9 -0
  80. package/dist/components/user-message.d.ts.map +1 -0
  81. package/dist/components/user-message.js +7 -0
  82. package/dist/components/user-message.js.map +1 -0
  83. package/dist/core/conversation-store.d.ts +107 -0
  84. package/dist/core/conversation-store.d.ts.map +1 -0
  85. package/dist/core/conversation-store.js +254 -0
  86. package/dist/core/conversation-store.js.map +1 -0
  87. package/dist/core/error-text.d.ts +19 -0
  88. package/dist/core/error-text.d.ts.map +1 -0
  89. package/dist/core/error-text.js +35 -0
  90. package/dist/core/error-text.js.map +1 -0
  91. package/dist/core/events.d.ts +98 -0
  92. package/dist/core/events.d.ts.map +1 -0
  93. package/dist/core/events.js +50 -0
  94. package/dist/core/events.js.map +1 -0
  95. package/dist/core/format.d.ts +23 -0
  96. package/dist/core/format.d.ts.map +1 -0
  97. package/dist/core/format.js +49 -0
  98. package/dist/core/format.js.map +1 -0
  99. package/dist/core/index.d.ts +27 -0
  100. package/dist/core/index.d.ts.map +1 -0
  101. package/dist/core/index.js +20 -0
  102. package/dist/core/index.js.map +1 -0
  103. package/dist/core/markdown.d.ts +26 -0
  104. package/dist/core/markdown.d.ts.map +1 -0
  105. package/dist/core/markdown.js +49 -0
  106. package/dist/core/markdown.js.map +1 -0
  107. package/dist/core/prose.d.ts +27 -0
  108. package/dist/core/prose.d.ts.map +1 -0
  109. package/dist/core/prose.js +79 -0
  110. package/dist/core/prose.js.map +1 -0
  111. package/dist/core/small-talk.d.ts +15 -0
  112. package/dist/core/small-talk.d.ts.map +1 -0
  113. package/dist/core/small-talk.js +42 -0
  114. package/dist/core/small-talk.js.map +1 -0
  115. package/dist/core/sse.d.ts +108 -0
  116. package/dist/core/sse.d.ts.map +1 -0
  117. package/dist/core/sse.js +236 -0
  118. package/dist/core/sse.js.map +1 -0
  119. package/dist/core/tool-label.d.ts +16 -0
  120. package/dist/core/tool-label.d.ts.map +1 -0
  121. package/dist/core/tool-label.js +31 -0
  122. package/dist/core/tool-label.js.map +1 -0
  123. package/dist/core/transport.d.ts +71 -0
  124. package/dist/core/transport.d.ts.map +1 -0
  125. package/dist/core/transport.js +147 -0
  126. package/dist/core/transport.js.map +1 -0
  127. package/dist/core/turn.d.ts +87 -0
  128. package/dist/core/turn.d.ts.map +1 -0
  129. package/dist/core/turn.js +232 -0
  130. package/dist/core/turn.js.map +1 -0
  131. package/dist/core/uuid.d.ts +21 -0
  132. package/dist/core/uuid.d.ts.map +1 -0
  133. package/dist/core/uuid.js +54 -0
  134. package/dist/core/uuid.js.map +1 -0
  135. package/dist/entries/chat-page.d.ts +28 -0
  136. package/dist/entries/chat-page.d.ts.map +1 -0
  137. package/dist/entries/chat-page.js +25 -0
  138. package/dist/entries/chat-page.js.map +1 -0
  139. package/dist/entries/co-pilot.d.ts +41 -0
  140. package/dist/entries/co-pilot.d.ts.map +1 -0
  141. package/dist/entries/co-pilot.js +39 -0
  142. package/dist/entries/co-pilot.js.map +1 -0
  143. package/dist/entries/lazy-panel.d.ts +15 -0
  144. package/dist/entries/lazy-panel.d.ts.map +1 -0
  145. package/dist/entries/lazy-panel.js +19 -0
  146. package/dist/entries/lazy-panel.js.map +1 -0
  147. package/dist/hooks/index.d.ts +7 -0
  148. package/dist/hooks/index.d.ts.map +1 -0
  149. package/dist/hooks/index.js +4 -0
  150. package/dist/hooks/index.js.map +1 -0
  151. package/dist/hooks/use-agent-chat.d.ts +46 -0
  152. package/dist/hooks/use-agent-chat.d.ts.map +1 -0
  153. package/dist/hooks/use-agent-chat.js +288 -0
  154. package/dist/hooks/use-agent-chat.js.map +1 -0
  155. package/dist/hooks/use-agent-config.d.ts +29 -0
  156. package/dist/hooks/use-agent-config.d.ts.map +1 -0
  157. package/dist/hooks/use-agent-config.js +45 -0
  158. package/dist/hooks/use-agent-config.js.map +1 -0
  159. package/dist/hooks/use-conversations.d.ts +19 -0
  160. package/dist/hooks/use-conversations.d.ts.map +1 -0
  161. package/dist/hooks/use-conversations.js +19 -0
  162. package/dist/hooks/use-conversations.js.map +1 -0
  163. package/dist/index.d.ts +28 -0
  164. package/dist/index.d.ts.map +1 -0
  165. package/dist/index.js +26 -0
  166. package/dist/index.js.map +1 -0
  167. package/dist/styles.css +1 -0
  168. package/package.json +105 -1
  169. package/src/branding.ts +40 -0
  170. package/src/components/approval-card.tsx +141 -0
  171. package/src/components/assistant-message.tsx +140 -0
  172. package/src/components/co-pilot-panel.tsx +109 -0
  173. package/src/components/code-block.tsx +63 -0
  174. package/src/components/collapsible-answer.tsx +55 -0
  175. package/src/components/composer.tsx +147 -0
  176. package/src/components/conversation-list.tsx +141 -0
  177. package/src/components/icons.tsx +189 -0
  178. package/src/components/launcher-fab.tsx +16 -0
  179. package/src/components/leaked-tool-call-notice.tsx +29 -0
  180. package/src/components/markdown-link.tsx +30 -0
  181. package/src/components/markdown-text.tsx +58 -0
  182. package/src/components/message-list.tsx +164 -0
  183. package/src/components/no-tools-note.tsx +33 -0
  184. package/src/components/panel-header.tsx +86 -0
  185. package/src/components/rehype-highlight-subset.ts +84 -0
  186. package/src/components/system-message.tsx +19 -0
  187. package/src/components/tool-chip.tsx +58 -0
  188. package/src/components/user-message.tsx +18 -0
  189. package/src/core/conversation-store.ts +342 -0
  190. package/src/core/error-text.ts +36 -0
  191. package/src/core/events.ts +127 -0
  192. package/src/core/format.ts +59 -0
  193. package/src/core/index.ts +115 -0
  194. package/src/core/markdown.ts +52 -0
  195. package/src/core/prose.ts +78 -0
  196. package/src/core/small-talk.ts +45 -0
  197. package/src/core/sse.ts +269 -0
  198. package/src/core/tool-label.ts +33 -0
  199. package/src/core/transport.ts +208 -0
  200. package/src/core/turn.ts +299 -0
  201. package/src/core/uuid.ts +59 -0
  202. package/src/entries/chat-page.tsx +56 -0
  203. package/src/entries/co-pilot.tsx +84 -0
  204. package/src/entries/lazy-panel.tsx +19 -0
  205. package/src/hooks/index.ts +8 -0
  206. package/src/hooks/use-agent-chat.ts +387 -0
  207. package/src/hooks/use-agent-config.ts +70 -0
  208. package/src/hooks/use-conversations.ts +39 -0
  209. package/src/index.ts +30 -0
  210. package/src/styles/_approval.scss +68 -0
  211. package/src/styles/_composer.scss +45 -0
  212. package/src/styles/_conversations.scss +160 -0
  213. package/src/styles/_messages.scss +444 -0
  214. package/src/styles/_mixins.scss +27 -0
  215. package/src/styles/_panel.scss +147 -0
  216. package/src/styles/_tokens.scss +30 -0
  217. package/src/styles.scss +16 -0
@@ -0,0 +1,160 @@
1
+ /* The conversations view. */
2
+
3
+ @use '@tetherto/mdk-react-devkit/styles' as *;
4
+ @use 'mixins' as *;
5
+
6
+ .mdk-agent-conversations {
7
+ display: flex;
8
+ flex: 1 1 auto;
9
+ flex-direction: column;
10
+ min-height: 0;
11
+
12
+ &__scroll {
13
+ @include scroll_column;
14
+ }
15
+
16
+ &__empty {
17
+ @include empty_note;
18
+ }
19
+
20
+ /* A row is a container, not a button: the delete control is a second button
21
+ and nesting one inside another is invalid. */
22
+ &__row {
23
+ display: flex;
24
+ gap: 12px;
25
+ align-items: center;
26
+ padding: 12px 16px;
27
+ border-bottom: 1px solid var(--mdk-agent-border);
28
+
29
+ &:hover {
30
+ background: var(--mdk-agent-surface-raised);
31
+ }
32
+
33
+ &--active {
34
+ background: var(--mdk-agent-surface-raised);
35
+ box-shadow: inset 2px 0 0 var(--mdk-agent-accent);
36
+ }
37
+ }
38
+
39
+ &__open {
40
+ display: flex;
41
+ flex: 1 1 auto;
42
+ flex-direction: column;
43
+ gap: 2px;
44
+ min-width: 0;
45
+ padding: 0;
46
+ border: none;
47
+ background: none;
48
+ color: inherit;
49
+ font: inherit;
50
+ text-align: left;
51
+ cursor: pointer;
52
+ }
53
+
54
+ &__title {
55
+ @include text_ellipsis;
56
+
57
+ color: var(--mdk-color-white, #fff);
58
+ }
59
+
60
+ &__meta {
61
+ color: var(--mdk-agent-text-muted);
62
+ font-size: 11px;
63
+ }
64
+
65
+ &__badge {
66
+ display: flex;
67
+ flex: none;
68
+ gap: 6px;
69
+ align-items: center;
70
+ color: var(--mdk-agent-text-muted);
71
+ font-size: 10px;
72
+ letter-spacing: 0.08em;
73
+ text-transform: uppercase;
74
+
75
+ &::before {
76
+ content: '';
77
+ width: 6px;
78
+ height: 6px;
79
+ background: currentcolor;
80
+ }
81
+
82
+ &--running {
83
+ color: var(--mdk-agent-accent);
84
+ }
85
+ }
86
+
87
+ &__delete {
88
+ display: flex;
89
+ flex: none;
90
+ align-items: center;
91
+ justify-content: center;
92
+ width: 24px;
93
+ height: 24px;
94
+ padding: 0;
95
+ border: none;
96
+ background: none;
97
+ color: var(--mdk-agent-text-muted);
98
+ cursor: pointer;
99
+
100
+ /* Revealed on hover, but never hidden from assistive tech or the keyboard. */
101
+ opacity: 0;
102
+
103
+ &:hover:not(:disabled) {
104
+ color: var(--mdk-agent-danger);
105
+ }
106
+
107
+ &:disabled {
108
+ cursor: not-allowed;
109
+ }
110
+ }
111
+
112
+ &__row:hover &__delete,
113
+ &__delete:focus-visible {
114
+ opacity: 1;
115
+ }
116
+
117
+ &__confirm {
118
+ display: flex;
119
+ flex: none;
120
+ gap: 6px;
121
+ align-items: center;
122
+
123
+ button {
124
+ padding: 3px 8px;
125
+ border: 1px solid var(--mdk-agent-border-strong);
126
+ background: none;
127
+ color: var(--mdk-agent-text);
128
+ font: inherit;
129
+ font-size: 11px;
130
+ cursor: pointer;
131
+ }
132
+
133
+ /* Two classes, so it outranks the element selector above without
134
+ `!important` — the cascade-layer setup exists precisely to avoid those. */
135
+ .mdk-agent-conversations__confirm-yes {
136
+ border-color: color-mix(in srgb, var(--mdk-agent-danger) 60%, transparent);
137
+ color: var(--mdk-agent-danger);
138
+ }
139
+ }
140
+
141
+ &__footer {
142
+ flex: none;
143
+ padding: 12px;
144
+ border-top: 1px solid var(--mdk-agent-border);
145
+
146
+ /* The devkit's outline button is light-on-dark by default, which reads as a
147
+ filled white slab inside this panel. */
148
+ button {
149
+ border: 1px solid var(--mdk-agent-border-strong);
150
+ background: transparent;
151
+ color: var(--mdk-agent-text);
152
+
153
+ &:hover:not(:disabled) {
154
+ border-color: var(--mdk-agent-accent);
155
+ background: var(--mdk-agent-surface-raised);
156
+ color: var(--mdk-color-white, #fff);
157
+ }
158
+ }
159
+ }
160
+ }
@@ -0,0 +1,444 @@
1
+ /* Transcript: bubbles, tool chips, markdown, the streaming and failure states. */
2
+
3
+ @use 'mixins' as *;
4
+
5
+ .mdk-agent-messages {
6
+ @include scroll_column;
7
+
8
+ gap: 20px;
9
+ padding: 16px;
10
+
11
+ &__empty {
12
+ @include empty_note;
13
+ }
14
+ }
15
+
16
+ .mdk-agent-message {
17
+ display: flex;
18
+ flex-direction: column;
19
+ gap: 6px;
20
+ min-width: 0;
21
+
22
+ &__role {
23
+ margin: 0;
24
+ color: var(--mdk-agent-text-muted);
25
+ font-size: 10px;
26
+ letter-spacing: 0.08em;
27
+ text-transform: uppercase;
28
+ }
29
+
30
+ &__dot {
31
+ display: inline-block;
32
+ width: 6px;
33
+ height: 6px;
34
+ margin-right: 6px;
35
+ background: var(--mdk-agent-accent);
36
+ }
37
+
38
+ &__bubble {
39
+ padding: 9px 12px;
40
+ border: 1px solid var(--mdk-agent-border-strong);
41
+ border-radius: var(--mdk-agent-radius);
42
+ white-space: pre-wrap;
43
+ overflow-wrap: anywhere;
44
+ }
45
+
46
+ &__tools {
47
+ display: flex;
48
+ flex-wrap: wrap;
49
+ gap: 6px;
50
+ }
51
+
52
+ /* The synthesized "what you are approving" line above the card. */
53
+ &__intent {
54
+ margin: 0;
55
+ }
56
+
57
+ &__error {
58
+ display: flex;
59
+ gap: 8px;
60
+ align-items: baseline;
61
+ margin: 0;
62
+ color: var(--mdk-agent-danger);
63
+ }
64
+
65
+ /* "Try again" sits on the error line rather than under it: one row, and the
66
+ affordance is where the operator is already looking. It keeps its own width —
67
+ sharing the row with a two-line message otherwise broke the label mid-word. */
68
+ &__retry {
69
+ flex: none;
70
+ padding: 0;
71
+ border: none;
72
+ background: none;
73
+ color: inherit;
74
+ font: inherit;
75
+ white-space: nowrap;
76
+ text-decoration: underline;
77
+ cursor: pointer;
78
+ }
79
+
80
+ /* A turn the operator stopped, or one the panel could not finish. */
81
+ &__note {
82
+ margin: 0;
83
+ color: var(--mdk-agent-text-muted);
84
+ font-size: 11px;
85
+ }
86
+
87
+ /* The operator's own turns hug the right edge, capped so a long question
88
+ still reads as a bubble rather than a full-width block. */
89
+ &--user {
90
+ align-items: flex-end;
91
+
92
+ .mdk-agent-message__role,
93
+ .mdk-agent-message__bubble {
94
+ max-width: 85%;
95
+ }
96
+ }
97
+ }
98
+
99
+ .mdk-agent-tool-chip {
100
+ display: inline-flex;
101
+ gap: 6px;
102
+ align-items: center;
103
+ padding: 3px 8px;
104
+ border: 1px solid var(--mdk-agent-border-strong);
105
+ border-radius: var(--mdk-agent-radius);
106
+ color: var(--mdk-agent-text-muted);
107
+ font-size: 11px;
108
+ line-height: 13px;
109
+
110
+ &__icon:empty {
111
+ display: none;
112
+ }
113
+
114
+ &__icon {
115
+ display: inline-flex;
116
+ }
117
+
118
+ &--ok {
119
+ color: var(--mdk-agent-success);
120
+ border-color: color-mix(in srgb, var(--mdk-agent-success) 45%, transparent);
121
+ }
122
+
123
+ &--running,
124
+ &--awaiting-approval {
125
+ color: var(--mdk-agent-accent);
126
+ border-color: color-mix(in srgb, var(--mdk-agent-accent) 45%, transparent);
127
+ }
128
+
129
+ /* A refusal is neither success nor failure — the operator meant it. */
130
+ &--rejected {
131
+ color: var(--mdk-agent-text-muted);
132
+ border-color: var(--mdk-agent-border-strong);
133
+ text-decoration: line-through;
134
+ }
135
+
136
+ &--error {
137
+ color: var(--mdk-agent-danger);
138
+ border-color: color-mix(in srgb, var(--mdk-agent-danger) 45%, transparent);
139
+ }
140
+
141
+ /* The turn ended before the result arrived: not a failure of the tool, and not
142
+ a success either — the outcome is simply unknown. */
143
+ &--interrupted {
144
+ color: var(--mdk-agent-text-muted);
145
+ border-color: var(--mdk-agent-border-strong);
146
+ border-style: dashed;
147
+ }
148
+ }
149
+
150
+ /* A note from the panel, not from the model — a re-minted session, mostly. */
151
+ .mdk-agent-system {
152
+ margin: 0;
153
+ padding: 6px 0;
154
+ border-top: 1px dashed var(--mdk-agent-border);
155
+ color: var(--mdk-agent-text-muted);
156
+ font-size: 11px;
157
+ text-align: center;
158
+ }
159
+
160
+ .mdk-agent-markdown {
161
+ min-width: 0;
162
+ overflow-wrap: anywhere;
163
+
164
+ /* While a turn streams the text is rendered raw — a half-written fence would
165
+ otherwise reflow the whole answer on every token. */
166
+ &--streaming {
167
+ white-space: pre-wrap;
168
+ }
169
+
170
+ > :first-child {
171
+ margin-top: 0;
172
+ }
173
+
174
+ > :last-child {
175
+ margin-bottom: 0;
176
+ }
177
+
178
+ /* Everything remark-gfm can emit is styled, not only what the reference model
179
+ happens to produce: nothing constrains the answer's format, so a heading, a
180
+ quote or an image is reachable from any ordinary question. Left at browser
181
+ defaults they render at document scale inside a 420px panel. */
182
+ p,
183
+ ul,
184
+ ol,
185
+ pre,
186
+ table,
187
+ blockquote,
188
+ hr,
189
+ .mdk-agent-code {
190
+ margin: 0 0 10px;
191
+ }
192
+
193
+ ul,
194
+ ol {
195
+ padding-left: 20px;
196
+ }
197
+
198
+ /* A panel is not a document: h1 sits barely above body text, and h4-h6 stop
199
+ shrinking rather than dropping below it. */
200
+ h1,
201
+ h2,
202
+ h3,
203
+ h4,
204
+ h5,
205
+ h6 {
206
+ margin: 14px 0 6px;
207
+ font-weight: 600;
208
+ line-height: 1.3;
209
+ }
210
+
211
+ h1 {
212
+ font-size: 15px;
213
+ }
214
+
215
+ h2 {
216
+ font-size: 14px;
217
+ }
218
+
219
+ h3,
220
+ h4,
221
+ h5,
222
+ h6 {
223
+ font-size: 13px;
224
+ }
225
+
226
+ blockquote {
227
+ padding-left: 10px;
228
+ border-left: 2px solid var(--mdk-agent-border-strong);
229
+ color: var(--mdk-agent-text-muted);
230
+ }
231
+
232
+ hr {
233
+ height: 0;
234
+ border: none;
235
+ border-top: 1px solid var(--mdk-agent-border);
236
+ }
237
+
238
+ /* An image the model links to must not push the panel wider than the viewport. */
239
+ img {
240
+ max-width: 100%;
241
+ height: auto;
242
+ }
243
+
244
+ code {
245
+ padding: 1px 4px;
246
+ background: var(--mdk-agent-surface-raised);
247
+ font-size: 12px;
248
+ }
249
+
250
+ pre {
251
+ padding: 10px;
252
+ overflow-x: auto;
253
+ background: var(--mdk-agent-surface-raised);
254
+ border: 1px solid var(--mdk-agent-border);
255
+
256
+ code {
257
+ padding: 0;
258
+ background: none;
259
+ }
260
+ }
261
+
262
+ /* Wide tables scroll inside the panel instead of widening it. */
263
+ table {
264
+ display: block;
265
+ width: max-content;
266
+ max-width: 100%;
267
+ overflow-x: auto;
268
+ border-collapse: collapse;
269
+ }
270
+
271
+ th,
272
+ td {
273
+ padding: 4px 10px 4px 0;
274
+ text-align: left;
275
+ }
276
+
277
+ th {
278
+ color: var(--mdk-agent-text-muted);
279
+ font-weight: 600;
280
+ }
281
+
282
+ /* GFM task lists: the checkbox is `disabled`, so it is a status marker rather
283
+ than a control, and it has to line up with the first line of its item. */
284
+ li:has(> input[type='checkbox']) {
285
+ list-style: none;
286
+ margin-left: -20px;
287
+ }
288
+
289
+ input[type='checkbox'] {
290
+ margin-right: 6px;
291
+ vertical-align: baseline;
292
+ accent-color: var(--mdk-agent-accent);
293
+ }
294
+
295
+ /* GFM footnotes: a `section` of definitions the answer refers to by `sup`. */
296
+ .footnotes {
297
+ margin-top: 12px;
298
+ padding-top: 6px;
299
+ border-top: 1px solid var(--mdk-agent-border);
300
+ color: var(--mdk-agent-text-muted);
301
+ font-size: 11px;
302
+
303
+ h2 {
304
+ /* remark-gfm labels the section "Footnotes" for screen readers only. */
305
+ position: absolute;
306
+ width: 1px;
307
+ height: 1px;
308
+ overflow: hidden;
309
+ clip-path: inset(50%);
310
+ }
311
+ }
312
+
313
+ a {
314
+ color: var(--mdk-agent-accent);
315
+ }
316
+
317
+ /* Reveals the rest of a long answer. Sits under the text as its own row. */
318
+ &__more {
319
+ align-self: flex-start;
320
+ padding: 0;
321
+ border: none;
322
+ background: none;
323
+ color: var(--mdk-agent-accent);
324
+ font: inherit;
325
+ font-size: 11px;
326
+ text-decoration: underline;
327
+ cursor: pointer;
328
+ }
329
+ }
330
+
331
+ /**
332
+ * A fenced block and its copy button.
333
+ *
334
+ * The wrapper carries the block's margin so the button can be positioned against
335
+ * the code rather than against the transcript.
336
+ */
337
+ .mdk-agent-code {
338
+ position: relative;
339
+
340
+ pre {
341
+ margin: 0;
342
+ }
343
+
344
+ &__copy {
345
+ position: absolute;
346
+ top: 4px;
347
+ right: 4px;
348
+ padding: 2px 6px;
349
+ border: 1px solid var(--mdk-agent-border-strong);
350
+ background: var(--mdk-agent-surface);
351
+ color: var(--mdk-agent-text-muted);
352
+ font: inherit;
353
+ font-size: 10px;
354
+ cursor: pointer;
355
+
356
+ /* Revealed on hover, but never hidden from the keyboard. */
357
+ opacity: 0;
358
+ }
359
+
360
+ &:hover &__copy,
361
+ &__copy:focus-visible {
362
+ opacity: 1;
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Syntax colours for the three grammars `rehype-highlight-subset` registers.
368
+ *
369
+ * highlight.js ships ~250 themes and none of them are imported: they are written
370
+ * for a page, carry their own background and foreground, and would fight the
371
+ * panel's tokens. These are the token classes bash, json and yaml can actually
372
+ * emit, mapped onto the same `--mdk-agent-*` variables as everything else, so the
373
+ * highlighting rethemes with the panel instead of overriding it.
374
+ */
375
+ .mdk-agent-markdown pre code.hljs {
376
+ .hljs-keyword,
377
+ .hljs-built_in,
378
+ .hljs-section {
379
+ color: var(--mdk-agent-accent);
380
+ }
381
+
382
+ .hljs-string,
383
+ .hljs-symbol {
384
+ color: var(--mdk-agent-success);
385
+ }
386
+
387
+ .hljs-attr,
388
+ .hljs-attribute {
389
+ color: color-mix(in srgb, var(--mdk-agent-accent) 60%, var(--mdk-agent-text));
390
+ }
391
+
392
+ .hljs-number,
393
+ .hljs-literal,
394
+ .hljs-bullet {
395
+ color: color-mix(in srgb, var(--mdk-agent-success) 55%, var(--mdk-agent-text));
396
+ }
397
+
398
+ .hljs-variable,
399
+ .hljs-template-variable,
400
+ .hljs-meta {
401
+ color: var(--mdk-agent-text);
402
+ }
403
+
404
+ .hljs-comment,
405
+ .hljs-quote {
406
+ color: var(--mdk-agent-text-muted);
407
+ font-style: italic;
408
+ }
409
+ }
410
+
411
+ .mdk-agent-no-tools {
412
+ display: inline-flex;
413
+ gap: 4px;
414
+ align-items: center;
415
+ margin-left: 8px;
416
+ color: var(--mdk-agent-text-muted);
417
+ letter-spacing: 0;
418
+ text-transform: none;
419
+ opacity: 0.75;
420
+
421
+ svg {
422
+ flex: none;
423
+ }
424
+ }
425
+
426
+ .mdk-agent-leaked {
427
+ padding: 10px 12px;
428
+ border: 1px dashed color-mix(in srgb, var(--mdk-agent-accent) 55%, transparent);
429
+ border-radius: var(--mdk-agent-radius);
430
+
431
+ &__title {
432
+ margin: 0 0 4px;
433
+ color: var(--mdk-agent-accent);
434
+ }
435
+
436
+ &__body {
437
+ margin: 0;
438
+ color: var(--mdk-agent-text-muted);
439
+ }
440
+
441
+ &__tool {
442
+ color: var(--mdk-agent-text);
443
+ }
444
+ }
@@ -0,0 +1,27 @@
1
+ /* Local mixins: the two shapes that repeat across the panel's own partials. */
2
+
3
+ /**
4
+ * A column that scrolls inside the panel rather than growing it.
5
+ *
6
+ * Both scrolling regions — the transcript and the conversations list — need the
7
+ * same four properties, and `min-height: 0` is the load-bearing one: without it a
8
+ * flex child refuses to shrink below its content and the panel grows instead of
9
+ * scrolling. A mixin rather than `@extend` because nothing in this repo extends
10
+ * (see `docs/STYLING.md`), and an `@extend` reaching across `@use` boundaries into
11
+ * a `@layer`-wrapped sheet is exactly where its output order stops being obvious.
12
+ */
13
+ @mixin scroll_column {
14
+ display: flex;
15
+ flex: 1 1 auto;
16
+ flex-direction: column;
17
+ min-height: 0;
18
+ overflow-y: auto;
19
+ overscroll-behavior: contain;
20
+ }
21
+
22
+ /** The muted, centered line a list or transcript shows when it has nothing in it. */
23
+ @mixin empty_note {
24
+ margin: auto 0;
25
+ color: var(--mdk-agent-text-muted);
26
+ text-align: center;
27
+ }