@wrongstack/tui 1.0.4 → 1.0.5

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 (49) hide show
  1. package/dist/app-action-type.d.ts +14 -0
  2. package/dist/app-key-handler.d.ts +5 -120
  3. package/dist/app-view-contract.d.ts +3 -0
  4. package/dist/app-view-sidebar.d.ts +9 -1
  5. package/dist/app.d.ts +3 -3
  6. package/dist/components/confirm-prompt.d.ts +1 -1
  7. package/dist/components/history/entry.d.ts +15 -1
  8. package/dist/components/history/index.d.ts +1 -1
  9. package/dist/components/history/tool-visual-types.d.ts +1 -1
  10. package/dist/components/history/types.d.ts +4 -0
  11. package/dist/components/inspect-overlay.d.ts +23 -1
  12. package/dist/components/powerline-rail.d.ts +4 -7
  13. package/dist/components/scrollable-history.d.ts +1 -1
  14. package/dist/components/sidebar-panel-frame.d.ts +31 -0
  15. package/dist/components/sidebar-panels-workspace.d.ts +11 -2
  16. package/dist/components/sidebar-scrollbar.d.ts +36 -0
  17. package/dist/components/sidebar.d.ts +13 -1
  18. package/dist/components/status-bar-icons.d.ts +0 -7
  19. package/dist/hooks/tui-slash-command-options.d.ts +30 -0
  20. package/dist/hooks/use-app-environment.d.ts +136 -0
  21. package/dist/hooks/use-app-pipeline-builders.d.ts +1 -0
  22. package/dist/hooks/use-app-ref-spine.d.ts +74 -0
  23. package/dist/hooks/use-app-state.d.ts +20 -0
  24. package/dist/hooks/use-design-kit-slash-commands.d.ts +8 -0
  25. package/dist/hooks/use-next-steps-auto-submit.d.ts +1 -0
  26. package/dist/hooks/use-provider-slash-commands.d.ts +13 -0
  27. package/dist/hooks/use-resource-slash-commands.d.ts +11 -0
  28. package/dist/hooks/use-session-slash-commands.d.ts +17 -0
  29. package/dist/hooks/use-settings-slash-commands.d.ts +22 -0
  30. package/dist/hooks/use-tui-slash-commands.d.ts +2 -29
  31. package/dist/index.js +7754 -6683
  32. package/dist/input-validation/action-types.d.ts +1 -1
  33. package/dist/key-handler-context.d.ts +142 -0
  34. package/dist/key-routes/key-route-busy.d.ts +23 -0
  35. package/dist/key-routes/key-route-composer.d.ts +33 -0
  36. package/dist/key-routes/key-route-overlay.d.ts +65 -0
  37. package/dist/key-routes/key-route-paste.d.ts +17 -0
  38. package/dist/key-routes/key-route-pointer.d.ts +18 -0
  39. package/dist/overlay-key-router.d.ts +2 -0
  40. package/dist/reducers/dialogs.d.ts +1 -1
  41. package/dist/reducers/workspace-panels.d.ts +11 -1
  42. package/dist/run-tui-exits.d.ts +46 -0
  43. package/dist/run-tui-launch.d.ts +23 -0
  44. package/dist/run-tui-mount.d.ts +28 -0
  45. package/dist/run-tui-session.d.ts +13 -0
  46. package/dist/run-tui.d.ts +1 -2
  47. package/dist/sidebar-sizing.d.ts +2 -1
  48. package/dist/ui-contracts.d.ts +15 -0
  49. package/package.json +7 -7
