codeam-cli 2.61.4 → 2.61.5

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,13 @@ 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.4] — 2026-07-16
8
+
9
+ ### Fixed
10
+
11
+ - **box:** Add unzip for CodeRabbit install (curl alone insufficient)
12
+ - **cli:** Bump ACP stack to latest + freeze claude binary (broken-chat fix)
13
+
7
14
  ## [2.61.3] — 2026-07-16
8
15
 
9
16
  ### Fixed
package/dist/index.js CHANGED
@@ -1073,11 +1073,11 @@ function quiet(fn) {
1073
1073
  log.debug(TAG, "ignored sync error", err);
1074
1074
  }
1075
1075
  }
1076
- function rmIfExistsQuiet(path75) {
1076
+ function rmIfExistsQuiet(path76) {
1077
1077
  try {
1078
- fs2.rmSync(path75, { force: true });
1078
+ fs2.rmSync(path76, { force: true });
1079
1079
  } catch (err) {
1080
- log.debug(TAG, `rmIfExists failed for ${path75}`, err);
1080
+ log.debug(TAG, `rmIfExists failed for ${path76}`, err);
1081
1081
  }
1082
1082
  }
1083
1083
  function killQuiet(target, signal = "SIGTERM") {
@@ -1261,8 +1261,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
1261
1261
  return decodedFile;
1262
1262
  };
1263
1263
  }
