@oxecli/oxe 1.0.34 → 1.0.36

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
@@ -42,6 +42,20 @@ export class CLI {
42
42
  const style = status === "failed" ? "\x1b[31m" : "\x1b[32m";
43
43
  process.stdout.write(`${style}${truncateEllipsis(String(text), max_action_chars, "text")}\x1b[0m\n`);
44
44
  }
45
+ printAssistantBlock(text) {
46
+ const rendered = aiMarkdown(text);
47
+ process.stdout.write(rendered);
48
+ if (!text.endsWith("\n"))
49
+ process.stdout.write("\n");
50
+ }
51
+ printFooterAfter(text, footer) {
52
+ const trailing = text.match(/\n*$/)?.[0].length ?? 0;
53
+ if (trailing < 2)
54
+ process.stdout.write("\n".repeat(2 - trailing));
55
+ process.stdout.write(aiMarkdown(footer));
56
+ if (!footer.endsWith("\n"))
57
+ process.stdout.write("\n");
58
+ }
45
59
  async showHelp() {
46
60
  // Mirror Python's `_show_help`: a bordered table panel with the command
47
61
  // column bold (with `<arg>` placeholders cyan) and descriptions dim, inside
@@ -76,7 +90,9 @@ export class CLI {
76
90
  // clear downward so the whole panel disappears and the cursor lands back
77
91
  // on the fresh line before the prompt.
78
92
  const n = panel.split("\n").length;
79
- process.stdout.write(`\x1b[${n}A\r\x1b[J`);
93
+ // Include the leading separator row in the cleanup so the next prompt
94
+ // creates exactly one fresh separator instead of duplicating it.
95
+ process.stdout.write(`\x1b[${n + 1}A\r\x1b[J`);
80
96
  }
81
97
  }
82
98
  async awaitRawCloseKey() {
@@ -141,13 +157,12 @@ export class CLI {
141
157
  process.stdout.write(`\x1b[1m❯\x1b[0m ${userDisplayText(payload, r["paste_spans"])}\n`);
142
158
  }
143
159
  else if (kind === "assistant") {
144
- process.stdout.write(aiMarkdown(payload) + "\n");
160
+ this.printAssistantBlock(payload);
145
161
  let footer = String(r["footer"] ?? "").trim();
146
162
  if (footer) {
147
163
  if (!footer.startsWith("("))
148
164
  footer = `(${footer})`;
149
- // Footer: labels white, only the backtick values grey (not the whole line).
150
- process.stdout.write("\n" + aiMarkdown(footer) + "\n");
165
+ this.printFooterAfter(payload, footer);
151
166
  }
152
167
  }
153
168
  else {
@@ -173,7 +188,7 @@ export class CLI {
173
188
  process.stdout.write(`\x1b[1m❯\x1b[0m ${userDisplayText(text, e["paste_spans"])}\n`);
174
189
  }
175
190
  else if (typ === "assistant") {
176
- process.stdout.write(aiMarkdown(text) + "\n");
191
+ this.printAssistantBlock(text);
177
192
  }
178
193
  else if (typ === "tool") {
179
194
  this.printToolEntry(e["started"], text, e["status"] ?? "");
package/dist/engine.js CHANGED
@@ -438,6 +438,10 @@ export class InferenceEngine {
438
438
  }
439
439
  async executeQuery(userPrompt, inputItems, story, pasteSpans) {
440
440
  this.inQuery = true;
441
+ // A completed status line belongs to the previous turn. Never let its
442
+ // replacement state reach the next user prompt.
443
+ this.workActive = false;
444
+ this.workRows = 0;
441
445
  this.interrupted = false;
442
446
  this.queryHasOutput = false;
443
447
  this.activeAbort = new AbortController();
@@ -552,6 +556,8 @@ export class InferenceEngine {
552
556
  dropRetryPrompts(conversation, inputItems, retryPrompts);
553
557
  process.stdout.write(aiMarkdown(emptyMessage) + "\n");
554
558
  process.stdout.write("\n" + summary() + "\n");
559
+ this.workActive = false;
560
+ this.workRows = 0;
555
561
  return;
556
562
  }
557
563
  if (!calls.length) {
@@ -560,6 +566,8 @@ export class InferenceEngine {
560
566
  story.push({ type: "footer", text: footerText() });
561
567
  attachFooter(conversation);
562
568
  attachFooter(inputItems);
569
+ this.workActive = false;
570
+ this.workRows = 0;
563
571
  return;
564
572
  }
565
573
  if (text.trim())
@@ -603,6 +611,10 @@ export class InferenceEngine {
603
611
  stripOrphanCalls(inputItems);
604
612
  }
605
613
  catch (err) {
614
+ if (this.interrupted) {
615
+ this.workActive = false;
616
+ this.workRows = 0;
617
+ }
606
618
  if (this.interrupted)
607
619
  throw new Error("interrupt");
608
620
  if (err?.message === "interrupt" || err?.message === "eof") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },