@wrongstack/tui 0.300.0 → 0.301.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 (53) hide show
  1. package/dist/app-action-type.d.ts +12 -1
  2. package/dist/app-key-handler.d.ts +17 -14
  3. package/dist/app-settings-type.d.ts +2 -0
  4. package/dist/app-state.d.ts +11 -0
  5. package/dist/app-status-region.d.ts +2 -3
  6. package/dist/app-ui-state.d.ts +33 -40
  7. package/dist/app-view-contract.d.ts +3 -1
  8. package/dist/app-view-state.d.ts +9 -0
  9. package/dist/app.d.ts +2 -2
  10. package/dist/brain-panel-model.d.ts +13 -1
  11. package/dist/components/connections-panel.d.ts +1 -1
  12. package/dist/components/coordinator-panel.d.ts +1 -0
  13. package/dist/components/cron-jobs.d.ts +12 -0
  14. package/dist/components/history/assistant.d.ts +0 -22
  15. package/dist/components/history/index.d.ts +1 -1
  16. package/dist/components/history.d.ts +1 -1
  17. package/dist/components/monitor-shell.d.ts +3 -0
  18. package/dist/components/powerline-rail.d.ts +21 -0
  19. package/dist/components/settings-picker-model.d.ts +1 -1
  20. package/dist/components/settings-picker.d.ts +3 -1
  21. package/dist/components/sidebar-content.d.ts +33 -3
  22. package/dist/components/sidebar-panels.d.ts +4 -6
  23. package/dist/components/status-bar-chips.d.ts +1 -4
  24. package/dist/components/status-bar-format.d.ts +15 -26
  25. package/dist/components/status-bar-types.d.ts +18 -7
  26. package/dist/components/status-bar.d.ts +2 -2
  27. package/dist/components/statusline-detail-panel.d.ts +1 -1
  28. package/dist/components/statusline-picker.d.ts +8 -2
  29. package/dist/components/topic-check-panel.d.ts +7 -0
  30. package/dist/esc-close-panels.d.ts +11 -1
  31. package/dist/f-key-panels.d.ts +1 -1
  32. package/dist/hooks/use-app-picker-keys.d.ts +2 -2
  33. package/dist/hooks/use-git-session-status.d.ts +9 -1
  34. package/dist/hooks/use-next-steps-auto-submit.d.ts +2 -2
  35. package/dist/hooks/use-statusbar-view-model.d.ts +9 -1
  36. package/dist/hooks/use-subagent-events.d.ts +11 -0
  37. package/dist/hooks/use-terminal-size.d.ts +57 -0
  38. package/dist/hooks/use-tui-activity.d.ts +5 -2
  39. package/dist/index.js +34384 -33861
  40. package/dist/input-validation/action-types.d.ts +1 -1
  41. package/dist/input-validation.d.ts +1 -1
  42. package/dist/markdown-table.d.ts +5 -20
  43. package/dist/overlay-key-router.d.ts +27 -6
  44. package/dist/reducers/dialogs.d.ts +1 -1
  45. package/dist/settings-contracts.d.ts +7 -0
  46. package/dist/sidebar-sizing.d.ts +34 -0
  47. package/dist/submit-controller.d.ts +2 -2
  48. package/dist/submit-prompt-refinement.d.ts +1 -1
  49. package/dist/terminal-width.d.ts +18 -6
  50. package/dist/topic-shift-advisor.d.ts +2 -0
  51. package/dist/ui-contracts.d.ts +15 -4
  52. package/package.json +8 -7
  53. package/dist/hooks/use-terminal-render-lifecycle.d.ts +0 -4
