kaizenai 0.3.0 → 0.5.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 (74) hide show
  1. package/README.md +0 -4
  2. package/bin/kaizen +16 -5
  3. package/dist/client/app-icon-180.png +0 -0
  4. package/dist/client/app-icon-192.png +0 -0
  5. package/dist/client/app-icon-512.png +0 -0
  6. package/dist/client/app-icon-96.png +0 -0
  7. package/dist/client/apple-touch-icon.png +0 -0
  8. package/dist/client/assets/index-C4Zm475L.js +638 -0
  9. package/dist/client/assets/index-CxKis6wK.css +32 -0
  10. package/dist/client/favicon.png +0 -0
  11. package/dist/client/index.html +17 -10
  12. package/dist/client/manifest-dark.webmanifest +3 -3
  13. package/dist/client/manifest.webmanifest +3 -3
  14. package/dist/client/pwa-192.png +0 -0
  15. package/dist/client/pwa-512.png +0 -0
  16. package/dist/server/cli-supervisor.js +306 -0
  17. package/dist/server/cli.js +12636 -0
  18. package/package.json +7 -10
  19. package/dist/client/assets/index-BBs80KD-.js +0 -623
  20. package/dist/client/assets/index-CkCgyLNq.css +0 -32
  21. package/src/server/acp-shared.ts +0 -315
  22. package/src/server/agent.ts +0 -1159
  23. package/src/server/attachments.ts +0 -133
  24. package/src/server/backgrounds.ts +0 -74
  25. package/src/server/cli-runtime.ts +0 -375
  26. package/src/server/cli-supervisor.ts +0 -97
  27. package/src/server/cli.ts +0 -68
  28. package/src/server/codex-app-server-protocol.ts +0 -453
  29. package/src/server/codex-app-server.ts +0 -1350
  30. package/src/server/cursor-acp.ts +0 -819
  31. package/src/server/discovery.ts +0 -322
  32. package/src/server/event-store.ts +0 -1470
  33. package/src/server/events.ts +0 -252
  34. package/src/server/external-open.ts +0 -272
  35. package/src/server/gemini-acp.ts +0 -844
  36. package/src/server/gemini-cli.ts +0 -525
  37. package/src/server/generate-title.ts +0 -36
  38. package/src/server/git-manager.ts +0 -79
  39. package/src/server/git-repository.ts +0 -101
  40. package/src/server/harness-types.ts +0 -20
  41. package/src/server/keybindings.ts +0 -177
  42. package/src/server/machine-name.ts +0 -22
  43. package/src/server/paths.ts +0 -112
  44. package/src/server/process-utils.ts +0 -22
  45. package/src/server/project-icon.ts +0 -352
  46. package/src/server/project-metadata.ts +0 -10
  47. package/src/server/provider-catalog.ts +0 -85
  48. package/src/server/provider-settings.ts +0 -155
  49. package/src/server/quick-response.ts +0 -153
  50. package/src/server/read-models.ts +0 -275
  51. package/src/server/recovery.ts +0 -507
  52. package/src/server/restart.ts +0 -56
  53. package/src/server/server.ts +0 -244
  54. package/src/server/terminal-manager.ts +0 -350
  55. package/src/server/theme-settings.ts +0 -179
  56. package/src/server/update-manager.ts +0 -230
  57. package/src/server/usage/base-provider-usage.ts +0 -57
  58. package/src/server/usage/claude-usage.ts +0 -558
  59. package/src/server/usage/codex-usage.ts +0 -144
  60. package/src/server/usage/cursor-browser.ts +0 -120
  61. package/src/server/usage/cursor-cookies.ts +0 -390
  62. package/src/server/usage/cursor-usage.ts +0 -490
  63. package/src/server/usage/gemini-usage.ts +0 -24
  64. package/src/server/usage/provider-usage.ts +0 -61
  65. package/src/server/usage/test-helpers.ts +0 -9
  66. package/src/server/usage/types.ts +0 -54
  67. package/src/server/usage/utils.ts +0 -325
  68. package/src/server/ws-router.ts +0 -742
  69. package/src/shared/branding.ts +0 -83
  70. package/src/shared/dev-ports.ts +0 -43
  71. package/src/shared/ports.ts +0 -2
  72. package/src/shared/protocol.ts +0 -156
  73. package/src/shared/tools.ts +0 -251
  74. package/src/shared/types.ts +0 -1040
