kaizenai 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/bin/kaizen +16 -5
  2. package/dist/client/app-icon-180.png +0 -0
  3. package/dist/client/app-icon-192.png +0 -0
  4. package/dist/client/app-icon-512.png +0 -0
  5. package/dist/client/app-icon-96.png +0 -0
  6. package/dist/client/apple-touch-icon.png +0 -0
  7. package/dist/client/assets/index-BR0jGwm_.css +32 -0
  8. package/dist/client/assets/index-CYqy6l6r.js +628 -0
  9. package/dist/client/favicon.png +0 -0
  10. package/dist/client/index.html +17 -10
  11. package/dist/client/manifest-dark.webmanifest +3 -3
  12. package/dist/client/manifest.webmanifest +3 -3
  13. package/dist/client/pwa-192.png +0 -0
  14. package/dist/client/pwa-512.png +0 -0
  15. package/dist/server/cli-supervisor.js +307 -0
  16. package/dist/server/cli.js +12371 -0
  17. package/package.json +7 -9
  18. package/dist/client/assets/index-BBs80KD-.js +0 -623
  19. package/dist/client/assets/index-CkCgyLNq.css +0 -32
  20. package/src/server/acp-shared.ts +0 -315
  21. package/src/server/agent.ts +0 -1159
  22. package/src/server/attachments.ts +0 -133
  23. package/src/server/backgrounds.ts +0 -74
  24. package/src/server/cli-runtime.ts +0 -375
  25. package/src/server/cli-supervisor.ts +0 -97
  26. package/src/server/cli.ts +0 -68
  27. package/src/server/codex-app-server-protocol.ts +0 -453
  28. package/src/server/codex-app-server.ts +0 -1350
  29. package/src/server/cursor-acp.ts +0 -819
  30. package/src/server/discovery.ts +0 -322
  31. package/src/server/event-store.ts +0 -1470
  32. package/src/server/events.ts +0 -252
  33. package/src/server/external-open.ts +0 -272
  34. package/src/server/gemini-acp.ts +0 -844
  35. package/src/server/gemini-cli.ts +0 -525
  36. package/src/server/generate-title.ts +0 -36
  37. package/src/server/git-manager.ts +0 -79
  38. package/src/server/git-repository.ts +0 -101
  39. package/src/server/harness-types.ts +0 -20
  40. package/src/server/keybindings.ts +0 -177
  41. package/src/server/machine-name.ts +0 -22
  42. package/src/server/paths.ts +0 -112
  43. package/src/server/process-utils.ts +0 -22
  44. package/src/server/project-icon.ts +0 -352
  45. package/src/server/project-metadata.ts +0 -10
  46. package/src/server/provider-catalog.ts +0 -85
  47. package/src/server/provider-settings.ts +0 -155
  48. package/src/server/quick-response.ts +0 -153
  49. package/src/server/read-models.ts +0 -275
  50. package/src/server/recovery.ts +0 -507
  51. package/src/server/restart.ts +0 -56
  52. package/src/server/server.ts +0 -244
  53. package/src/server/terminal-manager.ts +0 -350
  54. package/src/server/theme-settings.ts +0 -179
  55. package/src/server/update-manager.ts +0 -230
  56. package/src/server/usage/base-provider-usage.ts +0 -57
  57. package/src/server/usage/claude-usage.ts +0 -558
  58. package/src/server/usage/codex-usage.ts +0 -144
  59. package/src/server/usage/cursor-browser.ts +0 -120
  60. package/src/server/usage/cursor-cookies.ts +0 -390
  61. package/src/server/usage/cursor-usage.ts +0 -490
  62. package/src/server/usage/gemini-usage.ts +0 -24
  63. package/src/server/usage/provider-usage.ts +0 -61
  64. package/src/server/usage/test-helpers.ts +0 -9
  65. package/src/server/usage/types.ts +0 -54
  66. package/src/server/usage/utils.ts +0 -325
  67. package/src/server/ws-router.ts +0 -742
  68. package/src/shared/branding.ts +0 -83
  69. package/src/shared/dev-ports.ts +0 -43
  70. package/src/shared/ports.ts +0 -2
  71. package/src/shared/protocol.ts +0 -156
  72. package/src/shared/tools.ts +0 -251
  73. package/src/shared/types.ts +0 -1040
