@workerdeck/ui 1.4.0 → 2.1.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.
package/README.md CHANGED
@@ -176,10 +176,10 @@ lose by forgetting a second mount isn't one.
176
176
  - **`transcriptDensity` and `transcriptFont` reach `cards` only.** A terminal has one line height
177
177
  and is monospace by construction. Under `terminal` both are inert rather than broken — a host
178
178
  offering them as settings should say so, or hide them (the dashboard hides them).
179
- - **`midTurnSend: 'hold'` is a client-side hold, not an engine setting.** There is no option that
180
- stops Claude Code folding a mid-turn message into the running turn, so `'hold'` queues the
181
- message in the panel and sends it once the turn ends (an interrupt counts). A held message is
182
- not in the transcript yet — `HeldSendsBar` is its only trace — so do not hide it.
179
+ - **`unseen` is catch-up mode's whole switch.** Passing a watermark draws the boundary, fades what
180
+ was already read and offers the "N new rows since you were last here" bar; passing `undefined`
181
+ draws none of it. The mark is frozen at mount, so it never walks down the transcript under the
182
+ reader. A host offering this as a setting owns the storage — the panel has no preference.
183
183
  - **`scrubber` and `stickyPrompt` reach `terminal` only**, and by construction rather than policy.
184
184
  Both rest on the theme's premise — one line height and one cell make a row's height computable —
185
185
  and under `cards` the flags are inert.
@@ -5,11 +5,11 @@ import { clsx } from "clsx";
5
5
  import { extendTailwindMerge } from "tailwind-merge";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Select } from "@base-ui/react/select";
8
- import { ArrowDown, ArrowDownCircle, ArrowLeft, ArrowUp, AtSign, Brain, ChartPie, Check, CheckSquare, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, ClipboardList, Clock, Code, Copy, Download, File, FileDiff, FileText, Folder, FolderSearch, FolderTree, Gauge, Globe, Hand, Image, Info, Link2, LoaderCircle, MessageCircleQuestion, MessageSquareText, MoreHorizontal, Paperclip, PencilLine, Plug, Power, PowerOff, Puzzle, RefreshCw, RotateCcw, RotateCw, Search, ShieldCheck, SlashSquare, Sparkles, Square, SquarePen, Terminal, TriangleAlert, UsersRound, WifiOff, Wrench, X, Zap } from "lucide-react";
8
+ import { ArrowDown, ArrowDownCircle, ArrowLeft, ArrowRight, ArrowUp, AtSign, Brain, ChartPie, Check, CheckSquare, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, Circle, CircleAlert, ClipboardList, Clock, Code, Copy, Download, File, FileDiff, FileText, Folder, FolderSearch, FolderTree, Gauge, Globe, Hand, Image, Info, Link2, LoaderCircle, MessageCircleQuestion, MessageSquareText, MoreHorizontal, Paperclip, PencilLine, Plug, Power, PowerOff, Puzzle, RefreshCw, RotateCcw, RotateCw, Search, ShieldCheck, SlashSquare, Sparkles, Square, SquarePen, Terminal, TriangleAlert, UsersRound, WifiOff, Wrench, X, Zap } from "lucide-react";
9
9
  import { Menu } from "@base-ui/react/menu";
10
10
  import { Dialog } from "@base-ui/react/dialog";
11
11
  import { Tooltip } from "@base-ui/react/tooltip";
12
- import { PROTOCOL_VERSION, mergeUsage, orderUsageWindows, subagentLabel, toolTitle, usageInfos } from "@workerdeck/protocol";
12
+ import { PROTOCOL_VERSION, mergeUsage, orderUsageWindows, parseTodoWriteInput, sessionTasks, subagentLabel, taskCountLabel, taskSummary, toolTitle, usageInfos, visibleTasks } from "@workerdeck/protocol";
13
13
  import { recapLine, scanPromptTokens, summarizeSince, useAttachments, useClaudeSession, useDraft, useHostFileSearch, useProfileUsage, useToolCallHost } from "@workerdeck/react";
