@oxecli/oxe 1.0.0 → 1.0.1

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 CHANGED
@@ -271,7 +271,17 @@ export class CLI {
271
271
  export async function main() {
272
272
  enableAnsi();
273
273
  const app = new CLI();
274
- const config = await loadOrPrompt();
274
+ let config;
275
+ try {
276
+ config = await loadOrPrompt();
277
+ }
278
+ catch (err) {
279
+ if (err?.message === "interrupt" || err?.message === "eof") {
280
+ process.stdout.write("\nClosing terminal session. Goodbye!\n");
281
+ return;
282
+ }
283
+ throw err;
284
+ }
275
285
  app.config = config;
276
286
  const engine = new InferenceEngine(config);
277
287
  try {
package/dist/oxe.js CHANGED
@@ -1,6 +1,11 @@
1
1
  import { main } from "./cli.js";
2
2
  export { main };
3
3
  main().catch((err) => {
4
+ const msg = err?.message;
5
+ if (msg === "interrupt" || msg === "eof") {
6
+ // Graceful exit on Ctrl+C / Ctrl+D — no stack trace.
7
+ process.exit(0);
8
+ }
4
9
  console.error(err);
5
10
  process.exit(1);
6
11
  });
package/dist/ui.js CHANGED
@@ -324,7 +324,10 @@ export function splitBlocks(buffer, pasteSpans) {
324
324
  }
325
325
  return segs;
326
326
  }
327
- function renderBufferWithCursor(buffer, pasteSpans, prefix, cursor) {
327
+ function renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor) {
328
+ const w = terminalWidth();
329
+ const innerW = Math.max(w - 4, 10);
330
+ const border = "─".repeat(innerW);
328
331
  const [row, col] = cursorLineCol(buffer, cursor);
329
332
  const segs = splitBlocks(buffer, pasteSpans);
330
333
  let display = "";
@@ -334,23 +337,39 @@ function renderBufferWithCursor(buffer, pasteSpans, prefix, cursor) {
334
337
  display += " ";
335
338
  display += kind === "collapsed" ? `\x1b[1m\x1b[36m${disp}\x1b[0m` : disp;
336
339
  }
337
- const lines = display.split("\n");
338
340
  const prefixStr = `\x1b[1m${prefix}\x1b[0m `;
339
- // Reconstruct lines, prepending prefix to first line
340
- const rendered = [prefixStr + (lines[0] ?? "")];
341
- for (let i = 1; i < lines.length; i++)
342
- rendered.push(lines[i] ?? "");
343
- // Place cursor on the correct line/col (prefix+1 offset on line 0)
341
+ const innerLines = (prefixStr + display).split("\n");
342
+ // Build the panel lines, each padded to innerW.
343
+ const lines = [];
344
+ for (const l of innerLines) {
345
+ const plain = l.replace(/\x1b\[[0-9;]*m/g, "");
346
+ const pad = Math.max(innerW - 1 - plain.length, 0);
347
+ lines.push(`\x1b[90m│\x1b[0m ${l}${" ".repeat(pad)} \x1b[90m│\x1b[0m`);
348
+ }
349
+ // Placeholder row when empty
350
+ if (!buffer) {
351
+ const ph = `\x1b[2m${PROMPT_PLACEHOLDER}\x1b[0m`;
352
+ const pad = Math.max(innerW - 1 - PROMPT_PLACEHOLDER.length, 0);
353
+ lines.push(`\x1b[90m│\x1b[0m ${ph}${" ".repeat(pad)} \x1b[90m│\x1b[0m`);
354
+ }
355
+ const frame = [
356
+ `\x1b[90m┌─${label}─${border.slice(label.length + 2)}┐\x1b[0m`,
357
+ ...lines,
358
+ `\x1b[90m└${border}┘\x1b[0m`,
359
+ ].join("\n");
360
+ // Compute where the cursor should be placed.
344
361
  let cursorRow = row;
345
362
  let cursorCol = col + (row === 0 ? prefix.length + 1 : 0);
346
- const result = rendered.join("\n");
347
- const currentLines = result.split("\n").length;
348
- // Move cursor up currentLines-1 then right cursorCol
363
+ // +1 row for the top border.
364
+ cursorRow += 1;
365
+ const totalRows = frame.split("\n").length;
349
366
  let cmd = "";
350
- if (currentLines > 1)
351
- cmd += `\x1b[${currentLines - 1}A`;
352
- cmd += `\r\x1b[${cursorCol}C`;
353
- return result + cmd;
367
+ if (totalRows - 1 > cursorRow)
368
+ cmd += `\x1b[${totalRows - 1 - cursorRow}A`;
369
+ else if (cursorRow > totalRows - 1)
370
+ cmd += `\x1b[${cursorRow - (totalRows - 1)}B`;
371
+ cmd += `\r\x1b[${cursorCol + 2}C`;
372
+ return frame + cmd;
354
373
  }
355
374
  export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
356
375
  return new Promise((resolve, reject) => {
@@ -387,7 +406,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
387
406
  resolve(resolveVal);
388
407
  };
389
408
  const repaint = () => {
390
- const frame = renderBufferWithCursor(buffer, pasteSpans, prefix, cursor);
409
+ const frame = renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor);
391
410
  process.stdout.write("\r\x1b[K");
392
411
  process.stdout.write(frame);
393
412
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },