@workerdeck/ui 0.22.0 → 1.0.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 (145) hide show
  1. package/build/{SessionPanel-DgwjH4Ve.mjs → SessionPanel-DDgBkHsi.mjs} +2196 -3364
  2. package/build/SessionPanel-DDgBkHsi.mjs.map +1 -0
  3. package/build/SessionPanel-E_L_ldQ5.d.mts +207 -0
  4. package/build/format-B8ZM9LPy.d.mts +16 -0
  5. package/build/format.d.mts +8 -75
  6. package/build/format.mjs +2 -2
  7. package/build/index.d.mts +63 -1138
  8. package/build/index.mjs +4 -300
  9. package/build/index.mjs.map +1 -1
  10. package/build/scoped.css +80 -24
  11. package/build/{status-BE-zg88x.mjs → status-C0HSLZas.mjs} +14 -85
  12. package/build/status-C0HSLZas.mjs.map +1 -0
  13. package/build/workspace.d.mts +9 -124
  14. package/build/workspace.mjs +13 -143
  15. package/build/workspace.mjs.map +1 -1
  16. package/package.json +4 -4
  17. package/src/components/agent/CodeEditor.tsx +31 -103
  18. package/src/components/agent/Composer.tsx +114 -333
  19. package/src/components/agent/ContextDialog.tsx +20 -41
  20. package/src/components/agent/ContextRing.tsx +6 -28
  21. package/src/components/agent/Conversation.tsx +21 -33
  22. package/src/components/agent/EditorTabs.tsx +39 -67
  23. package/src/components/agent/EngineIcon.tsx +29 -72
  24. package/src/components/agent/EntryIcon.tsx +16 -0
  25. package/src/components/agent/FileCard.tsx +10 -16
  26. package/src/components/agent/FileTree.tsx +52 -125
  27. package/src/components/agent/FileViewer.tsx +30 -60
  28. package/src/components/agent/HostFilesDialog.tsx +40 -69
  29. package/src/components/agent/Loader.tsx +3 -24
  30. package/src/components/agent/McpDialog.tsx +64 -137
  31. package/src/components/agent/Message.tsx +2 -21
  32. package/src/components/agent/ModelSelect.tsx +33 -62
  33. package/src/components/agent/PermissionModeSelect.tsx +21 -79
  34. package/src/components/agent/PermissionPrompt.tsx +59 -63
  35. package/src/components/agent/ProjectIcon.tsx +228 -93
  36. package/src/components/agent/PromptTokenText.tsx +10 -16
  37. package/src/components/agent/QuestionPrompt.tsx +43 -64
  38. package/src/components/agent/Reasoning.tsx +13 -16
  39. package/src/components/agent/Response.tsx +4 -6
  40. package/src/components/agent/Scrubber.tsx +31 -80
  41. package/src/components/agent/SessionBrowser.tsx +64 -243
  42. package/src/components/agent/SessionEmptyState.tsx +10 -40
  43. package/src/components/agent/SessionInfoDialog.tsx +46 -78
  44. package/src/components/agent/SessionItem.tsx +53 -320
  45. package/src/components/agent/SessionList.tsx +23 -39
  46. package/src/components/agent/SessionPanel.tsx +345 -923
  47. package/src/components/agent/SessionStatusIcon.tsx +14 -28
  48. package/src/components/agent/SessionSteps.tsx +34 -187
  49. package/src/components/agent/SessionWorkspace.tsx +108 -215
  50. package/src/components/agent/SkillsDialog.tsx +35 -80
  51. package/src/components/agent/StatusBar.tsx +51 -136
  52. package/src/components/agent/SubagentStrip.tsx +12 -77
  53. package/src/components/agent/ToolCallCard.tsx +94 -135
  54. package/src/components/agent/Transcript.tsx +103 -1288
  55. package/src/components/agent/TranscriptItemView.tsx +155 -0
  56. package/src/components/agent/TranscriptRows.tsx +418 -0
  57. package/src/components/agent/UsageDialog.tsx +7 -29
  58. package/src/components/agent/UsageMeters.tsx +18 -73
  59. package/src/components/agent/pulse.tsx +9 -32
  60. package/src/components/agent/scrubber-marks.ts +33 -103
  61. package/src/components/agent/status.ts +1 -5
  62. package/src/components/agent/tool-result-fetch.tsx +3 -25
  63. package/src/components/agent/tool-result-image.tsx +32 -111
  64. package/src/components/agent/transcript-rows.ts +41 -118
  65. package/src/components/agent/transcript-variant.tsx +3 -80
  66. package/src/components/agent/use-height-epoch.ts +10 -24
  67. package/src/components/agent/use-path-links.ts +45 -63
  68. package/src/components/agent/use-subagent-frame.ts +106 -0
  69. package/src/components/agent/use-transcript-jumps.ts +49 -107
  70. package/src/components/prompt-area/animated-placeholder.tsx +6 -5
  71. package/src/components/prompt-area/clipboard-helpers.ts +26 -21
  72. package/src/components/prompt-area/cursor-helpers.ts +79 -37
  73. package/src/components/prompt-area/dom-helpers.ts +97 -69
  74. package/src/components/prompt-area/file-strip.tsx +90 -80
  75. package/src/components/prompt-area/html-to-markdown.ts +67 -46
  76. package/src/components/prompt-area/image-strip.tsx +8 -18
  77. package/src/components/prompt-area/index.ts +2 -15
  78. package/src/components/prompt-area/prompt-area-engine.ts +100 -115
  79. package/src/components/prompt-area/prompt-area-list-ops.ts +66 -59
  80. package/src/components/prompt-area/prompt-area.tsx +31 -38
  81. package/src/components/prompt-area/remove-button.tsx +3 -9
  82. package/src/components/prompt-area/segment-helpers.ts +4 -12
  83. package/src/components/prompt-area/trigger-popover.tsx +15 -27
  84. package/src/components/prompt-area/trigger-presets.ts +0 -10
  85. package/src/components/prompt-area/types.ts +3 -8
  86. package/src/components/prompt-area/use-chip-editing.ts +305 -0
  87. package/src/components/prompt-area/use-markdown-mode.ts +7 -17
  88. package/src/components/prompt-area/use-prompt-area-events.ts +80 -86
  89. package/src/components/prompt-area/use-prompt-area-keydown.ts +598 -0
  90. package/src/components/prompt-area/use-prompt-area-state.ts +5 -23
  91. package/src/components/prompt-area/use-prompt-area.ts +170 -896
  92. package/src/components/prompt-area/use-trigger-search.ts +21 -19
  93. package/src/components/terminal/PermissionPrompt.tsx +56 -59
  94. package/src/components/terminal/QuestionPrompt.tsx +28 -79
  95. package/src/components/terminal/StatusLine.tsx +13 -63
  96. package/src/components/terminal/TerminalTranscript.tsx +44 -160
  97. package/src/components/terminal/affordances.tsx +68 -98
  98. package/src/components/terminal/blocks.ts +20 -156
  99. package/src/components/terminal/diff.tsx +19 -67
  100. package/src/components/terminal/height.ts +163 -313
  101. package/src/components/terminal/image-box.ts +0 -44
  102. package/src/components/terminal/items.tsx +150 -305
  103. package/src/components/terminal/markdown.tsx +36 -95
  104. package/src/components/terminal/press.tsx +26 -53
  105. package/src/components/terminal/prompt.tsx +40 -170
  106. package/src/components/terminal/result-preview.ts +8 -56
  107. package/src/components/terminal/row.tsx +11 -98
  108. package/src/components/terminal/scrubber.tsx +108 -401
  109. package/src/components/terminal/surface.tsx +6 -54
  110. package/src/components/terminal/todos.ts +66 -0
  111. package/src/components/terminal/tool-run.ts +21 -192
  112. package/src/components/ui/AlertDialog.tsx +8 -23
  113. package/src/components/ui/Badge.tsx +18 -29
  114. package/src/components/ui/Button.tsx +7 -15
  115. package/src/components/ui/Card.tsx +2 -13
  116. package/src/components/ui/CodeBlock.tsx +10 -37
  117. package/src/components/ui/CopyButton.tsx +10 -23
  118. package/src/components/ui/Dialog.tsx +23 -36
  119. package/src/components/ui/Empty.tsx +6 -29
  120. package/src/components/ui/Input.tsx +14 -16
  121. package/src/components/ui/Menu.tsx +6 -18
  122. package/src/components/ui/PortalScope.tsx +1 -21
  123. package/src/components/ui/ProgressRing.tsx +8 -19
  124. package/src/components/ui/Select.tsx +18 -31
  125. package/src/components/ui/Sonner.tsx +1 -2
  126. package/src/components/ui/Spinner.tsx +1 -1
  127. package/src/components/ui/Splitter.tsx +30 -64
  128. package/src/components/ui/Textarea.tsx +2 -5
  129. package/src/components/ui/Tooltip.tsx +3 -13
  130. package/src/format.ts +0 -9
  131. package/src/index.ts +16 -113
  132. package/src/lib/clipboard.ts +8 -28
  133. package/src/lib/css.ts +8 -0
  134. package/src/lib/format.ts +101 -86
  135. package/src/lib/plan-request.ts +16 -0
  136. package/src/lib/status.ts +45 -95
  137. package/src/lib/tool-icon.ts +39 -47
  138. package/src/lib/utils.ts +1 -3
  139. package/src/styles/terminal.css +81 -49
  140. package/src/styles/theme.css +136 -19
  141. package/src/workspace.ts +1 -24
  142. package/build/SessionPanel-13l25ubU.d.mts +0 -609
  143. package/build/SessionPanel-DgwjH4Ve.mjs.map +0 -1
  144. package/build/format-ljc3lKpA.d.mts +0 -59
  145. package/build/status-BE-zg88x.mjs.map +0 -1
