@workerdeck/ui 0.19.0 → 0.21.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.
@@ -340,8 +340,21 @@ interface SessionPanelProps {
340
340
  * need a live closure at the far end. Same shape and same reason as
341
341
  * {@link SessionPanelProps.reveal}.
342
342
  *
343
- * Hosts must clear their request on a session switch: a stale one replayed at
344
- * remount would open a frame the new transcript cannot answer.
343
+ * **Withdrawing the request closes the frame.** The prop going away without a
344
+ * remount is itself a request — "the conversation, plainly" and it leaves
345
+ * through the same path Back takes, so the reader lands on the Task row they
346
+ * came from. It has to mean that, because a host that keeps its request in
347
+ * route state (the dashboard's `?subagent=`) has exactly one way to say it:
348
+ * clear the search — which is what the sidebar's plain session click already
349
+ * navigated with, and what the browser's Back button re-arrives on. Before
350
+ * this, both were silently ignored and the frame outlived the address that
351
+ * claimed it was gone. Still not a controlled value: the panel enters and
352
+ * leaves frames on its own and *reports* through
353
+ * {@link SessionPanelProps.onSubagentChange}; only a **change** of the prop
354
+ * is a request.
355
+ *
356
+ * Hosts must still clear their request on a session switch: a stale one
357
+ * replayed at remount would open a frame the new transcript cannot answer.
345
358
  *
346
359
  * Claude-only in practice, and gated by data rather than by a flag — codex and
347
360
  * provider sessions have no `parentToolUseId`, so they grow no task blocks and
@@ -351,6 +364,30 @@ interface SessionPanelProps {
351
364
  toolUseId: string;
352
365
  nonce: number;
353
366
  };
367
+ /**
368
+ * Which sub-agent the panel now has framed, or `undefined` for the session's
369
+ * own conversation — the outward half of
370
+ * {@link SessionPanelProps.openSubagent}, and a *statement* where that one is
371
+ * a *request*. Deliberately not an echo: the panel enters frames the host
372
+ * never asked for (a Task row pressed in the transcript) and leaves them on
373
+ * its own (Back, Escape, a reveal), so a host that tracked only its own
374
+ * requests would be wrong within one click. No nonce, for the same reason —
375
+ * a state that arrives twice is the same state, where a request that arrives
376
+ * twice is two requests.
377
+ *
378
+ * Never fired for a fresh mount's initial `undefined`, and never fired from
379
+ * an unmount. The first would be a lie with consequences: the seeding effect
380
+ * consumes `openSubagent` in the same commit, so for one commit the state is
381
+ * `undefined` even though a frame is about to open, and a host folding
382
+ * reports into route state would clear the very `?subagent=` request the
383
+ * panel is in the middle of honouring. The second lets a panel keyed away on
384
+ * a session switch stomp what the host already believes about the next one.
385
+ * See the notify effect for the mechanics.
386
+ *
387
+ * What the sessions list's secondary selection feeds on: the row of the agent
388
+ * on screen takes the blue and its session's card steps back to grey.
389
+ */
390
+ onSubagentChange?: (toolUseId: string | undefined) => void;
354
391
  /**
355
392
  * Terminal theme only: hold the prompt of the turn you are reading at the top
356
393
  * of the transcript, as the Claude Code CLI does. The **real row** is pinned
@@ -546,6 +583,7 @@ declare function SessionPanel({
546
583
  scrubberMarks,
547
584
  reveal,
548
585
  openSubagent,
586
+ onSubagentChange,
549
587
  stickyPrompt,
550
588
  controlsSurface,
551
589
  onControls,
@@ -558,4 +596,4 @@ declare function SessionPanel({
558
596
  }: SessionPanelProps): _$react.JSX.Element;
559
597
  //#endregion
560
598
  export { permissionModeChoices as C, PermissionModeSelectProps as S, useAffordances as _, SessionVitals as a, PermissionModeMeta as b, TranscriptDensityProvider as c, TranscriptVariantProvider as d, useTranscriptDensity as f, WithActions as g, TerminalAffordances as h, SessionSurfacePanel as i, TranscriptFont as l, CopyAction as m, SessionPanel as n, TerminalMetrics as o, useTranscriptVariant as p, SessionPanelProps as r, TranscriptDensity as s, SessionControls as t, TranscriptVariant as u, PERMISSION_MODES as v, permissionModeMeta as w, PermissionModeSelect as x, PermissionModeChoice as y };
561
- //# sourceMappingURL=SessionPanel-CnU_IJ3-.d.mts.map
599
+ //# sourceMappingURL=SessionPanel-BjNAnWMF.d.mts.map
@@ -11620,7 +11620,7 @@ const INTERACTIVE = [
11620
11620
  * the engine name — an absent capability hides the control instead of offering
11621
11621
  * one that can only fail.
11622
11622
  */
11623
- function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptDensity = "comfortable", transcriptFont = "sans", affordances, terminalMetrics, scrubber = false, scrubberMarks, reveal, openSubagent, stickyPrompt = false, controlsSurface = "internal", onControls, focusComposerOnClick = false, unseen, readOnly = false, toolHost, cacheTranscript, className }) {
11623
+ function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptDensity = "comfortable", transcriptFont = "sans", affordances, terminalMetrics, scrubber = false, scrubberMarks, reveal, openSubagent, onSubagentChange, stickyPrompt = false, controlsSurface = "internal", onControls, focusComposerOnClick = false, unseen, readOnly = false, toolHost, cacheTranscript, className }) {
11624
11624
  const external = panelSurface === "external";
11625
11625
  const statusExternal = statusSurface === "external";
11626
11626
  const controlsInStatus = controlsSurface === "status" && !statusExternal;
@@ -11657,25 +11657,25 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11657
11657
  setSubagentId(void 0);
11658
11658
  setReturnReveal(void 0);
11659
11659
  }, [sessionId]);