@@ -1,325 +0,0 @@
1
- import type {
2
- AgentProvider,
3
- ChatUsageSnapshot,
4
- ChatUsageWarning,
5
- ProviderUsageAvailability,
6
- ProviderUsageEntry,
7
- TranscriptEntry,
8
- } from "../../shared/types"
9
- import type { NumericUsage, ProviderRateLimitSnapshot } from "./types"
10
-
11
- export const WARNING_THRESHOLD = 75
12
- export const CRITICAL_THRESHOLD = 90
13
- export const STALE_AFTER_MS = 5 * 60 * 1000
14
-
15
- export function asRecord(value: unknown): Record<string, unknown> | null {
16
- if (!value || typeof value !== "object" || Array.isArray(value)) return null
17
- return value as Record<string, unknown>
18
- }
19
-
20
- export function parseJsonLine(line: string): Record<string, unknown> | null {
21
- try {
22
- return asRecord(JSON.parse(line))
23
- } catch {
24
- return null
25
- }
26
- }
27
-
28
- export function toNumber(value: unknown): number | null {
29
- return typeof value === "number" && Number.isFinite(value) ? value : null
30
- }
31
-
32
- export function toPercent(value: number | null) {
33
- if (value === null || !Number.isFinite(value)) return null
34
- return Math.max(0, Math.min(100, value))
35
- }
36
-
37
- export function usageWarnings(args: {
38
- contextUsedPercent: number | null
39
- sessionLimitUsedPercent: number | null
40
- updatedAt: number | null
41
- }): ChatUsageWarning[] {
42
- const warnings: ChatUsageWarning[] = []
43
-
44
- if (args.contextUsedPercent !== null) {
45
- if (args.contextUsedPercent >= CRITICAL_THRESHOLD) {
46
- warnings.push("context_critical")
47
- } else if (args.contextUsedPercent >= WARNING_THRESHOLD) {
48
- warnings.push("context_warning")
49
- }
50
- }
51
-
52
- if (args.sessionLimitUsedPercent !== null) {
53
- if (args.sessionLimitUsedPercent >= CRITICAL_THRESHOLD) {
54
- warnings.push("rate_critical")
55
- } else if (args.sessionLimitUsedPercent >= WARNING_THRESHOLD) {
56
- warnings.push("rate_warning")
57
- }
58
- }
59
-
60
- if (args.updatedAt !== null && Date.now() - args.updatedAt > STALE_AFTER_MS) {
61
- warnings.push("stale")
62
- }
63
-
64
- return warnings
65
- }
66
-
67
- export function relevantMessagesForCurrentContext(messages: TranscriptEntry[]) {
68
- let lastContextClearedIndex = -1
69
- for (let index = messages.length - 1; index >= 0; index -= 1) {
70
- if (messages[index]?.kind === "context_cleared") {
71
- lastContextClearedIndex = index
72
- break
73
- }
74
- }
75
-
76
- return lastContextClearedIndex >= 0 ? messages.slice(lastContextClearedIndex + 1) : messages
77
- }
78
-
79
- function estimateTokenCountFromText(text: string | undefined | null) {
80
- if (!text) return 0
81
- const trimmed = text.trim()
82
- if (!trimmed) return 0
83
- return Math.ceil(trimmed.length / 4)
84
- }
85
-
86
- function estimateTokenCountFromUnknown(value: unknown) {
87
- if (typeof value === "string") {
88
- return estimateTokenCountFromText(value)
89
- }
90
-
91
- try {
92
- return estimateTokenCountFromText(JSON.stringify(value))
93
- } catch {
94
- return 0
95
- }
96
- }
97
-
98
- export function estimateCurrentThreadTokens(messages: TranscriptEntry[]) {
99
- let total = 0
100
-
101
- for (const entry of relevantMessagesForCurrentContext(messages)) {
102
- switch (entry.kind) {
103
- case "user_prompt":
104
- total += estimateTokenCountFromText(entry.content)
105
- if (entry.attachments?.length) {
106
- total += entry.attachments.length * 256
107
- }
108
- break
109
- case "assistant_text":
110
- total += estimateTokenCountFromText(entry.text)
111
- break
112
- case "compact_summary":
113
- total += estimateTokenCountFromText(entry.summary)
114
- break
115
- case "result":
116
- total += estimateTokenCountFromText(entry.result)
117
- break
118
- case "tool_call":
119
- total += estimateTokenCountFromText(entry.tool.toolName)
120
- total += estimateTokenCountFromUnknown(entry.tool.input)
121
- break
122
- case "tool_result":
123
- total += estimateTokenCountFromUnknown(entry.content)
124
- break
125
- case "status":
126
- total += estimateTokenCountFromText(entry.status)
127
- break
128
- default:
129
- break
130
- }
131
- }
132
-
133
- return total
134
- }
135
-
136
- export function buildSnapshot(args: {
137
- provider: AgentProvider
138
- threadTokens: number | null
139
- contextWindowTokens: number | null
140
- lastTurnTokens: number | null
141
- inputTokens: number | null
142
- outputTokens: number | null
143
- cachedInputTokens: number | null
144
- reasoningOutputTokens?: number | null
145
- sessionLimitUsedPercent: number | null
146
- rateLimitResetAt: number | null
147
- source: ChatUsageSnapshot["source"]
148
- updatedAt: number | null
149
- }): ChatUsageSnapshot | null {
150
- const contextUsedPercent = args.threadTokens !== null && args.contextWindowTokens && args.contextWindowTokens > 0
151
- ? toPercent((args.threadTokens / args.contextWindowTokens) * 100)
152
- : null
153
-
154
- const snapshot: ChatUsageSnapshot = {
155
- provider: args.provider,
156
- threadTokens: args.threadTokens,
157
- contextWindowTokens: args.contextWindowTokens,
158
- contextUsedPercent,
159
- lastTurnTokens: args.lastTurnTokens,
160
- inputTokens: args.inputTokens,
161
- outputTokens: args.outputTokens,
162
- cachedInputTokens: args.cachedInputTokens,
163
- reasoningOutputTokens: args.reasoningOutputTokens ?? null,
164
- sessionLimitUsedPercent: toPercent(args.sessionLimitUsedPercent),
165
- rateLimitResetAt: args.rateLimitResetAt,
166
- source: args.source,
167
- updatedAt: args.updatedAt,
168
- warnings: usageWarnings({
169
- contextUsedPercent,
170
- sessionLimitUsedPercent: toPercent(args.sessionLimitUsedPercent),
171
- updatedAt: args.updatedAt,
172
- }),
173
- }
174
-
175
- const hasAnyData = [
176
- snapshot.threadTokens,
177
- snapshot.contextWindowTokens,
178
- snapshot.lastTurnTokens,
179
- snapshot.inputTokens,
180
- snapshot.outputTokens,
181
- snapshot.cachedInputTokens,
182
- snapshot.reasoningOutputTokens ?? null,
183
- snapshot.sessionLimitUsedPercent,
184
- ].some((value) => value !== null)
185
-
186
- return hasAnyData ? snapshot : null
187
- }
188
-
189
- export function usageTotals(usage: Record<string, unknown>): NumericUsage & { totalTokens: number } {
190
- const inputTokens = toNumber(usage.input_tokens) ?? 0
191
- const outputTokens = toNumber(usage.output_tokens) ?? 0
192
- const cachedInputTokens = (toNumber(usage.cache_read_input_tokens) ?? 0) + (toNumber(usage.cache_creation_input_tokens) ?? 0)
193
- const reasoningOutputTokens = toNumber(usage.reasoning_output_tokens) ?? 0
194
-
195
- return {
196
- inputTokens,
197
- outputTokens,
198
- cachedInputTokens,
199
- reasoningOutputTokens,
200
- totalTokens: inputTokens + outputTokens + cachedInputTokens + reasoningOutputTokens,
201
- }
202
- }
203
-
204
- export function mergeUsageSnapshots(
205
- reconstructed: ChatUsageSnapshot | null,
206
- live: ChatUsageSnapshot | null
207
- ): ChatUsageSnapshot | null {
208
- if (!reconstructed) return live
209
- if (!live) return reconstructed
210
-
211
- const merged: ChatUsageSnapshot = {
212
- ...reconstructed,
213
- ...live,
214
- provider: live.provider,
215
- threadTokens: live.threadTokens ?? reconstructed.threadTokens,
216
- contextWindowTokens: live.contextWindowTokens ?? reconstructed.contextWindowTokens,
217
- contextUsedPercent: live.contextUsedPercent ?? reconstructed.contextUsedPercent,
218
- lastTurnTokens: live.lastTurnTokens ?? reconstructed.lastTurnTokens,
219
- inputTokens: live.inputTokens ?? reconstructed.inputTokens,
220
- outputTokens: live.outputTokens ?? reconstructed.outputTokens,
221
- cachedInputTokens: live.cachedInputTokens ?? reconstructed.cachedInputTokens,
222
- reasoningOutputTokens: live.reasoningOutputTokens ?? reconstructed.reasoningOutputTokens,
223
- sessionLimitUsedPercent: live.sessionLimitUsedPercent ?? reconstructed.sessionLimitUsedPercent,
224
- rateLimitResetAt: live.rateLimitResetAt ?? reconstructed.rateLimitResetAt,
225
- source: live.source === "live" ? "live" : reconstructed.source,
226
- updatedAt: live.updatedAt ?? reconstructed.updatedAt,
227
- warnings: [],
228
- }
229
-
230
- merged.warnings = usageWarnings({
231
- contextUsedPercent: merged.contextUsedPercent,
232
- sessionLimitUsedPercent: merged.sessionLimitUsedPercent,
233
- updatedAt: merged.updatedAt,
234
- })
235
-
236
- return merged
237
- }
238
-
239
- export function applyThreadEstimate(
240
- snapshot: ChatUsageSnapshot | null,
241
- messages: TranscriptEntry[]
242
- ): ChatUsageSnapshot | null {
243
- const estimatedThreadTokens = estimateCurrentThreadTokens(messages)
244
- if (!snapshot) return null
245
-
246
- const contextUsedPercent = snapshot.contextWindowTokens && snapshot.contextWindowTokens > 0
247
- ? toPercent((estimatedThreadTokens / snapshot.contextWindowTokens) * 100)
248
- : null
249
-
250
- return {
251
- ...snapshot,
252
- threadTokens: estimatedThreadTokens,
253
- contextUsedPercent,
254
- warnings: usageWarnings({
255
- contextUsedPercent,
256
- sessionLimitUsedPercent: snapshot.sessionLimitUsedPercent,
257
- updatedAt: snapshot.updatedAt,
258
- }),
259
- }
260
- }
261
-
262
- export function deriveAvailability(updatedAt: number | null): ProviderUsageAvailability {
263
- if (updatedAt === null) return "available"
264
- if (updatedAt < Date.now() - STALE_AFTER_MS) return "stale"
265
- if (Date.now() < updatedAt) return "stale"
266
- return "available"
267
- }
268
-
269
- export function snapshotToEntry(provider: AgentProvider, snapshot: ChatUsageSnapshot | null): ProviderUsageEntry {
270
- if (!snapshot) {
271
- return {
272
- provider,
273
- sessionLimitUsedPercent: null,
274
- apiLimitUsedPercent: null,
275
- rateLimitResetAt: null,
276
- rateLimitResetLabel: null,
277
- weeklyLimitUsedPercent: null,
278
- weeklyRateLimitResetAt: null,
279
- weeklyRateLimitResetLabel: null,
280
- statusDetail: null,
281
- availability: "available",
282
- updatedAt: null,
283
- warnings: [],
284
- }
285
- }
286
-
287
- const availability = deriveAvailability(snapshot.updatedAt)
288
- const warnings = usageWarnings({
289
- contextUsedPercent: null,
290
- sessionLimitUsedPercent: snapshot.sessionLimitUsedPercent,
291
- updatedAt: snapshot.updatedAt,
292
- })
293
-
294
- return {
295
- provider,
296
- sessionLimitUsedPercent: snapshot.sessionLimitUsedPercent,
297
- apiLimitUsedPercent: null,
298
- rateLimitResetAt: snapshot.rateLimitResetAt,
299
- rateLimitResetLabel: (snapshot as ProviderRateLimitSnapshot).rateLimitResetLabel ?? null,
300
- weeklyLimitUsedPercent: (snapshot as ProviderRateLimitSnapshot).weeklyLimitUsedPercent ?? null,
301
- weeklyRateLimitResetAt: (snapshot as ProviderRateLimitSnapshot).weeklyRateLimitResetAt ?? null,
302
- weeklyRateLimitResetLabel: (snapshot as ProviderRateLimitSnapshot).weeklyRateLimitResetLabel ?? null,
303
- statusDetail: null,
304
- availability,
305
- updatedAt: snapshot.updatedAt,
306
- warnings,
307
- }
308
- }
309
-
310
- export function unavailableEntry(provider: AgentProvider): ProviderUsageEntry {
311
- return {
312
- provider,
313
- sessionLimitUsedPercent: null,
314
- apiLimitUsedPercent: null,
315
- rateLimitResetAt: null,
316
- rateLimitResetLabel: null,
317
- weeklyLimitUsedPercent: null,
318
- weeklyRateLimitResetAt: null,
319
- weeklyRateLimitResetLabel: null,
320
- statusDetail: null,
321
- availability: "unavailable",
322
- updatedAt: null,
323
- warnings: [],
324
- }
325
- }