@wrongstack/tui 0.298.0 → 0.298.1

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.
@@ -1,339 +1,11 @@
1
1
  import type React from 'react';
2
- import { type MutableRefObject } from 'react';
3
- import { EntryHeightCache } from '../height-cache.js';
4
- import { type RenderGroup } from './history/tool-group.js';
5
- import { type HistoryEntry, type HistoryProps } from './history.js';
6
- /**
7
- * Imperative scroll surface owned by the ScrollableHistory component. The app
8
- * key/mouse handlers call these instead of dispatching reducer actions: all
9
- * scroll math needs the live height cache, which lives here, and routing it
10
- * through app state previously forced totals and offsets to travel through
11
- * separate commits — the root cause of an entire family of jump bugs.
12
- */
13
- export interface HistoryScrollController {
14
- /** Scroll by `deltaUp` rows: positive = older content, negative = newer. */
15
- scrollBy(deltaUp: number): void;
16
- /** Scroll by one viewport page. */
17
- scrollPage(dir: 'up' | 'down'): void;
18
- /** Jump to the oldest retained entry. */
19
- scrollToTop(): void;
20
- /** Re-pin to the newest output. */
21
- scrollToBottom(): void;
22
- /** Jump to a 0-based cell clicked/dragged on the scrollbar track. */
23
- scrollToTrackCell(cell: number): void;
24
- /** True while the viewport is scrolled away from the newest output. */
25
- isScrolled(): boolean;
26
- /**
27
- * True when the viewport cell lands on a copyable card's copy icon. Lets the
28
- * mouse handler decide synchronously whether to consume the click before
29
- * firing the async copy. See {@link copyAtViewportCell} for the `row`/`col`
30
- * coordinate contract.
31
- */
32
- hasCopyTargetAt(row: number, col: number): boolean;
33
- /**
34
- * Handle a left-click inside the history viewport. `row` is 0-based from the
35
- * viewport top; `col` is 0-based from the LEFT EDGE OF THE HISTORY BAND, not
36
- * the raw terminal column. In the interactive mount the band renders flush at
37
- * terminal column 0 (the scrollbar occupies the rightmost columns), so the
38
- * caller passes the terminal column directly; a band that is inset from the
39
- * left must subtract its left offset first. When the cell lands on a copyable
40
- * card's copy icon, its content is written to the system clipboard and the
41
- * entry id is returned; otherwise returns null.
42
- */
43
- copyAtViewportCell(row: number, col: number): Promise<number | null>;
44
- /**
45
- * Begin a drag-to-select gesture at `row`,`col` (history-band viewport cell).
46
- * The cell must be inside a card's row range and inside the rendered band
47
- * (`0 <= col < termWidth`); the mouse handler has already excluded the rail.
48
- * Calls that don't satisfy that contract are silently ignored. Existing
49
- * scrollbar/copy-icon/wheel paths remain intact because they call their own
50
- * handlers; this only kicks in when the mouse layer explicitly routes a
51
- * left-press into the card band.
52
- */
53
- beginSelection(row: number, col: number): void;
54
- /**
55
- * Extend an active selection to `row`,`col`. If no selection is in progress,
56
- * the call is a no-op. Crossing into the gutter or below the viewport cancels
57
- * the drag internally — leaving stale viewport-relative coords around after
58
- * a mid-drag escape would let the next right-click paste from the wrong
59
- * card, which is the worse failure mode than the selection disappearing.
60
- */
61
- extendSelection(row: number, col: number): void;
62
- /**
63
- * End an active drag (left-release). Does NOT write to the clipboard — the
64
- * copy is performed by {@link commitSelection}, which is triggered by a
65
- * separate right-click in the history band (per the drag-select-then-commit
66
- * contract). If no selection is in progress, the call is a no-op.
67
- */
68
- endSelection(): void;
69
- /** Drop any in-progress or committed selection without copying. */
70
- clearSelection(): void;
71
- /**
72
- * Commit the active selection to the system clipboard. Returns true if a
73
- * non-empty selection was resolved and the write succeeded. Returns false
74
- * silently when there is no selection, the selection is empty (e.g. the drag
75
- * never moved), or the write fails — the caller can show a transient notice
76
- * on the truthy branch and stay silent on the falsy branch.
77
- */
78
- commitSelection(): Promise<boolean>;
79
- }
80
- /**
81
- * A clickable copy-icon target resolved in viewport coordinates during the
82
- * post-render measurement pass. `entryId` identifies a single card or the first
83
- * member of a compact tool group; `entryIds` contains every group member when
84
- * present. `startRow`/`endRow` bound the box's visible rows (0-based from the
85
- * viewport top, `endRow` exclusive); `iconCol` is the 0-based terminal column
86
- * the icon renders at on the box's first visible row.
87
- */
88
- export interface CopyHit {
89
- entryId: number;
90
- entryIds?: readonly number[] | undefined;
91
- startRow: number;
92
- endRow: number;
93
- iconCol: number;
94
- }
95
- /** Sentinel returned after copying the active, non-retained tool-stream box. */
96
- export declare const LIVE_TOOL_STREAM_COPY_ID = -1;
97
- /** Sentinel returned after copying a drag-select-then-right-click selection.
98
- * Distinct from any retained entry id so the host can render a different
99
- * status-line notice ("Selected range copied") without flashing a specific
100
- * card's copy icon (which only makes sense when a single entry was copied). */
101
- export declare const SELECTION_COPY_ID = -2;
102
- /**
103
- * Resolve the copy target under a viewport cell, or null. A cell matches when
104
- * its `row` is within the card's visible rows and its `col` is within the
105
- * icon's cell span. Iterates newest-first so overlapping row estimates favor
106
- * the most recently rendered card. Exported-shape pure helper for unit tests.
107
- */
108
- export declare function findCopyHit(hits: readonly CopyHit[], row: number, col: number): CopyHit | null;
109
- /** Resolve a hit to the complete current clipboard payload without performing I/O. */
110
- export declare function resolveCopyPayload(hit: CopyHit, entriesById: ReadonlyMap<number, HistoryEntry>, liveToolText?: string | undefined): {
111
- entryId: number;
112
- text: string;
113
- } | null;
114
- /**
115
- * Rows clipped from the top of the mounted history stack before it appears in
116
- * the viewport. Scrolled frames clip by the anchor's row offset; pinned frames
117
- * rely on Ink flex-end clipping, which hides top overflow from mounted groups
118
- * plus the live tool tail.
119
- */
120
- export declare function copyRegistryVisibleClip(opts: {
121
- scrolled: boolean;
122
- clip: number;
123
- mountedRows: number;
124
- tailRows: number;
125
- viewportRows: number;
126
- }): number;
127
- /** Build the live tool-stream header hit, accounting for ToolStreamBox's top margin.
128
- * The `pinnedSlack` offset must match {@link buildCopyRegistry}'s card-hit math so
129
- * the live-stream icon stays visually aligned with its header row in underfilled
130
- * pinned frames (flex-end parks the mounted stack at the bottom of the viewport). */
131
- export declare function liveToolStreamCopyHit(opts: {
132
- visible: boolean;
133
- mountedRows: number;
134
- visibleClip: number;
135
- viewportRows: number;
136
- iconCol: number;
137
- pinnedSlack?: number;
138
- }): CopyHit | null;
139
- /**
140
- * Selection rectangle in viewport cell coordinates, normalized so
141
- * `topLeft.row <= bottomRight.row` and the column pairs are likewise ordered.
142
- * Both endpoints are inclusive — the cell at `bottomRight` is selected.
143
- */
144
- export interface SelectionRect {
145
- topLeft: {
146
- row: number;
147
- col: number;
148
- };
149
- bottomRight: {
150
- row: number;
151
- col: number;
152
- };
153
- /** True while the user is still dragging; false after left-release but
154
- * before either clearSelection or commitSelection runs. */
155
- inProgress: boolean;
156
- }
157
- /** Canonicalize two viewport cells into a SelectionRect. Pure. */
158
- export declare function normalizeSelection(a: {
159
- row: number;
160
- col: number;
161
- }, b: {
162
- row: number;
163
- col: number;
164
- }, inProgress: boolean): SelectionRect;
165
- /** True when the column lies outside the rendered card band. Inside the band
166
- * the layout reserves `SCROLLBAR_HIT_WIDTH` columns for the rail AFTER the
167
- * band, so `0..termWidth-1` is always in-band and nothing inside needs to be
168
- * excluded. The mouse handler must already have excluded the rail before
169
- * calling into the controller — we only check the band bounds here. */
170
- export declare function isOutOfBand(col: number, termWidth: number): boolean;
171
- /**
172
- * One entry's contribution to a drag-selected range. Returned in document
173
- * (row-index-in-card) coordinates so the caller decides how to slice into
174
- * the entry's source text. `start` is the column inside the card (0-based
175
- * from the left edge of the card's visible rectangle, NOT the terminal
176
- * column — the gutter is excluded by the caller before reaching here).
177
- * `end` is inclusive. When `startRow === endRow`, the slice is one row; the
178
- * caller is responsible for translating text columns into source offsets.
179
- */
180
- export interface SelectionSlice {
181
- entryId: number;
182
- /** Inclusive row-in-card for the start of the slice. */
183
- startRow: number;
184
- /** Inclusive column, 0-based, inside the card's text area (gutter excluded). */
185
- startCol: number;
186
- /** Inclusive end row. */
187
- endRow: number;
188
- /** Inclusive end column, 0-based. */
189
- endCol: number;
190
- }
191
- /**
192
- * Translate a viewport-cell selection into per-entry row/col slices, walking
193
- * the same mounted-group geometry the copy-hit registry uses so the two
194
- * systems share one row index. Entries wholly outside the selection return
195
- * nothing. Entries whose vertical span is wholly inside the selection are
196
- * returned as a single row-range; entries the selection clips at the top or
197
- * bottom are returned with row bounds matching the clip.
198
- *
199
- * `cardVisibleCols` is the number of columns inside the card the user can
200
- * see — the band width minus the right gutter (`viewportWidth - SCROLLBAR_HIT_WIDTH`).
201
- * Slices never include the gutter or any column to its right; the caller has
202
- * already validated that.
203
- *
204
- * Returned slices are in document (entry-local) coordinates: `startRow`/`endRow`
205
- * are rows inside the entry's own geometry, NOT viewport cells. This is what
206
- * the assembler needs to recover text — slicing into the raw entry text uses
207
- * per-row layout, which the caller resolves via the layout store.
208
- */
209
- export declare function selectionToSlices(opts: {
210
- selection: SelectionRect;
211
- cards: ReadonlyArray<{
212
- entryId: number;
213
- /** 0-based viewport row of the card's first visible row. */
214
- viewportStartRow: number;
215
- /** 0-based viewport row just past the card's last visible row. */
216
- viewportEndRow: number;
217
- }>;
218
- cardVisibleCols: number;
219
- }): SelectionSlice[];
220
- export interface ScrollableHistoryProps extends HistoryProps {
221
- /** Height of the viewport in rows, computed by App from the bottom region. */
222
- viewportRows: number;
223
- /** Receives the imperative scroll controller. The component assigns on
224
- * mount and clears on unmount. Optional for isolated renderers. */
225
- controllerRef?: MutableRefObject<HistoryScrollController | null> | undefined;
226
- /** Reports scroll-state transitions (scrolled away from / re-pinned to the
227
- * newest output) so the host can adjust key hints. */
228
- onScrollInfo?: ((info: {
229
- scrolled: boolean;
230
- }) => void) | undefined;
231
- /** Optional cap on the width used for entry wrapping (right panel mode). */
232
- maxWidth?: number | undefined;
233
- /** Layout store for persisting entry height data across renders and sessions.
234
- * When provided, the ScrollableHistory seeds its height cache from the
235
- * store's persisted measurements and marks entries as measured after render,
236
- * eliminating estimate-vs-actual scroll jumps on re-render. */
237
- layoutStore?: import('../layout-store.js').LayoutStore | undefined;
238
- /**
239
- * Entry id of the card whose copy icon was just clicked. That card's icon
240
- * renders in the success color for the brief window the host keeps this set,
241
- * giving per-card visual feedback alongside the status-line "Copied" notice.
242
- * `null` / undefined = no card highlighted.
243
- */
244
- copiedEntryId?: number | null | undefined;
245
- /**
246
- * Called when the user scrolls near the top of the currently loaded
247
- * entries. The host should respond by loading older entries from the
248
- * history archive and dispatching `archiveLoaded` to prepend them.
249
- */
250
- onRequestOlderEntries?: (() => void) | undefined;
251
- }
252
- /** Pure thumb geometry for the scrollbar: where the thumb starts and how many
253
- * cells it spans, given the track height, scroll offset, and total content
254
- * height. Exported for testing. */
255
- export declare function scrollbarThumb(rows: number, offset: number, total: number): {
256
- top: number;
257
- size: number;
258
- scrollable: boolean;
259
- };
260
- /** Inverse of {@link scrollbarThumb}: given a clicked/dragged 0-based cell on a
261
- * track of `rows` height, return the scroll offset (rows up from the bottom)
262
- * that lands the visible window there. Cell 0 (top) → oldest content (max
263
- * offset); cell rows-1 (bottom) → newest (offset 0). Exported for testing. */
264
- export declare function scrollOffsetForTrackRow(rows: number, total: number, cell: number): number;
265
- /**
266
- * Per-card viewport span for the currently-mounted groups. Mirrors
267
- * {@link buildCopyRegistry}'s visibleClip math so the drag-select gesture asks
268
- * the same geometry question the copy-hit registry already answers.
269
- */
270
- export interface MountedCardSpan {
271
- entryId: number;
272
- /** 0-based viewport row of the first VISIBLE row of the card. */
273
- viewportStartRow: number;
274
- /** 0-based viewport row one past the last VISIBLE row of the card. */
275
- viewportEndRow: number;
276
- /** Card's geometry in rows; visibleClip + scrolled-clip aware. */
277
- totalRows: number;
278
- entryIds?: readonly number[];
279
- }
280
- /**
281
- * Build per-card viewport spans for every mounted render group. Pure — given
282
- * the same render-group list, height cache, scroll state, and viewport size,
283
- * the result is deterministic and matches the copy-hit registry. Exported so
284
- * tests can verify the span map without mounting the full component.
285
- */
286
- export declare function buildMountedCardSpans(opts: {
287
- renderGroups: readonly RenderGroup[];
288
- heightCache: EntryHeightCache;
289
- scrolled: boolean;
290
- clip: number;
291
- tailRows: number;
292
- viewportRows: number;
293
- showModelReasoning?: boolean | undefined;
294
- }): MountedCardSpan[];
295
- /**
296
- * Find the card whose viewport row range contains `row`. Pure.
297
- * Returns null when the row is in a blank gap or outside the viewport.
298
- */
299
- export declare function selectionHitAt(row: number, spans: readonly MountedCardSpan[]): {
300
- entryId: number;
301
- entryIds?: readonly number[];
302
- } | null;
303
- /**
304
- * Build the clipboard payload for a selection by slicing into each affected
305
- * entry's full renderable text. The v1 contract is line-then-column on the
306
- * entry's source text: each slice exposes `startRow`/`endRow` and
307
- * `startCol`/`endCol` in card-local coordinates; we split the entry's
308
- * text on `\n`, keep only the rows inside the row range, and within those
309
- * rows apply the column range. The matrix matches what the source line
310
- * index would be when no wrapping occurs — i.e. one card row maps to one
311
- * source line. Wrap-geometry translation is intentionally absent in v1
312
- * because the layout store does not yet expose per-card-row wrap segments;
313
- * it returns when those segments exist and a v1.1 test demands it.
314
- *
315
- * `toolGroupsByHeadId` lets a multi-member tool-group expand: when the
316
- * head id appears with `entryIds.length > 1`, the assembler copies via
317
- * `copyableTextForEntries` (raw ordered JSON of every member, matching
318
- * the existing copy-icon contract). A single-entry head falls through
319
- * to `copyableTextForEntry`.
320
- *
321
- * Multi-entry selections are joined with `\n---\n` so the user can see
322
- * where one card ends and the next begins. Empty selections and
323
- * selections that resolve to no text return `""` so the caller can fall
324
- * through silently.
325
- */
326
- export declare function assembleSelectionText(opts: {
327
- slices: readonly SelectionSlice[];
328
- entriesById: ReadonlyMap<number, HistoryEntry>;
329
- /**
330
- * For each tool-group head id present in `slices`, the ordered member list.
331
- * When a head has a multi-member group, the assembler slices into the
332
- * group's combined text via `copyableTextForEntries`. A single-entry
333
- * head falls through to `copyableTextForEntry`.
334
- */
335
- toolGroupsByHeadId?: ReadonlyMap<number, readonly number[]> | undefined;
336
- }): string;
2
+ import { type HistoryEntry } from './history.js';
3
+ export type { HistoryScrollController, ScrollableHistoryProps, } from './history/scroll-controller-types.js';
4
+ export { type CopyHit, LIVE_TOOL_STREAM_COPY_ID, SELECTION_COPY_ID, findCopyHit, resolveCopyPayload, copyRegistryVisibleClip, liveToolStreamCopyHit, } from './history/copy-geometry.js';
5
+ export { type SelectionRect, type SelectionSlice, normalizeSelection, isOutOfBand, selectionToSlices, assembleSelectionText, } from './history/selection-helpers.js';
6
+ export { type MountedCardSpan, scrollbarThumb, scrollOffsetForTrackRow, buildMountedCardSpans, selectionHitAt, } from './history/scrollbar-geometry.js';
7
+ export { Scrollbar } from './history/scrollbar-rail.js';
8
+ import type { ScrollableHistoryProps } from './history/scroll-controller-types.js';
337
9
  /**
338
10
  * Bounded history viewport with stable-anchor virtual scrolling.
339
11
  *
@@ -180,7 +180,7 @@ export type SettingsPickerPatch = Partial<{
180
180
  breakerEnabled: boolean;
181
181
  breakerAutoKillResetMs: number;
182
182
  showModelReasoning: boolean;
183
- showAgentSwarmPanel: boolean;
183
+ showAgentSwarmPanel: import('../app-settings-type.js').AgentSwarmPanelMode;
184
184
  readSymbols: boolean;
185
185
  showSageMemoryInject: boolean;
186
186
  sageMemoryInjectThreshold: number;
@@ -64,11 +64,11 @@ export interface SettingsPickerProps {
64
64
  /** Show the "Model Reasoning" blocks in chat history. Default: true. */
