@oxecli/oxe 1.0.19 → 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;
@@ -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.20",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },