codeam-cli 2.35.2 → 2.35.3

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/index.js +106 -80
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ 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.35.2] — 2026-06-10
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Bound preview install + add port-listening ready fallback
12
+ - **cli:** Stop resume_session from killing the agent dead
13
+
14
+ ### Tests
15
+
16
+ - **cli:** Make linkBdOntoPath/cliBinDir provisioner tests OS-independent
17
+
7
18
  ## [2.35.1] — 2026-06-10
8
19
 
9
20
  ### Fixed
package/dist/index.js CHANGED
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
498
498
  // package.json
499
499
  var package_default = {
500
500
  name: "codeam-cli",
501
- version: "2.35.2",
501
+ version: "2.35.3",
502
502
  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.",
503
503
  type: "commonjs",
504
504
  main: "dist/index.js",
@@ -5898,7 +5898,7 @@ function readAnonId() {
5898
5898
  }
5899
5899
  function superProperties() {
5900
5900
  return {
5901
- cliVersion: true ? "2.35.2" : "0.0.0-dev",
5901
+ cliVersion: true ? "2.35.3" : "0.0.0-dev",
5902
5902
  nodeVersion: process.version,
5903
5903
  platform: process.platform,
5904
5904
  arch: process.arch,
@@ -7246,10 +7246,10 @@ function buildForPlatform(platform2) {
7246
7246
  var import_node_crypto4 = require("crypto");
7247
7247
 
7248
7248
  // src/agents/claude/resolver.ts
7249
- function buildClaudeLaunch(extraArgs = [], os30 = createOsStrategy()) {
7250
- const found = os30.findInPath("claude") ?? os30.findInPath("claude-code");
7249
+ function buildClaudeLaunch(extraArgs = [], os31 = createOsStrategy()) {
7250
+ const found = os31.findInPath("claude") ?? os31.findInPath("claude-code");
7251
7251
  if (!found) return null;
7252
- return os30.buildLaunch(found, extraArgs);
7252
+ return os31.buildLaunch(found, extraArgs);
7253
7253
  }
7254
7254
 
7255
7255
  // src/agents/claude/installer.ts
@@ -9992,8 +9992,8 @@ var ClaudeRuntimeStrategy = class {
9992
9992
  meta = getAgent("claude");
9993
9993
  mode = "interactive";
9994
9994
  os;
9995
- constructor(os30) {
9996
- this.os = os30;
9995
+ constructor(os31) {
9996
+ this.os = os31;
9997
9997
  }
9998
9998
  /**
9999
9999
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -11023,8 +11023,8 @@ function codexCredentialLocator() {
11023
11023
  function codexLoginLauncher() {
11024
11024
  return {
11025
11025
  async ensureInstalled() {
11026
- const os30 = createOsStrategy();
11027
- return os30.findInPath("codex") !== null;
11026
+ const os31 = createOsStrategy();
11027
+ return os31.findInPath("codex") !== null;
11028
11028
  },
11029
11029
  launch() {
11030
11030
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -11047,8 +11047,8 @@ var CodexRuntimeStrategy = class {
11047
11047
  meta = getAgent("codex");
11048
11048
  mode = "interactive";
11049
11049
  os;
11050
- constructor(os30) {
11051
- this.os = os30;
11050
+ constructor(os31) {
11051
+ this.os = os31;
11052
11052
  }
11053
11053
  async prepareLaunch() {
11054
11054
  let binary = this.os.findInPath("codex");
@@ -11154,12 +11154,12 @@ var CodexRuntimeStrategy = class {
11154
11154
  });
11155
11155
  }
11156
11156
  };
11157
- function resolveNpm(os30) {
11158
- return os30.id === "win32" ? "npm.cmd" : "npm";
11157
+ function resolveNpm(os31) {
11158
+ return os31.id === "win32" ? "npm.cmd" : "npm";
11159
11159
  }
11160
- async function installCodexViaNpm(os30) {
11160
+ async function installCodexViaNpm(os31) {
11161
11161
  return new Promise((resolve7, reject) => {
11162
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os30), ["install", "-g", "@openai/codex"], {
11162
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os31), ["install", "-g", "@openai/codex"], {
11163
11163
  stdio: "inherit"
11164
11164
  });
11165
11165
  proc.on("close", (code) => {
@@ -11176,16 +11176,16 @@ async function installCodexViaNpm(os30) {
11176
11176
  });
11177
11177
  });
11178
11178
  }
11179
- function augmentNpmGlobalBin(os30) {
11179
+ function augmentNpmGlobalBin(os31) {
11180
11180
  try {
11181
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os30), ["prefix", "-g"], {
11181
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os31), ["prefix", "-g"], {
11182
11182
  stdio: ["ignore", "pipe", "ignore"]
11183
11183
  });
11184
11184
  if (result.status !== 0) return;
11185
11185
  const prefix = result.stdout.toString().trim();
11186
11186
  if (!prefix) return;
11187
- const binDir = os30.id === "win32" ? prefix : path17.join(prefix, "bin");
11188
- os30.augmentPath([binDir]);
11187
+ const binDir = os31.id === "win32" ? prefix : path17.join(prefix, "bin");
11188
+ os31.augmentPath([binDir]);
11189
11189
  } catch {
11190
11190
  }
11191
11191
  }
@@ -11269,9 +11269,9 @@ var import_node_child_process7 = require("child_process");
11269
11269
  // src/agents/coderabbit/installer.ts
11270
11270
  var import_node_child_process5 = require("child_process");
11271
11271
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
11272
- async function ensureCoderabbitInstalled(os30) {
11273
- if (os30.findInPath("coderabbit")) return true;
11274
- if (os30.id === "win32") {
11272
+ async function ensureCoderabbitInstalled(os31) {
11273
+ if (os31.findInPath("coderabbit")) return true;
11274
+ if (os31.id === "win32") {
11275
11275
  console.error(
11276
11276
  "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
11277
11277
  );
@@ -11286,8 +11286,8 @@ async function ensureCoderabbitInstalled(os30) {
11286
11286
  proc.on("error", () => resolve7(false));
11287
11287
  });
11288
11288
  if (!ok) return false;
11289
- os30.augmentPath([`${os30.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
11290
- return os30.findInPath("coderabbit") !== null;
11289
+ os31.augmentPath([`${os31.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
11290
+ return os31.findInPath("coderabbit") !== null;
11291
11291
  }
11292
11292
 
11293
11293
  // src/agents/coderabbit/link.ts
@@ -11314,10 +11314,10 @@ function coderabbitCredentialLocator() {
11314
11314
  extract: extractLocalCoderabbitToken
11315
11315
  };
11316
11316
  }
11317
- function coderabbitLoginLauncher(os30) {
11317
+ function coderabbitLoginLauncher(os31) {
11318
11318
  return {
11319
11319
  async ensureInstalled() {
11320
- return ensureCoderabbitInstalled(os30);
11320
+ return ensureCoderabbitInstalled(os31);
11321
11321
  },
11322
11322
  launch() {
11323
11323
  return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -11363,8 +11363,8 @@ var CoderabbitRuntimeStrategy = class {
11363
11363
  meta = getAgent("coderabbit");
11364
11364
  mode = "batch";
11365
11365
  os;
11366
- constructor(os30) {
11367
- this.os = os30;
11366
+ constructor(os31) {
11367
+ this.os = os31;
11368
11368
  }
11369
11369
  getDefaultArgs() {
11370
11370
  return ["review"];
@@ -11479,10 +11479,10 @@ function cursorCredentialLocator() {
11479
11479
  extract: extractLocalCursorToken
11480
11480
  };
11481
11481
  }
11482
- function cursorLoginLauncher(os30) {
11482
+ function cursorLoginLauncher(os31) {
11483
11483
  return {
11484
11484
  async ensureInstalled() {
11485
- if (os30.findInPath("cursor-agent")) return true;
11485
+ if (os31.findInPath("cursor-agent")) return true;
11486
11486
  console.error(
11487
11487
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
11488
11488
  );
@@ -11544,8 +11544,8 @@ var CursorRuntimeStrategy = class {
11544
11544
  meta = getAgent("cursor");
11545
11545
  mode = "interactive";
11546
11546
  os;
11547
- constructor(os30) {
11548
- this.os = os30;
11547
+ constructor(os31) {
11548
+ this.os = os31;
11549
11549
  }
11550
11550
  async prepareLaunch() {
11551
11551
  const binary = this.os.findInPath("cursor-agent");
@@ -11665,10 +11665,10 @@ function aiderCredentialLocator() {
11665
11665
  extract: extractLocalAiderToken
11666
11666
  };
11667
11667
  }
11668
- function aiderLoginLauncher(os30) {
11668
+ function aiderLoginLauncher(os31) {
11669
11669
  return {
11670
11670
  async ensureInstalled() {
11671
- if (os30.findInPath("aider")) return true;
11671
+ if (os31.findInPath("aider")) return true;
11672
11672
  console.error(
11673
11673
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
11674
11674
  );
@@ -11678,7 +11678,7 @@ function aiderLoginLauncher(os30) {
11678
11678
  console.error(
11679
11679
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
11680
11680
  );
11681
- return (0, import_node_child_process9.spawn)(os30.id === "win32" ? "cmd.exe" : "sh", os30.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
11681
+ return (0, import_node_child_process9.spawn)(os31.id === "win32" ? "cmd.exe" : "sh", os31.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
11682
11682
  stdio: "ignore"
11683
11683
  });
11684
11684
  }
@@ -11750,8 +11750,8 @@ var AiderRuntimeStrategy = class {
11750
11750
  meta = getAgent("aider");
11751
11751
  mode = "interactive";
11752
11752
  os;
11753
- constructor(os30) {
11754
- this.os = os30;
11753
+ constructor(os31) {
11754
+ this.os = os31;
11755
11755
  }
11756
11756
  async prepareLaunch() {
11757
11757
  const binary = this.os.findInPath("aider");
@@ -11880,8 +11880,8 @@ function geminiCredentialLocator() {
11880
11880
  function geminiLoginLauncher() {
11881
11881
  return {
11882
11882
  async ensureInstalled() {
11883
- const os30 = createOsStrategy();
11884
- return os30.findInPath("gemini") !== null;
11883
+ const os31 = createOsStrategy();
11884
+ return os31.findInPath("gemini") !== null;
11885
11885
  },
11886
11886
  launch() {
11887
11887
  return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -11914,8 +11914,8 @@ var GeminiRuntimeStrategy = class {
11914
11914
  meta = getAgent("gemini");
11915
11915
  mode = "interactive";
11916
11916
  os;
11917
- constructor(os30) {
11918
- this.os = os30;
11917
+ constructor(os31) {
11918
+ this.os = os31;
11919
11919
  }
11920
11920
  async prepareLaunch() {
11921
11921
  const binary = this.os.findInPath("gemini");
@@ -12015,18 +12015,18 @@ var GeminiRuntimeStrategy = class {
12015
12015
 
12016
12016
  // src/agents/registry.ts
12017
12017
  var runtimeBuilders = {
12018
- claude: (os30) => new ClaudeRuntimeStrategy(os30),
12019
- codex: (os30) => new CodexRuntimeStrategy(os30),
12020
- coderabbit: (os30) => new CoderabbitRuntimeStrategy(os30),
12021
- cursor: (os30) => new CursorRuntimeStrategy(os30),
12022
- aider: (os30) => new AiderRuntimeStrategy(os30),
12023
- gemini: (os30) => new GeminiRuntimeStrategy(os30)
12018
+ claude: (os31) => new ClaudeRuntimeStrategy(os31),
12019
+ codex: (os31) => new CodexRuntimeStrategy(os31),
12020
+ coderabbit: (os31) => new CoderabbitRuntimeStrategy(os31),
12021
+ cursor: (os31) => new CursorRuntimeStrategy(os31),
12022
+ aider: (os31) => new AiderRuntimeStrategy(os31),
12023
+ gemini: (os31) => new GeminiRuntimeStrategy(os31)
12024
12024
  };
12025
12025
  var deployBuilders = {
12026
12026
  claude: () => new ClaudeDeployStrategy(),
12027
12027
  codex: () => new CodexDeployStrategy()
12028
12028
  };
12029
- function createAgentStrategy(agent, os30 = createOsStrategy()) {
12029
+ function createAgentStrategy(agent, os31 = createOsStrategy()) {
12030
12030
  if (!AGENT_REGISTRY[agent]?.enabled) {
12031
12031
  throw new Error(
12032
12032
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -12036,10 +12036,10 @@ function createAgentStrategy(agent, os30 = createOsStrategy()) {
12036
12036
  if (!build) {
12037
12037
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
12038
12038
  }
12039
- return build(os30);
12039
+ return build(os31);
12040
12040
  }
12041
- function createInteractiveAgentStrategy(agent, os30 = createOsStrategy()) {
12042
- const s = createAgentStrategy(agent, os30);
12041
+ function createInteractiveAgentStrategy(agent, os31 = createOsStrategy()) {
12042
+ const s = createAgentStrategy(agent, os31);
12043
12043
  if (s.mode !== "interactive") {
12044
12044
  throw new Error(
12045
12045
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -15739,7 +15739,7 @@ function extractSelectPrompt(text) {
15739
15739
 
15740
15740
  // src/commands/start/handlers.ts
15741
15741
  var fs32 = __toESM(require("fs"));
15742
- var os25 = __toESM(require("os"));
15742
+ var os26 = __toESM(require("os"));
15743
15743
  var path39 = __toESM(require("path"));
15744
15744
  var import_crypto3 = require("crypto");
15745
15745
  var import_child_process17 = require("child_process");
@@ -17493,6 +17493,7 @@ function defaultBeadsHomeDir() {
17493
17493
  // src/beads/provisioner.ts
17494
17494
  var import_child_process15 = require("child_process");
17495
17495
  var fs30 = __toESM(require("fs"));
17496
+ var os25 = __toESM(require("os"));
17496
17497
  var path36 = __toESM(require("path"));
17497
17498
 
17498
17499
  // src/beads/install-bd.ts
@@ -17576,26 +17577,47 @@ var _provisionSeam = {
17576
17577
  };
17577
17578
  var _linkSeam = {
17578
17579
  platform: () => process.platform,
17580
+ homedir: () => os25.homedir(),
17581
+ isWritableDir: (dir) => {
17582
+ try {
17583
+ fs30.accessSync(dir, fs30.constants.W_OK);
17584
+ return true;
17585
+ } catch {
17586
+ return false;
17587
+ }
17588
+ },
17589
+ ensureDir: (dir) => {
17590
+ fs30.mkdirSync(dir, { recursive: true });
17591
+ },
17579
17592
  /**
17580
- * A directory ON PATH to symlink `bd` into, so the AGENT's shell + the
17581
- * SessionStart `bd prime` hook resolve `bd` by name.
17593
+ * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
17594
+ * SessionStart `bd prime` hook resolve `bd` by name. The dir MUST be on the
17595
+ * persistent shell PATH those processes use AND be writable.
17582
17596
  *
17583
- * Earlier this used `dirname(realpath(process.argv[1]))` but for a GLOBAL
17584
- * npm install that resolves to the package's own `dist/` dir (e.g.
17585
- * `…/node_modules/codeam-cli/dist`), which is NOT on PATH. The symlink landed
17586
- * somewhere nothing sees, so `which bd` and the hook still failed (observed
17587
- * live in a codespace). `dirname(process.execPath)` is the dir the `node`
17588
- * binary lives in for a global install that's the npm prefix `bin/` where
17589
- * the `codeam` launcher also lives, and IS on PATH. We prefer the first
17590
- * candidate that actually appears in `$PATH`, falling back to node's bin dir.
17597
+ * History: v2.35.1 used `dirname(realpath(argv[1]))` (the package `dist/`,
17598
+ * not on PATH); v2.35.2 used `dirname(process.execPath)` correct for a
17599
+ * normal global npm install, but in a GitHub Codespace `node` lives in a
17600
+ * TRANSIENT bootstrap prefix (`/tmp/codeam-node20/bin`) that is NOT on the
17601
+ * persistent shell PATH, so the hook still failed (validated live). The
17602
+ * dir that IS on PATH and writable in a codespace is `~/.local/bin`.
17603
+ *
17604
+ * Strategy: among [node's bin, ~/.local/bin, /usr/local/bin, entry dir],
17605
+ * pick the first that is BOTH on `$PATH` AND writable. If none qualifies
17606
+ * (codespace: node prefix off-PATH, /usr/local/bin read-only), fall back to
17607
+ * `~/.local/bin` — the standard user bin, on PATH for login shells —
17608
+ * which `linkBdOntoPath` creates if missing.
17591
17609
  */
17592
17610
  cliBinDir: () => {
17593
17611
  const pathDirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
17612
+ const home = _linkSeam.homedir();
17613
+ const localBin = home ? path36.join(home, ".local", "bin") : null;
17594
17614
  const candidates = [];
17595
17615
  try {
17596
17616
  candidates.push(path36.dirname(process.execPath));
17597
17617
  } catch {
17598
17618
  }
17619
+ if (localBin) candidates.push(localBin);
17620
+ candidates.push("/usr/local/bin");
17599
17621
  const entry = process.argv[1];
17600
17622
  if (entry) {
17601
17623
  try {
@@ -17604,8 +17626,11 @@ var _linkSeam = {
17604
17626
  candidates.push(path36.dirname(entry));
17605
17627
  }
17606
17628
  }
17607
- if (candidates.length === 0) return null;
17608
- return candidates.find((d3) => pathDirs.includes(d3)) ?? candidates[0];
17629
+ const onPathWritable = candidates.find(
17630
+ (d3) => pathDirs.includes(d3) && _linkSeam.isWritableDir(d3)
17631
+ );
17632
+ if (onPathWritable) return onPathWritable;
17633
+ return localBin ?? candidates[0] ?? null;
17609
17634
  },
17610
17635
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
17611
17636
  readlink: (linkPath) => {
@@ -17622,6 +17647,7 @@ function linkBdOntoPath(binaryPath) {
17622
17647
  if (_linkSeam.platform() === "win32") return;
17623
17648
  const binDir = _linkSeam.cliBinDir();
17624
17649
  if (!binDir) return;
17650
+ _linkSeam.ensureDir(binDir);
17625
17651
  const linkPath = path36.join(binDir, "bd");
17626
17652
  if (linkPath === binaryPath) return;
17627
17653
  const current = _linkSeam.readlink(linkPath);
@@ -18179,7 +18205,7 @@ function cleanupAttachmentTempFiles() {
18179
18205
  function saveFilesTemp(files) {
18180
18206
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18181
18207
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18182
- const tmpPath = path39.join(os25.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18208
+ const tmpPath = path39.join(os26.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18183
18209
  fs32.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18184
18210
  pendingAttachmentFiles.add(tmpPath);
18185
18211
  return tmpPath;
@@ -19215,7 +19241,7 @@ async function dispatchCommand(ctx, cmd) {
19215
19241
  // src/services/file-watcher.service.ts
19216
19242
  var import_child_process18 = require("child_process");
19217
19243
  var fs33 = __toESM(require("fs"));
19218
- var os26 = __toESM(require("os"));
19244
+ var os27 = __toESM(require("os"));
19219
19245
  var path40 = __toESM(require("path"));
19220
19246
  var import_ignore = __toESM(require("ignore"));
19221
19247
 
@@ -19326,10 +19352,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
19326
19352
  /[\\/]Start Menu([\\/]|$)/i,
19327
19353
  /[\\/]Templates([\\/]|$)/i
19328
19354
  ];
19329
- function isUnsafeWindowsWatchRoot(dir, homedir22) {
19355
+ function isUnsafeWindowsWatchRoot(dir, homedir23) {
19330
19356
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
19331
19357
  const cwd = norm(dir);
19332
- const home = norm(homedir22);
19358
+ const home = norm(homedir23);
19333
19359
  if (cwd === home) return true;
19334
19360
  if (/^[a-z]:$/.test(cwd)) return true;
19335
19361
  const sysRoots = [
@@ -19428,7 +19454,7 @@ var FileWatcherService = class {
19428
19454
  throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
19429
19455
  }
19430
19456
  const isWin = process.platform === "win32";
19431
- if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os26.homedir())) {
19457
+ if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os27.homedir())) {
19432
19458
  log.warn(
19433
19459
  "fileWatcher",
19434
19460
  `refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
@@ -22074,7 +22100,7 @@ var OutputService = class _OutputService {
22074
22100
  // src/services/history.service.ts
22075
22101
  var fs35 = __toESM(require("fs"));
22076
22102
  var path43 = __toESM(require("path"));
22077
- var os27 = __toESM(require("os"));
22103
+ var os28 = __toESM(require("os"));
22078
22104
  var https7 = __toESM(require("https"));
22079
22105
  var http7 = __toESM(require("http"));
22080
22106
  var import_zod2 = require("zod");
@@ -22236,7 +22262,7 @@ var HistoryService = class _HistoryService {
22236
22262
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
22237
22263
  }
22238
22264
  get projectDir() {
22239
- return this.runtime.resolveHistoryDir(this.cwd) ?? path43.join(os27.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22265
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path43.join(os28.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22240
22266
  }
22241
22267
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
22242
22268
  setCurrentConversationId(id) {
@@ -23442,7 +23468,7 @@ async function autoLinkAfterPair(opts) {
23442
23468
 
23443
23469
  // src/commands/pair-auto.ts
23444
23470
  var fs36 = __toESM(require("fs"));
23445
- var os28 = __toESM(require("os"));
23471
+ var os29 = __toESM(require("os"));
23446
23472
  var import_crypto7 = require("crypto");
23447
23473
 
23448
23474
  // src/commands/start-infra-only.ts
@@ -23668,7 +23694,7 @@ async function claimOnce(token, pluginId) {
23668
23694
  pluginId,
23669
23695
  ideName: "codeam-cli (codespace)",
23670
23696
  ideVersion: process.env.npm_package_version ?? "unknown",
23671
- hostname: os28.hostname(),
23697
+ hostname: os29.hostname(),
23672
23698
  codespaceName: process.env.CODESPACE_NAME ?? "",
23673
23699
  // Current git branch of the codespace's working directory, so the
23674
23700
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -25953,9 +25979,9 @@ function checkSessions() {
25953
25979
  }
25954
25980
  }
25955
25981
  function checkAgentBinaries() {
25956
- const os30 = createOsStrategy();
25982
+ const os31 = createOsStrategy();
25957
25983
  return getEnabledAgents().map((meta) => {
25958
- const found = os30.findInPath(meta.binaryName);
25984
+ const found = os31.findInPath(meta.binaryName);
25959
25985
  return {
25960
25986
  id: `agent-${meta.id}`,
25961
25987
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -26019,7 +26045,7 @@ function checkChokidar() {
26019
26045
  }
26020
26046
  async function doctor(args2 = []) {
26021
26047
  const json = args2.includes("--json");
26022
- const cliVersion = true ? "2.35.2" : "0.0.0-dev";
26048
+ const cliVersion = true ? "2.35.3" : "0.0.0-dev";
26023
26049
  const apiBase = resolveApiBaseUrl();
26024
26050
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
26025
26051
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -26218,7 +26244,7 @@ async function completion(args2) {
26218
26244
  // src/commands/version.ts
26219
26245
  var import_picocolors13 = __toESM(require("picocolors"));
26220
26246
  function version2() {
26221
- const v = true ? "2.35.2" : "unknown";
26247
+ const v = true ? "2.35.3" : "unknown";
26222
26248
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
26223
26249
  }
26224
26250
 
@@ -26347,7 +26373,7 @@ var _subcommandHelpKeys = Object.keys(HELPS);
26347
26373
 
26348
26374
  // src/lib/updateNotifier.ts
26349
26375
  var fs38 = __toESM(require("fs"));
26350
- var os29 = __toESM(require("os"));
26376
+ var os30 = __toESM(require("os"));
26351
26377
  var path49 = __toESM(require("path"));
26352
26378
  var https8 = __toESM(require("https"));
26353
26379
  var import_node_child_process12 = require("child_process");
@@ -26357,7 +26383,7 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
26357
26383
  var TTL_MS = 24 * 60 * 60 * 1e3;
26358
26384
  var REQUEST_TIMEOUT_MS = 1500;
26359
26385
  function cachePath() {
26360
- const dir = path49.join(os29.homedir(), ".codeam");
26386
+ const dir = path49.join(os30.homedir(), ".codeam");
26361
26387
  return path49.join(dir, "update-check.json");
26362
26388
  }
26363
26389
  function readCache() {
@@ -26504,7 +26530,7 @@ function checkForUpdates() {
26504
26530
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
26505
26531
  if (process.env.CI) return;
26506
26532
  if (!process.stdout.isTTY) return;
26507
- const current = true ? "2.35.2" : null;
26533
+ const current = true ? "2.35.3" : null;
26508
26534
  if (!current) return;
26509
26535
  const cache = readCache();
26510
26536
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.35.2",
3
+ "version": "2.35.3",
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",