codeam-cli 2.39.42 → 2.39.44

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 +12 -0
  2. package/dist/index.js +143 -67
  3. package/package.json +1 -1
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.39.43] — 2026-06-19
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Extract macOS cloudflared .tgz + self-heal gzip-corrupt cache
12
+
13
+ ## [2.39.42] — 2026-06-19
14
+
15
+ ### Added
16
+
17
+ - **cli:** Refuse preview + notify app when the detected port is in use
18
+
7
19
  ## [2.39.41] — 2026-06-19
8
20
 
9
21
  ### 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.39.42",
501
+ version: "2.39.44",
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",
@@ -5908,7 +5908,7 @@ function readAnonId() {
5908
5908
  }
5909
5909
  function superProperties() {
5910
5910
  return {
5911
- cliVersion: true ? "2.39.42" : "0.0.0-dev",
5911
+ cliVersion: true ? "2.39.44" : "0.0.0-dev",
5912
5912
  nodeVersion: process.version,
5913
5913
  platform: process.platform,
5914
5914
  arch: process.arch,
@@ -16480,7 +16480,10 @@ async function resolveCloudflared(opts = {}) {
16480
16480
  }
16481
16481
  try {
16482
16482
  await import_promises.default.access(CACHED_BINARY);
16483
- return CACHED_BINARY;
16483
+ if (await isExecutableBinary(CACHED_BINARY)) {
16484
+ return CACHED_BINARY;
16485
+ }
16486
+ await import_promises.default.rm(CACHED_BINARY, { force: true });
16484
16487
  } catch {
16485
16488
  }
16486
16489
  if (opts.skipDownload) {
@@ -16500,11 +16503,53 @@ async function downloadCloudflared(target) {
16500
16503
  `Failed to download cloudflared from ${url}: HTTP ${response.status}. Install manually from https://github.com/cloudflare/cloudflared/releases.`
16501
16504
  );
16502
16505
  }
16506
+ if (url.endsWith(".tgz")) {
16507
+ const tmp = `${target}.download.tgz`;
16508
+ await (0, import_promises2.pipeline)(
16509
+ response.body,
16510
+ (0, import_fs.createWriteStream)(tmp)
16511
+ );
16512
+ try {
16513
+ await extractTgz(tmp, import_path4.default.dirname(target));
16514
+ await import_promises.default.access(target);
16515
+ await import_promises.default.chmod(target, 493);
16516
+ } catch (err) {
16517
+ throw new Error(
16518
+ `Downloaded the cloudflared archive but could not extract the binary: ${err.message}. Install manually via \`brew install cloudflared\`.`
16519
+ );
16520
+ } finally {
16521
+ await import_promises.default.rm(tmp, { force: true });
16522
+ }
16523
+ return;
16524
+ }
16503
16525
  await (0, import_promises2.pipeline)(
16504
16526
  response.body,
16505
16527
  (0, import_fs.createWriteStream)(target, { mode: 493 })
16506
16528
  );
16507
16529
  }
16530
+ async function isExecutableBinary(p2) {
16531
+ let handle;
16532
+ try {
16533
+ handle = await import_promises.default.open(p2, "r");
16534
+ const buf = Buffer.alloc(2);
16535
+ await handle.read(buf, 0, 2, 0);
16536
+ return !(buf[0] === 31 && buf[1] === 139);
16537
+ } catch {
16538
+ return false;
16539
+ } finally {
16540
+ await handle?.close();
16541
+ }
16542
+ }
16543
+ function extractTgz(tgzPath, destDir) {
16544
+ return new Promise((resolve7, reject) => {
16545
+ const child = (0, import_child_process11.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
16546
+ child.on("error", (err) => reject(err));
16547
+ child.on(
16548
+ "exit",
16549
+ (code) => code === 0 ? resolve7() : reject(new Error(`tar exited with code ${code} while extracting cloudflared`))
16550
+ );
16551
+ });
16552
+ }
16508
16553
  function downloadUrlForPlatform() {
16509
16554
  const platform3 = process.platform;
16510
16555
  const arch2 = process.arch;
@@ -20208,6 +20253,7 @@ var import_crypto4 = require("crypto");
20208
20253
 
20209
20254
  // src/services/turn-files/git-changeset.ts
20210
20255
  var import_child_process21 = require("child_process");
20256
+ var fs37 = __toESM(require("fs/promises"));
20211
20257
  var path44 = __toESM(require("path"));
20212
20258
  async function collectRepoChangeset(opts) {
20213
20259
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
@@ -20222,7 +20268,16 @@ async function collectRepoChangeset(opts) {
20222
20268
  const entries = [];
20223
20269
  for (const row of parseStatus(status2)) {
20224
20270
  if (isIgnoredFilePath(row.filePath)) continue;
20225
- const stats = numstat.get(row.filePath) ?? { added: 0, removed: 0 };
20271
+ const numstatEntry = numstat.get(row.filePath);
20272
+ let stats;
20273
+ if (row.fileStatus === "added" && numstatEntry === void 0) {
20274
+ const lineCount = await readUntrackedLineCount(
20275
+ path44.join(opts.repoRoot, row.filePath)
20276
+ );
20277
+ stats = { added: lineCount, removed: 0 };
20278
+ } else {
20279
+ stats = numstatEntry ?? { added: 0, removed: 0 };
20280
+ }
20226
20281
  entries.push({
20227
20282
  filePath: row.filePath,
20228
20283
  fileStatus: row.fileStatus,
@@ -20239,6 +20294,27 @@ async function collectRepoChangeset(opts) {
20239
20294
  }
20240
20295
  return entries;
20241
20296
  }
20297
+ var MAX_UNTRACKED_LINE_SCAN = 1e5;
20298
+ var _readUntrackedLineCountImpl = {
20299
+ read: defaultReadUntrackedLineCount
20300
+ };
20301
+ function readUntrackedLineCount(absPath) {
20302
+ return _readUntrackedLineCountImpl.read(absPath);
20303
+ }
20304
+ async function defaultReadUntrackedLineCount(absPath) {
20305
+ try {
20306
+ const content = await fs37.readFile(absPath, "utf8");
20307
+ let count = 0;
20308
+ let pos = -1;
20309
+ while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
20310
+ count += 1;
20311
+ if (count >= MAX_UNTRACKED_LINE_SCAN) return count;
20312
+ }
20313
+ return content.length > 0 ? Math.max(count, 1) : 0;
20314
+ } catch {
20315
+ return 0;
20316
+ }
20317
+ }
20242
20318
  function parseStatus(raw) {
20243
20319
  const tokens = raw.split("\0");
20244
20320
  const rows = [];
@@ -20319,7 +20395,7 @@ function defaultRunGit(cwd, args2) {
20319
20395
  });
20320
20396
  }
20321
20397
  async function discoverRepos(workingDir, maxDepth = 4) {
20322
- const fs46 = await import("fs/promises");
20398
+ const fs47 = await import("fs/promises");
20323
20399
  const out2 = [];
20324
20400
  await walk(workingDir, 0);
20325
20401
  return out2;
@@ -20327,7 +20403,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20327
20403
  if (depth > maxDepth) return;
20328
20404
  let entries = [];
20329
20405
  try {
20330
- const dirents = await fs46.readdir(dir, { withFileTypes: true });
20406
+ const dirents = await fs47.readdir(dir, { withFileTypes: true });
20331
20407
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
20332
20408
  } catch {
20333
20409
  return;
@@ -20353,7 +20429,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20353
20429
  }
20354
20430
 
20355
20431
  // src/services/turn-files/files-outbox.ts
20356
- var fs37 = __toESM(require("fs/promises"));
20432
+ var fs38 = __toESM(require("fs/promises"));
20357
20433
  var path45 = __toESM(require("path"));
20358
20434
  var import_os7 = require("os");
20359
20435
  var HOME_OUTBOX_DIR = ".codeam/outbox";
@@ -20395,8 +20471,8 @@ var FilesOutbox = class {
20395
20471
  /** Persist the entry to disk and trigger a flush. Returns once the
20396
20472
  * line is durable on disk (not once the POST succeeds). */
20397
20473
  async enqueue(entry) {
20398
- await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
20399
- await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20474
+ await fs38.mkdir(path45.dirname(this.filePath), { recursive: true });
20475
+ await fs38.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20400
20476
  this.backoffIndex = 0;
20401
20477
  if (this.autoSchedule) this.scheduleFlush(0);
20402
20478
  }
@@ -20485,7 +20561,7 @@ var FilesOutbox = class {
20485
20561
  async readAll() {
20486
20562
  let raw = "";
20487
20563
  try {
20488
- raw = await fs37.readFile(this.filePath, "utf8");
20564
+ raw = await fs38.readFile(this.filePath, "utf8");
20489
20565
  } catch {
20490
20566
  return [];
20491
20567
  }
@@ -20509,12 +20585,12 @@ var FilesOutbox = class {
20509
20585
  async rewrite(entries) {
20510
20586
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
20511
20587
  if (entries.length === 0) {
20512
- await fs37.unlink(this.filePath).catch(() => void 0);
20588
+ await fs38.unlink(this.filePath).catch(() => void 0);
20513
20589
  return;
20514
20590
  }
20515
20591
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
20516
- await fs37.writeFile(tmpPath, payload, "utf8");
20517
- await fs37.rename(tmpPath, this.filePath);
20592
+ await fs38.writeFile(tmpPath, payload, "utf8");
20593
+ await fs38.rename(tmpPath, this.filePath);
20518
20594
  }
20519
20595
  };
20520
20596
  function applyJitter(ms) {
@@ -22412,7 +22488,7 @@ var OutputService = class _OutputService {
22412
22488
  };
22413
22489
 
22414
22490
  // src/services/history.service.ts
22415
- var fs38 = __toESM(require("fs"));
22491
+ var fs39 = __toESM(require("fs"));
22416
22492
  var path46 = __toESM(require("path"));
22417
22493
  var os30 = __toESM(require("os"));
22418
22494
  var https7 = __toESM(require("https"));
@@ -22441,7 +22517,7 @@ function parseJsonl(filePath) {
22441
22517
  const messages = [];
22442
22518
  let raw;
22443
22519
  try {
22444
- raw = fs38.readFileSync(filePath, "utf8");
22520
+ raw = fs39.readFileSync(filePath, "utf8");
22445
22521
  } catch (err) {
22446
22522
  if (err.code !== "ENOENT") {
22447
22523
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -22631,9 +22707,9 @@ var HistoryService = class _HistoryService {
22631
22707
  const dir = this.projectDir;
22632
22708
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22633
22709
  try {
22634
- const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22710
+ const files = fs39.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22635
22711
  try {
22636
- const stat3 = fs38.statSync(path46.join(dir, e.name));
22712
+ const stat3 = fs39.statSync(path46.join(dir, e.name));
22637
22713
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22638
22714
  } catch {
22639
22715
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22674,13 +22750,13 @@ var HistoryService = class _HistoryService {
22674
22750
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22675
22751
  let entries;
22676
22752
  try {
22677
- entries = fs38.readdirSync(dir, { withFileTypes: true });
22753
+ entries = fs39.readdirSync(dir, { withFileTypes: true });
22678
22754
  } catch {
22679
22755
  return null;
22680
22756
  }
22681
22757
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22682
22758
  try {
22683
- const stat3 = fs38.statSync(path46.join(dir, e.name));
22759
+ const stat3 = fs39.statSync(path46.join(dir, e.name));
22684
22760
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22685
22761
  } catch {
22686
22762
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22694,7 +22770,7 @@ var HistoryService = class _HistoryService {
22694
22770
  extractUsageFromFile(filePath) {
22695
22771
  let raw;
22696
22772
  try {
22697
- raw = fs38.readFileSync(filePath, "utf8");
22773
+ raw = fs39.readFileSync(filePath, "utf8");
22698
22774
  } catch {
22699
22775
  return null;
22700
22776
  }
@@ -22739,9 +22815,9 @@ var HistoryService = class _HistoryService {
22739
22815
  let totalCost = 0;
22740
22816
  let files;
22741
22817
  try {
22742
- files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22818
+ files = fs39.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22743
22819
  try {
22744
- return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
22820
+ return fs39.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
22745
22821
  } catch {
22746
22822
  return false;
22747
22823
  }
@@ -22752,7 +22828,7 @@ var HistoryService = class _HistoryService {
22752
22828
  for (const file of files) {
22753
22829
  let raw;
22754
22830
  try {
22755
- raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
22831
+ raw = fs39.readFileSync(path46.join(projectDir, file), "utf8");
22756
22832
  } catch {
22757
22833
  continue;
22758
22834
  }
@@ -23343,7 +23419,7 @@ function buildKeepAlive(ctx) {
23343
23419
  }
23344
23420
 
23345
23421
  // src/agents/claude/onboarding.ts
23346
- var fs39 = __toESM(require("fs"));
23422
+ var fs40 = __toESM(require("fs"));
23347
23423
  var os31 = __toESM(require("os"));
23348
23424
  var path47 = __toESM(require("path"));
23349
23425
  function ensureClaudeOnboarded() {
@@ -23351,7 +23427,7 @@ function ensureClaudeOnboarded() {
23351
23427
  const file = path47.join(os31.homedir(), ".claude.json");
23352
23428
  let config = {};
23353
23429
  try {
23354
- config = JSON.parse(fs39.readFileSync(file, "utf8"));
23430
+ config = JSON.parse(fs40.readFileSync(file, "utf8"));
23355
23431
  } catch {
23356
23432
  }
23357
23433
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -23362,8 +23438,8 @@ function ensureClaudeOnboarded() {
23362
23438
  if (typeof config.lastOnboardingVersion !== "string") {
23363
23439
  config.lastOnboardingVersion = "2.1.177";
23364
23440
  }
23365
- fs39.mkdirSync(path47.dirname(file), { recursive: true });
23366
- fs39.writeFileSync(file, JSON.stringify(config, null, 2));
23441
+ fs40.mkdirSync(path47.dirname(file), { recursive: true });
23442
+ fs40.writeFileSync(file, JSON.stringify(config, null, 2));
23367
23443
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
23368
23444
  } catch (err) {
23369
23445
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -23854,7 +23930,7 @@ async function autoLinkAfterPair(opts) {
23854
23930
  }
23855
23931
 
23856
23932
  // src/commands/pair-auto.ts
23857
- var fs40 = __toESM(require("fs"));
23933
+ var fs41 = __toESM(require("fs"));
23858
23934
  var os32 = __toESM(require("os"));
23859
23935
  var path48 = __toESM(require("path"));
23860
23936
  var import_crypto7 = require("crypto");
@@ -24053,10 +24129,10 @@ function readTokenFromArgs(args2) {
24053
24129
  if (fileFlag) {
24054
24130
  const path58 = fileFlag.slice("--token-file=".length);
24055
24131
  try {
24056
- const content = fs40.readFileSync(path58, "utf8").trim();
24132
+ const content = fs41.readFileSync(path58, "utf8").trim();
24057
24133
  if (content.length === 0) fail(`--token-file ${path58} is empty`);
24058
24134
  try {
24059
- fs40.unlinkSync(path58);
24135
+ fs41.unlinkSync(path58);
24060
24136
  } catch {
24061
24137
  }
24062
24138
  return content;
@@ -24153,7 +24229,7 @@ function isLivePairAuto(pid) {
24153
24229
  if (e.code !== "EPERM") return false;
24154
24230
  }
24155
24231
  try {
24156
- return fs40.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
24232
+ return fs41.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
24157
24233
  } catch {
24158
24234
  return true;
24159
24235
  }
@@ -24161,19 +24237,19 @@ function isLivePairAuto(pid) {
24161
24237
  function acquireSingletonLock() {
24162
24238
  const lockPath = pairAutoLockPath();
24163
24239
  try {
24164
- fs40.mkdirSync(path48.dirname(lockPath), { recursive: true });
24240
+ fs41.mkdirSync(path48.dirname(lockPath), { recursive: true });
24165
24241
  try {
24166
- fs40.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
24242
+ fs41.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
24167
24243
  } catch (e) {
24168
24244
  if (e.code !== "EEXIST") throw e;
24169
- const holder = Number(fs40.readFileSync(lockPath, "utf8").trim());
24245
+ const holder = Number(fs41.readFileSync(lockPath, "utf8").trim());
24170
24246
  if (isLivePairAuto(holder)) return false;
24171
- fs40.writeFileSync(lockPath, String(process.pid));
24247
+ fs41.writeFileSync(lockPath, String(process.pid));
24172
24248
  }
24173
24249
  process.once("exit", () => {
24174
24250
  try {
24175
- if (fs40.existsSync(lockPath) && Number(fs40.readFileSync(lockPath, "utf8").trim()) === process.pid) {
24176
- fs40.unlinkSync(lockPath);
24251
+ if (fs41.existsSync(lockPath) && Number(fs41.readFileSync(lockPath, "utf8").trim()) === process.pid) {
24252
+ fs41.unlinkSync(lockPath);
24177
24253
  }
24178
24254
  } catch {
24179
24255
  }
@@ -26315,7 +26391,7 @@ async function stopWorkspaceFromLocal(target) {
26315
26391
  }
26316
26392
 
26317
26393
  // src/commands/host/host-client.ts
26318
- var fs41 = __toESM(require("fs"));
26394
+ var fs42 = __toESM(require("fs"));
26319
26395
  var os33 = __toESM(require("os"));
26320
26396
  var path53 = __toESM(require("path"));
26321
26397
  function sampleCpuTimes() {
@@ -26376,7 +26452,7 @@ function collectOsInfo() {
26376
26452
  }
26377
26453
  function loadHostIdentity() {
26378
26454
  try {
26379
- const raw = fs41.readFileSync(hostIdentityPath(), "utf8");
26455
+ const raw = fs42.readFileSync(hostIdentityPath(), "utf8");
26380
26456
  const parsed = JSON.parse(raw);
26381
26457
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
26382
26458
  const p2 = parsed;
@@ -26389,12 +26465,12 @@ function loadHostIdentity() {
26389
26465
  }
26390
26466
  function saveHostIdentity(identity) {
26391
26467
  const file = hostIdentityPath();
26392
- fs41.mkdirSync(path53.dirname(file), { recursive: true, mode: 448 });
26393
- fs41.writeFileSync(file, JSON.stringify(identity, null, 2), {
26468
+ fs42.mkdirSync(path53.dirname(file), { recursive: true, mode: 448 });
26469
+ fs42.writeFileSync(file, JSON.stringify(identity, null, 2), {
26394
26470
  encoding: "utf8",
26395
26471
  mode: 384
26396
26472
  });
26397
- fs41.chmodSync(file, 384);
26473
+ fs42.chmodSync(file, 384);
26398
26474
  }
26399
26475
  var HostHttpError = class extends Error {
26400
26476
  constructor(message, status2) {
@@ -26417,7 +26493,7 @@ function isHostAuthRejection(err) {
26417
26493
  }
26418
26494
  function deleteHostIdentity() {
26419
26495
  try {
26420
- fs41.rmSync(hostIdentityPath(), { force: true });
26496
+ fs42.rmSync(hostIdentityPath(), { force: true });
26421
26497
  } catch {
26422
26498
  }
26423
26499
  }
@@ -26581,7 +26657,7 @@ var import_node_child_process13 = require("child_process");
26581
26657
  var os36 = __toESM(require("os"));
26582
26658
 
26583
26659
  // src/commands/host/workspace.ts
26584
- var fs42 = __toESM(require("fs"));
26660
+ var fs43 = __toESM(require("fs"));
26585
26661
  var os34 = __toESM(require("os"));
26586
26662
  var path54 = __toESM(require("path"));
26587
26663
  var import_node_child_process12 = require("child_process");
@@ -26634,16 +26710,16 @@ function maskToken(text, cloneToken) {
26634
26710
  }
26635
26711
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
26636
26712
  if (isAbsolutePathTarget(repoOrPath)) {
26637
- if (!fs42.existsSync(repoOrPath)) {
26713
+ if (!fs43.existsSync(repoOrPath)) {
26638
26714
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
26639
26715
  }
26640
26716
  return repoOrPath;
26641
26717
  }
26642
26718
  const dest = path54.join(selfHostedWorkspaceRoot(), deployId);
26643
- if (fs42.existsSync(path54.join(dest, ".git"))) {
26719
+ if (fs43.existsSync(path54.join(dest, ".git"))) {
26644
26720
  return dest;
26645
26721
  }
26646
- fs42.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
26722
+ fs43.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
26647
26723
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
26648
26724
  try {
26649
26725
  await execFileP9("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -26659,7 +26735,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
26659
26735
  }
26660
26736
 
26661
26737
  // src/commands/host/agent-provisioning.ts
26662
- var fs43 = __toESM(require("fs"));
26738
+ var fs44 = __toESM(require("fs"));
26663
26739
  var os35 = __toESM(require("os"));
26664
26740
  var path55 = __toESM(require("path"));
26665
26741
  var PUBLIC_TO_INTERNAL_AGENT = {
@@ -26676,12 +26752,12 @@ function toInternalAgentId(publicAgentId) {
26676
26752
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
26677
26753
  }
26678
26754
  function ensureDir(dir) {
26679
- fs43.mkdirSync(dir, { recursive: true, mode: 448 });
26755
+ fs44.mkdirSync(dir, { recursive: true, mode: 448 });
26680
26756
  }
26681
26757
  function writeFile0600(filePath, contents) {
26682
26758
  ensureDir(path55.dirname(filePath));
26683
- fs43.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
26684
- fs43.chmodSync(filePath, 384);
26759
+ fs44.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
26760
+ fs44.chmodSync(filePath, 384);
26685
26761
  }
26686
26762
  var claudeProvisioner = {
26687
26763
  write(auth, home) {
@@ -26690,7 +26766,7 @@ var claudeProvisioner = {
26690
26766
  }
26691
26767
  writeFile0600(path55.join(home, ".claude", ".credentials.json"), auth.value);
26692
26768
  const claudeJson = path55.join(home, ".claude.json");
26693
- if (!fs43.existsSync(claudeJson)) {
26769
+ if (!fs44.existsSync(claudeJson)) {
26694
26770
  writeFile0600(
26695
26771
  claudeJson,
26696
26772
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -27120,7 +27196,7 @@ async function hostAgent(args2 = []) {
27120
27196
  var import_node_dns = require("dns");
27121
27197
  var import_node_util5 = require("util");
27122
27198
  var import_node_crypto8 = require("crypto");
27123
- var fs44 = __toESM(require("fs"));
27199
+ var fs45 = __toESM(require("fs"));
27124
27200
  var path56 = __toESM(require("path"));
27125
27201
  var import_picocolors12 = __toESM(require("picocolors"));
27126
27202
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
@@ -27179,11 +27255,11 @@ async function checkHealth(apiBase2) {
27179
27255
  function checkConfigDir() {
27180
27256
  const dir = path56.join(require("os").homedir(), ".codeam");
27181
27257
  try {
27182
- fs44.mkdirSync(dir, { recursive: true, mode: 448 });
27258
+ fs45.mkdirSync(dir, { recursive: true, mode: 448 });
27183
27259
  const probe = path56.join(dir, ".doctor-probe");
27184
- fs44.writeFileSync(probe, "ok", { mode: 384 });
27185
- const read = fs44.readFileSync(probe, "utf8");
27186
- fs44.unlinkSync(probe);
27260
+ fs45.writeFileSync(probe, "ok", { mode: 384 });
27261
+ const read = fs45.readFileSync(probe, "utf8");
27262
+ fs45.unlinkSync(probe);
27187
27263
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
27188
27264
  return {
27189
27265
  id: "config-dir",
@@ -27289,7 +27365,7 @@ function checkChokidar() {
27289
27365
  }
27290
27366
  async function doctor(args2 = []) {
27291
27367
  const json = args2.includes("--json");
27292
- const cliVersion = true ? "2.39.42" : "0.0.0-dev";
27368
+ const cliVersion = true ? "2.39.44" : "0.0.0-dev";
27293
27369
  const apiBase2 = resolveApiBaseUrl();
27294
27370
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
27295
27371
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -27488,7 +27564,7 @@ async function completion(args2) {
27488
27564
  // src/commands/version.ts
27489
27565
  var import_picocolors13 = __toESM(require("picocolors"));
27490
27566
  function version2() {
27491
- const v = true ? "2.39.42" : "unknown";
27567
+ const v = true ? "2.39.44" : "unknown";
27492
27568
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
27493
27569
  }
27494
27570
 
@@ -27616,7 +27692,7 @@ function tryShowSubcommandHelp(cmd, args2) {
27616
27692
  var _subcommandHelpKeys = Object.keys(HELPS);
27617
27693
 
27618
27694
  // src/lib/updateNotifier.ts
27619
- var fs45 = __toESM(require("fs"));
27695
+ var fs46 = __toESM(require("fs"));
27620
27696
  var os37 = __toESM(require("os"));
27621
27697
  var path57 = __toESM(require("path"));
27622
27698
  var https8 = __toESM(require("https"));
@@ -27632,7 +27708,7 @@ function cachePath() {
27632
27708
  }
27633
27709
  function readCache() {
27634
27710
  try {
27635
- const raw = fs45.readFileSync(cachePath(), "utf8");
27711
+ const raw = fs46.readFileSync(cachePath(), "utf8");
27636
27712
  const parsed = JSON.parse(raw);
27637
27713
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
27638
27714
  return parsed;
@@ -27643,10 +27719,10 @@ function readCache() {
27643
27719
  function writeCache(cache) {
27644
27720
  try {
27645
27721
  const file = cachePath();
27646
- fs45.mkdirSync(path57.dirname(file), { recursive: true });
27722
+ fs46.mkdirSync(path57.dirname(file), { recursive: true });
27647
27723
  const tmp = `${file}.${process.pid}.tmp`;
27648
- fs45.writeFileSync(tmp, JSON.stringify(cache));
27649
- fs45.renameSync(tmp, file);
27724
+ fs46.writeFileSync(tmp, JSON.stringify(cache));
27725
+ fs46.renameSync(tmp, file);
27650
27726
  } catch {
27651
27727
  }
27652
27728
  }
@@ -27721,7 +27797,7 @@ function isLinkedInstall() {
27721
27797
  }).trim();
27722
27798
  if (!root) return false;
27723
27799
  const pkgPath = path57.join(root, PKG_NAME);
27724
- return fs45.lstatSync(pkgPath).isSymbolicLink();
27800
+ return fs46.lstatSync(pkgPath).isSymbolicLink();
27725
27801
  } catch {
27726
27802
  return false;
27727
27803
  }
@@ -27757,7 +27833,7 @@ function maybeAutoUpdate(currentVersion, latest) {
27757
27833
  return;
27758
27834
  }
27759
27835
  try {
27760
- fs45.unlinkSync(cachePath());
27836
+ fs46.unlinkSync(cachePath());
27761
27837
  } catch {
27762
27838
  }
27763
27839
  process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
@@ -27774,7 +27850,7 @@ function checkForUpdates() {
27774
27850
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
27775
27851
  if (process.env.CI) return;
27776
27852
  if (!process.stdout.isTTY) return;
27777
- const current = true ? "2.39.42" : null;
27853
+ const current = true ? "2.39.44" : null;
27778
27854
  if (!current) return;
27779
27855
  const cache = readCache();
27780
27856
  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.39.42",
3
+ "version": "2.39.44",
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",