@oxecli/oxe 1.0.4 → 1.0.5
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/cli.js +5 -2
- package/dist/config.js +2 -2
- package/dist/engine.js +1 -0
- package/dist/ui.js +35 -14
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -189,9 +189,12 @@ export class CLI {
|
|
|
189
189
|
this.sessionId = sid;
|
|
190
190
|
engine.reasoningEffort = String(rec["reasoning_effort"] ?? default_reasoning_effort);
|
|
191
191
|
clearScreen();
|
|
192
|
-
renderPanel(
|
|
192
|
+
renderPanel("AI CODING AGENT", "", `Engine: Ready ${sid}`, false);
|
|
193
|
+
process.stdout.write("\n");
|
|
193
194
|
process.stdout.write(`\x1b[2mResumed:\x1b[0m ${truncateLabel(rec["label"])}\n`);
|
|
194
|
-
process.stdout.write(
|
|
195
|
+
process.stdout.write("\n");
|
|
196
|
+
process.stdout.write(`\x1b[2m(${this.inputItems.length} items · ${estimateTokens(this.inputItems).toLocaleString()} tokens · Effort: \x1b[1;36m${engine.reasoningEffort}\x1b[0m\x1b[2m)\x1b[0m\n`);
|
|
197
|
+
process.stdout.write("\n");
|
|
195
198
|
renderPanel("Conversation history", "Restored");
|
|
196
199
|
process.stdout.write("\n");
|
|
197
200
|
if (this.story.length)
|
package/dist/config.js
CHANGED
|
@@ -209,7 +209,7 @@ export async function loadOrPrompt() {
|
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
211
|
/**
|
|
212
|
-
* Prompt for
|
|
212
|
+
* Prompt for an API key, echoing what the user types.
|
|
213
213
|
* Falls back to a plain readline read when stdin isn't a TTY (e.g. piped input).
|
|
214
214
|
*/
|
|
215
215
|
export async function promptApiKey(prompt) {
|
|
@@ -262,7 +262,7 @@ export async function promptApiKey(prompt) {
|
|
|
262
262
|
if (b < 32)
|
|
263
263
|
continue;
|
|
264
264
|
input += String.fromCharCode(b);
|
|
265
|
-
process.stdout.write(
|
|
265
|
+
process.stdout.write(String.fromCharCode(b));
|
|
266
266
|
}
|
|
267
267
|
};
|
|
268
268
|
const cleanup = () => {
|
package/dist/engine.js
CHANGED
package/dist/ui.js
CHANGED
|
@@ -392,13 +392,7 @@ export function renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor
|
|
|
392
392
|
const cursorRow = row + 1;
|
|
393
393
|
const cursorCol = col + prefix.length + 3;
|
|
394
394
|
const totalRows = body.length + 2;
|
|
395
|
-
|
|
396
|
-
if (totalRows - 1 > cursorRow)
|
|
397
|
-
cmd += `\x1b[${totalRows - 1 - cursorRow}A`;
|
|
398
|
-
else if (cursorRow > totalRows - 1)
|
|
399
|
-
cmd += `\x1b[${cursorRow - (totalRows - 1)}B`;
|
|
400
|
-
cmd += `\r\x1b[${cursorCol}C`;
|
|
401
|
-
return frame + cmd;
|
|
395
|
+
return { frame, cursorRow, cursorCol, totalRows };
|
|
402
396
|
}
|
|
403
397
|
export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
404
398
|
return new Promise((resolve, reject) => {
|
|
@@ -425,19 +419,46 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
425
419
|
process.stdin.setRawMode(true);
|
|
426
420
|
process.stdin.resume();
|
|
427
421
|
let done = false;
|
|
422
|
+
let lastCursorRow = 0;
|
|
423
|
+
let lastTotalRows = 0;
|
|
428
424
|
const finish = (resolveVal) => {
|
|
429
425
|
if (done)
|
|
430
426
|
return;
|
|
431
427
|
done = true;
|
|
432
428
|
process.stdin.setRawMode(false);
|
|
433
|
-
|
|
434
|
-
|
|
429
|
+
// Erase the whole prompt box (which occupies `lastTotalRows` lines) so no
|
|
430
|
+
// frame borders are left behind, then leave the cursor on the box's top
|
|
431
|
+
// row (a blank line). That way the caller's single leading newline yields
|
|
432
|
+
// exactly ONE blank row before the echoed user prompt — never two.
|
|
433
|
+
process.stdout.write(`\x1b[${lastCursorRow}A`);
|
|
434
|
+
for (let i = 0; i < lastTotalRows; i++) {
|
|
435
|
+
process.stdout.write("\r\x1b[K");
|
|
436
|
+
if (i < lastTotalRows - 1)
|
|
437
|
+
process.stdout.write("\n");
|
|
438
|
+
}
|
|
439
|
+
// Cursor is now on the last box row; move back up to the box's top row.
|
|
440
|
+
if (lastTotalRows > 1)
|
|
441
|
+
process.stdout.write(`\x1b[${lastTotalRows - 1}A`);
|
|
435
442
|
resolve(resolveVal);
|
|
436
443
|
};
|
|
437
|
-
const repaint = () => {
|
|
438
|
-
const frame = renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor);
|
|
439
|
-
|
|
440
|
-
|
|
444
|
+
const repaint = (isFirst = false) => {
|
|
445
|
+
const { frame, cursorRow, cursorCol, totalRows } = renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor);
|
|
446
|
+
lastCursorRow = cursorRow;
|
|
447
|
+
lastTotalRows = totalRows;
|
|
448
|
+
const frameLines = frame.split("\n");
|
|
449
|
+
if (!isFirst) {
|
|
450
|
+
// Cursor currently sits at cursorRow (inside the box). Move to the top
|
|
451
|
+
// border, then clear+rewrite each line so old content is fully removed.
|
|
452
|
+
process.stdout.write(`\x1b[${cursorRow}A`);
|
|
453
|
+
}
|
|
454
|
+
for (let i = 0; i < frameLines.length; i++) {
|
|
455
|
+
process.stdout.write("\r\x1b[K" + frameLines[i]);
|
|
456
|
+
if (i < frameLines.length - 1)
|
|
457
|
+
process.stdout.write("\n");
|
|
458
|
+
}
|
|
459
|
+
// Reposition the cursor inside the box.
|
|
460
|
+
const fromBottom = totalRows - 1 - cursorRow;
|
|
461
|
+
process.stdout.write(`\x1b[${fromBottom}A\r\x1b[${cursorCol}C`);
|
|
441
462
|
};
|
|
442
463
|
const insert = (text) => {
|
|
443
464
|
if (histIdx !== hist.length) {
|
|
@@ -559,7 +580,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
559
580
|
}
|
|
560
581
|
};
|
|
561
582
|
process.stdin.on("keypress", onKeypress);
|
|
562
|
-
repaint();
|
|
583
|
+
repaint(true);
|
|
563
584
|
});
|
|
564
585
|
}
|
|
565
586
|
// ---------------------------------------------------------------------------
|