65
65
  showModelReasoning: boolean;
66
66
  /**
67
- * Show the persistent FleetPanel below the status bar, including AGENT SWARM
68
- * activity and its todo mission queue. Full-screen agent/queue/goal overlays
69
- * remain independently available through their panel shortcuts. Default: true.
67
+ * Show the Mission Queue section (todo items) in the right sidebar. The
68
+ * lower-region FleetPanel is always visible when there is fleet activity;
69
+ * this toggle controls only the sidebar mission queue. Default: 'bottom'.
70
70
  */
71
- showAgentSwarmPanel: boolean;
71
+ showAgentSwarmPanel: import('../app-settings-type.js').AgentSwarmPanelMode;
72
72
  /** Show SAGE Memory Inject blocks in tool results. Default: false. */
73
73
  showSageMemoryInject: boolean;
74
74
  /** Minimum relation strength for SAGE memory injection. Default: 0.85. */
@@ -0,0 +1,47 @@
1
+ import type { ResumeSessionEntry } from '../app-state.js';
2
+ import type { FleetEntry } from '../app-state-fleet.js';
3
+ import type { TodoItem } from '@wrongstack/core/agent';
4
+ import type React from 'react';
5
+ import type { LiveSessionEntry } from './sessions-panel.js';
6
+ export interface SidebarContentProps {
7
+ /** Live context window data from useStatusbarViewModel. */
8
+ contextWindow: {
9
+ used: number;
10
+ max: number;
11
+ } | undefined;
12
+ /** Fleet entries (leader + subagents) from useStatusbarViewModel. */
13
+ entries: Record<string, FleetEntry>;
14
+ /** Fleet counts summary. */
15
+ fleetCounts: {
16
+ running: number;
17
+ idle: number;
18
+ pending: number;
19
+ completed: number;
20
+ } | undefined;
21
+ /** Current provider label for display. */
22
+ provider?: string | undefined;
23
+ /** Current model label for display. */
24
+ model?: string | undefined;
25
+ /** Actual sidebar width in columns (including border+padding chrome).
26
+ * Used to size the content area and truncate text appropriately. */
27
+ width: number;
28
+ /** Vertical scroll offset — number of rows scrolled from the top. */
29
+ scrollOffset?: number | undefined;
30
+ /** When true, the sidebar has keyboard focus (↑↓ scroll). */
31
+ focused?: boolean | undefined;
32
+ /** Live leader todo board — rendered as a compact mission queue. */
33
+ todos?: readonly TodoItem[] | undefined;
34
+ /** When true, show the agent-swarm + mission-queue section. Gated by the
35
+ * effective agent-swarm panel mode being 'sidebar' (see app-view.tsx). */
36
+ showSwarmSection?: boolean | undefined;
37
+ /** Live sessions from the SessionRegistry — same data as the F10 panel.
38
+ * Shown as compact "live" rows with project name + status + agent count. */
39
+ liveSessions?: readonly LiveSessionEntry[] | undefined;
40
+ /** Recent stored sessions for the `/resume` picker. Shown as compact rows
41
+ * with title + last-activity + outcome badge. */
42
+ resumeSessions?: readonly ResumeSessionEntry[] | undefined;
43
+ /** The current session ID — used to highlight the active session row. */
44
+ currentSessionId?: string | undefined;
45
+ }
46
+ export declare function SidebarContent({ contextWindow, entries, fleetCounts, provider, model, width, scrollOffset, focused, todos, showSwarmSection, liveSessions, resumeSessions, currentSessionId, }: SidebarContentProps): React.ReactElement;
47
+ //# sourceMappingURL=sidebar-content.d.ts.map
@@ -0,0 +1,40 @@
1
+ import type React from 'react';
2
+ /** Terminal widths below this hide the sidebar entirely. */
3
+ export declare const SIDEBAR_MIN_TERMINAL = 64;
4
+ /** Smallest sidebar width (in columns) when visible. */
5
+ export declare const SIDEBAR_MIN_WIDTH = 20;
6
+ /** Largest sidebar width (in columns). */
7
+ export declare const SIDEBAR_MAX_WIDTH = 48;
8
+ /** Fraction of terminal width to allocate to the sidebar. */
9
+ export declare const SIDEBAR_FRACTION = 0.25;
10
+ /**
11
+ * Compute the sidebar width in columns for a given terminal width.
12
+ * Returns 0 when the terminal is too narrow for a sidebar.
13
+ *
14
+ * Pure — no React, no Ink — so callers can use the same value for layout
15
+ * math (e.g. narrowing the history column) without mounting the component.
16
+ */
17
+ export declare function computeSidebarWidth(termCols: number): number;
18
+ export interface RightSidebarProps {
19
+ /**
20
+ * Optional explicit width override (in columns). When omitted, the width
21
+ * is derived from the current terminal width via {@link computeSidebarWidth}.
22
+ */
23
+ width?: number | undefined;
24
+ /**
25
+ * Maximum height in rows. Content beyond this is clipped (scroll handled
26
+ * by the caller via scrollOffset). When omitted, no height cap is applied.
27
+ */
28
+ maxHeight?: number | undefined;
29
+ /**
30
+ * When true, the sidebar border is highlighted to indicate keyboard focus.
31
+ */
32
+ focused?: boolean | undefined;
33
+ /**
34
+ * Content to render inside the sidebar. When omitted, a dimmed placeholder
35
+ * label is shown so the reserved region is visually self-documenting.
36
+ */
37
+ children?: React.ReactNode | undefined;
38
+ }
39
+ export declare function RightSidebar({ width, maxHeight, focused, children }: RightSidebarProps): React.ReactElement | null;
40
+ //# sourceMappingURL=sidebar.d.ts.map
@@ -58,6 +58,16 @@ export declare function stateChip(state: 'idle' | 'running' | 'streaming' | 'abo
58
58
  export declare function renderProgress(ratio: number, width: number): string;
59
59
  export declare function contextBarColor(ratio: number): string;
60
60
  export declare function renderMeter(ratio: number, width: number): string;
61
+ /**
62
+ * Block-style meter for the sidebar — a solid fill (`█`) plus an empty track
63
+ * (`░`). Returned as two segments so the caller can color the fill (e.g. by
64
+ * context pressure via {@link contextBarColor}) independently of the dim track.
65
+ * Width-safe: `filled.length + empty.length === max(1, width)` always holds.
66
+ */
67
+ export declare function blockMeter(ratio: number, width: number): {
68
+ filled: string;
69
+ empty: string;
70
+ };
61
71
  export declare function fmtTok(n: number): string;
62
72
  export declare function fmtMemory(bytes: number): string;
63
73
  export declare function fmtElapsed(ms: number): string;
@@ -372,5 +372,12 @@ export interface StatusBarProps {
372
372
  * Clicking opens /audit (TUI) — in the REPL it's informational.
373
373
  */
374
374
  sideEffectCount?: number | undefined;
375
+ /**
376
+ * Optional cap on the column width used for layout adaptation. When set,
377
+ * the status bar treats this as its effective terminal width instead of
378
+ * `stdout.columns` — needed when the bar sits in a column narrower than
379
+ * the full terminal (e.g. beside a sidebar).
380
+ */
381
+ maxWidth?: number | undefined;
375
382
  }
376
383
  //# sourceMappingURL=status-bar-types.d.ts.map
@@ -11,5 +11,5 @@ export declare const COMPACT_THRESHOLD = 50;
11
11
  * to show — git branch, elapsed time, todo counts, YOLO marker — so a
12
12
  * vanilla session keeps the original single-line footprint.
13
13
  */
14
- export declare function StatusBar({ model, provider, version, latestVersion, updateAvailable, state, thinkingWord, thinkingAnimationStyle, tokenCounter, hint, queueCount, yolo, autonomy, fleetWorkingTime, todos, plan, tasks, fleet, fleetAgents, git, subagentCount, brain, projectName, workingDir, processCount, processMemory, cpuPercent, context, estimatedContextTokens, Sage, memoryContextMonitor, contextStrategy, hiddenItems, mode, events, sessionId, eternalStage, goalSummary, droppedTools, indexState, breakerCountdown, modeLabel, debugStreamStats, enhanceCountdown, nextStepsAutoSubmitCountdown, nextStepsAutoSubmitLabel, autoProceedCountdown, sessionCount, mailbox, tokenSavingMode, toolCount, visibleChips, sideEffectCount, }: StatusBarProps): React.ReactElement;
14
+ export declare function StatusBar({ model, provider, version, latestVersion, updateAvailable, state, thinkingWord, thinkingAnimationStyle, tokenCounter, hint, queueCount, yolo, autonomy, fleetWorkingTime, todos, plan, tasks, fleet, fleetAgents, git, subagentCount, brain, projectName, workingDir, processCount, processMemory, cpuPercent, context, estimatedContextTokens, Sage, memoryContextMonitor, contextStrategy, hiddenItems, mode, events, sessionId, eternalStage, goalSummary, droppedTools, indexState, breakerCountdown, modeLabel, debugStreamStats, enhanceCountdown, nextStepsAutoSubmitCountdown, nextStepsAutoSubmitLabel, autoProceedCountdown, sessionCount, mailbox, tokenSavingMode, toolCount, visibleChips, sideEffectCount, maxWidth, }: StatusBarProps): React.ReactElement;
15
15
  //# sourceMappingURL=status-bar.d.ts.map
@@ -40,9 +40,10 @@ export type HitRegion =
40
40
  };
41
41
  /**
42
42
  * Columns at the right edge of the history viewport reserved for the copy/scroll
43
- * rail. Copy icons use the first column and the scrollbar track uses the last.
43
+ * rail. Copy icons use the first column, a blank gap separates them from the
44
+ * scrollbar track in the last column.
44
45
  */
45
- export declare const SCROLLBAR_HIT_WIDTH = 2;
46
+ export declare const SCROLLBAR_HIT_WIDTH = 3;
46
47
  /** Rows available to managed history after reserving the measured bottom UI. */
47
48
  export declare function historyViewportRows(termRows: number, bottomHeight: number): number;
48
49
  /**
@@ -1,6 +1,6 @@
1
1
  import { type Dispatch, type MutableRefObject, type SetStateAction } from 'react';
2
- import type { AppProps } from '../app-props.js';
3
2
  import type { Action } from '../app-action-type.js';
3
+ import type { AppProps } from '../app-props.js';
4
4
  import { type MemoryContextMonitorState } from '../memory-context-monitor.js';
5
5
  interface ProviderEventBridgeOptions {
6
6
  events: AppProps['events'];