14
14
  import { Streamdown } from "streamdown";
15
15
  import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
@@ -5140,7 +5140,7 @@ function taskBusy(task, children) {
5140
5140
  function taskFailed(task) {
5141
5141
  return callFailed(task);
5142
5142
  }
5143
- function taskSummary(task, children) {
5143
+ function taskSummary$1(task, children) {
5144
5144
  const busy = taskBusy(task, children);
5145
5145
  const calls = children.reduce((n, child) => n + (child.kind === "tool_call" ? 1 : 0), 0);
5146
5146
  const label = taskLabel(task);
@@ -5155,34 +5155,10 @@ const GLYPH = {
5155
5155
  in_progress: "◐",
5156
5156
  completed: "☒"
5157
5157
  };
5158
- function todoEntry(value) {
5159
- if (typeof value !== "object" || value === null) return;
5160
- const raw = value;
5161
- const status = raw.status;
5162
- if (status !== "pending" && status !== "in_progress" && status !== "completed") return;
5163
- const content = typeof raw.content === "string" ? raw.content.trim() : "";
5164
- if (content === "") return;
5165
- const active = typeof raw.activeForm === "string" ? raw.activeForm.trim() : "";
5166
- return {
5167
- status,
5168
- text: status === "in_progress" && active !== "" ? active : content
5169
- };
5170
- }
5171
- function parseTodos(input) {
5172
- const todos = input?.todos;
5173
- if (!Array.isArray(todos) || todos.length === 0) return;
5174
- const out = [];
5175
- for (const value of todos) {
5176
- const entry = todoEntry(value);
5177
- if (entry === void 0) return;
5178
- out.push(entry);
5179
- }
5180
- return out;
5181
- }
5182
5158
  function todoPreview(name, input) {
5183
5159
  if (name !== "TodoWrite") return;
5184
- const todos = parseTodos(input);
5185
- if (todos === void 0) return;
5160
+ const todos = parseTodoWriteInput(input);
5161
+ if (todos === void 0 || todos.length === 0) return;
5186
5162
  const done = todos.reduce((n, todo) => n + (todo.status === "completed" ? 1 : 0), 0);
5187
5163
  const shown = todos.slice(0, PREVIEW_TODOS);
5188
5164
  const hidden = todos.length - shown.length;
@@ -6076,6 +6052,102 @@ function ContextDialog({ usage, engine, open, onOpenChange, className }) {
6076
6052
  });
6077
6053
  }
6078
6054
  //#endregion
6055
+ //#region src/components/agent/TaskList.tsx
6056
+ function TaskList({ tasks, showCompleted, onShowCompletedChange, onSelectTask, className }) {
6057
+ const summary = taskSummary(tasks);
6058
+ const shown = visibleTasks(tasks, showCompleted);
6059
+ const hidden = tasks.length - shown.length;
6060
+ return /* @__PURE__ */ jsxs("div", {
6061
+ className: cn("flex flex-col", className),
6062
+ children: [/* @__PURE__ */ jsxs("div", {
6063
+ className: "flex items-baseline justify-between gap-4 pb-1.5",
6064
+ children: [/* @__PURE__ */ jsxs("span", {
6065
+ className: "text-label text-fg-3",
6066
+ children: [
6067
+ summary.done,
6068
+ " of ",
6069
+ summary.total,
6070
+ " done",
6071
+ summary.failed > 0 ? ` · ${summary.failed} failed` : ""
6072
+ ]
6073
+ }), summary.done > 0 && onShowCompletedChange ? /* @__PURE__ */ jsx("button", {
6074
+ type: "button",
6075
+ onClick: () => onShowCompletedChange(!showCompleted),
6076
+ className: "shrink-0 rounded-[4px] px-1 py-0.5 text-label text-fg-4 outline-none hover:bg-row-hover hover:text-fg-2",
6077
+ children: showCompleted ? "Hide completed" : `Show completed (${summary.done})`
6078
+ }) : null]
6079
+ }), shown.length === 0 ? /* @__PURE__ */ jsx("p", {
6080
+ className: "py-6 text-center text-body-sm text-fg-4",
6081
+ children: tasks.length === 0 ? "No tasks yet — a checklist appears once the agent plans one." : `${hidden} completed, all hidden.`
6082
+ }) : /* @__PURE__ */ jsx("div", {
6083
+ className: "flex flex-col",
6084
+ children: shown.map((task) => /* @__PURE__ */ jsx(TaskRow$1, {
6085
+ task,
6086
+ onSelect: onSelectTask
6087
+ }, task.key))
6088
+ })]
6089
+ });
6090
+ }
6091
+ function TaskRow$1({ task, onSelect }) {
6092
+ const pressable = onSelect !== void 0 && task.toolUseId !== void 0;
6093
+ const body = task.state === "failed" ? "text-danger" : task.state === "done" ? "text-fg-4" : "text-fg-2";
6094
+ const row = /* @__PURE__ */ jsxs(Fragment$1, { children: [
6095
+ /* @__PURE__ */ jsx(TaskIcon, { state: task.state }),
6096
+ /* @__PURE__ */ jsx("span", {
6097
+ className: cn("min-w-0 flex-1 truncate text-left", task.state === "done" ? "line-through" : void 0),
6098
+ children: task.label
6099
+ }),
6100
+ task.detail ? /* @__PURE__ */ jsx("span", {
6101
+ className: "shrink-0 tabular-nums text-fg-4",
6102
+ children: task.detail
6103
+ }) : null,
6104
+ pressable ? /* @__PURE__ */ jsx(ArrowRight, { className: "size-3.5 shrink-0 text-fg-4" }) : null
6105
+ ] });
6106
+ const className = cn("flex w-full items-center gap-1.5 rounded-[4px] px-1.5 py-1 text-body-sm outline-none", body);
6107
+ if (!pressable) return /* @__PURE__ */ jsx("div", {
6108
+ className,
6109
+ children: row
6110
+ });
6111
+ return /* @__PURE__ */ jsx("button", {
6112
+ type: "button",
6113
+ title: task.label,
6114
+ onClick: () => onSelect(task),
6115
+ className: cn(className, "hover:bg-row-active"),
6116
+ children: row
6117
+ });
6118
+ }
6119
+ function TaskIcon({ state }) {
6120
+ switch (state) {
6121
+ case "running": return /* @__PURE__ */ jsx(Spinner, { className: "size-[13px] shrink-0" });
6122
+ case "failed": return /* @__PURE__ */ jsx(CircleAlert, { className: "size-[13px] shrink-0" });
6123
+ case "done": return /* @__PURE__ */ jsx(Check, { className: "size-[13px] shrink-0" });
6124
+ default: return /* @__PURE__ */ jsx(Circle, { className: "size-[13px] shrink-0 text-fg-4" });
6125
+ }
6126
+ }
6127
+ //#endregion
6128
+ //#region src/components/agent/TasksDialog.tsx
6129
+ function TasksDialog({ tasks, showCompleted, onShowCompletedChange, onSelectTask, open, onOpenChange, className }) {
6130
+ return /* @__PURE__ */ jsx(Dialog$1, {
6131
+ open,
6132
+ onOpenChange,
6133
+ children: /* @__PURE__ */ jsxs(DialogContent, {
6134
+ className,
6135
+ children: [/* @__PURE__ */ jsx(DialogHeader, {
6136
+ title: "Tasks",
6137
+ description: "The agent's checklist and the tasks it has spawned"
6138
+ }), /* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsx(TaskList, {
6139
+ tasks,
6140
+ showCompleted,
6141
+ onShowCompletedChange,
6142
+ onSelectTask: onSelectTask ? (task) => {
6143
+ onOpenChange(false);
6144
+ onSelectTask(task);
6145
+ } : void 0
6146
+ }) })]
6147
+ })
6148
+ });
6149
+ }
6150
+ //#endregion
6079
6151
  //#region src/components/agent/EntryIcon.tsx
6080
6152
  function EntryIcon({ type }) {
6081
6153
  if (type === "dir") return /* @__PURE__ */ jsx(Folder, { className: "size-3.5 shrink-0 text-accent" });
@@ -8106,7 +8178,7 @@ function Slot({ onClick, hint, children }) {
8106
8178
  children
8107
8179
  });
8108
8180
  }
8109
- function StatusBar({ state, rateLimits, connected, connection, onOpenStatus, onOpenContext, onOpenUsage, controls, actions, placement = "top", className }) {
8181
+ function StatusBar({ state, rateLimits, connected, connection, onOpenStatus, onOpenContext, onOpenUsage, tasks, onOpenTasks, controls, actions, placement = "top", className }) {
8110
8182
  const meta = STATUS_META[state.status];
8111
8183
  const now = useNow();
8112
8184
  const windows = rateLimits ?? state.rateLimits;
@@ -8114,6 +8186,7 @@ function StatusBar({ state, rateLimits, connected, connection, onOpenStatus, onO
8114
8186
  const weekly = windows?.seven_day;
8115
8187
  const link = connection ?? (connected === false ? "reconnecting" : "live");
8116
8188
  const terminal = useTranscriptVariant() === "terminal";
8189
+ const taskCount = tasks && tasks.length > 0 ? taskSummary(tasks) : void 0;
8117
8190
  return /* @__PURE__ */ jsxs("div", {
8118
8191
  "data-slot": "status-bar",
8119
8192
  className: cn("flex h-[var(--wd-status-bar-height)] items-baseline gap-2 border-border bg-surface p-1.5", placement === "bottom" ? terminal ? void 0 : "border-t" : "border-b", className),
@@ -8157,6 +8230,17 @@ function StatusBar({ state, rateLimits, connected, connection, onOpenStatus, onO
8157
8230
  }) : null]
8158
8231
  })
8159
8232
  }) : null,
8233
+ taskCount ? /* @__PURE__ */ jsx(Slot, {
8234
+ onClick: onOpenTasks,
8235
+ hint: "Tasks",
8236
+ children: /* @__PURE__ */ jsxs("span", {
8237
+ className: "text-label text-fg-3",
8238
+ children: [/* @__PURE__ */ jsx("span", {
8239
+ className: cn("tabular-nums", taskCount.running > 0 ? "text-info" : void 0),
8240
+ children: taskCountLabel(taskCount)
8241
+ }), " tasks"]
8242
+ })
8243
+ }) : null,
8160
8244
  controls ? /* @__PURE__ */ jsx("span", {
8161
8245
  className: "self-center",
8162
8246
  children: controls
@@ -8867,7 +8951,7 @@ function itemHeight(item, m) {
8867
8951
  }
8868
8952
  }
8869
8953
  function blockHeight(block, m) {
8870
- if ("task" in block) return rowH(taskSummary(block.task, taskChildItems(block)), m);
8954
+ if ("task" in block) return rowH(taskSummary$1(block.task, taskChildItems(block)), m);
8871
8955
  if ("run" in block) {
8872
8956
  const busy = block.run.some((item) => item.status === "running" || item.status === "pending");
8873
8957
  return rowH(runSummary(block.run, busy), m);
@@ -9837,7 +9921,7 @@ function TaskRow({ block, fileUrl, onOpenSubagent }) {
9837
9921
  glyph: busy ? pulse : "●",
9838
9922
  glyphTone: failed ? "red" : busy ? "mark" : "dim",
9839
9923
  tone: failed ? "red" : "green",
9840
- children: taskSummary(block.task, children)
9924
+ children: taskSummary$1(block.task, children)
9841
9925
  })
9842
9926
  }), open ? /* @__PURE__ */ jsxs("div", {
9843
9927
  className: "term-nested",
@@ -10823,65 +10907,6 @@ function Transcript({ state, fileUrl, attachmentUrl, canBrowseFiles, hostImage,
10823
10907
  });
10824
10908
  }
10825
10909
  //#endregion
10826
- //#region src/components/agent/held-sends.tsx
10827
- function useHeldSends(options) {
10828
- const [held, setHeld] = useState([]);
10829
- const queue = useRef([]);
10830
- const sendRef = useRef(options.send);
10831
- sendRef.current = options.send;
10832
- const flush = useCallback(() => {
10833
- const queued = queue.current;
10834
- if (queued.length === 0) return;
10835
- queue.current = [];
10836
- setHeld([]);
10837
- for (const item of queued) sendRef.current(item.text, item.attachmentIds);
10838
- }, []);
10839
- useEffect(() => {
10840
- if (!options.busy) flush();
10841
- }, [options.busy, flush]);
10842
- return {
10843
- held,
10844
- submit: useCallback((text, attachmentIds) => {
10845
- if (!options.hold || !options.busy) {
10846
- sendRef.current(text, attachmentIds);
10847
- return;
10848
- }
10849
- queue.current = [...queue.current, {
10850
- text,
10851
- attachmentIds
10852
- }];
10853
- setHeld(queue.current);
10854
- }, [options.hold, options.busy]),
10855
- flush
10856
- };
10857
- }
10858
- function HeldSendsBar({ held, onSendNow }) {
10859
- if (held.length === 0) return null;
10860
- return /* @__PURE__ */ jsx("div", {
10861
- className: "px-3 pt-2",
10862
- children: /* @__PURE__ */ jsxs("div", {
10863
- className: "mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] items-center gap-2 rounded-md border border-border bg-surface px-3 py-1.5 text-label text-fg-3",
10864
- children: [
10865
- /* @__PURE__ */ jsx(Clock, { className: "size-3.5 shrink-0" }),
10866
- /* @__PURE__ */ jsxs("span", {
10867
- className: "min-w-0 flex-1 truncate",
10868
- children: [
10869
- held.length === 1 ? "1 message" : `${held.length} messages`,
10870
- " waiting for this turn to end — ",
10871
- held[held.length - 1].text
10872
- ]
10873
- }),
10874
- /* @__PURE__ */ jsx("button", {
10875
- type: "button",
10876
- onClick: onSendNow,
10877
- className: "shrink-0 underline-offset-2 hover:underline",
10878
- children: "Send now"
10879
- })
10880
- ]
10881
- })
10882
- });
10883
- }
10884
- //#endregion
10885
10910
  //#region src/components/agent/UsageMeters.tsx
10886
10911
  function useMinuteClock(active = true) {
10887
10912
  const [now, setNow] = useState(() => Date.now());
@@ -11033,7 +11058,7 @@ const INTERACTIVE = [
11033
11058
  "[role=\"radio\"]",
11034
11059
  "[role=\"tab\"]"
11035
11060
  ].join(",");
11036
- function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptDensity = "comfortable", transcriptFont = "sans", midTurnSend = "fold", affordances, terminalMetrics, scrubber = false, bookmarks, onToggleBookmark, reveal, openSubagent, onSubagentChange, stickyPrompt = false, controlsSurface = "internal", onControls, focusComposerOnClick = false, unseen, readOnly = false, toolHost, clientTools, cacheTranscript, emptyState, onLinkClick, fontSize, className }) {
11061
+ function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptDensity = "comfortable", transcriptFont = "sans", affordances, terminalMetrics, scrubber = false, bookmarks, onToggleBookmark, reveal, subagents, openSubagent, onSubagentChange, stickyPrompt = false, controlsSurface = "internal", onControls, focusComposerOnClick = false, unseen, readOnly = false, toolHost, clientTools, cacheTranscript, emptyState, onLinkClick, fontSize, className }) {
11037
11062
  const effectiveTermFontSize = terminalMetrics?.fontSize ?? fontSize;
11038
11063
  const effectiveTermLineHeight = terminalMetrics?.lineHeight ?? (fontSize !== void 0 ? Math.round(fontSize * (18 / 13)) : void 0);
11039
11064
  const external = panelSurface === "external";
@@ -11042,6 +11067,8 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11042
11067
  const controlsExternal = controlsSurface === "external" || controlsInStatus;
11043
11068
  const [protocolError, setProtocolError] = useState(void 0);
11044
11069
  const [panel, setPanel] = useState();
11070
+ const [showCompletedTasks, setShowCompletedTasks] = useState(false);
11071
+ const [taskReveal, setTaskReveal] = useState();
11045
11072
  const { state, connection, replaying, protocolMismatch, models, effectiveModel, handle, send, approve, deny, interrupt, setModel, setPermissionMode, reconnectNow, loadFullResult } = useClaudeSession(client, sessionId, {
11046
11073
  onProtocolError: setProtocolError,
11047
11074
  cacheTranscript
@@ -11096,6 +11123,14 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11096
11123
  const stamps = Object.values(usage).map((w) => w.updatedAt);
11097
11124
  return stamps.length > 0 ? Math.max(...stamps) : void 0;
11098
11125
  }, [usage]);
11126
+ const tasks = useMemo(() => sessionTasks({
11127
+ checklist: state.checklist,
11128
+ subagents: subagents ?? state.session?.subagents
11129
+ }), [
11130
+ state.checklist,
11131
+ subagents,
11132
+ state.session?.subagents
11133
+ ]);
11099
11134
  const onVitalsRef = useRef(onVitals);
11100
11135
  onVitalsRef.current = onVitals;
11101
11136
  const vitalsModel = effectiveModel ?? state.model;
@@ -11113,6 +11148,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11113
11148
  skills: state.skills,
11114
11149
  cwd: state.cwd,
11115
11150
  contextUsage: state.contextUsage,
11151
+ tasks,
11116
11152
  rateLimits,
11117
11153
  rateLimitsUpdatedAt: usageUpdatedAt,
11118
11154
  itemCount: state.items.length,
@@ -11130,6 +11166,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11130
11166
  state.skills,
11131
11167
  state.cwd,
11132
11168
  state.contextUsage,
11169
+ tasks,
11133
11170
  rateLimits,
11134
11171
  usageUpdatedAt,
11135
11172
  state.items.length,
@@ -11191,11 +11228,6 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11191
11228
  argumentHint: "<model>"
11192
11229
  }, ...state.commands];
11193
11230
  }, [state.commands]);
11194
- const heldSends = useHeldSends({
11195
- hold: midTurnSend === "hold",
11196
- busy: busy && !ended,
11197
- send
11198
- });
11199
11231
  const handleSend = (text, attachmentIds) => {
11200
11232
  if (attachmentIds.length === 0) {
11201
11233
  const modelCommand = /^\/model\s+(\S+)$/.exec(text);
@@ -11210,7 +11242,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11210
11242
  }
11211
11243
  setCaughtUp(true);
11212
11244
  repinTranscript.current?.();
11213
- heldSends.submit(text, attachmentIds);
11245
+ send(text, attachmentIds);
11214
11246
  };
11215
11247
  const actionsMenu = /* @__PURE__ */ jsxs(Menu$1, { children: [/* @__PURE__ */ jsx(MenuTrigger, { render: /* @__PURE__ */ jsx(Button, {
11216
11248
  variant: "ghost",
@@ -11268,6 +11300,8 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11268
11300
  onOpenStatus: external && !onOpenPanel ? void 0 : () => openPanel("info"),
11269
11301
  onOpenContext: external && !onOpenPanel ? void 0 : () => openPanel("context"),
11270
11302
  onOpenUsage: external && !onOpenPanel ? void 0 : () => openPanel("usage"),
11303
+ tasks,
11304
+ onOpenTasks: external && !onOpenPanel ? void 0 : () => openPanel("tasks"),
11271
11305
  actions: headerTakesActions ? void 0 : menu
11272
11306
  });
11273
11307
  const panelRef = useRef(null);
@@ -11359,7 +11393,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11359
11393
  from: catchUp.itemCount,
11360
11394
  since: catchUp.since
11361
11395
  } : void 0,
11362
- reveal: returnReveal ?? reveal,
11396
+ reveal: taskReveal ?? returnReveal ?? reveal,
11363
11397
  frame: subagentId === void 0 ? void 0 : { parentToolUseId: subagentId },
11364
11398
  onOpenSubagent: enterSubagent,
11365
11399
  emptyState,
@@ -11434,10 +11468,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11434
11468
  })
11435
11469
  })
11436
11470
  }) : null,
11437
- readOnly || subagentId !== void 0 ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HeldSendsBar, {
11438
- held: heldSends.held,
11439
- onSendNow: heldSends.flush
11440
- }), /* @__PURE__ */ jsx(Composer, {
11471
+ readOnly || subagentId !== void 0 ? null : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Composer, {
11441
11472
  ref: composerRef,
11442
11473
  onSend: handleSend,
11443
11474
  onInterrupt: interrupt,
@@ -11453,7 +11484,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11453
11484
  fontSize: effectiveTermFontSize,
11454
11485
  lineHeight: effectiveTermLineHeight,
11455
11486
  affordances
11456
- })] }),
11487
+ }) }),
11457
11488
  statusPlacement === "bottom" ? statusBar : null,
