codeam-cli 2.12.16 → 2.13.0
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/CHANGELOG.md +18 -0
- package/README.md +27 -6
- package/dist/index.js +46 -21
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.12.17] — 2026-05-16
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Submit multi-line composer prompts; document new commands + env vars
|
|
12
|
+
- **vsc-plugin:** Replace placeholder activity bar icon with branded </> mark
|
|
13
|
+
|
|
14
|
+
## [2.12.16] — 2026-05-15
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
- **meta:** Mention Codex support across CLI/VS Code/JetBrains/README
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **cli:** Scope codeam <agent> restore to that agent's most-recent session
|
|
23
|
+
- **cli:** Detect Codex shell-approval prompts as a select_prompt
|
|
24
|
+
|
|
7
25
|
## [2.12.14] — 2026-05-14
|
|
8
26
|
|
|
9
27
|
### Fixed
|
package/README.md
CHANGED
|
@@ -43,15 +43,18 @@ That's it. Open the [CodeAgent Mobile app](https://codeagent-mobile.com), enter
|
|
|
43
43
|
|
|
44
44
|
| Command | What it does |
|
|
45
45
|
|---|---|
|
|
46
|
-
| `codeam` | Start
|
|
47
|
-
| `codeam
|
|
48
|
-
| `codeam pair` | Pair a new mobile device (6-
|
|
46
|
+
| `codeam` | Start the active agent in the current directory, with mobile control |
|
|
47
|
+
| `codeam <agent>` | Start a specific agent — `codeam claude`, `codeam codex`, … |
|
|
48
|
+
| `codeam pair` | Pair a new mobile device (6-character code or QR, interactive agent picker) |
|
|
49
|
+
| `codeam pair --agent <id>` | Pair non-interactively for a specific agent (`claude`, `codex`, …) — useful in scripts |
|
|
49
50
|
| `codeam sessions` | List all paired devices |
|
|
51
|
+
| `codeam sessions switch` | Choose which paired session the next `codeam` invocation will use |
|
|
52
|
+
| `codeam sessions delete <session-id>` | Forget a specific paired session (leaves the others intact) |
|
|
50
53
|
| `codeam status` | Show connection status |
|
|
51
54
|
| `codeam logout` | Remove all paired sessions |
|
|
52
55
|
| `codeam deploy` | Provision a cloud workspace (GitHub Codespaces) and pair it to your phone |
|
|
53
|
-
| `codeam deploy ls` | List the cloud workspaces you've deployed (and which still have a session running) |
|
|
54
|
-
| `codeam deploy stop` | Pick a deployed workspace and stop its codeam session (and optionally the workspace itself) |
|
|
56
|
+
| `codeam deploy ls` (alias `list`) | List the cloud workspaces you've deployed (and which still have a session running) |
|
|
57
|
+
| `codeam deploy stop` (alias `remove`) | Pick a deployed workspace and stop its codeam session (and optionally the workspace itself) |
|
|
55
58
|
| `codeam --version`, `-v` | Print the installed CLI version |
|
|
56
59
|
| `codeam --help`, `-h` | Show usage and the full command list |
|
|
57
60
|
|
|
@@ -106,7 +109,25 @@ Adding more cloud backends (Gitpod, Coder, your own SSH host, …) is a single n
|
|
|
106
109
|
|
|
107
110
|
| Variable | Default | Effect |
|
|
108
111
|
|---|---|---|
|
|
109
|
-
| `
|
|
112
|
+
| `CODEAM_API_URL` | `https://codeagent-mobile-api.vercel.app` | Override the backend relay URL. Useful for hitting a staging environment or self-hosted backend. |
|
|
113
|
+
| `CODEAM_DISABLE_UPDATE_CHECK` | unset | Set to `1` to suppress the "update available" banner. The check also auto-skips on non-TTY stdout, when `CI=true`, and during tests. |
|
|
114
|
+
| `CODEAM_AUTO_TOKEN` | unset | One-shot pairing token consumed by `codeam pair-auto`. Used by the `codeam deploy` bootstrap; see *Advanced / scripted pairing* below. |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Advanced / scripted pairing
|
|
119
|
+
|
|
120
|
+
For automation (CI, Codespaces bootstraps, container entry-points) `codeam` ships a non-interactive pairing command:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
codeam pair-auto --token=<one-shot-pairing-token>
|
|
124
|
+
# or
|
|
125
|
+
codeam pair-auto --token-file=/path/to/token
|
|
126
|
+
# or pass the token via env:
|
|
127
|
+
CODEAM_AUTO_TOKEN=<token> codeam pair-auto
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This is the same path `codeam deploy` uses inside a freshly-provisioned Codespace to pair the cloud session to your phone with zero interactive prompts. End users on a laptop should keep using the interactive `codeam pair`.
|
|
110
131
|
|
|
111
132
|
---
|
|
112
133
|
|
package/dist/index.js
CHANGED
|
@@ -1689,7 +1689,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
1689
1689
|
// package.json
|
|
1690
1690
|
var package_default = {
|
|
1691
1691
|
name: "codeam-cli",
|
|
1692
|
-
version: "2.
|
|
1692
|
+
version: "2.13.0",
|
|
1693
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.",
|
|
1694
1694
|
type: "commonjs",
|
|
1695
1695
|
main: "dist/index.js",
|
|
@@ -1817,6 +1817,12 @@ var https = __toESM(require("https"));
|
|
|
1817
1817
|
var http = __toESM(require("http"));
|
|
1818
1818
|
var os2 = __toESM(require("os"));
|
|
1819
1819
|
|
|
1820
|
+
// src/lib/backend-headers.ts
|
|
1821
|
+
function vercelBypassHeader() {
|
|
1822
|
+
const token = process.env.CODEAM_VERCEL_BYPASS;
|
|
1823
|
+
return token ? { "x-vercel-protection-bypass": token } : {};
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1820
1826
|
// src/lib/poll-delay.ts
|
|
1821
1827
|
var MAX_DELAY_MS = 3e4;
|
|
1822
1828
|
function computePollDelay({ baseMs, failures }) {
|
|
@@ -1915,7 +1921,8 @@ async function _postJson(url, body) {
|
|
|
1915
1921
|
method: "POST",
|
|
1916
1922
|
headers: {
|
|
1917
1923
|
"Content-Type": "application/json",
|
|
1918
|
-
"Content-Length": Buffer.byteLength(data)
|
|
1924
|
+
"Content-Length": Buffer.byteLength(data),
|
|
1925
|
+
...vercelBypassHeader()
|
|
1919
1926
|
},
|
|
1920
1927
|
timeout: 1e4
|
|
1921
1928
|
},
|
|
@@ -1957,6 +1964,7 @@ async function _getJson(url) {
|
|
|
1957
1964
|
port: u2.port || (u2.protocol === "https:" ? 443 : 80),
|
|
1958
1965
|
path: u2.pathname + u2.search,
|
|
1959
1966
|
method: "GET",
|
|
1967
|
+
headers: { ...vercelBypassHeader() },
|
|
1960
1968
|
timeout: 1e4
|
|
1961
1969
|
},
|
|
1962
1970
|
(res) => {
|
|
@@ -2111,7 +2119,7 @@ var CommandRelayService = class {
|
|
|
2111
2119
|
port: url.port || (url.protocol === "https:" ? 443 : 80),
|
|
2112
2120
|
path: `${url.pathname}${url.search}`,
|
|
2113
2121
|
method: "GET",
|
|
2114
|
-
headers: { Accept: "text/event-stream", "Cache-Control": "no-cache" },
|
|
2122
|
+
headers: { Accept: "text/event-stream", "Cache-Control": "no-cache", ...vercelBypassHeader() },
|
|
2115
2123
|
timeout: 35e3
|
|
2116
2124
|
},
|
|
2117
2125
|
(res) => {
|
|
@@ -4832,8 +4840,17 @@ var AgentService = class {
|
|
|
4832
4840
|
* the pre-batch (empty/previous) state → Enter submits nothing and the text
|
|
4833
4841
|
* stays visible-but-unsubmitted in the input field.
|
|
4834
4842
|
*
|
|
4835
|
-
* Sending '\r' in a separate write() 50 ms later guarantees it arrives on
|
|
4843
|
+
* Sending '\r' in a separate write() ~50 ms later guarantees it arrives on
|
|
4836
4844
|
* a fresh event-loop tick, after React has flushed the text into input state.
|
|
4845
|
+
*
|
|
4846
|
+
* The delay scales with line count: Smart Composer outputs are ~500–1500
|
|
4847
|
+
* chars with embedded `\n`s (Task / Context / Steps blocks). Ink's input
|
|
4848
|
+
* field re-flows multi-line content per render and the 50 ms baseline that
|
|
4849
|
+
* worked for single-line prompts isn't enough headroom — the text lands in
|
|
4850
|
+
* the field but `\r` submits stale state and the prompt sits there until
|
|
4851
|
+
* the user hits Enter manually. Adding ~40 ms per extra line (capped at
|
|
4852
|
+
* 300 ms) keeps short prompts snappy while giving multi-line composer
|
|
4853
|
+
* outputs the time they need to settle.
|
|
4837
4854
|
*/
|
|
4838
4855
|
sendCommand(text) {
|
|
4839
4856
|
if (!this.strategy) {
|
|
@@ -4848,7 +4865,9 @@ var AgentService = class {
|
|
|
4848
4865
|
const s = this.strategy;
|
|
4849
4866
|
log.trace("claude", `sendCommand text=${text.length}B`);
|
|
4850
4867
|
s.write(text);
|
|
4851
|
-
|
|
4868
|
+
const lineCount = text.split("\n").length;
|
|
4869
|
+
const delay = Math.min(300, 50 + (lineCount - 1) * 40);
|
|
4870
|
+
setTimeout(() => s.write("\r"), delay);
|
|
4852
4871
|
}
|
|
4853
4872
|
/**
|
|
4854
4873
|
* Navigate a React Ink selector to the given 0-based target index and confirm.
|
|
@@ -6457,7 +6476,8 @@ var ChunkEmitter = class {
|
|
|
6457
6476
|
// it can route legacy translations / 426 us when we're
|
|
6458
6477
|
// too far behind. Bumped to 2.0.0 with the discriminated-
|
|
6459
6478
|
// chunk + delta-chrome refactor in this release.
|
|
6460
|
-
"X-Codeam-Protocol-Version": "2.0.0"
|
|
6479
|
+
"X-Codeam-Protocol-Version": "2.0.0",
|
|
6480
|
+
...vercelBypassHeader()
|
|
6461
6481
|
};
|
|
6462
6482
|
if (opts.pluginAuthToken) {
|
|
6463
6483
|
this.headers["X-Plugin-Auth-Token"] = opts.pluginAuthToken;
|
|
@@ -6972,7 +6992,8 @@ function post(endpoint, body) {
|
|
|
6972
6992
|
method: "POST",
|
|
6973
6993
|
headers: {
|
|
6974
6994
|
"Content-Type": "application/json",
|
|
6975
|
-
"Content-Length": Buffer.byteLength(payload)
|
|
6995
|
+
"Content-Length": Buffer.byteLength(payload),
|
|
6996
|
+
...vercelBypassHeader()
|
|
6976
6997
|
},
|
|
6977
6998
|
timeout: 15e3
|
|
6978
6999
|
},
|
|
@@ -8416,7 +8437,7 @@ async function claim(token, pluginId) {
|
|
|
8416
8437
|
};
|
|
8417
8438
|
const res = await fetch(url, {
|
|
8418
8439
|
method: "POST",
|
|
8419
|
-
headers: { "Content-Type": "application/json" },
|
|
8440
|
+
headers: { "Content-Type": "application/json", ...vercelBypassHeader() },
|
|
8420
8441
|
body: JSON.stringify(body)
|
|
8421
8442
|
});
|
|
8422
8443
|
const json = await res.json();
|
|
@@ -10504,7 +10525,7 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
10504
10525
|
// src/commands/version.ts
|
|
10505
10526
|
var import_picocolors11 = __toESM(require("picocolors"));
|
|
10506
10527
|
function version() {
|
|
10507
|
-
const v = true ? "2.
|
|
10528
|
+
const v = true ? "2.13.0" : "unknown";
|
|
10508
10529
|
console.log(`${import_picocolors11.default.bold("codeam-cli")} ${import_picocolors11.default.cyan(v)}`);
|
|
10509
10530
|
}
|
|
10510
10531
|
|
|
@@ -10513,24 +10534,28 @@ var import_picocolors12 = __toESM(require("picocolors"));
|
|
|
10513
10534
|
function help() {
|
|
10514
10535
|
const lines = [
|
|
10515
10536
|
"",
|
|
10516
|
-
` ${import_picocolors12.default.bold(import_picocolors12.default.magenta("codeam-cli"))} ${import_picocolors12.default.dim("\u2014
|
|
10537
|
+
` ${import_picocolors12.default.bold(import_picocolors12.default.magenta("codeam-cli"))} ${import_picocolors12.default.dim("\u2014 remote-control AI coding agents from your phone")}`,
|
|
10517
10538
|
"",
|
|
10518
10539
|
` ${import_picocolors12.default.bold("Usage")}`,
|
|
10519
10540
|
` ${import_picocolors12.default.cyan("codeam")} ${import_picocolors12.default.dim("[command]")}`,
|
|
10520
10541
|
"",
|
|
10521
10542
|
` ${import_picocolors12.default.bold("Commands")}`,
|
|
10522
|
-
` ${import_picocolors12.default.white("codeam")}
|
|
10523
|
-
` ${import_picocolors12.default.white("codeam
|
|
10524
|
-
` ${import_picocolors12.default.white("codeam
|
|
10525
|
-
` ${import_picocolors12.default.white("codeam
|
|
10526
|
-
` ${import_picocolors12.default.white("codeam
|
|
10527
|
-
` ${import_picocolors12.default.white("codeam
|
|
10528
|
-
` ${import_picocolors12.default.white("codeam
|
|
10529
|
-
` ${import_picocolors12.default.white("codeam
|
|
10543
|
+
` ${import_picocolors12.default.white("codeam")} ${import_picocolors12.default.dim("start the active agent with mobile control")}`,
|
|
10544
|
+
` ${import_picocolors12.default.white("codeam <agent>")} ${import_picocolors12.default.dim("start a specific agent \u2014 e.g. claude, codex")}`,
|
|
10545
|
+
` ${import_picocolors12.default.white("codeam pair")} ${import_picocolors12.default.dim("pair a new mobile device (interactive)")}`,
|
|
10546
|
+
` ${import_picocolors12.default.white("codeam pair --agent <id>")} ${import_picocolors12.default.dim("pair non-interactively for a specific agent")}`,
|
|
10547
|
+
` ${import_picocolors12.default.white("codeam sessions")} ${import_picocolors12.default.dim("list paired devices")}`,
|
|
10548
|
+
` ${import_picocolors12.default.white("codeam sessions switch")} ${import_picocolors12.default.dim("switch the active paired session")}`,
|
|
10549
|
+
` ${import_picocolors12.default.white("codeam sessions delete <id>")} ${import_picocolors12.default.dim("remove a specific paired session")}`,
|
|
10550
|
+
` ${import_picocolors12.default.white("codeam status")} ${import_picocolors12.default.dim("show connection info")}`,
|
|
10551
|
+
` ${import_picocolors12.default.white("codeam logout")} ${import_picocolors12.default.dim("remove all paired sessions")}`,
|
|
10552
|
+
` ${import_picocolors12.default.white("codeam deploy")} ${import_picocolors12.default.dim("provision a cloud workspace (Codespaces) and pair it")}`,
|
|
10553
|
+
` ${import_picocolors12.default.white("codeam deploy ls | list")} ${import_picocolors12.default.dim("list deployed cloud workspaces")}`,
|
|
10554
|
+
` ${import_picocolors12.default.white("codeam deploy stop | remove")} ${import_picocolors12.default.dim("stop a deployed workspace session")}`,
|
|
10530
10555
|
"",
|
|
10531
10556
|
` ${import_picocolors12.default.bold("Flags")}`,
|
|
10532
|
-
` ${import_picocolors12.default.white("-v, --version")}
|
|
10533
|
-
` ${import_picocolors12.default.white("-h, --help")}
|
|
10557
|
+
` ${import_picocolors12.default.white("-v, --version")} ${import_picocolors12.default.dim("print the CLI version")}`,
|
|
10558
|
+
` ${import_picocolors12.default.white("-h, --help")} ${import_picocolors12.default.dim("show this help")}`,
|
|
10534
10559
|
"",
|
|
10535
10560
|
` ${import_picocolors12.default.bold("Links")}`,
|
|
10536
10561
|
` ${import_picocolors12.default.dim("Docs:")} ${import_picocolors12.default.green("https://www.codeagent-mobile.com")}`,
|
|
@@ -10639,7 +10664,7 @@ function checkForUpdates() {
|
|
|
10639
10664
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
10640
10665
|
if (process.env.CI) return;
|
|
10641
10666
|
if (!process.stdout.isTTY) return;
|
|
10642
|
-
const current = true ? "2.
|
|
10667
|
+
const current = true ? "2.13.0" : null;
|
|
10643
10668
|
if (!current) return;
|
|
10644
10669
|
const cache = readCache();
|
|
10645
10670
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
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",
|