@@ -48,7 +48,9 @@
48
48
  /* Ligatures turn `=>` and `!=` into glyphs that no longer occupy the cells
49
49
  they were measured as. A grid renderer cannot have that. */
50
50
  font-variant-ligatures: none;
51
- font-feature-settings: 'liga' 0, 'calt' 0;
51
+ font-feature-settings:
52
+ 'liga' 0,
53
+ 'calt' 0;
52
54
  /* `ch` is the advance of `0`, so tabular figures keep digit columns — the
53
55
  diff's line numbers — genuinely aligned. */
54
56
  font-variant-numeric: tabular-nums;
@@ -150,15 +152,30 @@
150
152
 
151
153
  /* Indent levels. A nested row steps one cell per level — the same 2 columns a
152
154
  marker occupies, so a child's marker sits under its parent's first letter. */
153
- .term-row[data-indent='1'] { padding-left: var(--term-cell); }
154
- .term-row[data-indent='2'] { padding-left: calc(2 * var(--term-cell)); }
155
- .term-row[data-indent='3'] { padding-left: calc(3 * var(--term-cell)); }
155
+ .term-row[data-indent='1'] {
156
+ padding-left: var(--term-cell);
157
+ }
158
+ .term-row[data-indent='2'] {
159
+ padding-left: calc(2 * var(--term-cell));
160
+ }
161
+ .term-row[data-indent='3'] {
162
+ padding-left: calc(3 * var(--term-cell));
163
+ }
156
164
 
