codeam-cli 2.61.8 → 2.61.10

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,26 @@ 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.9] — 2026-07-16
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Push RECENT list + transcript on ACP session START (idle resume was empty) + sudo self-update
12
+
13
+ ## [2.61.8] — 2026-07-16
14
+
15
+ ### Added
16
+
17
+ - **cli:** Agent-agnostic RECENT list + auto-resume latest conversation (ACP session/list)
18
+
19
+ ### Fixed
20
+
21
+ - **cli:** Wrap public loadSession() with the load-replay guard (keystone)
22
+
23
+ ### Tests
24
+
25
+ - **cli:** Harness invariant — no unguarded connection.loadSession
26
+
7
27
  ## [2.61.7] — 2026-07-16
8
28
 
9
29
  ### 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.8" : "0.0.0-dev",
5978
+ cliVersion: true ? "2.61.10" : "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.8",
6159
+ version: "2.61.10",
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",
@@ -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.8" ? { ideVersion: "2.61.8" } : {}
7302
+ ..."2.61.10" ? { ideVersion: "2.61.10" } : {}
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.8" : null;
17903
+ const current = true ? "2.61.10" : 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.8" : null;
17920
+ const current = true ? "2.61.10" : 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.8" : null;
17940
+ return true ? "2.61.10" : null;
17941
17941
  }
