@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
@@ -17,67 +17,39 @@ export interface SessionInfoDialogProps {
17
17
  onOpenChange: (open: boolean) => void
18
18
  }
19
19
 
20
- /**
21
- * What this session *is*: engine, profile, model, mode, where it runs, which
22
- * credentials it found, and the files it has handed over.
23
- *
24
- * The identity half of the session's facts. Context and usage have their own
25
- * panels — they change every turn and are consulted mid-run, while everything
26
- * here is fixed at creation and looked up once.
27
- */
28
- export function SessionInfoDialog({
29
- state,
30
- client,
31
- sessionId,
32
- open,
33
- onOpenChange,
34
- }: SessionInfoDialogProps) {
20
+ export function SessionInfoDialog({ state, client, sessionId, open, onOpenChange }: SessionInfoDialogProps) {
35
21
  const session = state.session
36
22
  const mode = state.permissionMode ? permissionModeMeta(state.permissionMode) : undefined
37
23
  return (
38
24
  <Dialog open={open} onOpenChange={onOpenChange}>
39
25
  <DialogContent>
40
- <DialogHeader title='Session info' description={session?.title} />
26
+ <DialogHeader title="Session info" description={session?.title} />
41
27
  <DialogBody>
42
- <div className='flex flex-col divide-y divide-border'>
43
- <div className='pb-2'>
44
- <DialogRow label='Engine'>{state.engine ?? 'claude'}</DialogRow>
45
- {session?.profile ? (
46
- <DialogRow label='Profile'>{session.profile}</DialogRow>
47
- ) : null}
28
+ <div className="flex flex-col divide-y divide-border">
29
+ <div className="pb-2">
30
+ <DialogRow label="Engine">{state.engine ?? 'claude'}</DialogRow>
31
+ {session?.profile ? <DialogRow label="Profile">{session.profile}</DialogRow> : null}
48
32
  {state.model ? (
49
- <DialogRow label='Model' mono>
33
+ <DialogRow label="Model" mono>
50
34
  {state.model}
51
35
  </DialogRow>
52
36
  ) : null}
53
- {mode ? <DialogRow label='Permission mode'>{mode.label}</DialogRow> : null}
54
- {session?.apiKeySource ? (
55
- <DialogRow label='Credentials'>{session.apiKeySource}</DialogRow>
56
- ) : null}
37
+ {mode ? <DialogRow label="Permission mode">{mode.label}</DialogRow> : null}
38
+ {session?.apiKeySource ? <DialogRow label="Credentials">{session.apiKeySource}</DialogRow> : null}
57
39
  </div>
58
- <div className='py-2'>
59
- {state.cwd ? <CopyRow label='Working directory' value={state.cwd} /> : null}
60
- {state.sdkSessionId ? (
61
- <CopyRow label='Engine session id' value={state.sdkSessionId} />
62
- ) : null}
63
- {session ? <CopyRow label='Gateway session id' value={session.id} /> : null}
40
+ <div className="py-2">
41
+ {state.cwd ? <CopyRow label="Working directory" value={state.cwd} /> : null}
42
+ {state.sdkSessionId ? <CopyRow label="Engine session id" value={state.sdkSessionId} /> : null}
43
+ {session ? <CopyRow label="Gateway session id" value={session.id} /> : null}
64
44
  </div>
65
- <div className='py-2'>
66
- {session?.createdAt ? (
67
- <DialogRow label='Started'>{formatRelativeTime(session.createdAt)}</DialogRow>
68
- ) : null}
69
- {session?.numTurns !== undefined ? (
70
- <DialogRow label='Turns'>{session.numTurns}</DialogRow>
71
- ) : null}
72
- <DialogRow label='Cost' mono>
45
+ <div className="py-2">
46
+ {session?.createdAt ? <DialogRow label="Started">{formatRelativeTime(session.createdAt)}</DialogRow> : null}
47
+ {session?.numTurns !== undefined ? <DialogRow label="Turns">{session.numTurns}</DialogRow> : null}
48
+ <DialogRow label="Cost" mono>
73
49
  {formatCost(state.totalCostUsd)}
74
50
  </DialogRow>
75
51
  </div>
76
- {/* Only for an engine that has a scratch VFS — for the rest the route
77
- 404s, and a "Files" heading over nothing reads as a failed load. */}
78
- {state.capabilities.vfs ? (
79
- <SessionFiles client={client} sessionId={sessionId} open={open} />
80
- ) : null}
52
+ {state.capabilities.vfs ? <SessionFiles client={client} sessionId={sessionId} open={open} /> : null}
81
53
  </div>
82
54
  </DialogBody>
83
55
  </DialogContent>
@@ -85,47 +57,44 @@ export function SessionInfoDialog({
85
57
  )
86
58
  }
87
59
 
88
- /** Long ids are for pasting elsewhere, so give them a copy target. */
89
60
  function CopyRow({ label, value }: { label: string; value: string }) {
90
61
  return (
91
- <div className='flex items-start justify-between gap-2 py-1.5'>
92
- <div className='min-w-0 flex-1'>
93
- <div className='text-label text-fg-3'>{label}</div>
94
- <div className='mt-0.5 font-mono text-label break-all text-fg-1'>{value}</div>
62
+ <div className="flex items-start justify-between gap-2 py-1.5">
63
+ <div className="min-w-0 flex-1">
64
+ <div className="text-label text-fg-3">{label}</div>
65
+ <div className="mt-0.5 font-mono text-label break-all text-fg-1">{value}</div>
95
66
  </div>
96
67
  <CopyButton value={value} aria-label={`Copy ${label.toLowerCase()}`} />
97
68
  </div>
98
69
  )
99
70
  }
100
71
 
101
- /** Files the agent produced inside the session's VFS. Fetched when the panel
102
- * opens — this is not a live list and nothing pushes changes to it. */
103
- function SessionFiles({
104
- client,
105
- sessionId,
106
- open,
107
- }: {
108
- client: WorkerDeckClient
109
- sessionId: string | undefined
110
- open: boolean
111
- }) {
72
+ function SessionFiles({ client, sessionId, open }: { client: WorkerDeckClient; sessionId: string | undefined; open: boolean }) {
112
73
  const [files, setFiles] = useState<SessionFileInfo[] | undefined>()
113
74
  const [loading, setLoading] = useState(false)
114
75
 
115
76
  useEffect(() => {
116
- if (!open || !sessionId) return
77
+ if (!open || !sessionId) {
78
+ return
79
+ }
117
80
  let cancelled = false
118
81
  setLoading(true)
119
82
  client
120
83
  .listSessionFiles(sessionId)
121
84
  .then((list) => {
122
- if (!cancelled) setFiles(list)
85
+ if (!cancelled) {
86
+ setFiles(list)
87
+ }
123
88
  })
124
89
  .catch(() => {
125
- if (!cancelled) setFiles([])
90
+ if (!cancelled) {
91
+ setFiles([])
92
+ }
126
93
  })
127
94
  .finally(() => {
128
- if (!cancelled) setLoading(false)
95
+ if (!cancelled) {
96
+ setLoading(false)
97
+ }
129
98
  })
130
99
  return () => {
131
100
  cancelled = true
@@ -133,26 +102,25 @@ function SessionFiles({
133
102
  }, [client, sessionId, open])
134
103
 
135
104
  return (
136
- <div className='pt-3'>
137
- <h3 className='text-label font-medium text-fg-3'>Files</h3>
105
+ <div className="pt-3">
106
+ <h3 className="text-label font-medium text-fg-3">Files</h3>
138
107
  {loading ? (
139
- <div className='py-3 text-center'>
140
- <Spinner className='size-4 text-fg-4' />
108
+ <div className="py-3 text-center">
109
+ <Spinner className="size-4 text-fg-4" />
141
110
  </div>
142
111
  ) : !files?.length ? (
143
- <p className='py-2 text-body-sm text-fg-4'>Nothing delivered yet.</p>
112
+ <p className="py-2 text-body-sm text-fg-4">Nothing delivered yet.</p>
144
113
  ) : (
145
- <ul className='mt-1 flex flex-col'>
114
+ <ul className="mt-1 flex flex-col">
146
115
  {files.map((file) => (
147
116
  <li key={file.path}>
148
117
  <a
149
118
  href={sessionId ? client.sessionFileUrl(sessionId, file.path) : undefined}
150
- className='flex items-center gap-2 rounded-md px-1 py-1.5 hover:bg-surface-hover'>
151
- <Download className='size-3.5 shrink-0 text-fg-4' />
152
- <span className='min-w-0 flex-1 truncate font-mono text-label text-fg-1'>
153
- {file.path}
154
- </span>
155
- <span className='shrink-0 text-label text-fg-4'>{formatBytes(file.bytes)}</span>
119
+ className="flex items-center gap-2 rounded-md px-1 py-1.5 hover:bg-surface-hover"
120
+ >
121
+ <Download className="size-3.5 shrink-0 text-fg-4" />
122
+ <span className="min-w-0 flex-1 truncate font-mono text-label text-fg-1">{file.path}</span>
123
+ <span className="shrink-0 text-label text-fg-4">{formatBytes(file.bytes)}</span>
156
124
  </a>
157
125
  </li>
158
126
  ))}