@artooi/ag-ui-web-component 0.1.0 → 0.2.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 (109) hide show
  1. package/CHANGELOG.md +102 -2
  2. package/README.md +235 -47
  3. package/dist/ag-ui-web-component.bundle.js +451 -46
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/constants.d.ts +34 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/{ag_ui_chat.d.ts → core/ag_ui_chat.d.ts} +63 -6
  8. package/dist/core/ag_ui_chat.d.ts.map +1 -0
  9. package/dist/core/agui_client.d.ts.map +1 -0
  10. package/dist/core/conversation_store.d.ts.map +1 -0
  11. package/dist/core/create_http_agent.d.ts.map +1 -0
  12. package/dist/core/define_ag_ui_chat.d.ts.map +1 -0
  13. package/dist/dom/animations.d.ts +71 -0
  14. package/dist/dom/animations.d.ts.map +1 -0
  15. package/dist/{dom_driver.d.ts → dom/dom_driver.d.ts} +7 -1
  16. package/dist/dom/dom_driver.d.ts.map +1 -0
  17. package/dist/dom/native_setter.d.ts +5 -0
  18. package/dist/dom/native_setter.d.ts.map +1 -0
  19. package/dist/index.d.ts +19 -16
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3886 -388
  22. package/dist/index.js.map +4 -4
  23. package/dist/skills/fill_template.d.ts +17 -0
  24. package/dist/skills/fill_template.d.ts.map +1 -0
  25. package/dist/skills/parse_skills.d.ts +8 -0
  26. package/dist/skills/parse_skills.d.ts.map +1 -0
  27. package/dist/skills/skill.d.ts +24 -0
  28. package/dist/skills/skill.d.ts.map +1 -0
  29. package/dist/{client_tool_registry.d.ts → tools/client_tool_registry.d.ts} +6 -1
  30. package/dist/tools/client_tool_registry.d.ts.map +1 -0
  31. package/dist/tools/is_destructive.d.ts.map +1 -0
  32. package/dist/tools/is_navigates.d.ts.map +1 -0
  33. package/dist/tools/page_map.d.ts.map +1 -0
  34. package/dist/tools/route_map.d.ts +40 -0
  35. package/dist/tools/route_map.d.ts.map +1 -0
  36. package/dist/tools/state_hook.d.ts.map +1 -0
  37. package/dist/ui/confirmation_card.d.ts +22 -0
  38. package/dist/ui/confirmation_card.d.ts.map +1 -0
  39. package/dist/ui/render_markdown.d.ts +13 -0
  40. package/dist/ui/render_markdown.d.ts.map +1 -0
  41. package/dist/ui/reveal_words.d.ts +8 -0
  42. package/dist/ui/reveal_words.d.ts.map +1 -0
  43. package/dist/ui/skills_menu.d.ts +35 -0
  44. package/dist/ui/skills_menu.d.ts.map +1 -0
  45. package/dist/ui/styles.d.ts +2 -0
  46. package/dist/ui/styles.d.ts.map +1 -0
  47. package/dist/ui/tool_call_card.d.ts +35 -0
  48. package/dist/ui/tool_call_card.d.ts.map +1 -0
  49. package/package.json +5 -3
  50. package/src/constants.ts +38 -0
  51. package/src/core/ag_ui_chat.ts +786 -0
  52. package/src/{agui_client.ts → core/agui_client.ts} +1 -1
  53. package/src/{define_ag_ui_chat.ts → core/define_ag_ui_chat.ts} +1 -1
  54. package/src/dom/animations.ts +201 -0
  55. package/src/{dom_driver.ts → dom/dom_driver.ts} +35 -2
  56. package/src/dom/native_setter.ts +42 -0
  57. package/src/index.ts +61 -32
  58. package/src/skills/fill_template.ts +32 -0
  59. package/src/skills/parse_skills.ts +26 -0
  60. package/src/skills/skill.ts +23 -0
  61. package/src/{client_tool_registry.ts → tools/client_tool_registry.ts} +6 -4
  62. package/src/{is_destructive.ts → tools/is_destructive.ts} +1 -1
  63. package/src/{is_navigates.ts → tools/is_navigates.ts} +1 -1
  64. package/src/tools/route_map.ts +140 -0
  65. package/src/{state_hook.ts → tools/state_hook.ts} +1 -1
  66. package/src/ui/confirmation_card.ts +71 -0
  67. package/src/ui/render_markdown.ts +68 -0
  68. package/src/ui/reveal_words.ts +41 -0
  69. package/src/ui/skills_menu.ts +171 -0
  70. package/src/ui/styles.ts +631 -0
  71. package/src/{tool_call_card.ts → ui/tool_call_card.ts} +50 -19
  72. package/src/version.ts +1 -1
  73. package/dist/ag_ui_chat.d.ts.map +0 -1
  74. package/dist/agui_client.d.ts.map +0 -1
  75. package/dist/animations.d.ts +0 -33
  76. package/dist/animations.d.ts.map +0 -1
  77. package/dist/client_tool_registry.d.ts.map +0 -1
  78. package/dist/confirmation_modal.d.ts +0 -14
  79. package/dist/confirmation_modal.d.ts.map +0 -1
  80. package/dist/conversation_store.d.ts.map +0 -1
  81. package/dist/create_http_agent.d.ts.map +0 -1
  82. package/dist/define_ag_ui_chat.d.ts.map +0 -1
  83. package/dist/dom_driver.d.ts.map +0 -1
  84. package/dist/is_destructive.d.ts.map +0 -1
  85. package/dist/is_navigates.d.ts.map +0 -1
  86. package/dist/page_map.d.ts.map +0 -1
  87. package/dist/route_map.d.ts +0 -27
  88. package/dist/route_map.d.ts.map +0 -1
  89. package/dist/state_hook.d.ts.map +0 -1
  90. package/dist/styles.d.ts +0 -2
  91. package/dist/styles.d.ts.map +0 -1
  92. package/dist/tool_call_card.d.ts +0 -29
  93. package/dist/tool_call_card.d.ts.map +0 -1
  94. package/src/ag_ui_chat.ts +0 -411
  95. package/src/animations.ts +0 -86
  96. package/src/confirmation_modal.ts +0 -69
  97. package/src/route_map.ts +0 -83
  98. package/src/styles.ts +0 -296
  99. /package/dist/{agui_client.d.ts → core/agui_client.d.ts} +0 -0
  100. /package/dist/{conversation_store.d.ts → core/conversation_store.d.ts} +0 -0
  101. /package/dist/{create_http_agent.d.ts → core/create_http_agent.d.ts} +0 -0
  102. /package/dist/{define_ag_ui_chat.d.ts → core/define_ag_ui_chat.d.ts} +0 -0
  103. /package/dist/{is_destructive.d.ts → tools/is_destructive.d.ts} +0 -0
  104. /package/dist/{is_navigates.d.ts → tools/is_navigates.d.ts} +0 -0
  105. /package/dist/{page_map.d.ts → tools/page_map.d.ts} +0 -0
  106. /package/dist/{state_hook.d.ts → tools/state_hook.d.ts} +0 -0
  107. /package/src/{conversation_store.ts → core/conversation_store.ts} +0 -0
  108. /package/src/{create_http_agent.ts → core/create_http_agent.ts} +0 -0
  109. /package/src/{page_map.ts → tools/page_map.ts} +0 -0
