codeam-cli 2.67.0 → 2.67.2

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,23 @@ 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.67.1] — 2026-08-24
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** A Headroom proxy that is briefly down is not an invalid credential
12
+ - **cli:** Log the credential-invalid report instead of firing it blind
13
+
14
+ ## [2.67.0] — 2026-08-24
15
+
16
+ ### Added
17
+
18
+ - **cli:** Ask the backend for a named preview tunnel when the env has none
19
+
20
+ ### Fixed
21
+
22
+ - **cli:** Cap how long a self-update restart can be deferred
23
+
7
24
  ## [2.66.1] — 2026-08-24
8
25
 
9
26
  ### Fixed
package/dist/index.js CHANGED
@@ -8081,7 +8081,7 @@ function readAnonId() {
8081
8081
  }
8082
8082
  function superProperties() {
8083
8083
  return {
8084
- cliVersion: true ? "2.67.0" : "0.0.0-dev",
8084
+ cliVersion: true ? "2.67.2" : "0.0.0-dev",
8085
8085
  nodeVersion: process.version,
8086
8086
  platform: process.platform,
8087
8087
  arch: process.arch,
@@ -8323,7 +8323,7 @@ var http = __toESM(require("http"));
8323
8323
  // package.json
8324
8324
  var package_default = {
8325
8325
  name: "codeam-cli",
8326
- version: "2.67.0",
8326
+ version: "2.67.2",
8327
8327
  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.",
8328
8328
  type: "commonjs",
8329
8329
  main: "dist/index.js",
@@ -9855,7 +9855,7 @@ var CommandRelayService = class _CommandRelayService {
9855
9855
  // fresh + clear the "CLI update available" banner after a self-update
9856
9856
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9857
9857
  // pair/reconnect). Older backends ignore the extra field.
9858
- ..."2.67.0" ? { ideVersion: "2.67.0" } : {}
9858
+ ..."2.67.2" ? { ideVersion: "2.67.2" } : {}
9859
9859
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9860
9860
  }
9861
9861
  /**
@@ -14938,6 +14938,8 @@ function validateClaudeToken(token) {
14938
14938
  }
14939
14939
  const expiresAt = typeof oauth.expiresAt === "number" ? oauth.expiresAt : null;
14940
14940
  if (expiresAt === null) return { status: "unknown" };
14941
+ const hasAnyToken = typeof oauth.accessToken === "string" && oauth.accessToken.length > 0 || typeof oauth.refreshToken === "string" && oauth.refreshToken.length > 0;
14942
+ if (!hasAnyToken) return { status: "unknown" };
14941
14943
  if (expiresAt >= Date.now()) return { status: "valid" };
14942
14944
  const hasRefresh = typeof oauth.refreshToken === "string" && oauth.refreshToken.length > 0;
14943
14945
  if (hasRefresh) return { status: "unknown" };
@@ -22080,7 +22082,7 @@ async function autoUpgradeBeforeCriticalCommand() {
22080
22082
  if (process.env.NODE_ENV === "test") return;
22081
22083
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22082
22084
  if (process.env.CI) return;
22083
- const current2 = true ? "2.67.0" : null;
22085
+ const current2 = true ? "2.67.2" : null;
22084
22086
  if (!current2) return;
22085
22087
  const cache = readCache();
22086
22088
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22097,7 +22099,7 @@ function checkForUpdates() {
22097
22099
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22098
22100
  if (process.env.CI) return;
22099
22101
  if (!process.stdout.isTTY) return;
22100
- const current2 = true ? "2.67.0" : null;
22102
+ const current2 = true ? "2.67.2" : null;
22101
22103
  if (!current2) return;
22102
22104
  const cache = readCache();
22103
22105
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22120,7 +22122,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
22120
22122
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
22121
22123
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
22122
22124
  function currentCliVersion() {
22123
- return true ? "2.67.0" : null;
22125
+ return true ? "2.67.2" : null;
22124
22126
  }
22125
22127
  async function installedVersion(deps) {
22126
22128
  const ls = await deps.run(
@@ -36074,7 +36076,11 @@ You have two options:
36074
36076
  }
36075
36077
 
36076
36078
  // src/agents/acp/wakeCredentialProbe.ts
36079
+ function usesHouseProxy(env = process.env) {
36080
+ return /\/agent-proxy(\/|$)/.test(env.ANTHROPIC_BASE_URL ?? "");
36081
+ }
36077
36082
  async function localCredentialExpiryStatus(agent) {
36083
+ if (usesHouseProxy()) return "unknown";
36078
36084
  if (!/claude/i.test(agent)) return "unknown";
36079
36085
  const token = await extractLocalClaudeToken();
36080
36086
  if (!token) return "unknown";
@@ -37436,8 +37442,14 @@ var HOUSE_AGENT_LIMIT_RE = /HOUSE_AGENT_CEILING|CodeAgent Cloud[^\n]{0,60}(?:usa
37436
37442
  function looksLikeHouseAgentLimit(text) {
37437
37443
  return HOUSE_AGENT_LIMIT_RE.test(text);
37438
37444
  }
37445
+ var LOCAL_PROXY_RE = /(?:127\.0\.0\.1|localhost|\[::1\]):\d+/i;
37446
+ var CONNECTION_ERROR_RE = /ECONNREFUSED|ECONNRESET|ETIMEDOUT|EHOSTUNREACH|socket hang up|fetch failed|network error|connection (?:refused|reset|closed)/i;
37447
+ function looksLikeLocalProxyUnavailable(text) {
37448
+ return LOCAL_PROXY_RE.test(text) && CONNECTION_ERROR_RE.test(text);
37449
+ }
37439
37450
  function looksLikeAuthFailure(text) {
37440
37451
  if (looksLikeHouseAgentLimit(text)) return false;
37452
+ if (looksLikeLocalProxyUnavailable(text)) return false;
37441
37453
  return AUTH_FAILURE_RE.test(text);
37442
37454
  }
37443
37455
  function replyIsAuthFailure(finalText) {
@@ -37455,7 +37467,14 @@ function houseAgentLimitMessage(text) {
37455
37467
  const canUpgrade = /upgrade to pro/i.test(text);
37456
37468
  return "\u{1F4CA} **You\u2019ve reached your daily CodeAgent Cloud limit.**\n\nThe free CodeAgent Cloud agent has a daily usage ceiling that resets at midnight UTC. This is a usage limit, not a problem with your login \u2014 re-authenticating won\u2019t change it. " + (canUpgrade ? "To keep going now, upgrade to **Pro** for a higher ceiling, or connect your own agent (Claude, Codex, \u2026) in **Profile \u203A Agents** to run without this limit." : "To keep going now, connect your own agent (Claude, Codex, \u2026) in **Profile \u203A Agents** to run without this limit, or wait for the reset.");
37457
37469
  }
37458
- 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.";
37470
+ var AUTH_FAILURE_MESSAGE = (
37471
+ // ⚠️ Do NOT name a status code here. This bubble fires for several
37472
+ // different failures, and the old hard-coded "(API 401)" told users the API
37473
+ // had answered 401 when it never had — it also sent a live investigation
37474
+ // hunting for 401s in proxy logs that were serving 200s throughout
37475
+ // (2026-08-24). Say what happened, not a number we did not see.
37476
+ "\u{1F512} **Authentication failed \u2014 your agent credentials are invalid or expired.**\n\nTap [Re-authenticate this agent](codeam://reauth) to renew your credentials in Profile \u203A Agents, then send your message again."
37477
+ );
37459
37478
  var CURSOR_UPGRADE_MESSAGE = "\u26A1 **Cursor needs a paid plan to run the agent.**\n\nThe headless Cursor Agent requires Cursor **Pro** \u2014 your Free plan\u2019s included usage does NOT cover Agent runs, even with quota left. This is your Cursor account (not CodeAgent). Upgrade, then send your message again:\n\n[Upgrade to Cursor Pro \u2192](https://cursor.com/dashboard)";
37460
37479
  var ONE_M_CREDITS_MESSAGE = "\u{1F504} **Reconnect your Claude subscription to continue.**\n\nClaude requested 1M-context but your account doesn\u2019t have the usage credits for it on this credential. Reconnecting refreshes your subscription so the agent can keep going \u2014 disabling 1M context won\u2019t fix a credits gate.\n\nTap [Reconnect this agent](codeam://reauth) to reconnect your Claude subscription in Profile \u203A Agents, then send your message again.";
37461
37480
  var TURN_FAILURE_MESSAGE = "\u26A0\uFE0F **The agent hit an error and couldn\u2019t finish this turn.** Please send your message again.";
@@ -37553,6 +37572,10 @@ async function reportCredentialInvalid(opts, fetchImpl = fetch) {
37553
37572
  pluginId: opts.pluginId,
37554
37573
  ...opts.reason ? { reason: opts.reason } : {}
37555
37574
  });
37575
+ log.info(
37576
+ "acpRunner",
37577
+ `credential-invalid \u2192 reporting agent=${opts.agent} reason=${opts.reason ?? "unspecified"}`
37578
+ );
37556
37579
  try {
37557
37580
  const makeHeaders = (token) => ({
37558
37581
  "Content-Type": "application/json",
@@ -37570,10 +37593,21 @@ async function reportCredentialInvalid(opts, fetchImpl = fetch) {
37570
37593
  opts.pollSecret
37571
37594
  );
37572
37595
  if (freshToken !== null) {
37573
- await fetchImpl(url2, { method: "POST", headers: makeHeaders(freshToken), body });
37596
+ const retried = await fetchImpl(url2, {
37597
+ method: "POST",
37598
+ headers: makeHeaders(freshToken),
37599
+ body
37600
+ });
37601
+ log.info("acpRunner", `credential-invalid \u2190 ${retried.status} (after token refresh)`);
37602
+ return;
37574
37603
  }
37575
37604
  }
37576
- } catch {
37605
+ log.info("acpRunner", `credential-invalid \u2190 ${response.status}`);
37606
+ } catch (err) {
37607
+ log.warn(
37608
+ "acpRunner",
37609
+ `credential-invalid \u2192 failed: ${err instanceof Error ? err.message : String(err)}`
37610
+ );
37577
37611
  }
37578
37612
  }
37579
37613
  async function postCredentialSync(opts, fetchImpl = fetch) {
@@ -45724,7 +45758,7 @@ function checkChokidar() {
45724
45758
  }
45725
45759
  async function doctor(args2 = []) {
45726
45760
  const json = args2.includes("--json");
45727
- const cliVersion = true ? "2.67.0" : "0.0.0-dev";
45761
+ const cliVersion = true ? "2.67.2" : "0.0.0-dev";
45728
45762
  const apiBase2 = resolveApiBaseUrl();
45729
45763
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
45730
45764
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -46115,7 +46149,7 @@ async function mcpRun(args2) {
46115
46149
  // src/commands/version.ts
46116
46150
  var import_picocolors15 = __toESM(require("picocolors"));
46117
46151
  function version2() {
46118
- const v = true ? "2.67.0" : "unknown";
46152
+ const v = true ? "2.67.2" : "unknown";
46119
46153
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
46120
46154
  }
46121
46155
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.67.0",
3
+ "version": "2.67.2",
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",