codeam-cli 1.3.3 → 1.3.5

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.
Files changed (2) hide show
  1. package/dist/index.js +48 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -114,7 +114,7 @@ var import_picocolors = __toESM(require("picocolors"));
114
114
  // package.json
115
115
  var package_default = {
116
116
  name: "codeam-cli",
117
- version: "1.3.3",
117
+ version: "1.3.5",
118
118
  description: "Remote control Claude Code from your mobile device",
119
119
  main: "dist/index.js",
120
120
  bin: {
@@ -710,6 +710,10 @@ var ClaudeService = class {
710
710
  this.proc?.stdin?.write("\r");
711
711
  }, index * ARROW_MS + ENTER_MS);
712
712
  }
713
+ /** Send Escape key to Claude (cancels interactive prompts). */
714
+ sendEscape() {
715
+ this.proc?.stdin?.write("\x1B");
716
+ }
713
717
  /** Send Ctrl+C to Claude. */
714
718
  interrupt() {
715
719
  this.proc?.stdin?.write("");
@@ -875,23 +879,49 @@ function renderToLines(raw) {
875
879
  function detectSelector(lines) {
876
880
  if (lines.some((l) => /\?\s+for\s+shortcuts/i.test(l.trim()))) return null;
877
881
  if (!lines.some((l) => /^❯\s*\d+\./.test(l.trim()))) return null;
878
- const optionMap = /* @__PURE__ */ new Map();
879
- let question = "";
880
- for (const line of lines) {
881
- const t = line.trim();
882
+ let optionStartIdx = -1;
883
+ for (let i = 0; i < lines.length; i++) {
884
+ if (/^(?:❯\s*)?\d+\.\s/.test(lines[i].trim())) {
885
+ optionStartIdx = i;
886
+ break;
887
+ }
888
+ }
889
+ if (optionStartIdx === -1) return null;
890
+ const questionParts = [];
891
+ for (let i = 0; i < optionStartIdx; i++) {
892
+ const t = lines[i].trim();
893
+ if (!t) continue;
894
+ if (/^[─━—═\-]{3,}$/.test(t)) continue;
895
+ if (/^\[.*\]$/.test(t)) continue;
896
+ if (/^[>❯]\s/.test(t)) continue;
897
+ questionParts.push(t);
898
+ }
899
+ const question = questionParts.join(" ").trim();
900
+ const optionLabels = /* @__PURE__ */ new Map();
901
+ const optionDescs = /* @__PURE__ */ new Map();
902
+ let currentNum = -1;
903
+ for (let i = optionStartIdx; i < lines.length; i++) {
904
+ const t = lines[i].trim();
882
905
  if (!t) continue;
883
906
  const m = t.match(/^(?:❯\s*)?(\d+)\.\s+(.+)/);
884
907
  if (m) {
885
908
  const num = parseInt(m[1], 10);
886
- const label = m[2].trim();
887
- if (label && !optionMap.has(num)) optionMap.set(num, label);
888
- continue;
909
+ if (!optionLabels.has(num)) {
910
+ optionLabels.set(num, m[2].trim());
911
+ optionDescs.set(num, []);
912
+ }
913
+ currentNum = num;
914
+ } else if (currentNum !== -1 && !/^Enter to/i.test(t) && !/^[─━—═\-]{3,}$/.test(t) && !/↑.*↓.*navigate/i.test(t) && !/Esc to cancel/i.test(t)) {
915
+ optionDescs.get(currentNum)?.push(t);
889
916
  }
890
- if (t.endsWith("?")) question = t;
891
917
  }
892
- const keys = [...optionMap.keys()].sort((a, b) => a - b);
918
+ const keys = [...optionLabels.keys()].sort((a, b) => a - b);
893
919
  if (keys.length < 2 || keys[0] !== 1) return null;
894
- return { question, options: keys.map((k) => optionMap.get(k)) };
920
+ return {
921
+ question,
922
+ options: keys.map((k) => optionLabels.get(k)),
923
+ optionDescriptions: keys.map((k) => (optionDescs.get(k) ?? []).join(" ").trim())
924
+ };
895
925
  }
896
926
  function filterChrome(lines) {
897
927
  return lines.filter((line) => {
@@ -965,7 +995,7 @@ var OutputService = class _OutputService {
965
995
  if (idleMs2 >= _OutputService.SELECTOR_IDLE_MS) {
966
996
  this.stopPoll();
967
997
  this.active = false;
968
- this.postChunk({ type: "select_prompt", content: selector.question, options: selector.options, done: true }).catch(() => {
998
+ this.postChunk({ type: "select_prompt", content: selector.question, options: selector.options, optionDescriptions: selector.optionDescriptions, done: true }).catch(() => {
969
999
  });
970
1000
  }
971
1001
  return;
@@ -992,7 +1022,7 @@ var OutputService = class _OutputService {
992
1022
  this.stopPoll();
993
1023
  this.active = false;
994
1024
  if (selector) {
995
- this.postChunk({ type: "select_prompt", content: selector.question, options: selector.options, done: true }).catch(() => {
1025
+ this.postChunk({ type: "select_prompt", content: selector.question, options: selector.options, optionDescriptions: selector.optionDescriptions, done: true }).catch(() => {
996
1026
  });
997
1027
  } else {
998
1028
  const content = filterChrome(lines).join("\n").replace(/\n{3,}/g, "\n\n").trim();
@@ -1118,6 +1148,9 @@ async function start() {
1118
1148
  claude.selectOption(index);
1119
1149
  break;
1120
1150
  }
1151
+ case "escape_key":
1152
+ claude.sendEscape();
1153
+ break;
1121
1154
  case "stop_task":
1122
1155
  claude.interrupt();
1123
1156
  break;
@@ -1159,6 +1192,8 @@ async function start() {
1159
1192
  const index = inner.index ?? 0;
1160
1193
  outputSvc.newTurn();
1161
1194
  claude.selectOption(index);
1195
+ } else if (cmdType === "escape_key") {
1196
+ claude.sendEscape();
1162
1197
  } else if (cmdType === "stop_task") {
1163
1198
  claude.interrupt();
1164
1199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Remote control Claude Code from your mobile device",
5
5
  "main": "dist/index.js",
6
6
  "bin": {