1264
- function normalizeWindowsPath(path75) {
1265
- return path75.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1264
+ function normalizeWindowsPath(path76) {
1265
+ return path76.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1266
1266
  }
1267
1267
 
1268
1268
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3742,9 +3742,9 @@ async function addSourceContext(frames) {
3742
3742
  LRU_FILE_CONTENTS_CACHE.reduce();
3743
3743
  return frames;
3744
3744
  }
3745
- function getContextLinesFromFile(path75, ranges, output) {
3745
+ function getContextLinesFromFile(path76, ranges, output) {
3746
3746
  return new Promise((resolve8) => {
3747
- const stream = (0, import_node_fs.createReadStream)(path75);
3747
+ const stream = (0, import_node_fs.createReadStream)(path76);
3748
3748
  const lineReaded = (0, import_node_readline.createInterface)({
3749
3749
  input: stream
3750
3750
  });
@@ -3759,7 +3759,7 @@ function getContextLinesFromFile(path75, ranges, output) {
3759
3759
  let rangeStart = range[0];
3760
3760
  let rangeEnd = range[1];
3761
3761
  function onStreamError() {
3762
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path75, 1);
3762
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path76, 1);
3763
3763
  lineReaded.close();
3764
3764
  lineReaded.removeAllListeners();
3765
3765
  destroyStreamAndResolve();
@@ -3820,8 +3820,8 @@ function clearLineContext(frame) {
3820
3820
  delete frame.context_line;
3821
3821
  delete frame.post_context;
3822
3822
  }
3823
- function shouldSkipContextLinesForFile(path75) {
3824
- return path75.startsWith("node:") || path75.endsWith(".min.js") || path75.endsWith(".min.cjs") || path75.endsWith(".min.mjs") || path75.startsWith("data:");
3823
+ function shouldSkipContextLinesForFile(path76) {
3824
+ return path76.startsWith("node:") || path76.endsWith(".min.js") || path76.endsWith(".min.cjs") || path76.endsWith(".min.mjs") || path76.startsWith("data:");
3825
3825
  }
3826
3826
  function shouldSkipContextLinesForFrame(frame) {
3827
3827
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5975,7 +5975,7 @@ function readAnonId() {
5975
5975
  }
5976
5976
  function superProperties() {
5977
5977
  return {
5978
- cliVersion: true ? "2.61.4" : "0.0.0-dev",
5978
+ cliVersion: true ? "2.61.5" : "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.4",
6159
+ version: "2.61.5",
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.4" ? { ideVersion: "2.61.4" } : {}
7302
+ ..."2.61.5" ? { ideVersion: "2.61.5" } : {}
7303
7303
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
7304
7304
  }
7305
7305
  /**
@@ -13885,8 +13885,8 @@ function pickLine(obj) {
13885
13885
  function toHunk(raw, groupSeverity) {
13886
13886
  if (!raw || typeof raw !== "object") return null;
13887
13887
  const o = raw;
13888
- const path75 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
13889
- if (!path75) return null;
13888
+ const path76 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
13889
+ if (!path76) return null;
13890
13890
  const message = asString(
13891
13891
  pick(o, [
13892
13892
  "comment",
@@ -13903,7 +13903,7 @@ function toHunk(raw, groupSeverity) {
13903
13903
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
13904
13904
  const locObj = pick(o, ["location"]) ?? o;
13905
13905
  return {
13906
- path: path75.trim(),
13906
+ path: path76.trim(),
13907
13907
  line: pickLine(o) ?? pickLine(locObj),
13908
13908
  severity,
13909
13909
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -13986,10 +13986,10 @@ function parsePlain(stdout) {
13986
13986
  for (const line of stdout.split(/\r?\n/)) {
13987
13987
  const m = line.match(HUNK_LINE_RE);
13988
13988
  if (!m) continue;
13989
- const [, path75, lineNo, sevToken, message] = m;
13990
- if (!path75 || !lineNo || !message) continue;
13989
+ const [, path76, lineNo, sevToken, message] = m;
13990
+ if (!path76 || !lineNo || !message) continue;
13991
13991
  hunks.push({
13992
- path: path75.trim(),
13992
+ path: path76.trim(),
13993
13993
  line: Number(lineNo),
13994
13994
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
13995
13995
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -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.4" : null;
17903
+ const current = true ? "2.61.5" : 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.4" : null;
17920
+ const current = true ? "2.61.5" : 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.4" : null;
17940
+ return true ? "2.61.5" : null;
17941
17941
  }
17942
17942
  function runCmd(cmd, args2, timeoutMs) {
17943
17943
  return new Promise((resolve8) => {
@@ -23396,11 +23396,11 @@ function resolveTokenValue(args2) {
23396
23396
  }
23397
23397
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
23398
23398
  if (fileFlag) {
23399
- const path75 = fileFlag.slice("--token-file=".length);
23399
+ const path76 = fileFlag.slice("--token-file=".length);
23400
23400
  try {
23401
- const content = fs56.readFileSync(path75, "utf8").trim();
23402
- if (content.length === 0) fail(`--token-file ${path75} is empty`);
23403
- rmIfExistsQuiet(path75);
23401
+ const content = fs56.readFileSync(path76, "utf8").trim();
23402
+ if (content.length === 0) fail(`--token-file ${path76} is empty`);
23403
+ rmIfExistsQuiet(path76);
23404
23404
  return content;
23405
23405
  } catch (err) {
23406
23406
  fail(`Could not read --token-file: ${err.message}`);
@@ -30442,8 +30442,67 @@ var import_crypto5 = require("crypto");
30442
30442
 
30443
30443
  // src/services/turn-files/git-changeset.ts
30444
30444
  var import_child_process28 = require("child_process");
30445
- var fs61 = __toESM(require("fs/promises"));
30445
+ var fs62 = __toESM(require("fs/promises"));
30446
+ var path67 = __toESM(require("path"));
30447
+
30448
+ // src/services/turn-files/review-ignore.ts
30449
+ var import_ignore2 = __toESM(require("ignore"));
30450
+ var fs61 = __toESM(require("fs"));
30446
30451
  var path66 = __toESM(require("path"));
30452
+ var CURATED_REVIEW_IGNORE = [
30453
+ // Google Cloud SDK (the incident) — installs a huge python tree.
30454
+ "google-cloud-sdk/",
30455
+ "**/google-cloud-sdk/**",
30456
+ ".config/gcloud/",
30457
+ // Python package installs that land outside a venv (which is already covered).
30458
+ "**/site-packages/**",
30459
+ "**/dist-packages/**",
30460
+ "__pypackages__/",
30461
+ ".local/lib/",
30462
+ "**/.local/lib/**",
30463
+ "pip-wheel-metadata/",
30464
+ // JS package-manager stores/caches not already in isIgnoredFilePath's regex.
30465
+ ".pnpm-store/",
30466
+ "**/.pnpm-store/**",
30467
+ ".yarn/cache/",
30468
+ ".yarn/unplugged/",
30469
+ ".bun/",
30470
+ // Language toolchains dropped into $HOME/a project dir.
30471
+ ".rustup/",
30472
+ ".cargo/registry/",
30473
+ ".cargo/git/",
30474
+ "go/pkg/",
30475
+ ".nvm/",
30476
+ ".rbenv/",
30477
+ ".pyenv/",
30478
+ ".sdkman/",
30479
+ // Cloud / infra CLIs with bundled trees.
30480
+ ".azure/",
30481
+ ".aws/cli/",
30482
+ "awscli/",
30483
+ // CodeAgent's own runtime prefixes (never a user change).
30484
+ ".codeam/",
30485
+ "codeam-node20/"
30486
+ ];
30487
+ function makeReviewIgnore(repoRoot) {
30488
+ const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
30489
+ try {
30490
+ const custom = fs61.readFileSync(path66.join(repoRoot, ".codeam", "reviewignore"), "utf8");
30491
+ ig.add(custom);
30492
+ } catch {
30493
+ }
30494
+ return (relPath) => {
30495
+ if (!relPath) return false;
30496
+ try {
30497
+ return ig.ignores(relPath);
30498
+ } catch (err) {
30499
+ log.trace("review-ignore", `ignores() threw for "${relPath}"`, err);
30500
+ return false;
30501
+ }
30502
+ };
30503
+ }
30504
+
30505
+ // src/services/turn-files/git-changeset.ts
30447
30506
  async function collectRepoChangeset(opts) {
30448
30507
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
30449
30508
  if (status2 === null) return null;
@@ -30454,14 +30513,26 @@ async function collectRepoChangeset(opts) {
30454
30513
  "HEAD"
30455
30514
  ]).catch(() => null);
30456
30515
  const numstat = parseNumstat(numstatRaw ?? "");
30516
+ const reviewIgnore = makeReviewIgnore(opts.repoRoot);
30517
+ const rows = parseStatus(status2).filter(
30518
+ (row) => !isIgnoredFilePath(row.filePath) && !reviewIgnore(row.filePath)
30519
+ );
30520
+ const MAX_CHANGESET_FILES = Math.max(1, Number(process.env.CODEAM_MAX_CHANGESET_FILES ?? 500));
30521
+ const truncated = rows.length > MAX_CHANGESET_FILES;
30522
+ const bounded = truncated ? rows.slice(0, MAX_CHANGESET_FILES) : rows;
30523
+ if (truncated) {
30524
+ log.warn(
30525
+ "changeset",
30526
+ `${rows.length} changed files exceeds the ${MAX_CHANGESET_FILES}-file cap \u2014 reporting the first ${MAX_CHANGESET_FILES} only. This usually means a dependency/SDK/build install landed in the session's working directory; add it to .gitignore to remove it from reviews.`
30527
+ );
30528
+ }
30457
30529
  const entries = [];
30458
- for (const row of parseStatus(status2)) {
30459
- if (isIgnoredFilePath(row.filePath)) continue;
30530
+ for (const row of bounded) {
30460
30531
  const numstatEntry = numstat.get(row.filePath);
30461
30532
  let stats;
30462
- if (row.fileStatus === "added" && numstatEntry === void 0) {
30533
+ if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
30463
30534
  const lineCount = await readUntrackedLineCount(
30464
- path66.join(opts.repoRoot, row.filePath)
30535
+ path67.join(opts.repoRoot, row.filePath)
30465
30536
  );
30466
30537
  stats = { added: lineCount, removed: 0 };
30467
30538
  } else {
@@ -30492,7 +30563,7 @@ function readUntrackedLineCount(absPath) {
30492
30563
  }
30493
30564
  async function defaultReadUntrackedLineCount(absPath) {
30494
30565
  try {
30495
- const content = await fs61.readFile(absPath, "utf8");
30566
+ const content = await fs62.readFile(absPath, "utf8");
30496
30567
  let count = 0;
30497
30568
  let pos = -1;
30498
30569
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -30584,7 +30655,7 @@ function defaultRunGit(cwd, args2) {
30584
30655
  });
30585
30656
  }
30586
30657
  async function discoverRepos(workingDir, maxDepth = 4) {
30587
- const fs66 = await import("fs/promises");
30658
+ const fs67 = await import("fs/promises");
30588
30659
  const out2 = [];
30589
30660
  await walk(workingDir, 0);
30590
30661
  return out2;
@@ -30592,7 +30663,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
30592
30663
  if (depth > maxDepth) return;
30593
30664
  let entries = [];
30594
30665
  try {
30595
- const dirents = await fs66.readdir(dir, { withFileTypes: true });
30666
+ const dirents = await fs67.readdir(dir, { withFileTypes: true });
30596
30667
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
30597
30668
  } catch {
30598
30669
  return;
@@ -30603,8 +30674,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
30603
30674
  if (hasGit) {
30604
30675
  out2.push({
30605
30676
  repoRoot: dir,
30606
- repoPath: path66.relative(workingDir, dir),
30607
- repoName: path66.basename(dir)
30677
+ repoPath: path67.relative(workingDir, dir),
30678
+ repoName: path67.basename(dir)
30608
30679
  });
30609
30680
  return;
30610
30681
  }
@@ -30612,14 +30683,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
30612
30683
  if (!entry.isDirectory) continue;
30613
30684
  if (entry.name === "node_modules") continue;
30614
30685
  if (entry.name === "dist" || entry.name === "build") continue;
30615
- await walk(path66.join(dir, entry.name), depth + 1);
30686
+ await walk(path67.join(dir, entry.name), depth + 1);
30616
30687
  }
30617
30688
  }
30618
30689
  }
30619
30690
 
30620
30691
  // src/services/turn-files/files-outbox.ts
30621
- var fs62 = __toESM(require("fs/promises"));
30622
- var path67 = __toESM(require("path"));
30692
+ var fs63 = __toESM(require("fs/promises"));
30693
+ var path68 = __toESM(require("path"));
30623
30694
  var import_os11 = require("os");
30624
30695
  var HOME_OUTBOX_DIR = ".codeam/outbox";
30625
30696
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -30652,16 +30723,16 @@ var FilesOutbox = class {
30652
30723
  backoffIndex = 0;
30653
30724
  stopped = false;
30654
30725
  constructor(opts) {
30655
- const base = opts.baseDir ?? path67.join(homeDir(), HOME_OUTBOX_DIR);
30656
- this.filePath = path67.join(base, `${opts.sessionId}.jsonl`);
30726
+ const base = opts.baseDir ?? path68.join(homeDir(), HOME_OUTBOX_DIR);
30727
+ this.filePath = path68.join(base, `${opts.sessionId}.jsonl`);
30657
30728
  this.post = opts.post;
30658
30729
  this.autoSchedule = opts.autoSchedule !== false;
30659
30730
  }
30660
30731
  /** Persist the entry to disk and trigger a flush. Returns once the
30661
30732
  * line is durable on disk (not once the POST succeeds). */
30662
30733
  async enqueue(entry) {
30663
- await fs62.mkdir(path67.dirname(this.filePath), { recursive: true });
30664
- await fs62.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
30734
+ await fs63.mkdir(path68.dirname(this.filePath), { recursive: true });
30735
+ await fs63.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
30665
30736
  this.backoffIndex = 0;
30666
30737
  if (this.autoSchedule) this.scheduleFlush(0);
30667
30738
  }
@@ -30752,7 +30823,7 @@ var FilesOutbox = class {
30752
30823
  async readAll() {
30753
30824
  let raw = "";
30754
30825
  try {
30755
- raw = await fs62.readFile(this.filePath, "utf8");
30826
+ raw = await fs63.readFile(this.filePath, "utf8");
30756
30827
  } catch {
30757
30828
  return [];
30758
30829
  }
@@ -30776,12 +30847,12 @@ var FilesOutbox = class {
30776
30847
  async rewrite(entries) {
30777
30848
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
30778
30849
  if (entries.length === 0) {
30779
- await fs62.unlink(this.filePath).catch(() => void 0);
30850
+ await fs63.unlink(this.filePath).catch(() => void 0);
30780
30851
  return;
30781
30852
  }
30782
30853
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
30783
- await fs62.writeFile(tmpPath, payload, "utf8");
30784
- await fs62.rename(tmpPath, this.filePath);
30854
+ await fs63.writeFile(tmpPath, payload, "utf8");
30855
+ await fs63.rename(tmpPath, this.filePath);
30785
30856
  }
30786
30857
  };
30787
30858
  function applyJitter(ms) {
@@ -33942,7 +34013,7 @@ var AcpDriver = class {
33942
34013
  };
33943
34014
 
33944
34015
  // src/baton/transcript-mirror.ts
33945
- var fs63 = __toESM(require("fs"));
34016
+ var fs64 = __toESM(require("fs"));
33946
34017
  var TranscriptMirror = class {
33947
34018
  constructor(deps) {
33948
34019
  this.deps = deps;
@@ -34009,7 +34080,7 @@ var TranscriptMirror = class {
34009
34080
  }
34010
34081
  };
34011
34082
  function defaultWatch(file, onChange) {
34012
- const w3 = fs63.watch(file, { persistent: false }, () => onChange());
34083
+ const w3 = fs64.watch(file, { persistent: false }, () => onChange());
34013
34084
  return () => w3.close();
34014
34085
  }
34015
34086
 
@@ -34271,16 +34342,16 @@ function toEpochMs(ts) {
34271
34342
  }
34272
34343
 
34273
34344
  // src/agents/claude/onboarding.ts
34274
- var fs64 = __toESM(require("fs"));
34345
+ var fs65 = __toESM(require("fs"));
34275
34346
  var os50 = __toESM(require("os"));
34276
- var path68 = __toESM(require("path"));
34347
+ var path69 = __toESM(require("path"));
34277
34348
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
34278
34349
  function ensureClaudeOnboarded(cwd) {
34279
34350
  try {
34280
- const file = path68.join(os50.homedir(), ".claude.json");
34351
+ const file = path69.join(os50.homedir(), ".claude.json");
34281
34352
  let config = {};
34282
34353
  try {
34283
- config = JSON.parse(fs64.readFileSync(file, "utf8"));
34354
+ config = JSON.parse(fs65.readFileSync(file, "utf8"));
34284
34355
  } catch {
34285
34356
  }
34286
34357
  let changed = false;
@@ -34305,8 +34376,8 @@ function ensureClaudeOnboarded(cwd) {
34305
34376
  }
34306
34377
  }
34307
34378
  if (!changed) return;
34308
- fs64.mkdirSync(path68.dirname(file), { recursive: true });
34309
- fs64.writeFileSync(file, JSON.stringify(config, null, 2));
34379
+ fs65.mkdirSync(path69.dirname(file), { recursive: true });
34380
+ fs65.writeFileSync(file, JSON.stringify(config, null, 2));
34310
34381
  log.info(
34311
34382
  "claude",
34312
34383
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -34992,7 +35063,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
34992
35063
  var import_child_process29 = require("child_process");
34993
35064
  var import_util4 = require("util");
34994
35065
  var import_picocolors9 = __toESM(require("picocolors"));
34995
- var path69 = __toESM(require("path"));
35066
+ var path70 = __toESM(require("path"));
34996
35067
  var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
34997
35068
  var MAX_BUFFER = 8 * 1024 * 1024;
34998
35069
  function resetStdinForChild() {
@@ -35481,7 +35552,7 @@ var GitHubCodespacesProvider = class {
35481
35552
  });
35482
35553
  }
35483
35554
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
35484
- const remoteDir = path69.posix.dirname(remotePath);
35555
+ const remoteDir = path70.posix.dirname(remotePath);
35485
35556
  const parts = [
35486
35557
  `mkdir -p ${shellQuote(remoteDir)}`,
35487
35558
  `cat > ${shellQuote(remotePath)}`
@@ -35551,7 +35622,7 @@ function shellQuote(s) {
35551
35622
  // src/services/providers/gitpod.ts
35552
35623
  var import_child_process30 = require("child_process");
35553
35624
  var import_util5 = require("util");
35554
- var path70 = __toESM(require("path"));
35625
+ var path71 = __toESM(require("path"));
35555
35626
  var import_picocolors10 = __toESM(require("picocolors"));
35556
35627
  var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
35557
35628
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -35791,7 +35862,7 @@ var GitpodProvider = class {
35791
35862
  });
35792
35863
  }
35793
35864
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
35794
- const remoteDir = path70.posix.dirname(remotePath);
35865
+ const remoteDir = path71.posix.dirname(remotePath);
35795
35866
  const parts = [
35796
35867
  `mkdir -p ${shellQuote2(remoteDir)}`,
35797
35868
  `cat > ${shellQuote2(remotePath)}`
@@ -35827,7 +35898,7 @@ function shellQuote2(s) {
35827
35898
  // src/services/providers/gitlab-workspaces.ts
35828
35899
  var import_child_process31 = require("child_process");
35829
35900
  var import_util6 = require("util");
35830
- var path71 = __toESM(require("path"));
35901
+ var path72 = __toESM(require("path"));
35831
35902
  var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
35832
35903
  var MAX_BUFFER3 = 8 * 1024 * 1024;
35833
35904
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -36087,7 +36158,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
36087
36158
  }
36088
36159
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
36089
36160
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
36090
- const remoteDir = path71.posix.dirname(remotePath);
36161
+ const remoteDir = path72.posix.dirname(remotePath);
36091
36162
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
36092
36163
  if (options.mode != null) {
36093
36164
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -36155,7 +36226,7 @@ function shellQuote3(s) {
36155
36226
  // src/services/providers/railway.ts
36156
36227
  var import_child_process32 = require("child_process");
36157
36228
  var import_util7 = require("util");
36158
- var path72 = __toESM(require("path"));
36229
+ var path73 = __toESM(require("path"));
36159
36230
  var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
36160
36231
  var MAX_BUFFER4 = 8 * 1024 * 1024;
36161
36232
  function resetStdinForChild4() {
@@ -36391,7 +36462,7 @@ var RailwayProvider = class {
36391
36462
  if (!projectId || !serviceId) {
36392
36463
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
36393
36464
  }
36394
- const remoteDir = path72.posix.dirname(remotePath);
36465
+ const remoteDir = path73.posix.dirname(remotePath);
36395
36466
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
36396
36467
  if (options.mode != null) {
36397
36468
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -37037,8 +37108,8 @@ async function invite() {
37037
37108
  var import_node_dns = require("dns");
37038
37109
  var import_node_util5 = require("util");
37039
37110
  var import_node_crypto12 = require("crypto");
37040
- var fs65 = __toESM(require("fs"));
37041
- var path73 = __toESM(require("path"));
37111
+ var fs66 = __toESM(require("fs"));
37112
+ var path74 = __toESM(require("path"));
37042
37113
  var import_picocolors14 = __toESM(require("picocolors"));
37043
37114
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
37044
37115
  async function checkDns(apiBase2) {
@@ -37094,13 +37165,13 @@ async function checkHealth(apiBase2) {
37094
37165
  }
37095
37166
  }
37096
37167
  function checkConfigDir() {
37097
- const dir = path73.join(require("os").homedir(), ".codeam");
37168
+ const dir = path74.join(require("os").homedir(), ".codeam");
37098
37169
  try {
37099
- fs65.mkdirSync(dir, { recursive: true, mode: 448 });
37100
- const probe = path73.join(dir, ".doctor-probe");
37101
- fs65.writeFileSync(probe, "ok", { mode: 384 });
37102
- const read2 = fs65.readFileSync(probe, "utf8");
37103
- fs65.unlinkSync(probe);
37170
+ fs66.mkdirSync(dir, { recursive: true, mode: 448 });
37171
+ const probe = path74.join(dir, ".doctor-probe");
37172
+ fs66.writeFileSync(probe, "ok", { mode: 384 });
37173
+ const read2 = fs66.readFileSync(probe, "utf8");
37174
+ fs66.unlinkSync(probe);
37104
37175
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
37105
37176
  return {
37106
37177
  id: "config-dir",
@@ -37164,7 +37235,7 @@ function checkNodePty() {
37164
37235
  detail: "not required on this platform"
37165
37236
  };
37166
37237
  }
37167
- const vendoredPath = path73.join(__dirname, "vendor", "node-pty");
37238
+ const vendoredPath = path74.join(__dirname, "vendor", "node-pty");
37168
37239
  for (const target of [vendoredPath, "node-pty"]) {
37169
37240
  try {
37170
37241
  require(target);
@@ -37206,7 +37277,7 @@ function checkChokidar() {
37206
37277
  }
37207
37278
  async function doctor(args2 = []) {
37208
37279
  const json = args2.includes("--json");
37209
- const cliVersion = true ? "2.61.4" : "0.0.0-dev";
37280
+ const cliVersion = true ? "2.61.5" : "0.0.0-dev";
37210
37281
  const apiBase2 = resolveApiBaseUrl();
37211
37282
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
37212
37283
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -37717,7 +37788,7 @@ async function mcpRun(args2) {
37717
37788
  // src/commands/version.ts
37718
37789
  var import_picocolors15 = __toESM(require("picocolors"));
37719
37790
  function version2() {
37720
- const v = true ? "2.61.4" : "unknown";
37791
+ const v = true ? "2.61.5" : "unknown";
37721
37792
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
37722
37793
  }
37723
37794
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.61.4",
3
+ "version": "2.61.5",
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",
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- // src/postinstall.ts
5
- var c = {
6
- reset: "\x1B[0m",
7
- bold: "\x1B[1m",
8
- dim: "\x1B[2m",
9
- green: "\x1B[32m",
10
- cyan: "\x1B[36m",
11
- violet: "\x1B[35m",
12
- white: "\x1B[97m"
13
- };
14
- var lines = [
15
- "",
16
- ` ${c.violet}${c.bold}codeam-cli${c.reset} ${c.dim}\u2014 Claude Code remote control${c.reset}`,
17
- "",
18
- ` ${c.dim}1.${c.reset} Pair your phone:`,
19
- ` ${c.cyan}codeam pair${c.reset}`,
20
- "",
21
- ` ${c.dim}2.${c.reset} Launch Claude Code with mobile control:`,
22
- ` ${c.cyan}codeam${c.reset}`,
23
- "",
24
- ` ${c.dim}Other commands:${c.reset}`,
25
- ` ${c.white}codeam sessions${c.reset} ${c.dim}list paired devices${c.reset}`,
26
- ` ${c.white}codeam status${c.reset} ${c.dim}show connection info${c.reset}`,
27
- ` ${c.white}codeam logout${c.reset} ${c.dim}remove all sessions${c.reset}`,
28
- "",
29
- ` ${c.dim}Requires Claude Code:${c.reset} ${c.green}npm install -g @anthropic-ai/claude-code${c.reset}`,
30
- ` ${c.dim}Mobile app:${c.reset} ${c.green}https://www.codeagent-mobile.com${c.reset}`,
31
- ""
32
- ];
33
- process.stdout.write(lines.join("\n") + "\n");