@workerdeck/ui 0.12.0 → 0.15.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 (32) hide show
  1. package/README.md +19 -0
  2. package/build/{SessionPanel-NQ8ksCfj.mjs → SessionPanel-DI1NO4l8.mjs} +223 -163
  3. package/build/SessionPanel-DI1NO4l8.mjs.map +1 -0
  4. package/build/{SessionPanel-Dy9lQrOV.d.mts → SessionPanel-J2U8v88q.d.mts} +86 -8
  5. package/build/index.d.mts +118 -7
  6. package/build/index.mjs +355 -169
  7. package/build/index.mjs.map +1 -1
  8. package/build/workspace.d.mts +13 -1
  9. package/build/workspace.mjs +7 -2
  10. package/build/workspace.mjs.map +1 -1
  11. package/package.json +4 -4
  12. package/src/components/agent/Composer.tsx +112 -37
  13. package/src/components/agent/EngineIcon.tsx +97 -0
  14. package/src/components/agent/Loader.tsx +4 -1
  15. package/src/components/agent/Message.tsx +12 -5
  16. package/src/components/agent/QuestionPrompt.tsx +1 -1
  17. package/src/components/agent/SessionBrowser.tsx +266 -138
  18. package/src/components/agent/SessionPanel.tsx +149 -48
  19. package/src/components/agent/SessionWorkspace.tsx +17 -0
  20. package/src/components/agent/StatusBar.tsx +58 -12
  21. package/src/components/agent/Transcript.tsx +2 -3
  22. package/src/components/agent/line-prompt.tsx +2 -2
  23. package/src/components/agent/transcript-variant.tsx +14 -0
  24. package/src/components/ui/Badge.tsx +6 -1
  25. package/src/components/ui/Empty.tsx +56 -0
  26. package/src/components/ui/Menu.tsx +1 -1
  27. package/src/components/ui/Select.tsx +1 -1
  28. package/src/components/ui/Splitter.tsx +14 -0
  29. package/src/components/ui/Tooltip.tsx +1 -1
  30. package/src/index.ts +11 -1
  31. package/src/styles/theme.css +77 -15
  32. package/build/SessionPanel-NQ8ksCfj.mjs.map +0 -1
