codeam-cli 2.39.78 → 2.39.80

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.78] — 2026-06-21
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Keep Headroom savings reporting on a low-disk box that's already installed
12
+
13
+ ## [2.39.77] — 2026-06-21
14
+
15
+ ### Added
16
+
17
+ - **cli:** Report runtime 401 to mark the credential invalid
18
+
7
19
  ## [2.39.76] — 2026-06-21
8
20
 
9
21
  ### Added
package/dist/index.js CHANGED
@@ -5390,7 +5390,7 @@ function readAnonId() {
5390
5390
  }
5391
5391
  function superProperties() {
5392
5392
  return {
5393
- cliVersion: true ? "2.39.78" : "0.0.0-dev",
5393
+ cliVersion: true ? "2.39.80" : "0.0.0-dev",
5394
5394
  nodeVersion: process.version,
5395
5395
  platform: process.platform,
5396
5396
  arch: process.arch,
@@ -5549,7 +5549,7 @@ var os4 = __toESM(require("os"));
5549
5549
  // package.json
5550
5550
  var package_default = {
5551
5551
  name: "codeam-cli",
5552
- version: "2.39.78",
5552
+ version: "2.39.80",
5553
5553
  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.",
5554
5554
  type: "commonjs",
5555
5555
  main: "dist/index.js",
@@ -17224,14 +17224,17 @@ var ZERO = {
17224
17224
  retrieveHops: 0,
17225
17225
  cacheReadTokens: 0,
17226
17226
  cacheSavingsUsd: 0,
17227
- compressionSavingsUsd: 0
17227
+ compressionTokens: 0,
17228
+ compressionSavingsUsd: 0,
17229
+ compressionPct: 0
17228
17230
  };
17229
17231
  function read(stats, inputPricePerMillion) {
17230
17232
  const totals = stats.agent_usage?.totals;
17231
17233
  const compression = stats.summary?.compression;
17232
17234
  const rawTokensEst = totals?.before_tokens ?? compression?.total_tokens_before_with_cli_filtering ?? 0;
17233
17235
  const sentTokensEst = totals?.after_tokens ?? rawTokensEst - (compression?.total_tokens_removed ?? 0);
17234
- const compressionSavingsUsd = Math.max(0, rawTokensEst - sentTokensEst) / 1e6 * inputPricePerMillion;
17236
+ const compressionTokens = compression?.total_tokens_saved_with_cli_filtering ?? compression?.total_tokens_removed ?? Math.max(0, rawTokensEst - sentTokensEst);
17237
+ const compressionSavingsUsd = stats.summary?.cost?.breakdown?.compression_savings_usd ?? Math.max(0, compressionTokens) / 1e6 * inputPricePerMillion;
17235
17238
  return {
17236
17239
  rawTokensEst,
17237
17240
  sentTokensEst,
@@ -17239,7 +17242,9 @@ function read(stats, inputPricePerMillion) {
17239
17242
  retrieveHops: stats.summary?.mcp?.retrievals ?? 0,
17240
17243
  cacheReadTokens: stats.prefix_cache?.totals?.cache_read_tokens ?? 0,
17241
17244
  cacheSavingsUsd: stats.summary?.cost?.breakdown?.cache_savings_usd ?? 0,
17242
- compressionSavingsUsd
17245
+ compressionTokens,
17246
+ compressionSavingsUsd,
17247
+ compressionPct: compression?.avg_compression_pct ?? 0
17243
17248
  };
17244
17249
  }
17245
17250
  function mapStatsToSavings(stats, prev, inputPricePerMillion = DEFAULT_INPUT_PRICE_PER_MILLION) {
@@ -17252,7 +17257,10 @@ function mapStatsToSavings(stats, prev, inputPricePerMillion = DEFAULT_INPUT_PRI
17252
17257
  retrieveHops: d3(next.retrieveHops, prev.retrieveHops),
17253
17258
  cacheReadTokens: d3(next.cacheReadTokens, prev.cacheReadTokens),
17254
17259
  cacheSavingsUsd: d3(next.cacheSavingsUsd, prev.cacheSavingsUsd),
17255
- compressionSavingsUsd: d3(next.compressionSavingsUsd, prev.compressionSavingsUsd)
17260
+ compressionTokens: d3(next.compressionTokens, prev.compressionTokens),
17261
+ compressionSavingsUsd: d3(next.compressionSavingsUsd, prev.compressionSavingsUsd),
17262
+ // RATE — carry the latest absolute value through, never diff it.
17263
+ compressionPct: next.compressionPct
17256
17264
  };
17257
17265
  return { next, delta };
17258
17266
  }
@@ -17275,7 +17283,7 @@ var HeadroomStatsReporter = class {
17275
17283
  this.deps.inputPricePerMillionUsd ?? DEFAULT_INPUT_PRICE_PER_MILLION
17276
17284
  );
17277
17285
  this.prev = next;
17278
- if (delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0 || delta.compressionSavingsUsd > 0) {
17286
+ if (delta.compressionTokens > 0 || delta.compressionSavingsUsd > 0 || delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0) {
17279
17287
  await this.deps.postSavings(delta);
17280
17288
  }
17281
17289
  } catch {
@@ -17448,7 +17456,7 @@ function checkForUpdates() {
17448
17456
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17449
17457
  if (process.env.CI) return;
17450
17458
  if (!process.stdout.isTTY) return;
17451
- const current = true ? "2.39.78" : null;
17459
+ const current = true ? "2.39.80" : null;
17452
17460
  if (!current) return;
17453
17461
  const cache = readCache();
17454
17462
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17886,7 +17894,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
17886
17894
  detached: false
17887
17895
  });
17888
17896
  function currentCliVersion() {
17889
- return true ? "2.39.78" : null;
17897
+ return true ? "2.39.80" : null;
17890
17898
  }
17891
17899
  function runCmd(cmd, args2, timeoutMs) {
17892
17900
  return new Promise((resolve7) => {
@@ -23683,6 +23691,14 @@ function looksLikeAuthFailure(text) {
23683
23691
  return AUTH_FAILURE_RE.test(text);
23684
23692
  }
23685
23693
  var AUTH_FAILURE_MESSAGE = "\u{1F512} **Authentication failed \u2014 your agent credentials are invalid or expired (API 401).**\n\nTap [Re-authenticate this agent](codeam://reauth) to renew your credentials in Profile \u203A Agents, then send your message again.";
23694
+ var TURN_FAILURE_MESSAGE = "\u26A0\uFE0F **The agent hit an error and couldn\u2019t finish this turn.** Please send your message again.";
23695
+ function failureBubble(opts) {
23696
+ if (looksLikeAuthFailure(opts.detail) || looksLikeAuthFailure(opts.recentStderr)) {
23697
+ return AUTH_FAILURE_MESSAGE;
23698
+ }
23699
+ if (!opts.hadText) return TURN_FAILURE_MESSAGE;
23700
+ return null;
23701
+ }
23686
23702
  async function runAcpSession(opts) {
23687
23703
  const publisher = new AcpPublisher({
23688
23704
  sessionId: opts.sessionId,
@@ -23944,16 +23960,18 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
23944
23960
  log.info("acpRunner", `start_task \u2190 done stopReason=${reply.stopReason ?? "?"} id=${cmd.id.slice(0, 8)}`);
23945
23961
  await relay.sendResult(cmd.id, "completed", { stopReason: reply.stopReason });
23946
23962
  } catch (err) {
23963
+ const hadText = streaming.getCurrentText().trim().length > 0;
23947
23964
  await recoverFromFailedTurn(client2, streaming);
23948
23965
  const detail = describeError(err);
23949
23966
  log.warn("acpRunner", `prompt failed: ${detail}`);
23950
- if (looksLikeAuthFailure(detail) || looksLikeAuthFailure(recentStderr.join("\n"))) {
23951
- await publisher.publishOutput({
23952
- type: "text",
23953
- content: AUTH_FAILURE_MESSAGE,
23954
- done: true
23955
- });
23956
- history.appendAgentReply(AUTH_FAILURE_MESSAGE);
23967
+ const bubble = failureBubble({
23968
+ detail,
23969
+ recentStderr: recentStderr.join("\n"),
23970
+ hadText
23971
+ });
23972
+ if (bubble) {
23973
+ await publisher.publishOutput({ type: "text", content: bubble, done: true });
23974
+ history.appendAgentReply(bubble);
23957
23975
  void history.flush();
23958
23976
  }
23959
23977
  await relay.sendResult(cmd.id, "failed", { error: detail });
@@ -28591,7 +28609,7 @@ function checkChokidar() {
28591
28609
  }
28592
28610
  async function doctor(args2 = []) {
28593
28611
  const json = args2.includes("--json");
28594
- const cliVersion = true ? "2.39.78" : "0.0.0-dev";
28612
+ const cliVersion = true ? "2.39.80" : "0.0.0-dev";
28595
28613
  const apiBase2 = resolveApiBaseUrl();
28596
28614
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
28597
28615
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -28790,7 +28808,7 @@ async function completion(args2) {
28790
28808
  // src/commands/version.ts
28791
28809
  var import_picocolors14 = __toESM(require("picocolors"));
28792
28810
  function version2() {
28793
- const v = true ? "2.39.78" : "unknown";
28811
+ const v = true ? "2.39.80" : "unknown";
28794
28812
  console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
28795
28813
  }
28796
28814
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.39.78",
3
+ "version": "2.39.80",
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",