codebuff 1.0.218 → 1.0.220

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 (132) hide show
  1. package/dist/checkpoints/checkpoint-manager.d.ts +1 -1
  2. package/dist/checkpoints/checkpoint-manager.js +8 -6
  3. package/dist/checkpoints/checkpoint-manager.js.map +1 -1
  4. package/dist/cli-handlers/api-key.d.ts +25 -0
  5. package/dist/cli-handlers/api-key.js +66 -0
  6. package/dist/cli-handlers/api-key.js.map +1 -0
  7. package/dist/cli-handlers/checkpoint.d.ts +18 -0
  8. package/dist/cli-handlers/checkpoint.js +195 -0
  9. package/dist/cli-handlers/checkpoint.js.map +1 -0
  10. package/dist/cli-handlers/diff.d.ts +2 -0
  11. package/dist/cli-handlers/diff.js +31 -0
  12. package/dist/cli-handlers/diff.js.map +1 -0
  13. package/dist/cli-handlers/easter-egg.d.ts +1 -0
  14. package/dist/cli-handlers/easter-egg.js +126 -0
  15. package/dist/cli-handlers/easter-egg.js.map +1 -0
  16. package/dist/cli.d.ts +0 -18
  17. package/dist/cli.js +70 -397
  18. package/dist/cli.js.map +1 -1
  19. package/dist/client.d.ts +11 -11
  20. package/dist/client.js +123 -45
  21. package/dist/client.js.map +1 -1
  22. package/dist/code-map/tsconfig.tsbuildinfo +1 -1
  23. package/dist/common/actions.d.ts +288 -264
  24. package/dist/common/actions.js +10 -4
  25. package/dist/common/actions.js.map +1 -1
  26. package/dist/common/advanced-analyzer.d.ts +19 -0
  27. package/dist/common/advanced-analyzer.js +140 -0
  28. package/dist/common/advanced-analyzer.js.map +1 -0
  29. package/dist/common/billing/auto-topup.d.ts +8 -0
  30. package/dist/common/billing/auto-topup.js +192 -0
  31. package/dist/common/billing/auto-topup.js.map +1 -0
  32. package/dist/common/billing/balance-calculator.d.ts +55 -0
  33. package/dist/common/billing/balance-calculator.js +207 -0
  34. package/dist/common/billing/balance-calculator.js.map +1 -0
  35. package/dist/common/billing/check-auto-topup.d.ts +12 -0
  36. package/dist/common/billing/check-auto-topup.js +50 -0
  37. package/dist/common/billing/check-auto-topup.js.map +1 -0
  38. package/dist/common/billing/conversion.d.ts +9 -0
  39. package/dist/common/billing/conversion.js +20 -0
  40. package/dist/common/billing/conversion.js.map +1 -0
  41. package/dist/common/billing/credit-check.d.ts +8 -0
  42. package/dist/common/billing/credit-check.js +45 -0
  43. package/dist/common/billing/credit-check.js.map +1 -0
  44. package/dist/common/billing/credit-conversion.d.ts +24 -0
  45. package/dist/common/billing/credit-conversion.js +48 -0
  46. package/dist/common/billing/credit-conversion.js.map +1 -0
  47. package/dist/common/billing/grant-credits.d.ts +28 -0
  48. package/dist/common/billing/grant-credits.js +201 -0
  49. package/dist/common/billing/grant-credits.js.map +1 -0
  50. package/dist/common/billing/plans.d.ts +13 -0
  51. package/dist/common/billing/plans.js +44 -0
  52. package/dist/common/billing/plans.js.map +1 -0
  53. package/dist/common/billing/rollover-logic.d.ts +13 -0
  54. package/dist/common/billing/rollover-logic.js +174 -0
  55. package/dist/common/billing/rollover-logic.js.map +1 -0
  56. package/dist/common/billing/stripe-api.d.ts +31 -0
  57. package/dist/common/billing/stripe-api.js +104 -0
  58. package/dist/common/billing/stripe-api.js.map +1 -0
  59. package/dist/common/browser-actions.d.ts +62 -62
  60. package/dist/common/browser-actions.js +3 -3
  61. package/dist/common/browser-actions.js.map +1 -1
  62. package/dist/common/constants/grant-priorities.d.ts +2 -0
  63. package/dist/common/constants/grant-priorities.js +10 -0
  64. package/dist/common/constants/grant-priorities.js.map +1 -0
  65. package/dist/common/constants/tools.d.ts +1 -1
  66. package/dist/common/constants/tools.js +1 -1
  67. package/dist/common/constants/tools.js.map +1 -1
  68. package/dist/common/constants.d.ts +28 -1
  69. package/dist/common/constants.js +36 -7
  70. package/dist/common/constants.js.map +1 -1
  71. package/dist/common/db/schema.d.ts +323 -86
  72. package/dist/common/db/schema.js +55 -13
  73. package/dist/common/db/schema.js.map +1 -1
  74. package/dist/common/env.mjs +4 -1
  75. package/dist/common/env.mjs.map +1 -1
  76. package/dist/common/message-image-handling.d.ts +41 -0
  77. package/dist/common/message-image-handling.js +57 -0
  78. package/dist/common/message-image-handling.js.map +1 -0
  79. package/dist/common/types/agent-state.d.ts +8 -8
  80. package/dist/common/types/grant.d.ts +2 -0
  81. package/dist/common/types/grant.js +10 -0
  82. package/dist/common/types/grant.js.map +1 -0
  83. package/dist/common/types/usage.d.ts +37 -18
  84. package/dist/common/types/usage.js +9 -6
  85. package/dist/common/types/usage.js.map +1 -1
  86. package/dist/common/util/__tests__/saxy.test.d.ts +1 -0
  87. package/dist/common/util/__tests__/saxy.test.js +262 -0
  88. package/dist/common/util/__tests__/saxy.test.js.map +1 -0
  89. package/dist/common/util/credentials.d.ts +2 -2
  90. package/dist/common/util/dates.d.ts +10 -1
  91. package/dist/common/util/dates.js +11 -2
  92. package/dist/common/util/dates.js.map +1 -1
  93. package/dist/common/util/logger.js +32 -14
  94. package/dist/common/util/logger.js.map +1 -1
  95. package/dist/common/util/process-stream.d.ts +8 -0
  96. package/dist/common/util/process-stream.js +102 -0
  97. package/dist/common/util/process-stream.js.map +1 -0
  98. package/dist/common/util/promise.d.ts +1 -1
  99. package/dist/common/util/promise.js +2 -2
  100. package/dist/common/util/promise.js.map +1 -1
  101. package/dist/common/util/referral-credits.d.ts +1 -0
  102. package/dist/common/util/referral-credits.js +48 -0
  103. package/dist/common/util/referral-credits.js.map +1 -0
  104. package/dist/common/util/saxy.d.ts +8 -0
  105. package/dist/common/util/saxy.js +35 -12
  106. package/dist/common/util/saxy.js.map +1 -1
  107. package/dist/common/util/sync-failure.d.ts +1 -0
  108. package/dist/common/util/sync-failure.js +57 -0
  109. package/dist/common/util/sync-failure.js.map +1 -0
  110. package/dist/common/websockets/websocket-schema.d.ts +530 -480
  111. package/dist/index.js +1 -1
  112. package/dist/menu.js +5 -0
  113. package/dist/menu.js.map +1 -1
  114. package/dist/tool-handlers.js +1 -1
  115. package/dist/tool-handlers.js.map +1 -1
  116. package/dist/utils/__tests__/xml-stream-parser.test.js +6 -10
  117. package/dist/utils/__tests__/xml-stream-parser.test.js.map +1 -1
  118. package/dist/utils/tool-renderers.js +1 -1
  119. package/dist/utils/tool-renderers.js.map +1 -1
  120. package/package.json +1 -1
  121. package/dist/common/logger.d.ts +0 -1
  122. package/dist/common/logger.js +0 -7
  123. package/dist/common/logger.js.map +0 -1
  124. package/dist/common/util/constants.d.ts +0 -1
  125. package/dist/common/util/constants.js +0 -7
  126. package/dist/common/util/constants.js.map +0 -1
  127. package/dist/common/util/helpers.d.ts +0 -1
  128. package/dist/common/util/helpers.js +0 -6
  129. package/dist/common/util/helpers.js.map +0 -1
  130. package/dist/common/util/token-counter.d.ts +0 -3
  131. package/dist/common/util/token-counter.js +0 -27
  132. package/dist/common/util/token-counter.js.map +0 -1