@@ -0,0 +1,97 @@
1
+ import { cn } from '../../lib/utils.ts'
2
+
3
+ /**
4
+ * The engine's own mark, monochrome.
5
+ *
6
+ * Inlined rather than depended on: the React package these come from
7
+ * (`@lobehub/icons`) pulls antd, `@lobehub/ui` and a second copy of
8
+ * lucide-react — an absurd amount of bundle for a few glyphs in a sidebar.
9
+ * These are paths from `@lobehub/icons-static-svg` (MIT, © LobeHub), already
10
+ * `fill="currentColor"` single-path marks, so they take the row's colour like
11
+ * any other glyph and need no light/dark variants.
12
+ *
13
+ * The marks are trademarks of their owners (Anthropic, OpenAI, Google,
14
+ * DeepSeek, Moonshot), used here only to identify which engine a session runs
15
+ * on.
16
+ *
17
+ * Codex is drawn as OpenAI: the session's engine *is* OpenAI's, and OpenAI's
18
+ * mark is the one a person recognises at 12px.
19
+ */
20
+ const PATHS: Record<string, { title: string; d: string }> = {
21
+ claude: {
22
+ title: 'Claude',
23
+ d: 'M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z',
24
+ },
25
+ codex: {
26
+ title: 'OpenAI',
27
+ d: 'M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z',
28
+ },
29
+ gemini: {
30
+ title: 'Gemini',
31
+ d: 'M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z',
32
+ },
33
+ deepseek: {
34
+ title: 'DeepSeek',
35
+ d: 'M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z',
36
+ },
37
+ moonshot: {
38
+ title: 'Moonshot',
39
+ d: 'M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z',
40
+ },
41
+ }
42
+
43
+ /**
44
+ * Which mark a session wears.
45
+ *
46
+ * The two first-party engines are named directly. A `provider` session is
47
+ * whatever the host wired up, so its *model* is the only thing that says whose
48
+ * it is — sniffed loosely on purpose (`gemini-2.5-pro`, `deepseek-chat`,
49
+ * `kimi-k2`), and falling through to no mark rather than guessing wrong.
50
+ */
51
+ export function engineMark(engine: string, model?: string): string | undefined {
52
+ if (engine === 'claude') return 'claude'
53
+ if (engine === 'codex') return 'codex'
54
+ const id = model?.toLowerCase() ?? ''
55
+ if (!id) return undefined
56
+ if (id.includes('gemini')) return 'gemini'
57
+ if (id.includes('deepseek')) return 'deepseek'
58
+ if (id.includes('moonshot') || id.includes('kimi')) return 'moonshot'
59
+ if (id.includes('claude')) return 'claude'
60
+ if (id.startsWith('gpt') || id.startsWith('o1') || id.startsWith('o3') || id.includes('openai')) {
61
+ return 'codex'
62
+ }
63
+ return undefined
64
+ }
65
+
66
+ export function EngineIcon({
67
+ engine,
68
+ model,
69
+ className,
70
+ }: {
71
+ engine: string
72
+ model?: string
73
+ className?: string
74
+ }) {
75
+ const mark = PATHS[engineMark(engine, model) ?? '']
76
+ // An engine this build has never heard of still gets a slot, so the second
77
+ // line doesn't reflow around a missing glyph.
78
+ if (!mark) {
79
+ return (
80
+ <span aria-hidden title={engine} className={cn('shrink-0 text-fg-3', className)}>
81
+ ·
82
+ </span>
83
+ )
84
+ }
85
+ return (
86
+ <svg
87
+ viewBox='0 0 24 24'
88
+ fill='currentColor'
89
+ fillRule='evenodd'
90
+ role='img'
91
+ aria-label={mark.title}
92
+ className={cn('size-3 shrink-0 text-fg-3', className)}>
93
+ <title>{mark.title}</title>
94
+ <path d={mark.d} />
95
+ </svg>
96
+ )
97
+ }
@@ -79,7 +79,10 @@ export function Loader({ label, startedAt, tokens, className }: LoaderProps) {
79
79
 
80
80
  return (
81
81
  <div data-slot='loader' className={cn('flex items-baseline gap-2', className)}>
82
- <LineGlyph className='text-accent'>{pulse}</LineGlyph>
82
+ {/* `lines` is monochrome: the terminal treatment earns its calm by
83
+ spending no colour on decoration, and a pulsing glyph is already the
84
+ loudest thing on a still page. `cards` keeps the brand accent. */}
85
+ <LineGlyph className={lines ? 'text-fg-3' : 'text-accent'}>{pulse}</LineGlyph>
83
86
  <span className='min-w-0 flex-1 text-body-sm leading-5 text-fg-3'>
84
87
  {verb}…{' '}
85
88
  {readings.length ? <span className='text-label text-fg-4'>({readings.join(' · ')})</span> : null}
@@ -9,9 +9,12 @@ export interface MessageProps extends HTMLAttributes<HTMLDivElement> {
9
9
  /**
10
10
  * One chat turn row.
11
11
  *
12
- * `cards`: user messages sit right in a bubble; assistant content is flat,
13
- * full-width (the AI-chat convention assistant output is the page, user input
14
- * is quoted).
12
+ * `cards`: user messages sit in a bubble, assistant content is flat and
13
+ * full-width. Both are **left-aligned**: the transcript is a log read top to
14
+ * bottom, and an editor-shaped host (a full-width session view beside a sessions
15
+ * rail) has no right edge to anchor to — a bubble drifting right in a 1600px
16
+ * column separates a prompt from the reply it produced. The bubble alone is
17
+ * enough to say who spoke.
15
18
  *
16
19
  * `lines`: both are left-aligned full-width line items behind a gutter glyph —
17
20
  * `❯` for what was typed, `●` for what the model said. No bubble: a prompt is
@@ -35,12 +38,15 @@ export function Message({ from, className, children, ...props }: MessageProps) {
35
38
  // inside it, and square-ish so it reads as a strip, not a bubble.
36
39
  from === 'user' && '-mx-1 rounded-sm bg-surface px-1',
37
40
  )
38
- : cn('flex-col gap-1', from === 'user' ? 'items-end' : 'items-start'),
41
+ : 'flex-col items-start gap-1',
39
42
  className,
40
43
  )}
41
44
  {...props}>
42
45
  {lines ? (
43
46
  <>
47
+ {/* The prompt marker is accent, the same blue VS Code's own chat and
48
+ the iOS app give it: in a column of grey rows it is the one thing
49
+ that says "you said this", and it is what the eye scrolls back to. */}
44
50
  <LineGlyph className={from === 'user' ? 'text-accent' : 'text-fg-3'}>
45
51
  {from === 'user' ? '❯' : '●'}
46
52
  </LineGlyph>
@@ -65,7 +71,8 @@ export function MessageContent({ className, ...props }: HTMLAttributes<HTMLDivEl
65
71
  : cn(
66
72
  'text-body-sm leading-6 text-fg-1',
67
73
  // Bubble treatment only within a user message row.
68
- 'in-data-[from=user]:max-w-[85%] in-data-[from=user]:rounded-lg in-data-[from=user]:rounded-br-sm',
74
+ // The tail points bottom-*left* now that the bubble is left-aligned.
75
+ 'in-data-[from=user]:max-w-[85%] in-data-[from=user]:rounded-lg in-data-[from=user]:rounded-bl-sm',
69
76
  'in-data-[from=user]:bg-accent-bg in-data-[from=user]:px-3 in-data-[from=user]:py-2',
70
77
  'in-data-[from=user]:whitespace-pre-wrap',
71
78
  'in-data-[from=assistant]:w-full',
@@ -182,7 +182,7 @@ export function QuestionPrompt({ request, onAnswer, onDismiss, className }: Ques
182
182
  return (
183
183
  <div key={index} className='flex flex-col'>
184
184
  <div className='flex items-baseline gap-2'>
185
- <LineGlyph className='text-info'>?</LineGlyph>
185
+ <LineGlyph className='text-fg-3'>?</LineGlyph>
186
186
  <span className='min-w-0 flex-1 text-body-sm leading-5 text-fg-1'>
187
187
  {q.header ? <span className='text-fg-4'>{q.header} · </span> : null}
188
188
  <span className='font-medium'>{q.question}</span>