@@ -1,1040 +0,0 @@
1
- export const STORE_VERSION = 3 as const
2
- export const PROTOCOL_VERSION = 1 as const
3
-
4
- export type AgentProvider = "claude" | "codex" | "gemini" | "cursor"
5
-
6
- export interface ProviderModelOption {
7
- id: string
8
- label: string
9
- supportsEffort: boolean
10
- contextWindowOptions?: readonly ProviderContextWindowOption[]
11
- }
12
-
13
- export interface ProviderEffortOption {
14
- id: string
15
- label: string
16
- }
17
-
18
- export interface ProviderContextWindowOption {
19
- id: ClaudeContextWindow
20
- label: string
21
- }
22
-
23
- export interface GeminiThinkingOption {
24
- id: "off" | "standard" | "high"
25
- label: string
26
- }
27
-
28
- export const CLAUDE_REASONING_OPTIONS = [
29
- { id: "low", label: "Low" },
30
- { id: "medium", label: "Medium" },
31
- { id: "high", label: "High" },
32
- { id: "max", label: "Max" },
33
- ] as const satisfies readonly ProviderEffortOption[]
34
-
35
- export const CODEX_REASONING_OPTIONS = [
36
- { id: "minimal", label: "Minimal" },
37
- { id: "low", label: "Low" },
38
- { id: "medium", label: "Medium" },
39
- { id: "high", label: "High" },
40
- { id: "xhigh", label: "XHigh" },
41
- ] as const satisfies readonly ProviderEffortOption[]
42
-
43
- export type ClaudeReasoningEffort = (typeof CLAUDE_REASONING_OPTIONS)[number]["id"]
44
- export type CodexReasoningEffort = (typeof CODEX_REASONING_OPTIONS)[number]["id"]
45
- export type ClaudeContextWindow = "200k" | "1m"
46
- export type ServiceTier = "fast"
47
-
48
- export const CLAUDE_CONTEXT_WINDOW_FALLBACKS: Record<string, number> = {
49
- sonnet: 1_000_000,
50
- opus: 1_000_000,
51
- haiku: 200_000,
52
- }
53
-
54
- export const GEMINI_THINKING_OPTIONS = [
55
- { id: "off", label: "Off" },
56
- { id: "standard", label: "Standard" },
57
- { id: "high", label: "High" },
58
- ] as const satisfies readonly GeminiThinkingOption[]
59
-
60
- export type GeminiThinkingMode = (typeof GEMINI_THINKING_OPTIONS)[number]["id"]
61
-
62
- export interface ClaudeModelOptions {
63
- reasoningEffort: ClaudeReasoningEffort
64
- contextWindow?: ClaudeContextWindow
65
- }
66
-
67
- export interface CodexModelOptions {
68
- reasoningEffort: CodexReasoningEffort
69
- fastMode: boolean
70
- }
71
-
72
- export interface GeminiModelOptions {
73
- thinkingMode: GeminiThinkingMode
74
- }
75
-
76
- export interface CursorModelOptions {}
77
-
78
- export type CursorModelSpeed = "fast" | "standard"
79
-
80
- export const DEFAULT_CURSOR_MODEL = "claude-opus-4-6[thinking=true,context=200k,effort=high,fast=false]" as const
81
-
82
- export const CURSOR_MODELS = [
83
- { id: "composer-2[fast=true]", label: "Composer 2", supportsEffort: false },
84
- { id: "composer-1.5[]", label: "Composer 1.5", supportsEffort: false },
85
- { id: "gpt-5.3-codex[reasoning=medium,fast=false]", label: "Codex 5.3", supportsEffort: false },
86
- { id: "gpt-5.4[reasoning=medium,context=272k,fast=false]", label: "GPT-5.4", supportsEffort: false },
87
- { id: "claude-sonnet-4-6[thinking=true,context=200k,effort=medium]", label: "Sonnet 4.6", supportsEffort: false },
88
- { id: "claude-opus-4-6[thinking=true,context=200k,effort=high,fast=false]", label: "Opus 4.6", supportsEffort: false },
89
- { id: "claude-opus-4-5[thinking=true]", label: "Opus 4.5", supportsEffort: false },
90
- { id: "gpt-5.2[reasoning=medium,fast=false]", label: "GPT-5.2", supportsEffort: false },
91
- { id: "gemini-3.1-pro[]", label: "Gemini 3.1 Pro", supportsEffort: false },
92
- { id: "gpt-5.4-mini[reasoning=medium]", label: "GPT-5.4 Mini", supportsEffort: false },
93
- { id: "gpt-5.4-nano[reasoning=medium]", label: "GPT-5.4 Nano", supportsEffort: false },
94
- { id: "claude-haiku-4-5[thinking=true]", label: "Haiku 4.5", supportsEffort: false },
95
- { id: "gpt-5.3-codex-spark[reasoning=medium]", label: "Codex 5.3 Spark", supportsEffort: false },
96
- { id: "grok-4-20[thinking=true]", label: "Grok 4.20", supportsEffort: false },
97
- { id: "claude-sonnet-4-5[thinking=true,context=200k]", label: "Sonnet 4.5", supportsEffort: false },
98
- { id: "gpt-5.2-codex[reasoning=medium,fast=false]", label: "Codex 5.2", supportsEffort: false },
99
- { id: "gemini-3-flash[]", label: "Gemini 3 Flash", supportsEffort: false },
100
- { id: "claude-sonnet-4[thinking=false,context=200k]", label: "Sonnet 4", supportsEffort: false },
101
- { id: "kimi-k2.5[]", label: "Kimi K2.5", supportsEffort: false },
102
- ] as const satisfies readonly ProviderModelOption[]
103
-
104
- export const CURSOR_MODEL_ALIASES: Record<string, string> = {
105
- "composer-2-fast": "composer-2[fast=true]",
106
- "composer-1.5": "composer-1.5[]",
107
- "gpt-5.3-codex": "gpt-5.3-codex[reasoning=medium,fast=false]",
108
- "gpt-5.4": "gpt-5.4[reasoning=medium,context=272k,fast=false]",
109
- "gpt-5.4-medium": "gpt-5.4[reasoning=medium,context=272k,fast=false]",
110
- "claude-4.6-sonnet-medium-thinking": "claude-sonnet-4-6[thinking=true,context=200k,effort=medium]",
111
- "claude-4.6-opus-high-thinking": "claude-opus-4-6[thinking=true,context=200k,effort=high,fast=false]",
112
- "claude-4.5-opus-high-thinking": "claude-opus-4-5[thinking=true]",
113
- "gpt-5.2": "gpt-5.2[reasoning=medium,fast=false]",
114
- "gemini-3.1-pro": "gemini-3.1-pro[]",
115
- "gpt-5.4-mini": "gpt-5.4-mini[reasoning=medium]",
116
- "gpt-5.4-mini-medium": "gpt-5.4-mini[reasoning=medium]",
117
- "gpt-5.4-nano": "gpt-5.4-nano[reasoning=medium]",
118
- "gpt-5.4-nano-medium": "gpt-5.4-nano[reasoning=medium]",
119
- "claude-haiku-4.5": "claude-haiku-4-5[thinking=true]",
120
- "gpt-5.3-codex-spark-preview": "gpt-5.3-codex-spark[reasoning=medium]",
121
- "grok-4-20": "grok-4-20[thinking=true]",
122
- "grok-4-20-thinking": "grok-4-20[thinking=true]",
123
- "claude-4.5-sonnet-thinking": "claude-sonnet-4-5[thinking=true,context=200k]",
124
- "gpt-5.2-codex": "gpt-5.2-codex[reasoning=medium,fast=false]",
125
- "gemini-3-flash": "gemini-3-flash[]",
126
- "claude-4-sonnet": "claude-sonnet-4[thinking=false,context=200k]",
127
- "kimi-k2.5": "kimi-k2.5[]",
128
- }
129
-
130
- export function normalizeCursorModelId(model?: string): string {
131
- if (!model) return DEFAULT_CURSOR_MODEL
132
- if (CURSOR_MODELS.some((candidate) => candidate.id === model)) return model
133
- return CURSOR_MODEL_ALIASES[model] ?? DEFAULT_CURSOR_MODEL
134
- }
135
-
136
- export function getCursorModelBaseId(modelId: string): string {
137
- const bracketIndex = modelId.indexOf("[")
138
- return bracketIndex >= 0 ? modelId.slice(0, bracketIndex) : modelId
139
- }
140
-
141
- export function getCursorModelSpeed(modelId: string): CursorModelSpeed | null {
142
- const fastMatch = modelId.match(/\bfast=(true|false)\b/)
143
- if (!fastMatch) return null
144
- return fastMatch[1] === "true" ? "fast" : "standard"
145
- }
146
-
147
- export interface ProviderModelOptionsByProvider {
148
- claude: ClaudeModelOptions
149
- codex: CodexModelOptions
150
- gemini: GeminiModelOptions
151
- cursor: CursorModelOptions
152
- }
153
-
154
- export type ModelOptions = Partial<{
155
- [K in AgentProvider]: Partial<ProviderModelOptionsByProvider[K]>
156
- }>
157
-
158
- export function isClaudeReasoningEffort(value: unknown): value is ClaudeReasoningEffort {
159
- return CLAUDE_REASONING_OPTIONS.some((option) => option.id === value)
160
- }
161
-
162
- export function isCodexReasoningEffort(value: unknown): value is CodexReasoningEffort {
163
- return CODEX_REASONING_OPTIONS.some((option) => option.id === value)
164
- }
165
-
166
- export const CLAUDE_CONTEXT_WINDOW_OPTIONS = [
167
- { id: "200k", label: "200k" },
168
- { id: "1m", label: "1M" },
169
- ] as const satisfies readonly ProviderContextWindowOption[]
170
-
171
- export function isClaudeContextWindow(value: unknown): value is ClaudeContextWindow {
172
- return CLAUDE_CONTEXT_WINDOW_OPTIONS.some((option) => option.id === value)
173
- }
174
-
175
- export function isGeminiThinkingMode(value: unknown): value is GeminiThinkingMode {
176
- return GEMINI_THINKING_OPTIONS.some((option) => option.id === value)
177
- }
178
-
179
- export interface ProviderCatalogEntry {
180
- id: AgentProvider
181
- label: string
182
- systemActive: boolean
183
- defaultModel: string
184
- defaultEffort?: string
185
- defaultModelOptions: Record<string, unknown>
186
- supportsPlanMode: boolean
187
- models: ProviderModelOption[]
188
- efforts: ProviderEffortOption[]
189
- }
190
-
191
- export interface ProviderSettingsEntry {
192
- active: boolean
193
- }
194
-
195
- export type ProviderSettingsMap = Record<AgentProvider, ProviderSettingsEntry>
196
-
197
- export interface ProviderSettingsSnapshot {
198
- settings: ProviderSettingsMap
199
- warning: string | null
200
- filePathDisplay: string
201
- }
202
-
203
- export interface EffectiveProviderEntry extends ProviderCatalogEntry {
204
- active: boolean
205
- isSelectable: boolean
206
- isUsageEnabled: boolean
207
- isInactive: boolean
208
- inactiveMessage: string | null
209
- }
210
-
211
- export const PROVIDERS: ProviderCatalogEntry[] = [
212
- {
213
- id: "claude",
214
- label: "Claude",
215
- systemActive: true,
216
- defaultModel: "sonnet",
217
- defaultEffort: "high",
218
- defaultModelOptions: {
219
- reasoningEffort: "high",
220
- contextWindow: "200k",
221
- } as const satisfies ClaudeModelOptions,
222
- supportsPlanMode: true,
223
- models: [
224
- { id: "opus", label: "Opus", supportsEffort: true, contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS] },
225
- { id: "sonnet", label: "Sonnet", supportsEffort: true, contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS] },
226
- { id: "haiku", label: "Haiku", supportsEffort: true },
227
- ],
228
- efforts: [...CLAUDE_REASONING_OPTIONS],
229
- },
230
- {
231
- id: "codex",
232
- label: "Codex",
233
- systemActive: true,
234
- defaultModel: "gpt-5.4",
235
- defaultModelOptions: {
236
- reasoningEffort: "high",
237
- fastMode: false,
238
- } as const satisfies CodexModelOptions,
239
- supportsPlanMode: true,
240
- models: [
241
- { id: "gpt-5.4", label: "GPT-5.4", supportsEffort: false },
242
- { id: "gpt-5.3-codex", label: "GPT-5.3 Codex", supportsEffort: false },
243
- { id: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark", supportsEffort: false },
244
- ],
245
- efforts: [],
246
- },
247
- {
248
- id: "gemini",
249
- label: "Gemini",
250
- systemActive: false,
251
- defaultModel: "auto-gemini-2.5",
252
- defaultModelOptions: {
253
- thinkingMode: "standard",
254
- } as const satisfies GeminiModelOptions,
255
- supportsPlanMode: true,
256
- models: [
257
- { id: "auto-gemini-3", label: "Auto (Gemini 3)", supportsEffort: false },
258
- { id: "auto-gemini-2.5", label: "Auto (Gemini 2.5)", supportsEffort: false },
259
- { id: "gemini-3.1-pro-preview", label: "3.1 Pro Preview", supportsEffort: false },
260
- { id: "gemini-3-pro-preview", label: "3 Pro Preview", supportsEffort: false },
261
- { id: "gemini-3-flash-preview", label: "3 Flash Preview", supportsEffort: false },
262
- { id: "gemini-2.5-pro", label: "2.5 Pro", supportsEffort: false },
263
- { id: "gemini-2.5-flash", label: "2.5 Flash", supportsEffort: false },
264
- { id: "gemini-2.5-flash-lite", label: "2.5 Flash Lite", supportsEffort: false },
265
- ],
266
- efforts: [],
267
- },
268
- {
269
- id: "cursor",
270
- label: "Cursor",
271
- systemActive: true,
272
- defaultModel: DEFAULT_CURSOR_MODEL,
273
- defaultModelOptions: {
274
- } as const satisfies CursorModelOptions,
275
- supportsPlanMode: true,
276
- models: [...CURSOR_MODELS],
277
- efforts: [],
278
- },
279
- ]
280
-
281
- export const DEFAULT_PROVIDER_SETTINGS: ProviderSettingsMap = {
282
- claude: {
283
- active: true,
284
- },
285
- codex: {
286
- active: true,
287
- },
288
- gemini: {
289
- active: true,
290
- },
291
- cursor: {
292
- active: true,
293
- },
294
- }
295
-
296
- export function getProviderCatalog(provider: AgentProvider): ProviderCatalogEntry {
297
- const entry = PROVIDERS.find((candidate) => candidate.id === provider)
298
- if (!entry) {
299
- throw new Error(`Unknown provider: ${provider}`)
300
- }
301
- return entry
302
- }
303
-
304
- export function getProviderSettingsEntry(
305
- settings: Partial<Record<AgentProvider, Partial<ProviderSettingsEntry>>> | ProviderSettingsMap | null | undefined,
306
- provider: AgentProvider
307
- ): ProviderSettingsEntry {
308
- const defaults = DEFAULT_PROVIDER_SETTINGS[provider]
309
- const value = settings?.[provider]
310
-
311
- return {
312
- active: value?.active ?? defaults.active,
313
- }
314
- }
315
-
316
- export function getProviderInactiveMessage(
317
- provider: AgentProvider,
318
- settings: Partial<Record<AgentProvider, Partial<ProviderSettingsEntry>>> | ProviderSettingsMap | null | undefined
319
- ): string | null {
320
- const catalog = getProviderCatalog(provider)
321
- const entry = getProviderSettingsEntry(settings, provider)
322
- if (catalog.systemActive && entry.active) return null
323
- return `Provider ${catalog.label} is currently not active.`
324
- }
325
-
326
- export function isProviderSelectable(
327
- provider: AgentProvider,
328
- settings: Partial<Record<AgentProvider, Partial<ProviderSettingsEntry>>> | ProviderSettingsMap | null | undefined
329
- ): boolean {
330
- const catalog = getProviderCatalog(provider)
331
- const entry = getProviderSettingsEntry(settings, provider)
332
- return catalog.systemActive && entry.active
333
- }
334
-
335
- export function getEffectiveProviders(
336
- settings: Partial<Record<AgentProvider, Partial<ProviderSettingsEntry>>> | ProviderSettingsMap | null | undefined
337
- ): EffectiveProviderEntry[] {
338
- return PROVIDERS.map((provider) => {
339
- const providerSettings = getProviderSettingsEntry(settings, provider.id)
340
- const isSelectable = provider.systemActive && providerSettings.active
341
-
342
- return {
343
- ...provider,
344
- active: providerSettings.active,
345
- isSelectable,
346
- isUsageEnabled: isSelectable,
347
- isInactive: !isSelectable,
348
- inactiveMessage: getProviderInactiveMessage(provider.id, settings),
349
- }
350
- })
351
- }
352
-
353
- export function getSelectableProviders(
354
- settings: Partial<Record<AgentProvider, Partial<ProviderSettingsEntry>>> | ProviderSettingsMap | null | undefined
355
- ): ProviderCatalogEntry[] {
356
- return getEffectiveProviders(settings)
357
- .filter((provider) => provider.isSelectable)
358
- .map(({ active: _active, isSelectable: _isSelectable, isUsageEnabled: _isUsageEnabled, isInactive: _isInactive, inactiveMessage: _inactiveMessage, ...provider }) => provider)
359
- }
360
-
361
- export function getProviderDefaultModelOptions<T extends AgentProvider>(
362
- provider: T
363
- ): ProviderModelOptionsByProvider[T] {
364
- return getProviderCatalog(provider).defaultModelOptions as unknown as ProviderModelOptionsByProvider[T]
365
- }
366
-
367
- export const DEFAULT_CLAUDE_MODEL_OPTIONS =
368
- getProviderDefaultModelOptions("claude") as ClaudeModelOptions
369
-
370
- export const DEFAULT_CODEX_MODEL_OPTIONS =
371
- getProviderDefaultModelOptions("codex") as CodexModelOptions
372
-
373
- export const DEFAULT_GEMINI_MODEL_OPTIONS =
374
- getProviderDefaultModelOptions("gemini") as GeminiModelOptions
375
-
376
- export const DEFAULT_CURSOR_MODEL_OPTIONS =
377
- getProviderDefaultModelOptions("cursor") as CursorModelOptions
378
-
379
- export function getClaudeModelOption(modelId: string): ProviderModelOption | undefined {
380
- return getProviderCatalog("claude").models.find((candidate) => candidate.id === modelId)
381
- }
382
-
383
- export function getClaudeContextWindowOptions(modelId: string): readonly ProviderContextWindowOption[] {
384
- return getClaudeModelOption(modelId)?.contextWindowOptions ?? []
385
- }
386
-
387
- export function normalizeClaudeContextWindow(modelId: string, contextWindow?: unknown): ClaudeContextWindow | undefined {
388
- const options = getClaudeContextWindowOptions(modelId)
389
- if (options.length === 0) return undefined
390
- return options.some((option) => option.id === contextWindow)
391
- ? contextWindow as ClaudeContextWindow
392
- : DEFAULT_CLAUDE_MODEL_OPTIONS.contextWindow
393
- }
394
-
395
- export function resolveClaudeApiModelId(modelId: string, contextWindow?: ClaudeContextWindow): string {
396
- return contextWindow === "1m" ? `${modelId}[1m]` : modelId
397
- }
398
- export type KaizenStatus =
399
- | "idle"
400
- | "starting"
401
- | "running"
402
- | "waiting_for_user"
403
- | "failed"
404
-
405
- export const FEATURE_STAGES = ["idea", "todo", "progress", "testing", "done"] as const
406
- export type FeatureStage = (typeof FEATURE_STAGES)[number]
407
- export const FEATURE_BROWSER_STATES = ["OPEN", "CLOSED"] as const
408
- export type FeatureBrowserState = (typeof FEATURE_BROWSER_STATES)[number]
409
-
410
- export const FEATURE_STAGE_LABELS: Record<FeatureStage, string> = {
411
- idea: "IDEA",
412
- todo: "TODO",
413
- progress: "PROGRESS",
414
- testing: "TESTING",
415
- done: "DONE",
416
- }
417
-
418
- export interface ProjectSummary {
419
- id: string
420
- repoKey: string
421
- localPath: string
422
- worktreePaths: string[]
423
- title: string
424
- browserState: FeatureBrowserState
425
- generalChatsBrowserState: FeatureBrowserState
426
- createdAt: number
427
- updatedAt: number
428
- }
429
-
430
- export interface FeatureSummary {
431
- id: string
432
- projectId: string
433
- title: string
434
- description: string
435
- browserState: FeatureBrowserState
436
- stage: FeatureStage
437
- sortOrder: number
438
- directoryRelativePath: string
439
- overviewRelativePath: string
440
- createdAt: number
441
- updatedAt: number
442
- }
443
-
444
- export interface SidebarChatRow {
445
- _id: string
446
- _creationTime: number
447
- chatId: string
448
- title: string
449
- status: KaizenStatus
450
- localPath: string
451
- provider: AgentProvider | null
452
- lastMessageAt?: number
453
- hasAutomation: boolean
454
- featureId?: string | null
455
- }
456
-
457
- export interface SidebarFeatureRow {
458
- featureId: string
459
- title: string
460
- description: string
461
- browserState: FeatureBrowserState
462
- stage: FeatureStage
463
- sortOrder: number
464
- directoryRelativePath: string
465
- overviewRelativePath: string
466
- updatedAt: number
467
- chats: SidebarChatRow[]
468
- }
469
-
470
- export interface FeatureOverviewSnapshot {
471
- featureId: string
472
- projectId: string
473
- title: string
474
- directoryRelativePath: string
475
- overviewRelativePath: string
476
- localPath: string
477
- content: string
478
- updatedAt: number
479
- }
480
-
481
- export interface SidebarProjectGroup {
482
- groupKey: string
483
- title: string
484
- localPath: string
485
- iconDataUrl?: string | null
486
- browserState: FeatureBrowserState
487
- generalChatsBrowserState: FeatureBrowserState
488
- features: SidebarFeatureRow[]
489
- generalChats: SidebarChatRow[]
490
- }
491
-
492
- export type ProviderUsageAvailability = "available" | "unavailable" | "stale" | "login_required"
493
-
494
- export interface ProviderUsageEntry {
495
- provider: AgentProvider
496
- sessionLimitUsedPercent: number | null
497
- apiLimitUsedPercent?: number | null
498
- rateLimitResetAt: number | null
499
- rateLimitResetLabel?: string | null
500
- weeklyLimitUsedPercent?: number | null
501
- weeklyRateLimitResetAt?: number | null
502
- weeklyRateLimitResetLabel?: string | null
503
- statusDetail?: string | null
504
- availability: ProviderUsageAvailability
505
- lastRequestedAt?: number | null
506
- updatedAt: number | null
507
- warnings: ChatUsageWarning[]
508
- }
509
-
510
- export type ProviderUsageMap = Partial<Record<AgentProvider, ProviderUsageEntry>>
511
-
512
- export interface SidebarData {
513
- projectGroups: SidebarProjectGroup[]
514
- providerUsage?: ProviderUsageMap
515
- }
516
-
517
- export interface LocalProjectSummary {
518
- localPath: string
519
- title: string
520
- iconDataUrl?: string | null
521
- source: "saved" | "discovered"
522
- lastOpenedAt?: number
523
- chatCount: number
524
- }
525
-
526
- export interface DirectoryBrowserEntry {
527
- name: string
528
- localPath: string
529
- }
530
-
531
- export interface DirectoryBrowserSnapshot {
532
- currentPath: string
533
- parentPath: string | null
534
- roots: DirectoryBrowserEntry[]
535
- entries: DirectoryBrowserEntry[]
536
- }
537
-
538
- export interface SuggestedProjectFolder {
539
- label: string
540
- localPath: string
541
- }
542
-
543
- export interface LocalProjectsSnapshot {
544
- machine: {
545
- id: "local"
546
- displayName: string
547
- }
548
- projects: LocalProjectSummary[]
549
- suggestedFolders: SuggestedProjectFolder[]
550
- rootDirectory: DirectoryBrowserSnapshot | null
551
- }
552
-
553
- export type UpdateStatus =
554
- | "idle"
555
- | "checking"
556
- | "available"
557
- | "up_to_date"
558
- | "updating"
559
- | "restart_pending"
560
- | "error"
561
-
562
- export interface UpdateSnapshot {
563
- currentVersion: string
564
- latestVersion: string | null
565
- status: UpdateStatus
566
- updateAvailable: boolean
567
- lastCheckedAt: number | null
568
- error: string | null
569
- installAction: "restart" | "reload"
570
- }
571
-
572
- export type UpdateInstallErrorCode =
573
- | "version_not_live_yet"
574
- | "install_failed"
575
- | "command_missing"
576
-
577
- export interface UpdateInstallResult {
578
- ok: boolean
579
- action: "restart" | "reload"
580
- errorCode: UpdateInstallErrorCode | null
581
- userTitle: string | null
582
- userMessage: string | null
583
- }
584
-
585
- export type KeybindingAction =
586
- | "submitChatMessage"
587
- | "toggleProjectsSidebar"
588
- | "toggleEmbeddedTerminal"
589
- | "toggleRightSidebar"
590
- | "openInFinder"
591
- | "openInEditor"
592
- | "addSplitTerminal"
593
-
594
- export const DEFAULT_KEYBINDINGS: Record<KeybindingAction, string[]> = {
595
- submitChatMessage: ["enter"],
596
- toggleProjectsSidebar: ["ctrl+a"],
597
- toggleEmbeddedTerminal: ["cmd+j", "ctrl+`"],
598
- toggleRightSidebar: ["cmd+b", "ctrl+b"],
599
- openInFinder: ["cmd+alt+f", "ctrl+alt+f"],
600
- openInEditor: ["cmd+shift+o", "ctrl+shift+o"],
601
- addSplitTerminal: ["cmd+/", "ctrl+/"],
602
- }
603
-
604
- export interface KeybindingsSnapshot {
605
- bindings: Record<KeybindingAction, string[]>
606
- warning: string | null
607
- filePathDisplay: string
608
- }
609
-
610
- export type ThemePreference = "light" | "dark" | "system" | "custom"
611
- export type ColorTheme = "default" | "tokyo-night" | "catppuccin" | "dracula" | "nord" | "everforest" | "rose-pine"
612
- export type CustomAppearance = "light" | "dark" | "system"
613
-
614
- export interface ThemeSettingsSnapshot {
615
- settings: {
616
- themePreference: ThemePreference
617
- colorTheme: ColorTheme
618
- customAppearance: CustomAppearance
619
- backgroundImage: string | null
620
- backgroundOpacity: number
621
- backgroundBlur: number
622
- showProjectIconsInSidebar: boolean
623
- }
624
- warning: string | null
625
- filePathDisplay: string
626
- }
627
-
628
- export const DEFAULT_THEME_SETTINGS: ThemeSettingsSnapshot["settings"] = {
629
- themePreference: "system",
630
- colorTheme: "default",
631
- customAppearance: "system",
632
- backgroundImage: null,
633
- backgroundOpacity: 1,
634
- backgroundBlur: 0,
635
- showProjectIconsInSidebar: true,
636
- }
637
-
638
- export interface McpServerInfo {
639
- name: string
640
- status: string
641
- error?: string
642
- }
643
-
644
- export interface AccountInfo {
645
- email?: string
646
- organization?: string
647
- subscriptionType?: string
648
- tokenSource?: string
649
- apiKeySource?: string
650
- }
651
-
652
- export interface AskUserQuestionOption {
653
- label: string
654
- description?: string
655
- }
656
-
657
- export interface AskUserQuestionItem {
658
- id?: string
659
- question: string
660
- header?: string
661
- options?: AskUserQuestionOption[]
662
- multiSelect?: boolean
663
- }
664
-
665
- export type AskUserQuestionAnswerMap = Record<string, string[]>
666
-
667
- export interface TodoItem {
668
- content: string
669
- status: "pending" | "in_progress" | "completed"
670
- activeForm: string
671
- }
672
-
673
- export const MAX_CHAT_ATTACHMENTS = 8
674
- export const MAX_CHAT_IMAGE_BYTES = 10 * 1024 * 1024
675
- export const SUPPORTED_CHAT_IMAGE_MIME_TYPES = [
676
- "image/png",
677
- "image/jpeg",
678
- "image/webp",
679
- "image/gif",
680
- ] as const
681
-
682
- export interface ChatImageAttachment {
683
- type: "image"
684
- id: string
685
- name: string
686
- mimeType: string
687
- sizeBytes: number
688
- relativePath: string
689
- }
690
-
691
- export interface ChatImageAttachmentUpload {
692
- type: "image"
693
- name: string
694
- mimeType: string
695
- sizeBytes: number
696
- dataUrl: string
697
- }
698
-
699
- export type ChatAttachment = ChatImageAttachment
700
- export type ChatAttachmentUpload = ChatImageAttachmentUpload
701
-
702
- export interface ChatUserMessage {
703
- text: string
704
- attachments?: ChatAttachmentUpload[]
705
- }
706
-
707
- export interface HydratedChatImageAttachment extends ChatImageAttachment {
708
- previewUrl: string
709
- }
710
-
711
- export type HydratedChatAttachment = HydratedChatImageAttachment
712
-
713
- interface TranscriptEntryBase {
714
- _id: string
715
- messageId?: string
716
- createdAt: number
717
- hidden?: boolean
718
- debugRaw?: string
719
- }
720
-
721
- interface ToolCallBase<TKind extends string, TInput> {
722
- kind: "tool"
723
- toolKind: TKind
724
- toolName: string
725
- toolId: string
726
- input: TInput
727
- rawInput?: Record<string, unknown>
728
- }
729
-
730
- export interface AskUserQuestionToolCall
731
- extends ToolCallBase<"ask_user_question", { questions: AskUserQuestionItem[] }> { }
732
-
733
- export interface ExitPlanModeToolCall
734
- extends ToolCallBase<"exit_plan_mode", { plan?: string; summary?: string }> { }
735
-
736
- export interface TodoWriteToolCall
737
- extends ToolCallBase<"todo_write", { todos: TodoItem[] }> { }
738
-
739
- export interface SkillToolCall
740
- extends ToolCallBase<"skill", { skill: string }> { }
741
-
742
- export interface GlobToolCall
743
- extends ToolCallBase<"glob", { pattern: string }> { }
744
-
745
- export interface GrepToolCall
746
- extends ToolCallBase<"grep", { pattern: string; outputMode?: string }> { }
747
-
748
- export interface BashToolCall
749
- extends ToolCallBase<"bash", { command: string; description?: string; timeoutMs?: number; runInBackground?: boolean }> { }
750
-
751
- export interface WebSearchToolCall
752
- extends ToolCallBase<"web_search", { query: string }> { }
753
-
754
- export interface ReadFileToolCall
755
- extends ToolCallBase<"read_file", { filePath: string }> { }
756
-
757
- export interface WriteFileToolCall
758
- extends ToolCallBase<"write_file", { filePath: string; content: string }> { }
759
-
760
- export interface EditFileToolCall
761
- extends ToolCallBase<"edit_file", { filePath: string; oldString: string; newString: string }> { }
762
-
763
- export interface SubagentTaskToolCall
764
- extends ToolCallBase<"subagent_task", { subagentType?: string }> { }
765
-
766
- export interface McpGenericToolCall
767
- extends ToolCallBase<"mcp_generic", { server: string; tool: string; payload: Record<string, unknown> }> { }
768
-
769
- export interface UnknownToolCall
770
- extends ToolCallBase<"unknown_tool", { payload: Record<string, unknown> }> { }
771
-
772
- export type NormalizedToolCall =
773
- | AskUserQuestionToolCall
774
- | ExitPlanModeToolCall
775
- | TodoWriteToolCall
776
- | SkillToolCall
777
- | GlobToolCall
778
- | GrepToolCall
779
- | BashToolCall
780
- | WebSearchToolCall
781
- | ReadFileToolCall
782
- | WriteFileToolCall
783
- | EditFileToolCall
784
- | SubagentTaskToolCall
785
- | McpGenericToolCall
786
- | UnknownToolCall
787
-
788
- export interface ToolResultEntry extends TranscriptEntryBase {
789
- kind: "tool_result"
790
- toolId: string
791
- content: unknown
792
- isError?: boolean
793
- }
794
-
795
- export interface UserPromptEntry extends TranscriptEntryBase {
796
- kind: "user_prompt"
797
- content: string
798
- attachments?: ChatAttachment[]
799
- }
800
-
801
- export interface SystemInitEntry extends TranscriptEntryBase {
802
- kind: "system_init"
803
- provider: AgentProvider
804
- model: string
805
- tools: string[]
806
- agents: string[]
807
- slashCommands: string[]
808
- mcpServers: McpServerInfo[]
809
- }
810
-
811
- export interface AccountInfoEntry extends TranscriptEntryBase {
812
- kind: "account_info"
813
- accountInfo: AccountInfo
814
- }
815
-
816
- export interface AssistantTextEntry extends TranscriptEntryBase {
817
- kind: "assistant_text"
818
- text: string
819
- }
820
-
821
- export interface AssistantThoughtEntry extends TranscriptEntryBase {
822
- kind: "assistant_thought"
823
- text: string
824
- }
825
-
826
- export interface ToolCallEntry extends TranscriptEntryBase {
827
- kind: "tool_call"
828
- tool: NormalizedToolCall
829
- }
830
-
831
- export interface ResultEntry extends TranscriptEntryBase {
832
- kind: "result"
833
- subtype: "success" | "error" | "cancelled"
834
- isError: boolean
835
- durationMs: number
836
- result: string
837
- costUsd?: number
838
- }
839
-
840
- export interface StatusEntry extends TranscriptEntryBase {
841
- kind: "status"
842
- status: string
843
- }
844
-
845
- export interface CompactBoundaryEntry extends TranscriptEntryBase {
846
- kind: "compact_boundary"
847
- }
848
-
849
- export interface CompactSummaryEntry extends TranscriptEntryBase {
850
- kind: "compact_summary"
851
- summary: string
852
- }
853
-
854
- export interface ContextClearedEntry extends TranscriptEntryBase {
855
- kind: "context_cleared"
856
- }
857
-
858
- export interface InterruptedEntry extends TranscriptEntryBase {
859
- kind: "interrupted"
860
- }
861
-
862
- export type TranscriptEntry =
863
- | UserPromptEntry
864
- | SystemInitEntry
865
- | AccountInfoEntry
866
- | AssistantTextEntry
867
- | AssistantThoughtEntry
868
- | ToolCallEntry
869
- | ToolResultEntry
870
- | ResultEntry
871
- | StatusEntry
872
- | CompactBoundaryEntry
873
- | CompactSummaryEntry
874
- | ContextClearedEntry
875
- | InterruptedEntry
876
-
877
- export interface HydratedToolCallBase<TKind extends string, TInput, TResult> {
878
- id: string
879
- messageId?: string
880
- hidden?: boolean
881
- kind: "tool"
882
- toolKind: TKind
883
- toolName: string
884
- toolId: string
885
- input: TInput
886
- result?: TResult
887
- rawResult?: unknown
888
- isError?: boolean
889
- timestamp: string
890
- }
891
-
892
- export interface AskUserQuestionToolResult {
893
- answers: AskUserQuestionAnswerMap
894
- discarded?: boolean
895
- }
896
-
897
- export interface ExitPlanModeToolResult {
898
- confirmed?: boolean
899
- clearContext?: boolean
900
- message?: string
901
- discarded?: boolean
902
- attachments?: ChatAttachmentUpload[]
903
- }
904
-
905
- export type HydratedAskUserQuestionToolCall =
906
- HydratedToolCallBase<"ask_user_question", AskUserQuestionToolCall["input"], AskUserQuestionToolResult>
907
-
908
- export type HydratedExitPlanModeToolCall =
909
- HydratedToolCallBase<"exit_plan_mode", ExitPlanModeToolCall["input"], ExitPlanModeToolResult>
910
-
911
- export type HydratedTodoWriteToolCall =
912
- HydratedToolCallBase<"todo_write", TodoWriteToolCall["input"], unknown>
913
-
914
- export type HydratedSkillToolCall =
915
- HydratedToolCallBase<"skill", SkillToolCall["input"], unknown>
916
-
917
- export type HydratedGlobToolCall =
918
- HydratedToolCallBase<"glob", GlobToolCall["input"], unknown>
919
-
920
- export type HydratedGrepToolCall =
921
- HydratedToolCallBase<"grep", GrepToolCall["input"], unknown>
922
-
923
- export type HydratedBashToolCall =
924
- HydratedToolCallBase<"bash", BashToolCall["input"], unknown>
925
-
926
- export type HydratedWebSearchToolCall =
927
- HydratedToolCallBase<"web_search", WebSearchToolCall["input"], unknown>
928
-
929
- export interface ReadFileToolResult {
930
- content: string
931
- }
932
-
933
- export type HydratedReadFileToolCall =
934
- HydratedToolCallBase<"read_file", ReadFileToolCall["input"], ReadFileToolResult | string>
935
-
936
- export type HydratedWriteFileToolCall =
937
- HydratedToolCallBase<"write_file", WriteFileToolCall["input"], unknown>
938
-
939
- export type HydratedEditFileToolCall =
940
- HydratedToolCallBase<"edit_file", EditFileToolCall["input"], unknown>
941
-
942
- export type HydratedSubagentTaskToolCall =
943
- HydratedToolCallBase<"subagent_task", SubagentTaskToolCall["input"], unknown>
944
-
945
- export type HydratedMcpGenericToolCall =
946
- HydratedToolCallBase<"mcp_generic", McpGenericToolCall["input"], unknown>
947
-
948
- export type HydratedUnknownToolCall =
949
- HydratedToolCallBase<"unknown_tool", UnknownToolCall["input"], unknown>
950
-
951
- export type HydratedToolCall =
952
- | HydratedAskUserQuestionToolCall
953
- | HydratedExitPlanModeToolCall
954
- | HydratedTodoWriteToolCall
955
- | HydratedSkillToolCall
956
- | HydratedGlobToolCall
957
- | HydratedGrepToolCall
958
- | HydratedBashToolCall
959
- | HydratedWebSearchToolCall
960
- | HydratedReadFileToolCall
961
- | HydratedWriteFileToolCall
962
- | HydratedEditFileToolCall
963
- | HydratedSubagentTaskToolCall
964
- | HydratedMcpGenericToolCall
965
- | HydratedUnknownToolCall
966
-
967
- export type HydratedTranscriptMessage =
968
- | ({ kind: "user_prompt"; content: string; attachments?: HydratedChatAttachment[]; id: string; messageId?: string; timestamp: string; hidden?: boolean })
969
- | ({ kind: "system_init"; model: string; tools: string[]; agents: string[]; slashCommands: string[]; mcpServers: McpServerInfo[]; provider: AgentProvider; id: string; messageId?: string; timestamp: string; hidden?: boolean; debugRaw?: string })
970
- | ({ kind: "account_info"; accountInfo: AccountInfo; id: string; messageId?: string; timestamp: string; hidden?: boolean })
971
- | ({ kind: "assistant_text"; text: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
972
- | ({ kind: "assistant_thought"; text: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
973
- | ({ kind: "result"; success: boolean; cancelled?: boolean; result: string; durationMs: number; costUsd?: number; id: string; messageId?: string; timestamp: string; hidden?: boolean })
974
- | ({ kind: "status"; status: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
975
- | ({ kind: "compact_boundary"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
976
- | ({ kind: "compact_summary"; summary: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
977
- | ({ kind: "context_cleared"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
978
- | ({ kind: "interrupted"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
979
- | ({ kind: "unknown"; json: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
980
- | ({ id: string; messageId?: string; hidden?: boolean } & HydratedToolCall)
981
-
982
- export interface ChatRuntime {
983
- chatId: string
984
- projectId: string
985
- localPath: string
986
- title: string
987
- status: KaizenStatus
988
- provider: AgentProvider | null
989
- model: string | null
990
- planMode: boolean
991
- sessionToken: string | null
992
- pendingTool?: ChatPendingToolSnapshot | null
993
- inactiveProviderMessage?: string | null
994
- }
995
-
996
- export type ChatUsageWarning =
997
- | "context_warning"
998
- | "context_critical"
999
- | "rate_warning"
1000
- | "rate_critical"
1001
- | "stale"
1002
-
1003
- export interface ChatUsageSnapshot {
1004
- provider: AgentProvider
1005
- threadTokens: number | null
1006
- contextWindowTokens: number | null
1007
- contextUsedPercent: number | null
1008
- lastTurnTokens: number | null
1009
- inputTokens: number | null
1010
- outputTokens: number | null
1011
- cachedInputTokens: number | null
1012
- reasoningOutputTokens?: number | null
1013
- sessionLimitUsedPercent: number | null
1014
- rateLimitResetAt: number | null
1015
- source: "live" | "reconstructed" | "unavailable"
1016
- updatedAt: number | null
1017
- warnings: ChatUsageWarning[]
1018
- }
1019
-
1020
- export interface ChatSnapshot {
1021
- runtime: ChatRuntime
1022
- messages: TranscriptEntry[]
1023
- usage?: ChatUsageSnapshot | null
1024
- availableProviders: ProviderCatalogEntry[]
1025
- providerSettings?: ProviderSettingsSnapshot["settings"]
1026
- }
1027
-
1028
- export interface KaizenSnapshot {
1029
- sidebar: SidebarData
1030
- chat?: ChatSnapshot | null
1031
- }
1032
-
1033
- export interface PendingToolSnapshot {
1034
- toolUseId: string
1035
- toolKind: "ask_user_question" | "exit_plan_mode"
1036
- }
1037
-
1038
- export interface ChatPendingToolSnapshot extends PendingToolSnapshot {
1039
- source?: "active" | "recovered"
1040
- }