package/dist/cli.js CHANGED
@@ -26,13 +26,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.CLI = void 0;
27
27
  const path_1 = require("path");
28
28
  const readline = __importStar(require("readline"));
29
- const constants_1 = require("./common/api-keys/constants");
30
29
  const project_file_tree_1 = require("./common/project-file-tree");
31
30
  const string_1 = require("./common/util/string");
32
31
  const picocolors_1 = require("picocolors");
33
32
  const background_process_manager_1 = require("./background-process-manager");
34
33
  const chat_storage_1 = require("./chat-storage");
35
34
  const checkpoint_manager_1 = require("./checkpoints/checkpoint-manager");
35
+ const api_key_1 = require("./cli-handlers/api-key");
36
+ const checkpoint_1 = require("./cli-handlers/checkpoint");
37
+ const diff_1 = require("./cli-handlers/diff");
38
+ const easter_egg_1 = require("./cli-handlers/easter-egg");
36
39
  const client_1 = require("./client");
37
40
  const config_1 = require("./config");
38
41
  const menu_1 = require("./menu");
@@ -40,9 +43,6 @@ const project_files_1 = require("./project-files");
40
43
  const spinner_1 = require("./utils/spinner");
41
44
  const terminal_1 = require("./utils/terminal");
42
45
  const web_scraper_1 = require("./web-scraper");
