@wrongstack/tui 1.0.17 → 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 (94) 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/inspect-overlay.d.ts +1 -1
  30. package/dist/components/kanban-panel-presentation.d.ts +114 -0
  31. package/dist/components/kanban-panel.d.ts +2 -47
  32. package/dist/components/mailbox-panel.d.ts +2 -1
  33. package/dist/components/mcp-picker.d.ts +3 -1
  34. package/dist/components/mode-picker.d.ts +3 -1
  35. package/dist/components/model-picker.d.ts +1 -1
  36. package/dist/components/monitor-shell.d.ts +14 -3
  37. package/dist/components/plugin-picker.d.ts +3 -1
  38. package/dist/components/powerline-rail.d.ts +6 -3
  39. package/dist/components/provider-colors.d.ts +2 -12
  40. package/dist/components/refine-countdown-panel.d.ts +4 -3
  41. package/dist/components/settings-picker-row-list.d.ts +2 -1
  42. package/dist/components/settings-picker.d.ts +3 -1
  43. package/dist/components/shadow-panel.d.ts +2 -1
  44. package/dist/components/sidebar-content.d.ts +1 -47
  45. package/dist/components/sidebar-ipc-icons.d.ts +9 -0
  46. package/dist/components/sidebar-presentation.d.ts +98 -0
  47. package/dist/components/sidebar.d.ts +3 -1
  48. package/dist/components/skill-picker.d.ts +2 -1
  49. package/dist/components/slash-confirm-panel.d.ts +2 -0
  50. package/dist/components/slash-menu.d.ts +2 -1
  51. package/dist/components/slash-modal-frame.d.ts +9 -0
  52. package/dist/components/status-bar.d.ts +1 -1
  53. package/dist/components/statusline-picker.d.ts +2 -2
  54. package/dist/components/tools-picker.d.ts +3 -1
  55. package/dist/components/user-input-prompt.d.ts +4 -2
  56. package/dist/connection-actions.d.ts +20 -0
  57. package/dist/connections-health.d.ts +8 -1
  58. package/dist/esc-close-panels.d.ts +0 -1
  59. package/dist/f-key-panels.d.ts +4 -0
  60. package/dist/hooks/use-active-theme.d.ts +2 -1
  61. package/dist/hooks/use-app-panels-state.d.ts +1 -1
  62. package/dist/hooks/use-app-picker-keys.d.ts +2 -1
  63. package/dist/hooks/use-fleet-generation-gate.d.ts +4 -3
  64. package/dist/hooks/use-panel-controllers.d.ts +1 -1
  65. package/dist/hooks/use-picker-keys-types.d.ts +1 -0
  66. package/dist/hooks/use-shadow-panel.d.ts +1 -1
  67. package/dist/hooks/use-sidebar-panel-data.d.ts +7 -5
  68. package/dist/hooks/use-skill-mention-picker.d.ts +6 -0
  69. package/dist/hooks/use-statusbar-view-model.d.ts +2 -2
  70. package/dist/hooks/use-windowed-picker.d.ts +3 -4
  71. package/dist/index.js +9799 -7534
  72. package/dist/ink.d.ts +4 -4
  73. package/dist/input-graphemes.d.ts +4 -0
  74. package/dist/input-key-router.d.ts +2 -0
  75. package/dist/input-tokens.d.ts +10 -0
  76. package/dist/input-validation/action-types.d.ts +1 -1
  77. package/dist/input-validation-coordination.d.ts +9 -0
  78. package/dist/kanban-arguments.d.ts +48 -0
  79. package/dist/kanban-audit.d.ts +1 -1
  80. package/dist/kanban-command-types.d.ts +53 -0
  81. package/dist/kanban-reports.d.ts +42 -0
  82. package/dist/kanban-slash.d.ts +4 -125
  83. package/dist/key-routes/key-route-overlay.d.ts +2 -2
  84. package/dist/on-panel-open.d.ts +1 -1
  85. package/dist/picker-text-input.d.ts +4 -0
  86. package/dist/reducers/composer.d.ts +1 -1
  87. package/dist/reducers/panel-pickers.d.ts +1 -1
  88. package/dist/reducers/workspace-panels.d.ts +1 -1
  89. package/dist/run-tui-options.d.ts +1 -1
  90. package/dist/statusline-palette.d.ts +4 -0
  91. package/dist/theme-utils.d.ts +1 -1
  92. package/dist/ui-contracts.d.ts +1 -0
  93. package/dist/use-app-controller.d.ts +157 -0
  94. package/package.json +7 -7
