@wrongstack/tui 1.0.19 → 1.0.24

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 (91) hide show
  1. package/dist/app-action-type.d.ts +31 -0
  2. package/dist/app-key-handler.d.ts +1 -1
  3. package/dist/app-panel-state.d.ts +536 -0
  4. package/dist/app-props.d.ts +1 -1
  5. package/dist/app-state.d.ts +8 -534
  6. package/dist/app-status-region.d.ts +2 -1
  7. package/dist/app-ui-state.d.ts +2 -0
  8. package/dist/app-view-pickers.d.ts +2 -1
  9. package/dist/app-view-state.d.ts +2 -0
  10. package/dist/app.d.ts +2 -2
  11. package/dist/auth-panel-model.d.ts +1 -0
  12. package/dist/components/agent-monitor-presentation.d.ts +61 -0
  13. package/dist/components/agents-monitor.d.ts +3 -49
  14. package/dist/components/audit-panel.d.ts +2 -1
  15. package/dist/components/auth-panel.d.ts +3 -1
  16. package/dist/components/brain-panel.d.ts +3 -1
  17. package/dist/components/checkpoint-timeline.d.ts +1 -1
  18. package/dist/components/confirm-prompt.d.ts +6 -7
  19. package/dist/components/connections-panel.d.ts +2 -1
  20. package/dist/components/context-panel-sections.d.ts +53 -0
  21. package/dist/components/context-panel-types.d.ts +66 -0
  22. package/dist/components/context-panel.d.ts +2 -66
  23. package/dist/components/exit-confirm-panel.d.ts +2 -0
  24. package/dist/components/file-picker.d.ts +2 -1
  25. package/dist/components/help-panel.d.ts +5 -3
  26. package/dist/components/history/utils.d.ts +3 -9
  27. package/dist/components/history/visual-tool-output.d.ts +8 -0
  28. package/dist/components/input.d.ts +1 -1
  29. package/dist/components/kanban-panel-presentation.d.ts +114 -0
  30. package/dist/components/kanban-panel.d.ts +2 -47
  31. package/dist/components/mailbox-panel.d.ts +2 -1
  32. package/dist/components/mcp-picker.d.ts +3 -1
  33. package/dist/components/mode-picker.d.ts +3 -1
  34. package/dist/components/model-picker.d.ts +1 -1
  35. package/dist/components/monitor-shell.d.ts +14 -3
  36. package/dist/components/plugin-picker.d.ts +3 -1
  37. package/dist/components/powerline-rail.d.ts +6 -3
  38. package/dist/components/provider-colors.d.ts +2 -12
  39. package/dist/components/refine-countdown-panel.d.ts +4 -3
  40. package/dist/components/settings-picker-row-list.d.ts +2 -1
  41. package/dist/components/settings-picker.d.ts +3 -1
  42. package/dist/components/shadow-panel.d.ts +2 -1
  43. package/dist/components/sidebar-content.d.ts +1 -47
  44. package/dist/components/sidebar-ipc-icons.d.ts +9 -0
  45. package/dist/components/sidebar-presentation.d.ts +98 -0
  46. package/dist/components/sidebar.d.ts +3 -1
  47. package/dist/components/skill-picker.d.ts +2 -1
  48. package/dist/components/slash-confirm-panel.d.ts +2 -0
  49. package/dist/components/slash-menu.d.ts +2 -1
  50. package/dist/components/slash-modal-frame.d.ts +9 -0
  51. package/dist/components/statusline-picker.d.ts +2 -2
  52. package/dist/components/tools-picker.d.ts +3 -1
  53. package/dist/components/user-input-prompt.d.ts +4 -2
  54. package/dist/connection-actions.d.ts +20 -0
  55. package/dist/connections-health.d.ts +8 -1
  56. package/dist/esc-close-panels.d.ts +0 -1
  57. package/dist/f-key-panels.d.ts +4 -0
  58. package/dist/hooks/use-active-theme.d.ts +2 -1
  59. package/dist/hooks/use-app-panels-state.d.ts +1 -1
  60. package/dist/hooks/use-app-picker-keys.d.ts +2 -1
  61. package/dist/hooks/use-fleet-generation-gate.d.ts +4 -3
  62. package/dist/hooks/use-panel-controllers.d.ts +1 -1
  63. package/dist/hooks/use-picker-keys-types.d.ts +1 -0
  64. package/dist/hooks/use-shadow-panel.d.ts +1 -1
  65. package/dist/hooks/use-sidebar-panel-data.d.ts +7 -5
  66. package/dist/hooks/use-skill-mention-picker.d.ts +6 -0
  67. package/dist/hooks/use-statusbar-view-model.d.ts +2 -2
  68. package/dist/hooks/use-windowed-picker.d.ts +3 -4
  69. package/dist/index.js +9992 -7778
  70. package/dist/ink.d.ts +4 -4
  71. package/dist/input-graphemes.d.ts +4 -0
  72. package/dist/input-key-router.d.ts +2 -0
  73. package/dist/input-tokens.d.ts +10 -0
  74. package/dist/input-validation/action-types.d.ts +1 -1
  75. package/dist/input-validation-coordination.d.ts +9 -0
  76. package/dist/kanban-arguments.d.ts +48 -0
  77. package/dist/kanban-command-types.d.ts +53 -0
  78. package/dist/kanban-reports.d.ts +42 -0
  79. package/dist/kanban-slash.d.ts +4 -125
  80. package/dist/key-routes/key-route-overlay.d.ts +2 -2
  81. package/dist/on-panel-open.d.ts +1 -1
  82. package/dist/picker-text-input.d.ts +4 -0
  83. package/dist/reducers/composer.d.ts +1 -1
  84. package/dist/reducers/panel-pickers.d.ts +1 -1
  85. package/dist/reducers/workspace-panels.d.ts +1 -1
  86. package/dist/run-tui-options.d.ts +1 -1
  87. package/dist/statusline-palette.d.ts +4 -0
  88. package/dist/theme-utils.d.ts +1 -1
  89. package/dist/ui-contracts.d.ts +1 -0
  90. package/dist/use-app-controller.d.ts +157 -0
  91. package/package.json +7 -7