43
- const restoreCheckpointRegex = /^checkpoint\s+(\d+)$/;
44
- const undoCommands = ['undo', 'u'];
45
- const redoCommands = ['redo'];
46
46
  class CLI {
47
47
  client;
48
48
  readyPromise;
@@ -139,12 +139,22 @@ class CLI {
139
139
  /**
140
140
  * Prompts the user with a clean prompt state
141
141
  */
142
- freshPrompt() {
142
+ freshPrompt(userInput = '') {
143
143
  spinner_1.Spinner.get().stop();
144
144
  readline.cursorTo(process.stdout, 0);
145
- this.rl.line = '';
145
+ const rlAny = this.rl;
146
+ // clear line first
147
+ rlAny.line = '';
146
148
  this.setPrompt();
149
+ // then prompt
147
150
  this.rl.prompt();
151
+ if (!userInput) {
152
+ return;
153
+ }
154
+ // then rewrite new prompt
155
+ this.rl.write(' '.repeat(userInput.length)); // hacky way to move cursor
156
+ rlAny.line = userInput;
157
+ rlAny._refreshLine();
148
158
  }
149
159
  async printInitialPrompt(initialInput) {
150
160
  if (this.client.user) {
@@ -162,7 +172,7 @@ class CLI {
162
172
  }
163
173
  }
164
174
  async printDiff() {
165
- this.handleDiff();
175
+ (0, diff_1.handleDiff)(this.client.lastChanges);
166
176
  this.freshPrompt();
167
177
  }
168
178
  async handleLine(line) {
@@ -192,33 +202,8 @@ class CLI {
192
202
  }
193
203
  await this.forwardUserInput(userInput);
194
204
  }
195
- async saveCheckpoint(userInput) {
196
- if (checkpoint_manager_1.checkpointManager.disabledReason !== null) {
197
- return;
198
- }
199
- spinner_1.Spinner.get().start();
200
- await this.readyPromise;
201
- spinner_1.Spinner.get().stop();
202
- try {
203
- // Make sure the previous checkpoint is done
204
- await checkpoint_manager_1.checkpointManager.getLatestCheckpoint().fileStateIdPromise;
205
- }
206
- catch (error) {
207
- // No latest checkpoint available, no need to wait
208
- }
209
- // Save the current agent state
210
- try {
211
- const { checkpoint, created } = await checkpoint_manager_1.checkpointManager.addCheckpoint(this.client.agentState, this.client.lastToolResults, userInput);
212
- if (created) {
213
- console.log(`[checkpoint #${checkpoint.id} saved]`);
214
- }
215
- }
216
- catch (error) {
217
- // Unable to add checkpoint, do not display anything to user
218
- }
219
- }
220
205
  async processCommand(userInput) {
221
- if (userInput === 'help' || userInput === 'h') {
206
+ if (userInput === 'help' || userInput === 'h' || userInput === '/help') {
222
207
  (0, menu_1.displayMenu)();
223
208
  this.freshPrompt();
224
209
  return true;
@@ -238,10 +223,10 @@ class CLI {
238
223
  return true;
239
224
  }
240
225
  // Detect potential API key input first
241
- const detectionResult = this.detectApiKey(userInput);
226
+ const detectionResult = (0, api_key_1.detectApiKey)(userInput);
242
227
  if (detectionResult.status !== 'not_found') {
243
228
  // If something resembling an API key was detected (valid or just prefix), handle it
244
- await this.handleApiKeyInput(detectionResult);
229
+ await (0, api_key_1.handleApiKeyInput)(this.client, detectionResult, this.readyPromise, this.returnControlToUser.bind(this));
245
230
  return true; // Indicate command was handled
246
231
  }
247
232
  // Continue with other commands if no API key input was detected/handled
@@ -249,113 +234,68 @@ class CLI {
249
234
  await this.client.getUsage();
250
235
  return true;
251
236
  }
252
- if (undoCommands.includes(userInput)) {
253
- await this.saveCheckpoint(userInput);
254
- this.handleUndo();
255
- return true;
256
- }
257
- if (redoCommands.includes(userInput)) {
258
- await this.saveCheckpoint(userInput);
259
- this.handleRedo();
260
- return true;
261
- }
262
237
  if (userInput === 'quit' || userInput === 'exit' || userInput === 'q') {
263
238
  this.handleExit();
264
239
  return true;
265
240
  }
266
241
  if (['diff', 'doff', 'dif', 'iff', 'd'].includes(userInput)) {
267
- this.handleDiff();
242
+ (0, diff_1.handleDiff)(this.client.lastChanges);
268
243
  this.freshPrompt();
269
244
  return true;
270
245
  }
271
246
  if (userInput === 'uuddlrlrba' ||
272
247
  userInput === 'konami' ||
273
248
  userInput === 'codebuffy') {
274
- this.showEasterEgg();
249
+ (0, easter_egg_1.showEasterEgg)(this.returnControlToUser.bind(this));
275
250
  return true;
276
251
  }
277
252
  // Checkpoint commands
278
- if (userInput === 'checkpoint list' || userInput === 'checkpoints') {
279
- await this.saveCheckpoint(userInput);
280
- this.handleCheckpoints();
281
- return true;
282
- }
283
- const restoreMatch = userInput.match(restoreCheckpointRegex);
284
- if (restoreMatch) {
285
- const id = parseInt(restoreMatch[1], 10);
286
- await this.saveCheckpoint(userInput);
287
- await this.handleRestoreCheckpoint(id);
288
- return true;
289
- }
290
- if (userInput === 'checkpoint clear') {
291
- this.handleClearCheckpoints();
292
- return true;
293
- }
294
- return false;
295
- }
296
- /**
297
- * Detects if the user input contains a known API key pattern.
298
- * Returns information about the detected key or prefix.
299
- */
300
- detectApiKey(userInput) {
301
- // Build regex patterns for each key type
302
- const keyPatterns = constants_1.API_KEY_TYPES.map((keyType) => {
303
- const prefix = constants_1.KEY_PREFIXES[keyType];
304
- const length = constants_1.KEY_LENGTHS[keyType];
305
- const escapedPrefix = prefix.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
306
- return {
307
- type: keyType,
308
- prefix: prefix,
309
- length: length,
310
- // Regex to find the key potentially surrounded by whitespace or at start/end
311
- regex: new RegExp(`(?:^|\\s)(${escapedPrefix}[^\\s]{${length - prefix.length}})(?:\\s|$)`),
312
- };
313
- });
314
- // Test input against each pattern for a full match
315
- for (const patternInfo of keyPatterns) {
316
- const match = userInput.match(patternInfo.regex);
317
- if (match && match[1]) {
318
- // Found a full, valid key pattern
319
- return { status: 'found', type: patternInfo.type, key: match[1] };
253
+ if ((0, checkpoint_1.isCheckpointCommand)(userInput)) {
254
+ if ((0, checkpoint_1.isCheckpointCommand)(userInput, 'undo')) {
255
+ await (0, checkpoint_1.saveCheckpoint)(userInput, this.client, this.readyPromise);
256
+ const toRestore = await (0, checkpoint_1.handleUndo)(this.client, this.rl);
257
+ this.freshPrompt(toRestore);
258
+ return true;
320
259
  }
321
- }
322
- // If no full key matched, check if the input *starts* with any known prefix
323
- for (const patternInfo of keyPatterns) {
324
- if (userInput.includes(patternInfo.prefix)) {
325
- // Found a prefix, but it didn't match the full pattern (wrong length/format)
326
- return {
327
- status: 'prefix_only',
328
- type: patternInfo.type,
329
- prefix: patternInfo.prefix,
330
- length: patternInfo.length,
331
- };
260
+ if ((0, checkpoint_1.isCheckpointCommand)(userInput, 'redo')) {
261
+ await (0, checkpoint_1.saveCheckpoint)(userInput, this.client, this.readyPromise);
262
+ const toRestore = await (0, checkpoint_1.handleRedo)(this.client, this.rl);
263
+ this.freshPrompt(toRestore);
264
+ return true;
332
265
  }
266
+ if ((0, checkpoint_1.isCheckpointCommand)(userInput, 'list')) {
267
+ await (0, checkpoint_1.saveCheckpoint)(userInput, this.client, this.readyPromise);
268
+ await (0, checkpoint_1.listCheckpoints)();
269
+ this.freshPrompt();
270
+ return true;
271
+ }
272
+ const restoreMatch = (0, checkpoint_1.isCheckpointCommand)(userInput, 'restore');
273
+ if (restoreMatch) {
274
+ const id = parseInt(restoreMatch[1], 10);
275
+ await (0, checkpoint_1.saveCheckpoint)(userInput, this.client, this.readyPromise);
276
+ const toRestore = await (0, checkpoint_1.handleRestoreCheckpoint)(id, this.client, this.rl);
277
+ this.freshPrompt(toRestore);
278
+ return true;
279
+ }
280
+ if ((0, checkpoint_1.isCheckpointCommand)(userInput, 'clear')) {
281
+ (0, checkpoint_1.handleClearCheckpoints)();
282
+ this.freshPrompt();
283
+ return true;
284
+ }
285
+ if ((0, checkpoint_1.isCheckpointCommand)(userInput, 'save')) {
286
+ await (0, checkpoint_1.saveCheckpoint)(userInput, this.client, this.readyPromise, true);
287
+ (0, checkpoint_1.displayCheckpointMenu)();
288
+ this.freshPrompt();
289
+ return true;
290
+ }
291
+ (0, checkpoint_1.displayCheckpointMenu)();
292
+ this.freshPrompt();
293
+ return true;
333
294
  }
334
- // No valid key or known prefix detected
335
- return { status: 'not_found' };
336
- }
337
- /**
338
- * Handles the result of API key detection.
339
- */
340
- async handleApiKeyInput(detectionResult) {
341
- switch (detectionResult.status) {
342
- case 'found':
343
- spinner_1.Spinner.get().start();
344
- await this.readyPromise;
345
- spinner_1.Spinner.get().stop();
346
- // Call the client method to add the valid key
347
- await this.client.handleAddApiKey(detectionResult.type, detectionResult.key);
348
- // Note: client.handleAddApiKey calls returnControlToUser internally
349
- break;
350
- case 'prefix_only':
351
- // Print the warning for incorrect format/length
352
- console.log((0, picocolors_1.yellow)(`Input looks like a ${detectionResult.type} API key but has the wrong length or format. Expected ${detectionResult.length} characters starting with "${detectionResult.prefix}".`));
353
- this.freshPrompt(); // Give the user a fresh prompt after the warning
354
- break;
355
- }
295
+ return false;
356
296
  }
357
297
  async forwardUserInput(userInput) {
358
- await this.saveCheckpoint(userInput);
298
+ await (0, checkpoint_1.saveCheckpoint)(userInput, this.client, this.readyPromise);
359
299
  spinner_1.Spinner.get().start();
360
300
  this.client.lastChanges = [];
361
301
  const urls = (0, web_scraper_1.parseUrlsFromContent)(userInput);
@@ -397,62 +337,6 @@ class CLI {
397
337
  console.log((0, picocolors_1.green)('\nReconnected!'));
398
338
  this.returnControlToUser();
399
339
  }
400
- async handleUndo() {
401
- let failed = false;
402
- try {
403
- await checkpoint_manager_1.checkpointManager.restoreUndoCheckpoint();
404
- }
405
- catch (error) {
406
- failed = true;
407
- if (error instanceof checkpoint_manager_1.CheckpointsDisabledError) {
408
- console.log((0, picocolors_1.red)(`Checkpoints not enabled: ${error.message}`));
409
- }
410
- else {
411
- console.log((0, picocolors_1.red)(`Unable to undo: ${error.message}`));
412
- }
413
- }
414
- let userInput = '';
415
- if (!failed) {
416
- const currentCheckpoint = checkpoint_manager_1.checkpointManager.checkpoints[checkpoint_manager_1.checkpointManager.currentCheckpointId - 1];
417
- // Restore the agentState
418
- this.client.agentState = JSON.parse(currentCheckpoint.agentStateString);
419
- this.client.lastToolResults = JSON.parse(currentCheckpoint.lastToolResultsString);
420
- console.log((0, picocolors_1.green)(`Checkpoint #${checkpoint_manager_1.checkpointManager.currentCheckpointId} restored.`));
421
- userInput =
422
- checkpoint_manager_1.checkpointManager.checkpoints[checkpoint_manager_1.checkpointManager.currentCheckpointId - 1]
423
- ?.userInput ?? '';
424
- }
425
- this.freshPrompt();
426
- this.restoreUserInput(userInput);
427
- }
428
- async handleRedo() {
429
- let failed = false;
430
- try {
431
- await checkpoint_manager_1.checkpointManager.restoreRedoCheckpoint();
432
- }
433
- catch (error) {
434
- failed = true;
435
- if (error instanceof checkpoint_manager_1.CheckpointsDisabledError) {
436
- console.log((0, picocolors_1.red)(`Checkpoints not enabled: ${error.message}`));
437
- }
438
- else {
439
- console.log((0, picocolors_1.red)(`Unable to redo: ${error.message}`));
440
- }
441
- }
442
- let userInput = '';
443
- if (!failed) {
444
- const currentCheckpoint = checkpoint_manager_1.checkpointManager.checkpoints[checkpoint_manager_1.checkpointManager.currentCheckpointId - 1];
445
- // Restore the agentState
446
- this.client.agentState = JSON.parse(currentCheckpoint.agentStateString);
447
- this.client.lastToolResults = JSON.parse(currentCheckpoint.lastToolResultsString);
448
- console.log((0, picocolors_1.green)(`Checkpoint #${checkpoint_manager_1.checkpointManager.currentCheckpointId} restored.`));
449
- userInput =
450
- checkpoint_manager_1.checkpointManager.checkpoints[checkpoint_manager_1.checkpointManager.currentCheckpointId - 1]
451
- ?.userInput ?? '';
452
- }
453
- this.freshPrompt();
454
- this.restoreUserInput(userInput);
455
- }
456
340
  handleKeyPress(str, key) {
457
341
  if (key.name === 'escape') {
458
342
  this.handleEscKey();
@@ -508,127 +392,6 @@ class CLI {
508
392
  }
509
393
  spinner_1.Spinner.get().stop();
510
394
  }
511
- async showEasterEgg() {
512
- const text = 'codebuffy';
513
- // Utility: clear the terminal screen
514
- function clearScreen() {
515
- process.stdout.write('\u001b[2J\u001b[0;0H');
516
- }
517
- const termWidth = process.stdout.columns;
518
- const termHeight = process.stdout.rows;
519
- const baselineWidth = 80;
520
- const baselineHeight = 24;
521
- const scaleFactor = Math.min(termWidth / baselineWidth, termHeight / baselineHeight);
522
- // Utility: Generate a set of points tracing a "C" shape using an arc.
523
- function generateCPath(cx, cy, r, steps) {
524
- const points = [];
525
- // A typical "C" opens to the right: from 45° to 315° (in radians)
526
- const startAngle = Math.PI / 4;
527
- const endAngle = (7 * Math.PI) / 4;
528
- const angleStep = (endAngle - startAngle) / steps;
529
- for (let i = 0; i <= steps; i++) {
530
- const angle = startAngle + i * angleStep;
531
- const x = Math.floor(cx + r * Math.cos(angle));
532
- const y = Math.floor(cy + r * Math.sin(angle));
533
- points.push({ x, y });
534
- }
535
- return points;
536
- }
537
- // Utility: Generate points along a quadratic Bézier curve.
538
- function quadraticBezier(P0, P1, P2, steps) {
539
- const points = [];
540
- for (let i = 0; i <= steps; i++) {
541
- const t = i / steps;
542
- const x = Math.round((1 - t) ** 2 * P0.x + 2 * (1 - t) * t * P1.x + t ** 2 * P2.x);
543
- const y = Math.round((1 - t) ** 2 * P0.y + 2 * (1 - t) * t * P1.y + t ** 2 * P2.y);
544
- points.push({ x, y });
545
- }
546
- return points;
547
- }
548
- // Generate a vertical line from startY to endY at a given x.
549
- function generateVerticalLine(x, startY, endY) {
550
- const points = [];
551
- const step = startY < endY ? 1 : -1;
552
- for (let y = startY; y !== endY; y += step) {
553
- points.push({ x, y });
554
- }
555
- points.push({ x, y: endY });
556
- return points;
557
- }
558
- // Generate a path approximating a B shape using two quadratic Bézier curves
559
- // for the rounded bubbles, and then closing the shape with a vertical spine.
560
- function generateBPath(bX, bYTop, bYBottom, bWidth, bGap, stepsPerCurve) {
561
- let points = [];
562
- const middle = Math.floor((bYTop + bYBottom) / 2);
563
- // Upper bubble: from top-left (spine) out then back to the spine at the middle.
564
- const upperStart = { x: bX, y: bYTop };
565
- const upperControl = {
566
- x: bX + bWidth + bGap - 10,
567
- y: Math.floor((bYTop + middle) / 2),
568
- };
569
- const upperEnd = { x: bX, y: middle };
570
- const upperCurve = quadraticBezier(upperStart, upperControl, upperEnd, stepsPerCurve);
571
- // Lower bubble: from the middle to the bottom.
572
- const lowerStart = { x: bX, y: middle };
573
- const lowerControl = {
574
- x: bX + bWidth + bGap,
575
- y: Math.floor((middle + bYBottom) / 2),
576
- };
577
- const lowerEnd = { x: bX, y: bYBottom };
578
- const lowerCurve = quadraticBezier(lowerStart, lowerControl, lowerEnd, stepsPerCurve);
579
- // Combine the curves.
580
- points = points.concat(upperCurve, lowerCurve);
581
- // Add a vertical line from the bottom of the B back up to the top.
582
- const closingLine = generateVerticalLine(bX, bYBottom, bYTop);
583
- points = points.concat(closingLine);
584
- return points;
585
- }
586
- // Dynamically scale parameters for the shapes.
587
- // Use Math.max to ensure values don't get too small.
588
- const cCenterX = Math.floor(termWidth * 0.3);
589
- const cCenterY = Math.floor(termHeight / 2);
590
- const cRadius = Math.max(2, Math.floor(8 * scaleFactor));
591
- const cSteps = Math.max(10, Math.floor(30 * scaleFactor));
592
- const bX = Math.floor(termWidth * 0.55);
593
- const bYTop = Math.floor(termHeight / 2 - 7 * scaleFactor);
594
- const bYBottom = Math.floor(termHeight / 2 + 7 * scaleFactor);
595
- const bWidth = Math.max(2, Math.floor(8 * scaleFactor));
596
- const bGap = Math.max(1, Math.floor(35 * scaleFactor));
597
- const bStepsPerCurve = Math.max(10, Math.floor(20 * scaleFactor));
598
- // Generate the paths.
599
- const fullPath = [
600
- ...generateCPath(cCenterX, cCenterY, cRadius, cSteps),
601
- ...generateBPath(bX, bYTop, bYBottom, bWidth, bGap, bStepsPerCurve),
602
- ];
603
- // Array of picocolors functions for random colors.
604
- const colors = [picocolors_1.red, picocolors_1.green, picocolors_1.yellow, picocolors_1.blue, picocolors_1.magenta, picocolors_1.cyan];
605
- function getRandomColor() {
606
- return colors[Math.floor(Math.random() * colors.length)];
607
- }
608
- // Animation state: index into the fullPath.
609
- let index = 0;
610
- let completedCycle = false;
611
- // Main animation function
612
- function animate() {
613
- if (index >= fullPath.length) {
614
- completedCycle = true;
615
- return;
616
- }
617
- const { x, y } = fullPath[index];
618
- const cursorPosition = `\u001b[${y + 1};${x + 1}H`;
619
- process.stdout.write(cursorPosition + getRandomColor()(text));
620
- index++;
621
- }
622
- clearScreen();
623
- const interval = setInterval(() => {
624
- animate();
625
- if (completedCycle) {
626
- clearInterval(interval);
627
- clearScreen();
628
- this.returnControlToUser();
629
- }
630
- }, 100);
631
- }
632
395
  handleExit() {
633
396
  spinner_1.Spinner.get().restoreCursor();
634
397
  console.log('\n');
@@ -645,14 +408,15 @@ class CLI {
645
408
  }
646
409
  }
647
410
  const logMessages = [];
648
- const totalCredits = Object.values(this.client.creditsByPromptId)
411
+ const totalCreditsUsedThisSession = Object.values(this.client.creditsByPromptId)
649
412
  .flat()
650
413
  .reduce((sum, credits) => sum + credits, 0);
651
- logMessages.push(`${(0, string_1.pluralize)(totalCredits, 'credit')} used this session.`);
652
- if (this.client.limit && this.client.usage && this.client.nextQuotaReset) {
653
- const daysUntilReset = Math.max(0, Math.floor((this.client.nextQuotaReset.getTime() - Date.now()) /
654
- (1000 * 60 * 60 * 24)));
655
- logMessages.push(`${Math.max(0, this.client.limit - this.client.usage)} credits remaining. Renews in ${(0, string_1.pluralize)(daysUntilReset, 'day')}.`);
414
+ logMessages.push(`${(0, string_1.pluralize)(totalCreditsUsedThisSession, 'credit')} used this session, ${this.client.usageData.remainingBalance.toLocaleString()} credits left.`);
415
+ if (this.client.usageData.next_quota_reset) {
416
+ const daysUntilReset = Math.ceil((new Date(this.client.usageData.next_quota_reset).getTime() -
417
+ Date.now()) /
418
+ (1000 * 60 * 60 * 24));
419
+ logMessages.push(`Your free credits will reset in ${(0, string_1.pluralize)(daysUntilReset, 'day')}.`);
656
420
  }
657
421
  console.log(logMessages.join(' '));
658
422
  console.log((0, picocolors_1.green)('Codebuff out!'));
@@ -675,97 +439,6 @@ class CLI {
675
439
  }
676
440
  this.lastInputTime = currentTime;
677
441
  }
678
- handleDiff() {
679
- if (this.client.lastChanges.length === 0) {
680
- console.log((0, picocolors_1.yellow)('No changes found in the last assistant response.'));
681
- return;
682
- }
683
- this.client.lastChanges.forEach((change) => {
684
- console.log((0, picocolors_1.bold)(`___${change.path}___`));
685
- const lines = change.content
686
- .split('\n')
687
- .map((line) => (change.type === 'file' ? '+' + line : line));
688
- lines.forEach((line) => {
689
- if (line.startsWith('+')) {
690
- console.log((0, picocolors_1.green)(line));
691
- }
692
- else if (line.startsWith('-')) {
693
- console.log((0, picocolors_1.red)(line));
694
- }
695
- else if (line.startsWith('@@')) {
696
- console.log((0, picocolors_1.cyan)(line));
697
- }
698
- else {
699
- console.log(line);
700
- }
701
- });
702
- });
703
- }
704
- // Checkpoint command handlers
705
- async handleCheckpoints() {
706
- console.log(checkpoint_manager_1.checkpointManager.getCheckpointsAsString());
707
- this.freshPrompt();
708
- }
709
- async handleRestoreCheckpoint(id) {
710
- spinner_1.Spinner.get().start();
711
- if (checkpoint_manager_1.checkpointManager.disabledReason !== null) {
712
- console.log((0, picocolors_1.red)(`Checkpoints not enabled: ${checkpoint_manager_1.checkpointManager.disabledReason}`));
713
- this.freshPrompt();
714
- return;
715
- }
716
- const checkpoint = checkpoint_manager_1.checkpointManager.checkpoints[id - 1];
717
- if (!checkpoint) {
718
- console.log((0, picocolors_1.red)(`Checkpoint #${id} not found.`));
719
- this.freshPrompt();
720
- return;
721
- }
722
- try {
723
- // Wait for save before trying to restore checkpoint
724
- const latestCheckpoint = checkpoint_manager_1.checkpointManager.getLatestCheckpoint();
725
- await latestCheckpoint?.fileStateIdPromise;
726
- }
727
- catch (error) {
728
- // Should never happen
729
- }
730
- // Restore the agentState
731
- this.client.agentState = JSON.parse(checkpoint.agentStateString);
732
- this.client.lastToolResults = JSON.parse(checkpoint.lastToolResultsString);
733
- let failed = false;
734
- try {
735
- // Restore file state
736
- await checkpoint_manager_1.checkpointManager.restoreCheckointFileState({
737
- id: checkpoint.id,
738
- resetUndoIds: true,
739
- });
740
- }
741
- catch (error) {
742
- failed = true;
743
- spinner_1.Spinner.get().stop();
744
- console.log((0, picocolors_1.red)(`Unable to restore checkpoint: ${error.message}`));
745
- }
746
- if (!failed) {
747
- spinner_1.Spinner.get().stop();
748
- console.log((0, picocolors_1.green)(`Restored to checkpoint #${id}.`));
749
- }
750
- // Insert the original user input that created this checkpoint
751
- this.freshPrompt();
752
- this.restoreUserInput(checkpoint.userInput);
753
- }
754
- restoreUserInput(userInput) {
755
- if (!userInput.match(restoreCheckpointRegex) &&
756
- !undoCommands.includes(userInput) &&
757
- !redoCommands.includes(userInput)) {
758
- this.rl.write(' '.repeat(userInput.length)); // hacky way to move cursor
759
- const rlAny = this.rl;
760
- rlAny.line = userInput;
761
- rlAny._refreshLine();
762
- }
763
- }
764
- async handleClearCheckpoints() {
765
- checkpoint_manager_1.checkpointManager.clearCheckpoints();
766
- console.log('Cleared all checkpoints.');
767
- this.freshPrompt();
768
- }
769
442
  }
770
443
  exports.CLI = CLI;
771
444
  //# sourceMappingURL=cli.js.map