@@ -42,6 +42,8 @@ export type Action = {
42
42
  type: 'clearHistory';
43
43
  model?: string | undefined;
44
44
  provider?: string | undefined;
45
+ cwd?: string | undefined;
46
+ sessionId?: string | undefined;
45
47
  } | {
46
48
  type: 'streamDelta';
47
49
  delta: string;
@@ -229,6 +231,12 @@ export type Action = {
229
231
  } | {
230
232
  type: 'skillPickerOpen';
231
233
  entries: SkillEntry[];
234
+ mention?: import('@wrongstack/core/skill-mentions').SkillMention | undefined;
235
+ } | {
236
+ type: 'skillMentionResults';
237
+ entries: SkillEntry[];
238
+ hint?: string | undefined;
239
+ mention: import('@wrongstack/core/skill-mentions').SkillMention;
232
240
  } | {
233
241
  type: 'skillPickerClose';
234
242
  } | {
@@ -369,6 +377,15 @@ export type Action = {
369
377
  /** Total entries in the replay, for the batch counter. */
370
378
  total: number;
371
379
  done?: boolean | undefined;
380
+ /** Keep input gated until replay effects and suggestion restoration settle. */
381
+ holdUntilSettled?: boolean | undefined;
382
+ /** Actual attached session metadata; absent for read-only replay. */
383
+ banner?: {
384
+ sessionId: string;
385
+ cwd?: string | undefined;
386
+ model?: string | undefined;
387
+ provider?: string | undefined;
388
+ } | undefined;
372
389
  contextSnapshot?: ContextSnapshot | undefined;
373
390
  }
374
391
  /**
@@ -725,6 +742,9 @@ export type Action = {
725
742
  } | {
726
743
  type: 'helpHint';
727
744
  text?: string | undefined;
745
+ } | {
746
+ type: 'helpScrollDetail';
747
+ delta: number;
728
748
  } | {
729
749
  type: 'shadowOpen';
730
750
  shadow: ShadowState;
@@ -1122,6 +1142,17 @@ export type Action = {
1122
1142
  agent?: string | undefined;
1123
1143
  /** True when the task starts, false when it completes/fails. */
1124
1144
  active: boolean;
1145
+ } | {
1146
+ /** A task finished successfully; the reducer owns the count arithmetic. */
1147
+ type: 'goalRunTaskCompleted';
1148
+ phaseId: string;
1149
+ taskId: string;
1150
+ } | {
1151
+ /** Attach the assigned agent to an already-active task (reducer-owned). */
1152
+ type: 'goalRunTaskAgent';
1153
+ phaseId: string;
1154
+ taskId: string;
1155
+ agent?: string | undefined;
1125
1156
  } | {
1126
1157
  type: 'goalRunMonitorToggle';
1127
1158
  } | {
@@ -1,4 +1,4 @@
1
- import type { KeyEvent } from './components/input.js';
1
+ import { type KeyEvent } from './components/input.js';
2
2
  import type { AppKeyHandlerOptions } from './key-handler-context.js';
3
3
  export type { AppKeyHandlerOptions } from './key-handler-context.js';
4
4
  /** Keyboard activity means the user has taken control of an armed automatic turn. */
@@ -0,0 +1,536 @@
1
+ import type { StatuslineDensities, StatuslineLines, StatuslineOrder } from '@wrongstack/core/statusline';
2
+ import type { ContentBlock, DesignKitEntry, FleetChatVerbosity, SkillEntry, TokenSavingTier } from '@wrongstack/core/types';
3
+ import type { ResumeSessionEntry, SlashCommandMatch } from './app-state-core-types.js';
4
+ import type { AuthPanelState } from './auth-panel-model.js';
5
+ import type { BrainLogEntry, BrainRiskLevel } from './brain-contracts.js';
6
+ import type { BrainPanelSettings } from './brain-panel-model.js';
7
+ import type { AuditLevel, CacheTtl, CompactorStrategy, ContextMode, LogLevel, ReasoningEffort, SettingsMode, StatuslineMode, ToolResultViewMode } from './settings-contracts.js';
8
+ import type { AutonomyOption, ChipMeta, HelpEntry, LiveSessionEntry, McpPickerItem, ModeOption, PanelPositionMap, PluginPickerItem, ProjectPickerItem, PromptPickEntry, ProviderOption, SendMode, ShadowState, StatuslineItem, ToolPickerItem } from './ui-contracts.js';
9
+ export type PanelState = {
10
+ /**
11
+ * Context snapshot captured at Esc time, replayed into the STEERING
12
+ * preamble so the model sees exactly what it was mid-doing when the
13
+ * user pulled the cord. Cleared together with `steeringPending`.
14
+ * Without this the model has to guess from chat scrollback which
15
+ * tools were live — and it can't see subagent state at all.
16
+ */
17
+ steerSnapshot: {
18
+ runningTools: string[];
19
+ subagents: Array<{
20
+ label: string;
21
+ status: string;
22
+ tool?: string | undefined;
23
+ }>;
24
+ subagentsTerminated: number;
25
+ partialAssistantText: string;
26
+ } | null;
27
+ /**
28
+ * Tool-result inspect overlay. Holds the clicked card's ids; the view
29
+ * resolves the full (untruncated) payload from live history / stream.
30
+ * Null when closed.
31
+ */
32
+ inspectOverlay: {
33
+ entryId: number;
34
+ entryIds?: readonly number[] | undefined;
35
+ scroll: number;
36
+ } | null;
37
+ picker: {
38
+ open: boolean;
39
+ query: string;
40
+ matches: string[];
41
+ selected: number;
42
+ };
43
+ /** Slash command picker — open while typing a / command. */
44
+ slashPicker: {
45
+ open: boolean;
46
+ query: string;
47
+ matches: SlashCommandMatch[];
48
+ selected: number;
49
+ };
50
+ /** Two-step model picker (provider → model) — opened by `/model`. */
51
+ modelPicker: {
52
+ open: boolean;
53
+ step: 'provider' | 'model';
54
+ providerOptions: ProviderOption[];
55
+ modelOptions: string[];
56
+ /** Filtered list shown in step 2 (same as modelOptions when searchQuery is empty). */
57
+ filteredOptions: string[];
58
+ selected: number;
59
+ pickedProviderId?: string | undefined;
60
+ hint?: string | undefined;
61
+ /** Live search filter in step 2. */
62
+ searchQuery: string;
63
+ /**
64
+ * Reasoning effort chosen for the FOCUSED model with ←/→. `'default'`
65
+ * (the sentinel every navigation resets to) means "leave the persisted
66
+ * effort alone", which is what Enter did before the strip existed.
67
+ */
68
+ effort: string;
69
+ /**
70
+ * 'switch' — Enter switches the SESSION model (the /model command).
71
+ * 'pick' — generic reusable selection: Enter just RETURNS the choice
72
+ * to whoever called requestModelPick (Brain pool/voters/judge,
73
+ * future callers); other panels stay open underneath.
74
+ */
75
+ purpose: 'switch' | 'pick';
76
+ /** Overlay title override for 'pick' invocations. */
77
+ title?: string | undefined;
78
+ };
79
+ /** Single-step autonomy mode picker — opened by `/autonomy`. */
80
+ autonomyPicker: {
81
+ open: boolean;
82
+ options: AutonomyOption[];
83
+ selected: number;
84
+ hint?: string | undefined;
85
+ };
86
+ /** Single-step theme picker — opened by `/theme`. Lists every preset and
87
+ * applies the chosen one instantly (in-place palette mutation + persist). */
88
+ themePicker: {
89
+ open: boolean;
90
+ selected: number;
91
+ hint?: string | undefined;
92
+ };
93
+ /** Agent mode picker — opened by `/mode`. Selects teach/brief/code-reviewer/etc. */
94
+ modePicker: {
95
+ open: boolean;
96
+ modes: ModeOption[];
97
+ selected: number;
98
+ hint?: string | undefined;
99
+ };
100
+ /** Skill picker — lists discoverable skills and details the focused row. */
101
+ skillPicker: {
102
+ mention?: import('@wrongstack/core/skill-mentions').SkillMention | undefined;
103
+ open: boolean;
104
+ entries: SkillEntry[];
105
+ selected: number;
106
+ hint?: string | undefined;
107
+ };
108
+ /** Design Studio kit picker — opened by `/design`. */
109
+ designPicker: {
110
+ open: boolean;
111
+ kits: DesignKitEntry[];
112
+ selected: number;
113
+ /** Target stack applied on selection. */
114
+ stack: string;
115
+ };
116
+ /** Prompt library picker — opened by a bare `/prompt`. Browse + category filter + insert. */
117
+ promptPicker: {
118
+ open: boolean;
119
+ all: PromptPickEntry[];
120
+ /** ['all', '🕘 recent'?, '★ favorites'?, ...distinct categories]. */
121
+ categories: string[];
122
+ /** Recently-used slugs (most-recent first) backing the "🕘 recent" view. */
123
+ recentSlugs: string[];
124
+ catIndex: number;
125
+ selected: number;
126
+ };
127
+ /** Session resume picker — opened by `/resume`. Lists recent sessions with metadata. */
128
+ resumePicker: {
129
+ open: boolean;
130
+ sessions: ResumeSessionEntry[];
131
+ selected: number;
132
+ /** True while the resume operation is in flight (fetching + replaying). */
133
+ busy: boolean;
134
+ hint?: string | undefined;
135
+ /** Error message if the resume operation failed. */
136
+ error?: string | undefined;
137
+ };
138
+ /** Settings editor — opened by `/settings` or Ctrl+S. */
139
+ settingsPicker: {
140
+ open: boolean;
141
+ /** Focused row index. */
142
+ field: number;
143
+ /**
144
+ * Mirror of the persisted `Settings.lastSettingsField` — kept in the
145
+ * runtime slice so the reducer can read it during `settingsOpen`
146
+ * without re-loading the full Settings shape, and so the auto-save
147
+ * effect (see app.tsx) can write it back when the user navigates.
148
+ */
149
+ lastSettingsField: number;
150
+ mode: SettingsMode;
151
+ delayMs: number;
152
+ titleAnimation: boolean;
153
+ yolo: boolean;
154
+ fleetChat: FleetChatVerbosity;
155
+ chime: boolean;
156
+ confirmExit: boolean;
157
+ nextPrediction: boolean;
158
+ featureMcp: boolean;
159
+ featurePlugins: boolean;
160
+ featureMemory: boolean;
161
+ featureSkills: boolean;
162
+ featureModelsRegistry: boolean;
163
+ tokenSavingTier: TokenSavingTier;
164
+ allowOutsideProjectRoot: boolean;
165
+ contextAutoCompact: boolean;
166
+ contextStrategy: CompactorStrategy;
167
+ contextMode: ContextMode;
168
+ maxConcurrent: number;
169
+ logLevel: LogLevel;
170
+ auditLevel: AuditLevel;
171
+ indexOnStart: boolean;
172
+ /** Multi-file diff summary footer cutoff. 0 = off; positive = min file count. */
173
+ multiDiffSummaryThreshold: number;
174
+ maxIterations: number;
175
+ /** Maximum auto-proceed iterations (0 = unlimited). */
176
+ autoProceedMaxIterations: number;
177
+ /** Prompt refinement preview countdown (ms). */
178
+ enhanceDelayMs: number;
179
+ /** Pre-refine grace period (seconds). 0 = skip countdown entirely. */
180
+ preRefineSeconds: number;
181
+ /** Master toggle for the prompt refiner (mirrors Settings.enhanceEnabled). */
182
+ enhanceEnabled: boolean;
183
+ /** Refined-prompt language preference (mirrors Settings.enhanceLanguage). */
184
+ enhanceLanguage: 'original' | 'english';
185
+ /** Raw SSE stream debugging toggle. */
186
+ debugStream: boolean;
187
+ /** Statusline density mode. */
188
+ statuslineMode: StatuslineMode;
189
+ /** Reasoning mode: auto | on | off. */
190
+ reasoningMode: 'auto' | 'on' | 'off';
191
+ /** Reasoning effort level. */
192
+ reasoningEffort: ReasoningEffort;
193
+ /**
194
+ * Effort levels the ACTIVE model documents (models.dev reasoningConfig),
195
+ * injected by the host at /settings-open time. Absent = vocabulary
196
+ * undocumented; the effort cycle then covers the full canonical set.
197
+ */
198
+ reasoningEffortLevels?: string[] | undefined;
199
+ /** Preserve thinking across turns. */
200
+ reasoningPreserve: boolean;
201
+ /** Single word shown in the TUI rainbow working-state chip. */
202
+ thinkingWord: string;
203
+ /** True while free-text editing the thinking word (Enter on its row). */
204
+ thinkingWordEditing: boolean;
205
+ /** In-progress text buffer while `thinkingWordEditing`. */
206
+ thinkingWordDraft: string;
207
+ /**
208
+ * Show the "Model Reasoning" collapsible blocks in chat history.
209
+ * Separate from thinkingWord (status-bar chip) and reasoningMode
210
+ * (API-level provisioning). Default: true.
211
+ */
212
+ showModelReasoning: boolean;
213
+ /** Global default for all committed tool-result cards. */
214
+ toolResultViewMode: ToolResultViewMode;
215
+ /** Agent swarm panel placement: 'bottom' (lower region), 'sidebar' (right sidebar), or 'off'. Default: 'bottom'. */
216
+ showAgentSwarmPanel: import('./app-settings-type.js').AgentSwarmPanelMode;
217
+ /** Right sidebar visibility (mirrors Settings.showSidebar). Default: true. */
218
+ showSidebar: boolean;
219
+ /**
220
+ * Per-panel position map mirrored from the persisted Settings shape.
221
+ * Each F-key panel can be set to 'bottom' (F-key behavior, the default)
222
+ * or 'sidebar' (rendered in the right sidebar). When a panel is set to
223
+ * 'sidebar' AND its F-key toggle is on, the bottom view hides and the
224
+ * sidebar shows the panel twin instead. When the F-key is off, neither
225
+ * surface shows the panel.
226
+ */
227
+ panelPositions: PanelPositionMap;
228
+ /** Show SAGE Memory Inject blocks in tool results. Default: false (hidden). */
229
+ showSageMemoryInject: boolean;
230
+ /** Minimum relation strength for SAGE memory injection. Default: 0.85. */
231
+ sageMemoryInjectThreshold: number;
232
+ /** Register the leader's agent-callable `nextsteps` tool. Default: false. */
233
+ nextStepsTool: boolean;
234
+ /** When true, read tool includes codebase-index symbols alongside file content. */
235
+ readSymbols: boolean;
236
+ /** Prompt cache TTL. */
237
+ cacheTtl: CacheTtl;
238
+ /** Where to persist settings: 'global' or 'project'. */
239
+ configScope: 'global' | 'project';
240
+ /**
241
+ * Animation style for the working/thinking chip in the status bar. One
242
+ * of the styles exported by `components/animation-style.tsx`, plus the
243
+ * meta-mode `'cycle'` that rotates through the variant styles every
244
+ * `CYCLE_INTERVAL_SECONDS`. Persisted on every ←/→ change in `/settings`.
245
+ */
246
+ animationStyle: 'rainbow' | 'wave' | 'pulse' | 'dots' | 'breathe' | 'static' | 'cycle';
247
+ /**
248
+ * WrongProxy / WrongTrace: master switch. When true AND the daemon at
249
+ * `wrongProxyUrl` is reachable, every provider's base URL is rewritten
250
+ * through `${wrongProxyUrl}/proxy/<host><path>`. openai-codex is
251
+ * excluded by spec. Mirrors `Settings.wrongProxyEnabled` and the
252
+ * `tools.wrongProxy.enabled` config key. Picker field 59.
253
+ */
254
+ wrongProxyEnabled: boolean;
255
+ /**
256
+ * WrongProxy / WrongTrace URL. Default `http://localhost:3444`. The
257
+ * CLI's periodic probe targets `<wrongProxyUrl>/api/health`; a 2xx
258
+ * response flips the runtime's `active` flag. Picker field 60.
259
+ */
260
+ wrongProxyUrl: string;
261
+ /** True while free-text editing the WrongProxy URL (Enter on its row). */
262
+ wrongProxyUrlEditing: boolean;
263
+ /** In-progress text buffer while `wrongProxyUrlEditing`. */
264
+ wrongProxyUrlDraft: string;
265
+ /** Whether the process circuit breaker gates bash/exec. */
266
+ breakerEnabled: boolean;
267
+ /** Auto kill/reset delay (ms) when the breaker trips. 0 = manual recovery. */
268
+ breakerAutoKillResetMs: number;
269
+ /**
270
+ * Live filter for the row-search modal (entered via `/`). Empty
271
+ * string means filter is inactive. Non-empty means the user is
272
+ * typing a search query and only matching rows are visible.
273
+ * Cleared on picker close and on Esc-out-of-filter.
274
+ */
275
+ filter: string;
276
+ hint?: string | undefined;
277
+ };
278
+ /** Statusline editor — opened by `/statusline`. */
279
+ statuslinePicker: {
280
+ open: boolean;
281
+ /** Focused field index. */
282
+ field: number;
283
+ /** Current hidden-items list (user-toggled off chips). */
284
+ hiddenItems: StatuslineItem[];
285
+ /**
286
+ * Chips that are temporarily visible due to data/events, with expiration
287
+ * metadata. When a chip expires it is removed from this list. User-toggled
288
+ * chips stay visible via their data being truthy — they are NOT here.
289
+ */
290
+ visibleChips: ChipMeta[];
291
+ /** Per-chip line assignment being edited (mirrors statusline.json v3). */
292
+ lines: StatuslineLines;
293
+ /** Per-chip density pin being edited. */
294
+ densities: StatuslineDensities;
295
+ /** Custom left-to-right chip order being edited. */
296
+ order: StatuslineOrder;
297
+ /** Text filter over chip names/descriptions. */
298
+ filter: string;
299
+ /** True while `/` is capturing filter keystrokes. */
300
+ filtering: boolean;
301
+ /**
302
+ * True once the editor holds the live layout (seeded on open, or made
303
+ * true by any layout edit). The app only mirrors the editor's layout
304
+ * back into the live statusline while this is set, so a caller that
305
+ * opens the picker WITHOUT seeding it can never publish an empty layout
306
+ * over the user's saved one.
307
+ */
308
+ layoutSeeded: boolean;
309
+ hint?: string | undefined;
310
+ };
311
+ /** Plugin toggle editor — opened by `/plugin menu` or `/settings plugins`. */
312
+ pluginPicker: {
313
+ open: boolean;
314
+ items: PluginPickerItem[];
315
+ selected: number;
316
+ busy: boolean;
317
+ hint?: string | undefined;
318
+ };
319
+ /** MCP server picker — opened by `/mcp`. */
320
+ mcpPicker: {
321
+ open: boolean;
322
+ items: McpPickerItem[];
323
+ selected: number;
324
+ busy: boolean;
325
+ hint?: string | undefined;
326
+ };
327
+ /** Tool picker — opened by `/tools`. */
328
+ toolsPicker: {
329
+ open: boolean;
330
+ items: ToolPickerItem[];
331
+ selected: number;
332
+ busy: boolean;
333
+ hint?: string | undefined;
334
+ filter?: string | undefined;
335
+ };
336
+ /** Brain panel — opened by `/brain`. */
337
+ brainPanel: {
338
+ open: boolean;
339
+ riskLevel: BrainRiskLevel;
340
+ log: BrainLogEntry[];
341
+ selected: number;
342
+ hint?: string | undefined;
343
+ /** Settings-editor state (only meaningful when a BrainPanelHost is wired). */
344
+ view: 'settings' | 'log';
345
+ settings?: BrainPanelSettings | undefined;
346
+ /** Settings-view row cursor. */
347
+ row: number;
348
+ busy: boolean;
349
+ };
350
+ /** Help panel — opened by `/help`. */
351
+ helpPanel: {
352
+ open: boolean;
353
+ entries: HelpEntry[];
354
+ selected: number;
355
+ filter: string;
356
+ hint?: string | undefined;
357
+ detailScroll?: number | undefined;
358
+ };
359
+ /** Shadow Agent panel — opened by `/shadow`. */
360
+ shadowPanel: {
361
+ open: boolean;
362
+ shadow: ShadowState;
363
+ hint?: string | undefined;
364
+ };
365
+ /** Interactive API-key / OAuth manager — opened by `/auth`. */
366
+ authPanel: AuthPanelState;
367
+ /** Project switcher panel — opened by F1 or `/project`. */
368
+ projectPicker: {
369
+ open: boolean;
370
+ /** Original unfiltered items. Never mutated after open. */
371
+ allItems: ProjectPickerItem[];
372
+ /** Currently displayed items (filtered from allItems). Navigation targets this list. */
373
+ items: ProjectPickerItem[];
374
+ selected: number;
375
+ filter: string;
376
+ hint?: string | undefined;
377
+ };
378
+ /** F-key panel picker — opened by `/f`. Keyboard-navigable list of F1–F12 panels. */
379
+ fKeyPicker: {
380
+ open: boolean;
381
+ selected: number;
382
+ };
383
+ /** Pending tool confirmations — queue to handle multiple tools requesting confirmation. */
384
+ confirmQueue: {
385
+ toolUseId: string;
386
+ toolName: string;
387
+ input: unknown;
388
+ suggestedPattern: string;
389
+ resolve: (decision: 'yes' | 'no' | 'always' | 'always-exact' | 'always-command' | 'always-tool' | 'deny') => void;
390
+ /** True when the call was classified destructive. */
391
+ destructive: boolean;
392
+ boundaryReason?: string | undefined;
393
+ /** Real write destinations from `Tool.writeTargets`, when declared (VULN-001 Phase 2). */
394
+ writeTargets?: string[] | undefined;
395
+ }[];
396
+ /**
397
+ * Active bare-"continue" confirmation panel. Set when the user typed a lone
398
+ * "continue"/"devam"/"go on" and the runtime resolved it to a concrete next
399
+ * step. Makes the resolution — and its drift risk — visible before it is
400
+ * sent: a grounded resolution (todo / suggestion) auto-proceeds after a
401
+ * short countdown; an `open` resolution (no queued task, model will pick the
402
+ * step itself) requires an explicit keypress. Resolves to
403
+ * proceed / edit / cancel and `submit()` continues. Null when none pending.
404
+ */
405
+ continueConfirm: {
406
+ /** One-line summary shown in the panel header (e.g. "▶ Continue → todo: …"). */
407
+ label: string;
408
+ /** The full instruction that will be injected in place of "continue". */
409
+ instruction: string;
410
+ /** Where the resolution came from — drives copy + risk styling. */
411
+ source: 'todo' | 'suggestion' | 'open';
412
+ /** True for todo/suggestion (low drift); false for the `open` guess. */
413
+ grounded: boolean;
414
+ resolve: (decision: 'proceed' | 'edit' | 'cancel') => void;
415
+ } | null;
416
+ /**
417
+ * Pending destructive `/clear` confirmation. Unlike ordinary yes/no
418
+ * prompts this requires the user to type the full uppercase word `YES`.
419
+ */
420
+ clearConfirm: {
421
+ leaderActive: boolean;
422
+ subagentCount: number;
423
+ value: string;
424
+ resolve: (decision: boolean) => void;
425
+ } | null;
426
+ /**
427
+ * Pending `/exit` confirmation. Mirrors the `/clear` invariant: while a
428
+ * leader run or any subagent is in flight, `/exit` must not terminate the
429
+ * TUI silently. The panel asks for an Enter/Esc acknowledgement so the
430
+ * user can decide to abort the in-flight work first. When nothing is
431
+ * running, `/exit` resolves true without ever opening this panel.
432
+ */
433
+ exitConfirm: {
434
+ leaderActive: boolean;
435
+ subagentCount: number;
436
+ backgroundCount?: number | undefined;
437
+ resolve: (decision: boolean) => void;
438
+ } | null;
439
+ /** Generic slash-command confirmation rendered inside the TUI. */
440
+ slashConfirm: {
441
+ question: string;
442
+ defaultYes: boolean;
443
+ resolve: (decision: boolean | null) => void;
444
+ } | null;
445
+ /**
446
+ * Pending ESC-interrupt confirmation. Null when none is pending.
447
+ * When `confirmExit` is enabled and Esc is pressed mid-iteration, the
448
+ * snapshot is captured and `escConfirm` opens instead of immediately
449
+ * aborting. The prompt shows "Abort work and redirect?"
450
+ * (or similar) and waits for y/n/Esc.
451
+ */
452
+ escConfirm: {
453
+ snapshot: NonNullable<PanelState['steerSnapshot']>;
454
+ } | null;
455
+ /**
456
+ * Fallback model overlay — shown when `provider.fallback_pending` fires.
457
+ * The overlay displays a countdown and the candidate model list, letting
458
+ * the user manually pick a model or wait for auto-switch. Null when no
459
+ * fallback gate is pending.
460
+ */
461
+ fallbackOverlay: {
462
+ requestId: string;
463
+ from: {
464
+ providerId: string;
465
+ model: string;
466
+ };
467
+ status: number;
468
+ candidates: Array<{
469
+ providerId: string;
470
+ model: string;
471
+ }>;
472
+ autoSwitchSeconds: number;
473
+ selected: number;
474
+ } | null;
475
+ /**
476
+ * Mid-run send-mode picker. Set when the user submits a plain message while
477
+ * the agent is busy and `midRunSendPicker` is enabled — the picker asks how
478
+ * to deliver the text (queue / by-the-way / steer). The `resolve` callback
479
+ * is awaited inside `submit()` (same Promise pattern as `enhance`); on
480
+ * `'cancel'` (Esc) the caller restores the draft to the composer instead
481
+ * of sending — nothing is queued. Null when no picker is pending.
482
+ */
483
+ sendModePicker: {
484
+ selected: number;
485
+ text: string;
486
+ displayText: string;
487
+ blocks: ContentBlock[];
488
+ pasteContent?: string | undefined;
489
+ resolve: (decision: SendMode | 'cancel') => void;
490
+ } | null;
491
+ /** When true, the queue panel is shown (F7). */
492
+ queuePanelOpen: boolean;
493
+ /** When true, the audit (side effects) overlay is shown (/audit). */
494
+ auditPanelOpen: boolean;
495
+ /** When true, the plan panel is shown (F5). */
496
+ planPanelOpen: boolean;
497
+ /** When true, the project kanban panel is shown. */
498
+ kanbanPanelOpen: boolean;
499
+ /** When true, the goal panel is shown (F9). */
500
+ goalPanelOpen: boolean;
501
+ goalKanbanPanelOpen: boolean;
502
+ /** When true, the interactive context monitor is shown (`/context`). */
503
+ contextPanelOpen: boolean;
504
+ /** When true, the interactive service connections health panel is shown (`/connections`). */
505
+ connectionsPanelOpen: boolean;
506
+ /** When true, the sessions panel is shown (F10). */
507
+ sessionsPanelOpen: boolean;
508
+ /** Live session data for the sessions panel (F10). */
509
+ sessionsPanel: {
510
+ sessions: LiveSessionEntry[];
511
+ busy: boolean;
512
+ /** Selected index for arrow-key navigation. -1 when nothing selected. */
513
+ selected: number;
514
+ };
515
+ /**
516
+ * Pending session resume confirmation. When set, the F10 panel shows a
517
+ * "Press Enter to confirm resume, Esc to cancel" prompt. Set by the first
518
+ * Enter on a same-project session; the second Enter triggers the actual
519
+ * onResumeSession call.
520
+ */
521
+ sessionResumeConfirm: {
522
+ sessionId: string;
523
+ sessionName: string;
524
+ } | null;
525
+ /** Checkpoint timeline overlay — null when closed. */
526
+ rewindOverlay: {
527
+ checkpoints: Array<{
528
+ promptIndex: number;
529
+ promptPreview: string;
530
+ ts: string;
531
+ fileCount: number;
532
+ }>;
533
+ selected: number;
534
+ } | null;
535
+ };
536
+ //# sourceMappingURL=app-panel-state.d.ts.map
@@ -526,7 +526,7 @@ export interface AppProps {
526
526
  * Called when the user selects a project or action in the project picker.
527
527
  * The host CLI handles project switching (stopping agents, spawning new session).
528
528
  */
529
- onProjectSelect?: ((key: string, kind: 'project' | 'action') => void) | undefined;
529
+ onProjectSelect?: ((key: string, kind: 'project' | 'action') => void | string | null | Promise<void | string | null>) | undefined;
530
530
  /**
531
531
  * Request the TUI to exit with a specific code. When a project is selected in
532
532
  * the F1 picker, this is called to trigger a clean exit before the host CLI