codeam-cli 2.39.69 → 2.39.72
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 +16 -0
- package/dist/index.js +84 -62
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ 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.39.71] — 2026-06-21
|
|
8
|
+
|
|
9
|
+
### Tests
|
|
10
|
+
|
|
11
|
+
- **host-agent:** Drop the real-subprocess Headroom test (downloaded PyTorch in CI)
|
|
12
|
+
|
|
13
|
+
## [2.39.69] — 2026-06-21
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** Report Headroom prompt-cache savings, not just compression
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **cli:** Make the pairing code more legible (letter-spacing + bold + contrast)
|
|
22
|
+
|
|
7
23
|
## [2.39.68] — 2026-06-20
|
|
8
24
|
|
|
9
25
|
### Tests
|
package/dist/index.js
CHANGED
|
@@ -1084,12 +1084,12 @@ var PromiseQueue = class {
|
|
|
1084
1084
|
return promise;
|
|
1085
1085
|
}
|
|
1086
1086
|
async join() {
|
|
1087
|
-
let
|
|
1088
|
-
let length =
|
|
1087
|
+
let promises2 = Object.values(this.promiseByIds);
|
|
1088
|
+
let length = promises2.length;
|
|
1089
1089
|
while (length > 0) {
|
|
1090
|
-
await Promise.all(
|
|
1091
|
-
|
|
1092
|
-
length =
|
|
1090
|
+
await Promise.all(promises2);
|
|
1091
|
+
promises2 = Object.values(this.promiseByIds);
|
|
1092
|
+
length = promises2.length;
|
|
1093
1093
|
}
|
|
1094
1094
|
}
|
|
1095
1095
|
get length() {
|
|
@@ -1427,8 +1427,8 @@ function safeSetTimeout(fn, timeout) {
|
|
|
1427
1427
|
return t2;
|
|
1428
1428
|
}
|
|
1429
1429
|
var isError = (x) => x instanceof Error;
|
|
1430
|
-
function allSettled(
|
|
1431
|
-
return Promise.all(
|
|
1430
|
+
function allSettled(promises2) {
|
|
1431
|
+
return Promise.all(promises2.map((p2) => (p2 ?? Promise.resolve()).then((value) => ({
|
|
1432
1432
|
status: "fulfilled",
|
|
1433
1433
|
value
|
|
1434
1434
|
}), (reason) => ({
|
|
@@ -5388,7 +5388,7 @@ function readAnonId() {
|
|
|
5388
5388
|
}
|
|
5389
5389
|
function superProperties() {
|
|
5390
5390
|
return {
|
|
5391
|
-
cliVersion: true ? "2.39.
|
|
5391
|
+
cliVersion: true ? "2.39.72" : "0.0.0-dev",
|
|
5392
5392
|
nodeVersion: process.version,
|
|
5393
5393
|
platform: process.platform,
|
|
5394
5394
|
arch: process.arch,
|
|
@@ -5547,7 +5547,7 @@ var os4 = __toESM(require("os"));
|
|
|
5547
5547
|
// package.json
|
|
5548
5548
|
var package_default = {
|
|
5549
5549
|
name: "codeam-cli",
|
|
5550
|
-
version: "2.39.
|
|
5550
|
+
version: "2.39.72",
|
|
5551
5551
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
5552
5552
|
type: "commonjs",
|
|
5553
5553
|
main: "dist/index.js",
|
|
@@ -17406,7 +17406,7 @@ function checkForUpdates() {
|
|
|
17406
17406
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17407
17407
|
if (process.env.CI) return;
|
|
17408
17408
|
if (!process.stdout.isTTY) return;
|
|
17409
|
-
const current = true ? "2.39.
|
|
17409
|
+
const current = true ? "2.39.72" : null;
|
|
17410
17410
|
if (!current) return;
|
|
17411
17411
|
const cache = readCache();
|
|
17412
17412
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17499,7 +17499,8 @@ var CONTROL_AGENT_META = {
|
|
|
17499
17499
|
};
|
|
17500
17500
|
var PEP668_MARKER = "externally-managed-environment";
|
|
17501
17501
|
var PM_INSTALL_TIMEOUT_MS = 18e4;
|
|
17502
|
-
var
|
|
17502
|
+
var ENGINE_INSTALL_TIMEOUT_MS = 36e4;
|
|
17503
|
+
var HEADROOM_MIN_FREE_DISK_BYTES = 3 * 1024 * 1024 * 1024;
|
|
17503
17504
|
var defaultHeadroomRunner = {
|
|
17504
17505
|
which(cmd) {
|
|
17505
17506
|
try {
|
|
@@ -17711,57 +17712,63 @@ function bundledClaudeBinDir() {
|
|
|
17711
17712
|
}
|
|
17712
17713
|
return null;
|
|
17713
17714
|
}
|
|
17715
|
+
async function getFreeDiskBytes(dir) {
|
|
17716
|
+
try {
|
|
17717
|
+
const s = await fs39.promises.statfs(dir);
|
|
17718
|
+
return s.bsize * s.bavail;
|
|
17719
|
+
} catch {
|
|
17720
|
+
return null;
|
|
17721
|
+
}
|
|
17722
|
+
}
|
|
17714
17723
|
async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner) {
|
|
17715
|
-
const
|
|
17716
|
-
"headroom-ai",
|
|
17717
|
-
"fastapi",
|
|
17718
|
-
"uvicorn",
|
|
17719
|
-
"httpx[http2]",
|
|
17720
|
-
"websockets",
|
|
17721
|
-
"zstandard"
|
|
17722
|
-
];
|
|
17724
|
+
const SERVER_DEPS = ["fastapi", "uvicorn", "httpx[http2]", "websockets", "zstandard"];
|
|
17723
17725
|
const pipAvailable = await ensurePip(runner);
|
|
17724
17726
|
if (!pipAvailable) {
|
|
17725
17727
|
return false;
|
|
17726
17728
|
}
|
|
17727
|
-
const
|
|
17728
|
-
const
|
|
17729
|
-
const
|
|
17730
|
-
|
|
17731
|
-
|
|
17732
|
-
|
|
17733
|
-
|
|
17734
|
-
return true;
|
|
17729
|
+
const pipInstall = async (pkgs, extraArgs, timeoutMs) => {
|
|
17730
|
+
const base = ["-m", "pip", "install", "--quiet", ...extraArgs, ...pkgs];
|
|
17731
|
+
const r = await runner.run("python3", base, { timeoutMs });
|
|
17732
|
+
if (r.code === 0) return true;
|
|
17733
|
+
if (r.stderr.includes(PEP668_MARKER)) {
|
|
17734
|
+
const r2 = await runner.run("python3", [...base, "--break-system-packages"], { timeoutMs });
|
|
17735
|
+
return r2.code === 0;
|
|
17735
17736
|
}
|
|
17736
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
17740
|
-
|
|
17741
|
-
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17737
|
+
return false;
|
|
17738
|
+
};
|
|
17739
|
+
const torchInstalled = await pipInstall(
|
|
17740
|
+
["torch"],
|
|
17741
|
+
["--index-url", "https://download.pytorch.org/whl/cpu"],
|
|
17742
|
+
ENGINE_INSTALL_TIMEOUT_MS
|
|
17743
|
+
);
|
|
17744
|
+
let torchOk = false;
|
|
17745
|
+
if (torchInstalled) {
|
|
17746
|
+
const v = await runner.run("python3", ["-c", "import torch; import torch.export"], {
|
|
17747
|
+
timeoutMs: 6e4
|
|
17748
|
+
});
|
|
17749
|
+
torchOk = v.code === 0;
|
|
17750
|
+
if (!torchOk) {
|
|
17750
17751
|
log.warn(
|
|
17751
17752
|
"host-agent",
|
|
17752
|
-
`
|
|
17753
|
+
`torch installed but failed its deep-import validation (code=${String(v.code)}) \u2014 disabling Kompress to avoid a hung proxy; using the AST code engine only`
|
|
17753
17754
|
);
|
|
17754
|
-
return false;
|
|
17755
17755
|
}
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
|
|
17759
|
-
)
|
|
17760
|
-
|
|
17761
|
-
|
|
17756
|
+
}
|
|
17757
|
+
log.info(
|
|
17758
|
+
"host-agent",
|
|
17759
|
+
torchOk ? "PyTorch installed + validated \u2014 Kompress (ML) compressor enabled" : "Kompress unavailable (torch absent/broken) \u2014 installing the AST code engine only"
|
|
17760
|
+
);
|
|
17761
|
+
const headroomPkg = torchOk ? "headroom-ai[code,ml]" : "headroom-ai[code]";
|
|
17762
|
+
const installOk = await pipInstall(
|
|
17763
|
+
[headroomPkg, ...SERVER_DEPS],
|
|
17764
|
+
[],
|
|
17765
|
+
ENGINE_INSTALL_TIMEOUT_MS
|
|
17766
|
+
);
|
|
17762
17767
|
if (!installOk) {
|
|
17768
|
+
log.warn("host-agent", `headroom engine install failed (${headroomPkg}) \u2014 skipping Headroom`);
|
|
17763
17769
|
return false;
|
|
17764
17770
|
}
|
|
17771
|
+
log.info("host-agent", `headroom + engines installed (${headroomPkg})`);
|
|
17765
17772
|
if (!runner.which("headroom")) {
|
|
17766
17773
|
log.warn("host-agent", "headroom not found on PATH after install \u2014 skipping init");
|
|
17767
17774
|
return false;
|
|
@@ -17811,7 +17818,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
|
|
|
17811
17818
|
detached: false
|
|
17812
17819
|
});
|
|
17813
17820
|
function currentCliVersion() {
|
|
17814
|
-
return true ? "2.39.
|
|
17821
|
+
return true ? "2.39.72" : null;
|
|
17815
17822
|
}
|
|
17816
17823
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17817
17824
|
return new Promise((resolve7) => {
|
|
@@ -18214,17 +18221,32 @@ var HostAgentSupervisor = class {
|
|
|
18214
18221
|
}
|
|
18215
18222
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl) {
|
|
18216
18223
|
report("headroom", "setting up Headroom proxy");
|
|
18217
|
-
const
|
|
18218
|
-
if (
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18224
|
+
const freeBytes = await getFreeDiskBytes(os32.homedir());
|
|
18225
|
+
if (freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
18226
|
+
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
18227
|
+
const needGb = Math.round(HEADROOM_MIN_FREE_DISK_BYTES / 1e9);
|
|
18228
|
+
report(
|
|
18229
|
+
"headroom",
|
|
18230
|
+
`Token-saving optimizer skipped \u2014 needs ~${needGb} GB free, host has ${freeGb} GB. The agent runs normally without it.`
|
|
18231
|
+
);
|
|
18232
|
+
log.warn(
|
|
18233
|
+
"host-agent",
|
|
18234
|
+
`Headroom skipped: insufficient disk (free=${freeGb}GB < ${needGb}GB)`
|
|
18235
|
+
);
|
|
18226
18236
|
persistHeadroomConfig({ enabled: false });
|
|
18227
|
-
|
|
18237
|
+
} else {
|
|
18238
|
+
const headroomOk = await this.setupHeadroom(payload.headroomAgent);
|
|
18239
|
+
if (headroomOk) {
|
|
18240
|
+
persistHeadroomConfig({
|
|
18241
|
+
enabled: true,
|
|
18242
|
+
agent: agentIdToHeadroomKind(payload.headroomAgent),
|
|
18243
|
+
ingestUrl: payload.headroomSavingsIngestUrl
|
|
18244
|
+
});
|
|
18245
|
+
log.info("host-agent", "Headroom proxy ready; persisted headroom config for child spawns");
|
|
18246
|
+
} else {
|
|
18247
|
+
persistHeadroomConfig({ enabled: false });
|
|
18248
|
+
log.warn("host-agent", "Headroom setup failed (best-effort) \u2014 child will run without Headroom");
|
|
18249
|
+
}
|
|
18228
18250
|
}
|
|
18229
18251
|
} else if (payload.headroomEnabled === false) {
|
|
18230
18252
|
persistHeadroomConfig({ enabled: false });
|
|
@@ -28450,7 +28472,7 @@ function checkChokidar() {
|
|
|
28450
28472
|
}
|
|
28451
28473
|
async function doctor(args2 = []) {
|
|
28452
28474
|
const json = args2.includes("--json");
|
|
28453
|
-
const cliVersion = true ? "2.39.
|
|
28475
|
+
const cliVersion = true ? "2.39.72" : "0.0.0-dev";
|
|
28454
28476
|
const apiBase2 = resolveApiBaseUrl();
|
|
28455
28477
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
28456
28478
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -28649,7 +28671,7 @@ async function completion(args2) {
|
|
|
28649
28671
|
// src/commands/version.ts
|
|
28650
28672
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
28651
28673
|
function version2() {
|
|
28652
|
-
const v = true ? "2.39.
|
|
28674
|
+
const v = true ? "2.39.72" : "unknown";
|
|
28653
28675
|
console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
|
|
28654
28676
|
}
|
|
28655
28677
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.72",
|
|
4
4
|
"description": "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|