codeam-cli 1.4.58 → 2.0.1
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 +64 -0
- package/LICENSE +21 -0
- package/dist/index.js +86 -38
- package/package.json +14 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `codeam-cli` are documented here.
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
## [2.0.0] — 2026-04-23
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **Version alignment** — all three CodeAgent Mobile clients (`codeam-cli`, the VS Code extension, and the JetBrains plugin) now share a single version line starting at `2.0.0`. Going forward, a single `vX.Y.Z` git tag releases all of them together via the automated pipeline.
|
|
11
|
+
- First release built from the public source repository at [`edgar-durand/codeagent-mobile-clients`](https://github.com/edgar-durand/codeagent-mobile-clients).
|
|
12
|
+
|
|
13
|
+
## [1.4.58] — 2026-04-23
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- First release published from the public source repository at [`edgar-durand/codeagent-mobile-clients`](https://github.com/edgar-durand/codeagent-mobile-clients). No functional changes — only the `repository` and `bugs` URLs in `package.json` now point to the public repo.
|
|
17
|
+
|
|
18
|
+
## [1.4.57] — 2026-04-22
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- Dynamic model list — `list_models` now returns the actual set of Claude models loaded by the running agent instead of a hardcoded array.
|
|
22
|
+
|
|
23
|
+
## [1.4.55] — 2026-04-21
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- README now links to the official Claude Code quickstart.
|
|
27
|
+
- SEO / npm discoverability pass (keywords, description).
|
|
28
|
+
|
|
29
|
+
## [1.4.54] — 2026-04-20
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- Retry critical output chunks up to 3× on transient network errors.
|
|
33
|
+
- Silence `ECONNRESET` / socket hang-ups so they no longer corrupt Claude's TUI output stream.
|
|
34
|
+
|
|
35
|
+
## [1.4.50] — 2026-04-19
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- Robust spinner-line deduplication via ellipsis strip — handles every spinner/status format the TUI produces.
|
|
39
|
+
- Ignore user-typed input echoed back through the PTY when deduplicating chrome steps.
|
|
40
|
+
- Smart auto-scroll and live context-ring percentage.
|
|
41
|
+
|
|
42
|
+
## [1.4.46] — 2026-04-17
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- Thinking-UI `chrome_steps` support — detect bullet / tree / status lines from the new Claude Code TUI format and forward them as step events to the mobile app.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- Deduplicate chrome steps per turn — the CLI accumulates unique history while clients replace per-turn snapshots, so mobile no longer shows repeated lines.
|
|
49
|
+
- API forwards the `steps` field in output chunks (previously silently dropped).
|
|
50
|
+
|
|
51
|
+
## [1.4.38] — 2026-04-14
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
- Sync terminal-typed prompts back to the mobile app in real time.
|
|
55
|
+
- Load the current Claude conversation on session entry via a new `get_conversation` command.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
- Prompt submission after pairing — first keystroke no longer lost.
|
|
59
|
+
- Keyboard dismiss and output-noise cleanup.
|
|
60
|
+
- Re-push conversation to the API after every Claude turn so auto-load always finds a fresh snapshot.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
For versions prior to 1.4.38, consult the [npm release page](https://www.npmjs.com/package/codeam-cli?activeTab=versions).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Edgar Durand
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.js
CHANGED
|
@@ -116,7 +116,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
116
116
|
// package.json
|
|
117
117
|
var package_default = {
|
|
118
118
|
name: "codeam-cli",
|
|
119
|
-
version: "
|
|
119
|
+
version: "2.0.1",
|
|
120
120
|
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.",
|
|
121
121
|
main: "dist/index.js",
|
|
122
122
|
bin: {
|
|
@@ -124,7 +124,9 @@ var package_default = {
|
|
|
124
124
|
},
|
|
125
125
|
files: [
|
|
126
126
|
"dist",
|
|
127
|
-
"README.md"
|
|
127
|
+
"README.md",
|
|
128
|
+
"CHANGELOG.md",
|
|
129
|
+
"LICENSE"
|
|
128
130
|
],
|
|
129
131
|
scripts: {
|
|
130
132
|
build: "tsup",
|
|
@@ -163,14 +165,21 @@ var package_default = {
|
|
|
163
165
|
],
|
|
164
166
|
homepage: "https://codeagent-mobile.com",
|
|
165
167
|
bugs: {
|
|
166
|
-
url: "https://github.com/
|
|
168
|
+
url: "https://github.com/edgar-durand/codeagent-mobile-clients/issues"
|
|
167
169
|
},
|
|
168
170
|
author: "Edgar Durand",
|
|
169
171
|
repository: {
|
|
170
172
|
type: "git",
|
|
171
|
-
url: "git+https://github.com/
|
|
173
|
+
url: "git+https://github.com/edgar-durand/codeagent-mobile-clients.git"
|
|
172
174
|
},
|
|
173
175
|
license: "MIT",
|
|
176
|
+
publishConfig: {
|
|
177
|
+
access: "public"
|
|
178
|
+
},
|
|
179
|
+
funding: {
|
|
180
|
+
type: "github",
|
|
181
|
+
url: "https://github.com/sponsors/edgar-durand"
|
|
182
|
+
},
|
|
174
183
|
engines: {
|
|
175
184
|
node: ">=18.0.0"
|
|
176
185
|
},
|
|
@@ -181,6 +190,7 @@ var package_default = {
|
|
|
181
190
|
ws: "^8.18.0"
|
|
182
191
|
},
|
|
183
192
|
devDependencies: {
|
|
193
|
+
"@codeagent/shared": "*",
|
|
184
194
|
"@types/node": "^22.0.0",
|
|
185
195
|
"@types/qrcode-terminal": "^0.12.0",
|
|
186
196
|
"@types/ws": "^8.5.0",
|
|
@@ -919,7 +929,7 @@ var ClaudeService = class {
|
|
|
919
929
|
var https2 = __toESM(require("https"));
|
|
920
930
|
var http2 = __toESM(require("http"));
|
|
921
931
|
|
|
922
|
-
// src/
|
|
932
|
+
// ../../packages/shared/src/protocol/parseChrome.ts
|
|
923
933
|
var SPINNER_RE = /^[✳✢✶✻✽✴✷✸✹⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏◐◑◒◓▁▂▃▄▅▆▇█]\s/;
|
|
924
934
|
var BULLET_TOOL_RE = /^•\s+(?:Read(?:ing)?|Edit(?:ing)?|Writ(?:e|ing)|Bash|Runn(?:ing)?|Search(?:ing)?|Glob(?:bing)?|Grep(?:ping)?|Creat(?:e|ing)|Execut(?:e|ing)|Task|Agent|NotebookEdit)\b/i;
|
|
925
935
|
var TREE_LINE_RE = /^└\s/;
|
|
@@ -1000,8 +1010,7 @@ function classifyStep(text) {
|
|
|
1000
1010
|
return { tool: "other", label, status: "running" };
|
|
1001
1011
|
}
|
|
1002
1012
|
|
|
1003
|
-
// src/
|
|
1004
|
-
var API_BASE4 = process.env.CODEAM_API_URL ?? "https://codeagent-mobile-api.vercel.app";
|
|
1013
|
+
// ../../packages/shared/src/protocol/renderToLines.ts
|
|
1005
1014
|
function renderToLines(raw) {
|
|
1006
1015
|
const screen = [""];
|
|
1007
1016
|
let row = 0;
|
|
@@ -1107,11 +1116,12 @@ function renderToLines(raw) {
|
|
|
1107
1116
|
}
|
|
1108
1117
|
return screen;
|
|
1109
1118
|
}
|
|
1119
|
+
|
|
1120
|
+
// ../../packages/shared/src/protocol/selector.ts
|
|
1110
1121
|
function detectSelector(lines) {
|
|
1111
1122
|
if (lines.some((l) => /\?\s+for\s+shortcuts/i.test(l.trim()))) return null;
|
|
1112
1123
|
const clean = lines.map(
|
|
1113
1124
|
(l) => l.replace(/^[│╭╰╮╯┌└┐┘├┤┬┴┼]\s?/, "").replace(/\s*[│╭╰╮╯┌└┐┘├┤┬┴┼─━═]+\s*$/, "")
|
|
1114
|
-
// strip trailing fill + border
|
|
1115
1125
|
);
|
|
1116
1126
|
if (!clean.some((l) => /^❯\s*\d+\./.test(l.trim()))) return null;
|
|
1117
1127
|
let optionStartIdx = -1;
|
|
@@ -1213,6 +1223,8 @@ function detectListSelector(lines) {
|
|
|
1213
1223
|
currentIndex
|
|
1214
1224
|
};
|
|
1215
1225
|
}
|
|
1226
|
+
|
|
1227
|
+
// ../../packages/shared/src/protocol/filterChrome.ts
|
|
1216
1228
|
function filterChrome(lines) {
|
|
1217
1229
|
const result = [];
|
|
1218
1230
|
let skipEchoContinuation = false;
|
|
@@ -1255,6 +1267,39 @@ function filterChrome(lines) {
|
|
|
1255
1267
|
}
|
|
1256
1268
|
return result;
|
|
1257
1269
|
}
|
|
1270
|
+
|
|
1271
|
+
// ../../packages/shared/src/models/pricing.ts
|
|
1272
|
+
var MODEL_PRICING = {
|
|
1273
|
+
"claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
1274
|
+
"claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
1275
|
+
"claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
1276
|
+
"claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
|
1277
|
+
"claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }
|
|
1278
|
+
};
|
|
1279
|
+
var MODEL_CONTEXT_WINDOW = {
|
|
1280
|
+
"claude-opus-4": 1e6,
|
|
1281
|
+
"claude-sonnet-4": 1e6,
|
|
1282
|
+
"claude-3-5-sonnet": 2e5,
|
|
1283
|
+
"claude-3-5-haiku": 2e5,
|
|
1284
|
+
"claude-3-haiku": 2e5
|
|
1285
|
+
};
|
|
1286
|
+
var DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
1287
|
+
function getPricing(model) {
|
|
1288
|
+
for (const [prefix, pricing] of Object.entries(MODEL_PRICING)) {
|
|
1289
|
+
if (model.startsWith(prefix)) return pricing;
|
|
1290
|
+
}
|
|
1291
|
+
return MODEL_PRICING["claude-sonnet-4"];
|
|
1292
|
+
}
|
|
1293
|
+
function getContextWindow(model) {
|
|
1294
|
+
if (!model) return DEFAULT_CONTEXT_WINDOW;
|
|
1295
|
+
for (const [prefix, size] of Object.entries(MODEL_CONTEXT_WINDOW)) {
|
|
1296
|
+
if (model.startsWith(prefix)) return size;
|
|
1297
|
+
}
|
|
1298
|
+
return DEFAULT_CONTEXT_WINDOW;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// src/services/output.service.ts
|
|
1302
|
+
var API_BASE4 = process.env.CODEAM_API_URL ?? "https://codeagent-mobile-api.vercel.app";
|
|
1258
1303
|
var OutputService = class _OutputService {
|
|
1259
1304
|
constructor(sessionId, pluginId, onSessionIdDetected, onRateLimitDetected, onTurnComplete, onTerminalTurnDetected) {
|
|
1260
1305
|
this.sessionId = sessionId;
|
|
@@ -1542,6 +1587,27 @@ var path4 = __toESM(require("path"));
|
|
|
1542
1587
|
var os4 = __toESM(require("os"));
|
|
1543
1588
|
var https3 = __toESM(require("https"));
|
|
1544
1589
|
var http3 = __toESM(require("http"));
|
|
1590
|
+
|
|
1591
|
+
// src/services/logger.ts
|
|
1592
|
+
var LEVELS = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
|
|
1593
|
+
function currentLevel() {
|
|
1594
|
+
const raw = (process.env.CODEAM_LOG ?? "error").toLowerCase();
|
|
1595
|
+
return LEVELS[raw] ?? LEVELS.error;
|
|
1596
|
+
}
|
|
1597
|
+
function emit(level, tag, msg, err) {
|
|
1598
|
+
if (LEVELS[level] > currentLevel()) return;
|
|
1599
|
+
const detail = err instanceof Error ? `: ${err.message}` : err !== void 0 ? `: ${String(err)}` : "";
|
|
1600
|
+
process.stderr.write(`[codeam:${level}] ${tag} \u2014 ${msg}${detail}
|
|
1601
|
+
`);
|
|
1602
|
+
}
|
|
1603
|
+
var log = {
|
|
1604
|
+
error: (tag, msg, err) => emit("error", tag, msg, err),
|
|
1605
|
+
warn: (tag, msg, err) => emit("warn", tag, msg, err),
|
|
1606
|
+
info: (tag, msg, err) => emit("info", tag, msg, err),
|
|
1607
|
+
debug: (tag, msg, err) => emit("debug", tag, msg, err)
|
|
1608
|
+
};
|
|
1609
|
+
|
|
1610
|
+
// src/services/history.service.ts
|
|
1545
1611
|
var API_BASE5 = process.env.CODEAM_API_URL ?? "https://codeagent-mobile-api.vercel.app";
|
|
1546
1612
|
function encodeCwd(cwd) {
|
|
1547
1613
|
return cwd.replace(/\//g, "-");
|
|
@@ -1559,7 +1625,10 @@ function parseJsonl(filePath) {
|
|
|
1559
1625
|
let raw;
|
|
1560
1626
|
try {
|
|
1561
1627
|
raw = fs4.readFileSync(filePath, "utf8");
|
|
1562
|
-
} catch {
|
|
1628
|
+
} catch (err) {
|
|
1629
|
+
if (err.code !== "ENOENT") {
|
|
1630
|
+
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
1631
|
+
}
|
|
1563
1632
|
return messages;
|
|
1564
1633
|
}
|
|
1565
1634
|
const lines = raw.split("\n").filter(Boolean);
|
|
@@ -1603,11 +1672,17 @@ function post(endpoint, body) {
|
|
|
1603
1672
|
},
|
|
1604
1673
|
(res) => {
|
|
1605
1674
|
res.resume();
|
|
1606
|
-
|
|
1675
|
+
const ok = res.statusCode !== void 0 && res.statusCode >= 200 && res.statusCode < 300;
|
|
1676
|
+
if (!ok) log.warn("history:post", `${endpoint} \u2192 HTTP ${res.statusCode}`);
|
|
1677
|
+
resolve(ok);
|
|
1607
1678
|
}
|
|
1608
1679
|
);
|
|
1609
|
-
req.on("error", () =>
|
|
1680
|
+
req.on("error", (err) => {
|
|
1681
|
+
log.warn("history:post", `${endpoint} network error`, err);
|
|
1682
|
+
resolve(false);
|
|
1683
|
+
});
|
|
1610
1684
|
req.on("timeout", () => {
|
|
1685
|
+
log.warn("history:post", `${endpoint} timeout after 15s`);
|
|
1611
1686
|
req.destroy();
|
|
1612
1687
|
resolve(false);
|
|
1613
1688
|
});
|
|
@@ -1615,33 +1690,6 @@ function post(endpoint, body) {
|
|
|
1615
1690
|
req.end();
|
|
1616
1691
|
});
|
|
1617
1692
|
}
|
|
1618
|
-
var MODEL_PRICING = {
|
|
1619
|
-
"claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
1620
|
-
"claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
1621
|
-
"claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
1622
|
-
"claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
|
1623
|
-
"claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 }
|
|
1624
|
-
};
|
|
1625
|
-
function getPricing(model) {
|
|
1626
|
-
for (const [prefix, pricing] of Object.entries(MODEL_PRICING)) {
|
|
1627
|
-
if (model.startsWith(prefix)) return pricing;
|
|
1628
|
-
}
|
|
1629
|
-
return MODEL_PRICING["claude-sonnet-4"];
|
|
1630
|
-
}
|
|
1631
|
-
var MODEL_CONTEXT_WINDOW = {
|
|
1632
|
-
"claude-opus-4": 1e6,
|
|
1633
|
-
"claude-sonnet-4": 1e6,
|
|
1634
|
-
"claude-3-5-sonnet": 2e5,
|
|
1635
|
-
"claude-3-5-haiku": 2e5,
|
|
1636
|
-
"claude-3-haiku": 2e5
|
|
1637
|
-
};
|
|
1638
|
-
function getContextWindow(model) {
|
|
1639
|
-
if (!model) return 2e5;
|
|
1640
|
-
for (const [prefix, size] of Object.entries(MODEL_CONTEXT_WINDOW)) {
|
|
1641
|
-
if (model.startsWith(prefix)) return size;
|
|
1642
|
-
}
|
|
1643
|
-
return 2e5;
|
|
1644
|
-
}
|
|
1645
1693
|
var HistoryService = class {
|
|
1646
1694
|
constructor(pluginId, cwd) {
|
|
1647
1695
|
this.pluginId = pluginId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"README.md"
|
|
11
|
+
"README.md",
|
|
12
|
+
"CHANGELOG.md",
|
|
13
|
+
"LICENSE"
|
|
12
14
|
],
|
|
13
15
|
"scripts": {
|
|
14
16
|
"build": "tsup",
|
|
@@ -47,14 +49,21 @@
|
|
|
47
49
|
],
|
|
48
50
|
"homepage": "https://codeagent-mobile.com",
|
|
49
51
|
"bugs": {
|
|
50
|
-
"url": "https://github.com/
|
|
52
|
+
"url": "https://github.com/edgar-durand/codeagent-mobile-clients/issues"
|
|
51
53
|
},
|
|
52
54
|
"author": "Edgar Durand",
|
|
53
55
|
"repository": {
|
|
54
56
|
"type": "git",
|
|
55
|
-
"url": "git+https://github.com/
|
|
57
|
+
"url": "git+https://github.com/edgar-durand/codeagent-mobile-clients.git"
|
|
56
58
|
},
|
|
57
59
|
"license": "MIT",
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"funding": {
|
|
64
|
+
"type": "github",
|
|
65
|
+
"url": "https://github.com/sponsors/edgar-durand"
|
|
66
|
+
},
|
|
58
67
|
"engines": {
|
|
59
68
|
"node": ">=18.0.0"
|
|
60
69
|
},
|
|
@@ -65,6 +74,7 @@
|
|
|
65
74
|
"ws": "^8.18.0"
|
|
66
75
|
},
|
|
67
76
|
"devDependencies": {
|
|
77
|
+
"@codeagent/shared": "*",
|
|
68
78
|
"@types/node": "^22.0.0",
|
|
69
79
|
"@types/qrcode-terminal": "^0.12.0",
|
|
70
80
|
"@types/ws": "^8.5.0",
|