@workerdeck/ui 0.20.0 → 0.22.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 (43) hide show
  1. package/README.md +3 -2
  2. package/build/{SessionPanel-CnU_IJ3-.d.mts → SessionPanel-13l25ubU.d.mts} +55 -7
  3. package/build/{SessionPanel-CHktI2CF.mjs → SessionPanel-DgwjH4Ve.mjs} +642 -231
  4. package/build/SessionPanel-DgwjH4Ve.mjs.map +1 -0
  5. package/build/index.d.mts +309 -53
  6. package/build/index.mjs +534 -397
  7. package/build/index.mjs.map +1 -1
  8. package/build/scoped.css +3547 -0
  9. package/build/workspace.d.mts +10 -1
  10. package/build/workspace.mjs +4 -2
  11. package/build/workspace.mjs.map +1 -1
  12. package/package.json +15 -7
  13. package/src/components/agent/Composer.tsx +10 -10
  14. package/src/components/agent/ContextDialog.tsx +3 -2
  15. package/src/components/agent/Conversation.tsx +1 -1
  16. package/src/components/agent/McpDialog.tsx +3 -1
  17. package/src/components/agent/Scrubber.tsx +248 -0
  18. package/src/components/agent/SessionBrowser.tsx +113 -293
  19. package/src/components/agent/SessionItem.tsx +538 -0
  20. package/src/components/agent/SessionList.tsx +3 -1
  21. package/src/components/agent/SessionPanel.tsx +112 -21
  22. package/src/components/agent/SessionStatusIcon.tsx +43 -0
  23. package/src/components/agent/SessionSteps.tsx +118 -61
  24. package/src/components/agent/SessionWorkspace.tsx +11 -0
  25. package/src/components/agent/SkillsDialog.tsx +3 -2
  26. package/src/components/agent/StatusBar.tsx +1 -1
  27. package/src/components/agent/Transcript.tsx +147 -73
  28. package/src/components/agent/UsageDialog.tsx +3 -1
  29. package/src/components/agent/scrubber-marks.ts +277 -0
  30. package/src/components/terminal/PermissionPrompt.tsx +3 -0
  31. package/src/components/terminal/QuestionPrompt.tsx +3 -0
  32. package/src/components/terminal/StatusLine.tsx +3 -1
  33. package/src/components/ui/AlertDialog.tsx +23 -20
  34. package/src/components/ui/Dialog.tsx +26 -23
  35. package/src/components/ui/Menu.tsx +20 -17
  36. package/src/components/ui/PortalScope.tsx +27 -0
  37. package/src/components/ui/Select.tsx +19 -16
  38. package/src/components/ui/Tooltip.tsx +13 -10
  39. package/src/index.ts +5 -1
  40. package/src/styles/scoped.entry.css +16 -0
  41. package/src/styles/terminal.css +1 -1
  42. package/src/styles/theme.css +223 -8
  43. package/build/SessionPanel-CHktI2CF.mjs.map +0 -1
package/build/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as formatDuration, c as formatRelativeTime, d as rateLimitWindowSeconds, f as toolInputPreview, i as formatCountdown, l as formatTokens, n as formatBytes, o as formatRateLimitWindow, r as formatCost, s as formatRateLimitWindowLong, t as formatAgoPrecise, u as friendlyModel } from "./format-ljc3lKpA.mjs";
2
- import { C as permissionModeChoices, S as PermissionModeSelectProps, _ as useAffordances, a as SessionVitals, b as PermissionModeMeta, c as TranscriptDensityProvider, d as TranscriptVariantProvider, f as useTranscriptDensity, g as WithActions, h as TerminalAffordances, i as SessionSurfacePanel, l as TranscriptFont, m as CopyAction, n as SessionPanel, o as TerminalMetrics, p as useTranscriptVariant, r as SessionPanelProps, s as TranscriptDensity, t as SessionControls, u as TranscriptVariant, v as PERMISSION_MODES, w as permissionModeMeta, x as PermissionModeSelect, y as PermissionModeChoice } from "./SessionPanel-CnU_IJ3-.mjs";
2
+ import { C as permissionModeChoices, S as PermissionModeSelectProps, _ as useAffordances, a as SessionVitals, b as PermissionModeMeta, c as TranscriptDensityProvider, d as TranscriptVariantProvider, f as useTranscriptDensity, g as WithActions, h as TerminalAffordances, i as SessionSurfacePanel, l as TranscriptFont, m as CopyAction, n as SessionPanel, o as TerminalMetrics, p as useTranscriptVariant, r as SessionPanelProps, s as TranscriptDensity, t as SessionControls, u as TranscriptVariant, v as PERMISSION_MODES, w as permissionModeMeta, x as PermissionModeSelect, y as PermissionModeChoice } from "./SessionPanel-13l25ubU.mjs";
3
3
  import * as _$react from "react";
4
4
  import { ButtonHTMLAttributes, FunctionComponent, HTMLAttributes, InputHTMLAttributes, ReactElement, ReactNode, Ref, RefObject, TextareaHTMLAttributes } from "react";
5
5
  import { VariantProps } from "class-variance-authority";
@@ -883,17 +883,21 @@ interface TranscriptProps {
883
883
  /** Terminal theme only: the pointer affordances a real terminal cannot offer.
884
884
  * `false` for none. See {@link TerminalAffordances}. */
885
885
  affordances?: TerminalAffordances | boolean;
886
- /** Terminal theme only: hold the prompt of the turn being read at the top of
887
- * the scroller. The *real* row is pinned, not a copy see `TranscriptRows`. */
886
+ /** Hold the prompt of the turn being read at the top of the scroller. Works
887
+ * in both variants: the terminal clips to one line, cards shows a frosted
888
+ * bar. The *real* row is pinned, not a copy — see `TranscriptRows`. */
888
889
  stickyPrompt?: boolean;
889
890
  /**
890
- * Terminal theme only: mount the overview-ruler scrubber — a 2ch rail of
891
- * marks (your prompts, each turn's response and result as one mark, errors,
892
- * the pending approval, the catch-up boundary) that replaces the native
893
- * scrollbar. Ignored under `cards`: the rail's positions ride the height
894
- * calculator, which has no claim there. With `affordances={false}` the rail
895
- * degrades to passive paint no drag, peek or click and the native
896
- * scrollbar stays. See {@link TerminalScrubber}.
891
+ * Mount the overview scrubber — a 12px rail of marks (your prompts, each
892
+ * turn's response and result as one mark, errors, the pending approval, the
893
+ * catch-up boundary) over the scroller's right edge. Two rails behind one
894
+ * prop: under `terminal` it is the pixel-exact ruler that replaces the
895
+ * native scrollbar (positions ride the height calculator; drag scrubs), and
896
+ * under `cards` it is the **proportional annotation rail**positioned by
897
+ * `itemIndex / items.length`, because proportional text gives the
898
+ * calculator no claim there — where the native scrollbar stays and the rail
899
+ * only peeks and jumps. With `affordances={false}` either rail degrades to
900
+ * passive paint — no drag, peek or click.
897
901
  */
898
902
  scrubber?: boolean;
899
903
  /**
@@ -989,6 +993,12 @@ interface TranscriptProps {
989
993
  * sessions list instead.
990
994
  */
991
995
  onOpenSubagent?: (toolUseId: string) => void;
996
+ /**
997
+ * Replaces the default empty state when the transcript has no items. Pass a
998
+ * `ReactNode` to show your product's own onboarding instead of WorkerDeck's
999
+ * generic "`>_` Tell the agent what to do." placeholder.
1000
+ */
1001
+ emptyState?: ReactNode;
992
1002
  className?: string;
993
1003
  }
