codeam-cli 2.51.3 → 2.52.0

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,12 @@ 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.51.3] — 2026-06-29
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Stop retrying on terminal enroll-token 4xx (ENROLL_TOKEN_EXPIRED / ENROLL_TOKEN_INVALID)
12
+
7
13
  ## [2.51.2] — 2026-06-29
8
14
 
9
15
  ### Fixed
package/dist/index.js CHANGED
@@ -5397,7 +5397,7 @@ function readAnonId() {
5397
5397
  }
5398
5398
  function superProperties() {
5399
5399
  return {
5400
- cliVersion: true ? "2.51.3" : "0.0.0-dev",
5400
+ cliVersion: true ? "2.52.0" : "0.0.0-dev",
5401
5401
  nodeVersion: process.version,
5402
5402
  platform: process.platform,
5403
5403
  arch: process.arch,
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
5578
5578
  // package.json
5579
5579
  var package_default = {
5580
5580
  name: "codeam-cli",
5581
- version: "2.51.3",
5581
+ version: "2.52.0",
5582
5582
  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.",
5583
5583
  type: "commonjs",
5584
5584
  main: "dist/index.js",
@@ -5893,6 +5893,30 @@ async function postBeadsEvent(input) {
5893
5893
  };
5894
5894
  }
5895
5895
  }
5896
+ async function postCliUpdateEvent(input) {
5897
+ try {
5898
+ const payload = { phase: input.phase };
5899
+ if (input.error) payload.error = input.error;
5900
+ await _transport.postJsonAuthed(
5901
+ `${API_BASE}/api/agents/cli-update/events`,
5902
+ {
5903
+ sessionId: input.sessionId,
5904
+ pluginId: input.pluginId,
5905
+ phase: input.phase,
5906
+ ...input.error ? { error: input.error } : {}
5907
+ },
5908
+ input.pluginAuthToken
5909
+ );
5910
+ return { ok: true };
5911
+ } catch (err) {
5912
+ const e = err;
5913
+ return {
5914
+ ok: false,
5915
+ status: typeof e.statusCode === "number" ? e.statusCode : 0,
5916
+ message: e.message || "unknown"
5917
+ };
5918
+ }
5919
+ }
5896
5920
  async function postBeadsProvisioning(input) {
5897
5921
  try {
5898
5922
  await _transport.postJsonAuthed(
@@ -14829,7 +14853,7 @@ async function autoUpgradeBeforeCriticalCommand() {
14829
14853
  if (process.env.NODE_ENV === "test") return;
14830
14854
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14831
14855
  if (process.env.CI) return;
14832
- const current = true ? "2.51.3" : null;
14856
+ const current = true ? "2.52.0" : null;
14833
14857
  if (!current) return;
14834
14858
  const cache = readCache();
14835
14859
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -14846,7 +14870,7 @@ function checkForUpdates() {
14846
14870
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14847
14871
  if (process.env.CI) return;
14848
14872
  if (!process.stdout.isTTY) return;
14849
- const current = true ? "2.51.3" : null;
14873
+ const current = true ? "2.52.0" : null;
14850
14874
  if (!current) return;
14851
14875
  const cache = readCache();
14852
14876
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -15548,7 +15572,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process15.s
15548
15572
  detached: false
15549
15573
  });
15550
15574
  function currentCliVersion() {
15551
- return true ? "2.51.3" : null;
15575
+ return true ? "2.52.0" : null;
15552
15576
  }
15553
15577
  function runCmd(cmd, args2, timeoutMs) {
15554
15578
  return new Promise((resolve7) => {
@@ -18946,6 +18970,87 @@ var beadsConfigureH = async (ctx, cmd, parsed) => {
18946
18970
  const result = await configureBeads(action, { agent: rawAgentId, cwd: process.cwd(), pluginAuthToken: ctx.pluginAuthToken }, deps);
18947
18971
  await ctx.relay.sendResult(cmd.id, "completed", result);
18948
18972
  };
18973
+ var defaultCliUpdateDeps = {
18974
+ install: () => runNpmInstallLatest(),
18975
+ // "Don't self-relaunch" gate — leave this process running and let the
18976
+ // on-disk update apply on the next natural restart, instead of killing it:
18977
+ // - self-hosted (CODEAM_AUTO_APPROVE=1): the HostAgentSupervisor does NOT
18978
+ // auto-restart children on exit, so exiting would orphan the session.
18979
+ // - codespace (CODESPACES=true): the pair-auto daemon owns a daemon lock +
18980
+ // the relay connection; a naive detached re-exec does NOT replicate the
18981
+ // careful setsid/lock-aware restart the install flow uses, so a failed
18982
+ // respawn would leave the mobile session permanently OFFLINE. Codespaces
18983
+ // sleep/resume often, so the update lands on next wake — safe + non-fatal.
18984
+ // Only a truly local `codeam start` (neither marker) re-execs in place below.
18985
+ isSupervised: () => process.env["CODEAM_AUTO_APPROVE"] === "1" || process.env["CODESPACES"] === "true",
18986
+ relaunch: (args2) => {
18987
+ const entry = process.argv[1];
18988
+ const child = (0, import_child_process21.spawn)(process.execPath, [entry, ...args2], {
18989
+ detached: true,
18990
+ stdio: "inherit"
18991
+ });
18992
+ child.unref();
18993
+ process.exit(0);
18994
+ }
18995
+ };
18996
+ var CLI_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
18997
+ var CLI_UPDATE_MAX_ATTEMPTS = 3;
18998
+ async function runNpmInstallLatest() {
18999
+ let lastError = "";
19000
+ for (let attempt = 1; attempt <= CLI_UPDATE_MAX_ATTEMPTS; attempt++) {
19001
+ const result = await new Promise((resolve7) => {
19002
+ (0, import_child_process21.execFile)(
19003
+ "npm",
19004
+ ["install", "-g", "codeam-cli@latest"],
19005
+ { timeout: CLI_UPDATE_INSTALL_TIMEOUT_MS },
19006
+ (err, _stdout, stderr) => {
19007
+ if (!err) {
19008
+ resolve7({ ok: true });
19009
+ } else {
19010
+ resolve7({ ok: false, error: (stderr || err.message).slice(0, 300) });
19011
+ }
19012
+ }
19013
+ );
19014
+ });
19015
+ if (result.ok) return { ok: true };
19016
+ lastError = result.error ?? "unknown";
19017
+ if (attempt < CLI_UPDATE_MAX_ATTEMPTS) {
19018
+ await new Promise((r) => setTimeout(r, 1e3 * attempt));
19019
+ }
19020
+ }
19021
+ return { ok: false, error: lastError };
19022
+ }
19023
+ var cliSelfUpdateH = (deps = defaultCliUpdateDeps) => async (ctx, cmd) => {
19024
+ const report = async (phase, error) => {
19025
+ if (!ctx.pluginAuthToken) return;
19026
+ try {
19027
+ await postCliUpdateEvent({
19028
+ sessionId: ctx.sessionId,
19029
+ pluginId: ctx.pluginId,
19030
+ pluginAuthToken: ctx.pluginAuthToken,
19031
+ phase,
19032
+ error
19033
+ });
19034
+ } catch {
19035
+ }
19036
+ };
19037
+ await report("updating");
19038
+ const result = await deps.install();
19039
+ if (!result.ok) {
19040
+ await report("failed", result.error?.slice(0, 200));
19041
+ await ctx.relay.sendResult(cmd.id, "completed", { updated: false });
19042
+ return;
19043
+ }
19044
+ await report("relaunching");
19045
+ await ctx.relay.sendResult(cmd.id, "completed", { updated: true });
19046
+ if (deps.isSupervised()) {
19047
+ log.info("cli-update", "supervised context \u2014 update installed, applies on next restart");
19048
+ return;
19049
+ }
19050
+ const origArgs = process.argv.slice(2);
19051
+ log.info("cli-update", `re-execing ${process.argv[1]} with args: ${origArgs.join(" ")}`);
19052
+ deps.relaunch(origArgs);
19053
+ };
18949
19054
  var terminalOpenH = async (ctx, cmd, parsed) => {
18950
19055
  const r = openTerminal({
18951
19056
  cols: typeof parsed.cols === "number" ? parsed.cols : void 0,
@@ -19933,7 +20038,8 @@ var handlers = {
19933
20038
  env_write: envWriteH,
19934
20039
  headroom_configure: headroomConfigureH,
19935
20040
  headroom_budget: headroomBudgetH,
19936
- beads_configure: beadsConfigureH
20041
+ beads_configure: beadsConfigureH,
20042
+ cli_self_update: cliSelfUpdateH()
19937
20043
  };
19938
20044
  async function dispatchCommand(ctx, cmd) {
19939
20045
  if (cmd.type === "beads_action") {
@@ -30802,9 +30908,9 @@ async function probeCodeamPair(provider, workspace) {
30802
30908
  }
30803
30909
  async function stopWorkspaceFromLocal(target) {
30804
30910
  if (target.provider.id === "github-codespaces") {
30805
- const { execFile: execFile13 } = await import("child_process");
30911
+ const { execFile: execFile14 } = await import("child_process");
30806
30912
  const { promisify: promisify11 } = await import("util");
30807
- const execFileP10 = promisify11(execFile13);
30913
+ const execFileP10 = promisify11(execFile14);
30808
30914
  await execFileP10("gh", ["codespace", "stop", "-c", target.id], { maxBuffer: 8 * 1024 * 1024 });
30809
30915
  return;
30810
30916
  }
@@ -31086,7 +31192,7 @@ function checkChokidar() {
31086
31192
  }
31087
31193
  async function doctor(args2 = []) {
31088
31194
  const json = args2.includes("--json");
31089
- const cliVersion = true ? "2.51.3" : "0.0.0-dev";
31195
+ const cliVersion = true ? "2.52.0" : "0.0.0-dev";
31090
31196
  const apiBase2 = resolveApiBaseUrl();
31091
31197
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
31092
31198
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -31285,7 +31391,7 @@ async function completion(args2) {
31285
31391
  // src/commands/version.ts
31286
31392
  var import_picocolors15 = __toESM(require("picocolors"));
31287
31393
  function version2() {
31288
- const v = true ? "2.51.3" : "unknown";
31394
+ const v = true ? "2.52.0" : "unknown";
31289
31395
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
31290
31396
  }
31291
31397
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.51.3",
3
+ "version": "2.52.0",
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",