@@ -781,6 +781,9 @@ export type Action = {
781
781
  info: State['confirmQueue'][0];
782
782
  } | {
783
783
  type: 'confirmClose';
784
+ } | {
785
+ type: 'confirmResolved';
786
+ toolUseId: string;
784
787
  } | {
785
788
  type: 'confirmClearAll';
786
789
  } | {
@@ -1195,6 +1198,17 @@ export type Action = {
1195
1198
  /** Reset sidebar scroll offset to 0. */
1196
1199
  | {
1197
1200
  type: 'sidebarScrollReset';
1201
+ }
1202
+ /** Jump the sidebar scroll to an absolute offset (scrollbar press/drag). */
1203
+ | {
1204
+ type: 'sidebarScrollSet';
1205
+ /** Absolute offset in rows from the content top; clamped to [0, max]. */
1206
+ offset: number;
1207
+ viewportHeight?: number | undefined;
1208
+ /** See the `sidebarScroll` twin field — identical clamp semantics. */
1209
+ sidebarTwinRowCount?: number | undefined;
1210
+ /** See the `sidebarScroll` twin field — identical clamp semantics. */
1211
+ effectiveSwarmOnSidebar?: boolean | undefined;
1198
1212
  } | {
1199
1213
  type: 'toggleKanbanPanel';
1200
1214
  } | {
@@ -1,123 +1,8 @@
1
- import type { Director } from '@wrongstack/core/coordination';
2
- import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
3
- import type { Action } from './app-action-type.js';
4
- import type { AppProps } from './app-props.js';
5
- import type { State } from './app-state.js';
6
- import { type KeyEvent } from './components/input.js';
7
- import type { HistoryScrollController } from './components/scrollable-history.js';
8
- import type { StatusBarClickMap } from './components/status-bar-types.js';
9
- import { type StatuslineItem } from './components/statusline-picker.js';
10
- import { type DOMElement } from './ink.js';
11
- import { type PasteAccumState } from './paste-accumulator.js';
12
- interface AppKeyHandlerOptions {
13
- state: State;
14
- dispatch: Dispatch<Action>;
15
- historyScrollRef: MutableRefObject<HistoryScrollController | null>;
16
- /** Resets the live-tail timeout after a user-driven history navigation. */
17
- onHistoryScrollActivity?: (() => void) | undefined;
18
- runInterruptLadder: () => void;
19
- enhanceCancelledRef: MutableRefObject<boolean>;
20
- enhanceAbortRef: MutableRefObject<AbortController | null>;
21
- inputGateRef: MutableRefObject<boolean>;
22
- lastEscAtRef: MutableRefObject<number>;
23
- pasteAccumRef: MutableRefObject<PasteAccumState>;
24
- pasteFlushTimerRef: MutableRefObject<ReturnType<typeof setTimeout> | null>;
25
- commitPaste: (full: string) => Promise<void>;
26
- tryPickerKey: (input: string, key: KeyEvent, isEnter: boolean) => boolean;
27
- dismissedEscAtRef: MutableRefObject<number>;
28
- streamingTextRef: MutableRefObject<string>;
29
- confirmExitRef: MutableRefObject<boolean>;
30
- activeCtrlRef: MutableRefObject<AbortController | null>;
31
- clearPendingConfirms: () => void;
32
- liveDirector: () => Director | null;
33
- openProjectPicker: () => Promise<void>;
34
- loadLiveSessions: () => Promise<void>;
35
- openStatuslinePicker: (field?: number) => void;
36
- statuslineHiddenItems: StatuslineItem[];
37
- getSddRun: AppProps['getSddRun'];
38
- onSddLifecycle: AppProps['onSddLifecycle'];
39
- getSettings: AppProps['getSettings'];
40
- saveSettings: AppProps['saveSettings'];
41
- lastEnterAtRef: MutableRefObject<number>;
42
- draftRef: MutableRefObject<{
43
- buffer: string;
44
- cursor: number;
45
- }>;
46
- setDraft: (buffer: string, cursor: number) => void;
47
- /** Submits the composer. `overrideRaw` bypasses the buffer (bash mode
48
- * forwards its draft through the `!` shell path this way). */
49
- submit: (overrideRaw?: string) => void;
50
- mouseMode: boolean;
51
- termRows: number;
52
- terminalColumns: number;
53
- terminalRows: number;
54
- /** Width of the main column (terminal width minus sidebar). When > 0,
55
- * scrollbar hit-tests use this instead of terminalColumns so the scrollbar
56
- * track is correctly positioned to the left of the sidebar. */
57
- mainColumnWidth: number;
58
- /**
59
- * Whether a full-width overlay owns the screen.
60
- *
61
- * Passed in rather than derived. The old proxy —
62
- * `mainColumnWidth >= stdout.columns` — is true whenever the sidebar is
63
- * ZERO wide, and `computeSidebarWidth` returns 0 for any terminal under
64
- * `SIDEBAR_MIN_TERMINAL` (64 columns). So on a narrow terminal the flag was
65
- * permanently true with nothing open, and the whole `if (!overlayOpen)`
66
- * block below — wheel scrolling, scrollbar drag, drag-select, copy icons,
67
- * every status-bar chip click, PageUp/PageDown — silently stopped working,
68
- * along with Shift+Tab, `?` help, and (via `routeInputKey`) up/down input
69
- * history. `app.tsx` already hands the real value to `useMouseTracking`.
70
- */
71
- overlayOpen: boolean;
72
- /**
73
- * Effective swarm-on-sidebar read: `panelPositions.fleet === 'sidebar'`
74
- * OR the legacy `showAgentSwarmPanel === 'sidebar'` flag from
75
- * `liveSettings`. The renderer at `app-view.tsx:897-899` reads
76
- * ONLY the legacy `showAgentSwarmPanel` field (not the panel-
77
- * position map) to decide whether to show the mission card; the
78
- * scroll-clamp reservation must match that source or a config-only
79
- * legacy 'sidebar' swarm mode (no recent picker open) will render
80
- * the mission card but the clamp will under-reserve, hiding the
81
- * bottom mission rows behind `RightSidebar`'s `overflowY="hidden"`
82
- * viewport. The OR with `panelPositions.fleet` is directionally
83
- * safe (over-reservation is harmless) and aligns with the field
84
- * that gates whether the swarm twin is mounted. See
85
- * {@link SidebarLayoutState.effectiveSwarmOnSidebar}. Threaded into
86
- * `sidebarScroll` dispatches so the reducer's mission-queue
87
- * reservation matches the actual render.
88
- */
89
- effectiveSwarmOnSidebar: boolean;
90
- /**
91
- * Approximate row count for routed sidebar twin panels mounted above
92
- * `SidebarContent`. Subtracted from `viewportHeight` by the reducer's
93
- * scroll clamp so the user can't scroll past the end into blank space.
94
- * See {@link SidebarLayoutState.sidebarTwinRowCount}.
95
- */
96
- sidebarTwinRowCount: number;
97
- statusBarWrapRef: MutableRefObject<DOMElement | null>;
98
- belowStatusBarRef: MutableRefObject<DOMElement | null>;
99
- /** Chip click map published by StatusBar on every render. */
100
- statusBarClickMapRef: MutableRefObject<StatusBarClickMap | null>;
101
- openModelPicker: () => Promise<void>;
102
- nextStepsAutoSubmitTimerRef: MutableRefObject<ReturnType<typeof setInterval> | undefined>;
103
- nextStepsAutoSubmitSuggestionRef: MutableRefObject<string | null>;
104
- nextStepsAutoSubmitLabel: string | null;
105
- setNextStepsAutoSubmitCountdown: Dispatch<SetStateAction<number | null>>;
106
- setNextStepsAutoSubmitLabel: Dispatch<SetStateAction<string | null>>;
107
- cancelNextStepsCountdown: () => void;
108
- pasteClipboardText: () => Promise<void>;
109
- pasteClipboardImage: () => Promise<void>;
110
- slashRegistry: AppProps['slashRegistry'];
111
- agent: AppProps['agent'];
112
- /**
113
- * Called with the copied entry's id after a chat card's copy icon is clicked
114
- * and its content was successfully written to the clipboard. Lets the host
115
- * surface a transient "Copied" confirmation and flash that card's icon. Not
116
- * called when the click missed or the write failed.
117
- */
118
- onHistoryCopy?: ((entryId: number) => void) | undefined;
119
- }
1
+ import type { KeyEvent } from './components/input.js';
2
+ import type { AppKeyHandlerOptions } from './key-handler-context.js';
3
+ export type { AppKeyHandlerOptions } from './key-handler-context.js';
4
+ /** Keyboard activity means the user has taken control of an armed automatic turn. */
5
+ export declare function stopNextStepsAutoSubmitOnKey(cancel: () => void): void;
120
6
  /** Creates the terminal key host around focused overlay/input routers. */
121
7
  export declare function createAppKeyHandler(options: AppKeyHandlerOptions): (input: string, key: KeyEvent) => Promise<void>;
122
- export {};
123
8
  //# sourceMappingURL=app-key-handler.d.ts.map
@@ -61,6 +61,8 @@ interface AppViewRuntime {
61
61
  statusBarRows: number;
62
62
  /** Chip click map published by StatusBar; consumed by the mouse hit-test. */
63
63
  statusBarClickMapRef: MutableRefObject<import('./components/status-bar-types.js').StatusBarClickMap | null>;
64
+ /** Actual inspect-modal title row used for Copy/Close hit-testing. */
65
+ inspectOverlayHeaderRef: MutableRefObject<DOMElement | null>;
64
66
  stableOnKey: (input: string, key: KeyEvent) => void;
65
67
  liveTodos: ReturnType<typeof useLiveTodos>;
66
68
  liveSettings: ReturnType<NonNullable<AppProps['getSettings']>> | undefined;
@@ -82,6 +84,7 @@ interface AppViewRuntime {
82
84
  enhanceCountdown: number | null;
83
85
  nextStepsAutoSubmitCountdown: number | null;
84
86
  nextStepsAutoSubmitLabel: string | null;
87
+ nextStepsAutoSubmitDeadlineMs: number | null;
85
88
  setDraft: (buffer: string, cursor: number) => void;
86
89
  focusedBoardId: string | null;
87
90
  getCronJobs: () => Promise<CronListResult>;
@@ -8,6 +8,14 @@ interface AppViewSidebarProps {
8
8
  runtime: AppViewProps['runtime'];
9
9
  sidebarWidth: number;
10
10
  sidebarContentWidth: number;
11
+ /** Current sidebar scroll offset (rows) — positions the scrollbar thumb. */
12
+ sidebarScrollOffset: number;
13
+ /**
14
+ * Estimated scrollable overflow (rows) from `estimateSidebarMaxScroll`,
15
+ * computed by `app-view.tsx` with the same inputs the wheel/press
16
+ * dispatchers thread. > 0 shows the one-column scrollbar in the rail.
17
+ */
18
+ sidebarMaxScroll: number;
11
19
  sidebarSlotVisible: (id: PanelId) => boolean;
12
20
  hiddenSidebarPanelCount: number;
13
21
  sidebarProcessData: ReturnType<typeof useSidebarProcessList>;
@@ -23,6 +31,6 @@ interface AppViewSidebarProps {
23
31
  * is bootstrapping or the daemon URL hasn't produced a response yet. */
24
32
  sidebarWrongProxyData: ReturnType<typeof useSidebarWrongProxy>;
25
33
  }
26
- export declare function AppViewSidebar({ host, runtime, sidebarWidth, sidebarContentWidth, sidebarSlotVisible, hiddenSidebarPanelCount, sidebarProcessData, sidebarConnectionsData, sidebarKanbanData, sidebarPlanData, sidebarWrongProxyEnabled, sidebarWrongProxyData, }: AppViewSidebarProps): React.ReactElement | null;
34
+ export declare function AppViewSidebar({ host, runtime, sidebarWidth, sidebarContentWidth, sidebarScrollOffset, sidebarMaxScroll, sidebarSlotVisible, hiddenSidebarPanelCount, sidebarProcessData, sidebarConnectionsData, sidebarKanbanData, sidebarPlanData, sidebarWrongProxyEnabled, sidebarWrongProxyData, }: AppViewSidebarProps): React.ReactElement | null;
27
35
  export {};
28
36
  //# sourceMappingURL=app-view-sidebar.d.ts.map
package/dist/app.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
+ export { buildGoalPreamble } from '@wrongstack/core/execution';
3
+ export type { AppProps } from './app-props.js';
2
4
  export { type Action, type FleetEntry, type QueueItem, type ResumeSessionEntry, reducer, type Settings, type SlashCommandMatch, type State, } from './app-reducer.js';
3
5
  export { nextInputWordStart, previousInputWordStart } from './input-editing.js';
4
6
  export { renderRunningTools } from './running-tools.js';
5
7
  export { selectedSlashCommandLine } from './slash-command-search.js';
6
- export { buildGoalPreamble } from '@wrongstack/core/execution';
7
- export type { AppProps } from './app-props.js';
8
8
  export { buildSteeringPreamble } from './steering-preamble.js';
9
9
  import type { AppProps } from './app-props.js';
10
10
  export declare function App(props: AppProps): React.ReactElement;
@@ -5,7 +5,7 @@ interface ConfirmPromptProps {
5
5
  input: unknown;
6
6
  suggestedPattern: string;
7
7
  onDecision: (decision: ConfirmDecision) => void;
8
- /** Enable YOLO mode (capital Y). Approves the current call. */
8
+ /** Enable YOLO mode (capital Y). Destructive current calls remain pending. */
9
9
  onEnableYolo: () => void;
10
10
  /** Whether this call was classified destructive. */
11
11
  destructive?: boolean;
@@ -3,7 +3,17 @@ import React from 'react';
3
3
  import type { ToolResultViewMode } from '../../tool-result-view-mode.js';
4
4
  import type { HistoryEntry } from './types.js';
5
5
  export { councilHeadline, councilSeatLine } from './entry-helpers.js';
6
- export declare const Entry: React.MemoExoticComponent<({ entry, termWidth, termHeight, setSuggestions, autonomyMode, multiDiffSummaryThreshold, todos, showModelReasoning, showSageMemoryInject, toolResultViewMode, }: {
6
+ export declare const NEXT_STEP_SWEEP_DURATION_MS = 10000;
7
+ /** Number of completed glyphs in the final ten-second auto-submit sweep. */
8
+ export declare function nextStepSweepGlyphCount(glyphCount: number, deadlineMs: number, nowMs: number): number;
9
+ export declare function nextStepSweepParts(text: string, deadlineMs: number, nowMs: number): {
10
+ lit: string;
11
+ cursor: string;
12
+ pending: string;
13
+ };
14
+ /** Find the newest rendered panel that owns the armed suggestion label. */
15
+ export declare function findArmedNextStepsEntryId(entries: readonly HistoryEntry[], label: string | null | undefined): number | null;
16
+ export declare const Entry: React.MemoExoticComponent<({ entry, termWidth, termHeight, setSuggestions, autonomyMode, nextStepsAutoSubmitLabel, nextStepsAutoSubmitDeadlineMs, multiDiffSummaryThreshold, todos, showModelReasoning, showSageMemoryInject, toolResultViewMode, }: {
7
17
  entry: HistoryEntry;
8
18
  termWidth: number;
9
19
  /** Available managed-history rows; used by height-aware entries such as the banner. */
@@ -12,6 +22,10 @@ export declare const Entry: React.MemoExoticComponent<({ entry, termWidth, termH
12
22
  setSuggestions?: ((steps: string[]) => void) | undefined;
13
23
  /** Current autonomy mode — when 'auto', first step shows an auto marker. */
14
24
  autonomyMode?: string | undefined;
25
+ /** Exact armed suggestion label; identifies the row that will be submitted. */
26
+ nextStepsAutoSubmitLabel?: string | null | undefined;
27
+ /** Exact deadline; drives a character-by-character sweep during its final 10 seconds. */
28
+ nextStepsAutoSubmitDeadlineMs?: number | null | undefined;
15
29
  /** User-tunable cutoff for the multi-file diff summary footer. Passes
16
30
  * through to `formatMultiDiffSummary`; `undefined` means "use default". */
17
31
  multiDiffSummaryThreshold?: number | undefined;
@@ -16,5 +16,5 @@ export { AssistantStreamBox, assistantStreamBoxHeight, countLines, firstNonEmpty
16
16
  * primitives or stable reducer references, so default shallow
17
17
  * comparison is sufficient.
18
18
  */
19
- export declare const History: React.MemoExoticComponent<({ entries, generation, toolStream, setSuggestions, autonomyMode, multiDiffSummaryThreshold, todos, showModelReasoning, showSageMemoryInject, toolResultViewMode, toolResultViewOverrides, }: HistoryProps) => React.ReactElement>;
19
+ export declare const History: React.MemoExoticComponent<({ entries, generation, toolStream, setSuggestions, autonomyMode, nextStepsAutoSubmitLabel, nextStepsAutoSubmitDeadlineMs, multiDiffSummaryThreshold, todos, showModelReasoning, showSageMemoryInject, toolResultViewMode, toolResultViewOverrides, }: HistoryProps) => React.ReactElement>;
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- export type ToolVisualLineKind = 'ok' | 'warn' | 'error' | 'meta' | 'path' | 'match' | 'code' | 'stdout' | 'stderr';
1
+ export type ToolVisualLineKind = 'ok' | 'warn' | 'error' | 'meta' | 'path' | 'match' | 'context' | 'code' | 'stdout' | 'stderr';
2
2
  export interface ToolVisualLine {
3
3
  kind: ToolVisualLineKind;
4
4
  text: string;
@@ -15,6 +15,10 @@ export interface HistoryProps {
15
15
  * next-step suggestion indicating it will be auto-submitted.
16
16
  */
17
17
  autonomyMode?: string | undefined;
18
+ /** Label of the next step currently armed for automatic submission. */
19
+ nextStepsAutoSubmitLabel?: string | null | undefined;
20
+ /** Exact automatic-submit deadline used by the final 10-second text sweep. */
21
+ nextStepsAutoSubmitDeadlineMs?: number | null | undefined;
18
22
  /**
19
23
  * Generation counter for wholesale history replacements (session resume).
20
24
  * Keys the internal <Static> so a replacement remounts it — Ink's Static
@@ -1,6 +1,9 @@
1
1
  import type React from 'react';
2
+ import type { MutableRefObject } from 'react';
3
+ import { type DOMElement } from '../ink.js';
2
4
  import type { HistoryEntry } from './history/types.js';
3
5
  export declare const INSPECT_OVERLAY_MIN_ROWS = 15;
6
+ export type InspectOverlayHeaderAction = 'copy' | 'close';
4
7
  export declare function resolveInspectOverlayContent(overlay: {
5
8
  entryId: number;
6
9
  entryIds?: readonly number[] | undefined;
@@ -16,6 +19,23 @@ export declare function inspectOverlaySize(termCols: number, viewportRows: numbe
16
19
  width: number;
17
20
  height: number;
18
21
  };
22
+ /**
23
+ * Resolve a terminal click against the two fixed-width controls rendered at
24
+ * the right edge of the centered inspect-overlay title row. Mouse coordinates
25
+ * are the terminal protocol's one-based cells.
26
+ */
27
+ export declare function inspectOverlayHeaderActionAt(header: DOMElement | null, x: number, y: number): InspectOverlayHeaderAction | null;
28
+ /**
29
+ * Thumb geometry for the overlay's vertical scrollbar. The track is
30
+ * `visibleRows` tall; when the wrapped body fits, the thumb covers the whole
31
+ * (dim) track. Otherwise the thumb length is proportional to the visible
32
+ * fraction and travels from the top (offset 0) to flush bottom
33
+ * (offset = totalRows - visibleRows).
34
+ */
35
+ export declare function scrollbarThumbGeometry(totalRows: number, visibleRows: number, offset: number): {
36
+ thumbStart: number;
37
+ thumbLength: number;
38
+ };
19
39
  interface InspectOverlayProps {
20
40
  title: string;
21
41
  body: string;
@@ -24,7 +44,9 @@ interface InspectOverlayProps {
24
44
  viewportRows: number;
25
45
  onScroll: (delta: number) => void;
26
46
  onClose: () => void;
47
+ copied?: boolean | undefined;
48
+ headerRef?: MutableRefObject<DOMElement | null> | undefined;
27
49
  }
28
- export declare function InspectOverlay({ title, body, scroll, termCols, viewportRows, onScroll, onClose, }: InspectOverlayProps): React.ReactElement;
50
+ export declare function InspectOverlay({ title, body, scroll, termCols, viewportRows, onScroll, onClose, copied, headerRef, }: InspectOverlayProps): React.ReactElement;
29
51
  export {};
30
52
  //# sourceMappingURL=inspect-overlay.d.ts.map
@@ -62,9 +62,6 @@ interface PowerlineRailProps {
62
62
  /** Chips in render order. Plain elements are treated as single-level chips. */
63
63
  segments: Array<React.ReactElement | RailSpanEntry>;
64
64
  budget: number;
65
- monochrome?: boolean | undefined;
66
- /** Override the filler background for per-line tonal layering. */
67
- fillBg?: string | undefined;
68
65
  /**
69
66
  * Optional right-anchored segment. When provided, the rail reserves
70
67
  * space for this segment at the right edge of the budget so its
@@ -74,10 +71,10 @@ interface PowerlineRailProps {
74
71
  rightAnchor?: React.ReactElement | null | undefined;
75
72
  }
76
73
  /**
77
- * Full-width status segments with a single uniform background.
78
- * No per-chip backgrounds, no transition glyphs, no segment caps —
79
- * just clean chips separated by a single space.
74
+ * Status segments on the terminal's natural background.
75
+ * No per-chip backgrounds, transition glyphs, or segment caps — just clean
76
+ * chips separated by whitespace. The caller owns any outer side inset.
80
77
  */
81
- export declare function PowerlineRail({ segments, budget, monochrome, fillBg, rightAnchor, }: PowerlineRailProps): React.ReactElement;
78
+ export declare function PowerlineRail({ segments, budget, rightAnchor, }: PowerlineRailProps): React.ReactElement;
82
79
  export {};
83
80
  //# sourceMappingURL=powerline-rail.d.ts.map
@@ -9,6 +9,6 @@ import type { ScrollableHistoryProps } from './history/scroll-controller-types.j
9
9
  /**
10
10
  * Bounded history viewport with stable-anchor virtual scrolling.
11
11
  */
12
- export declare const ScrollableHistory: React.MemoExoticComponent<({ entries, toolStream, streamingText, viewportRows, controllerRef, onScrollInfo, maxWidth, setSuggestions, autonomyMode, multiDiffSummaryThreshold, todos, showModelReasoning, showSageMemoryInject, layoutStore, copiedEntryId, onRequestOlderEntries, toolResultViewMode, toolResultViewOverrides, onToolResultViewChange, }: ScrollableHistoryProps) => React.ReactElement>;
12
+ export declare const ScrollableHistory: React.MemoExoticComponent<({ entries, toolStream, streamingText, viewportRows, controllerRef, onScrollInfo, maxWidth, setSuggestions, autonomyMode, nextStepsAutoSubmitLabel, nextStepsAutoSubmitDeadlineMs, multiDiffSummaryThreshold, todos, showModelReasoning, showSageMemoryInject, layoutStore, copiedEntryId, onRequestOlderEntries, toolResultViewMode, toolResultViewOverrides, onToolResultViewChange, }: ScrollableHistoryProps) => React.ReactElement>;
13
13
  export type { HistoryEntry };
14
14
  //# sourceMappingURL=scrollable-history.d.ts.map
@@ -129,6 +129,37 @@ export declare function SidebarPanelCard(props: CardProps): React.ReactElement;
129
129
  * "framed" look on rails wide enough to afford them.
130
130
  */
131
131
  export declare function SidebarPanelFrame({ accent, icon, title, width, kicker, right, pillLabel, pillColor, footer, children, }: SidebarPanelFrameProps): React.ReactElement;
132
+ /**
133
+ * A fixed-width progress meter row: `▮▮▮▮▮░░░░░` filling exactly
134
+ * `innerWidth` columns (no label — pair it with a `SidebarSectionHeader`
135
+ * badge for the numeric readout). Replaces the hand-rolled bar pairs that
136
+ * Plan / Goal / Connections used to render inline so every sidebar panel
137
+ * shows the same meter texture. Pure display — clamps the ratio to [0, 1].
138
+ */
139
+ export declare function SidebarMeter({ ratio, innerWidth, color, trackColor, marginTop, }: {
140
+ /** Fill ratio 0..1 (values outside are clamped). */
141
+ ratio: number;
142
+ innerWidth: number;
143
+ color: string;
144
+ trackColor?: string | undefined;
145
+ marginTop?: number | undefined;
146
+ }): React.ReactElement;
147
+ /**
148
+ * A single row of colored count chips — `●2 ◐1 ✓4 !1` — the shared idiom
149
+ * for "state distribution" summaries (fleet statuses, worktree states,
150
+ * connection health). Chips whose count is 0 are omitted so the row stays
151
+ * quiet on idle rails; render nothing at all when every count is 0.
152
+ */
153
+ export declare function SidebarCountsRow({ counts, innerWidth, marginTop, }: {
154
+ /** Chip order is render order; zero-count chips are dropped. */
155
+ counts: readonly {
156
+ label: string;
157
+ count: number;
158
+ color: string;
159
+ }[];
160
+ innerWidth: number;
161
+ marginTop?: number | undefined;
162
+ }): React.ReactElement | null;
132
163
  /**
133
164
  * useSidebarPanelSize — returns a sensible default width / height for a
134
165
  * sidebar panel given the terminal dimensions. Width mirrors
@@ -14,10 +14,17 @@ export interface ProjectPickerSidebarProps {
14
14
  export declare function ProjectPickerSidebar({ items, selected, filter, hint, currentProject, width, }: ProjectPickerSidebarProps): React.ReactElement;
15
15
  export interface FleetPanelSidebarProps {
16
16
  entries: Record<string, FleetEntry>;
17
+ /**
18
+ * Pre-computed running count from the caller. Retained for interface
19
+ * compatibility; the panel derives every displayed count (pill + chips)
20
+ * from `entries` so leader and subagents can never diverge.
21
+ */
17
22
  runningCount: number;
23
+ /** Live tick (ms) — drives per-agent elapsed labels. Defaults to Date.now(). */
24
+ nowTick?: number | undefined;
18
25
  width: number;
19
26
  }
20
- export declare function FleetPanelSidebar({ entries, runningCount, width, }: FleetPanelSidebarProps): React.ReactElement;
27
+ export declare function FleetPanelSidebar({ entries, nowTick, width, }: FleetPanelSidebarProps): React.ReactElement;
21
28
  export interface AgentsPanelSidebarProps {
22
29
  entries: Record<string, FleetEntry>;
23
30
  totalCost: number;
@@ -27,9 +34,11 @@ export interface AgentsPanelSidebarProps {
27
34
  export declare function AgentsPanelSidebar({ entries, totalCost, nowTick, width, }: AgentsPanelSidebarProps): React.ReactElement;
28
35
  export interface WorktreePanelSidebarProps {
29
36
  worktrees: Record<string, WorktreeRow>;
37
+ /** Live tick (ms) — drives per-worktree age labels. Defaults to Date.now(). */
38
+ nowTick?: number | undefined;
30
39
  width: number;
31
40
  }
32
- export declare function WorktreePanelSidebar({ worktrees, width, }: WorktreePanelSidebarProps): React.ReactElement;
41
+ export declare function WorktreePanelSidebar({ worktrees, nowTick, width, }: WorktreePanelSidebarProps): React.ReactElement;
33
42
  export interface CoordinatorPanelSidebarProps {
34
43
  running: boolean;
35
44
  activePhases: number;
@@ -0,0 +1,36 @@
1
+ import type React from 'react';
2
+ /** Thumb geometry for a given scroll state. Pure — unit-tested. */
3
+ export declare function sidebarScrollbarThumb(viewportRows: number, maxScroll: number, offset: number): {
4
+ size: number;
5
+ top: number;
6
+ };
7
+ /**
8
+ * Inverse mapping: a 0-based track cell (mouse row − 1 over the rail)
9
+ * becomes the absolute scroll offset at that track position — top of track
10
+ * = 0, bottom of track = maxScroll. Pure — unit-tested and shared with the
11
+ * press/drag dispatcher in `app-key-handler.ts` so click-scrubbing reaches
12
+ * the exact extremes the wheel can reach.
13
+ */
14
+ export declare function sidebarOffsetForCell(cell: number, viewportRows: number, maxScroll: number): number;
15
+ export interface SidebarScrollbarProps {
16
+ /** Visible content rows — the track height (RightSidebar's innerHeight). */
17
+ viewportRows: number;
18
+ /** Current scroll offset in rows. */
19
+ offset: number;
20
+ /**
21
+ * Estimated overflow beyond the viewport; ≤ 0 renders a dimmed,
22
+ * thumb-less track — the rail column itself stays visible.
23
+ */
24
+ maxScroll: number;
25
+ /** When true the thumb reads in the accent color (keyboard focus). */
26
+ focused?: boolean | undefined;
27
+ }
28
+ /**
29
+ * The rail itself: one column of `░` track cells with a `▉` thumb segment.
30
+ * Persistent by design: when there is nothing to scroll it renders a dimmed
31
+ * thumb-less track (not null) so the rail never pops in and out of existence
32
+ * as the content-height estimate fluctuates. Returns null only when there is
33
+ * no room to draw a track at all (< 1 viewport row).
34
+ */
35
+ export declare function SidebarScrollbar({ viewportRows, offset, maxScroll, focused, }: SidebarScrollbarProps): React.ReactElement | null;
36
+ //# sourceMappingURL=sidebar-scrollbar.d.ts.map
@@ -39,12 +39,24 @@ interface RightSidebarProps {
39
39
  * When true, the sidebar border is highlighted to indicate keyboard focus.
40
40
  */
41
41
  focused?: boolean | undefined;
42
+ /**
43
+ * Current sidebar scroll offset in rows. Positions the scrollbar thumb.
44
+ */
45
+ scrollOffset?: number | undefined;
46
+ /**
47
+ * Estimated scrollable overflow in rows (from
48
+ * `estimateSidebarMaxScroll`). > 0 draws a one-column scrollbar with a
49
+ * thumb in the rail's right padding column; ≤ 0 keeps the rail visible
50
+ * as a dimmed, thumb-less track (persistent rail — no bottom-right
51
+ * flicker). Content columns are untouched either way.
52
+ */
53
+ maxScroll?: number | undefined;
42
54
  /**
43
55
  * Content to render inside the sidebar. When omitted, a dimmed placeholder
44
56
  * label is shown so the reserved region is visually self-documenting.
45
57
  */
46
58
  children?: React.ReactNode | undefined;
47
59
  }
48
- export declare function RightSidebar({ width, maxHeight, focused, children, }: RightSidebarProps): React.ReactElement | null;
60
+ export declare function RightSidebar({ width, maxHeight, focused, scrollOffset, maxScroll, children, }: RightSidebarProps): React.ReactElement | null;
49
61
  export {};
50
62
  //# sourceMappingURL=sidebar.d.ts.map
@@ -44,13 +44,6 @@ export declare const STATUSLINE_ICONS: {
44
44
  export declare const COMPACT_THRESHOLD = 50;
45
45
  export declare function chipColor(color: string, isNoColor: boolean): string | undefined;
46
46
  export declare const STACK_ORANGE = "#FD9F02";
47
- /**
48
- * Per-rail background tone. Read through a function (not a frozen array) so
49
- * it follows a live `/theme` switch, and genuinely alternated so the four
50
- * rails read as four bands instead of one block: identity/safety sit on the
51
- * base surface, vitals/async on the raised one.
52
- */
53
- export declare function lineBackground(logical: 0 | 1 | 2 | 3): string;
54
47
  export declare const SPINNER_FRAMES: string[];
55
48
  export declare const SPINNER_INTERVAL_MS = 1000;
56
49
  //# sourceMappingURL=status-bar-icons.d.ts.map
@@ -0,0 +1,30 @@
1
+ import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
2
+ import type { Action } from '../app-action-type.js';
3
+ import type { AppProps } from '../app-props.js';
4
+ import type { State } from '../app-state.js';
5
+ import type { StatuslineItem } from '../components/statusline-picker.js';
6
+ /** Registration options shared by the parent and its domain slice hooks. */
7
+ export interface TuiSlashCommandOptions {
8
+ slashRegistry: AppProps['slashRegistry'];
9
+ skillLoader: AppProps['skillLoader'];
10
+ getResourceMenu: AppProps['getResourceMenu'];
11
+ getPickableProviders: AppProps['getPickableProviders'];
12
+ switchProviderAndModel: AppProps['switchProviderAndModel'];
13
+ openModelPicker: () => Promise<void>;
14
+ openFKeyPicker: () => void;
15
+ projectRoot: string;
16
+ agent: AppProps['agent'];
17
+ dispatch: Dispatch<Action>;
18
+ getSettings: AppProps['getSettings'];
19
+ saveSettings: AppProps['saveSettings'];
20
+ openSettings: () => void;
21
+ state: State;
22
+ openStatuslinePicker: () => void;
23
+ setHiddenItems: (items: StatuslineItem[]) => void;
24
+ hiddenItemsRef: MutableRefObject<StatuslineItem[]>;
25
+ setMailboxPanelOpen: Dispatch<SetStateAction<boolean>>;
26
+ switchAutonomy: AppProps['switchAutonomy'];
27
+ listSessions: AppProps['listSessions'];
28
+ openPromptPicker: () => Promise<void>;
29
+ }
30
+ //# sourceMappingURL=tui-slash-command-options.d.ts.map