@@ -1,5 +1,4 @@
1
1
  import type { Context } from '@wrongstack/core/agent';
2
- import { type KanbanBoard, type KanbanLifecycleStage, type KanbanTask } from '@wrongstack/kanban';
3
2
  import type React from 'react';
4
3
  interface KanbanPanelProps {
5
4
  projectRoot: string;
@@ -23,50 +22,6 @@ interface KanbanPanelProps {
23
22
  */
24
23
  initialBoardId?: string | undefined;
25
24
  }
26
- export declare function KanbanPanel({ projectRoot, sessionId, sessionContext, onClose, terminalWidth, initialBoardId, }: KanbanPanelProps): React.ReactElement;
27
- /**
28
- * Pure, deterministic layout math for the kanban board's column view.
29
- *
30
- * Reserves horizontal space for the chrome that surrounds the columns
31
- * (board list panel + task detail panel + gaps + outer border), then
32
- * picks the largest column count that still keeps every column at least
33
- * `minColumnWidth` cols wide, and finally shrinks each column's width to
34
- * match the available budget (never below `minColumnWidth`).
35
- *
36
- * Exported so Sprint 2's regression tests can pin the math down without
37
- * mounting Ink.
38
- */
39
- export declare function computeBoardColumnLayout(totalColumns: number, terminalWidth: number): {
40
- visibleColumnCount: number;
41
- columnWidth: number;
42
- overflow: number;
43
- };
44
- /**
45
- * The next stage a managed card may advance to, or null when the card is
46
- * already at the terminal `done` stage (or the current stage is unknown).
47
- * The domain only allows one-step forward transitions; callers must keep
48
- * this in lockstep with `KANBAN_AGENT_STAGES` in `@wrongstack/kanban`.
49
- *
50
- * Exported so unit tests can pin the stage order without rendering the panel.
51
- */
52
- export declare function nextManagedStage(current: KanbanLifecycleStage): KanbanLifecycleStage | null;
53
- /**
54
- * Look up the lifecycle stage that owns the given column under a managed
55
- * Kanban Agent board. Returns null when the board is not managed, or when
56
- * the column is not mapped to any of the five canonical stages (treated
57
- * as a legacy/custom column by the renderer).
58
- */
59
- export declare function stageForColumn(board: Pick<KanbanBoard, 'lifecycle'>, columnId: string): KanbanLifecycleStage | null;
60
- /**
61
- * Pure success-criteria summary string. Returns null when there are no
62
- * checks. Format: "Criteria N/M passed".
63
- */
64
- export declare function summarizeSuccessCriteria(task: KanbanTask): string | null;
65
- /**
66
- * Pure goal-metrics rollup string. Returns null when there are no metrics.
67
- * Format: "Metrics 2 met · 1 missed · 0 waived · 0 pending" (zero counts
68
- * are skipped to keep the line short).
69
- */
70
- export declare function summarizeGoalMetrics(task: KanbanTask): string | null;
71
- export {};
25
+ export declare function KanbanPanel({ projectRoot, sessionId, sessionContext, onClose, terminalWidth: widthOverride, initialBoardId, }: KanbanPanelProps): React.ReactElement;
26
+ export { computeBoardColumnLayout, nextManagedStage, stageForColumn, summarizeGoalMetrics, summarizeSuccessCriteria, } from './kanban-panel-presentation.js';
72
27
  //# sourceMappingURL=kanban-panel.d.ts.map
@@ -36,7 +36,8 @@ interface MailboxPanelProps {
36
36
  unreadCount: number;
37
37
  /** Whether the panel is visible. When false, returns null. */
38
38
  open: boolean;
39
+ maxRows?: number | undefined;
39
40
  }
40
- export declare function MailboxPanel({ messages, agents, unreadCount, open, }: MailboxPanelProps): React.ReactElement | null;
41
+ export declare function MailboxPanel({ messages, agents, unreadCount, open, maxRows, }: MailboxPanelProps): React.ReactElement | null;
41
42
  export {};
42
43
  //# sourceMappingURL=mailbox-panel.d.ts.map
@@ -9,11 +9,13 @@ export interface McpPickerItem {
9
9
  lazy?: boolean | undefined;
10
10
  }
11
11
  interface McpPickerProps {
12
+ maxRows?: number | undefined;
13
+ columns?: number | undefined;
12
14
  items: McpPickerItem[];
13
15
  selected: number;
14
16
  busy?: boolean | undefined;
15
17
  hint?: string | undefined;
16
18
  }
17
- export declare function McpPicker({ items, selected, busy, hint, }: McpPickerProps): React.ReactElement;
19
+ export declare function McpPicker({ items, selected, busy, hint, maxRows, columns, }: McpPickerProps): React.ReactElement;
18
20
  export {};
19
21
  //# sourceMappingURL=mcp-picker.d.ts.map
@@ -8,11 +8,13 @@ export interface ModeOption {
8
8
  isActive: boolean;
9
9
  }
10
10
  interface ModePickerProps {
11
+ maxRows?: number | undefined;
12
+ columns?: number | undefined;
11
13
  modes: ModeOption[];
12
14
  selected: number;
13
15
  hint?: string | undefined;
14
16
  }
15
17
  export declare function toModeOptions(modes: Mode[], activeId: string | null): ModeOption[];
16
- export declare function ModePicker({ modes, selected, hint }: ModePickerProps): React.ReactElement;
18
+ export declare function ModePicker({ modes, selected, hint, maxRows, columns, }: ModePickerProps): React.ReactElement;
17
19
  export {};
18
20
  //# sourceMappingURL=mode-picker.d.ts.map
@@ -65,6 +65,6 @@ interface ModelPickerProps {
65
65
  *
66
66
  * Driven entirely by props — App owns cursor state, key events, and search.
67
67
  */
68
- export declare function ModelPicker({ step, providerOptions, filteredOptions, selected, pickedProviderId, searchQuery, hint, titleLabel, columns, maxRows, effortOptions, effortChoice, }: ModelPickerProps): React.ReactElement;
68
+ export declare function ModelPicker({ step, providerOptions, filteredOptions, selected, pickedProviderId, searchQuery, hint, titleLabel, columns: columnsOverride, maxRows, effortOptions, effortChoice, }: ModelPickerProps): React.ReactElement;
69
69
  export {};
70
70
  //# sourceMappingURL=model-picker.d.ts.map
@@ -1,6 +1,14 @@
1
1
  import type { ReactNode } from 'react';
2
+ import { useInput } from '../ink.js';
3
+ export declare const PanelInputProvider: import("react").Provider<boolean>;
4
+ /** A foreground prompt temporarily owns all keyboard input over a monitor. */
5
+ export declare function usePanelInput(handler: Parameters<typeof useInput>[0]): void;
6
+ export declare const MonitorViewportProvider: import("react").Provider<{
7
+ columns: number;
8
+ rows: number;
9
+ } | null>;
2
10
  export declare const PanelShortcutsProvider: import("react").Provider<boolean>;
3
- /** True when panel letter shortcuts may fire (empty composer draft). */
11
+ /** True when this surface may handle panel letter shortcuts. */
4
12
  export declare function usePanelShortcutsEnabled(): boolean;
5
13
  interface MonitorSize {
6
14
  columns: number;
@@ -30,17 +38,20 @@ interface MonitorShellProps {
30
38
  grow?: boolean | undefined;
31
39
  /** Clamp the shell's total height (including borders) to prevent overflow. */
32
40
  maxHeight?: number | undefined;
41
+ /** Pickers already own wheel navigation; disable shell wheel scrolling there. */
42
+ wheelScroll?: boolean | undefined;
33
43
  }
34
44
  /** Shared chrome for F-key monitors: one visual hierarchy and one geometry contract. */
35
- export declare function MonitorShell({ accent, icon, title, kicker, right, footer, children, grow, maxHeight, }: MonitorShellProps): import("react").JSX.Element;
45
+ export declare function MonitorShell({ accent, icon, title, kicker, right, footer, children, grow, maxHeight, wheelScroll, }: MonitorShellProps): import("react").JSX.Element;
36
46
  export declare function SectionLabel({ children, color, }: {
37
47
  children: ReactNode;
38
48
  color?: string | undefined;
39
49
  }): import("react").JSX.Element;
40
- export declare function KeyCap({ keyName, label, color, }: {
50
+ export declare function KeyCap({ keyName, label, color, keepTogether, }: {
41
51
  keyName: string;
42
52
  label: string;
43
53
  color?: string | undefined;
54
+ keepTogether?: boolean | undefined;
44
55
  }): import("react").JSX.Element;
45
56
  export declare function EmptyPanelState({ icon, title, detail, accent, }: {
46
57
  icon: string;
@@ -13,11 +13,13 @@ export interface PluginPickerItem {
13
13
  lockable?: boolean | undefined;
14
14
  }
15
15
  interface PluginPickerProps {
16
+ maxRows?: number | undefined;
17
+ columns?: number | undefined;
16
18
  items: PluginPickerItem[];
17
19
  selected: number;
18
20
  busy?: boolean | undefined;
19
21
  hint?: string | undefined;
20
22
  }
21
- export declare function PluginPicker({ items, selected, busy, hint, }: PluginPickerProps): React.ReactElement;
23
+ export declare function PluginPicker({ items, selected, busy, hint, maxRows, columns, }: PluginPickerProps): React.ReactElement;
22
24
  export {};
23
25
  //# sourceMappingURL=plugin-picker.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type React from 'react';
2
+ import { type Theme } from '../theme.js';
2
3
  export declare function visibleNodeText(node: React.ReactNode): string;
3
4
  /**
4
5
  * Columns between adjacent chip payloads: one transition glyph plus one
@@ -72,14 +73,16 @@ interface PowerlineRailProps {
72
73
  rightAnchor?: React.ReactElement | null | undefined;
73
74
  /** Keep the segmented silhouette but emit no foreground/background colors. */
74
75
  monochrome?: boolean | undefined;
76
+ /** Explicit candidate palette for the theme picker; never changes the active theme. */
77
+ palette?: Theme | undefined;
75
78
  }
76
79
  /**
77
- * Theme-aware, Powerline-style status capsules. Chip payloads keep their
78
- * semantic foreground colors while low-contrast surface tones provide the
80
+ * Theme-aware, Powerline-style status capsules. Chip payloads share a readable
81
+ * foreground while five theme-derived surface tones provide the
79
82
  * connected silhouette. The renderer and layout fitter share the exact cap,
80
83
  * transition, padding and anchor costs, keeping overflow and pointer spans
81
84
  * aligned with the cells on screen.
82
85
  */
83
- export declare function PowerlineRail({ segments, budget, rightAnchor, monochrome, }: PowerlineRailProps): React.ReactElement;
86
+ export declare function PowerlineRail({ segments, budget, rightAnchor, monochrome, palette, }: PowerlineRailProps): React.ReactElement;
84
87
  export {};
85
88
  //# sourceMappingURL=powerline-rail.d.ts.map
@@ -17,18 +17,8 @@ export declare function badgeForKind(kind: 'oauth' | 'api_key' | 'session_token'
17
17
  } | undefined;
18
18
  /** Brand colors for known OAuth strategies; unknown plugin strategies use the fallback. */
19
19
  export declare const OAUTH_KIND_COLORS: Record<string, string>;
20
- /** Semantic UI colors used across auth / model panels. */
21
- export declare const UI_COLORS: {
22
- readonly focused: '#89b4fa';
23
- readonly active: '#a6e3a1';
24
- readonly inactive: '#585b70';
25
- readonly warning: '#f9e2af';
26
- readonly error: '#f38ba8';
27
- readonly hint: '#f9e2af';
28
- readonly border: '#89b4fa';
29
- readonly title: '#89b4fa';
30
- readonly selectedModel: '#89b4fa';
31
- readonly dimmed: string | undefined;
20
+ export declare const UI_COLORS: Record<"active" | "border" | "error" | "focused" | "hint" | "inactive" | "selectedModel" | "title" | "warning", string> & {
21
+ dimmed: string | undefined;
32
22
  };
33
23
  /**
34
24
  * Statusline item category colors — imported by status-bar.tsx and
@@ -16,9 +16,10 @@ interface RefineCountdownPanelProps {
16
16
  * Pre-refine grace countdown ("about to refine — last chance to bail").
17
17
  *
18
18
  * Shown for the window between submit and the refiner's first LLM call:
19
- * Enter starts refining immediately, any other key sends the message
20
- * unchanged (skip), Esc cancels back to the composer, and expiry
21
- * proceeds into the normal refine flow. Mirrors the
19
+ * Enter starts refining immediately, Backspace/Delete or Esc cancels back
20
+ * to the composer (the submitted text is restored as the draft), any other
21
+ * key sends the message unchanged (skip), and expiry proceeds into the
22
+ * normal refine flow. Mirrors the
22
23
  * WebUI/SimpleUI RefinePanel's 'countdown' face.
23
24
  */
24
25
  export declare function RefineCountdownPanel({ original, seconds, onDecision, providerId, model, }: RefineCountdownPanelProps): React.ReactElement;
@@ -7,6 +7,7 @@ export interface SettingsPickerRowData {
7
7
  detail?: string | undefined;
8
8
  }
9
9
  interface SettingsPickerRowListProps {
10
+ compactWidth?: number | undefined;
10
11
  rows: readonly SettingsPickerRowData[];
11
12
  field: number;
12
13
  fieldRowIndex: readonly number[];
@@ -20,6 +21,6 @@ interface SettingsPickerRowListProps {
20
21
  }
21
22
  export declare function deriveSettingsSectionFieldStarts(fieldRowIndex: readonly number[]): readonly number[];
22
23
  export declare function buildVisibleSectionHeaders(rows: readonly SettingsPickerRowData[], fieldRowIndex: readonly number[], windowStart: number, windowEnd: number): Set<number>;
23
- export declare function SettingsPickerRowList({ rows, field, fieldRowIndex, filterActive, rankedResults, highlightSegments, windowStart, windowEnd, filterWindowStart, filterWindowEnd, }: SettingsPickerRowListProps): React.ReactElement;
24
+ export declare function SettingsPickerRowList({ compactWidth, rows, field, fieldRowIndex, filterActive, rankedResults, highlightSegments, windowStart, windowEnd, filterWindowStart, filterWindowEnd, }: SettingsPickerRowListProps): React.ReactElement;
24
25
  export {};
25
26
  //# sourceMappingURL=settings-picker-row-list.d.ts.map
@@ -127,6 +127,8 @@ export interface SettingsPickerProps {
127
127
  * for multi-line input buffers instead of assuming a constant.
128
128
  */
129
129
  inputHeight?: number | undefined;
130
+ maxRows?: number | undefined;
131
+ columns?: number | undefined;
130
132
  hint?: string | undefined;
131
133
  /** @internal Test seam for asserting the production row/header layout contract. */
132
134
  onLayoutComputed?: ((layout: {
@@ -134,5 +136,5 @@ export interface SettingsPickerProps {
134
136
  fieldRowIndex: readonly number[];
135
137
  }) => void) | undefined;
136
138
  }
137
- 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, wrongProxyUrlEditing, wrongProxyUrlDraft, reasoningMode, reasoningEffort, reasoningEffortLevels, reasoningPreserve, cacheTtl, contextAutoCompact, contextStrategy, contextMode, maxConcurrent, logLevel, auditLevel, debugStream, statuslineMode, configScope, profileConfigPath, animationStyle, breakerEnabled, breakerAutoKillResetMs, showModelReasoning, toolResultViewMode, showAgentSwarmPanel, showSidebar, showSageMemoryInject, sageMemoryInjectThreshold, nextStepsTool, readSymbols, panelPositions, wrongProxyEnabled, wrongProxyUrl, inputHeight, hint, onLayoutComputed, }: SettingsPickerProps): React.ReactElement;
139
+ 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, wrongProxyUrlEditing, wrongProxyUrlDraft, reasoningMode, reasoningEffort, reasoningEffortLevels, reasoningPreserve, cacheTtl, contextAutoCompact, contextStrategy, contextMode, maxConcurrent, logLevel, auditLevel, debugStream, statuslineMode, configScope, profileConfigPath, animationStyle, breakerEnabled, breakerAutoKillResetMs, showModelReasoning, toolResultViewMode, showAgentSwarmPanel, showSidebar, showSageMemoryInject, sageMemoryInjectThreshold, nextStepsTool, readSymbols, panelPositions, wrongProxyEnabled, wrongProxyUrl, inputHeight, maxRows, columns, hint, onLayoutComputed, }: SettingsPickerProps): React.ReactElement;
138
140
  //# sourceMappingURL=settings-picker.d.ts.map
@@ -6,9 +6,10 @@ export interface ShadowState {
6
6
  intervalMs: number;
7
7
  }
8
8
  interface ShadowPanelProps {
9
+ maxRows?: number | undefined;
9
10
  shadow: ShadowState;
10
11
  hint?: string | undefined;
11
12
  }
12
- export declare function ShadowPanel({ shadow, hint }: ShadowPanelProps): React.ReactElement;
13
+ export declare function ShadowPanel({ shadow, hint, maxRows }: ShadowPanelProps): React.ReactElement;
13
14
  export {};
14
15
  //# sourceMappingURL=shadow-panel.d.ts.map
@@ -80,52 +80,6 @@ interface SidebarContentProps {
80
80
  */
81
81
  effectiveSidebarRoutes?: ReadonlySet<PanelId> | undefined;
82
82
  }
83
- /**
84
- * Normalized "is this session row the current session?" predicate used by
85
- * both the `SidebarContent` SESSIONS card (live + resume rows) and the
86
- * `SessionsPanelSidebar` (sidebar twin). The runtime `currentSessionId`
87
- * is the authoritative source — when defined, the row whose id matches
88
- * is the current row. When undefined (e.g. before the host registers a
89
- * session), the per-row `isCurrent` flag is the fallback (carried over
90
- * from the resume-picker domain for the case where the picker marks
91
- * the current session as non-resumable but the host hasn't published
92
- * the runtime id yet). A row without an id can never be the current
93
- * row, regardless of what its fallback flag says. The two SESSIONS
94
- * rows used to disagree on which key to read (live used strict id
95
- * compare, resume used `rs.isCurrent` first); this helper is the
96
- * single source of truth.
97
- */
98
- export declare function isCurrentSession(rowId: string | undefined, currentSessionId: string | undefined, fallbackIsCurrent?: boolean | undefined): boolean;
99
- /**
100
- * (Replaced by `SidebarSectionHeader` in `./sidebar-panel-frame.tsx`.)
101
- * Kept here as a doc-comment so anyone hunting for "the sidebar's section
102
- * header" lands on the right file. The local `SectionHeader` symbol was
103
- * promoted to the shared `sidebar-panel-frame.tsx` so routed panels and
104
- * persistent content cards use the same capsuled-pill component.
105
- */
106
- /**
107
- * The `Card` component now lives in `./sidebar-card.tsx` as the shared
108
- * raised-surface iskelet used by both the persistent cards (this file) and
109
- * the routed F-key panel twins (`sidebar-panel-frame.tsx` +
110
- * `sidebar-panels-{workspace,task}.tsx`). Imported at the top of this file
111
- * for the `MODEL CORE`, `PROMPT CACHE`, `SYSTEM`, `AGENT SWARM`, `MISSIONS`,
112
- * and `SESSIONS` cards — the migration keeps the persistent
113
- * call sites identical because the shared component preserves the same
114
- * `innerWidth` / `marginBottom` / `accent` / `children` contract.
115
- */
116
- interface ContextSegment {
117
- label: string;
118
- shortLabel: string;
119
- tokens: number;
120
- color: string;
121
- glyph: string;
122
- }
123
- export declare function contextSpectrum(breakdown: ContextBreakdown | undefined, contextWindow: {
124
- used: number;
125
- max: number;
126
- } | undefined, width: number): Array<ContextSegment & {
127
- cells: number;
128
- }>;
129
83
  export declare function SidebarContent({ contextWindow, contextBreakdown, cacheStats, entries, fleetCounts, provider, model, themeName, width, scrollOffset, focused, todos, showSwarmSection, liveSessions, resumeSessions, currentSessionId, processMemory, cpuPercent, cpuHistory, rssHistory, heapHistory, totalMem, effectiveSidebarRoutes, }: SidebarContentProps): React.ReactElement;
130
- export {};
84
+ export { contextSpectrum, isCurrentSession } from './sidebar-presentation.js';
131
85
  //# sourceMappingURL=sidebar-content.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { ConnectionHealthStatus } from '../connections-health.js';
2
+ import type { SidebarConnection } from '../hooks/use-sidebar-panel-data.js';
3
+ export declare function ipcStatusColor(status: ConnectionHealthStatus | undefined): string;
4
+ /** Stable service order, icon-only, using the same health readings as Connections. */
5
+ export declare function SidebarIpcIcons({ connections, width, }: {
6
+ connections: readonly SidebarConnection[];
7
+ width: number;
8
+ }): React.ReactElement;
9
+ //# sourceMappingURL=sidebar-ipc-icons.d.ts.map
@@ -0,0 +1,98 @@
1
+ import type { TodoItem } from '@wrongstack/core/agent';
2
+ import type { ContextBreakdown } from '@wrongstack/core/utils';
3
+ import type React from 'react';
4
+ import type { ResumeSessionEntry } from '../app-state.js';
5
+ import type { FleetEntry } from '../app-state-fleet.js';
6
+ /** Truncate a string to fit within `max` display columns, adding an ellipsis. */
7
+ export declare function trunc(s: string, max: number): string;
8
+ /**
9
+ * Normalized "is this session row the current session?" predicate used by
10
+ * both the `SidebarContent` SESSIONS card (live + resume rows) and the
11
+ * `SessionsPanelSidebar` (sidebar twin). The runtime `currentSessionId`
12
+ * is the authoritative source — when defined, the row whose id matches
13
+ * is the current row. When undefined (e.g. before the host registers a
14
+ * session), the per-row `isCurrent` flag is the fallback (carried over
15
+ * from the resume-picker domain for the case where the picker marks
16
+ * the current session as non-resumable but the host hasn't published
17
+ * the runtime id yet). A row without an id can never be the current
18
+ * row, regardless of what its fallback flag says. The two SESSIONS
19
+ * rows used to disagree on which key to read (live used strict id
20
+ * compare, resume used `rs.isCurrent` first); this helper is the
21
+ * single source of truth.
22
+ */
23
+ export declare function isCurrentSession(rowId: string | undefined, currentSessionId: string | undefined, fallbackIsCurrent?: boolean | undefined): boolean;
24
+ /** Format a fleet entry's status as a compact colored glyph. */
25
+ export declare function statusGlyph(entry: FleetEntry): {
26
+ icon: string;
27
+ color: string;
28
+ };
29
+ /** Compact icon for a live session status. */
30
+ export declare function liveSessionIcon(status: string): string;
31
+ /** Compact color for a live session status. */
32
+ export declare function liveSessionColor(status: string): string;
33
+ /** Outcome badge for a resume session entry. */
34
+ export declare function outcomeBadge(outcome: ResumeSessionEntry['outcome']): {
35
+ label: string;
36
+ color: string;
37
+ } | null;
38
+ /** Short relative time like "3m", "2h", "1d". */
39
+ export declare function fmtRelative(iso: string | undefined): string;
40
+ /**
41
+ * (Replaced by `SidebarSectionHeader` in `./sidebar-panel-frame.tsx`.)
42
+ * Kept here as a doc-comment so anyone hunting for "the sidebar's section
43
+ * header" lands on the right file. The local `SectionHeader` symbol was
44
+ * promoted to the shared `sidebar-panel-frame.tsx` so routed panels and
45
+ * persistent content cards use the same capsuled-pill component.
46
+ */
47
+ /**
48
+ * The `Card` component now lives in `./sidebar-card.tsx` as the shared
49
+ * raised-surface iskelet used by both the persistent cards (this file) and
50
+ * the routed F-key panel twins (`sidebar-panel-frame.tsx` +
51
+ * `sidebar-panels-{workspace,task}.tsx`). Imported at the top of this file
52
+ * for the `MODEL CORE`, `PROMPT CACHE`, `SYSTEM`, `AGENT SWARM`, `MISSIONS`,
53
+ * and `SESSIONS` cards — the migration keeps the persistent
54
+ * call sites identical because the shared component preserves the same
55
+ * `innerWidth` / `marginBottom` / `accent` / `children` contract.
56
+ */
57
+ interface ContextSegment {
58
+ label: string;
59
+ shortLabel: string;
60
+ tokens: number;
61
+ color: string;
62
+ glyph: string;
63
+ }
64
+ export declare function contextSpectrum(breakdown: ContextBreakdown | undefined, contextWindow: {
65
+ used: number;
66
+ max: number;
67
+ } | undefined, width: number): Array<ContextSegment & {
68
+ cells: number;
69
+ }>;
70
+ export interface MissionRow {
71
+ id: string;
72
+ status: TodoItem['status'];
73
+ label: string;
74
+ }
75
+ /** Sort + cap the todo board for the mission queue, plus done/total stats. */
76
+ export declare function buildMissionRows(todos: readonly TodoItem[] | undefined, maxRows: number): {
77
+ rows: MissionRow[];
78
+ overflow: number;
79
+ done: number;
80
+ total: number;
81
+ };
82
+ /**
83
+ * A labeled system-vitals row: morphing dial glyph + right-aligned trend
84
+ * sparkline. Replaces the old block meter — still exactly one row per
85
+ * metric, so the SYSTEM card keeps its 5-row budget in
86
+ * computeMaxSidebarScroll(). The dial and value are colored by the *current*
87
+ * load via contextBarColor; the sparkline traces the recent history in the
88
+ * same heat color (latest sample at the right edge).
89
+ */
90
+ export declare function DialRow({ label, value, ratio, history, innerWidth, }: {
91
+ label: string;
92
+ value: string;
93
+ ratio: number;
94
+ history?: readonly number[] | undefined;
95
+ innerWidth: number;
96
+ }): React.ReactElement;
97
+ export {};
98
+ //# sourceMappingURL=sidebar-presentation.d.ts.map
@@ -56,7 +56,9 @@ interface RightSidebarProps {
56
56
  * label is shown so the reserved region is visually self-documenting.
57
57
  */
58
58
  children?: React.ReactNode | undefined;
59
+ /** Icon-only live connection strip, sharing the existing one-row footer. */
60
+ statusIcons?: React.ReactNode | undefined;
59
61
  }
60
- export declare function RightSidebar({ width, maxHeight, focused, scrollOffset, maxScroll, children, }: RightSidebarProps): React.ReactElement | null;
62
+ export declare function RightSidebar({ width, maxHeight, focused, scrollOffset, maxScroll, children, statusIcons, }: RightSidebarProps): React.ReactElement | null;
61
63
  export {};
62
64
  //# sourceMappingURL=sidebar.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import type { SkillEntry } from '@wrongstack/core/types';
2
2
  import type React from 'react';
3
3
  interface SkillPickerProps {
4
+ mention?: boolean | undefined;
4
5
  entries: readonly SkillEntry[];
5
6
  selected: number;
6
7
  hint?: string | undefined;
@@ -8,6 +9,6 @@ interface SkillPickerProps {
8
9
  maxRows?: number | undefined;
9
10
  }
10
11
  /** Interactive two-pane skill browser, matching the `/theme` picker layout. */
11
- export declare function SkillPicker({ entries, selected, hint, columns, maxRows, }: SkillPickerProps): React.ReactElement;
12
+ export declare function SkillPicker({ mention, entries, selected, hint, columns, maxRows, }: SkillPickerProps): React.ReactElement;
12
13
  export {};
13
14
  //# sourceMappingURL=skill-picker.d.ts.map
@@ -4,6 +4,8 @@ interface SlashConfirmPanelProps {
4
4
  defaultYes: boolean;
5
5
  }
6
6
  interface SlashConfirmationKey {
7
+ ctrl?: boolean | undefined;
8
+ meta?: boolean | undefined;
7
9
  escape?: boolean | undefined;
8
10
  return?: boolean | undefined;
9
11
  }
@@ -4,7 +4,8 @@ interface SlashMenuProps {
4
4
  query: string;
5
5
  matches: SlashCommandMatch[];
6
6
  selected: number;
7
+ maxRows?: number | undefined;
7
8
  }
8
- export declare function SlashMenu({ query, matches, selected }: SlashMenuProps): React.ReactElement;
9
+ export declare function SlashMenu({ query, matches, selected, maxRows, }: SlashMenuProps): React.ReactElement;
9
10
  export {};
10
11
  //# sourceMappingURL=slash-menu.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from 'react';
2
+ /** Pin a slash command's decision controls while its explanation scrolls. */
3
+ export declare function SlashModalFrame({ title, accent, children, footer, }: {
4
+ title: string;
5
+ accent: string;
6
+ children: ReactNode;
7
+ footer: ReactNode;
8
+ }): import("react").JSX.Element;
9
+ //# sourceMappingURL=slash-modal-frame.d.ts.map
@@ -40,8 +40,8 @@ export declare function nextDensity(current: StatuslineDensity, delta?: number):
40
40
  * either its name or its blurb.
41
41
  */
42
42
  export declare function matchesFilter(item: StatuslineItem, filter: string): boolean;
43
- /** Field indices the arrow keys may land on under the current filter. */
44
- export declare function navigableFields(filter: string, order?: StatuslineOrder): number[];
43
+ /** Shared visual/keyboard order: effective line groups, then saved order within each line. */
44
+ export declare function navigableFields(filter: string, order?: StatuslineOrder, lines?: StatuslineLines): number[];
45
45
  interface StatuslinePickerProps {
46
46
  /** Focused field index into STATUSLINE_ITEMS. */
47
47
  field: number;
@@ -11,12 +11,14 @@ export interface ToolPickerItem {
11
11
  description: string;
12
12
  }
13
13
  interface ToolsPickerProps {
14
+ maxRows?: number | undefined;
15
+ columns?: number | undefined;
14
16
  items: ToolPickerItem[];
15
17
  selected: number;
16
18
  busy?: boolean | undefined;
17
19
  hint?: string | undefined;
18
20
  filter?: string | undefined;
19
21
  }
20
- export declare function ToolsPicker({ items, selected, busy, hint, filter, }: ToolsPickerProps): React.ReactElement;
22
+ export declare function ToolsPicker({ items, selected, busy, hint, filter, maxRows, columns, }: ToolsPickerProps): React.ReactElement;
21
23
  export {};
22
24
  //# sourceMappingURL=tools-picker.d.ts.map
@@ -14,9 +14,11 @@ type AnswerDraft = {
14
14
  };
15
15
  type Draft = Record<string, AnswerDraft>;
16
16
  export declare function usePendingUserInput(events: EventBus): PendingUserInput | null;
17
- export declare function UserInputPrompt({ pending }: {
17
+ interface UserInputPromptProps {
18
18
  pending: PendingUserInput;
19
- }): React.ReactElement;
19
+ onInterrupt?: (() => void) | undefined;
20
+ }
21
+ export declare function UserInputPrompt(props: UserInputPromptProps): React.ReactElement;
20
22
  export declare function initialDraft(request: UserInputRequest): Draft;
21
23
  export declare function validateDraft(questions: UserInputQuestion[], draft: Draft): {
22
24
  valid: boolean;
@@ -0,0 +1,20 @@
1
+ import type { ConnectionHealthServiceId } from './connections-health.js';
2
+ export interface ConnectionActionResult {
3
+ serviceId: ConnectionHealthServiceId;
4
+ action: 'shutdown' | 'restart';
5
+ success: boolean;
6
+ message: string;
7
+ }
8
+ export declare const RESTARTABLE_SERVICES: readonly ConnectionHealthServiceId[];
9
+ export declare function isRestartableService(serviceId: ConnectionHealthServiceId): boolean;
10
+ export declare function isEndpointAlive(endpoint: string): Promise<boolean>;
11
+ export declare function waitForShutdown(probe?: () => Promise<boolean> | boolean): Promise<void>;
12
+ export declare function executeConnectionAction(serviceId: ConnectionHealthServiceId, action: 'shutdown' | 'restart', projectRoot: string, indexDir?: string | undefined): Promise<ConnectionActionResult>;
13
+ export declare function restartAllConnectionServices(projectRoot: string, indexDir?: string | undefined): Promise<ConnectionActionResult[]>;
14
+ export declare function killSessionCatalogServer(projectRoot: string, action: 'shutdown' | 'restart'): Promise<ConnectionActionResult>;
15
+ export declare function killKanbanServer(projectRoot: string, action: 'shutdown' | 'restart'): Promise<ConnectionActionResult>;
16
+ export declare function killSageServer(projectRoot: string, action: 'shutdown' | 'restart'): Promise<ConnectionActionResult>;
17
+ export declare function killChronicleServer(projectRoot: string, action: 'shutdown' | 'restart'): Promise<ConnectionActionResult>;
18
+ export declare function killCodebaseIndexServer(projectRoot: string, indexDir: string | undefined, action: 'shutdown' | 'restart'): Promise<ConnectionActionResult>;
19
+ export declare function killMailboxServer(projectRoot: string, action: 'shutdown' | 'restart'): Promise<ConnectionActionResult>;
20
+ //# sourceMappingURL=connection-actions.d.ts.map
@@ -9,8 +9,9 @@
9
9
  * `@wrongstack/tools`).
10
10
  */
11
11
  export type ConnectionHealthStatus = 'healthy' | 'degraded' | 'offline' | 'unavailable' | 'error';
12
+ export type ConnectionHealthServiceId = 'session-catalog' | 'chronicle' | 'codebase-index' | 'sage' | 'kanban' | 'mailbox' | 'governance';
12
13
  export interface ConnectionHealthService {
13
- id: 'chronicle' | 'codebase-index' | 'sage' | 'kanban' | 'mailbox';
14
+ id: ConnectionHealthServiceId;
14
15
  label: string;
15
16
  status: ConnectionHealthStatus;
16
17
  required: boolean;
@@ -29,6 +30,12 @@ export interface ConnectionHealthService {
29
30
  watchedFiles?: number | undefined;
30
31
  } | undefined;
31
32
  lastError?: string | undefined;
33
+ control?: 'restart' | 'none' | undefined;
34
+ advisory?: {
35
+ code: string;
36
+ operatorAction: string;
37
+ executionDisposition: string;
38
+ } | undefined;
32
39
  }
33
40
  export interface ConnectionsHealthReport {
34
41
  checkedAt: number;
@@ -14,7 +14,6 @@
14
14
  *
15
15
  * Excluded panels (own their own Esc):
16
16
  * - worktreeMonitor — `isWorktreeMonitorCloseKey` in WorktreeMonitor.tsx
17
- * - goalRun monitor — PhaseMonitor owns Esc via its own useInput
18
17
  * - kanbanPanel — `key.escape || 'q' → onClose` in KanbanPanel.tsx
19
18
  * - goalKanbanPanel — `key.escape || 'q' → onClose` in GoalKanbanPanel.tsx
20
19
  *
@@ -1,5 +1,9 @@
1
1
  import type { Action } from './app-action-type.js';
2
+ import type { State } from './app-state.js';
2
3
  import type { StatuslineItem } from './components/statusline-picker.js';
4
+ import type { PanelPositionMap } from './ui-contracts.js';
5
+ /** The bottom panel owns input; sidebar twins leave the composer available. */
6
+ export declare function activeBottomFKeyPanel(state: State, positions: PanelPositionMap): number | null;
3
7
  export type FKeyPanelAction = 'projectPickerOpen' | 'toggleMonitor' | 'toggleAgentsMonitor' | 'toggleWorktreeMonitor' | 'togglePlanPanel' | 'toggleTodosMonitor' | 'toggleQueuePanel' | 'toggleProcessList' | 'toggleKanbanPanel' | 'toggleGoalPanel' | 'toggleSessionsPanel' | 'toggleCoordinatorMonitor' | 'toggleCronMonitor' | 'toggleConnectionsPanel' | 'statuslineOpen';
4
8
  /** Host-side action keys that require work beyond a reducer dispatch. */
5
9
  type FKeyHostAction = 'openProjectPicker' | 'loadLiveSessions' | 'openStatuslinePicker';
@@ -4,7 +4,8 @@ import { type Theme } from '../theme.js';
4
4
  * current `theme` snapshot. Used by the App shell to force a re-render
5
5
  * when `setActiveTheme()` mutates the global theme — child components
6
6
  * read `theme` directly via destructuring, so the parent re-render
7
- * propagates the new palette into the whole tree.
7
+ * propagates the new palette into ordinary children. Memoized boundaries
8
+ * subscribe separately: unchanged props must not keep an old palette alive.
8
9
  *
9
10
  * The hook itself returns the live `theme` reference; callers don't
10
11
  * typically need to use it (they can keep reading `theme` directly),