157
165
  .term-gutter {
158
166
  /* `pre` so a space-only gutter keeps its cell — an unmarked row must still
159
167
  start its text on the same column as a marked one. */
160
168
  white-space: pre;
161
169
  user-select: none;
170
+ /* The gutter is decorative (`aria-hidden`) and it is the leading edge of every
171
+ row, which is where a reader naturally starts dragging to select a line. A
172
+ drag that *begins* on an unselectable node starts no selection at all, so
173
+ without this the most natural way to select transcript text did nothing.
174
+ Letting the press fall through to the row keeps `user-select: none` doing
175
+ its real job — keeping the glyph out of the copied text — without owning
176
+ the pointer. The row below is still pressable from here, since the press
177
+ handler lives on the ancestor. */
178
+ pointer-events: none;
162
179
  color: var(--term-dim);
163
180
  }
164
181
 
@@ -215,20 +232,42 @@
215
232
  * takes `tone` and passes it straight through, so adding a colour is one line
216
233
  * here and nothing in the components.
217
234
  */
218
- [data-terminal] [data-tone='fg'] { color: var(--term-fg); }
219
- [data-terminal] [data-tone='bright'] { color: var(--term-bright); }
220
- [data-terminal] [data-tone='dim'] { color: var(--term-dim); }
221
- [data-terminal] [data-tone='faint'] { color: var(--term-faint); }
222
- [data-terminal] [data-tone='mark'] { color: var(--term-mark); }
223
- [data-terminal] [data-tone='blue'] { color: var(--term-blue); }
224
- [data-terminal] [data-tone='green'] { color: var(--term-green); }
225
- [data-terminal] [data-tone='red'] { color: var(--term-red); }
226
- [data-terminal] [data-tone='yellow'] { color: var(--term-yellow); }
227
- [data-terminal] [data-tone='magenta'] { color: var(--term-magenta); }
235
+ [data-terminal] [data-tone='fg'] {
236
+ color: var(--term-fg);
237
+ }
238
+ [data-terminal] [data-tone='bright'] {
239
+ color: var(--term-bright);
240
+ }
241
+ [data-terminal] [data-tone='dim'] {
242
+ color: var(--term-dim);
243
+ }
244
+ [data-terminal] [data-tone='faint'] {
245
+ color: var(--term-faint);
246
+ }
247
+ [data-terminal] [data-tone='mark'] {
248
+ color: var(--term-mark);
249
+ }
250
+ [data-terminal] [data-tone='blue'] {
251
+ color: var(--term-blue);
252
+ }
253
+ [data-terminal] [data-tone='green'] {
254
+ color: var(--term-green);
255
+ }
256
+ [data-terminal] [data-tone='red'] {
257
+ color: var(--term-red);
258
+ }
259
+ [data-terminal] [data-tone='yellow'] {
260
+ color: var(--term-yellow);
261
+ }
262
+ [data-terminal] [data-tone='magenta'] {
263
+ color: var(--term-magenta);
264
+ }
228
265
 
