codeam-cli 2.39.69 → 2.39.71

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 CHANGED
@@ -4,6 +4,16 @@ 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.69] — 2026-06-21
8
+
9
+ ### Added
10
+
11
+ - **cli:** Report Headroom prompt-cache savings, not just compression
12
+
13
+ ### Fixed
14
+
15
+ - **cli:** Make the pairing code more legible (letter-spacing + bold + contrast)
16
+
7
17
  ## [2.39.68] — 2026-06-20
8
18
 
9
19
  ### 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 promises = Object.values(this.promiseByIds);
1088
- let length = promises.length;
1087
+ let promises2 = Object.values(this.promiseByIds);
1088
+ let length = promises2.length;
1089
1089
  while (length > 0) {
1090
- await Promise.all(promises);
1091
- promises = Object.values(this.promiseByIds);
1092
- length = promises.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(promises) {
1431
- return Promise.all(promises.map((p2) => (p2 ?? Promise.resolve()).then((value) => ({
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.69" : "0.0.0-dev",
5391
+ cliVersion: true ? "2.39.71" : "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.69",
5550
+ version: "2.39.71",
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.69" : null;
17409
+ const current = true ? "2.39.71" : 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 PIP_INSTALL_TIMEOUT_MS = 12e4;
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,50 @@ 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 PIP_PACKAGES = [
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 installOk = await (async () => {
17728
- const baseArgs = ["-m", "pip", "install", "--quiet", ...PIP_PACKAGES];
17729
- const firstResult = await runner.run("python3", baseArgs, {
17730
- timeoutMs: PIP_INSTALL_TIMEOUT_MS
17731
- });
17732
- if (firstResult.code === 0) {
17733
- log.info("host-agent", "headroom pip install succeeded");
17734
- return true;
17735
- }
17736
- if (firstResult.stderr.includes(PEP668_MARKER)) {
17737
- log.info(
17738
- "host-agent",
17739
- "PEP 668 externally-managed-environment detected \u2014 retrying with --break-system-packages"
17740
- );
17741
- const retryResult = await runner.run(
17742
- "python3",
17743
- [...baseArgs, "--break-system-packages"],
17744
- { timeoutMs: PIP_INSTALL_TIMEOUT_MS }
17745
- );
17746
- if (retryResult.code === 0) {
17747
- log.info("host-agent", "headroom pip install succeeded (--break-system-packages)");
17748
- return true;
17749
- }
17750
- log.warn(
17751
- "host-agent",
17752
- `headroom pip install failed even with --break-system-packages (code=${String(retryResult.code)}) \u2014 skipping Headroom`
17753
- );
17754
- return false;
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;
17755
17736
  }
17756
- log.warn(
17757
- "host-agent",
17758
- `headroom pip install exited code=${String(firstResult.code)} \u2014 skipping Headroom`
17759
- );
17760
17737
  return false;
17761
- })();
17738
+ };
17739
+ const torchOk = await pipInstall(
17740
+ ["torch"],
17741
+ ["--index-url", "https://download.pytorch.org/whl/cpu"],
17742
+ ENGINE_INSTALL_TIMEOUT_MS
17743
+ );
17744
+ log.info(
17745
+ "host-agent",
17746
+ torchOk ? "CPU-only PyTorch installed \u2014 Kompress (ML) compressor available" : "CPU torch install failed \u2014 installing code-aware engine only (Kompress unavailable)"
17747
+ );
17748
+ const headroomPkg = torchOk ? "headroom-ai[code,ml]" : "headroom-ai[code]";
17749
+ const installOk = await pipInstall(
17750
+ [headroomPkg, ...SERVER_DEPS],
17751
+ [],
17752
+ ENGINE_INSTALL_TIMEOUT_MS
17753
+ );
17762
17754
  if (!installOk) {
17755
+ log.warn("host-agent", `headroom engine install failed (${headroomPkg}) \u2014 skipping Headroom`);
17763
17756
  return false;
17764
17757
  }
17758
+ log.info("host-agent", `headroom + engines installed (${headroomPkg})`);
17765
17759
  if (!runner.which("headroom")) {
17766
17760
  log.warn("host-agent", "headroom not found on PATH after install \u2014 skipping init");
17767
17761
  return false;
@@ -17811,7 +17805,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
17811
17805
  detached: false
17812
17806
  });
17813
17807
  function currentCliVersion() {
17814
- return true ? "2.39.69" : null;
17808
+ return true ? "2.39.71" : null;
17815
17809
  }
17816
17810
  function runCmd(cmd, args2, timeoutMs) {
17817
17811
  return new Promise((resolve7) => {
@@ -18214,17 +18208,32 @@ var HostAgentSupervisor = class {
18214
18208
  }
18215
18209
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl) {
18216
18210
  report("headroom", "setting up Headroom proxy");
18217
- const headroomOk = await this.setupHeadroom(payload.headroomAgent);
18218
- if (headroomOk) {
18219
- persistHeadroomConfig({
18220
- enabled: true,
18221
- agent: agentIdToHeadroomKind(payload.headroomAgent),
18222
- ingestUrl: payload.headroomSavingsIngestUrl
18223
- });
18224
- log.info("host-agent", "Headroom proxy ready; persisted headroom config for child spawns");
18225
- } else {
18211
+ const freeBytes = await getFreeDiskBytes(os32.homedir());
18212
+ if (freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
18213
+ const freeGb = (freeBytes / 1e9).toFixed(1);
18214
+ const needGb = Math.round(HEADROOM_MIN_FREE_DISK_BYTES / 1e9);
18215
+ report(
18216
+ "headroom",
18217
+ `Token-saving optimizer skipped \u2014 needs ~${needGb} GB free, host has ${freeGb} GB. The agent runs normally without it.`
18218
+ );
18219
+ log.warn(
18220
+ "host-agent",
18221
+ `Headroom skipped: insufficient disk (free=${freeGb}GB < ${needGb}GB)`
18222
+ );
18226
18223
  persistHeadroomConfig({ enabled: false });
18227
- log.warn("host-agent", "Headroom setup failed (best-effort) \u2014 child will run without Headroom");
18224
+ } else {
18225
+ const headroomOk = await this.setupHeadroom(payload.headroomAgent);
18226
+ if (headroomOk) {
18227
+ persistHeadroomConfig({
18228
+ enabled: true,
18229
+ agent: agentIdToHeadroomKind(payload.headroomAgent),
18230
+ ingestUrl: payload.headroomSavingsIngestUrl
18231
+ });
18232
+ log.info("host-agent", "Headroom proxy ready; persisted headroom config for child spawns");
18233
+ } else {
18234
+ persistHeadroomConfig({ enabled: false });
18235
+ log.warn("host-agent", "Headroom setup failed (best-effort) \u2014 child will run without Headroom");
18236
+ }
18228
18237
  }
18229
18238
  } else if (payload.headroomEnabled === false) {
18230
18239
  persistHeadroomConfig({ enabled: false });
@@ -28450,7 +28459,7 @@ function checkChokidar() {
28450
28459
  }
28451
28460
  async function doctor(args2 = []) {
28452
28461
  const json = args2.includes("--json");
28453
- const cliVersion = true ? "2.39.69" : "0.0.0-dev";
28462
+ const cliVersion = true ? "2.39.71" : "0.0.0-dev";
28454
28463
  const apiBase2 = resolveApiBaseUrl();
28455
28464
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
28456
28465
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -28649,7 +28658,7 @@ async function completion(args2) {
28649
28658
  // src/commands/version.ts
28650
28659
  var import_picocolors14 = __toESM(require("picocolors"));
28651
28660
  function version2() {
28652
- const v = true ? "2.39.69" : "unknown";
28661
+ const v = true ? "2.39.71" : "unknown";
28653
28662
  console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
28654
28663
  }
28655
28664
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.39.69",
3
+ "version": "2.39.71",
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",