codeam-cli 2.52.6 → 2.52.7

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 +6 -0
  2. package/dist/index.js +148 -101
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ 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.52.6] — 2026-07-03
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** An invalid pairing latches the output pipeline — no more silent dead-token spam
12
+
7
13
  ## [2.52.5] — 2026-07-02
8
14
 
9
15
  ### CI
package/dist/index.js CHANGED
@@ -560,8 +560,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
560
560
  return decodedFile;
561
561
  };
562
562
  }
563
- function normalizeWindowsPath(path62) {
564
- return path62.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
563
+ function normalizeWindowsPath(path63) {
564
+ return path63.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
565
565
  }
566
566
 
567
567
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3041,9 +3041,9 @@ async function addSourceContext(frames) {
3041
3041
  LRU_FILE_CONTENTS_CACHE.reduce();
3042
3042
  return frames;
3043
3043
  }
3044
- function getContextLinesFromFile(path62, ranges, output) {
3044
+ function getContextLinesFromFile(path63, ranges, output) {
3045
3045
  return new Promise((resolve7) => {
3046
- const stream = (0, import_node_fs.createReadStream)(path62);
3046
+ const stream = (0, import_node_fs.createReadStream)(path63);
3047
3047
  const lineReaded = (0, import_node_readline.createInterface)({
3048
3048
  input: stream
3049
3049
  });
@@ -3058,7 +3058,7 @@ function getContextLinesFromFile(path62, ranges, output) {
3058
3058
  let rangeStart = range[0];
3059
3059
  let rangeEnd = range[1];
3060
3060
  function onStreamError() {
3061
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path62, 1);
3061
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path63, 1);
3062
3062
  lineReaded.close();
3063
3063
  lineReaded.removeAllListeners();
3064
3064
  destroyStreamAndResolve();
@@ -3119,8 +3119,8 @@ function clearLineContext(frame) {
3119
3119
  delete frame.context_line;
3120
3120
  delete frame.post_context;
3121
3121
  }
3122
- function shouldSkipContextLinesForFile(path62) {
3123
- return path62.startsWith("node:") || path62.endsWith(".min.js") || path62.endsWith(".min.cjs") || path62.endsWith(".min.mjs") || path62.startsWith("data:");
3122
+ function shouldSkipContextLinesForFile(path63) {
3123
+ return path63.startsWith("node:") || path63.endsWith(".min.js") || path63.endsWith(".min.cjs") || path63.endsWith(".min.mjs") || path63.startsWith("data:");
3124
3124
  }
3125
3125
  function shouldSkipContextLinesForFrame(frame) {
3126
3126
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5397,7 +5397,7 @@ function readAnonId() {
5397
5397
  }
5398
5398
  function superProperties() {
5399
5399
  return {
5400
- cliVersion: true ? "2.52.6" : "0.0.0-dev",
5400
+ cliVersion: true ? "2.52.7" : "0.0.0-dev",
5401
5401
  nodeVersion: process.version,
5402
5402
  platform: process.platform,
5403
5403
  arch: process.arch,
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
5578
5578
  // package.json
5579
5579
  var package_default = {
5580
5580
  name: "codeam-cli",
5581
- version: "2.52.6",
5581
+ version: "2.52.7",
5582
5582
  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.",
5583
5583
  type: "commonjs",
5584
5584
  main: "dist/index.js",
@@ -12842,11 +12842,11 @@ function parseReview(stdout) {
12842
12842
  for (const line of lines) {
12843
12843
  const m = line.match(HUNK_LINE_RE);
12844
12844
  if (!m) continue;
12845
- const [, path62, lineNo, sevToken, message] = m;
12846
- if (!path62 || !lineNo || !message) continue;
12845
+ const [, path63, lineNo, sevToken, message] = m;
12846
+ if (!path63 || !lineNo || !message) continue;
12847
12847
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
12848
12848
  hunks.push({
12849
- path: path62.trim(),
12849
+ path: path63.trim(),
12850
12850
  line: Number(lineNo),
12851
12851
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
12852
12852
  message: cleanedMessage
@@ -14928,7 +14928,7 @@ async function autoUpgradeBeforeCriticalCommand() {
14928
14928
  if (process.env.NODE_ENV === "test") return;
14929
14929
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14930
14930
  if (process.env.CI) return;
14931
- const current = true ? "2.52.6" : null;
14931
+ const current = true ? "2.52.7" : null;
14932
14932
  if (!current) return;
14933
14933
  const cache = readCache();
14934
14934
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -14945,7 +14945,7 @@ function checkForUpdates() {
14945
14945
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14946
14946
  if (process.env.CI) return;
14947
14947
  if (!process.stdout.isTTY) return;
14948
- const current = true ? "2.52.6" : null;
14948
+ const current = true ? "2.52.7" : null;
14949
14949
  if (!current) return;
14950
14950
  const cache = readCache();
14951
14951
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -15647,7 +15647,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process15.s
15647
15647
  detached: false
15648
15648
  });
15649
15649
  function currentCliVersion() {
15650
- return true ? "2.52.6" : null;
15650
+ return true ? "2.52.7" : null;
15651
15651
  }
15652
15652
  function runCmd(cmd, args2, timeoutMs) {
15653
15653
  return new Promise((resolve7) => {
@@ -20389,12 +20389,12 @@ function readTokenFromArgs(args2) {
20389
20389
  }
20390
20390
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
20391
20391
  if (fileFlag) {
20392
- const path62 = fileFlag.slice("--token-file=".length);
20392
+ const path63 = fileFlag.slice("--token-file=".length);
20393
20393
  try {
20394
- const content = fs44.readFileSync(path62, "utf8").trim();
20395
- if (content.length === 0) fail(`--token-file ${path62} is empty`);
20394
+ const content = fs44.readFileSync(path63, "utf8").trim();
20395
+ if (content.length === 0) fail(`--token-file ${path63} is empty`);
20396
20396
  try {
20397
- fs44.unlinkSync(path62);
20397
+ fs44.unlinkSync(path63);
20398
20398
  } catch {
20399
20399
  }
20400
20400
  return content;
@@ -21075,12 +21075,58 @@ function requiresAcp(agent) {
21075
21075
  return getAcpAdapter(agent) !== null;
21076
21076
  }
21077
21077
 
21078
+ // src/agents/acp/claude-binary.ts
21079
+ var import_fs4 = __toESM(require("fs"));
21080
+ var import_path8 = __toESM(require("path"));
21081
+ function currentPlatformKey() {
21082
+ return `${process.platform}-${process.arch}`;
21083
+ }
21084
+ function defaultSdkDir() {
21085
+ try {
21086
+ const manifest = require.resolve("@anthropic-ai/claude-agent-sdk/package.json");
21087
+ return import_path8.default.dirname(manifest);
21088
+ } catch {
21089
+ return null;
21090
+ }
21091
+ }
21092
+ function resolveClaudeNativeBinary(deps = {}) {
21093
+ const existsSync21 = deps.existsSync ?? import_fs4.default.existsSync;
21094
+ const platformKey = deps.platformKey ?? currentPlatformKey();
21095
+ const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
21096
+ if (!sdkDir) return null;
21097
+ const scopeDir = import_path8.default.dirname(sdkDir);
21098
+ const binName = process.platform === "win32" ? "claude.exe" : "claude";
21099
+ const candidate = import_path8.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
21100
+ return existsSync21(candidate) ? candidate : null;
21101
+ }
21102
+ var realSleep = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
21103
+ async function waitForClaudeNativeBinary(opts = {}) {
21104
+ const timeoutMs = opts.timeoutMs ?? 18e4;
21105
+ const pollMs = opts.pollMs ?? 500;
21106
+ const now = opts.now ?? Date.now;
21107
+ const sleep3 = opts.sleep ?? realSleep;
21108
+ const deps = {
21109
+ sdkDir: opts.sdkDir,
21110
+ platformKey: opts.platformKey,
21111
+ existsSync: opts.existsSync
21112
+ };
21113
+ const deadline = now() + timeoutMs;
21114
+ let found = resolveClaudeNativeBinary(deps);
21115
+ if (found) return found;
21116
+ while (now() < deadline) {
21117
+ await sleep3(pollMs);
21118
+ found = resolveClaudeNativeBinary(deps);
21119
+ if (found) return found;
21120
+ }
21121
+ return resolveClaudeNativeBinary(deps);
21122
+ }
21123
+
21078
21124
  // src/agents/acp/runner.ts
21079
21125
  var import_node_crypto7 = require("crypto");
21080
21126
 
21081
21127
  // src/services/history.service.ts
21082
- var fs45 = __toESM(require("fs"));
21083
- var path51 = __toESM(require("path"));
21128
+ var fs46 = __toESM(require("fs"));
21129
+ var path52 = __toESM(require("path"));
21084
21130
  var os38 = __toESM(require("os"));
21085
21131
  var https7 = __toESM(require("https"));
21086
21132
  var http6 = __toESM(require("http"));
@@ -21108,7 +21154,7 @@ function parseJsonl(filePath) {
21108
21154
  const messages = [];
21109
21155
  let raw;
21110
21156
  try {
21111
- raw = fs45.readFileSync(filePath, "utf8");
21157
+ raw = fs46.readFileSync(filePath, "utf8");
21112
21158
  } catch (err) {
21113
21159
  if (err.code !== "ENOENT") {
21114
21160
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -21249,7 +21295,7 @@ var HistoryService = class _HistoryService {
21249
21295
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
21250
21296
  }
21251
21297
  get projectDir() {
21252
- return this.runtime.resolveHistoryDir(this.cwd) ?? path51.join(os38.homedir(), ".claude", "projects", encodeCwd(this.cwd));
21298
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path52.join(os38.homedir(), ".claude", "projects", encodeCwd(this.cwd));
21253
21299
  }
21254
21300
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
21255
21301
  setCurrentConversationId(id) {
@@ -21261,7 +21307,7 @@ var HistoryService = class _HistoryService {
21261
21307
  /** Return the current message count in the active conversation. */
21262
21308
  getCurrentMessageCount() {
21263
21309
  if (!this.currentConversationId) return 0;
21264
- const filePath = path51.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21310
+ const filePath = path52.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21265
21311
  return parseJsonl(filePath).length;
21266
21312
  }
21267
21313
  /**
@@ -21272,7 +21318,7 @@ var HistoryService = class _HistoryService {
21272
21318
  const deadline = Date.now() + timeoutMs;
21273
21319
  while (Date.now() < deadline) {
21274
21320
  if (!this.currentConversationId) return null;
21275
- const filePath = path51.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21321
+ const filePath = path52.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21276
21322
  const messages = parseJsonl(filePath);
21277
21323
  if (messages.length > previousCount) {
21278
21324
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -21298,16 +21344,16 @@ var HistoryService = class _HistoryService {
21298
21344
  const dir = this.projectDir;
21299
21345
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21300
21346
  try {
21301
- const files = fs45.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21347
+ const files = fs46.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21302
21348
  try {
21303
- const stat3 = fs45.statSync(path51.join(dir, e.name));
21349
+ const stat3 = fs46.statSync(path52.join(dir, e.name));
21304
21350
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21305
21351
  } catch {
21306
21352
  return { name: e.name, mtime: 0, birthtime: 0 };
21307
21353
  }
21308
21354
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
21309
21355
  if (files.length > 0) {
21310
- this.currentConversationId = path51.basename(files[0].name, ".jsonl");
21356
+ this.currentConversationId = path52.basename(files[0].name, ".jsonl");
21311
21357
  }
21312
21358
  } catch {
21313
21359
  }
@@ -21341,13 +21387,13 @@ var HistoryService = class _HistoryService {
21341
21387
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21342
21388
  let entries;
21343
21389
  try {
21344
- entries = fs45.readdirSync(dir, { withFileTypes: true });
21390
+ entries = fs46.readdirSync(dir, { withFileTypes: true });
21345
21391
  } catch {
21346
21392
  return null;
21347
21393
  }
21348
21394
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21349
21395
  try {
21350
- const stat3 = fs45.statSync(path51.join(dir, e.name));
21396
+ const stat3 = fs46.statSync(path52.join(dir, e.name));
21351
21397
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21352
21398
  } catch {
21353
21399
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -21356,12 +21402,12 @@ var HistoryService = class _HistoryService {
21356
21402
  if (files.length === 0) return null;
21357
21403
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
21358
21404
  if (!files.some((f) => f.name === targetFile)) return null;
21359
- return this.extractUsageFromFile(path51.join(dir, targetFile));
21405
+ return this.extractUsageFromFile(path52.join(dir, targetFile));
21360
21406
  }
21361
21407
  extractUsageFromFile(filePath) {
21362
21408
  let raw;
21363
21409
  try {
21364
- raw = fs45.readFileSync(filePath, "utf8");
21410
+ raw = fs46.readFileSync(filePath, "utf8");
21365
21411
  } catch {
21366
21412
  return null;
21367
21413
  }
@@ -21406,9 +21452,9 @@ var HistoryService = class _HistoryService {
21406
21452
  let totalCost = 0;
21407
21453
  let files;
21408
21454
  try {
21409
- files = fs45.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21455
+ files = fs46.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21410
21456
  try {
21411
- return fs45.statSync(path51.join(projectDir, f)).mtimeMs >= monthStartMs;
21457
+ return fs46.statSync(path52.join(projectDir, f)).mtimeMs >= monthStartMs;
21412
21458
  } catch {
21413
21459
  return false;
21414
21460
  }
@@ -21419,7 +21465,7 @@ var HistoryService = class _HistoryService {
21419
21465
  for (const file of files) {
21420
21466
  let raw;
21421
21467
  try {
21422
- raw = fs45.readFileSync(path51.join(projectDir, file), "utf8");
21468
+ raw = fs46.readFileSync(path52.join(projectDir, file), "utf8");
21423
21469
  } catch {
21424
21470
  continue;
21425
21471
  }
@@ -21498,7 +21544,7 @@ var HistoryService = class _HistoryService {
21498
21544
  if (this.runtime.resolveHistoryFile) {
21499
21545
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
21500
21546
  }
21501
- return path51.join(this.projectDir, `${sessionId}.jsonl`);
21547
+ return path52.join(this.projectDir, `${sessionId}.jsonl`);
21502
21548
  }
21503
21549
  /**
21504
21550
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -21532,7 +21578,7 @@ var HistoryService = class _HistoryService {
21532
21578
  };
21533
21579
  });
21534
21580
  }
21535
- return parseJsonl(path51.join(this.projectDir, `${sessionId}.jsonl`));
21581
+ return parseJsonl(path52.join(this.projectDir, `${sessionId}.jsonl`));
21536
21582
  }
21537
21583
  async loadConversation(sessionId) {
21538
21584
  const messages = this.readConversation(sessionId);
@@ -21588,7 +21634,7 @@ var HistoryService = class _HistoryService {
21588
21634
  if (!filePath) return false;
21589
21635
  let mtimeMs;
21590
21636
  try {
21591
- mtimeMs = fs45.statSync(filePath).mtimeMs;
21637
+ mtimeMs = fs46.statSync(filePath).mtimeMs;
21592
21638
  } catch {
21593
21639
  return false;
21594
21640
  }
@@ -21657,10 +21703,10 @@ var HistoryService = class _HistoryService {
21657
21703
 
21658
21704
  // src/agents/acp/client.ts
21659
21705
  var import_node_child_process17 = require("child_process");
21660
- var fs46 = __toESM(require("fs/promises"));
21706
+ var fs47 = __toESM(require("fs/promises"));
21661
21707
  var fsSync = __toESM(require("fs"));
21662
21708
  var os39 = __toESM(require("os"));
21663
- var path52 = __toESM(require("path"));
21709
+ var path53 = __toESM(require("path"));
21664
21710
  var import_node_stream = require("stream");
21665
21711
 
21666
21712
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -24493,7 +24539,7 @@ var AcpClient = class {
24493
24539
  },
24494
24540
  readTextFile: async (params) => {
24495
24541
  try {
24496
- const content = await fs46.readFile(params.path, "utf8");
24542
+ const content = await fs47.readFile(params.path, "utf8");
24497
24543
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
24498
24544
  } catch (err) {
24499
24545
  const code = err.code;
@@ -24513,7 +24559,7 @@ var AcpClient = class {
24513
24559
  },
24514
24560
  writeTextFile: async (params) => {
24515
24561
  try {
24516
- await fs46.writeFile(params.path, params.content, "utf8");
24562
+ await fs47.writeFile(params.path, params.content, "utf8");
24517
24563
  return {};
24518
24564
  } catch (err) {
24519
24565
  const code = err.code;
@@ -24567,20 +24613,20 @@ function knownAgentBinaryDirs() {
24567
24613
  out2.push("/tmp/codeam-node20/bin");
24568
24614
  for (const root of [
24569
24615
  "/usr/local/share/nvm/versions/node",
24570
- path52.join(home, ".nvm/versions/node")
24616
+ path53.join(home, ".nvm/versions/node")
24571
24617
  ]) {
24572
24618
  try {
24573
24619
  for (const child of fsSync.readdirSync(root)) {
24574
- out2.push(path52.join(root, child, "bin"));
24620
+ out2.push(path53.join(root, child, "bin"));
24575
24621
  }
24576
24622
  } catch {
24577
24623
  }
24578
24624
  }
24579
- out2.push(path52.join(home, ".volta/bin"));
24625
+ out2.push(path53.join(home, ".volta/bin"));
24580
24626
  out2.push("/usr/local/bin");
24581
24627
  out2.push("/usr/bin");
24582
- out2.push(path52.join(home, ".local/bin"));
24583
- out2.push(path52.join(home, "bin"));
24628
+ out2.push(path53.join(home, ".local/bin"));
24629
+ out2.push(path53.join(home, "bin"));
24584
24630
  return out2.filter((p2) => {
24585
24631
  try {
24586
24632
  return fsSync.statSync(p2).isDirectory();
@@ -24591,7 +24637,7 @@ function knownAgentBinaryDirs() {
24591
24637
  }
24592
24638
  function expandPathForAgentBinaries(existingPath) {
24593
24639
  const existing = new Set(
24594
- existingPath.split(path52.delimiter).filter((p2) => p2.length > 0)
24640
+ existingPath.split(path53.delimiter).filter((p2) => p2.length > 0)
24595
24641
  );
24596
24642
  const additions = [];
24597
24643
  for (const dir of knownAgentBinaryDirs()) {
@@ -24601,7 +24647,7 @@ function expandPathForAgentBinaries(existingPath) {
24601
24647
  }
24602
24648
  }
24603
24649
  if (additions.length === 0) return existingPath;
24604
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path52.delimiter);
24650
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path53.delimiter);
24605
24651
  }
24606
24652
 
24607
24653
  // src/services/streaming/transport.ts
@@ -25115,15 +25161,15 @@ function commonPrefixLength(a, b) {
25115
25161
 
25116
25162
  // src/agents/acp/onboarding.ts
25117
25163
  var import_child_process23 = require("child_process");
25118
- var fs47 = __toESM(require("fs"));
25164
+ var fs48 = __toESM(require("fs"));
25119
25165
  var os40 = __toESM(require("os"));
25120
- var path53 = __toESM(require("path"));
25166
+ var path54 = __toESM(require("path"));
25121
25167
  var _onboardingSeam = {
25122
- markerPath: (sessionId) => path53.join(os40.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25123
- exists: (p2) => fs47.existsSync(p2),
25168
+ markerPath: (sessionId) => path54.join(os40.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25169
+ exists: (p2) => fs48.existsSync(p2),
25124
25170
  write: (p2) => {
25125
- fs47.mkdirSync(path53.dirname(p2), { recursive: true });
25126
- fs47.writeFileSync(p2, "");
25171
+ fs48.mkdirSync(path54.dirname(p2), { recursive: true });
25172
+ fs48.writeFileSync(p2, "");
25127
25173
  },
25128
25174
  disabled: () => {
25129
25175
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -25160,7 +25206,7 @@ function resolveRepoName(cwd) {
25160
25206
  if (name) return name;
25161
25207
  }
25162
25208
  }
25163
- const base = path53.basename(cwd || "");
25209
+ const base = path54.basename(cwd || "");
25164
25210
  if (base && !isUuid(base)) return base;
25165
25211
  return "this project";
25166
25212
  }
@@ -25438,8 +25484,8 @@ var import_crypto5 = require("crypto");
25438
25484
 
25439
25485
  // src/services/turn-files/git-changeset.ts
25440
25486
  var import_child_process24 = require("child_process");
25441
- var fs48 = __toESM(require("fs/promises"));
25442
- var path54 = __toESM(require("path"));
25487
+ var fs49 = __toESM(require("fs/promises"));
25488
+ var path55 = __toESM(require("path"));
25443
25489
  async function collectRepoChangeset(opts) {
25444
25490
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
25445
25491
  if (status2 === null) return null;
@@ -25457,7 +25503,7 @@ async function collectRepoChangeset(opts) {
25457
25503
  let stats;
25458
25504
  if (row.fileStatus === "added" && numstatEntry === void 0) {
25459
25505
  const lineCount = await readUntrackedLineCount(
25460
- path54.join(opts.repoRoot, row.filePath)
25506
+ path55.join(opts.repoRoot, row.filePath)
25461
25507
  );
25462
25508
  stats = { added: lineCount, removed: 0 };
25463
25509
  } else {
@@ -25488,7 +25534,7 @@ function readUntrackedLineCount(absPath) {
25488
25534
  }
25489
25535
  async function defaultReadUntrackedLineCount(absPath) {
25490
25536
  try {
25491
- const content = await fs48.readFile(absPath, "utf8");
25537
+ const content = await fs49.readFile(absPath, "utf8");
25492
25538
  let count = 0;
25493
25539
  let pos = -1;
25494
25540
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -25580,7 +25626,7 @@ function defaultRunGit(cwd, args2) {
25580
25626
  });
25581
25627
  }
25582
25628
  async function discoverRepos(workingDir, maxDepth = 4) {
25583
- const fs52 = await import("fs/promises");
25629
+ const fs53 = await import("fs/promises");
25584
25630
  const out2 = [];
25585
25631
  await walk(workingDir, 0);
25586
25632
  return out2;
@@ -25588,7 +25634,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25588
25634
  if (depth > maxDepth) return;
25589
25635
  let entries = [];
25590
25636
  try {
25591
- const dirents = await fs52.readdir(dir, { withFileTypes: true });
25637
+ const dirents = await fs53.readdir(dir, { withFileTypes: true });
25592
25638
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
25593
25639
  } catch {
25594
25640
  return;
@@ -25599,8 +25645,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25599
25645
  if (hasGit) {
25600
25646
  out2.push({
25601
25647
  repoRoot: dir,
25602
- repoPath: path54.relative(workingDir, dir),
25603
- repoName: path54.basename(dir)
25648
+ repoPath: path55.relative(workingDir, dir),
25649
+ repoName: path55.basename(dir)
25604
25650
  });
25605
25651
  return;
25606
25652
  }
@@ -25608,14 +25654,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25608
25654
  if (!entry.isDirectory) continue;
25609
25655
  if (entry.name === "node_modules") continue;
25610
25656
  if (entry.name === "dist" || entry.name === "build") continue;
25611
- await walk(path54.join(dir, entry.name), depth + 1);
25657
+ await walk(path55.join(dir, entry.name), depth + 1);
25612
25658
  }
25613
25659
  }
25614
25660
  }
25615
25661
 
25616
25662
  // src/services/turn-files/files-outbox.ts
25617
- var fs49 = __toESM(require("fs/promises"));
25618
- var path55 = __toESM(require("path"));
25663
+ var fs50 = __toESM(require("fs/promises"));
25664
+ var path56 = __toESM(require("path"));
25619
25665
  var import_os7 = require("os");
25620
25666
  var HOME_OUTBOX_DIR = ".codeam/outbox";
25621
25667
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -25648,16 +25694,16 @@ var FilesOutbox = class {
25648
25694
  backoffIndex = 0;
25649
25695
  stopped = false;
25650
25696
  constructor(opts) {
25651
- const base = opts.baseDir ?? path55.join(homeDir(), HOME_OUTBOX_DIR);
25652
- this.filePath = path55.join(base, `${opts.sessionId}.jsonl`);
25697
+ const base = opts.baseDir ?? path56.join(homeDir(), HOME_OUTBOX_DIR);
25698
+ this.filePath = path56.join(base, `${opts.sessionId}.jsonl`);
25653
25699
  this.post = opts.post;
25654
25700
  this.autoSchedule = opts.autoSchedule !== false;
25655
25701
  }
25656
25702
  /** Persist the entry to disk and trigger a flush. Returns once the
25657
25703
  * line is durable on disk (not once the POST succeeds). */
25658
25704
  async enqueue(entry) {
25659
- await fs49.mkdir(path55.dirname(this.filePath), { recursive: true });
25660
- await fs49.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25705
+ await fs50.mkdir(path56.dirname(this.filePath), { recursive: true });
25706
+ await fs50.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25661
25707
  this.backoffIndex = 0;
25662
25708
  if (this.autoSchedule) this.scheduleFlush(0);
25663
25709
  }
@@ -25746,7 +25792,7 @@ var FilesOutbox = class {
25746
25792
  async readAll() {
25747
25793
  let raw = "";
25748
25794
  try {
25749
- raw = await fs49.readFile(this.filePath, "utf8");
25795
+ raw = await fs50.readFile(this.filePath, "utf8");
25750
25796
  } catch {
25751
25797
  return [];
25752
25798
  }
@@ -25770,12 +25816,12 @@ var FilesOutbox = class {
25770
25816
  async rewrite(entries) {
25771
25817
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
25772
25818
  if (entries.length === 0) {
25773
- await fs49.unlink(this.filePath).catch(() => void 0);
25819
+ await fs50.unlink(this.filePath).catch(() => void 0);
25774
25820
  return;
25775
25821
  }
25776
25822
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
25777
- await fs49.writeFile(tmpPath, payload, "utf8");
25778
- await fs49.rename(tmpPath, this.filePath);
25823
+ await fs50.writeFile(tmpPath, payload, "utf8");
25824
+ await fs50.rename(tmpPath, this.filePath);
25779
25825
  }
25780
25826
  };
25781
25827
  function applyJitter(ms) {
@@ -28404,15 +28450,15 @@ function fetchQuotaUsage(runtime, historySvc) {
28404
28450
  }
28405
28451
 
28406
28452
  // src/agents/claude/onboarding.ts
28407
- var fs50 = __toESM(require("fs"));
28453
+ var fs51 = __toESM(require("fs"));
28408
28454
  var os41 = __toESM(require("os"));
28409
- var path56 = __toESM(require("path"));
28455
+ var path57 = __toESM(require("path"));
28410
28456
  function ensureClaudeOnboarded() {
28411
28457
  try {
28412
- const file = path56.join(os41.homedir(), ".claude.json");
28458
+ const file = path57.join(os41.homedir(), ".claude.json");
28413
28459
  let config = {};
28414
28460
  try {
28415
- config = JSON.parse(fs50.readFileSync(file, "utf8"));
28461
+ config = JSON.parse(fs51.readFileSync(file, "utf8"));
28416
28462
  } catch {
28417
28463
  }
28418
28464
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -28423,8 +28469,8 @@ function ensureClaudeOnboarded() {
28423
28469
  if (typeof config.lastOnboardingVersion !== "string") {
28424
28470
  config.lastOnboardingVersion = "2.1.177";
28425
28471
  }
28426
- fs50.mkdirSync(path56.dirname(file), { recursive: true });
28427
- fs50.writeFileSync(file, JSON.stringify(config, null, 2));
28472
+ fs51.mkdirSync(path57.dirname(file), { recursive: true });
28473
+ fs51.writeFileSync(file, JSON.stringify(config, null, 2));
28428
28474
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
28429
28475
  } catch (err) {
28430
28476
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -28528,9 +28574,10 @@ async function start(requestedAgent) {
28528
28574
  const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
28529
28575
  if (process.env.CODESPACES === "true") {
28530
28576
  const GATE_TIMEOUT_MS = 24e4;
28577
+ const claudeBinaryReady = session.agent === "claude" ? waitForClaudeNativeBinary({ timeoutMs: GATE_TIMEOUT_MS }).catch(() => null) : Promise.resolve();
28531
28578
  let gateTimer;
28532
28579
  await Promise.race([
28533
- Promise.all([beadsReady.catch(() => null), depsReady]),
28580
+ Promise.all([beadsReady.catch(() => null), depsReady, claudeBinaryReady]),
28534
28581
  new Promise((resolve7) => {
28535
28582
  gateTimer = setTimeout(resolve7, GATE_TIMEOUT_MS);
28536
28583
  })
@@ -29074,7 +29121,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
29074
29121
  var import_child_process25 = require("child_process");
29075
29122
  var import_util4 = require("util");
29076
29123
  var import_picocolors9 = __toESM(require("picocolors"));
29077
- var path57 = __toESM(require("path"));
29124
+ var path58 = __toESM(require("path"));
29078
29125
  var execFileP6 = (0, import_util4.promisify)(import_child_process25.execFile);
29079
29126
  var MAX_BUFFER = 8 * 1024 * 1024;
29080
29127
  function resetStdinForChild() {
@@ -29563,7 +29610,7 @@ var GitHubCodespacesProvider = class {
29563
29610
  });
29564
29611
  }
29565
29612
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29566
- const remoteDir = path57.posix.dirname(remotePath);
29613
+ const remoteDir = path58.posix.dirname(remotePath);
29567
29614
  const parts = [
29568
29615
  `mkdir -p ${shellQuote(remoteDir)}`,
29569
29616
  `cat > ${shellQuote(remotePath)}`
@@ -29633,7 +29680,7 @@ function shellQuote(s) {
29633
29680
  // src/services/providers/gitpod.ts
29634
29681
  var import_child_process26 = require("child_process");
29635
29682
  var import_util5 = require("util");
29636
- var path58 = __toESM(require("path"));
29683
+ var path59 = __toESM(require("path"));
29637
29684
  var import_picocolors10 = __toESM(require("picocolors"));
29638
29685
  var execFileP7 = (0, import_util5.promisify)(import_child_process26.execFile);
29639
29686
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -29873,7 +29920,7 @@ var GitpodProvider = class {
29873
29920
  });
29874
29921
  }
29875
29922
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29876
- const remoteDir = path58.posix.dirname(remotePath);
29923
+ const remoteDir = path59.posix.dirname(remotePath);
29877
29924
  const parts = [
29878
29925
  `mkdir -p ${shellQuote2(remoteDir)}`,
29879
29926
  `cat > ${shellQuote2(remotePath)}`
@@ -29909,7 +29956,7 @@ function shellQuote2(s) {
29909
29956
  // src/services/providers/gitlab-workspaces.ts
29910
29957
  var import_child_process27 = require("child_process");
29911
29958
  var import_util6 = require("util");
29912
- var path59 = __toESM(require("path"));
29959
+ var path60 = __toESM(require("path"));
29913
29960
  var execFileP8 = (0, import_util6.promisify)(import_child_process27.execFile);
29914
29961
  var MAX_BUFFER3 = 8 * 1024 * 1024;
29915
29962
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -30169,7 +30216,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
30169
30216
  }
30170
30217
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
30171
30218
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
30172
- const remoteDir = path59.posix.dirname(remotePath);
30219
+ const remoteDir = path60.posix.dirname(remotePath);
30173
30220
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
30174
30221
  if (options.mode != null) {
30175
30222
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -30237,7 +30284,7 @@ function shellQuote3(s) {
30237
30284
  // src/services/providers/railway.ts
30238
30285
  var import_child_process28 = require("child_process");
30239
30286
  var import_util7 = require("util");
30240
- var path60 = __toESM(require("path"));
30287
+ var path61 = __toESM(require("path"));
30241
30288
  var execFileP9 = (0, import_util7.promisify)(import_child_process28.execFile);
30242
30289
  var MAX_BUFFER4 = 8 * 1024 * 1024;
30243
30290
  function resetStdinForChild4() {
@@ -30473,7 +30520,7 @@ var RailwayProvider = class {
30473
30520
  if (!projectId || !serviceId) {
30474
30521
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
30475
30522
  }
30476
- const remoteDir = path60.posix.dirname(remotePath);
30523
+ const remoteDir = path61.posix.dirname(remotePath);
30477
30524
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
30478
30525
  if (options.mode != null) {
30479
30526
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -31119,8 +31166,8 @@ async function invite() {
31119
31166
  var import_node_dns = require("dns");
31120
31167
  var import_node_util5 = require("util");
31121
31168
  var import_node_crypto8 = require("crypto");
31122
- var fs51 = __toESM(require("fs"));
31123
- var path61 = __toESM(require("path"));
31169
+ var fs52 = __toESM(require("fs"));
31170
+ var path62 = __toESM(require("path"));
31124
31171
  var import_picocolors14 = __toESM(require("picocolors"));
31125
31172
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
31126
31173
  async function checkDns(apiBase2) {
@@ -31176,13 +31223,13 @@ async function checkHealth(apiBase2) {
31176
31223
  }
31177
31224
  }
31178
31225
  function checkConfigDir() {
31179
- const dir = path61.join(require("os").homedir(), ".codeam");
31226
+ const dir = path62.join(require("os").homedir(), ".codeam");
31180
31227
  try {
31181
- fs51.mkdirSync(dir, { recursive: true, mode: 448 });
31182
- const probe = path61.join(dir, ".doctor-probe");
31183
- fs51.writeFileSync(probe, "ok", { mode: 384 });
31184
- const read2 = fs51.readFileSync(probe, "utf8");
31185
- fs51.unlinkSync(probe);
31228
+ fs52.mkdirSync(dir, { recursive: true, mode: 448 });
31229
+ const probe = path62.join(dir, ".doctor-probe");
31230
+ fs52.writeFileSync(probe, "ok", { mode: 384 });
31231
+ const read2 = fs52.readFileSync(probe, "utf8");
31232
+ fs52.unlinkSync(probe);
31186
31233
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
31187
31234
  return {
31188
31235
  id: "config-dir",
@@ -31246,7 +31293,7 @@ function checkNodePty() {
31246
31293
  detail: "not required on this platform"
31247
31294
  };
31248
31295
  }
31249
- const vendoredPath = path61.join(__dirname, "vendor", "node-pty");
31296
+ const vendoredPath = path62.join(__dirname, "vendor", "node-pty");
31250
31297
  for (const target of [vendoredPath, "node-pty"]) {
31251
31298
  try {
31252
31299
  require(target);
@@ -31288,7 +31335,7 @@ function checkChokidar() {
31288
31335
  }
31289
31336
  async function doctor(args2 = []) {
31290
31337
  const json = args2.includes("--json");
31291
- const cliVersion = true ? "2.52.6" : "0.0.0-dev";
31338
+ const cliVersion = true ? "2.52.7" : "0.0.0-dev";
31292
31339
  const apiBase2 = resolveApiBaseUrl();
31293
31340
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
31294
31341
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -31487,7 +31534,7 @@ async function completion(args2) {
31487
31534
  // src/commands/version.ts
31488
31535
  var import_picocolors15 = __toESM(require("picocolors"));
31489
31536
  function version2() {
31490
- const v = true ? "2.52.6" : "unknown";
31537
+ const v = true ? "2.52.7" : "unknown";
31491
31538
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
31492
31539
  }
31493
31540
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.52.6",
3
+ "version": "2.52.7",
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",