229
266
  /* Weight is the only other axis. A terminal has one type size, so emphasis has
230
267
  to be carried by weight and colour — never by a larger glyph. */
231
- [data-terminal] [data-weight='bold'] { font-weight: 600; }
268
+ [data-terminal] [data-weight='bold'] {
269
+ font-weight: 600;
270
+ }
232
271
 
233
272
  /* The scroller. Its horizontal padding IS `--term-bleed` — that is the whole
234
273
  contract a full-bleed band relies on — and its vertical padding is a line, so
@@ -415,12 +454,7 @@
415
454
  /* Dashed, for a boundary *within* a prompt. A repeating gradient rather than a
416
455
  dashed border, for the same no-layout reason. */
417
456
  [data-terminal] .term-rule-dashed {
418
- background: repeating-linear-gradient(
419
- to right,
420
- var(--term-faint) 0 4px,
421
- transparent 4px 8px
422
- )
423
- left center / 100% 1px no-repeat;
457
+ background: repeating-linear-gradient(to right, var(--term-faint) 0 4px, transparent 4px 8px) left center / 100% 1px no-repeat;
424
458
  }
425
459
 
426
460
  /* The focused option. A fill, never an outline: an outline is 2px of layout the
@@ -938,9 +972,18 @@
938
972
  percentages: the whole point of the 16px rail is that a lane is a reliable
939
973
  8px target, and a percentage would reintroduce the drift the fixed width was
940
974
  chosen to remove. */
941
- .term-scrubber .term-scrub-mark[data-lane='l'] { left: 0; width: 6px; }
942
- .term-scrubber .term-scrub-mark[data-lane='r'] { left: 6px; width: 6px; }
943
- .term-scrubber .term-scrub-mark[data-lane='f'] { left: 0; width: 12px; }
975
+ .term-scrubber .term-scrub-mark[data-lane='l'] {
976
+ left: 0;
977
+ width: 6px;
978
+ }
979
+ .term-scrubber .term-scrub-mark[data-lane='r'] {
980
+ left: 6px;
981
+ width: 6px;
982
+ }
983
+ .term-scrubber .term-scrub-mark[data-lane='f'] {
984
+ left: 0;
985
+ width: 12px;
986
+ }
944
987
 
945
988
  /* Lane marks are two-tone: the first 2px — the mark's own anchor — at full
946
989
  strength, the rest of the row's extent a 25% tail, so a long answer reads
@@ -950,11 +993,7 @@
950
993
  findable. The alarms (error, approval) stay solid: they are alarms, not
951
994
  extents. */
952
995
  .term-scrubber .term-scrub-mark[data-kind='user'] {
953
- background: linear-gradient(
954
- to bottom,
955
- var(--term-blue) 0 2px,
956
- color-mix(in srgb, var(--term-blue) 25%, transparent) 2px
957
- );
996
+ background: linear-gradient(to bottom, var(--term-blue) 0 2px, color-mix(in srgb, var(--term-blue) 25%, transparent) 2px);
958
997
  }
959
998
  /* A sub-agent's stretch of the transcript, in the input lane: green, because
960
999
  every other colour on this rail is already spoken for and none of them means
@@ -963,27 +1002,17 @@
963
1002
  as an extent (2px head, 25% tail) like the two marks it shares its geometry
964
1003
  with: collapsed it is a tick, expanded it is the band the sub-agent covers. */
965
1004
  .term-scrubber .term-scrub-mark[data-kind='subagent'] {
966
- background: linear-gradient(
967
- to bottom,
968
- var(--term-green) 0 2px,
969
- color-mix(in srgb, var(--term-green) 25%, transparent) 2px
970
- );
1005
+ background: linear-gradient(to bottom, var(--term-green) 0 2px, color-mix(in srgb, var(--term-green) 25%, transparent) 2px);
971
1006
  }
972
1007
  .term-scrubber .term-scrub-mark[data-kind='turn'] {
973
- background: linear-gradient(
974
- to bottom,
975
- var(--term-fg) 0 2px,
976
- color-mix(in srgb, var(--term-fg) 25%, transparent) 2px
977
- );
1008
+ background: linear-gradient(to bottom, var(--term-fg) 0 2px, color-mix(in srgb, var(--term-fg) 25%, transparent) 2px);
978
1009
  }
979
1010
  .term-scrubber .term-scrub-mark[data-kind='turnFailed'] {
980
- background: linear-gradient(
981
- to bottom,
982
- var(--term-red) 0 2px,
983
- color-mix(in srgb, var(--term-red) 25%, transparent) 2px
984
- );
1011
+ background: linear-gradient(to bottom, var(--term-red) 0 2px, color-mix(in srgb, var(--term-red) 25%, transparent) 2px);
1012
+ }
1013
+ .term-scrubber .term-scrub-mark[data-kind='error'] {
1014
+ background: var(--term-red);
985
1015
  }
986
- .term-scrubber .term-scrub-mark[data-kind='error'] { background: var(--term-red); }
987
1016
  /* A failed tool call is an alarm, so it is solid like the rest of them — in the
988
1017
  response lane, since it is something the run produced — but at 55%, which is the one thing keeping the rail readable. A session
989
1018
  error is rare and a turn failure rarer; a tool that failed and was recovered
@@ -995,18 +1024,21 @@
995
1024
  .term-scrubber .term-scrub-mark[data-kind='toolFailed'] {
996
1025
  background: color-mix(in srgb, var(--term-red) 55%, transparent);
997
1026
  }
998
- .term-scrubber .term-scrub-mark[data-kind='bookmark'] { background: var(--term-magenta); }
1027
+ .term-scrubber .term-scrub-mark[data-kind='bookmark'] {
1028
+ background: var(--term-magenta);
1029
+ }
999
1030
  .term-scrubber .term-scrub-mark[data-kind='approval'] {
1000
1031
  background: var(--term-yellow);
1001
1032
  animation: term-scrub-pulse 1.2s infinite;
1002
1033
  }
1003
1034
  /* The catch-up boundary: a dashed hairline centered in its 3px hit box. */
1004
1035
  .term-scrubber .term-scrub-mark[data-kind='recap'] {
1005
- background: repeating-linear-gradient(to right, var(--term-faint) 0 3px, transparent 3px 6px)
1006
- left center / 100% 1px no-repeat;
1036
+ background: repeating-linear-gradient(to right, var(--term-faint) 0 3px, transparent 3px 6px) left center / 100% 1px no-repeat;
1007
1037
  }
1008
1038
  @keyframes term-scrub-pulse {
1009
- 50% { opacity: 0.3; }
1039
+ 50% {
1040
+ opacity: 0.3;
1041
+ }
1010
1042
  }
1011
1043
  @media (prefers-reduced-motion: reduce) {
1012
1044
  .term-scrubber .term-scrub-mark[data-kind='approval'] {
@@ -180,7 +180,7 @@
180
180
  `list.hoverBackground` / `list.activeSelectionBackground`, which is what the
181
181
  design was drawn against. */
182
182
  --row-hover: #2a2d2e;
183
- --row-active: rgb(255 255 255 / 0.10);
183
+ --row-active: rgb(255 255 255 / 0.1);
184
184
  --row-selected: #04395e;
185
185
  --row-selected-weak: #37373d;
186
186
 
@@ -234,9 +234,7 @@
234
234
 
235
235
  /* ---------- Inset frame ---------- */
236
236
  --shine: #303030;
237
- --frame-shadow:
238
- 0 4px 24px rgba(0, 0, 0, 0.55),
239
- 0 2px 6px rgba(0, 0, 0, 0.45);
237
+ --frame-shadow: 0 4px 24px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.45);
240
238
 
241
239
  /* See the light block — lifted for the dark ground. */
242
240
  --wd-scrub-bookmark: #c586c0;
@@ -485,6 +483,99 @@
485
483
  }
486
484
  }
487
485
 
486
+ /* ── Panel font size & Streamdown overrides ──────────────────────────────
487
+ *
488
+ * OUTSIDE `@layer base` so these beat Tailwind utility classes in the cascade
489
+ * (utilities live in a layer; unlayered rules always win over layered ones).
490
+ *
491
+ * `--wd-font-size` is set on the session panel root by the `fontSize` prop.
492
+ * When present it drives all text in the cards variant — body text, headings,
493
+ * code, tables — through one value. When absent the fallback `var(--text-body-sm)`
494
+ * resolves to the same `0.8125rem` the utility class used to set.
495
+ *
496
+ * Streamdown ships `rem`-based heading sizes (text-3xl … text-sm) that resolve
497
+ * against the document root and ignore the panel's local font-size. The `em`-based
498
+ * overrides below scale with `--wd-font-size`. The specificity confines this to
499
+ * cards-mode assistant output; the terminal theme renders headings as weight-only
500
+ * (no size change) through its own components and is unaffected.
501
+ *
502
+ * The heading scale mirrors Streamdown's hierarchy but at a tighter range — its
503
+ * 30 → 14 px span (h1 → h6) sits inside a 13px body, so the ratio is condensed:
504
+ * h1 at 1.5em, descending to h6 at 1em.
505
+ */
506
+ [data-slot='message-content'] {
507
+ font-size: var(--wd-font-size, var(--text-body-sm));
508
+ line-height: 1.6;
509
+ }
510
+ [data-slot='message-content'] h1 {
511
+ font-size: 1.5em;
512
+ line-height: 1.35;
513
+ margin-top: 1.5em;
514
+ }
515
+ [data-slot='message-content'] h2 {
516
+ font-size: 1.3em;
517
+ line-height: 1.35;
518
+ margin-top: 1.5em;
519
+ }
520
+ [data-slot='message-content'] h3 {
521
+ font-size: 1.15em;
522
+ line-height: 1.4;
523
+ margin-top: 1.25em;
524
+ }
525
+ [data-slot='message-content'] h4 {
526
+ font-size: 1.05em;
527
+ line-height: 1.4;
528
+ margin-top: 1.25em;
529
+ }
530
+ [data-slot='message-content'] h5 {
531
+ font-size: 1em;
532
+ line-height: 1.4;
533
+ margin-top: 1em;
534
+ }
535
+ [data-slot='message-content'] h6 {
536
+ font-size: 1em;
537
+ line-height: 1.4;
538
+ margin-top: 1em;
539
+ }
540
+ [data-slot='message-content'] pre {
541
+ font-size: 0.9em;
542
+ }
543
+ [data-slot='message-content'] code {
544
+ font-size: 0.9em;
545
+ }
546
+ [data-slot='message-content'] pre code {
547
+ font-size: inherit;
548
+ }
549
+ /* Table, cells, and headers: Streamdown puts `text-sm` (rem) on td/th directly,
550
+ so overriding the table alone is not enough — the cell class wins. */
551
+ [data-slot='message-content'] table {
552
+ font-size: 0.95em;
553
+ }
554
+ [data-slot='message-content'] td {
555
+ font-size: inherit;
556
+ }
557
+ [data-slot='message-content'] th {
558
+ font-size: inherit;
559
+ }
560
+ /* Code block body wrapper: Streamdown puts `text-sm` on the wrapper div around
561
+ the <pre>; override so it inherits the 0.9em from the pre rule above. */
562
+ [data-slot='message-content'] [data-streamdown='code-block-body'] {
563
+ font-size: 0.9em;
564
+ }
565
+ /* Inline code: Streamdown puts `text-sm` directly on the <code>. */
566
+ [data-slot='message-content'] :not(pre) > code {
567
+ font-size: 0.9em;
568
+ }
569
+ /* The composer's prompt area and its chips inherit the panel's font size so the
570
+ prompt and the output read at the same scale. The two-selector specificity
571
+ beats the utility class on the element. */
572
+ [data-slot='session-panel'] .prompt-area-container {
573
+ font-size: var(--wd-font-size, var(--text-body-sm));
574
+ }
575
+ [data-slot='session-panel'] .prompt-area-chip {
576
+ font-size: var(--wd-font-size, 0.8125rem);
577
+ }
578
+
488
579
  /* The inset frame's gradient "shine" edge (app shells). Do NOT add bg-* on top. */