@@ -284,6 +284,7 @@ export type Action = {
284
284
  readSymbols: boolean;
285
285
  showSageMemoryInject: boolean;
286
286
  sageMemoryInjectThreshold: number;
287
+ nextStepsTool: boolean;
287
288
  } | {
288
289
  type: 'settingsClose';
289
290
  } | {
@@ -600,11 +601,21 @@ export type Action = {
600
601
  } | {
601
602
  type: 'enhanceBusy';
602
603
  on: boolean;
604
+ } | {
605
+ type: 'topicCheckBusy';
606
+ on: boolean;
603
607
  } | {
604
608
  type: 'refineCountdownOpen';
605
609
  info: NonNullable<State['refineCountdown']>;
606
- } | {
610
+ }
611
+ /**
612
+ * `info` scopes the close to the countdown the caller opened. A refine flow
613
+ * that was superseded by a newer countdown must not tear the newer one down
614
+ * when it finally unwinds; omitting `info` closes unconditionally.
615
+ */
616
+ | {
607
617
  type: 'refineCountdownClose';
618
+ info?: NonNullable<State['refineCountdown']>;
608
619
  } | {
609
620
  type: 'refineFailureOpen';
610
621
  info: NonNullable<State['refineFailure']>;
@@ -5,8 +5,8 @@ import type { AppProps } from './app-props.js';
5
5
  import type { State } from './app-state.js';
6
6
  import { type KeyEvent } from './components/input.js';
7
7
  import type { HistoryScrollController } from './components/scrollable-history.js';
8
+ import type { StatusBarClickMap } from './components/status-bar-types.js';
8
9
  import { type StatuslineItem } from './components/statusline-picker.js';
9
- import type { AutonomyStage } from './hooks/use-statusline-state.js';
10
10
  import { type DOMElement } from './ink.js';
11
11
  import { type PasteAccumState } from './paste-accumulator.js';
12
12
  interface AppKeyHandlerOptions {
@@ -51,6 +51,20 @@ interface AppKeyHandlerOptions {
51
51
  * scrollbar hit-tests use this instead of terminalColumns so the scrollbar
52
52
  * track is correctly positioned to the left of the sidebar. */
53
53
  mainColumnWidth: number;
54
+ /**
55
+ * Whether a full-width overlay owns the screen.
56
+ *
57
+ * Passed in rather than derived. The old proxy —
58
+ * `mainColumnWidth >= stdout.columns` — is true whenever the sidebar is
59
+ * ZERO wide, and `computeSidebarWidth` returns 0 for any terminal under
60
+ * `SIDEBAR_MIN_TERMINAL` (64 columns). So on a narrow terminal the flag was
61
+ * permanently true with nothing open, and the whole `if (!overlayOpen)`
62
+ * block below — wheel scrolling, scrollbar drag, drag-select, copy icons,
63
+ * every status-bar chip click, PageUp/PageDown — silently stopped working,
64
+ * along with Shift+Tab, `?` help, and (via `routeInputKey`) up/down input
65
+ * history. `app.tsx` already hands the real value to `useMouseTracking`.
66
+ */
67
+ overlayOpen: boolean;
54
68
  /**
55
69
  * Effective swarm-on-sidebar read: `panelPositions.fleet === 'sidebar'`
56
70
  * OR the legacy `showAgentSwarmPanel === 'sidebar'` flag from
@@ -78,19 +92,8 @@ interface AppKeyHandlerOptions {
78
92
  sidebarTwinRowCount: number;
79
93
  statusBarWrapRef: MutableRefObject<DOMElement | null>;
80
94
  belowStatusBarRef: MutableRefObject<DOMElement | null>;
81
- liveStatuslineMode: string;
82
- statuslineHiddenForPicker: () => StatuslineItem[];
83
- liveModel: string;
84
- liveProvider: string;
85
- yoloLive: boolean;
86
- autonomyLive: AutonomyStage;
87
- projectName: string | undefined;
88
- workingDirChip: string | undefined;
89
- todos: {
90
- pending: number;
91
- inProgress: number;
92
- completed: number;
93
- };
95
+ /** Chip click map published by StatusBar on every render. */
96
+ statusBarClickMapRef: MutableRefObject<StatusBarClickMap | null>;
94
97
  openModelPicker: () => Promise<void>;
95
98
  nextStepsAutoSubmitTimerRef: MutableRefObject<ReturnType<typeof setInterval> | undefined>;
96
99
  nextStepsAutoSubmitSuggestionRef: MutableRefObject<string | null>;
@@ -89,6 +89,8 @@ export type Settings = {
89
89
  showSageMemoryInject: boolean;
90
90
  /** Minimum relation strength for SAGE memory injection. Default: 0.85. */
91
91
  sageMemoryInjectThreshold: number;
92
+ /** Register the leader's agent-callable `nextsteps` tool. Default: false. */
93
+ nextStepsTool: boolean;
92
94
  /** Prompt cache TTL. */
93
95
  cacheTtl: CacheTtl;
94
96
  /** Where to persist settings: 'global' or 'project'. */
@@ -288,6 +288,8 @@ export type State = {
288
288
  showSageMemoryInject: boolean;
289
289
  /** Minimum relation strength for SAGE memory injection. Default: 0.85. */
290
290
  sageMemoryInjectThreshold: number;
291
+ /** Register the leader's agent-callable `nextsteps` tool. Default: false. */
292
+ nextStepsTool: boolean;
291
293
  /** When true, read tool includes codebase-index symbols alongside file content. */
292
294
  readSymbols: boolean;
293
295
  /** Prompt cache TTL. */
@@ -438,6 +440,8 @@ export type State = {
438
440
  enhanceEnabled: boolean;
439
441
  /** True while the refiner LLM call is in flight (before the panel appears). Drives a "refining…" indicator. */
440
442
  enhanceBusy: boolean;
443
+ /** True only while the long-history topic advisor performs a remote ambiguity check. */
444
+ topicCheckBusy: boolean;
441
445
  /**
442
446
  * Active pre-refine grace countdown. Set after the user submits a prompt
443
447
  * that passes the refiner gate but BEFORE the refiner LLM call starts.
@@ -453,6 +457,13 @@ export type State = {
453
457
  seconds: number;
454
458
  resolve: (decision: 'proceed' | 'skip' | 'cancel') => void;
455
459
  } | null;
460
+ /**
461
+ * Monotonic id of the active countdown, bumped on every open. The panel is
462
+ * keyed on it so a second countdown mounts a FRESH component instead of
463
+ * inheriting the previous one's expired timer — which wedged the panel at
464
+ * "refining in 0s…" with an orphaned resolve. Mirrors `historyGen`.
465
+ */
466
+ refineCountdownGen: number;
456
467
  /**
457
468
  * Active refinement-failure recovery panel. Set when a refine attempt (and
458
469
  * its automatic timeout retry) failed and the user must choose how to
@@ -1,10 +1,9 @@
1
1
  import type React from 'react';
2
- import type { AgentSwarmPanelMode } from './app-settings-type.js';
3
2
  import type { AppViewProps } from './app-view-contract.js';
4
- export declare function resolveAgentSwarmPanelVisibility(settingsOpen: boolean, pickerValue: AgentSwarmPanelMode, persistedValue: AgentSwarmPanelMode | undefined): AgentSwarmPanelMode;
3
+ export { resolveAgentSwarmPanelVisibility } from './app-ui-state.js';
5
4
  export interface AppStatusRegionProps extends AppViewProps {
6
5
  /** Optional column width cap for the status bar (when beside a sidebar). */
7
6
  mainColumnWidth?: number | undefined;
8
7
  }
9
- export declare function AppStatusRegion({ host, runtime, mainColumnWidth }: AppStatusRegionProps): React.ReactElement;
8
+ export declare function AppStatusRegion({ host, runtime, mainColumnWidth, }: AppStatusRegionProps): React.ReactElement;
10
9
  //# sourceMappingURL=app-status-region.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type { State } from './app-reducer.js';
2
+ import type { AgentSwarmPanelMode, Settings } from './app-settings-type.js';
2
3
  import type { StatuslineItem } from './components/statusline-picker.js';
3
4
  import { type PanelId, type PanelPositionMap } from './ui-contracts.js';
4
5
  export declare function mergeStatuslineHiddenItems(hookHidden: StatuslineItem[], reducerHidden: StatuslineItem[]): StatuslineItem[];
@@ -11,6 +12,38 @@ export declare function mergeStatuslineHiddenItems(hookHidden: StatuslineItem[],
11
12
  * collapse the sidebar to width 0 and prevent the twin from mounting.
12
13
  */
13
14
  export declare function isPickerOverlayOpen(state: State): boolean;
15
+ /** Coerced form of {@link effectivePanelPositionsInput} for direct map reads. */
16
+ export declare function effectivePanelPositions(state: State, liveSettings: Settings | undefined): PanelPositionMap;
17
+ /**
18
+ * Pure dual-source read for the legacy tri-state swarm panel mode: the
19
+ * picker draft wins while the settings picker is open, the persisted value
20
+ * (defaulting to 'bottom') otherwise. Prefer
21
+ * {@link effectiveAgentSwarmPanelMode} at call sites that hold `State`.
22
+ */
23
+ export declare function resolveAgentSwarmPanelVisibility(settingsOpen: boolean, pickerValue: AgentSwarmPanelMode, persistedValue: AgentSwarmPanelMode | undefined): AgentSwarmPanelMode;
24
+ /** {@link resolveAgentSwarmPanelVisibility} bound to app state + live settings. */
25
+ export declare function effectiveAgentSwarmPanelMode(state: State, liveSettings: Settings | undefined): AgentSwarmPanelMode;
26
+ /**
27
+ * Open flags for each routable panel — which twins are candidates for a
28
+ * sidebar slot. Shared by the dispatcher and the renderer so the
29
+ * scroll-clamp reservation in `resolveSidebarLayout` and the actual twin
30
+ * mounting in `app-view.tsx` can never disagree about which panels are
31
+ * open. The agents slot honors the legacy `showAgentSwarmPanel: 'off'`
32
+ * tri-state (an explicitly hidden swarm panel must not occupy a slot), and
33
+ * the coordinator slot stays reachable from both entry points: Ctrl+P
34
+ * (goalRunMonitorToggle) opens the phase monitor WITHOUT setting
35
+ * `coordinator.monitorOpen` — `closePanels` resets the latter.
36
+ */
37
+ export declare function buildSidebarOpenFlags(state: State, liveSettings: Settings | undefined): Partial<Record<PanelId, boolean>>;
38
+ /**
39
+ * The one way to compute the sidebar layout from app state. Bundles the
40
+ * dual-source panel-position read, the shared open-flags map, and the
41
+ * legacy swarm-mode flag so the dispatcher (`app.tsx`) and the renderer
42
+ * (`app-view.tsx`) call `resolveSidebarLayout` with byte-identical inputs.
43
+ * Before this wrapper existed the two sites drifted: the dispatcher never
44
+ * saw the picker draft and the renderer never passed the open flags.
45
+ */
46
+ export declare function resolveAppSidebarLayout(state: State, termCols: number, liveSettings: Settings | undefined, mailboxPanelOpen: boolean): SidebarLayoutState;
14
47
  export interface SidebarLayoutState {
15
48
  panelPositions: PanelPositionMap;
16
49
  overlayOpen: boolean;
@@ -38,44 +71,4 @@ export interface SidebarLayoutState {
38
71
  */
39
72
  sidebarTwinRowCount: number;
40
73
  }
41
- /**
42
- * Resolve the TUI's right-sidebar layout once from the open-panel flags and
43
- * persisted panel routing. Both the renderer and input/mouse hit-testing use
44
- * this so a sidebar-routed panel narrows history consistently instead of
45
- * being treated as a full-width overlay by one surface.
46
- */
47
- export declare function resolveSidebarLayout(state: State, termCols: number, panelPositionsInput: Partial<Record<PanelId, 'bottom' | 'sidebar'>> | undefined, mailboxPanelOpen: boolean,
48
- /**
49
- * Open flags for each routable panel, used to compute the visible-twin
50
- * row count for the scroll-clamp reservation. Panels not listed
51
- * (or `undefined`) are treated as closed. Should mirror the same
52
- * `sidebarPanelOpenFlags` map built in `app-view.tsx` so the
53
- * dispatcher and the renderer agree on which twins are mounted.
54
- */
55
- sidebarOpenFlags?: Partial<Record<PanelId, boolean>> | undefined,
56
- /**
57
- * Legacy `showAgentSwarmPanel === 'sidebar'` flag from the persisted
58
- * `liveSettings` config — the same field the renderer at
59
- * `app-view.tsx:897-899` reads (picker draft when open, persisted
60
- * `liveSettings.showAgentSwarmPanel` when closed) to decide whether
61
- * the mission card renders on the sidebar. The scroll-clamp
62
- * reservation must match this source or a config-only 'sidebar'
63
- * swarm mode (no recent picker open) renders the mission card but
64
- * the clamp under-reserves, hiding the bottom mission rows behind
65
- * `RightSidebar`'s `overflowY="hidden"` viewport. OR'd with
66
- * `panelPositions.fleet === 'sidebar'` for safety (over-reservation
67
- * is harmless). Defaults to `false` when omitted so existing call
68
- * sites stay correct.
69
- */
70
- legacySwarmOnSidebar?: boolean | undefined): SidebarLayoutState;
71
- /**
72
- * Conservative row-height estimate for any routed sidebar twin panel.
73
- * Each twin renders a 1-row header + a 1-row separator + variable content +
74
- * optional 1-row footer. 8 rows covers the natural height of the
75
- * content-rich twins (Todos / Plan / Kanban / Goal / Sessions /
76
- * Coordinator) without overshooting the simpler ones (Fleet / Worktree /
77
- * etc.). Over-estimation is safe; the scroll-clamp subtracts this from
78
- * `viewportHeight`.
79
- */
80
- export declare const ESTIMATED_TWIN_HEIGHT = 8;
81
74
  //# sourceMappingURL=app-ui-state.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import type { AgentTimelineEntry, Director } from '@wrongstack/core/coordination';
2
2
  import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
3
- import type { AppProps } from './app-props.js';
4
3
  import type { Action } from './app-action-type.js';
4
+ import type { AppProps } from './app-props.js';
5
5
  import type { State } from './app-state.js';
6
6
  import type { deriveAppViewState } from './app-view-state.js';
7
7
  import type { KeyEvent } from './components/input.js';
@@ -54,6 +54,8 @@ export interface AppViewRuntime {
54
54
  bottomRegionRef: MutableRefObject<DOMElement | null>;
55
55
  statusBarWrapRef: MutableRefObject<DOMElement | null>;
56
56
  belowStatusBarRef: MutableRefObject<DOMElement | null>;
57
+ /** Chip click map published by StatusBar; consumed by the mouse hit-test. */
58
+ statusBarClickMapRef: MutableRefObject<import('./components/status-bar-types.js').StatusBarClickMap | null>;
57
59
  stableOnKey: (input: string, key: KeyEvent) => void;
58
60
  liveTodos: ReturnType<typeof useLiveTodos>;
59
61
  liveSettings: ReturnType<NonNullable<AppProps['getSettings']>> | undefined;
@@ -1,10 +1,19 @@
1
1
  import type { State } from './app-state.js';
2
+ import type { PanelPositionMap } from './ui-contracts.js';
2
3
  interface AppViewStateOptions {
3
4
  state: State;
4
5
  terminalColumns: number;
5
6
  displayThinkingWord: string;
6
7
  fleetRunning: number;
7
8
  liveAnimationStyle: State['settingsPicker']['animationStyle'];
9
+ /**
10
+ * Per-panel routing from `effectivePanelPositions`. A panel routed to
11
+ * the sidebar renders in the right rail, NOT the bottom region — so it
12
+ * must neither hide the composer nor count as a lower-region panel.
13
+ * Reading the raw open flags here without routing collapsed the composer
14
+ * to a placeholder whenever a sidebar-routed panel was toggled.
15
+ */
16
+ panelPositions: PanelPositionMap;
8
17
  }
9
18
  /** Pure composer sizing/visibility and lower-panel projection. */
10
19
  export declare function deriveAppViewState(options: AppViewStateOptions): {
package/dist/app.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  export { type Action, type FleetEntry, type QueueItem, type ResumeSessionEntry, reducer, type Settings, type SlashCommandMatch, type State, } from './app-reducer.js';
3
+ export { nextInputWordStart, previousInputWordStart } from './input-editing.js';
3
4
  export { renderRunningTools } from './running-tools.js';
4
5
  export { selectedSlashCommandLine } from './slash-command-search.js';
5
- export { nextInputWordStart, previousInputWordStart } from './input-editing.js';
6
6
  import type { AppProps } from './app-props.js';
7
- export type { AppProps } from './app-props.js';
8
7
  export { buildGoalPreamble } from '@wrongstack/core/execution';
8
+ export type { AppProps } from './app-props.js';
9
9
  export { buildSteeringPreamble } from './steering-preamble.js';
10
10
  export declare function App(props: AppProps): React.ReactElement;
11
11
  //# sourceMappingURL=app.d.ts.map
@@ -61,6 +61,8 @@ export interface BrainPanelSettings {
61
61
  councilPerCallTimeoutMs?: number | undefined;
62
62
  /** Seats polled concurrently, 1..8 (undefined = default 3). */
63
63
  councilMaxConcurrency?: number | undefined;
64
+ /** Output budget per voter seat call (undefined = default 2000). */
65
+ councilVoterMaxTokens?: number | undefined;
64
66
  /** Output budget for the judge call (undefined = follows the seat budget). */
65
67
  councilJudgeMaxTokens?: number | undefined;
66
68
  /** Explicitly configured voters (empty = seats derive from the pool). */
@@ -140,12 +142,13 @@ export interface BrainPanelHost {
140
142
  setCouncilApproval(fraction: number): Promise<string | null>;
141
143
  setCouncilDistinctness(mode: 'none' | 'model' | 'provider'): Promise<string | null>;
142
144
  /**
143
- * The three positive-integer council knobs. `undefined` clears back to the
145
+ * The positive-integer council knobs. `undefined` clears back to the
144
146
  * default — unlike the LLM/cache ladders, `BrainCouncilPatch` accepts `null`
145
147
  * for these, so a "default" rung is reachable here.
146
148
  */
147
149
  setCouncilPerCallTimeout(ms: number | undefined): Promise<string | null>;
148
150
  setCouncilMaxConcurrency(count: number | undefined): Promise<string | null>;
151
+ setCouncilVoterMaxTokens(tokens: number | undefined): Promise<string | null>;
149
152
  setCouncilJudgeMaxTokens(tokens: number | undefined): Promise<string | null>;
150
153
  setLedgerEnabled(on: boolean): Promise<string | null>;
151
154
  setAutoDeny(count: number | undefined): Promise<string | null>;
@@ -204,6 +207,8 @@ export type BrainPanelRow = {
204
207
  kind: 'councilTimeout';
205
208
  } | {
206
209
  kind: 'councilConcurrency';
210
+ } | {
211
+ kind: 'councilVoterMaxTokens';
207
212
  } | {
208
213
  kind: 'councilJudgeMaxTokens';
209
214
  } | {
@@ -282,6 +287,13 @@ export declare const COUNCIL_DISTINCTNESS_PRESETS: ReadonlyArray<'none' | 'model
282
287
  export declare const COUNCIL_TIMEOUT_PRESETS: ReadonlyArray<number | undefined>;
283
288
  export declare const COUNCIL_CONCURRENCY_PRESETS: ReadonlyArray<number | undefined>;
284
289
  export declare const COUNCIL_JUDGE_MAX_TOKENS_PRESETS: ReadonlyArray<number | undefined>;
290
+ /**
291
+ * Per-seat output budget rungs. The default is 2000 (see
292
+ * `BRAIN_COUNCIL_DEFAULT_VOTER_MAX_TOKENS` in core) — reasoning models spend
293
+ * their thinking tokens from this budget, so the rungs skew higher than the
294
+ * judge ladder.
295
+ */
296
+ export declare const COUNCIL_VOTER_MAX_TOKENS_PRESETS: ReadonlyArray<number | undefined>;
285
297
  /**
286
298
  * Fallback lens cycle for hosts that publish no `personaCatalog`. Prefer
287
299
  * {@link personaCycle}, which uses the host's catalog when it is available —
@@ -2,6 +2,6 @@ interface ConnectionsPanelProps {
2
2
  projectRoot: string;
3
3
  onClose: () => void;
4
4
  }
5
- export declare function ConnectionsPanel({ projectRoot, onClose }: ConnectionsPanelProps): React.ReactElement;
5
+ export declare function ConnectionsPanel({ projectRoot, onClose, }: ConnectionsPanelProps): React.ReactElement;
6
6
  export {};
7
7
  //# sourceMappingURL=connections-panel.d.ts.map
@@ -1,3 +1,4 @@
1
+ /** F11 — project-level AutonomousCoordinator monitor. */
1
2
  import type React from 'react';
2
3
  import type { State } from '../app-state.js';
3
4
  export interface CoordinatorPanelProps {
@@ -1,3 +1,15 @@
1
+ /**
2
+ * CronJobsMonitor — F-key panel showing all scheduled cron jobs.
3
+ *
4
+ * Follows the same pattern as ProcessListMonitor:
5
+ * - 1s tick for live elapsed times + data refresh
6
+ * - MonitorShell wrapper for consistent chrome
7
+ * - panelWindow for scrollable list
8
+ * - Keyboard navigation (↑↓ PgUp/PgDn Home/End)
9
+ * - Confirmation prompt for cancel action
10
+ *
11
+ * Data source: `getCronJobs` callback wired to the agent's `cron_list` tool.
12
+ */
1
13
  import type React from 'react';
2
14
  export interface CronJobView {
3
15
  name: string;
@@ -37,26 +37,4 @@ export declare function AssistantBody({ text, termWidth, contentWidth, }: {
37
37
  /** Real inner width of the surrounding panel. Defaults to `termWidth`. */
38
38
  contentWidth?: number | undefined;
39
39
  }): React.ReactElement;
40
- export declare const ASSISTANT_TAIL_HEIGHT: number;
41
- /**
42
- * Build the CONSTANT-height row set for the live assistant tail: always exactly
43
- * `tailLines` rows (newest pinned to the bottom, blank padding on top), each
44
- * truncated to `contentWidth` so nothing wraps. Pure + exported for testing.
45
- */
46
- export declare function assistantTailRows(text: string, tailLines: number, contentWidth: number): string[];
47
- /**
48
- * The live "ASSISTANT: (streaming...)" tail shown below committed history.
49
- *
50
- * Renders at a CONSTANT height (header + ASSISTANT_TAIL_LINES rows) with every
51
- * line truncated to the terminal width so nothing wraps. A wrapping/growing
52
- * tail pinned to the bottom of the screen forces the terminal to scroll on each
53
- * delta, and in inline mode each scroll leaks the input prompt
54
- * row into permanent scrollback. Holding the height fixed limits that to one
55
- * scroll when streaming starts. Rows are bottom-aligned (blank padding on top)
56
- * so the newest line stays pinned to the bottom.
57
- */
58
- export declare function AssistantTail({ text, termWidth, }: {
59
- text: string;
60
- termWidth: number;
61
- }): React.ReactElement;
62
40
  //# sourceMappingURL=assistant.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import type React from 'react';
2
2
  import type { HistoryProps } from './types.js';
3
- export { ASSISTANT_TAIL_HEIGHT, AssistantBody, AssistantTail, assistantContentWidth, assistantTailRows, MESSAGE_PANEL_BORDER_WIDTH, MESSAGE_PANEL_CHROME_WIDTH, MESSAGE_PANEL_MARGIN, splitFencedBlocks, } from './assistant.js';
3
+ export { AssistantBody, assistantContentWidth, MESSAGE_PANEL_BORDER_WIDTH, MESSAGE_PANEL_CHROME_WIDTH, MESSAGE_PANEL_MARGIN, splitFencedBlocks, } from './assistant.js';
4
4
  export { Banner } from './banner.js';
5
5
  export { CodeBlock, DiffBlock, DiffFileBlock, type DiffFilePreview, type DiffLineKind, type DiffLineRow, type DiffPreview, extractDiffPreview, extractMultiFileDiffs, extractReplaceDiffs, formatDiffStats, formatMultiDiffSummary, MULTI_DIFF_MAX_FILES, MULTI_DIFF_MAX_ROWS, MULTI_DIFF_SUMMARY_THRESHOLD, type MultiDiffSummary, parseUnifiedDiff, summarizeMultiFileDiffs, } from './code-block.js';
6
6
  export { Entry } from './entry.js';
@@ -1,2 +1,2 @@
1
- export { ASSISTANT_TAIL_HEIGHT, AssistantBody, AssistantTail, type AutonomyAgentStatus, assistantContentWidth, assistantTailRows, Banner, type BodySegment, CodeBlock, countLines, DiffBlock, DiffFileBlock, type DiffFilePreview, type DiffLineKind, type DiffLineRow, type DiffPreview, Entry, extractDiffPreview, extractMultiFileDiffs, extractReplaceDiffs, firstNonEmpty, fmtBytes, fmtDuration, fmtTok, formatMatchHit, formatMultiDiffSummary, formatToolArgs, formatToolOutput, formatToolVisualOutput, History, type HistoryEntry, type HistoryProps, MAX_STREAM_DISPLAY_CHARS, MESSAGE_PANEL_BORDER_WIDTH, MESSAGE_PANEL_CHROME_WIDTH, MESSAGE_PANEL_MARGIN, MULTI_DIFF_MAX_FILES, MULTI_DIFF_MAX_ROWS, MULTI_DIFF_SUMMARY_THRESHOLD, type MultiDiffSummary, numOf, parseUnifiedDiff, previewArgs, previewOutput, scanNumberedRange, shortenPath, splitFencedBlocks, streamBoxRows, stringOf, summarizeMultiFileDiffs, ToolOutputLines, ToolStreamBox, toolStreamBoxHeight, type ToolVisualLine, type ToolVisualLineKind, tailForDisplay, truncMid, tryParseJson, } from './history/index.js';
1
+ export { AssistantBody, type AutonomyAgentStatus, assistantContentWidth, Banner, type BodySegment, CodeBlock, countLines, DiffBlock, DiffFileBlock, type DiffFilePreview, type DiffLineKind, type DiffLineRow, type DiffPreview, Entry, extractDiffPreview, extractMultiFileDiffs, extractReplaceDiffs, firstNonEmpty, fmtBytes, fmtDuration, fmtTok, formatMatchHit, formatMultiDiffSummary, formatToolArgs, formatToolOutput, formatToolVisualOutput, History, type HistoryEntry, type HistoryProps, MAX_STREAM_DISPLAY_CHARS, MESSAGE_PANEL_BORDER_WIDTH, MESSAGE_PANEL_CHROME_WIDTH, MESSAGE_PANEL_MARGIN, MULTI_DIFF_MAX_FILES, MULTI_DIFF_MAX_ROWS, MULTI_DIFF_SUMMARY_THRESHOLD, type MultiDiffSummary, numOf, parseUnifiedDiff, previewArgs, previewOutput, scanNumberedRange, shortenPath, splitFencedBlocks, streamBoxRows, stringOf, summarizeMultiFileDiffs, ToolOutputLines, ToolStreamBox, type ToolVisualLine, type ToolVisualLineKind, tailForDisplay, toolStreamBoxHeight, truncMid, tryParseJson, } from './history/index.js';
2
2
  //# sourceMappingURL=history.d.ts.map
@@ -1,4 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
+ export declare const PanelShortcutsProvider: import("react").Provider<boolean>;
3
+ /** True when panel letter shortcuts may fire (empty composer draft). */
4
+ export declare function usePanelShortcutsEnabled(): boolean;
2
5
  export interface MonitorSize {
3
6
  columns: number;
4
7
  rows: number;
@@ -1,5 +1,26 @@
1
1
  import type React from 'react';
2
2
  export declare function visibleNodeText(node: React.ReactNode): string;
3
+ export interface RailSpanEntry {
4
+ /** Stable identifier used by the mouse hit-test ('model', 'todos', …). */
5
+ id: string;
6
+ node: React.ReactElement;
7
+ }
8
+ export interface RailSpan {
9
+ id: string;
10
+ /** 0-based start column within the rail's row. */
11
+ start: number;
12
+ /** Rendered width in columns. */
13
+ len: number;
14
+ }
15
+ /**
16
+ * 0-based column spans of the segments PowerlineRail will actually keep,
17
+ * mirroring its keep/drop and right-anchor trim math exactly. The status-bar
18
+ * mouse hit-test consumes this so click targets are derived from the SAME
19
+ * nodes the renderer draws — dead-reckoned column constants drifted every
20
+ * time a chip changed width or moved lines. Keep this in lockstep with
21
+ * PowerlineRail's layout loop above.
22
+ */
23
+ export declare function computeRailSpans(entries: readonly RailSpanEntry[], budget: number, rightAnchor?: React.ReactElement | null): RailSpan[];
3
24
  export interface PowerlineRailProps {
4
25
  segments: React.ReactElement[];
5
26
  budget: number;
@@ -83,7 +83,7 @@ export type AnimationStyleChoice = (typeof ANIMATION_STYLE_CHOICES)[number];
83
83
  export declare function formatAnimationStyle(style: AnimationStyleChoice): string;
84
84
  export declare const MODE_DESC: Record<SettingsMode, string>;
85
85
  /** Total number of settings rows (used for wrap-around navigation).
86
- * Indices 0–44 are the legacy auto-rebuilt Settings surface; 45..44+PANEL_IDS.length
86
+ * Indices 0–45 are the legacy auto-rebuilt Settings surface; 46..45+PANEL_IDS.length
87
87
  * are the per-panel position rows (one per PanelId in PANEL_IDS order)
88
88
  * added when the showAgentSwarmPanel tri-state was generalized into the
89
89
  * per-panel PanelPositionMap. Derived from PANEL_IDS.length so adding
@@ -73,6 +73,8 @@ export interface SettingsPickerProps {
73
73
  showSageMemoryInject: boolean;
74
74
  /** Minimum relation strength for SAGE memory injection. Default: 0.85. */
75
75
  sageMemoryInjectThreshold: number;
76
+ /** Register the leader's agent-callable `nextsteps` tool. Default: false. */
77
+ nextStepsTool: boolean;
76
78
  /** When true, read tool includes codebase-index symbols alongside file content. */
77
79
  readSymbols: boolean;
78
80
  /**
@@ -102,5 +104,5 @@ export interface SettingsPickerProps {
102
104
  filter?: string | undefined;
103
105
  hint?: string | undefined;
104
106
  }
105
- export declare function SettingsPicker({ field, filter, mode, delayMs, titleAnimation, yolo, fleetChat, chime, confirmExit, nextPrediction, featureMcp, featurePlugins, featureMemory, featureSkills, featureModelsRegistry, tokenSavingTier, allowOutsideProjectRoot, maxIterations, autoProceedMaxIterations, enhanceDelayMs, enhanceEnabled, enhanceLanguage, preRefineSeconds, indexOnStart, multiDiffSummaryThreshold, thinkingWord, thinkingWordEditing, thinkingWordDraft, reasoningMode, reasoningEffort, reasoningPreserve, cacheTtl, contextAutoCompact, contextStrategy, contextMode, maxConcurrent, logLevel, auditLevel, debugStream, statuslineMode, configScope, profileConfigPath, animationStyle, breakerEnabled, breakerAutoKillResetMs, showModelReasoning, showAgentSwarmPanel, showSageMemoryInject, sageMemoryInjectThreshold, readSymbols, panelPositions, hint, }: SettingsPickerProps): React.ReactElement;
107
+ export declare function SettingsPicker({ field, filter, mode, delayMs, titleAnimation, yolo, fleetChat, chime, confirmExit, nextPrediction, featureMcp, featurePlugins, featureMemory, featureSkills, featureModelsRegistry, tokenSavingTier, allowOutsideProjectRoot, maxIterations, autoProceedMaxIterations, enhanceDelayMs, enhanceEnabled, enhanceLanguage, preRefineSeconds, indexOnStart, multiDiffSummaryThreshold, thinkingWord, thinkingWordEditing, thinkingWordDraft, reasoningMode, reasoningEffort, reasoningPreserve, cacheTtl, contextAutoCompact, contextStrategy, contextMode, maxConcurrent, logLevel, auditLevel, debugStream, statuslineMode, configScope, profileConfigPath, animationStyle, breakerEnabled, breakerAutoKillResetMs, showModelReasoning, showAgentSwarmPanel, showSageMemoryInject, sageMemoryInjectThreshold, nextStepsTool, readSymbols, panelPositions, hint, }: SettingsPickerProps): React.ReactElement;
106
108
  //# sourceMappingURL=settings-picker.d.ts.map
@@ -1,7 +1,9 @@
1
- import type { ResumeSessionEntry } from '../app-state.js';
2
- import type { FleetEntry } from '../app-state-fleet.js';
3
1
  import type { TodoItem } from '@wrongstack/core/agent';
2
+ import type { ContextBreakdown } from '@wrongstack/core/utils';
4
3
  import type React from 'react';
4
+ import type { ResumeSessionEntry } from '../app-state.js';
5
+ import type { FleetEntry } from '../app-state-fleet.js';
6
+ import type { HeapSample } from '../heap-watchdog.js';
5
7
  import type { LiveSessionEntry } from './sessions-panel.js';
6
8
  export interface SidebarContentProps {
7
9
  /** Live context window data from useStatusbarViewModel. */
@@ -9,6 +11,8 @@ export interface SidebarContentProps {
9
11
  used: number;
10
12
  max: number;
11
13
  } | undefined;
14
+ /** Honest per-category accounting behind the context window display. */
15
+ contextBreakdown?: ContextBreakdown | undefined;
12
16
  /** Fleet entries (leader + subagents) from useStatusbarViewModel. */
13
17
  entries: Record<string, FleetEntry>;
14
18
  /** Fleet counts summary. */
@@ -42,6 +46,18 @@ export interface SidebarContentProps {
42
46
  resumeSessions?: readonly ResumeSessionEntry[] | undefined;
43
47
  /** The current session ID — used to highlight the active session row. */
44
48
  currentSessionId?: string | undefined;
49
+ /** Current RSS/heap sample for this CLI process. */
50
+ processMemory?: HeapSample | undefined;
51
+ /** CPU usage percentage (0-100). Derived from process.cpuUsage delta. */
52
+ cpuPercent?: number | undefined;
53
+ /** Recent CPU ratios (0-1, oldest → newest) for the trend sparkline. */
54
+ cpuHistory?: readonly number[] | undefined;
55
+ /** Recent RSS/totalMem ratios (0-1) for the trend sparkline. */
56
+ rssHistory?: readonly number[] | undefined;
57
+ /** Recent heap-pressure ratios (0-1) for the trend sparkline. */
58
+ heapHistory?: readonly number[] | undefined;
59
+ /** Total physical RAM in bytes — denominator of the RAM ratio. */
60
+ totalMem?: number | undefined;
45
61
  }
46
62
  /**
47
63
  * Normalized "is this session row the current session?" predicate used by
@@ -59,5 +75,19 @@ export interface SidebarContentProps {
59
75
  * single source of truth.
60
76
  */
61
77
  export declare function isCurrentSession(rowId: string | undefined, currentSessionId: string | undefined, fallbackIsCurrent?: boolean | undefined): boolean;
62
- export declare function SidebarContent({ contextWindow, entries, fleetCounts, provider, model, width, scrollOffset, focused, todos, showSwarmSection, liveSessions, resumeSessions, currentSessionId, }: SidebarContentProps): React.ReactElement;
78
+ interface ContextSegment {
79
+ label: string;
80
+ shortLabel: string;
81
+ tokens: number;
82
+ color: string;
83
+ glyph: string;
84
+ }
85
+ export declare function contextSpectrum(breakdown: ContextBreakdown | undefined, contextWindow: {
86
+ used: number;
87
+ max: number;
88
+ } | undefined, width: number): Array<ContextSegment & {
89
+ cells: number;
90
+ }>;
91
+ export declare function SidebarContent({ contextWindow, contextBreakdown, entries, fleetCounts, provider, model, width, scrollOffset, focused, todos, showSwarmSection, liveSessions, resumeSessions, currentSessionId, processMemory, cpuPercent, cpuHistory, rssHistory, heapHistory, totalMem, }: SidebarContentProps): React.ReactElement;
92
+ export {};
63
93
  //# sourceMappingURL=sidebar-content.d.ts.map
@@ -1,12 +1,10 @@
1
- import type React from 'react';
2
- import type { FleetEntry } from '../app-state.js';
3
1
  import type { TodoItem } from '@wrongstack/core/agent';
4
- import type { GoalSummary } from '../app-state.js';
2
+ import type React from 'react';
3
+ import type { FleetEntry, GoalSummary, ResumeSessionEntry } from '../app-state.js';
5
4
  import type { QueueItem } from '../app-state-core-types.js';
6
- import type { LiveSessionEntry } from './sessions-panel.js';
7
- import type { ProjectPickerItem } from './project-picker.js';
8
- import type { ResumeSessionEntry } from '../app-state.js';
9
5
  import type { WorktreeRow } from '../ui-contracts.js';
6
+ import type { ProjectPickerItem } from './project-picker.js';
7
+ import type { LiveSessionEntry } from './sessions-panel.js';
10
8
  export interface ProjectPickerSidebarProps {
11
9
  /** Already-filtered picker items. Navigation indices target this list directly. */
12
10
  items: readonly ProjectPickerItem[];
@@ -24,13 +24,10 @@ export declare function EternalStageChip({ stage, monochrome, }: {
24
24
  * the per-glyph Catppuccin pastel hue sweep (the original wave UI);
25
25
  * the other three reuse the helpers from `animation-style.tsx`.
26
26
  */
27
- export declare function ThinkingChip({ text, style, phase, cycleTick, colorPhase, }: {
27
+ export declare function ThinkingChip({ text, style, phase, cycleTick, }: {
28
28
  text: string;
29
29
  style: AnimationStyle | 'cycle';
30
30
  phase: number;
31
31
  cycleTick: number;
32
- /** Fast (~120ms cadence) animation frame for color effects (rainbow/wave/pulse).
33
- * Derived from `animationTime` to decouple color speed from the 1s spinner. */
34
- colorPhase: number;
35
32
  }): React.ReactElement;
36
33
  //# sourceMappingURL=status-bar-chips.d.ts.map
@@ -25,32 +25,6 @@ export declare function tokenDisplayTotals(usage: {
25
25
  cacheWrite?: number | undefined;
26
26
  } | undefined, estimatedInput?: number | undefined): TokenDisplayTotals;
27
27
  export declare function hasTokenDisplay(tokens: TokenDisplayTotals): boolean;
28
- export declare function statusBarModelSpan(opts: {
29
- model: string;
30
- provider?: string | undefined;
31
- yolo?: boolean | undefined;
32
- autonomy?: 'off' | 'suggest' | 'auto' | 'eternal' | 'eternal-parallel' | undefined;
33
- projectName?: string | undefined;
34
- workingDir?: string | undefined;
35
- projectHidden?: boolean | undefined;
36
- workingDirHidden?: boolean | undefined;
37
- monochrome?: boolean | undefined;
38
- }): {
39
- start: number;
40
- len: number;
41
- };
42
- export declare function statusBarAutonomySpan(opts: {
43
- yolo?: boolean | undefined;
44
- autonomy?: 'off' | 'suggest' | 'auto' | 'eternal' | 'eternal-parallel' | undefined;
45
- monochrome?: boolean | undefined;
46
- }): {
47
- start: number;
48
- len: number;
49
- } | null;
50
- export declare function statusBarTodosSpan(): {
51
- start: number;
52
- len: number;
53
- };
54
28
  export declare function stateChip(state: 'idle' | 'running' | 'streaming' | 'aborting', fleetRunning: number, thinkingWord?: string | undefined): {
55
29
  label: string;
56
30
  color: string;
@@ -68,6 +42,21 @@ export declare function blockMeter(ratio: number, width: number): {
68
42
  filled: string;
69
43
  empty: string;
70
44
  };
45
+ /**
46
+ * Render a 0..1 ratio history as a compact sparkline (oldest → newest, the
47
+ * latest sample is the last character). Each value maps onto one of the eight
48
+ * block levels, so a flat history renders as a flat line and spikes pop as
49
+ * peaks. Only the trailing `width` samples are drawn; a width of 0 (or an
50
+ * empty history) renders nothing.
51
+ */
52
+ export declare function sparkline(values: readonly number[], width: number): string;
53
+ /**
54
+ * A morphing dial glyph that fills like a loading ring as the ratio rises:
55
+ * `○` (idle) → `◔` → `◑` → `◕` → `●` (saturated). Non-bar replacement for
56
+ * block meters in the sidebar SYSTEM card. Same glyph family as the
57
+ * session-status dots (● ◉ ◐ ○) already used elsewhere in the TUI.
58
+ */
59
+ export declare function dialGlyph(ratio: number): string;
71
60
  export declare function fmtTok(n: number): string;
72
61
  export declare function fmtMemory(bytes: number): string;
73
62
  export declare function fmtElapsed(ms: number): string;