@jcy2387/dsh-conversation-ui 0.1.0-rc.12
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.
- package/LICENSE +21 -0
- package/README.en.md +123 -0
- package/README.md +123 -0
- package/conversation-ui-off.yml +3 -0
- package/cordis.patch.yml +10 -0
- package/lib/client.js +3672 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +302 -0
- package/package.json +182 -0
- package/src/boot-config.ts +28 -0
- package/src/client/AnimatedDisclosure.tsx +89 -0
- package/src/client/ConversationCard.module.css +253 -0
- package/src/client/ConversationCard.tsx +122 -0
- package/src/client/DeliverablesCard.module.css +187 -0
- package/src/client/DeliverablesCard.tsx +142 -0
- package/src/client/FollowHost.tsx +25 -0
- package/src/client/ToolActivityGroup.tsx +341 -0
- package/src/client/TurnPreludeUserNodeView.tsx +258 -0
- package/src/client/TurnProcessMember.tsx +92 -0
- package/src/client/TypewriterAssistantNodeView.module.css +1260 -0
- package/src/client/TypewriterAssistantNodeView.tsx +390 -0
- package/src/client/TypewriterToolNodeView.tsx +916 -0
- package/src/client/conversation-ui-card-controller.ts +162 -0
- package/src/client/conversation-ui-settings-api.ts +65 -0
- package/src/client/deliverables.ts +263 -0
- package/src/client/index.ts +242 -0
- package/src/client/locales.ts +74 -0
- package/src/client/teleprompterGlide.ts +590 -0
- package/src/client/turnElapsed.ts +27 -0
- package/src/client/turnProcessFold.ts +224 -0
- package/src/client/useConversationContent.ts +471 -0
- package/src/client/useFpsGuard.ts +84 -0
- package/src/config.ts +44 -0
- package/src/css-modules.d.ts +9 -0
- package/src/index.ts +2 -0
- package/src/package-meta.ts +39 -0
- package/src/plugin.ts +155 -0
- package/src/profile-installation.ts +121 -0
- package/src/settings-api.ts +33 -0
- package/src/settings.ts +30 -0
|
@@ -0,0 +1,1260 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
min-width: 0;
|
|
5
|
+
color: var(--dsw-alias-label-primary);
|
|
6
|
+
font-size: 16px;
|
|
7
|
+
line-height: 28px;
|
|
8
|
+
animation: dsh-codex-stream-enter 140ms ease-out both;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.body {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 16px;
|
|
15
|
+
min-width: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.markdownFlow {
|
|
19
|
+
min-width: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Final-answer code blocks keep their source lines intact and scroll
|
|
23
|
+
* horizontally instead of breaking paths/commands at arbitrary characters.
|
|
24
|
+
* The bounded viewport prevents a long log from pushing the answer away. */
|
|
25
|
+
.root .markdownFlow :global(pre) {
|
|
26
|
+
max-height: min(60vh, 480px);
|
|
27
|
+
overflow: auto;
|
|
28
|
+
overflow-wrap: normal;
|
|
29
|
+
white-space: pre;
|
|
30
|
+
word-break: normal;
|
|
31
|
+
tab-size: 2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.root .markdownFlow :global(pre) :global(code) {
|
|
35
|
+
white-space: inherit;
|
|
36
|
+
word-break: inherit;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* MarkdownText owns spacing within one assistant text block. Its default
|
|
40
|
+
* adjacent 16px margins collapse, which leaves a paragraph visually attached
|
|
41
|
+
* to the final row of a long path list. Keep this boundary at one readable
|
|
42
|
+
* text-line rhythm without changing list nesting or other block pairs. */
|
|
43
|
+
.markdownFlow > div > :where(ul, ol) + p {
|
|
44
|
+
margin-block-start: 24px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Codex keeps progress prose and the final answer in one calm document flow.
|
|
48
|
+
* Phase attributes preserve their different semantics without adding chat
|
|
49
|
+
* bubbles or labels that would compete with the answer itself. */
|
|
50
|
+
.root[data-stream-phase='streaming'],
|
|
51
|
+
.root[data-stream-phase='process'] {
|
|
52
|
+
color: var(--dsw-alias-label-primary);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Progress prose is not the final answer: keep its Markdown root at the same
|
|
56
|
+
* size as ordinary assistant text, while emphasis does not make a status
|
|
57
|
+
* sentence look heavier than the surrounding streamed text. */
|
|
58
|
+
.root[data-stream-phase='streaming'] .markdownFlow > :global(div),
|
|
59
|
+
.root[data-stream-phase='process'] .markdownFlow > :global(div) {
|
|
60
|
+
font-family: inherit;
|
|
61
|
+
font-size: 16px;
|
|
62
|
+
font-weight: 400;
|
|
63
|
+
line-height: 28px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.root[data-stream-phase='streaming'] .markdownFlow :global(strong),
|
|
67
|
+
.root[data-stream-phase='process'] .markdownFlow :global(strong) {
|
|
68
|
+
/* MarkdownText's own `.markdown strong` rule is equally specific and can
|
|
69
|
+
* win when its stylesheet is injected after this module. Think/process
|
|
70
|
+
* emphasis is intentionally quiet, so make that contract order-independent. */
|
|
71
|
+
font-weight: 400 !important;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.root[data-stream-phase='final'] {
|
|
75
|
+
margin-block-start: 2px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.turnFoldRow {
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
align-items: stretch;
|
|
82
|
+
gap: 6px;
|
|
83
|
+
margin-block: 0 14px;
|
|
84
|
+
color: var(--dsw-alias-label-secondary);
|
|
85
|
+
font-size: 14px;
|
|
86
|
+
line-height: 24px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.turnPrelude {
|
|
90
|
+
margin-block-start: 16px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.turnWaiting {
|
|
94
|
+
width: fit-content;
|
|
95
|
+
margin-block-start: 0;
|
|
96
|
+
background: linear-gradient(
|
|
97
|
+
105deg,
|
|
98
|
+
var(--dsw-alias-label-tertiary) 15%,
|
|
99
|
+
var(--dsw-alias-label-primary) 42%,
|
|
100
|
+
var(--dsw-alias-label-tertiary) 68%
|
|
101
|
+
);
|
|
102
|
+
background-clip: text;
|
|
103
|
+
background-size: 220% 100%;
|
|
104
|
+
color: transparent;
|
|
105
|
+
font-size: 14px;
|
|
106
|
+
line-height: 24px;
|
|
107
|
+
animation: dsh-turn-waiting-shimmer 1.8s linear infinite;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@keyframes dsh-turn-waiting-shimmer {
|
|
111
|
+
from { background-position: 130% 0; }
|
|
112
|
+
to { background-position: -90% 0; }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Light Stream owns the immediate Turn status. The native direct-child
|
|
116
|
+
* placeholder would otherwise duplicate the waiting signal at the flow tip. */
|
|
117
|
+
:global([data-chat-flow] > [role='status']) {
|
|
118
|
+
display: none !important;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.turnFoldRow::after {
|
|
122
|
+
width: 100%;
|
|
123
|
+
height: 1px;
|
|
124
|
+
flex: none;
|
|
125
|
+
background: var(--dsw-alias-border-l2);
|
|
126
|
+
content: '';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.turnFoldButton,
|
|
130
|
+
.turnFoldLabel {
|
|
131
|
+
display: inline-flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
align-self: flex-start;
|
|
134
|
+
gap: 6px;
|
|
135
|
+
flex: none;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.turnFoldButton {
|
|
139
|
+
padding: 2px 0;
|
|
140
|
+
border: 0;
|
|
141
|
+
border-radius: 4px;
|
|
142
|
+
background: transparent;
|
|
143
|
+
color: inherit;
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
font: inherit;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.turnFoldButton:hover {
|
|
149
|
+
color: var(--dsw-alias-label-primary);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.turnFoldButton:focus-visible {
|
|
153
|
+
outline: 2px solid var(--dsw-alias-border-l3);
|
|
154
|
+
outline-offset: 3px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.turnFoldButton > svg {
|
|
158
|
+
flex: none;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Author-level display rules on Assistant and Tool rows override the browser's
|
|
162
|
+
* built-in `[hidden]` stylesheet. Keep every registered process member truly
|
|
163
|
+
* out of layout while its Turn is collapsed. */
|
|
164
|
+
[data-turn-process][hidden] {
|
|
165
|
+
display: none !important;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* ChatView keeps each flat node in its own flow row. Hiding only the inner
|
|
169
|
+
* process member would leave the parent row-gap behind, producing a large
|
|
170
|
+
* blank band. Preserve the boundary row and the mixed final-answer row, but
|
|
171
|
+
* remove every other collapsed process anchor from layout. */
|
|
172
|
+
:global([data-chat-anchor-key]:has([data-turn-process][hidden]):not(:has([data-turn-fold-row])):not(:has([data-stream-phase='final'])):not(:has([data-stream-tool-group-frame]))) {
|
|
173
|
+
display: none !important;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Portaled members live inside the first row's group frame. Remove their empty
|
|
177
|
+
* original Chat anchors so the host row-gap cannot leave phantom bands. */
|
|
178
|
+
:global([data-chat-anchor-key]:has([data-tool-group-proxy])) {
|
|
179
|
+
display: none !important;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* A collapsed Turn still removes the group host itself; a collapsed activity
|
|
183
|
+
* group keeps its heading and only removes the command rows below it. */
|
|
184
|
+
:global([data-chat-anchor-key]:has([data-stream-tool-group-anchor][hidden])) {
|
|
185
|
+
display: none !important;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.root[data-stream-phase='interrupted'] {
|
|
189
|
+
color: var(--dsw-alias-label-secondary);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* Every non-human Chat Node becomes one compact event row. Tool renderers
|
|
193
|
+
* keep their own icons, titles, summaries, and disclosure bodies; this layer
|
|
194
|
+
* only supplies the shared Codex timeline rhythm and entry transition. */
|
|
195
|
+
.eventRow {
|
|
196
|
+
min-width: 0;
|
|
197
|
+
color: var(--dsw-alias-label-secondary);
|
|
198
|
+
font-size: 14px;
|
|
199
|
+
line-height: 24px;
|
|
200
|
+
animation: dsh-codex-stream-enter 140ms ease-out both;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.eventRow[data-stream-node='tool-call'],
|
|
204
|
+
.eventRow[data-stream-node='workflow-run'],
|
|
205
|
+
.eventRow[data-stream-node='model-retry'],
|
|
206
|
+
.eventRow[data-stream-node='compaction'],
|
|
207
|
+
.eventRow[data-stream-node='manual-compaction'] {
|
|
208
|
+
margin-block: 2px;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.eventRow[data-stream-state='running'] {
|
|
212
|
+
color: var(--dsw-alias-label-tertiary);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Context compaction is a status marker, not a second disclosure surface.
|
|
216
|
+
* Keep the native icon/title/summary but remove the meaningless chevron and
|
|
217
|
+
* let the wrapper's click capture keep the row non-expandable. */
|
|
218
|
+
.eventRow[data-stream-node='compaction'] [data-compaction-disclosure],
|
|
219
|
+
.eventRow[data-stream-node='manual-compaction'] [data-compaction-disclosure] {
|
|
220
|
+
display: none !important;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.eventRow[data-stream-node='compaction'] :global(button:has([data-compaction-icon])),
|
|
224
|
+
.eventRow[data-stream-node='manual-compaction'] :global(button:has([data-compaction-icon])) {
|
|
225
|
+
cursor: default;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.eventRow[data-stream-node='compaction'] :global(button:has([data-compaction-icon])):hover,
|
|
229
|
+
.eventRow[data-stream-node='compaction'] :global(button:has([data-compaction-icon])):focus-visible,
|
|
230
|
+
.eventRow[data-stream-node='manual-compaction'] :global(button:has([data-compaction-icon])):hover,
|
|
231
|
+
.eventRow[data-stream-node='manual-compaction'] :global(button:has([data-compaction-icon])):focus-visible {
|
|
232
|
+
background: transparent !important;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.eventRow[data-stream-node='compaction'] [data-compaction-icon],
|
|
236
|
+
.eventRow[data-stream-node='manual-compaction'] [data-compaction-icon] {
|
|
237
|
+
color: var(--dsw-alias-label-secondary) !important;
|
|
238
|
+
opacity: 1 !important;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.eventRow[data-stream-node='compaction'] :global(button:has([data-compaction-icon])),
|
|
242
|
+
.eventRow[data-stream-node='manual-compaction'] :global(button:has([data-compaction-icon])) {
|
|
243
|
+
color: var(--dsw-alias-label-secondary) !important;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.eventRow[data-stream-node='compaction'] :global(button:has([data-compaction-icon])) > span,
|
|
247
|
+
.eventRow[data-stream-node='manual-compaction'] :global(button:has([data-compaction-icon])) > span {
|
|
248
|
+
color: var(--dsw-alias-label-secondary) !important;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* The native compaction node can be mounted outside the overlay wrapper in
|
|
252
|
+
* paged/history surfaces. Match its unique data marker directly as well, so
|
|
253
|
+
* its title and summary use the same tone as the context-injection row. */
|
|
254
|
+
:global(button:has([data-compaction-icon])),
|
|
255
|
+
:global(button:has([data-compaction-icon])) > span {
|
|
256
|
+
color: var(--dsw-alias-label-secondary) !important;
|
|
257
|
+
opacity: 1 !important;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* Consecutive same-kind tools are mounted into one shared activity frame. The
|
|
261
|
+
* frame owns one heading and one disclosure affordance; its members retain the
|
|
262
|
+
* native Harness Tool rows so command/file details remain independently useful. */
|
|
263
|
+
.toolGroupAnchor {
|
|
264
|
+
min-width: 0;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.toolGroupFrame {
|
|
268
|
+
min-width: 0;
|
|
269
|
+
margin-block: 2px 8px;
|
|
270
|
+
overflow: hidden;
|
|
271
|
+
background: transparent;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.toolGroupHeader {
|
|
275
|
+
position: relative;
|
|
276
|
+
display: flex;
|
|
277
|
+
width: 100%;
|
|
278
|
+
min-height: 28px;
|
|
279
|
+
align-items: center;
|
|
280
|
+
gap: 6px;
|
|
281
|
+
padding: 2px 8px 2px 22px;
|
|
282
|
+
border: 0;
|
|
283
|
+
background: transparent;
|
|
284
|
+
color: var(--dsw-alias-label-secondary);
|
|
285
|
+
cursor: pointer;
|
|
286
|
+
font: inherit;
|
|
287
|
+
font-size: 14px;
|
|
288
|
+
line-height: 24px;
|
|
289
|
+
text-align: start;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.toolGroupHeader:hover {
|
|
293
|
+
color: var(--dsw-alias-label-primary);
|
|
294
|
+
background: transparent;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.toolGroupHeader:focus-visible {
|
|
298
|
+
outline: none;
|
|
299
|
+
background: transparent;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.toolGroupHeaderIcon {
|
|
303
|
+
position: absolute;
|
|
304
|
+
inset-block-start: 50%;
|
|
305
|
+
inset-inline-start: 0;
|
|
306
|
+
display: inline-flex;
|
|
307
|
+
transform: translateY(-50%);
|
|
308
|
+
width: 14px;
|
|
309
|
+
height: 14px;
|
|
310
|
+
align-items: center;
|
|
311
|
+
justify-content: center;
|
|
312
|
+
flex: none;
|
|
313
|
+
color: var(--dsw-alias-label-tertiary);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.toolGroupHeaderGlyph {
|
|
317
|
+
display: inline-flex;
|
|
318
|
+
width: 14px;
|
|
319
|
+
height: 14px;
|
|
320
|
+
align-items: center;
|
|
321
|
+
justify-content: center;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.toolGroupHeaderLabel {
|
|
325
|
+
min-width: 0;
|
|
326
|
+
overflow: hidden;
|
|
327
|
+
text-overflow: ellipsis;
|
|
328
|
+
white-space: nowrap;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.toolGroupHeaderChevron {
|
|
332
|
+
display: inline-flex;
|
|
333
|
+
margin-inline-start: 0;
|
|
334
|
+
flex: none;
|
|
335
|
+
color: var(--dsw-alias-label-tertiary);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.editStats {
|
|
339
|
+
flex: none;
|
|
340
|
+
margin-inline-start: 4px;
|
|
341
|
+
color: var(--dsw-alias-label-tertiary);
|
|
342
|
+
font-size: 14px;
|
|
343
|
+
line-height: 24px;
|
|
344
|
+
white-space: nowrap;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.toolGroupFrame > .eventRow[data-stream-tool-group-member],
|
|
348
|
+
.toolGroupFrame > [data-tool-group-member] > .eventRow[data-stream-tool-group-member] {
|
|
349
|
+
margin-block: 0;
|
|
350
|
+
padding-inline: 8px 6px;
|
|
351
|
+
border: 0;
|
|
352
|
+
border-radius: 0;
|
|
353
|
+
background: transparent;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.toolGroupFrame .toolSemanticIcon,
|
|
357
|
+
.toolGroupFrame .streamSemanticIcon {
|
|
358
|
+
/* An expanded Bash row grows with its terminal output. Keep the semantic
|
|
359
|
+
* glyph anchored to the row header instead of centering it in the whole
|
|
360
|
+
* expanded card. */
|
|
361
|
+
inset-block-start: 4px;
|
|
362
|
+
transform: none;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
366
|
+
> .eventRow[data-stream-tool-group-member] > :global([data-chat-call-id]),
|
|
367
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
368
|
+
> .eventRow[data-stream-tool-group-member] > * > :global([data-sample='bash']),
|
|
369
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
370
|
+
> [data-tool-group-member] > .eventRow[data-stream-tool-group-member] > :global([data-chat-call-id]),
|
|
371
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
372
|
+
> [data-tool-group-member] > .eventRow[data-stream-tool-group-member] > * > :global([data-sample='bash']) {
|
|
373
|
+
display: none !important;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
377
|
+
> .eventRow[data-stream-tool-group-member] > .toolSemanticIcon,
|
|
378
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
379
|
+
> [data-tool-group-member] > .eventRow[data-stream-tool-group-member] > .toolSemanticIcon {
|
|
380
|
+
display: none;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
384
|
+
> .eventRow[data-stream-tool-group-member] > :not(.toolSemanticIcon):not(.streamSemanticIcon),
|
|
385
|
+
.toolGroupFrame[data-stream-tool-group-collapsed]
|
|
386
|
+
> [data-tool-group-member] > .eventRow[data-stream-tool-group-member] > :not(.toolSemanticIcon):not(.streamSemanticIcon) {
|
|
387
|
+
display: none !important;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.eventRow :global([data-disclosure-row]) {
|
|
391
|
+
min-width: 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* Codex-style Tool chrome: the semantic glyph is a stable leading landmark;
|
|
395
|
+
* disclosure state is a separate trailing affordance. The Harness ToolRow
|
|
396
|
+
* still owns click/keyboard state and the expanded body—we only rearrange its
|
|
397
|
+
* existing header geometry inside the root call. */
|
|
398
|
+
.eventRow[data-stream-tool-row] {
|
|
399
|
+
position: relative;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* A Tool remains the visible activity handoff after its result arrives and
|
|
403
|
+
* until the Agent publishes the next row. Sweep only the root header so an
|
|
404
|
+
* expanded result card is never washed by the progress treatment. */
|
|
405
|
+
.eventRow[data-stream-tool-row][data-stream-progress='active']
|
|
406
|
+
> :global([data-chat-call-id])
|
|
407
|
+
> :global([data-slot='tool.call.toolview'])
|
|
408
|
+
> :global([data-tool])
|
|
409
|
+
> *
|
|
410
|
+
> :global([data-disclosure-row]),
|
|
411
|
+
.eventRow[data-stream-tool-row][data-stream-progress='active']
|
|
412
|
+
> :global([data-chat-call-id])
|
|
413
|
+
> :global([data-slot='tool.call.toolview'])
|
|
414
|
+
> *
|
|
415
|
+
> :global([data-sample='bash']) {
|
|
416
|
+
position: relative;
|
|
417
|
+
overflow: hidden;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.eventRow[data-stream-tool-row][data-stream-progress='active']
|
|
421
|
+
> :global([data-chat-call-id])
|
|
422
|
+
> :global([data-slot='tool.call.toolview'])
|
|
423
|
+
> :global([data-tool])
|
|
424
|
+
> *
|
|
425
|
+
> :global([data-disclosure-row])::after,
|
|
426
|
+
.eventRow[data-stream-tool-row][data-stream-progress='active']
|
|
427
|
+
> :global([data-chat-call-id])
|
|
428
|
+
> :global([data-slot='tool.call.toolview'])
|
|
429
|
+
> *
|
|
430
|
+
> :global([data-sample='bash'])::after {
|
|
431
|
+
position: absolute;
|
|
432
|
+
inset-block: 0;
|
|
433
|
+
left: -300px;
|
|
434
|
+
width: 300px;
|
|
435
|
+
background: linear-gradient(
|
|
436
|
+
90deg,
|
|
437
|
+
transparent 0%,
|
|
438
|
+
color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%,
|
|
439
|
+
transparent 100%
|
|
440
|
+
);
|
|
441
|
+
animation: dsh-conversation-ui-think-sweep 2.6s ease-out infinite;
|
|
442
|
+
content: '';
|
|
443
|
+
pointer-events: none;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.toolSemanticIcon,
|
|
447
|
+
.streamSemanticIcon {
|
|
448
|
+
position: absolute;
|
|
449
|
+
z-index: 1;
|
|
450
|
+
inset-block-start: 4px;
|
|
451
|
+
inset-inline-start: 0;
|
|
452
|
+
display: inline-flex;
|
|
453
|
+
width: 14px;
|
|
454
|
+
height: 14px;
|
|
455
|
+
align-items: center;
|
|
456
|
+
justify-content: center;
|
|
457
|
+
color: var(--dsw-alias-label-tertiary);
|
|
458
|
+
pointer-events: none;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* Harness-native rows (context injection, compaction, retry, and future
|
|
462
|
+
* disclosure-backed nodes) keep their semantic glyph leading while the
|
|
463
|
+
* disclosure affordance is always the final flex item. The core DisclosureRow
|
|
464
|
+
* swaps its leading icon for a chevron when open; an owned semantic overlay
|
|
465
|
+
* keeps context rows stable in both states. */
|
|
466
|
+
.eventRow[data-stream-semantic-icon-owned] {
|
|
467
|
+
position: relative;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.eventRow[data-stream-native-disclosure]
|
|
471
|
+
> :not(.streamSemanticIcon)
|
|
472
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
473
|
+
> :first-child {
|
|
474
|
+
display: contents;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.eventRow[data-stream-native-disclosure]
|
|
478
|
+
> :not(.streamSemanticIcon)
|
|
479
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
480
|
+
> :first-child
|
|
481
|
+
> :first-child:not(:last-child) {
|
|
482
|
+
opacity: 1;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.eventRow[data-stream-semantic-icon-owned]
|
|
486
|
+
> :not(.streamSemanticIcon)
|
|
487
|
+
> :global([data-disclosure-row])[aria-expanded] {
|
|
488
|
+
padding-inline-start: 22px;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.eventRow[data-stream-semantic-icon-owned]
|
|
492
|
+
> :not(.streamSemanticIcon)
|
|
493
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
494
|
+
> :first-child
|
|
495
|
+
> :first-child:not(:last-child) {
|
|
496
|
+
display: none;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.eventRow[data-stream-native-disclosure]
|
|
500
|
+
> :not(.streamSemanticIcon)
|
|
501
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
502
|
+
> :first-child
|
|
503
|
+
> svg {
|
|
504
|
+
position: static;
|
|
505
|
+
order: 4;
|
|
506
|
+
flex: none;
|
|
507
|
+
margin: 0 0 0 6px;
|
|
508
|
+
opacity: 0;
|
|
509
|
+
color: var(--dsw-alias-label-secondary);
|
|
510
|
+
transition: opacity 100ms ease, transform 120ms ease;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.eventRow[data-stream-native-disclosure]
|
|
514
|
+
> :not(.streamSemanticIcon)
|
|
515
|
+
> :global([data-disclosure-row])[aria-expanded]:hover
|
|
516
|
+
> :first-child
|
|
517
|
+
> svg,
|
|
518
|
+
.eventRow[data-stream-native-disclosure]
|
|
519
|
+
> :not(.streamSemanticIcon)
|
|
520
|
+
> :global([data-disclosure-row])[aria-expanded]:focus-visible
|
|
521
|
+
> :first-child
|
|
522
|
+
> svg {
|
|
523
|
+
opacity: 1;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.eventRow[data-stream-native-disclosure]
|
|
527
|
+
> :not(.streamSemanticIcon)
|
|
528
|
+
> :global([data-disclosure-row])[aria-expanded='false']
|
|
529
|
+
> :first-child
|
|
530
|
+
> svg {
|
|
531
|
+
transform: rotate(-90deg);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.eventRow[data-stream-native-disclosure]
|
|
535
|
+
> :not(.streamSemanticIcon)
|
|
536
|
+
> :global([data-disclosure-row])[aria-expanded='true']
|
|
537
|
+
> :first-child
|
|
538
|
+
> svg {
|
|
539
|
+
transform: rotate(0deg);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/* Root ToolCallBranch -> ToolRow -> DisclosureRow -> header. Keeping the
|
|
543
|
+
* direct-child chain prevents a parent tool from restyling nested subcalls. */
|
|
544
|
+
.eventRow[data-stream-tool-row]
|
|
545
|
+
> :global([data-chat-call-id])
|
|
546
|
+
> :global([data-slot='tool.call.toolview'])
|
|
547
|
+
> :global([data-tool])
|
|
548
|
+
> *
|
|
549
|
+
> :global([data-disclosure-row]) {
|
|
550
|
+
padding-inline-start: 22px;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/* A non-expandable row needs no disclosure control; its original leading
|
|
554
|
+
* glyph is hidden because the semantic overlay above now owns that position. */
|
|
555
|
+
.eventRow[data-stream-tool-row]
|
|
556
|
+
> :global([data-chat-call-id])
|
|
557
|
+
> :global([data-slot='tool.call.toolview'])
|
|
558
|
+
> :global([data-tool])
|
|
559
|
+
> *
|
|
560
|
+
> :global([data-disclosure-row]):not([aria-expanded])
|
|
561
|
+
> :first-child {
|
|
562
|
+
display: none;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/* For expandable rows, flatten the old leading slot into the header. Its
|
|
566
|
+
* first child is the hover-only idle icon; the last svg is the real Harness
|
|
567
|
+
* chevron, which moves behind title/summary as layout order 4. */
|
|
568
|
+
.eventRow[data-stream-tool-row]
|
|
569
|
+
> :global([data-chat-call-id])
|
|
570
|
+
> :global([data-slot='tool.call.toolview'])
|
|
571
|
+
> :global([data-tool])
|
|
572
|
+
> *
|
|
573
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
574
|
+
> :first-child {
|
|
575
|
+
display: contents;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.eventRow[data-stream-tool-row]
|
|
579
|
+
> :global([data-chat-call-id])
|
|
580
|
+
> :global([data-slot='tool.call.toolview'])
|
|
581
|
+
> :global([data-tool])
|
|
582
|
+
> *
|
|
583
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
584
|
+
> :first-child
|
|
585
|
+
> :first-child:not(:last-child) {
|
|
586
|
+
display: none;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.eventRow[data-stream-tool-row]
|
|
590
|
+
> :global([data-chat-call-id])
|
|
591
|
+
> :global([data-slot='tool.call.toolview'])
|
|
592
|
+
> :global([data-tool])
|
|
593
|
+
> *
|
|
594
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
595
|
+
> :nth-child(n + 3) {
|
|
596
|
+
flex-grow: 0;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
.eventRow[data-stream-tool-row]
|
|
600
|
+
> :global([data-chat-call-id])
|
|
601
|
+
> :global([data-slot='tool.call.toolview'])
|
|
602
|
+
> :global([data-tool])
|
|
603
|
+
> *
|
|
604
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
605
|
+
> :first-child
|
|
606
|
+
> svg {
|
|
607
|
+
position: static;
|
|
608
|
+
order: 4;
|
|
609
|
+
flex: none;
|
|
610
|
+
margin: 0 0 0 6px;
|
|
611
|
+
opacity: 0;
|
|
612
|
+
color: var(--dsw-alias-label-secondary);
|
|
613
|
+
transition: opacity 100ms ease, transform 120ms ease;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.eventRow[data-stream-tool-row]
|
|
617
|
+
> :global([data-chat-call-id])
|
|
618
|
+
> :global([data-slot='tool.call.toolview'])
|
|
619
|
+
> :global([data-tool])
|
|
620
|
+
> *
|
|
621
|
+
> :global([data-disclosure-row])[aria-expanded]:hover
|
|
622
|
+
> :first-child
|
|
623
|
+
> svg,
|
|
624
|
+
.eventRow[data-stream-tool-row]
|
|
625
|
+
> :global([data-chat-call-id])
|
|
626
|
+
> :global([data-slot='tool.call.toolview'])
|
|
627
|
+
> :global([data-tool])
|
|
628
|
+
> *
|
|
629
|
+
> :global([data-disclosure-row])[aria-expanded]:focus-visible
|
|
630
|
+
> :first-child
|
|
631
|
+
> svg {
|
|
632
|
+
opacity: 1;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
.eventRow[data-stream-tool-row]
|
|
636
|
+
> :global([data-chat-call-id])
|
|
637
|
+
> :global([data-slot='tool.call.toolview'])
|
|
638
|
+
> :global([data-tool])
|
|
639
|
+
> *
|
|
640
|
+
> :global([data-disclosure-row])[aria-expanded='false']
|
|
641
|
+
> :first-child
|
|
642
|
+
> svg {
|
|
643
|
+
transform: rotate(-90deg);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.eventRow[data-stream-tool-row]
|
|
647
|
+
> :global([data-chat-call-id])
|
|
648
|
+
> :global([data-slot='tool.call.toolview'])
|
|
649
|
+
> :global([data-tool])
|
|
650
|
+
> *
|
|
651
|
+
> :global([data-disclosure-row])[aria-expanded='true']
|
|
652
|
+
> :first-child
|
|
653
|
+
> svg {
|
|
654
|
+
transform: rotate(0deg);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/* Bash is the one built-in Tool view that owns its disclosure row directly
|
|
658
|
+
* instead of composing ToolRow/DisclosureRow. Apply the same leading/trailing
|
|
659
|
+
* contract to that row without changing its terminal card implementation. */
|
|
660
|
+
.eventRow[data-stream-tool-row]
|
|
661
|
+
> :global([data-chat-call-id])
|
|
662
|
+
> :global([data-slot='tool.call.toolview'])
|
|
663
|
+
> *
|
|
664
|
+
> :global([data-sample='bash']) {
|
|
665
|
+
padding-inline-start: 22px;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.eventRow[data-stream-tool-row]
|
|
669
|
+
> :global([data-chat-call-id])
|
|
670
|
+
> :global([data-slot='tool.call.toolview'])
|
|
671
|
+
> *
|
|
672
|
+
> :global([data-sample='bash']):not([aria-expanded])
|
|
673
|
+
> :first-child {
|
|
674
|
+
display: none;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
.eventRow[data-stream-tool-row]
|
|
678
|
+
> :global([data-chat-call-id])
|
|
679
|
+
> :global([data-slot='tool.call.toolview'])
|
|
680
|
+
> *
|
|
681
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
682
|
+
> :first-child {
|
|
683
|
+
display: contents;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.eventRow[data-stream-tool-row]
|
|
687
|
+
> :global([data-chat-call-id])
|
|
688
|
+
> :global([data-slot='tool.call.toolview'])
|
|
689
|
+
> *
|
|
690
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
691
|
+
> :first-child
|
|
692
|
+
> :first-child:not(:last-child) {
|
|
693
|
+
display: none;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.eventRow[data-stream-tool-row]
|
|
697
|
+
> :global([data-chat-call-id])
|
|
698
|
+
> :global([data-slot='tool.call.toolview'])
|
|
699
|
+
> *
|
|
700
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
701
|
+
> :nth-child(n + 3) {
|
|
702
|
+
flex-grow: 0;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.eventRow[data-stream-tool-row]
|
|
706
|
+
> :global([data-chat-call-id])
|
|
707
|
+
> :global([data-slot='tool.call.toolview'])
|
|
708
|
+
> *
|
|
709
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
710
|
+
> :first-child
|
|
711
|
+
> svg {
|
|
712
|
+
position: static;
|
|
713
|
+
order: 4;
|
|
714
|
+
flex: none;
|
|
715
|
+
margin: 0 0 0 6px;
|
|
716
|
+
opacity: 0;
|
|
717
|
+
color: var(--dsw-alias-label-secondary);
|
|
718
|
+
transition: opacity 100ms ease, transform 120ms ease;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
.eventRow[data-stream-tool-row]
|
|
722
|
+
> :global([data-chat-call-id])
|
|
723
|
+
> :global([data-slot='tool.call.toolview'])
|
|
724
|
+
> *
|
|
725
|
+
> :global([data-sample='bash'])[aria-expanded]:hover
|
|
726
|
+
> :first-child
|
|
727
|
+
> svg,
|
|
728
|
+
.eventRow[data-stream-tool-row]
|
|
729
|
+
> :global([data-chat-call-id])
|
|
730
|
+
> :global([data-slot='tool.call.toolview'])
|
|
731
|
+
> *
|
|
732
|
+
> :global([data-sample='bash'])[aria-expanded]:focus-visible
|
|
733
|
+
> :first-child
|
|
734
|
+
> svg {
|
|
735
|
+
opacity: 1;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.eventRow[data-stream-tool-row]
|
|
739
|
+
> :global([data-chat-call-id])
|
|
740
|
+
> :global([data-slot='tool.call.toolview'])
|
|
741
|
+
> *
|
|
742
|
+
> :global([data-sample='bash'])[aria-expanded='false']
|
|
743
|
+
> :first-child
|
|
744
|
+
> svg {
|
|
745
|
+
transform: rotate(-90deg);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
.eventRow[data-stream-tool-row]
|
|
749
|
+
> :global([data-chat-call-id])
|
|
750
|
+
> :global([data-slot='tool.call.toolview'])
|
|
751
|
+
> *
|
|
752
|
+
> :global([data-sample='bash'])[aria-expanded='true']
|
|
753
|
+
> :first-child
|
|
754
|
+
> svg {
|
|
755
|
+
transform: rotate(0deg);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/* Nested ToolCallBranch rows live under the root call's `data-subcalls`
|
|
759
|
+
* container, so the root-only chain above deliberately cannot reach them.
|
|
760
|
+
* The plugin owns a stable semantic-icon portal in each nested header because
|
|
761
|
+
* Harness removes its native icon node when a DisclosureRow opens. */
|
|
762
|
+
.nestedToolSemanticIcon {
|
|
763
|
+
position: absolute;
|
|
764
|
+
z-index: 1;
|
|
765
|
+
inset-block-start: 5px;
|
|
766
|
+
inset-inline-start: 1px;
|
|
767
|
+
display: inline-flex;
|
|
768
|
+
width: 14px;
|
|
769
|
+
height: 14px;
|
|
770
|
+
align-items: center;
|
|
771
|
+
justify-content: center;
|
|
772
|
+
color: var(--dsw-alias-label-tertiary);
|
|
773
|
+
pointer-events: none;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
.eventRow[data-stream-tool-row]
|
|
777
|
+
:global([data-subcalls])
|
|
778
|
+
> :global([data-chat-call-id])
|
|
779
|
+
> :global([data-slot='tool.call.toolview'])
|
|
780
|
+
> :global([data-tool])
|
|
781
|
+
> *
|
|
782
|
+
> :global([data-disclosure-row])[aria-expanded]:has(> .nestedToolSemanticIcon),
|
|
783
|
+
.eventRow[data-stream-tool-row]
|
|
784
|
+
:global([data-subcalls])
|
|
785
|
+
> :global([data-chat-call-id])
|
|
786
|
+
> :global([data-slot='tool.call.toolview'])
|
|
787
|
+
> *
|
|
788
|
+
> :global([data-sample='bash'])[aria-expanded]:has(> .nestedToolSemanticIcon) {
|
|
789
|
+
padding-inline-start: 22px;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.eventRow[data-stream-tool-row]
|
|
793
|
+
:global([data-subcalls])
|
|
794
|
+
> :global([data-chat-call-id])
|
|
795
|
+
> :global([data-slot='tool.call.toolview'])
|
|
796
|
+
> :global([data-tool])
|
|
797
|
+
> *
|
|
798
|
+
> :global([data-disclosure-row])[aria-expanded]:has(> .nestedToolSemanticIcon)
|
|
799
|
+
> :first-child
|
|
800
|
+
> :first-child:not(:last-child),
|
|
801
|
+
.eventRow[data-stream-tool-row]
|
|
802
|
+
:global([data-subcalls])
|
|
803
|
+
> :global([data-chat-call-id])
|
|
804
|
+
> :global([data-slot='tool.call.toolview'])
|
|
805
|
+
> *
|
|
806
|
+
> :global([data-sample='bash'])[aria-expanded]:has(> .nestedToolSemanticIcon)
|
|
807
|
+
> :first-child
|
|
808
|
+
> :first-child:not(:last-child) {
|
|
809
|
+
display: none;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
.eventRow[data-stream-tool-row]
|
|
813
|
+
:global([data-subcalls])
|
|
814
|
+
> :global([data-chat-call-id])
|
|
815
|
+
> :global([data-slot='tool.call.toolview'])
|
|
816
|
+
> :global([data-tool])
|
|
817
|
+
> *
|
|
818
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
819
|
+
> :first-child,
|
|
820
|
+
.eventRow[data-stream-tool-row]
|
|
821
|
+
:global([data-subcalls])
|
|
822
|
+
> :global([data-chat-call-id])
|
|
823
|
+
> :global([data-slot='tool.call.toolview'])
|
|
824
|
+
> *
|
|
825
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
826
|
+
> :first-child {
|
|
827
|
+
display: contents;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
.eventRow[data-stream-tool-row]
|
|
831
|
+
:global([data-subcalls])
|
|
832
|
+
> :global([data-chat-call-id])
|
|
833
|
+
> :global([data-slot='tool.call.toolview'])
|
|
834
|
+
> :global([data-tool])
|
|
835
|
+
> *
|
|
836
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
837
|
+
> :nth-child(n + 3),
|
|
838
|
+
.eventRow[data-stream-tool-row]
|
|
839
|
+
:global([data-subcalls])
|
|
840
|
+
> :global([data-chat-call-id])
|
|
841
|
+
> :global([data-slot='tool.call.toolview'])
|
|
842
|
+
> *
|
|
843
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
844
|
+
> :nth-child(n + 3) {
|
|
845
|
+
flex-grow: 0;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
.eventRow[data-stream-tool-row]
|
|
849
|
+
:global([data-subcalls])
|
|
850
|
+
> :global([data-chat-call-id])
|
|
851
|
+
> :global([data-slot='tool.call.toolview'])
|
|
852
|
+
> :global([data-tool])
|
|
853
|
+
> *
|
|
854
|
+
> :global([data-disclosure-row])[aria-expanded]
|
|
855
|
+
> :first-child
|
|
856
|
+
> svg,
|
|
857
|
+
.eventRow[data-stream-tool-row]
|
|
858
|
+
:global([data-subcalls])
|
|
859
|
+
> :global([data-chat-call-id])
|
|
860
|
+
> :global([data-slot='tool.call.toolview'])
|
|
861
|
+
> *
|
|
862
|
+
> :global([data-sample='bash'])[aria-expanded]
|
|
863
|
+
> :first-child
|
|
864
|
+
> svg {
|
|
865
|
+
position: static;
|
|
866
|
+
order: 4;
|
|
867
|
+
flex: none;
|
|
868
|
+
margin: 0 0 0 6px;
|
|
869
|
+
opacity: 0;
|
|
870
|
+
color: var(--dsw-alias-label-secondary);
|
|
871
|
+
transition: opacity 100ms ease, transform 120ms ease;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.eventRow[data-stream-tool-row]
|
|
875
|
+
:global([data-subcalls])
|
|
876
|
+
> :global([data-chat-call-id])
|
|
877
|
+
> :global([data-slot='tool.call.toolview'])
|
|
878
|
+
> :global([data-tool])
|
|
879
|
+
> *
|
|
880
|
+
> :global([data-disclosure-row])[aria-expanded]:hover
|
|
881
|
+
> :first-child
|
|
882
|
+
> svg,
|
|
883
|
+
.eventRow[data-stream-tool-row]
|
|
884
|
+
:global([data-subcalls])
|
|
885
|
+
> :global([data-chat-call-id])
|
|
886
|
+
> :global([data-slot='tool.call.toolview'])
|
|
887
|
+
> :global([data-tool])
|
|
888
|
+
> *
|
|
889
|
+
> :global([data-disclosure-row])[aria-expanded]:focus-visible
|
|
890
|
+
> :first-child
|
|
891
|
+
> svg,
|
|
892
|
+
.eventRow[data-stream-tool-row]
|
|
893
|
+
:global([data-subcalls])
|
|
894
|
+
> :global([data-chat-call-id])
|
|
895
|
+
> :global([data-slot='tool.call.toolview'])
|
|
896
|
+
> *
|
|
897
|
+
> :global([data-sample='bash'])[aria-expanded]:hover
|
|
898
|
+
> :first-child
|
|
899
|
+
> svg,
|
|
900
|
+
.eventRow[data-stream-tool-row]
|
|
901
|
+
:global([data-subcalls])
|
|
902
|
+
> :global([data-chat-call-id])
|
|
903
|
+
> :global([data-slot='tool.call.toolview'])
|
|
904
|
+
> *
|
|
905
|
+
> :global([data-sample='bash'])[aria-expanded]:focus-visible
|
|
906
|
+
> :first-child
|
|
907
|
+
> svg {
|
|
908
|
+
opacity: 1;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
.eventRow[data-stream-tool-row]
|
|
912
|
+
:global([data-subcalls])
|
|
913
|
+
> :global([data-chat-call-id])
|
|
914
|
+
> :global([data-slot='tool.call.toolview'])
|
|
915
|
+
> :global([data-tool])
|
|
916
|
+
> *
|
|
917
|
+
> :global([data-disclosure-row])[aria-expanded='false']
|
|
918
|
+
> :first-child
|
|
919
|
+
> svg,
|
|
920
|
+
.eventRow[data-stream-tool-row]
|
|
921
|
+
:global([data-subcalls])
|
|
922
|
+
> :global([data-chat-call-id])
|
|
923
|
+
> :global([data-slot='tool.call.toolview'])
|
|
924
|
+
> *
|
|
925
|
+
> :global([data-sample='bash'])[aria-expanded='false']
|
|
926
|
+
> :first-child
|
|
927
|
+
> svg {
|
|
928
|
+
transform: rotate(-90deg);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.eventRow[data-stream-tool-row]
|
|
932
|
+
:global([data-subcalls])
|
|
933
|
+
> :global([data-chat-call-id])
|
|
934
|
+
> :global([data-slot='tool.call.toolview'])
|
|
935
|
+
> :global([data-tool])
|
|
936
|
+
> *
|
|
937
|
+
> :global([data-disclosure-row])[aria-expanded='true']
|
|
938
|
+
> :first-child
|
|
939
|
+
> svg,
|
|
940
|
+
.eventRow[data-stream-tool-row]
|
|
941
|
+
:global([data-subcalls])
|
|
942
|
+
> :global([data-chat-call-id])
|
|
943
|
+
> :global([data-slot='tool.call.toolview'])
|
|
944
|
+
> *
|
|
945
|
+
> :global([data-sample='bash'])[aria-expanded='true']
|
|
946
|
+
> :first-child
|
|
947
|
+
> svg {
|
|
948
|
+
transform: rotate(0deg);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
@keyframes dsh-codex-stream-enter {
|
|
952
|
+
from {
|
|
953
|
+
opacity: 0;
|
|
954
|
+
transform: translateY(4px);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
to {
|
|
958
|
+
opacity: 1;
|
|
959
|
+
transform: translateY(0);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
.reasoningText {
|
|
964
|
+
min-width: 0;
|
|
965
|
+
color: var(--dsw-alias-label-primary);
|
|
966
|
+
font-size: 14px;
|
|
967
|
+
font-weight: 400;
|
|
968
|
+
line-height: 24px;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/* MarkdownText applies its own 16px base shorthand on the inner root. Think
|
|
972
|
+
* should remain a quiet 14px/24px process stream, not inherit the answer's
|
|
973
|
+
* heavier markdown rhythm. */
|
|
974
|
+
.reasoningText > :global(div) {
|
|
975
|
+
font-family: inherit;
|
|
976
|
+
font-size: 14px;
|
|
977
|
+
font-weight: 400;
|
|
978
|
+
line-height: 24px;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
.reasoningText :global(p),
|
|
982
|
+
.reasoningText :global(li),
|
|
983
|
+
.reasoningText :global(blockquote),
|
|
984
|
+
.reasoningText :global(strong),
|
|
985
|
+
.reasoningText :global(h1),
|
|
986
|
+
.reasoningText :global(h2),
|
|
987
|
+
.reasoningText :global(h3),
|
|
988
|
+
.reasoningText :global(h4),
|
|
989
|
+
.reasoningText :global(h5),
|
|
990
|
+
.reasoningText :global(h6) {
|
|
991
|
+
font-size: 14px;
|
|
992
|
+
font-weight: 400;
|
|
993
|
+
line-height: 24px;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.reasoningText :global(strong) {
|
|
997
|
+
font-weight: 400 !important;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
.reasoningText :global(h1),
|
|
1001
|
+
.reasoningText :global(h2),
|
|
1002
|
+
.reasoningText :global(h3),
|
|
1003
|
+
.reasoningText :global(h4),
|
|
1004
|
+
.reasoningText :global(h5),
|
|
1005
|
+
.reasoningText :global(h6) {
|
|
1006
|
+
margin-block: 8px;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
.reasoningText[data-stream-state='running'] {
|
|
1010
|
+
color: var(--dsw-alias-label-secondary);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
.think {
|
|
1014
|
+
display: flex;
|
|
1015
|
+
flex-direction: column;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.thinkRow {
|
|
1019
|
+
position: relative;
|
|
1020
|
+
overflow: hidden;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
.think[data-state='running'] .thinkRow::after {
|
|
1024
|
+
content: '';
|
|
1025
|
+
position: absolute;
|
|
1026
|
+
inset-block: 0;
|
|
1027
|
+
left: 0;
|
|
1028
|
+
width: 300px;
|
|
1029
|
+
background: linear-gradient(
|
|
1030
|
+
90deg,
|
|
1031
|
+
transparent 0%,
|
|
1032
|
+
color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%,
|
|
1033
|
+
transparent 100%
|
|
1034
|
+
);
|
|
1035
|
+
animation: dsh-conversation-ui-think-sweep 2.6s ease-out infinite;
|
|
1036
|
+
pointer-events: none;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
@keyframes dsh-conversation-ui-think-sweep {
|
|
1040
|
+
0% { left: -300px; }
|
|
1041
|
+
90%, 100% { left: 100%; }
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.thinkLeading {
|
|
1045
|
+
flex-shrink: 0;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.thinkChevron {
|
|
1049
|
+
color: var(--dsw-alias-label-secondary);
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.thinkTitle {
|
|
1053
|
+
font-weight: 400;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
.thinkSeparator {
|
|
1057
|
+
flex: none;
|
|
1058
|
+
width: 2px;
|
|
1059
|
+
height: 2px;
|
|
1060
|
+
margin: 0 8px;
|
|
1061
|
+
border-radius: 1px;
|
|
1062
|
+
background: var(--dsw-alias-label-caption);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.thinkSummary {
|
|
1066
|
+
min-width: 0;
|
|
1067
|
+
overflow: hidden;
|
|
1068
|
+
flex: 0 1 auto;
|
|
1069
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1070
|
+
font-size: 14px;
|
|
1071
|
+
line-height: 24px;
|
|
1072
|
+
text-overflow: ellipsis;
|
|
1073
|
+
white-space: nowrap;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
.thinkSummary[data-follow-end] {
|
|
1077
|
+
text-overflow: clip;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
.thinkBody {
|
|
1081
|
+
padding: 4px 0 4px 22px;
|
|
1082
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1083
|
+
font-size: 14px;
|
|
1084
|
+
line-height: 24px;
|
|
1085
|
+
white-space: pre-wrap;
|
|
1086
|
+
word-break: break-word;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/*
|
|
1090
|
+
* AnimatedDisclosure chrome: keeps the semantic icon in the leading slot and
|
|
1091
|
+
* places the disclosure chevron after the title/summary, matching Tool rows.
|
|
1092
|
+
*/
|
|
1093
|
+
.disclosureRoot {
|
|
1094
|
+
display: flex;
|
|
1095
|
+
flex-direction: column;
|
|
1096
|
+
width: 100%;
|
|
1097
|
+
min-width: 0;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.disclosureRow {
|
|
1101
|
+
position: relative;
|
|
1102
|
+
overflow: hidden;
|
|
1103
|
+
display: flex;
|
|
1104
|
+
align-items: center;
|
|
1105
|
+
height: 24px;
|
|
1106
|
+
min-width: 0;
|
|
1107
|
+
cursor: pointer;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
.disclosureLeading {
|
|
1111
|
+
position: relative;
|
|
1112
|
+
flex: none;
|
|
1113
|
+
width: 16px;
|
|
1114
|
+
height: 16px;
|
|
1115
|
+
display: inline-flex;
|
|
1116
|
+
align-items: center;
|
|
1117
|
+
justify-content: center;
|
|
1118
|
+
margin-right: 6px;
|
|
1119
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
.disclosureTitle {
|
|
1123
|
+
flex: none;
|
|
1124
|
+
font-size: 14px;
|
|
1125
|
+
line-height: 24px;
|
|
1126
|
+
color: var(--dsw-alias-label-secondary);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
.disclosureTrailing {
|
|
1130
|
+
display: inline-flex;
|
|
1131
|
+
flex: none;
|
|
1132
|
+
align-items: center;
|
|
1133
|
+
justify-content: center;
|
|
1134
|
+
width: 14px;
|
|
1135
|
+
height: 14px;
|
|
1136
|
+
margin-left: 6px;
|
|
1137
|
+
opacity: 0;
|
|
1138
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1139
|
+
transition: opacity 100ms ease;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
.disclosureRow:hover .disclosureTrailing,
|
|
1143
|
+
.disclosureRow:focus-visible .disclosureTrailing {
|
|
1144
|
+
opacity: 1;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/*
|
|
1148
|
+
* The animated body: one grid track transitions 0fr <-> 1fr, so the height
|
|
1149
|
+
* glides to the body's natural size with no measured pixel target. The direct
|
|
1150
|
+
* child clips to the track; `visibility` (not display) keeps a collapsed body
|
|
1151
|
+
* out of the accessibility tree and tab order while it still measures for the
|
|
1152
|
+
* animation - it flips visible immediately on expand and waits for the height
|
|
1153
|
+
* to collapse before hiding. Rides the deepsuite curve tokens with fallbacks
|
|
1154
|
+
* for standalone composition.
|
|
1155
|
+
*/
|
|
1156
|
+
.disclosureContent {
|
|
1157
|
+
display: grid;
|
|
1158
|
+
grid-template-rows: 1fr;
|
|
1159
|
+
visibility: visible;
|
|
1160
|
+
transition:
|
|
1161
|
+
grid-template-rows var(--ds-transition-duration, 0.2s) var(--ds-ease-in-out, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
1162
|
+
visibility 0s;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
.disclosureContent[data-collapsed] {
|
|
1166
|
+
grid-template-rows: 0fr;
|
|
1167
|
+
visibility: hidden;
|
|
1168
|
+
transition:
|
|
1169
|
+
grid-template-rows var(--ds-transition-duration, 0.2s) var(--ds-ease-in-out, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
1170
|
+
visibility 0s var(--ds-transition-duration, 0.2s);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
.disclosureContent > * {
|
|
1174
|
+
min-height: 0;
|
|
1175
|
+
overflow: hidden;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1179
|
+
.root,
|
|
1180
|
+
.eventRow {
|
|
1181
|
+
animation: none;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.think[data-state='running'] .thinkRow::after {
|
|
1185
|
+
animation: none;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.eventRow[data-stream-tool-row][data-stream-progress='active']
|
|
1189
|
+
> :global([data-chat-call-id])
|
|
1190
|
+
> :global([data-slot='tool.call.toolview'])
|
|
1191
|
+
> :global([data-tool])
|
|
1192
|
+
> *
|
|
1193
|
+
> :global([data-disclosure-row])::after,
|
|
1194
|
+
.eventRow[data-stream-tool-row][data-stream-progress='active']
|
|
1195
|
+
> :global([data-chat-call-id])
|
|
1196
|
+
> :global([data-slot='tool.call.toolview'])
|
|
1197
|
+
> *
|
|
1198
|
+
> :global([data-sample='bash'])::after {
|
|
1199
|
+
animation: none;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
.turnWaiting {
|
|
1203
|
+
background: none;
|
|
1204
|
+
color: var(--dsw-alias-label-secondary);
|
|
1205
|
+
animation: none;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
.disclosureContent,
|
|
1209
|
+
.disclosureContent[data-collapsed] {
|
|
1210
|
+
transition: none;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
.stopped {
|
|
1215
|
+
align-self: flex-start;
|
|
1216
|
+
padding: 0 6px;
|
|
1217
|
+
border-radius: 6px;
|
|
1218
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1219
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1220
|
+
font-size: 11px;
|
|
1221
|
+
line-height: 18px;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
.visuallyHidden {
|
|
1225
|
+
position: absolute;
|
|
1226
|
+
overflow: hidden;
|
|
1227
|
+
width: 1px;
|
|
1228
|
+
height: 1px;
|
|
1229
|
+
padding: 0;
|
|
1230
|
+
border: 0;
|
|
1231
|
+
margin: -1px;
|
|
1232
|
+
clip: rect(0 0 0 0);
|
|
1233
|
+
clip-path: inset(50%);
|
|
1234
|
+
white-space: nowrap;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/*
|
|
1238
|
+
* Follow host: ordinary document flow. The last text block owns the
|
|
1239
|
+
* conversation scrollport's bottom-follow while the reply reveals
|
|
1240
|
+
* (see useConversationFollow).
|
|
1241
|
+
*/
|
|
1242
|
+
.follow {
|
|
1243
|
+
min-width: 0;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/*
|
|
1247
|
+
* Trim the half-leading above and below each text block so line boxes hug
|
|
1248
|
+
* the font's ascent/descent edges. `text` edges are used instead of
|
|
1249
|
+
* `cap alphabetic` because assistant text is CJK-heavy and cap-height
|
|
1250
|
+
* trimming would clip ideographic glyphs.
|
|
1251
|
+
*/
|
|
1252
|
+
@supports (text-box-trim: trim-both) {
|
|
1253
|
+
/* Do not trim blocks containing inline code: a wrapped code chip can be
|
|
1254
|
+
* taller than its first line box, and trimming the parent lets the chip
|
|
1255
|
+
* escape its measured height and collide with the following content. */
|
|
1256
|
+
.root :is(p, h1, h2, h3, h4, h5, h6, blockquote):not(:has(code)) {
|
|
1257
|
+
text-box-trim: trim-both;
|
|
1258
|
+
text-box-edge: text;
|
|
1259
|
+
}
|
|
1260
|
+
}
|