994
1004
  declare function Transcript({
@@ -1012,6 +1022,7 @@ declare function Transcript({
1012
1022
  reveal,
1013
1023
  frame,
1014
1024
  onOpenSubagent,
1025
+ emptyState,
1015
1026
  className
1016
1027
  }: TranscriptProps): _$react.JSX.Element;
1017
1028
  //#endregion
@@ -1115,6 +1126,7 @@ declare function TerminalTranscript({
1115
1126
  //#endregion
1116
1127
  //#region src/components/terminal/StatusLine.d.ts
1117
1128
  interface TerminalStatusLineProps {
1129
+ className?: string;
1118
1130
  state: TranscriptState;
1119
1131
  /** Plan windows to read from, when they should not be the session's own — the
1120
1132
  * gateway's per-profile state merged over this transcript's. See
@@ -1130,6 +1142,7 @@ interface TerminalStatusLineProps {
1130
1142
  onOpenUsage?: () => void;
1131
1143
  }
1132
1144
  declare function TerminalStatusLine({
1145
+ className,
1133
1146
  state,
1134
1147
  rateLimits,
1135
1148
  connection,
@@ -1161,11 +1174,13 @@ interface TerminalPermissionPromptProps {
1161
1174
  /** `message` is fed back to the agent, which can then try something else;
1162
1175
  * `interrupt` also stops the turn. */
1163
1176
  onDeny: (requestId: string, message?: string, interrupt?: boolean) => void;
1177
+ className?: string;
1164
1178
  }
1165
1179
  declare function TerminalPermissionPrompt({
1166
1180
  request,
1167
1181
  onApprove,
1168
- onDeny
1182
+ onDeny,
1183
+ className
1169
1184
  }: TerminalPermissionPromptProps): _$react.JSX.Element;
1170
1185
  //#endregion
1171
1186
  //#region src/components/terminal/QuestionPrompt.d.ts
@@ -1176,11 +1191,13 @@ interface TerminalQuestionPromptProps {
1176
1191
  onAnswer: (requestId: string, updatedInput: Record<string, unknown>) => void;
1177
1192
  /** Deny the tool — the model proceeds without an answer. */
1178
1193
  onDismiss: (requestId: string, message?: string) => void;
1194
+ className?: string;
1179
1195
  }
1180
1196
  declare function TerminalQuestionPrompt({
1181
1197
  request,
1182
1198
  onAnswer,
1183
- onDismiss
1199
+ onDismiss,
1200
+ className
1184
1201
  }: TerminalQuestionPromptProps): _$react.JSX.Element;
1185
1202
  //#endregion
1186
1203
  //#region src/components/terminal/diff.d.ts
@@ -1641,6 +1658,7 @@ interface ContextDialogProps {
1641
1658
  usage?: ContextUsage;
1642
1659
  open: boolean;
1643
1660
  onOpenChange: (open: boolean) => void;
1661
+ className?: string;
1644
1662
  }
1645
1663
  /**
1646
1664
  * What is in the model's context window right now, category by category.
@@ -1652,7 +1670,8 @@ interface ContextDialogProps {
1652
1670
  declare function ContextDialog({
1653
1671
  usage,
1654
1672
  open,
1655
- onOpenChange
1673
+ onOpenChange,
1674
+ className
1656
1675
  }: ContextDialogProps): _$react.JSX.Element;
1657
1676
  //#endregion
1658
1677
  //#region src/components/agent/UsageDialog.d.ts
@@ -1678,6 +1697,7 @@ interface UsageDialogProps {
1678
1697
  updatedAt?: number;
1679
1698
  open: boolean;
1680
1699
  onOpenChange: (open: boolean) => void;
1700
+ className?: string;
1681
1701
  }
1682
1702
  /**
1683
1703
  * The session's view of the plan: every window as a meter (see
@@ -1690,7 +1710,8 @@ declare function UsageDialog({
1690
1710
  totalCostUsd,
1691
1711
  updatedAt,
1692
1712
  open,
1693
- onOpenChange
1713
+ onOpenChange,
1714
+ className
1694
1715
  }: UsageDialogProps): _$react.JSX.Element;
1695
1716
  //#endregion
1696
1717
  //#region src/components/agent/UsageMeters.d.ts
@@ -1768,6 +1789,7 @@ interface McpDialogProps {
1768
1789
  * that 501 are worse than buttons that aren't there.
1769
1790
  */
1770
1791
  canManageServers?: boolean;
1792
+ className?: string;
1771
1793
  }
1772
1794
  /**
1773
1795
  * The session's MCP servers, at the CLI's own `/mcp` depth: servers → one server
@@ -1786,7 +1808,8 @@ declare function McpDialog({
1786
1808
  sessionId,
1787
1809
  open,
1788
1810
  onOpenChange,
1789
- canManageServers
1811
+ canManageServers,
1812
+ className
1790
1813
  }: McpDialogProps): _$react.JSX.Element;
1791
1814
  //#endregion
1792
1815
  //#region src/components/agent/SkillsDialog.d.ts
@@ -1797,6 +1820,7 @@ interface SkillsDialogProps {
1797
1820
  /** Insert a skill's opening message into the composer, if the host offers
1798
1821
  * that. Omit and the dialog is read-only. */
1799
1822
  onUse?: (skill: SkillInfo) => void;
1823
+ className?: string;
1800
1824
  }
1801
1825
  /**
1802
1826
  * What this session's engine can do beyond its own tools: the skills it found,
@@ -1815,7 +1839,8 @@ declare function SkillsDialog({
1815
1839
  skills,
1816
1840
  open,
1817
1841
  onOpenChange,
1818
- onUse
1842
+ onUse,
1843
+ className
1819
1844
  }: SkillsDialogProps): _$react.JSX.Element;
1820
1845
  //#endregion
1821
1846
  //#region src/components/agent/HostFilesDialog.d.ts
@@ -1848,12 +1873,14 @@ interface SessionListItemProps {
1848
1873
  active?: boolean;
1849
1874
  onSelect?: (id: string) => void;
1850
1875
  onDelete?: (id: string) => void;
1876
+ className?: string;
1851
1877
  }
1852
1878
  declare function SessionListItem({
1853
1879
  session,
1854
1880
  active,
1855
1881
  onSelect,
1856
- onDelete
1882
+ onDelete,
1883
+ className
1857
1884
  }: SessionListItemProps): _$react.JSX.Element;
1858
1885
  interface SessionListProps {
1859
1886
  sessions: SessionInfo[];
@@ -1872,6 +1899,37 @@ declare function SessionList({
1872
1899
  className
1873
1900
  }: SessionListProps): _$react.JSX.Element;
1874
1901
  //#endregion
1902
+ //#region src/components/agent/SessionStatusIcon.d.ts
1903
+ /**
1904
+ * State as one glyph — a ringing bell when it wants a human, a spinner while it
1905
+ * works, a moon when it is only sleeping. Replaces the text badge: in a sidebar
1906
+ * the word costs more room than it earns, and the states that matter are the two
1907
+ * you can recognise without reading.
1908
+ *
1909
+ * **It reads `row.state`, not `info.status`, and that distinction is the whole
1910
+ * point of the row model.** `sessionState` already folds in the arm this glyph
1911
+ * cannot see for itself: a *background* sub-agent outlives its turn by design,
1912
+ * so the turn ends, `status` comes to rest at `idle`, and the agent keeps
1913
+ * working. Reading the raw status drew a **moon on a row filed under the
1914
+ * "Working" header** — the list contradicting itself on one line, which is
1915
+ * exactly what a derived view model exists to prevent. The value was in scope
1916
+ * and unread.
1917
+ *
1918
+ * The terminal statuses still come off `info.status`, because `ended` collapses
1919
+ * `failed` and `closed` into one bucket and those are worth telling apart here.
1920
+ *
1921
+ * It lives in its own file rather than inside the dashboard's browser because
1922
+ * the extension's cards draw it too, and a second copy there is how the two
1923
+ * lists last disagreed about what a parked session looks like.
1924
+ */
1925
+ declare function SessionStatusIcon({
1926
+ row,
1927
+ className
1928
+ }: {
1929
+ row: SessionRow;
1930
+ className?: string;
1931
+ }): _$react.JSX.Element;
1932
+ //#endregion
1875
1933
  //#region src/components/agent/SessionBrowser.d.ts
1876
1934
  /**
1877
1935
  * A sessions list with the affordances a list of thirty needs: search, facets,
@@ -1895,6 +1953,13 @@ interface SessionBrowserProps {
1895
1953
  * phone — makes the scope filter genuinely inert rather than empty. */
1896
1954
  scope?: WorkspaceScope;
1897
1955
  activeId?: string;
1956
+ /**
1957
+ * Which sub-agent the host currently has open, by tool-use id — the *finer*
1958
+ * of the two selections. The card holding it drops to the secondary grey and
1959
+ * that step takes the blue; see `SessionItem`. A host with no sub-agent
1960
+ * surface leaves it undefined and nothing changes.
1961
+ */
1962
+ activeSubagentId?: string;
1898
1963
  onSelect?: (row: SessionRow) => void;
1899
1964
  onDelete?: (row: SessionRow) => void;
1900
1965
  /**
@@ -1923,6 +1988,11 @@ interface SessionBrowserProps {
1923
1988
  * transcript to a `Task` row. Absent, the sub-agent list still expands and a
1924
1989
  * step just opens its session — see `SessionRowItemProps`. */
1925
1990
  onSelectSubagent?: (row: SessionRow, toolUseId: string) => void;
1991
+ /** Open a session and travel to one of its **tasks** — see
1992
+ * `SessionItem.onRevealStep`. A task has no agent behind it, so it is a place
1993
+ * to go rather than a thing to open, and framing it as an agent drew an empty
1994
+ * view. */
1995
+ onRevealStep?: (row: SessionRow, toolUseId: string) => void;
1926
1996
  /** Rendered when nothing at all exists (as opposed to nothing matching). */
1927
1997
  emptyState?: React.ReactNode;
1928
1998
  /**
@@ -1971,38 +2041,168 @@ declare function SessionBrowser({
1971
2041
  onConfigChange,
1972
2042
  scope,
1973
2043
  activeId,
2044
+ activeSubagentId,
1974
2045
  onSelect,
1975
2046
  onDelete,
1976
2047
  onRename,
1977
2048
  onClearContext,
1978
2049
  onSelectSubagent,
2050
+ onRevealStep,
1979
2051
  emptyState,
1980
2052
  showControls,
1981
2053
  projectIcons,
1982
2054
  className
1983
2055
  }: SessionBrowserProps): _$react.JSX.Element;
2056
+ //#endregion
2057
+ //#region src/components/agent/SessionItem.d.ts
1984
2058
  /**
1985
- * State as one glypha ringing bell when it wants a human, a spinner while it
1986
- * works, a moon when it is only sleeping. Replaces the text badge: in a sidebar
1987
- * the word costs more room than it earns, and the states that matter are the two
1988
- * you can recognise without reading.
1989
- *
1990
- * **It reads `row.state`, not `info.status`, and that distinction is the whole
1991
- * point of the row model.** `sessionState` already folds in the arm this glyph
1992
- * cannot see for itself: a *background* sub-agent outlives its turn by design, so
1993
- * the turn ends, `status` comes to rest at `idle`, and the agent keeps working.
1994
- * Reading the raw status drew a **moon on a row filed under the "Working"
1995
- * header** the list contradicting itself on one line, which is exactly what a
1996
- * derived view model exists to prevent. The value was in scope and unread.
1997
- *
1998
- * The terminal statuses still come off `info.status`, because `ended` collapses
1999
- * `failed` and `closed` into one bucket and those are worth telling apart here.
2059
+ * One session in a list the **card**, and the only drawing of it in the
2060
+ * product.
2061
+ *
2062
+ * The dashboard's `SessionBrowser` and the VS Code sidebar both render this;
2063
+ * before it existed they rendered two hand-kept copies that agreed on the model
2064
+ * and disagreed on every measurement, and the two lists read as two products.
2065
+ * iOS mirrors this file's geometry rather than either copy.
2066
+ *
2067
+ * ## The shape
2068
+ *
2069
+ * A 4px-padded, 4px-rounded card whose whole surface is the hit target, holding
2070
+ * two 20px lines and, when it is open, the work under them.
2071
+ *
2072
+ * **Line one is state and identity**: the status glyph leads, the title takes
2073
+ * the rest, and the line closes with the unread badge and the context ring. The
2074
+ * glyph leads because a sessions list is scanned for *state* first — which of
2075
+ * these is working, which is waiting on me — and the title is what you read once
2076
+ * the glyph has told you which row to read. The two readings that close the line
2077
+ * are the two that change while you are looking at them.
2078
+ *
2079
+ * **Line two is identity and cost**: the engine's mark and its model in the
2080
+ * vendor's own colour, then the project, then everything else the host wants
2081
+ * said, then the age — a `·`-joined run that ends in the one part of it that
2082
+ * keeps moving. The line's right edge belongs to the disclosure (which doubles
2083
+ * as the count of the work below, so the card says how much there is without
2084
+ * being opened) and to the host's own actions.
2085
+ *
2086
+ * **The gutter is one 16px cell, shared by both lines.** The two glyphs are
2087
+ * different sizes and laying them out as plain flex children starts the two
2088
+ * text columns at different x — two pixels, invisible as a measurement and
2089
+ * obvious as a misalignment. Centring inside a fixed cell fixes the text edges
2090
+ * and the ink centres at once. It is the terminal gutter's argument at card
2091
+ * scale.
2092
+ *
2093
+ * ## Selection
2094
+ *
2095
+ * **Selection is the card's own fill**, not a gutter bar: the card is an inset
2096
+ * shape with air around it, so filling it is unambiguous in a way a fill on a
2097
+ * full-bleed row is not, and it leaves the left edge to the state glyph.
2098
+ *
2099
+ * There are **two selections at two grains**, and the card and its steps split
2100
+ * them:
2101
+ *
2102
+ * | what is on screen | card | the step |
2103
+ * | --- | --- | --- |
2104
+ * | nothing | transparent, hovers | transparent, hovers |
2105
+ * | this session | `--row-selected` (blue) | transparent, hovers |
2106
+ * | one of its sub-agents | `--row-selected-weak` (grey) | `--row-selected` (blue) |
2107
+ *
2108
+ * **The blue always marks the finest thing selected.** Opening a sub-agent
2109
+ * selects its session too, so both claims are true at once and the blue can only
2110
+ * carry one; it goes to the agent, and the card steps back to grey — present,
2111
+ * holding what you are looking at, not itself the thing you are looking at.
2112
+ * Reversing that (blue card, blue row inside it) says nothing, which is what a
2113
+ * blue-on-blue card looked like.
2114
+ *
2115
+ * A filled card does **not** also answer hover: the fill is already spent, and a
2116
+ * selected row that lightened under the pointer read as a third state nobody
2117
+ * could name. Its steps still do, on `--row-active`, which is a tint and so
2118
+ * works on all three grounds.
2119
+ *
2120
+ * A **task** never takes the blue. It is a reference to a place inside a
2121
+ * session, so pressing one selects the session and travels to its marker — see
2122
+ * `StepRow`.
2000
2123
  */
2001
- declare function SessionStatusIcon({
2002
- row
2003
- }: {
2124
+ interface SessionItemProps {
2004
2125
  row: SessionRow;
2005
- }): _$react.JSX.Element;
2126
+ /** This session is the one the host is showing. */
2127
+ active?: boolean;
2128
+ /**
2129
+ * Which sub-agent is open, by `Step.key` — the *finer* of the two selections.
2130
+ * When it names one of this card's agents, that step takes the blue and the
2131
+ * card drops to the secondary grey. A key belonging to some other card's
2132
+ * agent, or to a task, changes nothing here.
2133
+ */
2134
+ activeStepKey?: string;
2135
+ /** Shown when the list is not already grouped by gateway. */
2136
+ showGateway?: boolean;
2137
+ /**
2138
+ * False when the list is already grouped by project — the header above has
2139
+ * said the name, so the card must not spend its metadata line repeating it.
2140
+ * What takes the slot is the *sub-path inside the project*
2141
+ * (`projectSubpath`): `packages/ui`, `packages/server` — the one thing the
2142
+ * header cannot say and the only thing that tells two sessions in one repo
2143
+ * apart. A session at the project root has nothing to add and the slot
2144
+ * disappears entirely. Exactly the rule `showGateway` follows one facet over.
2145
+ */
2146
+ showProject?: boolean;
2147
+ /** Resolved project-icon bytes by content hash. A hash this map has not got
2148
+ * yet simply draws no icon. */
2149
+ projectIcons?: Record<string, string>;
2150
+ /** Uncontrolled by default — pass both to drive expansion from the host. */
2151
+ expanded?: boolean;
2152
+ onExpandedChange?: (expanded: boolean) => void;
2153
+ onSelect?: () => void;
2154
+ /** Open the session *at* one of its sub-agents — hand the panel body over to
2155
+ * that agent's own work. Only ever called for an **agent** step. Absent is not
2156
+ * a missing feature: without it a step just opens the session, which is all a
2157
+ * host with no sub-agent surface can offer. */
2158
+ onSelectSubagent?: (toolUseId: string) => void;
2159
+ /**
2160
+ * Open the session and travel to a **task**'s row in the transcript — where
2161
+ * the work was started, and where it finished.
2162
+ *
2163
+ * A separate seam from `onSelectSubagent` because the destinations are
2164
+ * different, and conflating them is not a styling detail: a task has no agent
2165
+ * behind it, so framing its tool-use id selects **no items at all** and the
2166
+ * panel draws an empty agent view. That was the bug. A task is a reference,
2167
+ * and the only honest thing to do with a reference is follow it.
2168
+ */
2169
+ onRevealStep?: (toolUseId: string) => void;
2170
+ /** Enables in-place rename. The trigger is the host's — see `renameOn`. */
2171
+ onRename?: (title: string) => void;
2172
+ /**
2173
+ * How a rename starts. `doubleClick` is the editor feel (a rename is a thing
2174
+ * you do to the word you are looking at); `external` means the host opens it
2175
+ * from its own affordance — a menu entry, a pencil in `actions` — and drives
2176
+ * it through `editing`/`onEditingChange`.
2177
+ */
2178
+ renameOn?: 'doubleClick' | 'external';
2179
+ editing?: boolean;
2180
+ onEditingChange?: (editing: boolean) => void;
2181
+ /** The card's trailing controls, at the end of line two. A single overflow
2182
+ * glyph is what the design draws; a host with three always-on actions can put
2183
+ * them here instead. */
2184
+ actions?: ReactNode;
2185
+ className?: string;
2186
+ }
2187
+ declare function SessionItem({
2188
+ row,
2189
+ active,
2190
+ activeStepKey,
2191
+ showGateway,
2192
+ showProject,
2193
+ projectIcons,
2194
+ expanded,
2195
+ onExpandedChange,
2196
+ onSelect,
2197
+ onSelectSubagent,
2198
+ onRevealStep,
2199
+ onRename,
2200
+ renameOn,
2201
+ editing,
2202
+ onEditingChange,
2203
+ actions,
2204
+ className
2205
+ }: SessionItemProps): _$react.JSX.Element;
2006
2206
  //#endregion
2007
2207
  //#region src/components/agent/EngineIcon.d.ts
2008
2208
  /**
@@ -2064,10 +2264,16 @@ type Step = {
2064
2264
  label: string; /** What one of these is called, for the disclosure's count. */
2065
2265
  noun: string;
2066
2266
  /**
2067
- * An **agent** has an identity and work of its own, so it is pressable and
2068
- * wears the sub-agent colour. A **task** is something the model described with
2069
- * no agent behind it (`isAgentRecord`), so it is inert: there is no frame to
2070
- * open, and a row that offered one would show an empty screen.
2267
+ * Both kinds press. The kind decides **where the press goes**, which is the
2268
+ * whole of the distinction.
2269
+ *
2270
+ * An **agent** has an identity and work of its own, so it wears the sub-agent
2271
+ * colour and opens that agent's own frame. A **task** is something the model
2272
+ * described with no agent behind it (`isAgentRecord`), so there is no frame:
2273
+ * framing its id selects no items and draws an empty screen. What it has
2274
+ * instead is a *place* — the spawning call's row in the transcript — so it is
2275
+ * muted, never selected, and travels there. See `StepRow` for why an inert
2276
+ * row was the worse answer.
2071
2277
  *
2072
2278
  * Two values and not a boolean because the checklist source this shape was
2073
2279
  * drawn for (see above) produces the second kind natively — a to-do is a task
@@ -2080,7 +2286,26 @@ type Step = {
2080
2286
  title: string;
2081
2287
  onSelect: () => void;
2082
2288
  };
2083
- declare function sessionSteps(info: SessionInfo, onSelectSubagent: (toolUseId: string) => void): Step[];
2289
+ /**
2290
+ * The steps under one session, **agents first**.
2291
+ *
2292
+ * The two kinds do different things when pressed and are worth different
2293
+ * amounts of attention: an agent has work of its own to go and read, a task is a
2294
+ * marker in a transcript. Interleaved in dispatch order they read as one
2295
+ * undifferentiated list, and the rows you can actually open are scattered
2296
+ * through it. Grouped, the openable ones are a block at the top and the markers
2297
+ * are a tail you can skip.
2298
+ *
2299
+ * Stable **within** each group, deliberately: dispatch order is the only order
2300
+ * these records have that means anything (it is the order the work was started
2301
+ * in), so the sort partitions and never reorders inside a partition.
2302
+ *
2303
+ * `onSelect` is handed the **kind** as well as the id, because the two kinds go
2304
+ * to different places — see `SessionItem`, which is what routes them. Passing
2305
+ * only the id is what let a task be opened as if it were an agent, and a framed
2306
+ * task id matches no items, so the panel drew an **empty agent view**.
2307
+ */
2308
+ declare function sessionSteps(info: SessionInfo, onSelect: (toolUseId: string, kind: Step['kind']) => void): Step[];
2084
2309
  /** How many of these are still going — the live half of the disclosure's count. */
2085
2310
  declare function runningSteps(steps: readonly Step[]): number;
2086
2311
  /**
@@ -2107,23 +2332,54 @@ declare function StepToggle({
2107
2332
  onToggle: () => void;
2108
2333
  }): _$react.JSX.Element;
2109
2334
  /**
2110
- * One step under its session. Pressing an **agent** hands the panel over to that
2111
- * agent's own work — it is not a session and never becomes one, but it does now
2112
- * have a surface (`SessionPanel.openSubagent`). A host that cannot frame one
2113
- * falls back to revealing its `Task` row, which was this row's only meaning
2114
- * before the takeover existed. A **task** is not pressable at all; see
2115
- * {@link Step.kind}.
2116
- *
2117
- * Divided from the row's header and from each other by a rule rather than by
2118
- * indentation: these are a list *inside* the row, and at 11px an indent is not
2119
- * enough to say so. The rule is black at 25% so it darkens whatever the row is
2120
- * filled with, selected or not, without needing a colour per state.
2335
+ * One step under its session **pressable, all of them**, and what a press
2336
+ * means is what tells the two kinds apart.
2337
+ *
2338
+ * Pressing an **agent** hands the panel over to that agent's own work
2339
+ * (`SessionPanel.openSubagent`): it is not a session and never becomes one, but
2340
+ * it has a surface, so it can be the selected thing. Pressing a **task** selects
2341
+ * the *session* and travels to that task's marker inside it — a task is a
2342
+ * reference to a place in a transcript, not a thing with a screen, so it can be
2343
+ * followed but never held.
2344
+ *
2345
+ * That is a reversal, and a deliberate one. A task used to be inert markup on
2346
+ * the argument that "a disabled-looking button still announces itself as one" —
2347
+ * correct about the markup, wrong about the premise, because there *was* always
2348
+ * somewhere to go and the row simply swallowed the click on its way there. A row
2349
+ * that looks like a list item, sits in a list, and does nothing when pressed is
2350
+ * the worse lie. So every step answers the pointer and every step answers a
2351
+ * press; only what the press does differs.
2352
+ *
2353
+ * Divided from the card's header by **indentation and its own hit shape**, not
2354
+ * by a rule. The rules came first, on the argument that at 11px an indent is not
2355
+ * enough to say "list inside a row" — and they were right about the reading and
2356
+ * wrong about the cost: a stack of hairlines across every open card turned the
2357
+ * list into a ledger, and a rule cannot answer a pointer. A step that lights up
2358
+ * under the cursor and fills when it is the one on screen says *list* far more
2359
+ * plainly than a line between two of them, and it says it while doing the job
2360
+ * the rule could not.
2361
+ *
2362
+ * **Only an agent can wear the selection**, and `active` is guarded on that here
2363
+ * rather than trusted from the caller: a host that hands back a task's key is
2364
+ * describing where it navigated, not what it selected, and the row must not
2365
+ * paint itself blue for it.
2366
+ *
2367
+ * The hover is `--row-active` — **alpha, not a flat fill** — because this row
2368
+ * has to answer the pointer on three different grounds: a transparent card, a
2369
+ * blue one (its session is selected), and a grey one (a sibling agent is). A
2370
+ * flat value tuned for any of those is wrong on the other two; a tint darkens or
2371
+ * lifts whatever it lands on. It is the one place in the list where the alpha
2372
+ * token earns its keep.
2121
2373
  */
2122
2374
  declare function StepRow({
2123
2375
  step,
2376
+ active,
2124
2377
  onSelect
2125
2378
  }: {
2126
2379
  step: Step;
2380
+ /** The panel is showing this step's own work. Ignored for tasks, which cannot
2381
+ * be the selected thing — see above. */
2382
+ active?: boolean;
2127
2383
  onSelect: () => void;
2128
2384
  }): _$react.JSX.Element;
2129
2385
  //#endregion
@@ -2312,5 +2568,5 @@ declare function toolIcon(toolName: string): LucideIcon;
2312
2568
  */
2313
2569
  declare function isMutatingTool(toolName: string): boolean;
2314
2570
  //#endregion
2315
- export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, ContextDialog, type ContextDialogProps, ContextRing, Conversation, ConversationContent, type ConversationProps, ConversationScrollButton, CopyAction, CopyButton, type CopyButtonProps, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, type FileCardProps, type FileDeliveredItem, HostFilesDialog, type HostFilesDialogProps, Ink, Input, Loader, McpDialog, type McpDialogProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, PERMISSION_MODES, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, ProgressRing, type ProgressRingProps, ProjectIcon, PromptArea, type PromptAreaHandle, type PromptAreaProps, PromptTokenText, QUESTION_BEHAVIORS, type QuestionBehaviorMeta, QuestionPrompt, type QuestionPromptProps, Reasoning, type ReasoningProps, Response, type ResponseProps, Row, type RowProps, STATUS_META, type Segment, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionInfoDialog, type SessionInfoDialogProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionPanel, type SessionPanelProps, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepRow, StepToggle, SubagentStrip, type TerminalAffordances, TerminalDiff, TerminalItemView, TerminalMarkdown, type TerminalMarkdownProps, type TerminalMetrics, TerminalPermissionPrompt, type TerminalPermissionPromptProps, TerminalQuestionPrompt, type TerminalQuestionPromptProps, TerminalStatusLine, type TerminalStatusLineProps, TerminalSurface, type TerminalSurfaceProps, TerminalTranscript, type TerminalTranscriptProps, type TextSegment, Textarea, Tip, Toaster, type Tone, ToolCallCard, type ToolCallCardProps, type ToolCallItem, TooltipContent, TooltipProvider, Transcript, type TranscriptDensity, TranscriptDensityProvider, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
2571
+ export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, ContextDialog, type ContextDialogProps, ContextRing, Conversation, ConversationContent, type ConversationProps, ConversationScrollButton, CopyAction, CopyButton, type CopyButtonProps, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, type FileCardProps, type FileDeliveredItem, HostFilesDialog, type HostFilesDialogProps, Ink, Input, Loader, McpDialog, type McpDialogProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, PERMISSION_MODES, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, ProgressRing, type ProgressRingProps, ProjectIcon, PromptArea, type PromptAreaHandle, type PromptAreaProps, PromptTokenText, QUESTION_BEHAVIORS, type QuestionBehaviorMeta, QuestionPrompt, type QuestionPromptProps, Reasoning, type ReasoningProps, Response, type ResponseProps, Row, type RowProps, STATUS_META, type Segment, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionInfoDialog, type SessionInfoDialogProps, SessionItem, type SessionItemProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionPanel, type SessionPanelProps, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepRow, StepToggle, SubagentStrip, type TerminalAffordances, TerminalDiff, TerminalItemView, TerminalMarkdown, type TerminalMarkdownProps, type TerminalMetrics, TerminalPermissionPrompt, type TerminalPermissionPromptProps, TerminalQuestionPrompt, type TerminalQuestionPromptProps, TerminalStatusLine, type TerminalStatusLineProps, TerminalSurface, type TerminalSurfaceProps, TerminalTranscript, type TerminalTranscriptProps, type TextSegment, Textarea, Tip, Toaster, type Tone, ToolCallCard, type ToolCallCardProps, type ToolCallItem, TooltipContent, TooltipProvider, Transcript, type TranscriptDensity, TranscriptDensityProvider, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
2316
2572
  //# sourceMappingURL=index.d.mts.map