codeam-cli 2.39.66 → 2.39.69

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,18 @@ 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.68] — 2026-06-20
8
+
9
+ ### Tests
10
+
11
+ - **host-agent:** Don't leak a heartbeat timer in the self_hosted_stop test
12
+
13
+ ## [2.39.66] — 2026-06-20
14
+
15
+ ### Fixed
16
+
17
+ - **cli:** Kill preview dev-server process group to stop port leaks (EADDRINUSE)
18
+
7
19
  ## [2.39.65] — 2026-06-20
8
20
 
9
21
  ### Added
package/dist/index.js CHANGED
@@ -5388,7 +5388,7 @@ function readAnonId() {
5388
5388
  }
5389
5389
  function superProperties() {
5390
5390
  return {
5391
- cliVersion: true ? "2.39.66" : "0.0.0-dev",
5391
+ cliVersion: true ? "2.39.69" : "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.66",
5550
+ version: "2.39.69",
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",
@@ -8281,10 +8281,12 @@ function boxRow(content, visibleLength) {
8281
8281
  return ` \u2502${content}${pad}\u2502`;
8282
8282
  }
8283
8283
  function showPairingCode(code) {
8284
+ const spaced = code.split("").join(" ");
8284
8285
  console.log(BOX_BORDER_TOP);
8285
- const codeVisible = ` Code: ${code}`.length;
8286
+ const label = " Code: ";
8287
+ const codeVisible = `${label}${spaced}`.length;
8286
8288
  console.log(
8287
- boxRow(` Code: ${import_picocolors.default.bold(import_picocolors.default.yellow(code))}`, codeVisible)
8289
+ boxRow(`${label}${import_picocolors.default.bold(import_picocolors.default.yellow(spaced))}`, codeVisible)
8288
8290
  );
8289
8291
  console.log(BOX_BORDER_BOT);
8290
8292
  console.log("");
@@ -17181,7 +17183,14 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
17181
17183
  }
17182
17184
 
17183
17185
  // src/services/headroom/stats-reporter.ts
17184
- var ZERO = { rawTokensEst: 0, sentTokensEst: 0, cachedTokens: 0, retrieveHops: 0 };
17186
+ var ZERO = {
17187
+ rawTokensEst: 0,
17188
+ sentTokensEst: 0,
17189
+ cachedTokens: 0,
17190
+ retrieveHops: 0,
17191
+ cacheReadTokens: 0,
17192
+ cacheSavingsUsd: 0
17193
+ };
17185
17194
  function read(stats) {
17186
17195
  const totals = stats.agent_usage?.totals;
17187
17196
  const compression = stats.summary?.compression;
@@ -17191,7 +17200,9 @@ function read(stats) {
17191
17200
  rawTokensEst,
17192
17201
  sentTokensEst,
17193
17202
  cachedTokens: 0,
17194
- retrieveHops: stats.summary?.mcp?.retrievals ?? 0
17203
+ retrieveHops: stats.summary?.mcp?.retrievals ?? 0,
17204
+ cacheReadTokens: stats.prefix_cache?.totals?.cache_read_tokens ?? 0,
17205
+ cacheSavingsUsd: stats.summary?.cost?.breakdown?.cache_savings_usd ?? 0
17195
17206
  };
17196
17207
  }
17197
17208
  function mapStatsToSavings(stats, prev) {
@@ -17201,7 +17212,9 @@ function mapStatsToSavings(stats, prev) {
17201
17212
  rawTokensEst: d3(next.rawTokensEst, prev.rawTokensEst),
17202
17213
  sentTokensEst: d3(next.sentTokensEst, prev.sentTokensEst),
17203
17214
  cachedTokens: d3(next.cachedTokens, prev.cachedTokens),
17204
- retrieveHops: d3(next.retrieveHops, prev.retrieveHops)
17215
+ retrieveHops: d3(next.retrieveHops, prev.retrieveHops),
17216
+ cacheReadTokens: d3(next.cacheReadTokens, prev.cacheReadTokens),
17217
+ cacheSavingsUsd: d3(next.cacheSavingsUsd, prev.cacheSavingsUsd)
17205
17218
  };
17206
17219
  return { next, delta };
17207
17220
  }
@@ -17220,7 +17233,9 @@ var HeadroomStatsReporter = class {
17220
17233
  try {
17221
17234
  const { next, delta } = mapStatsToSavings(await this.deps.fetchStats(), this.prev);
17222
17235
  this.prev = next;
17223
- if (delta.rawTokensEst > 0) await this.deps.postSavings(delta);
17236
+ if (delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0) {
17237
+ await this.deps.postSavings(delta);
17238
+ }
17224
17239
  } catch {
17225
17240
  }
17226
17241
  }
@@ -17391,7 +17406,7 @@ function checkForUpdates() {
17391
17406
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17392
17407
  if (process.env.CI) return;
17393
17408
  if (!process.stdout.isTTY) return;
17394
- const current = true ? "2.39.66" : null;
17409
+ const current = true ? "2.39.69" : null;
17395
17410
  if (!current) return;
17396
17411
  const cache = readCache();
17397
17412
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17796,7 +17811,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
17796
17811
  detached: false
17797
17812
  });
17798
17813
  function currentCliVersion() {
17799
- return true ? "2.39.66" : null;
17814
+ return true ? "2.39.69" : null;
17800
17815
  }
17801
17816
  function runCmd(cmd, args2, timeoutMs) {
17802
17817
  return new Promise((resolve7) => {
@@ -17867,6 +17882,20 @@ var defaultDisableService = () => {
17867
17882
  } catch {
17868
17883
  }
17869
17884
  };
17885
+ var defaultTeardownHeadroom = () => {
17886
+ try {
17887
+ const kind = JSON.parse(fs39.readFileSync(headroomConfigPath(), "utf8")).agent;
17888
+ if (kind) {
17889
+ (0, import_node_child_process13.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
17890
+ }
17891
+ } catch {
17892
+ }
17893
+ try {
17894
+ (0, import_node_child_process13.execFileSync)("pkill", ["-TERM", "-f", "headroom.*proxy"], { stdio: "ignore" });
17895
+ } catch {
17896
+ }
17897
+ persistHeadroomConfig({ enabled: false });
17898
+ };
17870
17899
  var HostAgentSupervisor = class {
17871
17900
  constructor(identity, deps = {}) {
17872
17901
  this.identity = identity;
@@ -17877,6 +17906,7 @@ var HostAgentSupervisor = class {
17877
17906
  this.metrics = deps.metricsCollector ?? new MetricsCollector();
17878
17907
  this.onIdentityRejected = deps.onIdentityRejected ?? defaultOnIdentityRejected;
17879
17908
  this.disableService = deps.disableService ?? defaultDisableService;
17909
+ this.teardownHeadroom = deps.teardownHeadroom ?? defaultTeardownHeadroom;
17880
17910
  this.selfUpdate = deps.selfUpdate ?? runSelfUpdate;
17881
17911
  this.onUpdated = deps.onUpdated ?? defaultOnUpdated;
17882
17912
  }
@@ -17910,6 +17940,7 @@ var HostAgentSupervisor = class {
17910
17940
  onIdentityRejected;
17911
17941
  /** Best-effort systemd de-provision used by `self_hosted_wipe`. */
17912
17942
  disableService;
17943
+ teardownHeadroom;
17913
17944
  /** Guards against firing the self-heal more than once. */
17914
17945
  healing = false;
17915
17946
  /**
@@ -18107,6 +18138,7 @@ var HostAgentSupervisor = class {
18107
18138
  if (cmd.type === "self_hosted_wipe") {
18108
18139
  log.warn("host-agent", `self_hosted_wipe received id=${cmd.id} \u2014 de-provisioning`);
18109
18140
  this.stop();
18141
+ this.teardownHeadroom();
18110
18142
  this.disableService();
18111
18143
  if (!this.healing) {
18112
18144
  this.healing = true;
@@ -21795,6 +21827,13 @@ var AcpClient = class {
21795
21827
  if (!this.connection) {
21796
21828
  throw new Error("AcpClient.loadSession called before start()");
21797
21829
  }
21830
+ if (sessionId === this.sessionId) {
21831
+ log.info(
21832
+ "acpClient",
21833
+ `loadSession skipped \u2014 already the active session (${sessionId.slice(0, 8)})`
21834
+ );
21835
+ return;
21836
+ }
21798
21837
  log.info("acpClient", `loadSession \u2192 sessionId=${sessionId.slice(0, 8)}`);
21799
21838
  await this.connection.loadSession({
21800
21839
  sessionId,
@@ -28411,7 +28450,7 @@ function checkChokidar() {
28411
28450
  }
28412
28451
  async function doctor(args2 = []) {
28413
28452
  const json = args2.includes("--json");
28414
- const cliVersion = true ? "2.39.66" : "0.0.0-dev";
28453
+ const cliVersion = true ? "2.39.69" : "0.0.0-dev";
28415
28454
  const apiBase2 = resolveApiBaseUrl();
28416
28455
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
28417
28456
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -28610,7 +28649,7 @@ async function completion(args2) {
28610
28649
  // src/commands/version.ts
28611
28650
  var import_picocolors14 = __toESM(require("picocolors"));
28612
28651
  function version2() {
28613
- const v = true ? "2.39.66" : "unknown";
28652
+ const v = true ? "2.39.69" : "unknown";
28614
28653
  console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
28615
28654
  }
28616
28655
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.39.66",
3
+ "version": "2.39.69",
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",