489
580
  .frame-shine {
490
581
  border: 1px solid transparent;
@@ -672,7 +763,7 @@
672
763
  overflow: hidden;
673
764
  white-space: nowrap;
674
765
  text-overflow: ellipsis;
675
- font-size: var(--text-body-sm);
766
+ font-size: var(--wd-font-size, var(--text-body-sm));
676
767
  color: var(--fg-2);
677
768
  background: color-mix(in srgb, var(--bg) 88%, transparent);
678
769
  backdrop-filter: blur(12px);
@@ -713,28 +804,50 @@
713
804
  .wd-scrubber[data-interactive] .wd-scrub-mark:hover {
714
805
  outline: 1px solid color-mix(in srgb, var(--fg-1) 40%, transparent);
715
806
  }
716
- .wd-scrubber .wd-scrub-mark[data-lane='l'] { left: 0; width: 6px; }
717
- .wd-scrubber .wd-scrub-mark[data-lane='r'] { left: 6px; width: 6px; }
718
- .wd-scrubber .wd-scrub-mark[data-lane='f'] { left: 0; width: 12px; }
719
- .wd-scrubber .wd-scrub-mark[data-kind='user'] { background: var(--accent); }
720
- .wd-scrubber .wd-scrub-mark[data-kind='subagent'] { background: var(--success); }
721
- .wd-scrubber .wd-scrub-mark[data-kind='turn'] { background: var(--fg-3); }
722
- .wd-scrubber .wd-scrub-mark[data-kind='turnFailed'] { background: var(--danger); }
723
- .wd-scrubber .wd-scrub-mark[data-kind='error'] { background: var(--danger); }
807
+ .wd-scrubber .wd-scrub-mark[data-lane='l'] {
808
+ left: 0;
809
+ width: 6px;
810
+ }
811
+ .wd-scrubber .wd-scrub-mark[data-lane='r'] {
812
+ left: 6px;
813
+ width: 6px;
814
+ }
815
+ .wd-scrubber .wd-scrub-mark[data-lane='f'] {
816
+ left: 0;
817
+ width: 12px;
818
+ }
819
+ .wd-scrubber .wd-scrub-mark[data-kind='user'] {
820
+ background: var(--accent);
821
+ }
822
+ .wd-scrubber .wd-scrub-mark[data-kind='subagent'] {
823
+ background: var(--success);
824
+ }
825
+ .wd-scrubber .wd-scrub-mark[data-kind='turn'] {
826
+ background: var(--fg-3);
827
+ }
828
+ .wd-scrubber .wd-scrub-mark[data-kind='turnFailed'] {
829
+ background: var(--danger);
830
+ }
831
+ .wd-scrubber .wd-scrub-mark[data-kind='error'] {
832
+ background: var(--danger);
833
+ }
724
834
  .wd-scrubber .wd-scrub-mark[data-kind='toolFailed'] {
725
835
  background: color-mix(in srgb, var(--danger) 55%, transparent);
726
836
  }
727
- .wd-scrubber .wd-scrub-mark[data-kind='bookmark'] { background: var(--wd-scrub-bookmark); }
837
+ .wd-scrubber .wd-scrub-mark[data-kind='bookmark'] {
838
+ background: var(--wd-scrub-bookmark);
839
+ }
728
840
  .wd-scrubber .wd-scrub-mark[data-kind='approval'] {
729
841
  background: var(--warning);
730
842
  animation: wd-scrub-pulse 1.2s infinite;
731
843
  }
732
844
  .wd-scrubber .wd-scrub-mark[data-kind='recap'] {
733
- background: repeating-linear-gradient(to right, var(--fg-4) 0 3px, transparent 3px 6px)
734
- left center / 100% 1px no-repeat;
845
+ background: repeating-linear-gradient(to right, var(--fg-4) 0 3px, transparent 3px 6px) left center / 100% 1px no-repeat;
735
846
  }
736
847
  @keyframes wd-scrub-pulse {
737
- 50% { opacity: 0.3; }
848
+ 50% {
849
+ opacity: 0.3;
850
+ }
738
851
  }
739
852
  @media (prefers-reduced-motion: reduce) {
740
853
  .wd-scrubber .wd-scrub-mark[data-kind='approval'] {
@@ -762,8 +875,12 @@
762
875
  pointer-events: none;
763
876
  z-index: 11;
764
877
  }
765
- .wd-scrubber .wd-scrub-peek [data-tone='muted'] { color: var(--fg-3); }
766
- .wd-scrubber .wd-scrub-peek [data-tone='danger'] { color: var(--danger); }
878
+ .wd-scrubber .wd-scrub-peek [data-tone='muted'] {
879
+ color: var(--fg-3);
880
+ }
881
+ .wd-scrubber .wd-scrub-peek [data-tone='danger'] {
882
+ color: var(--danger);
883
+ }
767
884
  .wd-scrubber .wd-scrub-ex {
768
885
  display: -webkit-box;
769
886
  -webkit-line-clamp: 4;
package/src/workspace.ts CHANGED
@@ -1,27 +1,4 @@
1
- /**
2
- * The workspace layer — the VS Code-shaped layout around `SessionPanel`, and
3
- * the Monaco editor at the middle of it.
4
- *
5
- * This is a **separate entry point** (`@workerdeck/ui/workspace`) for one
6
- * reason: Monaco. It is only reachable from here, so an embedder who imports
7
- * the root entry never pulls it into their module graph.
8
- *
9
- * That matters more than tree-shaking alone would suggest. Rollup does drop
10
- * `CodeEditor` from a `SessionPanel`-only bundle — but Vite resolves Monaco's
11
- * `new Worker(new URL(…, import.meta.url))` calls during *transform*, before
12
- * tree-shaking runs, and emits ~9MB of language-service workers as assets that
13
- * are never retracted. Keeping the import unreachable from the root entry is
14
- * what actually prevents that; `sideEffects: false` does not.
15
- *
16
- * Consequently `monaco-editor` is an **optional peer dependency**: importing
17
- * this entry means installing it, and importing only the root entry means not
18
- * having to. See the README for the Vite configuration Monaco needs.
19
- */
20
-
21
- export {
22
- SessionWorkspace,
23
- type SessionWorkspaceProps,
24
- } from './components/agent/SessionWorkspace.tsx'
1
+ export { SessionWorkspace, type SessionWorkspaceProps } from './components/agent/SessionWorkspace.tsx'
25
2
  export { FileTree, type FileTreeProps } from './components/agent/FileTree.tsx'
26
3
  export { EditorTabs, type EditorTabsProps } from './components/agent/EditorTabs.tsx'
27
4
  export { FileViewer, type FileViewerProps } from './components/agent/FileViewer.tsx'