11660
+ const leaveSubagent = useCallback(() => {
11661
+ setSubagentId((current) => {
11662
+ if (current !== void 0) setReturnReveal({
11663
+ toolUseId: current,
11664
+ nonce: Date.now()
11665
+ });
11666
+ });
11667
+ }, []);
11660
11668
  const openSubagentNonce = openSubagent?.nonce;
11661
11669
  const openSubagentId = openSubagent?.toolUseId;
11662
11670
  useEffect(() => {
11663
- if (openSubagentId === void 0) return;
11664
- setSubagentId(openSubagentId);
11671
+ if (openSubagentId === void 0) leaveSubagent();
11672
+ else setSubagentId(openSubagentId);
11665
11673
  }, [openSubagentNonce]);
11666
11674
  const revealNonce = reveal?.nonce;
11667
11675
  useEffect(() => {
11668
11676
  if (revealNonce === void 0) return;
11669
11677
  setSubagentId(void 0);
11670
11678
  }, [revealNonce]);
11671
- const leaveSubagent = useCallback(() => {
11672
- setSubagentId((current) => {
11673
- if (current !== void 0) setReturnReveal({
11674
- toolUseId: current,
11675
- nonce: Date.now()
11676
- });
11677
- });
11678
- }, []);
11679
11679
  useEffect(() => {
11680
11680
  if (subagentId === void 0) return;
11681
11681
  const onKey = (event) => {
@@ -11685,6 +11685,14 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
11685
11685
  window.addEventListener("keydown", onKey);
11686
11686
  return () => window.removeEventListener("keydown", onKey);
11687
11687
  }, [subagentId, leaveSubagent]);
11688
+ const onSubagentChangeRef = useRef(onSubagentChange);
11689
+ onSubagentChangeRef.current = onSubagentChange;
11690
+ const reportedSubagentId = useRef(void 0);
11691
+ useEffect(() => {
11692
+ if (reportedSubagentId.current === subagentId) return;
11693
+ reportedSubagentId.current = subagentId;
11694
+ onSubagentChangeRef.current?.(subagentId);
11695
+ }, [subagentId]);
11688
11696
  const [caughtUp, setCaughtUp] = useState(false);
11689
11697
  useEffect(() => {
11690
11698
  setCaughtUp(false);
@@ -12172,4 +12180,4 @@ function Notice({ level, onDismiss, children }) {
12172
12180
  //#endregion
12173
12181
  export { toolIcon as $, PERMISSION_MODES as A, MenuSeparator as At, skillPrompt as B, badgeVariants as Bt, TerminalQuestionPrompt as C, DialogContent as Ct, parseUserQuestions as D, Menu$1 as Dt, QuestionPrompt as E, DialogTrigger as Et, SkillsDialog as F, SelectItemText as Ft, Band as G, TerminalMarkdown as H, buttonVariants as Ht, McpDialog as I, SelectTrigger as It, Row as J, Blank as K, HostFilesDialog as L, SelectValue as Lt, permissionModeChoices as M, Select$1 as Mt, permissionModeMeta as N, SelectContent as Nt, SubagentStrip as O, MenuContent as Ot, ModelSelect as P, SelectItem as Pt, isMutatingTool as Q, ContextDialog as R, Input as Rt, SessionInfoDialog as S, DialogClose as St, QUESTION_BEHAVIORS as T, DialogRow as Tt, TerminalDiff as U, cn as Ut, TerminalSurface as V, Button as Vt, previewPatch as W, WithActions as X, CopyAction as Y, useAffordances as Z, Conversation as _, Tip as _t, Transcript as a, hashtagTrigger as at, StatusBar as b, Dialog$1 as bt, ToolCallCard as c, PromptArea as ct, Response as d, ProgressRing as dt, TranscriptDensityProvider as et, PromptTokenText as f, Splitter as ft, FileCard as g, copyText as gt, Loader as h, CopyButton as ht, useMinuteClock as i, commandTrigger as it, PermissionModeSelect as j, MenuTrigger as jt, PermissionPrompt as k, MenuItem as kt, SessionEmptyState as l, plainTextToSegments as lt, MessageContent as m, Spinner as mt, UsageDialog as n, useTranscriptDensity as nt, TerminalItemView as o, mentionTrigger as ot, Message as p, CodeBlock as pt, Ink as q, UsageMeters as r, useTranscriptVariant as rt, TerminalTranscript as s, usePromptAreaState as st, SessionPanel as t, TranscriptVariantProvider as tt, Reasoning as u, segmentsToPlainText as ut, ConversationContent as v, TooltipContent as vt, TerminalPermissionPrompt as w, DialogHeader as wt, STATUS_META as x, DialogBody as xt, ConversationScrollButton as y, TooltipProvider as yt, Composer as z, Badge as zt };
12174
12182
 
12175
- //# sourceMappingURL=SessionPanel-CHktI2CF.mjs.map
12183
+ //# sourceMappingURL=SessionPanel-DNuPKg5c.mjs.map