11458
11489
  !external ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
11459
11490
  /* @__PURE__ */ jsx(SessionInfoDialog, {
@@ -11485,6 +11516,19 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11485
11516
  open: panel === "mcp",
11486
11517
  onOpenChange: (next) => setPanel(next ? "mcp" : void 0)
11487
11518
  }),
11519
+ /* @__PURE__ */ jsx(TasksDialog, {
11520
+ tasks,
11521
+ showCompleted: showCompletedTasks,
11522
+ onShowCompletedChange: setShowCompletedTasks,
11523
+ onSelectTask: (task) => {
11524
+ if (task.toolUseId) setTaskReveal({
11525
+ toolUseId: task.toolUseId,
11526
+ nonce: Date.now()
11527
+ });
11528
+ },
11529
+ open: panel === "tasks",
11530
+ onOpenChange: (next) => setPanel(next ? "tasks" : void 0)
11531
+ }),
11488
11532
  /* @__PURE__ */ jsx(SkillsDialog, {
11489
11533
  skills: state.skills,
11490
11534
  open: panel === "skills",
@@ -11568,6 +11612,6 @@ function Notice({ level, onDismiss, children }) {
11568
11612
  });
11569
11613
  }
11570
11614
  //#endregion
11571
- export { Ink as $, PermissionPrompt as A, DialogHeader as At, EntryIcon as B, SelectItem as Bt, SessionInfoDialog as C, Tip as Ct, QuestionPrompt as D, DialogBody as Dt, QUESTION_BEHAVIORS as E, Dialog$1 as Et, permissionModeMeta as F, MenuItem as Ft, TerminalSurface as G, Input as Gt, contextNote as H, SelectTrigger as Ht, ModelSelect as I, MenuSeparator as It, TerminalMarkdown as J, Button as Jt, ToolTitleProvider as K, Badge as Kt, SkillsDialog as L, MenuTrigger as Lt, PERMISSION_MODES as M, DialogTrigger as Mt, PermissionModeSelect as N, Menu$1 as Nt, parseUserQuestions as O, DialogClose as Ot, permissionModeChoices as P, MenuContent as Pt, Blank as Q, McpDialog as R, Select$1 as Rt, STATUS_META as S, copyText as St, TerminalPermissionPrompt as T, TooltipProvider as Tt, Composer as U, SelectValue as Ut, ContextDialog as V, SelectItemText as Vt, skillPrompt as W, PortalScope as Wt, previewPatch as X, cn as Xt, TerminalDiff as Y, buttonVariants as Yt, Band as Z, Loader as _, ProgressRing as _t, HeldSendsBar as a, toolIcon as at, ConversationScrollButton as b, Spinner as bt, ToolCallCard as c, useTranscriptDensity as ct, Message as d, hashtagTrigger as dt, Row as et, MessageContent as f, mentionTrigger as ft, SessionEmptyState as g, segmentsToPlainText as gt, TerminalTranscript as h, plainTextToSegments as ht, useMinuteClock as i, isMutatingTool as it, Response as j, DialogRow as jt, SubagentStrip as k, DialogContent as kt, Reasoning as l, useTranscriptVariant as lt, TerminalItemView as m, PromptArea as mt, UsageDialog as n, WithActions as nt, useHeldSends as o, TranscriptDensityProvider as ot, FileCard as p, usePromptAreaState as pt, useToolTitle as q, badgeVariants as qt, UsageMeters as r, useAffordances as rt, Transcript as s, TranscriptVariantProvider as st, SessionPanel as t, CopyAction as tt, PromptTokenText as u, commandTrigger as ut, Conversation as v, Splitter as vt, TerminalQuestionPrompt as w, TooltipContent as wt, StatusBar as x, CopyButton as xt, ConversationContent as y, CodeBlock as yt, HostFilesDialog as z, SelectContent as zt };
11615
+ export { Ink as $, PERMISSION_MODES as A, DialogHeader as At, TaskList as B, SelectItem as Bt, TerminalPermissionPrompt as C, Tip as Ct, SubagentStrip as D, DialogBody as Dt, parseUserQuestions as E, Dialog$1 as Et, SkillsDialog as F, MenuItem as Ft, TerminalSurface as G, Input as Gt, contextNote as H, SelectTrigger as Ht, McpDialog as I, MenuSeparator as It, TerminalMarkdown as J, Button as Jt, ToolTitleProvider as K, Badge as Kt, HostFilesDialog as L, MenuTrigger as Lt, permissionModeChoices as M, DialogTrigger as Mt, permissionModeMeta as N, Menu$1 as Nt, PermissionPrompt as O, DialogClose as Ot, ModelSelect as P, MenuContent as Pt, Blank as Q, EntryIcon as R, Select$1 as Rt, TerminalQuestionPrompt as S, copyText as St, QuestionPrompt as T, TooltipProvider as Tt, Composer as U, SelectValue as Ut, ContextDialog as V, SelectItemText as Vt, skillPrompt as W, PortalScope as Wt, previewPatch as X, cn as Xt, TerminalDiff as Y, buttonVariants as Yt, Band as Z, ConversationContent as _, ProgressRing as _t, Transcript as a, toolIcon as at, STATUS_META as b, Spinner as bt, PromptTokenText as c, useTranscriptDensity as ct, FileCard as d, hashtagTrigger as dt, Row as et, TerminalItemView as f, mentionTrigger as ft, Conversation as g, segmentsToPlainText as gt, Loader as h, plainTextToSegments as ht, useMinuteClock as i, isMutatingTool as it, PermissionModeSelect as j, DialogRow as jt, Response as k, DialogContent as kt, Message as l, useTranscriptVariant as lt, SessionEmptyState as m, PromptArea as mt, UsageDialog as n, WithActions as nt, ToolCallCard as o, TranscriptDensityProvider as ot, TerminalTranscript as p, usePromptAreaState as pt, useToolTitle as q, badgeVariants as qt, UsageMeters as r, useAffordances as rt, Reasoning as s, TranscriptVariantProvider as st, SessionPanel as t, CopyAction as tt, MessageContent as u, commandTrigger as ut, ConversationScrollButton as v, Splitter as vt, QUESTION_BEHAVIORS as w, TooltipContent as wt, SessionInfoDialog as x, CopyButton as xt, StatusBar as y, CodeBlock as yt, TasksDialog as z, SelectContent as zt };
11572
11616
 
11573
- //# sourceMappingURL=SessionPanel-DQp2oStr.mjs.map
11617
+ //# sourceMappingURL=SessionPanel-DrMj8Yv0.mjs.map