codeam-cli 2.39.58 → 2.39.60

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,22 @@ 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.39.59] — 2026-06-20
8
+
9
+ ### Fixed
10
+
11
+ - **host-agent:** Resolve bundled claude via fs walk, not exports-blocked require
12
+
13
+ ## [2.39.58] — 2026-06-20
14
+
15
+ ### Added
16
+
17
+ - **host-agent:** Event-driven session lifecycle (off the heartbeat)
18
+
19
+ ### Fixed
20
+
21
+ - **host-agent:** Put SDK-bundled claude on PATH for `headroom init`
22
+
7
23
  ## [2.39.57] — 2026-06-20
8
24
 
9
25
  ### Added
package/dist/index.js CHANGED
@@ -5388,7 +5388,7 @@ function readAnonId() {
5388
5388
  }
5389
5389
  function superProperties() {
5390
5390
  return {
5391
- cliVersion: true ? "2.39.58" : "0.0.0-dev",
5391
+ cliVersion: true ? "2.39.60" : "0.0.0-dev",
5392
5392
  nodeVersion: process.version,
5393
5393
  platform: process.platform,
5394
5394
  arch: process.arch,
@@ -5547,7 +5547,7 @@ var os4 = __toESM(require("os"));
5547
5547
  // package.json
5548
5548
  var package_default = {
5549
5549
  name: "codeam-cli",
5550
- version: "2.39.58",
5550
+ version: "2.39.60",
5551
5551
  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.",
5552
5552
  type: "commonjs",
5553
5553
  main: "dist/index.js",
@@ -11065,12 +11065,12 @@ function isAvailable() {
11065
11065
  }
11066
11066
  function augmentPath() {
11067
11067
  const dirs = probeInstallDirs();
11068
- const sep4 = path14.delimiter;
11068
+ const sep5 = path14.delimiter;
11069
11069
  const current = process.env.PATH ?? "";
11070
- const existing = new Set(current.split(sep4).filter(Boolean));
11070
+ const existing = new Set(current.split(sep5).filter(Boolean));
11071
11071
  const additions = dirs.filter((d3) => !existing.has(d3));
11072
11072
  if (additions.length === 0) return;
11073
- process.env.PATH = additions.join(sep4) + sep4 + current;
11073
+ process.env.PATH = additions.join(sep5) + sep5 + current;
11074
11074
  }
11075
11075
  function runInstaller() {
11076
11076
  const isWindows = process.platform === "win32";
@@ -17367,7 +17367,7 @@ function checkForUpdates() {
17367
17367
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17368
17368
  if (process.env.CI) return;
17369
17369
  if (!process.stdout.isTTY) return;
17370
- const current = true ? "2.39.58" : null;
17370
+ const current = true ? "2.39.60" : null;
17371
17371
  if (!current) return;
17372
17372
  const cache = readCache();
17373
17373
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17638,16 +17638,34 @@ function readHeadroomChildEnv() {
17638
17638
  }
17639
17639
  }
17640
17640
  function bundledClaudeBinDir() {
17641
- const require_2 = require;
17641
+ const roots = /* @__PURE__ */ new Set();
17642
+ let dir = __dirname;
17643
+ for (let i = 0; i < 6; i++) {
17644
+ roots.add(path45.join(dir, "node_modules"));
17645
+ const parent = path45.dirname(dir);
17646
+ if (parent === dir) break;
17647
+ dir = parent;
17648
+ }
17642
17649
  try {
17643
- const sdkManifest = require_2.resolve("@anthropic-ai/claude-agent-sdk/package.json");
17644
- const atAnthropic = path45.dirname(path45.dirname(sdkManifest));
17645
- for (const entry of fs39.readdirSync(atAnthropic)) {
17650
+ const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
17651
+ const marker = `${path45.sep}@anthropic-ai${path45.sep}`;
17652
+ const idx = main2.lastIndexOf(marker);
17653
+ if (idx !== -1) roots.add(main2.slice(0, idx));
17654
+ } catch {
17655
+ }
17656
+ for (const nm of roots) {
17657
+ const atAnthropic = path45.join(nm, "@anthropic-ai");
17658
+ let entries;
17659
+ try {
17660
+ entries = fs39.readdirSync(atAnthropic);
17661
+ } catch {
17662
+ continue;
17663
+ }
17664
+ for (const entry of entries) {
17646
17665
  if (!entry.startsWith("claude-agent-sdk-")) continue;
17647
17666
  const bin = path45.join(atAnthropic, entry, "claude");
17648
17667
  if (fs39.existsSync(bin)) return path45.dirname(bin);
17649
17668
  }
17650
- } catch {
17651
17669
  }
17652
17670
  return null;
17653
17671
  }
@@ -17751,7 +17769,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
17751
17769
  detached: false
17752
17770
  });
17753
17771
  function currentCliVersion() {
17754
- return true ? "2.39.58" : null;
17772
+ return true ? "2.39.60" : null;
17755
17773
  }
17756
17774
  function runCmd(cmd, args2, timeoutMs) {
17757
17775
  return new Promise((resolve7) => {
@@ -23430,6 +23448,11 @@ var AcpHistory = class {
23430
23448
  ]);
23431
23449
  }
23432
23450
  };
23451
+ var AUTH_FAILURE_RE = /invalid authentication credentials|authentication[_ ]error|please run \/login|\bunauthorized\b|\binvalid x-api-key\b|oauth token (?:expired|revoked)|(?:api error|http|status)[:\s]+401|\b401\b[^\n]{0,40}(?:unauthor|authenticat|credential|api[_ ]?key|login)/i;
23452
+ function looksLikeAuthFailure(text) {
23453
+ return AUTH_FAILURE_RE.test(text);
23454
+ }
23455
+ var AUTH_FAILURE_MESSAGE = "\u{1F512} **Authentication failed \u2014 your agent credentials are invalid or expired (API 401).**\n\nRe-authenticate this agent in **Profile \u203A Agents**, then send your message again.";
23433
23456
  async function runAcpSession(opts) {
23434
23457
  const publisher = new AcpPublisher({
23435
23458
  sessionId: opts.sessionId,
@@ -23437,6 +23460,7 @@ async function runAcpSession(opts) {
23437
23460
  pluginAuthToken: opts.pluginAuthToken
23438
23461
  });
23439
23462
  const streaming = new StreamingState(publisher);
23463
+ const recentStderr = [];
23440
23464
  registerTerminalHandlers({
23441
23465
  onData: ({ sessionId, data }) => {
23442
23466
  void publisher.publishOutput({
@@ -23497,14 +23521,17 @@ async function runAcpSession(opts) {
23497
23521
  optionIdByLabel
23498
23522
  });
23499
23523
  },
23500
- onStderr: (_line) => {
23524
+ onStderr: (line) => {
23525
+ recentStderr.push(line);
23526
+ if (recentStderr.length > 40) recentStderr.shift();
23501
23527
  },
23502
23528
  onUnexpectedExit: (code, signal) => {
23503
23529
  log.warn("acpRunner", `adapter died code=${code} signal=${signal}; shutting down session`);
23530
+ const authFail = looksLikeAuthFailure(recentStderr.join("\n"));
23504
23531
  void streaming.closeAll().then(
23505
23532
  () => publisher.publishOutput({
23506
23533
  type: "text",
23507
- content: `Agent adapter exited unexpectedly (code=${code ?? "null"} signal=${signal ?? "null"}).`,
23534
+ content: authFail ? AUTH_FAILURE_MESSAGE : `Agent adapter exited unexpectedly (code=${code ?? "null"} signal=${signal ?? "null"}).`,
23508
23535
  done: true
23509
23536
  })
23510
23537
  );
@@ -23598,7 +23625,9 @@ async function runAcpSession(opts) {
23598
23625
  history,
23599
23626
  initialize.agentCapabilities,
23600
23627
  turnFiles,
23601
- getBeads
23628
+ getBeads,
23629
+ publisher,
23630
+ recentStderr
23602
23631
  );
23603
23632
  },
23604
23633
  { id: opts.agent, name: opts.agent, displayName: opts.agent }
@@ -23622,7 +23651,7 @@ async function runAcpSession(opts) {
23622
23651
  await new Promise(() => {
23623
23652
  });
23624
23653
  }
23625
- async function handleCommand(cmd, client2, relay, acpSessionId, models, streaming, opts, history, agentCaps, turnFiles, getBeads) {
23654
+ async function handleCommand(cmd, client2, relay, acpSessionId, models, streaming, opts, history, agentCaps, turnFiles, getBeads, publisher, recentStderr) {
23626
23655
  switch (cmd.type) {
23627
23656
  case "beads_action": {
23628
23657
  const beads = getBeads();
@@ -23673,8 +23702,16 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
23673
23702
  await relay.sendResult(cmd.id, "completed", { stopReason: reply.stopReason });
23674
23703
  } catch (err) {
23675
23704
  await recoverFromFailedTurn(client2, streaming);
23676
- log.warn("acpRunner", `prompt failed: ${describeError(err)}`);
23677
- await relay.sendResult(cmd.id, "failed", { error: describeError(err) });
23705
+ const detail = describeError(err);
23706
+ log.warn("acpRunner", `prompt failed: ${detail}`);
23707
+ if (looksLikeAuthFailure(detail) || looksLikeAuthFailure(recentStderr.join("\n"))) {
23708
+ await publisher.publishOutput({
23709
+ type: "text",
23710
+ content: AUTH_FAILURE_MESSAGE,
23711
+ done: true
23712
+ });
23713
+ }
23714
+ await relay.sendResult(cmd.id, "failed", { error: detail });
23678
23715
  }
23679
23716
  return;
23680
23717
  }
@@ -28303,7 +28340,7 @@ function checkChokidar() {
28303
28340
  }
28304
28341
  async function doctor(args2 = []) {
28305
28342
  const json = args2.includes("--json");
28306
- const cliVersion = true ? "2.39.58" : "0.0.0-dev";
28343
+ const cliVersion = true ? "2.39.60" : "0.0.0-dev";
28307
28344
  const apiBase2 = resolveApiBaseUrl();
28308
28345
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
28309
28346
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -28502,7 +28539,7 @@ async function completion(args2) {
28502
28539
  // src/commands/version.ts
28503
28540
  var import_picocolors14 = __toESM(require("picocolors"));
28504
28541
  function version2() {
28505
- const v = true ? "2.39.58" : "unknown";
28542
+ const v = true ? "2.39.60" : "unknown";
28506
28543
  console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
28507
28544
  }
28508
28545
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.39.58",
3
+ "version": "2.39.60",
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",