codeam-cli 2.61.93 → 2.61.95

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.94] — 2026-08-08
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Harden Headroom proxy against resume death — accurate liveness + proactive boot relaunch (#604)
12
+
13
+ ## [2.61.93] — 2026-08-08
14
+
15
+ ### Fixed
16
+
17
+ - **cli:** Post pack events to /api/agent-packs/events (#602)
18
+
7
19
  ## [2.61.92] — 2026-08-08
8
20
 
9
21
  ### Added
package/dist/index.js CHANGED
@@ -8017,7 +8017,7 @@ function readAnonId() {
8017
8017
  }
8018
8018
  function superProperties() {
8019
8019
  return {
8020
- cliVersion: true ? "2.61.93" : "0.0.0-dev",
8020
+ cliVersion: true ? "2.61.95" : "0.0.0-dev",
8021
8021
  nodeVersion: process.version,
8022
8022
  platform: process.platform,
8023
8023
  arch: process.arch,
@@ -8198,7 +8198,7 @@ var os4 = __toESM(require("os"));
8198
8198
  // package.json
8199
8199
  var package_default = {
8200
8200
  name: "codeam-cli",
8201
- version: "2.61.93",
8201
+ version: "2.61.95",
8202
8202
  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.",
8203
8203
  type: "commonjs",
8204
8204
  main: "dist/index.js",
@@ -8909,9 +8909,18 @@ function isPidAlive(pid) {
8909
8909
  return false;
8910
8910
  }
8911
8911
  }
8912
+ function pidLooksLikeProxy(pid) {
8913
+ try {
8914
+ const cmd = fs5.readFileSync(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ").toLowerCase();
8915
+ if (cmd.trim() === "") return false;
8916
+ return cmd.includes("headroom") && cmd.includes("proxy");
8917
+ } catch {
8918
+ return isPidAlive(pid);
8919
+ }
8920
+ }
8912
8921
  function isHeadroomProxyProcessAlive() {
8913
8922
  const pid = readHeadroomProxyPidfile();
8914
- return pid !== null && isPidAlive(pid);
8923
+ return pid !== null && isPidAlive(pid) && pidLooksLikeProxy(pid);
8915
8924
  }
8916
8925
  function headroomProxyPidfileAgeMs(nowMs) {
8917
8926
  try {
@@ -9033,7 +9042,7 @@ async function ensureHeadroomProxy(deps) {
9033
9042
  const ageMs = deps.proxyStartupAgeMs();
9034
9043
  if (ageMs !== null && ageMs < PROXY_STARTUP_GRACE_MS) return "starting";
9035
9044
  log.warn("headroom-supervisor", "proxy :8787 is confirmed down \u2014 respawning");
9036
- deps.spawnProxy();
9045
+ (deps.spawnProxyForce ?? deps.spawnProxy)();
9037
9046
  return "respawned";
9038
9047
  }
9039
9048
  async function ensureHeadroomProxyReady(deps, opts = {}) {
@@ -9100,14 +9109,17 @@ function makeRealProxySupervisorDeps() {
9100
9109
  proxyProcessAlive: () => isHeadroomProxyProcessAlive(),
9101
9110
  proxyStartupAgeMs: () => headroomProxyPidfileAgeMs(Date.now()),
9102
9111
  spawnProxy: spawnProxyReal,
9103
- spawnProxyForce: () => spawnHeadroomProxy(
9104
- {
9105
- tag: "headroom-supervisor",
9106
- spawnErrorMsg: (detail) => `force-respawn error (best-effort): ${detail}`,
9107
- failureMsg: (detail) => `force-respawn failed (best-effort): ${detail}`
9108
- },
9109
- { force: true }
9110
- )
9112
+ spawnProxyForce: () => {
9113
+ killHeadroomProxy();
9114
+ spawnHeadroomProxy(
9115
+ {
9116
+ tag: "headroom-supervisor",
9117
+ spawnErrorMsg: (detail) => `force-respawn error (best-effort): ${detail}`,
9118
+ failureMsg: (detail) => `force-respawn failed (best-effort): ${detail}`
9119
+ },
9120
+ { force: true }
9121
+ );
9122
+ }
9111
9123
  };
9112
9124
  }
9113
9125
 
@@ -9503,7 +9515,7 @@ var CommandRelayService = class _CommandRelayService {
9503
9515
  // fresh + clear the "CLI update available" banner after a self-update
9504
9516
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9505
9517
  // pair/reconnect). Older backends ignore the extra field.
9506
- ..."2.61.93" ? { ideVersion: "2.61.93" } : {}
9518
+ ..."2.61.95" ? { ideVersion: "2.61.95" } : {}
9507
9519
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9508
9520
  }
9509
9521
  /**
@@ -20676,7 +20688,7 @@ async function autoUpgradeBeforeCriticalCommand() {
20676
20688
  if (process.env.NODE_ENV === "test") return;
20677
20689
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20678
20690
  if (process.env.CI) return;
20679
- const current2 = true ? "2.61.93" : null;
20691
+ const current2 = true ? "2.61.95" : null;
20680
20692
  if (!current2) return;
20681
20693
  const cache = readCache();
20682
20694
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20693,7 +20705,7 @@ function checkForUpdates() {
20693
20705
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20694
20706
  if (process.env.CI) return;
20695
20707
  if (!process.stdout.isTTY) return;
20696
- const current2 = true ? "2.61.93" : null;
20708
+ const current2 = true ? "2.61.95" : null;
20697
20709
  if (!current2) return;
20698
20710
  const cache = readCache();
20699
20711
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20713,7 +20725,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
20713
20725
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
20714
20726
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
20715
20727
  function currentCliVersion() {
20716
- return true ? "2.61.93" : null;
20728
+ return true ? "2.61.95" : null;
20717
20729
  }
20718
20730
  function runCmd(cmd, args2, timeoutMs) {
20719
20731
  return new Promise((resolve9) => {
@@ -21209,6 +21221,7 @@ var HostAgentSupervisor = class {
21209
21221
  this.heartbeatTimer = setInterval(() => void this.beat(), HEARTBEAT_INTERVAL_MS);
21210
21222
  this.heartbeatTimer.unref?.();
21211
21223
  this.resumePersistedSession();
21224
+ void ensureHeadroomProxyReady(makeRealProxySupervisorDeps()).catch(() => void 0);
21212
21225
  void reportSessionEvent(
21213
21226
  { hostId: this.identity.hostId, hostToken: this.identity.hostToken },
21214
21227
  { event: "reconcile", activeDeployIds: this.activeSessions().map((s) => s.id) }
@@ -32765,6 +32778,12 @@ function guardrailDecision(request, policy) {
32765
32778
  return null;
32766
32779
  }
32767
32780
 
32781
+ // src/agents/acp/modes.ts
32782
+ var FULL_AUTO_MODE_RE = /bypass|yolo|danger|full.?access|skip.?perm|auto.?approve/i;
32783
+ function modeIsFullAutoApprove(modeId) {
32784
+ return FULL_AUTO_MODE_RE.test(modeId);
32785
+ }
32786
+
32768
32787
  // src/agents/acp/client.ts
32769
32788
  var TRANSIENT_ADAPTER_SPAWN_RE = /ETXTBSY|ENOENT/;
32770
32789
  var MAX_START_ATTEMPTS = 5;
@@ -33231,7 +33250,7 @@ var AcpClient = class {
33231
33250
  * (`AcpHistory.switchActiveSession` + `onActiveSessionChanged`), exactly like
33232
33251
  * the `resume_session` rail.
33233
33252
  */
33234
- async newConversation() {
33253
+ async newConversation(opts) {
33235
33254
  if (!this.connection) {
33236
33255
  throw new Error("AcpClient.newConversation called before start()");
33237
33256
  }
@@ -33240,6 +33259,21 @@ var AcpClient = class {
33240
33259
  mcpServers: this.opts.mcpServers ?? []
33241
33260
  });
33242
33261
  this.sessionId = ns.sessionId;
33262
+ this.captureModelConfig(ns.configOptions ?? []);
33263
+ this.captureModes(ns.modes ?? null);
33264
+ if (opts?.ensureFullAutoMode && this.availableModes.length > 0) {
33265
+ const full = this.availableModes.find((m) => modeIsFullAutoApprove(m.id));
33266
+ if (full && this.currentModeId !== full.id) {
33267
+ try {
33268
+ await this.connection.setSessionMode({ sessionId: ns.sessionId, modeId: full.id });
33269
+ this.currentModeId = full.id;
33270
+ log.info("acpClient", `newConversation \u2192 re-asserted full-auto mode ${full.id}`);
33271
+ } catch (err) {
33272
+ const msg = err instanceof Error ? err.message : String(err);
33273
+ log.warn("acpClient", `newConversation \u2014 could not re-assert full-auto mode: ${msg}`);
33274
+ }
33275
+ }
33276
+ }
33243
33277
  log.info("acpClient", `newConversation \u2190 ok sid=${ns.sessionId.slice(0, 8)}`);
33244
33278
  return ns.sessionId;
33245
33279
  }
@@ -35778,7 +35812,9 @@ function buildPackRunnerDeps(ctx) {
35778
35812
  return {
35779
35813
  driver: {
35780
35814
  newConversation: async () => {
35781
- const id = await ctx.client.newConversation();
35815
+ const id = await ctx.client.newConversation({
35816
+ ensureFullAutoMode: ctx.opts.autoApprovePermissions === true
35817
+ });
35782
35818
  ctx.history.switchActiveSession(id);
35783
35819
  ctx.onActiveSessionChanged?.(id);
35784
35820
  return id;
@@ -36426,10 +36462,6 @@ async function listModesH(ctx) {
36426
36462
  });
36427
36463
  return;
36428
36464
  }
36429
- var FULL_AUTO_MODE_RE = /bypass|yolo|danger|full.?access|skip.?perm|auto.?approve/i;
36430
- function modeIsFullAutoApprove(modeId) {
36431
- return FULL_AUTO_MODE_RE.test(modeId);
36432
- }
36433
36465
  async function setModeH(ctx) {
36434
36466
  const { cmd, client: client3, relay, opts } = ctx;
36435
36467
  const payload = cmd.payload;
@@ -42470,7 +42502,7 @@ function checkChokidar() {
42470
42502
  }
42471
42503
  async function doctor(args2 = []) {
42472
42504
  const json = args2.includes("--json");
42473
- const cliVersion = true ? "2.61.93" : "0.0.0-dev";
42505
+ const cliVersion = true ? "2.61.95" : "0.0.0-dev";
42474
42506
  const apiBase2 = resolveApiBaseUrl();
42475
42507
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
42476
42508
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -42861,7 +42893,7 @@ async function mcpRun(args2) {
42861
42893
  // src/commands/version.ts
42862
42894
  var import_picocolors15 = __toESM(require("picocolors"));
42863
42895
  function version2() {
42864
- const v = true ? "2.61.93" : "unknown";
42896
+ const v = true ? "2.61.95" : "unknown";
42865
42897
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
42866
42898
  }
42867
42899
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.61.93",
3
+ "version": "2.61.95",
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",