codeam-cli 2.39.74 → 2.39.76

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.75] — 2026-06-21
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Render pairing code + QR on stderr, not stdout (fixes #356)
12
+
13
+ ## [2.39.74] — 2026-06-21
14
+
15
+ ### Fixed
16
+
17
+ - **cli:** Preview no longer dies silently on string setup_commands
18
+
7
19
  ## [2.39.73] — 2026-06-21
8
20
 
9
21
  ### Fixed
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.74" : "0.0.0-dev",
5393
+ cliVersion: true ? "2.39.76" : "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.74",
5552
+ version: "2.39.76",
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",
@@ -8295,18 +8295,16 @@ function boxRow(content, visibleLength) {
8295
8295
  }
8296
8296
  function showPairingCode(code) {
8297
8297
  const spaced = code.split("").join(" ");
8298
- console.log(BOX_BORDER_TOP);
8298
+ out(BOX_BORDER_TOP);
8299
8299
  const label = " Code: ";
8300
8300
  const codeVisible = `${label}${spaced}`.length;
8301
- console.log(
8302
- boxRow(`${label}${import_picocolors.default.bold(import_picocolors.default.yellow(spaced))}`, codeVisible)
8303
- );
8304
- console.log(BOX_BORDER_BOT);
8305
- console.log("");
8301
+ out(boxRow(`${label}${import_picocolors.default.bold(import_picocolors.default.yellow(spaced))}`, codeVisible));
8302
+ out(BOX_BORDER_BOT);
8303
+ out("");
8306
8304
  import_qrcode_terminal.default.generate(code, { small: true }, (qr) => {
8307
- qr.split("\n").forEach((line) => console.log(" " + line));
8305
+ qr.split("\n").forEach((line) => out(" " + line));
8308
8306
  });
8309
- console.log("");
8307
+ out("");
8310
8308
  }
8311
8309
  function formatRemaining(expiresAt) {
8312
8310
  const secs = Math.max(0, Math.floor((expiresAt - Date.now()) / 1e3));
@@ -13321,8 +13319,11 @@ async function link(args2 = []) {
13321
13319
  }
13322
13320
  spin.stop("Got pairing code");
13323
13321
  showPairingCode(pairing.code);
13324
- console.log(import_picocolors2.default.dim(" Scan the QR or enter the code in CodeAgent Mobile."));
13325
- console.log("");
13322
+ process.stderr.write(
13323
+ `${import_picocolors2.default.dim(" Scan the QR or enter the code in CodeAgent Mobile.")}
13324
+
13325
+ `
13326
+ );
13326
13327
  const waitSpin = dist_exports.spinner();
13327
13328
  const waitMsg = () => `Waiting for mobile pair... \xB7 expires in ${formatRemaining(pairing.expiresAt)}`;
13328
13329
  waitSpin.start(waitMsg());
@@ -17215,30 +17216,34 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
17215
17216
  }
17216
17217
 
17217
17218
  // src/services/headroom/stats-reporter.ts
17219
+ var DEFAULT_INPUT_PRICE_PER_MILLION = 3;
17218
17220
  var ZERO = {
17219
17221
  rawTokensEst: 0,
17220
17222
  sentTokensEst: 0,
17221
17223
  cachedTokens: 0,
17222
17224
  retrieveHops: 0,
17223
17225
  cacheReadTokens: 0,
17224
- cacheSavingsUsd: 0
17226
+ cacheSavingsUsd: 0,
17227
+ compressionSavingsUsd: 0
17225
17228
  };
17226
- function read(stats) {
17229
+ function read(stats, inputPricePerMillion) {
17227
17230
  const totals = stats.agent_usage?.totals;
17228
17231
  const compression = stats.summary?.compression;
17229
17232
  const rawTokensEst = totals?.before_tokens ?? compression?.total_tokens_before_with_cli_filtering ?? 0;
17230
17233
  const sentTokensEst = totals?.after_tokens ?? rawTokensEst - (compression?.total_tokens_removed ?? 0);
17234
+ const compressionSavingsUsd = Math.max(0, rawTokensEst - sentTokensEst) / 1e6 * inputPricePerMillion;
17231
17235
  return {
17232
17236
  rawTokensEst,
17233
17237
  sentTokensEst,
17234
17238
  cachedTokens: 0,
17235
17239
  retrieveHops: stats.summary?.mcp?.retrievals ?? 0,
17236
17240
  cacheReadTokens: stats.prefix_cache?.totals?.cache_read_tokens ?? 0,
17237
- cacheSavingsUsd: stats.summary?.cost?.breakdown?.cache_savings_usd ?? 0
17241
+ cacheSavingsUsd: stats.summary?.cost?.breakdown?.cache_savings_usd ?? 0,
17242
+ compressionSavingsUsd
17238
17243
  };
17239
17244
  }
17240
- function mapStatsToSavings(stats, prev) {
17241
- const next = read(stats);
17245
+ function mapStatsToSavings(stats, prev, inputPricePerMillion = DEFAULT_INPUT_PRICE_PER_MILLION) {
17246
+ const next = read(stats, inputPricePerMillion);
17242
17247
  const d3 = (a, b) => Math.max(0, a - b);
17243
17248
  const delta = next.rawTokensEst < prev.rawTokensEst ? next : {
17244
17249
  rawTokensEst: d3(next.rawTokensEst, prev.rawTokensEst),
@@ -17246,7 +17251,8 @@ function mapStatsToSavings(stats, prev) {
17246
17251
  cachedTokens: d3(next.cachedTokens, prev.cachedTokens),
17247
17252
  retrieveHops: d3(next.retrieveHops, prev.retrieveHops),
17248
17253
  cacheReadTokens: d3(next.cacheReadTokens, prev.cacheReadTokens),
17249
- cacheSavingsUsd: d3(next.cacheSavingsUsd, prev.cacheSavingsUsd)
17254
+ cacheSavingsUsd: d3(next.cacheSavingsUsd, prev.cacheSavingsUsd),
17255
+ compressionSavingsUsd: d3(next.compressionSavingsUsd, prev.compressionSavingsUsd)
17250
17256
  };
17251
17257
  return { next, delta };
17252
17258
  }
@@ -17263,9 +17269,13 @@ var HeadroomStatsReporter = class {
17263
17269
  }
17264
17270
  async tick() {
17265
17271
  try {
17266
- const { next, delta } = mapStatsToSavings(await this.deps.fetchStats(), this.prev);
17272
+ const { next, delta } = mapStatsToSavings(
17273
+ await this.deps.fetchStats(),
17274
+ this.prev,
17275
+ this.deps.inputPricePerMillionUsd ?? DEFAULT_INPUT_PRICE_PER_MILLION
17276
+ );
17267
17277
  this.prev = next;
17268
- if (delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0) {
17278
+ if (delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0 || delta.compressionSavingsUsd > 0) {
17269
17279
  await this.deps.postSavings(delta);
17270
17280
  }
17271
17281
  } catch {
@@ -17438,7 +17448,7 @@ function checkForUpdates() {
17438
17448
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17439
17449
  if (process.env.CI) return;
17440
17450
  if (!process.stdout.isTTY) return;
17441
- const current = true ? "2.39.74" : null;
17451
+ const current = true ? "2.39.76" : null;
17442
17452
  if (!current) return;
17443
17453
  const cache = readCache();
17444
17454
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17453,6 +17463,11 @@ function checkForUpdates() {
17453
17463
  }
17454
17464
 
17455
17465
  // src/commands/host-agent.ts
17466
+ function resolveInputPricePerMillion(agentId) {
17467
+ const a = agentId.toLowerCase();
17468
+ const model = a.includes("codex") || a.includes("gpt") ? "gpt-5.5" : "claude-sonnet-4";
17469
+ return getPricing(model).input;
17470
+ }
17456
17471
  var HEARTBEAT_INTERVAL_MS = 2e4;
17457
17472
  var SELF_UPDATE_PKG = "codeam-cli";
17458
17473
  var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
@@ -17463,6 +17478,9 @@ function maybeStartHeadroomReporter(ctx) {
17463
17478
  try {
17464
17479
  const ingestUrl = process.env["HEADROOM_SAVINGS_INGEST_URL"] ?? `${resolveApiBaseUrl()}/api/codespaces/${ctx.codespaceId}/headroom-savings`;
17465
17480
  const reporter = new HeadroomStatsReporter({
17481
+ inputPricePerMillionUsd: resolveInputPricePerMillion(
17482
+ process.env["HEADROOM_AGENT"] ?? "claude"
17483
+ ),
17466
17484
  fetchStats: async () => {
17467
17485
  const res = await fetch("http://localhost:8787/stats");
17468
17486
  return res.json();
@@ -17837,7 +17855,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
17837
17855
  detached: false
17838
17856
  });
17839
17857
  function currentCliVersion() {
17840
- return true ? "2.39.74" : null;
17858
+ return true ? "2.39.76" : null;
17841
17859
  }
17842
17860
  function runCmd(cmd, args2, timeoutMs) {
17843
17861
  return new Promise((resolve7) => {
@@ -26090,8 +26108,11 @@ async function pair(args2 = []) {
26090
26108
  process.exit(0);
26091
26109
  }
26092
26110
  showPairingCode(result.code);
26093
- console.log(import_picocolors5.default.dim(" Scan the QR code or enter the code in CodeAgent Mobile."));
26094
- console.log("");
26111
+ process.stderr.write(
26112
+ `${import_picocolors5.default.dim(" Scan the QR code or enter the code in CodeAgent Mobile.")}
26113
+
26114
+ `
26115
+ );
26095
26116
  const waitSpin = dist_exports.spinner();
26096
26117
  const waitMessage = () => `Waiting for mobile app... \xB7 expires in ${formatRemaining(result.expiresAt)}`;
26097
26118
  waitSpin.start(waitMessage());
@@ -28491,7 +28512,7 @@ function checkChokidar() {
28491
28512
  }
28492
28513
  async function doctor(args2 = []) {
28493
28514
  const json = args2.includes("--json");
28494
- const cliVersion = true ? "2.39.74" : "0.0.0-dev";
28515
+ const cliVersion = true ? "2.39.76" : "0.0.0-dev";
28495
28516
  const apiBase2 = resolveApiBaseUrl();
28496
28517
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
28497
28518
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -28690,7 +28711,7 @@ async function completion(args2) {
28690
28711
  // src/commands/version.ts
28691
28712
  var import_picocolors14 = __toESM(require("picocolors"));
28692
28713
  function version2() {
28693
- const v = true ? "2.39.74" : "unknown";
28714
+ const v = true ? "2.39.76" : "unknown";
28694
28715
  console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
28695
28716
  }
28696
28717
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.39.74",
3
+ "version": "2.39.76",
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",