@@ -0,0 +1,631 @@
1
+ // Shadow-DOM-scoped styles for the chat shell. Kept as a string constant so
2
+ // the Custom Element can inject it into its shadow root without a build-time
3
+ // CSS pipeline. Scoped by the shadow boundary, so class names stay terse.
4
+
5
+ export const STYLES = `
6
+ :host {
7
+ /* Colors */
8
+ --ag-ui-bg: #ffffff;
9
+ --ag-ui-fg: #1a1a2e;
10
+ --ag-ui-accent: #4f46e5;
11
+ --ag-ui-user-bg: #4f46e5;
12
+ --ag-ui-user-fg: #ffffff;
13
+ --ag-ui-assistant-bg: #f1f1f6;
14
+ --ag-ui-input-bg: var(--ag-ui-bg);
15
+ --ag-ui-tool-bg: var(--ag-ui-assistant-bg);
16
+ --ag-ui-tool-fg: var(--ag-ui-accent);
17
+ --ag-ui-header-bg: var(--ag-ui-accent);
18
+ --ag-ui-header-fg: #ffffff;
19
+ --ag-ui-border: #e2e2ec;
20
+ --ag-ui-radius: 12px;
21
+
22
+ /* Status accents for tool-call cards. */
23
+ --ag-ui-success: #15803d;
24
+ --ag-ui-danger: #b91c1c;
25
+ --ag-ui-muted: #6b7280;
26
+
27
+ /* Surface — set --ag-ui-shadow: none for a flush, embedded panel. */
28
+ --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);
29
+ --ag-ui-font: inherit;
30
+ --ag-ui-font-size: 14px;
31
+ --ag-ui-code-font: ui-monospace, "SF Mono", Menlo, monospace;
32
+
33
+ /* Spacing — the density preset overrides these. */
34
+ --ag-ui-space: 10px;
35
+ --ag-ui-pad: 16px;
36
+ --ag-ui-msg-pad: 8px 12px;
37
+ --ag-ui-msg-radius: 14px;
38
+
39
+ /* Layout — override from outside to dock the widget anywhere.
40
+ Set --ag-ui-position: static (and place this element in your own
41
+ grid/flex layout) to embed it in the page flow instead of floating. */
42
+ --ag-ui-position: fixed;
43
+ --ag-ui-z-index: 2147483000;
44
+ --ag-ui-width: 380px;
45
+ --ag-ui-height: 560px;
46
+ --ag-ui-inset: auto 24px 24px auto;
47
+ --ag-ui-max-width: calc(100vw - 48px);
48
+ --ag-ui-max-height: calc(100vh - 48px);
49
+
50
+ position: var(--ag-ui-position);
51
+ inset: var(--ag-ui-inset);
52
+ z-index: var(--ag-ui-z-index);
53
+ width: var(--ag-ui-width);
54
+ max-width: var(--ag-ui-max-width);
55
+ height: var(--ag-ui-height);
56
+ max-height: var(--ag-ui-max-height);
57
+ display: flex;
58
+ font-family: var(--ag-ui-font);
59
+ font-size: var(--ag-ui-font-size);
60
+ color: var(--ag-ui-fg);
61
+ }
62
+
63
+ /* ── Themes ─────────────────────────────────────────────────────────────
64
+ Themes only re-set the colour variables; layout/spacing are unaffected.
65
+ theme="auto" follows the OS via prefers-color-scheme. */
66
+ :host([theme="dark"]) {
67
+ --ag-ui-bg: #15151f;
68
+ --ag-ui-fg: #e8e8f2;
69
+ --ag-ui-assistant-bg: #25253a;
70
+ --ag-ui-header-bg: #1f1f30;
71
+ --ag-ui-header-fg: #e8e8f2;
72
+ --ag-ui-border: #33334a;
73
+ --ag-ui-muted: #9aa0b4;
74
+ --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
75
+ }
76
+
77
+ @media (prefers-color-scheme: dark) {
78
+ :host([theme="auto"]) {
79
+ --ag-ui-bg: #15151f;
80
+ --ag-ui-fg: #e8e8f2;
81
+ --ag-ui-assistant-bg: #25253a;
82
+ --ag-ui-header-bg: #1f1f30;
83
+ --ag-ui-header-fg: #e8e8f2;
84
+ --ag-ui-border: #33334a;
85
+ --ag-ui-muted: #9aa0b4;
86
+ --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
87
+ }
88
+ }
89
+
90
+ /* A terminal-flavoured "code" theme: dark, monospace, green accent. */
91
+ :host([theme="code"]) {
92
+ --ag-ui-bg: #0d1117;
93
+ --ag-ui-fg: #c9d1d9;
94
+ --ag-ui-accent: #3fb950;
95
+ --ag-ui-user-bg: #238636;
96
+ --ag-ui-assistant-bg: #161b22;
97
+ --ag-ui-header-bg: #010409;
98
+ --ag-ui-header-fg: #c9d1d9;
99
+ --ag-ui-border: #30363d;
100
+ --ag-ui-muted: #8b949e;
101
+ --ag-ui-font: var(--ag-ui-code-font);
102
+ --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
103
+ }
104
+
105
+ /* ── Density ────────────────────────────────────────────────────────────── */
106
+ :host([density="compact"]) {
107
+ --ag-ui-font-size: 13px;
108
+ --ag-ui-space: 6px;
109
+ --ag-ui-pad: 10px;
110
+ --ag-ui-msg-pad: 5px 9px;
111
+ --ag-ui-msg-radius: 10px;
112
+ }
113
+
114
+ /* ── Placement presets ──────────────────────────────────────────────────── */
115
+ :host([placement="bottom-left"]) {
116
+ --ag-ui-inset: auto auto 24px 24px;
117
+ }
118
+
119
+ :host([placement="side"]) {
120
+ --ag-ui-inset: 0 0 0 auto;
121
+ --ag-ui-width: 420px;
122
+ --ag-ui-height: 100vh;
123
+ --ag-ui-max-height: 100vh;
124
+ --ag-ui-radius: 0;
125
+ }
126
+
127
+ :host([placement="full"]) {
128
+ --ag-ui-inset: 0;
129
+ --ag-ui-width: 100vw;
130
+ --ag-ui-height: 100vh;
131
+ --ag-ui-max-width: 100vw;
132
+ --ag-ui-max-height: 100vh;
133
+ --ag-ui-radius: 0;
134
+ }
135
+
136
+ /* Embedded: drop the floating chrome and the high z-index stacking context so
137
+ the widget lives in the host's own layout (fixes overlay/z-index clashes). */
138
+ :host([placement="embedded"]) {
139
+ --ag-ui-position: static;
140
+ --ag-ui-width: 100%;
141
+ --ag-ui-height: 100%;
142
+ --ag-ui-max-width: 100%;
143
+ --ag-ui-max-height: 100%;
144
+ --ag-ui-shadow: none;
145
+ --ag-ui-z-index: auto;
146
+ }
147
+
148
+ .chat {
149
+ position: relative;
150
+ display: flex;
151
+ flex-direction: column;
152
+ flex: 1;
153
+ min-height: 0;
154
+ background: var(--ag-ui-bg);
155
+ border: 1px solid var(--ag-ui-border);
156
+ border-radius: var(--ag-ui-radius);
157
+ box-shadow: var(--ag-ui-shadow);
158
+ overflow: hidden;
159
+ }
160
+
161
+ .header {
162
+ display: flex;
163
+ align-items: center;
164
+ justify-content: space-between;
165
+ gap: 8px;
166
+ padding: 10px 14px;
167
+ border-bottom: 1px solid var(--ag-ui-border);
168
+ background: var(--ag-ui-header-bg);
169
+ color: var(--ag-ui-header-fg);
170
+ }
171
+
172
+ .header-title {
173
+ font-weight: 600;
174
+ overflow: hidden;
175
+ text-overflow: ellipsis;
176
+ white-space: nowrap;
177
+ }
178
+
179
+ .header-controls {
180
+ display: flex;
181
+ gap: 2px;
182
+ flex: none;
183
+ }
184
+
185
+ .header-btn {
186
+ border: none;
187
+ background: transparent;
188
+ color: inherit;
189
+ font: inherit;
190
+ line-height: 1;
191
+ padding: 4px 7px;
192
+ border-radius: 6px;
193
+ cursor: pointer;
194
+ opacity: 0.85;
195
+ }
196
+
197
+ .header-btn:hover {
198
+ opacity: 1;
199
+ background: rgba(255, 255, 255, 0.18);
200
+ }
201
+
202
+ /* Collapsed: keep just the header bar — hide the whole body, and let the host
203
+ shrink to the header. (A host can also fully hide the element itself.) */
204
+ :host([collapsed]) {
205
+ height: auto;
206
+ max-height: none;
207
+ }
208
+
209
+ :host([collapsed]) .messages,
210
+ :host([collapsed]) .input-row,
211
+ :host([collapsed]) .skill-chips,
212
+ :host([collapsed]) .skill-palette,
213
+ :host([collapsed]) .skill-hint {
214
+ display: none;
215
+ }
216
+
217
+ /* Edge-docked placements pin top *and* bottom, which would otherwise keep the
218
+ panel full-height when collapsed; unpin the bottom so it shrinks to the
219
+ header. (Floating/bottom-left pin only the bottom, so they already shrink.) */
220
+ :host([collapsed][placement="side"]),
221
+ :host([collapsed][placement="full"]) {
222
+ bottom: auto;
223
+ }
224
+
225
+ .messages {
226
+ flex: 1;
227
+ overflow-y: auto;
228
+ padding: var(--ag-ui-pad);
229
+ display: flex;
230
+ flex-direction: column;
231
+ gap: var(--ag-ui-space);
232
+ }
233
+
234
+ .message {
235
+ max-width: 80%;
236
+ padding: var(--ag-ui-msg-pad);
237
+ border-radius: var(--ag-ui-msg-radius);
238
+ line-height: 1.4;
239
+ white-space: pre-wrap;
240
+ word-break: break-word;
241
+ }
242
+
243
+ /* ── Incoming-text animations (data-text-animation) ─────────────────────── */
244
+ :host([data-text-animation="fade"]) .message--assistant {
245
+ animation: ag-ui-msg-fade 0.25s ease both;
246
+ }
247
+
248
+ @keyframes ag-ui-msg-fade {
249
+ from { opacity: 0; transform: translateY(4px); }
250
+ to { opacity: 1; transform: none; }
251
+ }
252
+
253
+ .message--assistant .word {
254
+ animation: ag-ui-word-in 0.3s ease both;
255
+ animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);
256
+ }
257
+
258
+ @keyframes ag-ui-word-in {
259
+ from { opacity: 0; }
260
+ to { opacity: 1; }
261
+ }
262
+
263
+ @media (prefers-reduced-motion: reduce) {
264
+ :host([data-text-animation="fade"]) .message--assistant,
265
+ .message--assistant .word {
266
+ animation: none;
267
+ }
268
+ }
269
+
270
+ .message--user {
271
+ align-self: flex-end;
272
+ background: var(--ag-ui-user-bg);
273
+ color: var(--ag-ui-user-fg);
274
+ border-bottom-right-radius: 4px;
275
+ }
276
+
277
+ .message--assistant {
278
+ align-self: flex-start;
279
+ background: var(--ag-ui-assistant-bg);
280
+ border-bottom-left-radius: 4px;
281
+ /* Assistant bubbles hold rendered markdown/HTML, so collapse the source
282
+ whitespace the renderer leaves between block tags. */
283
+ white-space: normal;
284
+ }
285
+
286
+ /* Rendered-markdown elements inside an assistant bubble. */
287
+ .message--assistant > :first-child {
288
+ margin-top: 0;
289
+ }
290
+
291
+ .message--assistant > :last-child {
292
+ margin-bottom: 0;
293
+ }
294
+
295
+ .message--assistant p,
296
+ .message--assistant ul,
297
+ .message--assistant ol,
298
+ .message--assistant blockquote,
299
+ .message--assistant pre {
300
+ margin: 0.5em 0;
301
+ }
302
+
303
+ .message--assistant ul,
304
+ .message--assistant ol {
305
+ padding-left: 1.3em;
306
+ }
307
+
308
+ .message--assistant a {
309
+ color: var(--ag-ui-accent);
310
+ text-decoration: underline;
311
+ }
312
+
313
+ .message--assistant code {
314
+ font-family: ui-monospace, "SF Mono", Menlo, monospace;
315
+ font-size: 0.92em;
316
+ background: rgba(127, 127, 127, 0.16);
317
+ padding: 1px 4px;
318
+ border-radius: 4px;
319
+ }
320
+
321
+ .message--assistant pre {
322
+ padding: 8px 10px;
323
+ overflow: auto;
324
+ background: var(--ag-ui-bg);
325
+ border: 1px solid var(--ag-ui-border);
326
+ border-radius: 6px;
327
+ }
328
+
329
+ .message--assistant pre code {
330
+ background: none;
331
+ padding: 0;
332
+ }
333
+
334
+ .message--assistant blockquote {
335
+ padding-left: 10px;
336
+ border-left: 3px solid var(--ag-ui-border);
337
+ color: var(--ag-ui-muted);
338
+ }
339
+
340
+ .pending {
341
+ align-self: flex-start;
342
+ display: inline-flex;
343
+ gap: 4px;
344
+ align-items: center;
345
+ padding: 12px 14px;
346
+ background: var(--ag-ui-assistant-bg);
347
+ border-radius: 14px;
348
+ border-bottom-left-radius: 4px;
349
+ }
350
+
351
+ .pending-dot {
352
+ width: 6px;
353
+ height: 6px;
354
+ border-radius: 50%;
355
+ background: var(--ag-ui-muted);
356
+ animation: ag-ui-pending 1.2s infinite ease-in-out both;
357
+ }
358
+
359
+ .pending-dot:nth-child(2) {
360
+ animation-delay: 0.16s;
361
+ }
362
+
363
+ .pending-dot:nth-child(3) {
364
+ animation-delay: 0.32s;
365
+ }
366
+
367
+ @keyframes ag-ui-pending {
368
+ 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
369
+ 40% { opacity: 1; transform: translateY(-3px); }
370
+ }
371
+
372
+ @media (prefers-reduced-motion: reduce) {
373
+ .pending-dot {
374
+ animation: none;
375
+ opacity: 0.6;
376
+ }
377
+ }
378
+
379
+ .tool-call {
380
+ align-self: flex-start;
381
+ max-width: 80%;
382
+ box-sizing: border-box;
383
+ display: flex;
384
+ flex-direction: column;
385
+ gap: 6px;
386
+ font-size: 12px;
387
+ font-family: ui-monospace, "SF Mono", Menlo, monospace;
388
+ padding: 8px 10px;
389
+ border-radius: 8px;
390
+ background: var(--ag-ui-tool-bg);
391
+ border: 1px solid var(--ag-ui-border);
392
+ color: var(--ag-ui-tool-fg);
393
+ }
394
+
395
+ .tool-call-head {
396
+ display: flex;
397
+ align-items: center;
398
+ justify-content: space-between;
399
+ gap: 8px;
400
+ }
401
+
402
+ .tool-call-name {
403
+ font-weight: 600;
404
+ word-break: break-word;
405
+ }
406
+
407
+ .tool-call-status {
408
+ flex: none;
409
+ padding: 1px 8px;
410
+ border-radius: 999px;
411
+ font-size: 11px;
412
+ font-weight: 600;
413
+ background: rgba(127, 127, 127, 0.16);
414
+ color: var(--ag-ui-muted);
415
+ }
416
+
417
+ .tool-call[data-status="done"] .tool-call-status {
418
+ color: var(--ag-ui-success);
419
+ }
420
+
421
+ .tool-call[data-status="error"] .tool-call-status {
422
+ color: var(--ag-ui-danger);
423
+ }
424
+
425
+ .tool-call[data-status="declined"] .tool-call-status {
426
+ color: var(--ag-ui-muted);
427
+ }
428
+
429
+ .tool-call-args,
430
+ .tool-call-result {
431
+ margin: 0;
432
+ padding: 6px 8px;
433
+ max-height: 160px;
434
+ overflow: auto;
435
+ background: var(--ag-ui-bg);
436
+ border: 1px solid var(--ag-ui-border);
437
+ border-radius: 6px;
438
+ white-space: pre-wrap;
439
+ word-break: break-word;
440
+ color: var(--ag-ui-fg);
441
+ }
442
+
443
+ .tool-call-toggle {
444
+ align-self: flex-start;
445
+ border: none;
446
+ padding: 0;
447
+ background: none;
448
+ font: inherit;
449
+ font-weight: 600;
450
+ color: var(--ag-ui-accent);
451
+ cursor: pointer;
452
+ }
453
+
454
+ .tool-call-toggle::before {
455
+ content: "▸ ";
456
+ }
457
+
458
+ .tool-call-toggle[aria-expanded="true"]::before {
459
+ content: "▾ ";
460
+ }
461
+
462
+ .input-row {
463
+ display: flex;
464
+ gap: 8px;
465
+ padding: 12px;
466
+ border-top: 1px solid var(--ag-ui-border);
467
+ }
468
+
469
+ .input {
470
+ flex: 1;
471
+ resize: none;
472
+ background: var(--ag-ui-input-bg);
473
+ border: 1px solid var(--ag-ui-border);
474
+ border-radius: 8px;
475
+ padding: 8px 10px;
476
+ font: inherit;
477
+ color: inherit;
478
+ outline: none;
479
+ }
480
+
481
+ .input:focus {
482
+ border-color: var(--ag-ui-accent);
483
+ }
484
+
485
+ .send {
486
+ border: none;
487
+ border-radius: 8px;
488
+ padding: 0 16px;
489
+ background: var(--ag-ui-accent);
490
+ color: #ffffff;
491
+ font: inherit;
492
+ font-weight: 600;
493
+ cursor: pointer;
494
+ }
495
+
496
+ .send:disabled {
497
+ opacity: 0.5;
498
+ cursor: default;
499
+ }
500
+
501
+ /* Inline confirmation card — lives in the transcript, no focus-stealing overlay. */
502
+ .confirm {
503
+ align-self: stretch;
504
+ box-sizing: border-box;
505
+ display: flex;
506
+ flex-direction: column;
507
+ gap: 8px;
508
+ padding: 12px;
509
+ background: var(--ag-ui-bg);
510
+ border: 1px solid var(--ag-ui-accent);
511
+ border-radius: 10px;
512
+ }
513
+
514
+ .confirm[data-resolved] {
515
+ opacity: 0.7;
516
+ border-color: var(--ag-ui-border);
517
+ }
518
+
519
+ .confirm-body {
520
+ font-weight: 600;
521
+ }
522
+
523
+ .confirm-args {
524
+ margin: 0;
525
+ padding: 8px 10px;
526
+ max-height: 140px;
527
+ overflow: auto;
528
+ font-size: 12px;
529
+ font-family: ui-monospace, "SF Mono", Menlo, monospace;
530
+ background: var(--ag-ui-assistant-bg);
531
+ border-radius: 8px;
532
+ white-space: pre-wrap;
533
+ word-break: break-word;
534
+ }
535
+
536
+ .confirm-actions {
537
+ display: flex;
538
+ gap: 8px;
539
+ justify-content: flex-end;
540
+ }
541
+
542
+ .confirm-btn {
543
+ border: 1px solid var(--ag-ui-border);
544
+ border-radius: 8px;
545
+ padding: 8px 14px;
546
+ font: inherit;
547
+ font-weight: 600;
548
+ cursor: pointer;
549
+ background: var(--ag-ui-bg);
550
+ color: var(--ag-ui-fg);
551
+ }
552
+
553
+ .confirm-btn:disabled {
554
+ cursor: default;
555
+ opacity: 0.6;
556
+ }
557
+
558
+ .confirm-btn--confirm {
559
+ border-color: var(--ag-ui-accent);
560
+ background: var(--ag-ui-accent);
561
+ color: #ffffff;
562
+ }
563
+
564
+ /* Skills — chips row + the /-command palette, above the input. */
565
+ .skill-chips {
566
+ display: flex;
567
+ flex-wrap: wrap;
568
+ gap: 6px;
569
+ padding: 10px 12px;
570
+ }
571
+
572
+ .skill-chip {
573
+ border: 1px solid var(--ag-ui-border);
574
+ border-radius: 999px;
575
+ padding: 4px 12px;
576
+ font: inherit;
577
+ font-size: 0.9em;
578
+ cursor: pointer;
579
+ background: var(--ag-ui-assistant-bg);
580
+ color: var(--ag-ui-fg);
581
+ }
582
+
583
+ .skill-chip:hover {
584
+ border-color: var(--ag-ui-accent);
585
+ }
586
+
587
+ .skill-palette {
588
+ margin: 8px 12px 0;
589
+ display: flex;
590
+ flex-direction: column;
591
+ max-height: 220px;
592
+ overflow: auto;
593
+ background: var(--ag-ui-bg);
594
+ border: 1px solid var(--ag-ui-border);
595
+ border-radius: 8px;
596
+ box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);
597
+ }
598
+
599
+ .skill-item {
600
+ display: flex;
601
+ flex-direction: column;
602
+ gap: 2px;
603
+ align-items: flex-start;
604
+ padding: 8px 12px;
605
+ border: none;
606
+ background: none;
607
+ font: inherit;
608
+ text-align: left;
609
+ cursor: pointer;
610
+ color: var(--ag-ui-fg);
611
+ }
612
+
613
+ .skill-item[aria-selected="true"] {
614
+ background: var(--ag-ui-assistant-bg);
615
+ }
616
+
617
+ .skill-item-title {
618
+ font-weight: 600;
619
+ }
620
+
621
+ .skill-item-desc {
622
+ font-size: 0.85em;
623
+ color: var(--ag-ui-muted);
624
+ }
625
+
626
+ .skill-hint {
627
+ margin: 8px 12px 0;
628
+ font-size: 0.85em;
629
+ color: var(--ag-ui-danger);
630
+ }
631
+ `;