17942
17942
  function runCmd(cmd, args2, timeoutMs) {
17943
17943
  return new Promise((resolve8) => {
@@ -18629,9 +18629,25 @@ var HostAgentSupervisor = class {
18629
18629
  "host-agent",
18630
18630
  `fleet_create_box id=${payload.boxId} name=${containerName} mem=${limits.memoryMb}m cpus=${limits.cpus} pids=${limits.pidsLimit}`
18631
18631
  );
18632
+ const rm = await this.docker.run(["rm", "-f", containerName], {
18633
+ timeoutMs: DOCKER_RUN_TIMEOUT_MS
18634
+ });
18635
+ if (rm.code !== 0 && !isMissingContainerError(rm.stderr)) {
18636
+ log.warn(
18637
+ "host-agent",
18638
+ `fleet_create_box: pre-create rm of ${containerName} failed (code=${rm.code}): ${rm.stderr.trim().slice(-200)} \u2014 attempting run anyway`
18639
+ );
18640
+ }
18641
+ const image = resolveFleetBoxImage();
18632
18642
  const args2 = [
18633
18643
  "run",
18634
18644
  "-d",
18645
+ // Registry-default image: always pull so a new box never silently
18646
+ // runs this host's STALE cached :latest (2026-07-16: cache had CLI
18647
+ // 2.61.4 while the registry had 2.61.9). An explicit
18648
+ // CODEAM_FLEET_BOX_IMAGE override (int test / operator) keeps
18649
+ // docker's default policy — a local-only tag can't be pulled.
18650
+ ...process.env.CODEAM_FLEET_BOX_IMAGE ? [] : ["--pull=always"],
18635
18651
  "--name",
18636
18652
  containerName,
18637
18653
  "--cap-drop",
@@ -18674,7 +18690,7 @@ var HostAgentSupervisor = class {
18674
18690
  // instead of dying with "token expired". Not a secret → plain KEY=value.
18675
18691
  "-e",
18676
18692
  "CODEAM_ENROLL_EPHEMERAL=1",
18677
- resolveFleetBoxImage()
18693
+ image
18678
18694
  ];
18679
18695
  const res = await this.docker.run(args2, {
18680
18696
  timeoutMs: DOCKER_RUN_TIMEOUT_MS,
@@ -22598,16 +22614,23 @@ function buildNpmInstallInvocation(opts) {
22598
22614
  path59.dirname(execPath),
22599
22615
  process.platform === "win32" ? "npm.cmd" : "npm"
22600
22616
  );
22601
- const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
22602
- const args2 = prefix ? ["install", "-g", "--prefix", prefix, "codeam-cli@latest"] : ["install", "-g", "codeam-cli@latest"];
22603
- return { command: command2, args: args2 };
22617
+ const npmCommand = exists2(siblingNpm) ? siblingNpm : "npm";
22618
+ const npmArgs = prefix ? ["install", "-g", "--prefix", prefix, "codeam-cli@latest"] : ["install", "-g", "codeam-cli@latest"];
22619
+ if (opts?.sudo) {
22620
+ return { command: "sudo", args: ["-n", npmCommand, ...npmArgs] };
22621
+ }
22622
+ return { command: npmCommand, args: npmArgs };
22623
+ }
22624
+ function isPermissionError(stderr) {
22625
+ return /EACCES|permission denied|errno[\s"']*-13|operation not permitted/i.test(stderr);
22604
22626
  }
22605
22627
  async function runNpmInstallLatest() {
22606
22628
  let lastError = "";
22607
- const invocation = buildNpmInstallInvocation();
22608
- const useShell = process.platform === "win32";
22609
- const command2 = useShell && invocation.command.includes(" ") ? `"${invocation.command}"` : invocation.command;
22629
+ let useSudo = false;
22610
22630
  for (let attempt = 1; attempt <= CLI_UPDATE_MAX_ATTEMPTS; attempt++) {
22631
+ const invocation = buildNpmInstallInvocation({ sudo: useSudo });
22632
+ const useShell = process.platform === "win32";
22633
+ const command2 = useShell && invocation.command.includes(" ") ? `"${invocation.command}"` : invocation.command;
22611
22634
  const result = await new Promise((resolve8) => {
22612
22635
  (0, import_child_process24.execFile)(
22613
22636
  command2,
@@ -22624,6 +22647,10 @@ async function runNpmInstallLatest() {
22624
22647
  });
22625
22648
  if (result.ok) return { ok: true };
22626
22649
  lastError = result.error ?? "unknown";
22650
+ if (!useSudo && process.platform !== "win32" && isPermissionError(lastError)) {
22651
+ useSudo = true;
22652
+ continue;
22653
+ }
22627
22654
  if (attempt < CLI_UPDATE_MAX_ATTEMPTS) {
22628
22655
  await new Promise((r) => setTimeout(r, 1e3 * attempt));
22629
22656
  }
@@ -32623,6 +32650,22 @@ async function runAcpSession(opts) {
32623
32650
  const jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
32624
32651
  pluginAuthToken: opts.pluginAuthToken
32625
32652
  });
32653
+ void (async () => {
32654
+ try {
32655
+ const listed = await client3.listSessions();
32656
+ if (listed && listed.length > 0) {
32657
+ await publisher.pushSessionList({ agentId: opts.agent, sessions: listed });
32658
+ log.info("acpRunner", `session-start: pushed ${listed.length} conversation(s) to RECENT`);
32659
+ }
32660
+ const uploaded = await jsonlHistory.uploadConversationIfChanged(acpSessionId);
32661
+ log.info(
32662
+ "acpRunner",
32663
+ `session-start: transcript upload ${acpSessionId.slice(0, 8)} \u2192 ${uploaded}`
32664
+ );
32665
+ } catch (err) {
32666
+ log.warn("acpRunner", `session-start push failed (best-effort): ${describeError(err)}`);
32667
+ }
32668
+ })();
32626
32669
  const onboardingWelcomeDone = maybeSendOnboardingWelcome({
32627
32670
  streaming,
32628
32671
  history,
@@ -37394,7 +37437,7 @@ function checkChokidar() {
37394
37437
  }
37395
37438
  async function doctor(args2 = []) {
37396
37439
  const json = args2.includes("--json");
37397
- const cliVersion = true ? "2.61.8" : "0.0.0-dev";
37440
+ const cliVersion = true ? "2.61.10" : "0.0.0-dev";
37398
37441
  const apiBase2 = resolveApiBaseUrl();
37399
37442
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
37400
37443
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -37905,7 +37948,7 @@ async function mcpRun(args2) {
37905
37948
  // src/commands/version.ts
37906
37949
  var import_picocolors15 = __toESM(require("picocolors"));
37907
37950
  function version2() {
37908
- const v = true ? "2.61.8" : "unknown";
37951
+ const v = true ? "2.61.10" : "unknown";
37909
37952
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
37910
37953
  }
37911
37954
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.61.8",
3
+ "version": "2.61.10",
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",