codeam-cli 2.61.5 → 2.61.7

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.61.5] — 2026-07-16
8
+
9
+ ### Added
10
+
11
+ - **cli:** ACP chrome-leak canary + detector (stability monitor, part 2)
12
+ - **ci:** Canary seeds onboarding + auths via in-house MiniMax backend
13
+
14
+ ### Fixed
15
+
16
+ - **ci:** Canary auths by subscription (CLAUDE_CODE_OAUTH_TOKEN), not API key
17
+ - **cli:** Stop the changeset reporter from spamming install/SDK files
18
+
7
19
  ## [2.61.4] — 2026-07-16
8
20
 
9
21
  ### Fixed
package/dist/index.js CHANGED
@@ -5975,7 +5975,7 @@ function readAnonId() {
5975
5975
  }
5976
5976
  function superProperties() {
5977
5977
  return {
5978
- cliVersion: true ? "2.61.5" : "0.0.0-dev",
5978
+ cliVersion: true ? "2.61.7" : "0.0.0-dev",
5979
5979
  nodeVersion: process.version,
5980
5980
  platform: process.platform,
5981
5981
  arch: process.arch,
@@ -6156,7 +6156,7 @@ var os4 = __toESM(require("os"));
6156
6156
  // package.json
6157
6157
  var package_default = {
6158
6158
  name: "codeam-cli",
6159
- version: "2.61.5",
6159
+ version: "2.61.7",
6160
6160
  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.",
6161
6161
  type: "commonjs",
6162
6162
  main: "dist/index.js",
@@ -6225,7 +6225,7 @@ var package_default = {
6225
6225
  url: "https://github.com/sponsors/edgar-durand"
6226
6226
  },
6227
6227
  engines: {
6228
- node: ">=20.0.0"
6228
+ node: ">=22.0.0"
6229
6229
  },
6230
6230
  dependencies: {
6231
6231
  "@agentclientprotocol/claude-agent-acp": "0.59.0",
@@ -7299,7 +7299,7 @@ var CommandRelayService = class _CommandRelayService {
7299
7299
  // fresh + clear the "CLI update available" banner after a self-update
7300
7300
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
7301
7301
  // pair/reconnect). Older backends ignore the extra field.
7302
- ..."2.61.5" ? { ideVersion: "2.61.5" } : {}
7302
+ ..."2.61.7" ? { ideVersion: "2.61.7" } : {}
7303
7303
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
7304
7304
  }
7305
7305
  /**
@@ -17900,7 +17900,7 @@ async function autoUpgradeBeforeCriticalCommand() {
17900
17900
  if (process.env.NODE_ENV === "test") return;
17901
17901
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17902
17902
  if (process.env.CI) return;
17903
- const current = true ? "2.61.5" : null;
17903
+ const current = true ? "2.61.7" : null;
17904
17904
  if (!current) return;
17905
17905
  const cache = readCache();
17906
17906
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17917,7 +17917,7 @@ function checkForUpdates() {
17917
17917
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17918
17918
  if (process.env.CI) return;
17919
17919
  if (!process.stdout.isTTY) return;
17920
- const current = true ? "2.61.5" : null;
17920
+ const current = true ? "2.61.7" : null;
17921
17921
  if (!current) return;
17922
17922
  const cache = readCache();
17923
17923
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17937,7 +17937,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
17937
17937
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
17938
17938
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
17939
17939
  function currentCliVersion() {
17940
- return true ? "2.61.5" : null;
17940
+ return true ? "2.61.7" : null;
17941
17941
  }
17942
17942
  function runCmd(cmd, args2, timeoutMs) {
17943
17943
  return new Promise((resolve8) => {
@@ -18254,6 +18254,12 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process23.s
18254
18254
  stdio: ["ignore", "pipe", "pipe"],
18255
18255
  detached: false
18256
18256
  });
18257
+ var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process23.spawn)(process.execPath, [process.argv[1]], {
18258
+ cwd,
18259
+ env: { ...process.env, ...env, CODEAM_AUTO_APPROVE: "1" },
18260
+ stdio: ["ignore", "pipe", "pipe"],
18261
+ detached: false
18262
+ });
18257
18263
  var defaultOnIdentityRejected = () => {
18258
18264
  deleteHostIdentity();
18259
18265
  log.warn("host-agent", "host identity rejected by backend \u2014 wiped sealed identity, exiting");
@@ -18268,6 +18274,7 @@ var HostAgentSupervisor = class {
18268
18274
  this.identity = identity;
18269
18275
  this.deps = deps;
18270
18276
  this.spawnChild = deps.spawnChild ?? defaultSpawner;
18277
+ this.resumeSpawner = deps.resumeSpawner ?? defaultResumeSpawner;
18271
18278
  this.resolveAgentAuth = deps.resolveAgentAuth ?? unsealAgentAuth;
18272
18279
  this.setupHeadroom = deps.setupHeadroom ?? setupHeadroomForSelfHosted;
18273
18280
  this.isHeadroomInstalled = deps.isHeadroomInstalled ?? (() => defaultHeadroomRunner.which("headroom"));
@@ -18284,6 +18291,7 @@ var HostAgentSupervisor = class {
18284
18291
  deps;
18285
18292
  children = /* @__PURE__ */ new Map();
18286
18293
  spawnChild;
18294
+ resumeSpawner;
18287
18295
  resolveAgentAuth;
18288
18296
  setupHeadroom;
18289
18297
  /** Probe whether Headroom is already installed (defaults to `which headroom`). */
@@ -18344,6 +18352,7 @@ var HostAgentSupervisor = class {
18344
18352
  void this.beat();
18345
18353
  this.heartbeatTimer = setInterval(() => void this.beat(), HEARTBEAT_INTERVAL_MS);
18346
18354
  this.heartbeatTimer.unref?.();
18355
+ this.resumePersistedSession();
18347
18356
  void reportSessionEvent(
18348
18357
  { hostId: this.identity.hostId, hostToken: this.identity.hostToken },
18349
18358
  { event: "reconcile", activeDeployIds: this.activeSessions().map((s) => s.id) }
@@ -18933,6 +18942,60 @@ var HostAgentSupervisor = class {
18933
18942
  spawnSessionChild(env, cwd, args2 = []) {
18934
18943
  return this.spawnChild({ ...env, ...readHeadroomChildEnv() }, cwd, args2);
18935
18944
  }
18945
+ /**
18946
+ * Auto-resume the user's last active session on supervisor boot (2026-07-16
18947
+ * churn fix). Before this, a restart / self-update killed the session child
18948
+ * and never re-spawned it — the session lost its heartbeat, went "CLI
18949
+ * disconnected", and the user had to reconnect by hand (churn right after an
18950
+ * update). Spawn bare `codeam` via the resume spawner (reconnects the SAME
18951
+ * pluginId via start(), then heartbeats) so the session comes back on its own
18952
+ * in its ORIGINAL ACP shape (self-hosted/codespace = ACP-only; the resume
18953
+ * spawner sets CODEAM_AUTO_APPROVE=1 to keep the local baton/native-TUI OFF).
18954
+ *
18955
+ * Best-effort + guarded: no-op when there's no persisted session, when the
18956
+ * persisted session lacks the reconnect material (pluginId + pollSecret +
18957
+ * agent), or when a fresh deploy already owns a child this boot.
18958
+ */
18959
+ resumePersistedSession() {
18960
+ try {
18961
+ if (this.children.size > 0) return;
18962
+ const session = getActiveSession();
18963
+ if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
18964
+ const cwd = process.cwd();
18965
+ const proc = this.resumeSpawner({ ...readHeadroomChildEnv() }, cwd);
18966
+ const child = {
18967
+ deployId: session.id,
18968
+ proc,
18969
+ agent: session.agent,
18970
+ startedAt: Date.now()
18971
+ };
18972
+ this.children.set(session.id, child);
18973
+ let tail = "";
18974
+ const appendTail = (buf) => {
18975
+ tail = (tail + buf.toString("utf8")).slice(-2e3);
18976
+ };
18977
+ proc.stdout?.on("data", appendTail);
18978
+ proc.stderr?.on("data", appendTail);
18979
+ proc.once("exit", (code) => {
18980
+ if (this.children.get(session.id)?.proc === proc) this.children.delete(session.id);
18981
+ if (typeof code === "number" && code !== 0) {
18982
+ log.warn(
18983
+ "host-agent",
18984
+ `resumed session ${session.id.slice(0, 8)} exited (${code}): ${tail.trim().slice(-300)}`
18985
+ );
18986
+ }
18987
+ });
18988
+ log.info(
18989
+ "host-agent",
18990
+ `resumed session ${session.id.slice(0, 8)} pluginId=${session.pluginId.slice(0, 12)} (ACP)`
18991
+ );
18992
+ } catch (err) {
18993
+ log.warn(
18994
+ "host-agent",
18995
+ `resume persisted session failed (best-effort): ${err instanceof Error ? err.message : String(err)}`
18996
+ );
18997
+ }
18998
+ }
18936
18999
  /**
18937
19000
  * Run the backend-supplied per-agent CLI install script (e.g.
18938
19001
  * `claude.ai/install.sh`, `npm i -g @openai/codex`). Best-effort + bounded:
@@ -37277,7 +37340,7 @@ function checkChokidar() {
37277
37340
  }
37278
37341
  async function doctor(args2 = []) {
37279
37342
  const json = args2.includes("--json");
37280
- const cliVersion = true ? "2.61.5" : "0.0.0-dev";
37343
+ const cliVersion = true ? "2.61.7" : "0.0.0-dev";
37281
37344
  const apiBase2 = resolveApiBaseUrl();
37282
37345
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
37283
37346
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -37788,7 +37851,7 @@ async function mcpRun(args2) {
37788
37851
  // src/commands/version.ts
37789
37852
  var import_picocolors15 = __toESM(require("picocolors"));
37790
37853
  function version2() {
37791
- const v = true ? "2.61.5" : "unknown";
37854
+ const v = true ? "2.61.7" : "unknown";
37792
37855
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
37793
37856
  }
37794
37857
 
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/postinstall.ts
5
+ var c = {
6
+ reset: "\x1B[0m",
7
+ bold: "\x1B[1m",
8
+ dim: "\x1B[2m",
9
+ green: "\x1B[32m",
10
+ cyan: "\x1B[36m",
11
+ violet: "\x1B[35m",
12
+ white: "\x1B[97m"
13
+ };
14
+ var lines = [
15
+ "",
16
+ ` ${c.violet}${c.bold}codeam-cli${c.reset} ${c.dim}\u2014 Claude Code remote control${c.reset}`,
17
+ "",
18
+ ` ${c.dim}1.${c.reset} Pair your phone:`,
19
+ ` ${c.cyan}codeam pair${c.reset}`,
20
+ "",
21
+ ` ${c.dim}2.${c.reset} Launch Claude Code with mobile control:`,
22
+ ` ${c.cyan}codeam${c.reset}`,
23
+ "",
24
+ ` ${c.dim}Other commands:${c.reset}`,
25
+ ` ${c.white}codeam sessions${c.reset} ${c.dim}list paired devices${c.reset}`,
26
+ ` ${c.white}codeam status${c.reset} ${c.dim}show connection info${c.reset}`,
27
+ ` ${c.white}codeam logout${c.reset} ${c.dim}remove all sessions${c.reset}`,
28
+ "",
29
+ ` ${c.dim}Requires Claude Code:${c.reset} ${c.green}npm install -g @anthropic-ai/claude-code${c.reset}`,
30
+ ` ${c.dim}Mobile app:${c.reset} ${c.green}https://www.codeagent-mobile.com${c.reset}`,
31
+ ""
32
+ ];
33
+ process.stdout.write(lines.join("\n") + "\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.61.5",
3
+ "version": "2.61.7",
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",
@@ -69,7 +69,7 @@
69
69
  "url": "https://github.com/sponsors/edgar-durand"
70
70
  },
71
71
  "engines": {
72
- "node": ">=20.0.0"
72
+ "node": ">=22.0.0"
73
73
  },
74
74
  "dependencies": {
75
75
  "@agentclientprotocol/claude-agent-acp": "0.59.0",