codebuff 1.0.219 → 1.0.221
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.
- package/dist/checkpoints/checkpoint-manager.d.ts +1 -1
- package/dist/checkpoints/checkpoint-manager.js +8 -6
- package/dist/checkpoints/checkpoint-manager.js.map +1 -1
- package/dist/cli-handlers/api-key.d.ts +25 -0
- package/dist/cli-handlers/api-key.js +66 -0
- package/dist/cli-handlers/api-key.js.map +1 -0
- package/dist/cli-handlers/checkpoint.d.ts +18 -0
- package/dist/cli-handlers/checkpoint.js +195 -0
- package/dist/cli-handlers/checkpoint.js.map +1 -0
- package/dist/cli-handlers/diff.d.ts +2 -0
- package/dist/cli-handlers/diff.js +31 -0
- package/dist/cli-handlers/diff.js.map +1 -0
- package/dist/cli-handlers/easter-egg.d.ts +1 -0
- package/dist/cli-handlers/easter-egg.js +126 -0
- package/dist/cli-handlers/easter-egg.js.map +1 -0
- package/dist/cli.d.ts +0 -18
- package/dist/cli.js +70 -397
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +11 -11
- package/dist/client.js +123 -45
- package/dist/client.js.map +1 -1
- package/dist/code-map/tsconfig.tsbuildinfo +1 -1
- package/dist/common/actions.d.ts +288 -264
- package/dist/common/actions.js +10 -4
- package/dist/common/actions.js.map +1 -1
- package/dist/common/advanced-analyzer.d.ts +19 -0
- package/dist/common/advanced-analyzer.js +140 -0
- package/dist/common/advanced-analyzer.js.map +1 -0
- package/dist/common/billing/auto-topup.d.ts +8 -0
- package/dist/common/billing/auto-topup.js +192 -0
- package/dist/common/billing/auto-topup.js.map +1 -0
- package/dist/common/billing/balance-calculator.d.ts +55 -0
- package/dist/common/billing/balance-calculator.js +207 -0
- package/dist/common/billing/balance-calculator.js.map +1 -0
- package/dist/common/billing/check-auto-topup.d.ts +12 -0
- package/dist/common/billing/check-auto-topup.js +50 -0
- package/dist/common/billing/check-auto-topup.js.map +1 -0
- package/dist/common/billing/conversion.d.ts +9 -0
- package/dist/common/billing/conversion.js +20 -0
- package/dist/common/billing/conversion.js.map +1 -0
- package/dist/common/billing/credit-check.d.ts +8 -0
- package/dist/common/billing/credit-check.js +45 -0
- package/dist/common/billing/credit-check.js.map +1 -0
- package/dist/common/billing/credit-conversion.d.ts +24 -0
- package/dist/common/billing/credit-conversion.js +48 -0
- package/dist/common/billing/credit-conversion.js.map +1 -0
- package/dist/common/billing/grant-credits.d.ts +28 -0
- package/dist/common/billing/grant-credits.js +201 -0
- package/dist/common/billing/grant-credits.js.map +1 -0
- package/dist/common/billing/plans.d.ts +13 -0
- package/dist/common/billing/plans.js +44 -0
- package/dist/common/billing/plans.js.map +1 -0
- package/dist/common/billing/rollover-logic.d.ts +13 -0
- package/dist/common/billing/rollover-logic.js +174 -0
- package/dist/common/billing/rollover-logic.js.map +1 -0
- package/dist/common/billing/stripe-api.d.ts +31 -0
- package/dist/common/billing/stripe-api.js +104 -0
- package/dist/common/billing/stripe-api.js.map +1 -0
- package/dist/common/browser-actions.d.ts +62 -62
- package/dist/common/constants/grant-priorities.d.ts +2 -0
- package/dist/common/constants/grant-priorities.js +10 -0
- package/dist/common/constants/grant-priorities.js.map +1 -0
- package/dist/common/constants.d.ts +28 -1
- package/dist/common/constants.js +36 -7
- package/dist/common/constants.js.map +1 -1
- package/dist/common/db/schema.d.ts +323 -86
- package/dist/common/db/schema.js +55 -13
- package/dist/common/db/schema.js.map +1 -1
- package/dist/common/env.mjs +4 -1
- package/dist/common/env.mjs.map +1 -1
- package/dist/common/message-image-handling.d.ts +41 -0
- package/dist/common/message-image-handling.js +57 -0
- package/dist/common/message-image-handling.js.map +1 -0
- package/dist/common/types/agent-state.d.ts +8 -8
- package/dist/common/types/grant.d.ts +2 -0
- package/dist/common/types/grant.js +10 -0
- package/dist/common/types/grant.js.map +1 -0
- package/dist/common/types/usage.d.ts +37 -18
- package/dist/common/types/usage.js +9 -6
- package/dist/common/types/usage.js.map +1 -1
- package/dist/common/util/__tests__/saxy.test.d.ts +1 -0
- package/dist/common/util/__tests__/saxy.test.js +262 -0
- package/dist/common/util/__tests__/saxy.test.js.map +1 -0
- package/dist/common/util/credentials.d.ts +2 -2
- package/dist/common/util/dates.d.ts +10 -1
- package/dist/common/util/dates.js +11 -2
- package/dist/common/util/dates.js.map +1 -1
- package/dist/common/util/logger.js +32 -14
- package/dist/common/util/logger.js.map +1 -1
- package/dist/common/util/process-stream.d.ts +8 -0
- package/dist/common/util/process-stream.js +102 -0
- package/dist/common/util/process-stream.js.map +1 -0
- package/dist/common/util/promise.d.ts +1 -1
- package/dist/common/util/promise.js +2 -2
- package/dist/common/util/promise.js.map +1 -1
- package/dist/common/util/referral-credits.d.ts +1 -0
- package/dist/common/util/referral-credits.js +48 -0
- package/dist/common/util/referral-credits.js.map +1 -0
- package/dist/common/util/saxy.d.ts +8 -0
- package/dist/common/util/saxy.js +35 -12
- package/dist/common/util/saxy.js.map +1 -1
- package/dist/common/util/sync-failure.d.ts +1 -0
- package/dist/common/util/sync-failure.js +57 -0
- package/dist/common/util/sync-failure.js.map +1 -0
- package/dist/common/websockets/websocket-schema.d.ts +530 -480
- package/dist/index.js +1 -1
- package/dist/utils/__tests__/xml-stream-parser.test.js +6 -10
- package/dist/utils/__tests__/xml-stream-parser.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/common/logger.d.ts +0 -1
- package/dist/common/logger.js +0 -7
- package/dist/common/logger.js.map +0 -1
- package/dist/common/util/constants.d.ts +0 -1
- package/dist/common/util/constants.js +0 -7
- package/dist/common/util/constants.js.map +0 -1
- package/dist/common/util/helpers.d.ts +0 -1
- package/dist/common/util/helpers.js +0 -6
- package/dist/common/util/helpers.js.map +0 -1
- package/dist/common/util/token-counter.d.ts +0 -3
- package/dist/common/util/token-counter.js +0 -27
- 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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
249
|
+
(0, easter_egg_1.showEasterEgg)(this.returnControlToUser.bind(this));
|
|
275
250
|
return true;
|
|
276
251
|
}
|
|
277
252
|
// Checkpoint commands
|
|
278
|
-
if (
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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)(
|
|
652
|
-
if (this.client.
|
|
653
|
-
const daysUntilReset = Math.
|
|
654
|
-
(
|
|
655
|
-
|
|
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
|