@oxecli/oxe 1.0.18 → 1.0.20

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/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;
@@ -961,6 +970,41 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
961
970
  }
962
971
  }
963
972
  };
973
+ const isNewlineKey = (key) => {
974
+ if (!key)
975
+ return false;
976
+ // Bare \n / Ctrl+J = newline.
977
+ if (key.name === "enter")
978
+ return true;
979
+ // Enter with a modifier (Shift/Ctrl/Alt/Meta) = newline.
980
+ if (key.name === "return")
981
+ return !!(key.shift || key.ctrl || key.meta);
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.
985
+ const seq = key.sequence || "";
986
+ if (/^\x1b\[13;([2-9]|\d{2,})u$/.test(seq))
987
+ return true;
988
+ if (/^\x1b\[13;([2-9]|\d{2,})~$/.test(seq))
989
+ return true;
990
+ // Legacy Shift+Enter decoded by Node as F3 with shift.
991
+ if (key.name === "f3" && key.shift)
992
+ return true;
993
+ return false;
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
+ };
964
1008
  const onKeypress = (str, key) => {
965
1009
  if (key && key.ctrl && key.name === "c") {
966
1010
  settle(new Error("interrupt"), true);
@@ -970,12 +1014,20 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
970
1014
  settle(new Error("eof"), true);
971
1015
  return;
972
1016
  }
973
- if (key && key.name === "return") {
1017
+ // Plain Enter submits; any modified Enter (Shift/Ctrl+Enter) inserts a
1018
+ // newline, mirroring the Python original's _read_input_event (which maps
1019
+ // \x1b[13;2u / \x1b[13;5u / Shift+\r to "\n").
1020
+ if (isSubmitEnterKey(key)) {
974
1021
  if (buffer.trim()) {
975
1022
  settle([buffer, pasteSpans], false);
976
1023
  }
977
1024
  return;
978
1025
  }
1026
+ if (isNewlineKey(key)) {
1027
+ insert("\n");
1028
+ repaint();
1029
+ return;
1030
+ }
979
1031
  if (key && key.name === "backspace") {
980
1032
  backspace();
981
1033
  repaint();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },