codeam-cli 2.12.15 → 2.12.16

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 (3) hide show
  1. package/README.md +6 -2
  2. package/dist/index.js +76 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,10 +5,12 @@
5
5
  [![license](https://img.shields.io/npm/l/codeam-cli.svg?color=34d399&style=flat-square)](https://github.com/edgar-durand/codeagent-mobile-clients/blob/main/LICENSE)
6
6
  [![node](https://img.shields.io/node/v/codeam-cli.svg?color=34d399&style=flat-square)](https://nodejs.org/)
7
7
 
8
- > **Remote control [Claude Code](https://claude.ai/code) from your phone.**
8
+ > **Remote control AI coding agents from your phone.**
9
9
  > Send prompts, stream responses, and approve commands in real-time — from the subway, the couch, or anywhere away from your desk.
10
10
 
11
- `codeam-cli` is the companion CLI for [**CodeAgent Mobile**](https://codeagent-mobile.com). It wraps Claude Code inside a pseudo-terminal, relays your mobile prompts to the agent, and streams the output back to your phone in real-time.
11
+ `codeam-cli` is the companion CLI for [**CodeAgent Mobile**](https://codeagent-mobile.com). It wraps AI coding agents inside a pseudo-terminal, relays your mobile prompts to the agent, and streams the output back to your phone in real-time.
12
+
13
+ Currently supports **[Claude Code](https://claude.ai/code)** (Anthropic) and **[OpenAI Codex](https://github.com/openai/codex)** — start either via `codeam` (Claude Code) or `codeam codex` (OpenAI Codex).
12
14
 
13
15
  ---
14
16
 
@@ -42,6 +44,7 @@ That's it. Open the [CodeAgent Mobile app](https://codeagent-mobile.com), enter
42
44
  | Command | What it does |
43
45
  |---|---|
44
46
  | `codeam` | Start Claude Code in the current directory, with mobile control |
47
+ | `codeam codex` | Start OpenAI Codex in the current directory, with mobile control |
45
48
  | `codeam pair` | Pair a new mobile device (6-digit code or QR) |
46
49
  | `codeam sessions` | List all paired devices |
47
50
  | `codeam status` | Show connection status |
@@ -94,6 +97,7 @@ Adding more cloud backends (Gitpod, Coder, your own SSH host, …) is a single n
94
97
 
95
98
  - **Node.js 18+**
96
99
  - **Claude Code** — see the [official quickstart](https://code.claude.com/docs/en/quickstart)
100
+ - **OpenAI Codex** (optional) — see the [official quickstart](https://github.com/openai/codex)
97
101
  - **[CodeAgent Mobile](https://codeagent-mobile.com)** app on your phone ([iOS](https://apps.apple.com/) / [Android](https://play.google.com/store/apps/details?id=com.codeagent.mobile))
98
102
 
99
103
  ---
package/dist/index.js CHANGED
@@ -1658,6 +1658,13 @@ function makeConfig(baseDir) {
1658
1658
  }
1659
1659
  return session;
1660
1660
  }
1661
+ function getActiveSessionForAgent2(agent) {
1662
+ const c2 = load();
1663
+ const matches = c2.sessions.filter((s) => s.agent === agent);
1664
+ if (matches.length === 0) return null;
1665
+ matches.sort((a, b) => b.pairedAt - a.pairedAt);
1666
+ return matches[0];
1667
+ }
1661
1668
  function clearAll2() {
1662
1669
  try {
1663
1670
  fs.unlinkSync(file);
@@ -1670,10 +1677,10 @@ function makeConfig(baseDir) {
1670
1677
  function loadCliConfig2() {
1671
1678
  return load();
1672
1679
  }
1673
- return { getConfig: getConfig2, ensurePluginId: ensurePluginId2, addSession: addSession2, removeSession: removeSession2, setActiveSession: setActiveSession2, getActiveSession: getActiveSession2, clearAll: clearAll2, saveCliConfig: saveCliConfig2, loadCliConfig: loadCliConfig2 };
1680
+ return { getConfig: getConfig2, ensurePluginId: ensurePluginId2, addSession: addSession2, removeSession: removeSession2, setActiveSession: setActiveSession2, getActiveSession: getActiveSession2, getActiveSessionForAgent: getActiveSessionForAgent2, clearAll: clearAll2, saveCliConfig: saveCliConfig2, loadCliConfig: loadCliConfig2 };
1674
1681
  }
1675
1682
  var _default = makeConfig();
1676
- var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, clearAll, saveCliConfig, loadCliConfig } = _default;
1683
+ var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, clearAll, saveCliConfig, loadCliConfig } = _default;
1677
1684
 
1678
1685
  // src/ui/banner.ts
1679
1686
  var import_picocolors = __toESM(require("picocolors"));
@@ -1682,7 +1689,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
1682
1689
  // package.json
1683
1690
  var package_default = {
1684
1691
  name: "codeam-cli",
1685
- version: "2.12.15",
1692
+ version: "2.12.16",
1686
1693
  description: "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands \u2014 from anywhere.",
1687
1694
  type: "commonjs",
1688
1695
  main: "dist/index.js",
@@ -5804,7 +5811,7 @@ var BOX_DRAW_RE = /^[╭─╮│╰╯]/u;
5804
5811
  var BULLET_CHARS = "\u2022\xB7\u2027\u2219\u22C5";
5805
5812
  var CODEX_AGENT_REPLY_RE = new RegExp(`^[${BULLET_CHARS}]\\s`, "u");
5806
5813
  var STRIP_BULLET_RE = new RegExp(`^(\\s*)[${BULLET_CHARS}]\\s`, "u");
5807
- var CODEX_USER_ECHO_RE = /^[›>]\s+\S/u;
5814
+ var CODEX_USER_ECHO_RE = /^[›>]\s+(?!\d+\.\s)\S/u;
5808
5815
  var TIP_RE = /^\s*Tip:\s/i;
5809
5816
  var LEARN_MORE_RE = /^\s*Learn more:\s/i;
5810
5817
  var CODEX_STATUS_FOOTER_RE = /\bdefault\s+[·•]\s+\S+/i;
@@ -5979,8 +5986,53 @@ function wrapCodexCodeBlocks(lines) {
5979
5986
  function parseCodexChrome(_line) {
5980
5987
  return null;
5981
5988
  }
5982
- function detectCodexSelector(_lines) {
5983
- return null;
5989
+ function detectCodexSelector(lines) {
5990
+ const hasConfirmTrailer = lines.some(
5991
+ (l) => /press\s+enter\s+to\s+confirm/i.test(l)
5992
+ );
5993
+ if (!hasConfirmTrailer) return null;
5994
+ let optionStartIdx = -1;
5995
+ for (let i = 0; i < lines.length; i++) {
5996
+ if (/^\s*(?:>\s+)?\d+\.\s/.test(lines[i])) {
5997
+ optionStartIdx = i;
5998
+ break;
5999
+ }
6000
+ }
6001
+ if (optionStartIdx === -1) return null;
6002
+ const questionParts = [];
6003
+ for (let i = 0; i < optionStartIdx; i++) {
6004
+ const t2 = lines[i].trim();
6005
+ if (!t2) continue;
6006
+ if (/^[>›]\s*$/.test(t2)) continue;
6007
+ questionParts.push(t2);
6008
+ }
6009
+ const question = questionParts.join("\n").trim();
6010
+ const optionLabels = /* @__PURE__ */ new Map();
6011
+ let cursorIndex = 0;
6012
+ let hasCursor = false;
6013
+ for (let i = optionStartIdx; i < lines.length; i++) {
6014
+ const t2 = lines[i].trim();
6015
+ if (!t2) continue;
6016
+ if (/^press\s+enter\s+to\s+confirm/i.test(t2)) break;
6017
+ const m = t2.match(/^(>\s+)?(\d+)\.\s+(.+)/);
6018
+ if (!m) continue;
6019
+ const num = parseInt(m[2], 10);
6020
+ if (!optionLabels.has(num)) {
6021
+ optionLabels.set(num, m[3].trim());
6022
+ if (m[1]) {
6023
+ cursorIndex = optionLabels.size - 1;
6024
+ hasCursor = true;
6025
+ }
6026
+ }
6027
+ }
6028
+ const keys = [...optionLabels.keys()].sort((a, b) => a - b);
6029
+ if (keys.length < 2 || keys[0] !== 1) return null;
6030
+ return {
6031
+ question,
6032
+ options: keys.map((k2) => optionLabels.get(k2)),
6033
+ optionDescriptions: keys.map(() => ""),
6034
+ currentIndex: hasCursor ? cursorIndex : 0
6035
+ };
5984
6036
  }
5985
6037
 
5986
6038
  // src/agents/codex/renderer.ts
@@ -8103,13 +8155,22 @@ async function dispatchCommand(ctx, cmd) {
8103
8155
  }
8104
8156
 
8105
8157
  // src/commands/start.ts
8106
- async function start() {
8158
+ async function start(requestedAgent) {
8107
8159
  showIntro();
8108
- const session = getActiveSession();
8160
+ const session = requestedAgent ? getActiveSessionForAgent(requestedAgent) : getActiveSession();
8109
8161
  if (!session) {
8110
- console.log(` ${import_picocolors2.default.dim("No paired session found.")}`);
8111
- console.log(` ${import_picocolors2.default.dim(`Run ${import_picocolors2.default.white("codeam pair")} to connect your mobile app.`)}
8162
+ if (requestedAgent) {
8163
+ const displayName = AGENT_REGISTRY[requestedAgent]?.displayName ?? requestedAgent;
8164
+ console.log(` ${import_picocolors2.default.dim(`No paired ${displayName} session found.`)}`);
8165
+ console.log(
8166
+ ` ${import_picocolors2.default.dim(`Run ${import_picocolors2.default.white("codeam pair")} from a ${displayName} setup to connect your mobile app.`)}
8167
+ `
8168
+ );
8169
+ } else {
8170
+ console.log(` ${import_picocolors2.default.dim("No paired session found.")}`);
8171
+ console.log(` ${import_picocolors2.default.dim(`Run ${import_picocolors2.default.white("codeam pair")} to connect your mobile app.`)}
8112
8172
  `);
8173
+ }
8113
8174
  process.exit(0);
8114
8175
  }
8115
8176
  if (!session.agent) {
@@ -10443,7 +10504,7 @@ async function stopWorkspaceFromLocal(target) {
10443
10504
  // src/commands/version.ts
10444
10505
  var import_picocolors11 = __toESM(require("picocolors"));
10445
10506
  function version() {
10446
- const v = true ? "2.12.15" : "unknown";
10507
+ const v = true ? "2.12.16" : "unknown";
10447
10508
  console.log(`${import_picocolors11.default.bold("codeam-cli")} ${import_picocolors11.default.cyan(v)}`);
10448
10509
  }
10449
10510
 
@@ -10578,7 +10639,7 @@ function checkForUpdates() {
10578
10639
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
10579
10640
  if (process.env.CI) return;
10580
10641
  if (!process.stdout.isTTY) return;
10581
- const current = true ? "2.12.15" : null;
10642
+ const current = true ? "2.12.16" : null;
10582
10643
  if (!current) return;
10583
10644
  const cache = readCache();
10584
10645
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -10621,6 +10682,9 @@ async function main() {
10621
10682
  if (args[0] === "stop" || args[0] === "remove") return deployStop();
10622
10683
  return deploy(args);
10623
10684
  default:
10685
+ if (typeof command === "string" && isKnownAgentId(command)) {
10686
+ return start(command);
10687
+ }
10624
10688
  return start();
10625
10689
  }
10626
10690
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.12.15",
3
+ "version": "2.12.16",
4
4
  "description": "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands — from anywhere.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",