@oxecli/oxe 1.0.19 → 1.0.21

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
@@ -19,7 +19,6 @@ export class CLI {
19
19
  constructor() {
20
20
  clearScreen();
21
21
  renderPanel("AI CODING AGENT", "", "Engine: Ready", false);
22
- process.stdout.write("\n");
23
22
  this.config = null;
24
23
  }
25
24
  saveSession(engine) {
@@ -361,7 +360,6 @@ export class CLI {
361
360
  this.sessionId = null;
362
361
  clearScreen();
363
362
  renderPanel("AI CODING AGENT", "", "Engine: Ready", false);
364
- process.stdout.write("\n");
365
363
  continue;
366
364
  }
367
365
  if (lower.startsWith("/resume")) {
package/dist/config.js CHANGED
@@ -151,6 +151,10 @@ export async function loadOrPrompt() {
151
151
  let key_data = {};
152
152
  for (;;) {
153
153
  if (!api_key) {
154
+ // The CLI banner ends with a trailing newline; write one more blank so
155
+ // there is exactly one empty line between the banner and this panel
156
+ // (mirrors Python's console.print() after the banner).
157
+ process.stdout.write("\n");
154
158
  renderPanel("[bold white]Oxe Desktop Authentication[/bold white]\n\n" +
155
159
  `[dim]Only valid Oxe API keys (starting with [bold]${OXE_KEY_PREFIX}[/bold]) generated on your\n` +
156
160
  "Oxe web dashboard are authorized to run this agent.\n\n" +
package/dist/ui.js CHANGED
@@ -7,8 +7,12 @@ let rawKeyListeners = 0;
7
7
  export function enableRawStdin() {
8
8
  if (rawKeyListeners === 0) {
9
9
  readline.emitKeypressEvents(process.stdin);
10
- if (process.stdin.isTTY)
10
+ if (process.stdin.isTTY) {
11
11
  process.stdin.setRawMode(true);
12
+ // Enable the kitty keyboard protocol (CSI u) so modified Enter (Shift /
13
+ // Ctrl+Enter) arrives as \x1b[13;<mod>u rather than a plain \r.
14
+ process.stdout.write("\x1b[>1u");
15
+ }
12
16
  process.stdin.resume();
13
17
  hideCursor();
14
18
  }
@@ -725,8 +729,13 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
725
729
  let histIdx = hist.length;
726
730
  let draft = null;
727
731
  readline.emitKeypressEvents(process.stdin);
728
- if (process.stdin.isTTY)
732
+ if (process.stdin.isTTY) {
729
733
  process.stdin.setRawMode(true);
734
+ // Enable the kitty keyboard protocol (CSI u) so Windows Terminal / modern
735
+ // terminals send distinct sequences for Shift+Enter / Ctrl+Enter
736
+ // (\x1b[13;<mod>u) instead of an indistinguishable plain \r.
737
+ process.stdout.write("\x1b[>1u");
738
+ }
730
739
  process.stdin.resume();
731
740
  hideCursor();
732
741
  let done = false;
@@ -964,19 +973,38 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
964
973
  const isNewlineKey = (key) => {
965
974
  if (!key)
966
975
  return false;
976
+ // Bare \n / Ctrl+J = newline.
967
977
  if (key.name === "enter")
968
- return true; // bare \n / Ctrl+J
978
+ return true;
979
+ // Enter with a modifier (Shift/Ctrl/Alt/Meta) = newline.
969
980
  if (key.name === "return")
970
981
  return !!(key.shift || key.ctrl || key.meta);
971
- // Kitty-keyboard-protocol Shift/Ctrl+Enter (name is "undefined" in Node).
982
+ // Kitty-keyboard-protocol / CSI-u modified Enter: \x1b[13;<m>u where
983
+ // <m> is a modifier bitmask (2=Shift, 3=Alt, 5=Ctrl, 6=Shift+Ctrl, ...).
984
+ // Also the legacy \x1b[13;<m>~ form. ANY modifier > 1 on Enter = newline.
972
985
  const seq = key.sequence || "";
973
- if (seq === "\x1b[13;2u" || seq === "\x1b[13;5u" || seq === "\x1b[13;2~")
986
+ if (/^\x1b\[13;([2-9]|\d{2,})u$/.test(seq))
974
987
  return true;
975
- // Legacy Shift+Enter decoded as F3 with shift.
988
+ if (/^\x1b\[13;([2-9]|\d{2,})~$/.test(seq))
989
+ return true;
990
+ // Legacy Shift+Enter decoded by Node as F3 with shift.
976
991
  if (key.name === "f3" && key.shift)
977
992
  return true;
978
993
  return false;
979
994
  };
995
+ // True for a plain (unmodified) Enter: Node's "return" without modifiers,
996
+ // or the kitty-protocol encodings \x1b[13u / \x1b[13;1u (modifier flags = 1
997
+ // meaning none).
998
+ const isSubmitEnterKey = (key) => {
999
+ if (!key)
1000
+ return false;
1001
+ if (key.name === "return" && !(key.shift || key.ctrl || key.meta))
1002
+ return true;
1003
+ const seq = key.sequence || "";
1004
+ if (seq === "\x1b[13u" || /^\x1b\[13;1u$/.test(seq))
1005
+ return true;
1006
+ return false;
1007
+ };
980
1008
  const onKeypress = (str, key) => {
981
1009
  if (key && key.ctrl && key.name === "c") {
982
1010
  settle(new Error("interrupt"), true);
@@ -989,7 +1017,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
989
1017
  // Plain Enter submits; any modified Enter (Shift/Ctrl+Enter) inserts a
990
1018
  // newline, mirroring the Python original's _read_input_event (which maps
991
1019
  // \x1b[13;2u / \x1b[13;5u / Shift+\r to "\n").
992
- if (key && key.name === "return" && !(key.shift || key.ctrl || key.meta)) {
1020
+ if (isSubmitEnterKey(key)) {
993
1021
  if (buffer.trim()) {
994
1022
  settle([buffer, pasteSpans], false);
995
1023
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },