codeam-cli 2.4.31 → 2.4.33

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,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.4.31] — 2026-05-05
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Vendor node-pty into dist/ — guarantees ConPTY binary on Windows (v2.4.31)
12
+
7
13
  ## [2.4.30] — 2026-05-05
8
14
 
9
15
  ### Fixed
package/dist/index.js CHANGED
@@ -521,7 +521,7 @@ var require_windowsPtyAgent = __commonJS({
521
521
  exports2.argsToCommandLine = exports2.WindowsPtyAgent = void 0;
522
522
  var fs9 = require("fs");
523
523
  var os8 = require("os");
524
- var path15 = require("path");
524
+ var path16 = require("path");
525
525
  var child_process_1 = require("child_process");
526
526
  var net_1 = require("net");
527
527
  var windowsConoutConnection_1 = require_windowsConoutConnection();
@@ -557,7 +557,7 @@ var require_windowsPtyAgent = __commonJS({
557
557
  }
558
558
  }
559
559
  this._ptyNative = this._useConpty ? conptyNative : winptyNative;
560
- cwd = path15.resolve(cwd);
560
+ cwd = path16.resolve(cwd);
561
561
  var commandLine = argsToCommandLine(file, args2);
562
562
  var term;
563
563
  if (this._useConpty) {
@@ -679,7 +679,7 @@ var require_windowsPtyAgent = __commonJS({
679
679
  WindowsPtyAgent2.prototype._getConsoleProcessList = function() {
680
680
  var _this = this;
681
681
  return new Promise(function(resolve2) {
682
- var agent = child_process_1.fork(path15.join(__dirname, "conpty_console_list_agent"), [_this._innerPid.toString()]);
682
+ var agent = child_process_1.fork(path16.join(__dirname, "conpty_console_list_agent"), [_this._innerPid.toString()]);
683
683
  agent.on("message", function(message) {
684
684
  clearTimeout(timeout);
685
685
  resolve2(message.consoleProcessList);
@@ -1013,14 +1013,14 @@ var require_unixTerminal = __commonJS({
1013
1013
  Object.defineProperty(exports2, "__esModule", { value: true });
1014
1014
  exports2.UnixTerminal = void 0;
1015
1015
  var fs9 = require("fs");
1016
- var path15 = require("path");
1016
+ var path16 = require("path");
1017
1017
  var tty = require("tty");
1018
1018
  var terminal_1 = require_terminal();
1019
1019
  var utils_1 = require_utils();
1020
1020
  var native = utils_1.loadNativeModule("pty");
1021
1021
  var pty = native.module;
1022
1022
  var helperPath = native.dir + "/spawn-helper";
1023
- helperPath = path15.resolve(__dirname, helperPath);
1023
+ helperPath = path16.resolve(__dirname, helperPath);
1024
1024
  helperPath = helperPath.replace("app.asar", "app.asar.unpacked");
1025
1025
  helperPath = helperPath.replace("node_modules.asar", "node_modules.asar.unpacked");
1026
1026
  var DEFAULT_FILE = "sh";
@@ -1392,7 +1392,7 @@ var require_src = __commonJS({
1392
1392
  // src/commands/start.ts
1393
1393
  var fs7 = __toESM(require("fs"));
1394
1394
  var os6 = __toESM(require("os"));
1395
- var path9 = __toESM(require("path"));
1395
+ var path10 = __toESM(require("path"));
1396
1396
  var import_crypto = require("crypto");
1397
1397
  var import_child_process5 = require("child_process");
1398
1398
  var import_picocolors2 = __toESM(require("picocolors"));
@@ -1482,7 +1482,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
1482
1482
  // package.json
1483
1483
  var package_default = {
1484
1484
  name: "codeam-cli",
1485
- version: "2.4.31",
1485
+ version: "2.4.33",
1486
1486
  description: "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands \u2014 from anywhere.",
1487
1487
  main: "dist/index.js",
1488
1488
  bin: {
@@ -1963,27 +1963,35 @@ var CommandRelayService = class {
1963
1963
  }
1964
1964
  };
1965
1965
 
1966
+ // src/services/pty/unix.strategy.ts
1967
+ var import_child_process = require("child_process");
1968
+ var fs3 = __toESM(require("fs"));
1969
+ var os3 = __toESM(require("os"));
1970
+ var path3 = __toESM(require("path"));
1971
+
1966
1972
  // src/services/pty/types.ts
1967
1973
  var fs2 = __toESM(require("fs"));
1968
1974
  var path2 = __toESM(require("path"));
1969
1975
  function findInPath(name) {
1970
- const dirs = (process.env.PATH ?? "").split(path2.delimiter);
1976
+ const isWin = process.platform === "win32";
1977
+ const dirs = (process.env.PATH ?? "").split(path2.delimiter).filter(Boolean);
1978
+ const hasExt = path2.extname(name).length > 0;
1979
+ const candidates = isWin && !hasExt ? [`${name}.exe`, `${name}.cmd`, `${name}.bat`, `${name}.ps1`, name] : [name];
1980
+ const accessFlag = isWin ? fs2.constants.F_OK : fs2.constants.X_OK;
1971
1981
  for (const dir of dirs) {
1972
- const full = `${dir}/${name}`;
1973
- try {
1974
- fs2.accessSync(full, fs2.constants.X_OK);
1975
- return full;
1976
- } catch {
1982
+ for (const candidate of candidates) {
1983
+ const full = path2.join(dir, candidate);
1984
+ try {
1985
+ fs2.accessSync(full, accessFlag);
1986
+ return full;
1987
+ } catch {
1988
+ }
1977
1989
  }
1978
1990
  }
1979
1991
  return null;
1980
1992
  }
1981
1993
 
1982
1994
  // src/services/pty/unix.strategy.ts
1983
- var import_child_process = require("child_process");
1984
- var fs3 = __toESM(require("fs"));
1985
- var os3 = __toESM(require("os"));
1986
- var path3 = __toESM(require("path"));
1987
1995
  var PYTHON_PTY_HELPER = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
1988
1996
  m,s=pty.openpty()
1989
1997
  try:
@@ -2285,6 +2293,7 @@ var WindowsConPtyStrategy = class _WindowsConPtyStrategy {
2285
2293
  dataSub = null;
2286
2294
  exitSub = null;
2287
2295
  rawModeSet = false;
2296
+ resizeHandler = null;
2288
2297
  /**
2289
2298
  * Factory that returns a working ConPTY strategy or `null` if
2290
2299
  * node-pty can't load. The caller (claude.service.ts) decides
@@ -2296,10 +2305,12 @@ var WindowsConPtyStrategy = class _WindowsConPtyStrategy {
2296
2305
  return new _WindowsConPtyStrategy(opts, lib);
2297
2306
  }
2298
2307
  spawn(cmd, cwd, args2 = []) {
2308
+ const cols = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 120;
2309
+ const rows = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : 30;
2299
2310
  this.pty = this.lib.spawn(cmd, args2, {
2300
2311
  name: "xterm-256color",
2301
- cols: 220,
2302
- rows: 50,
2312
+ cols,
2313
+ rows,
2303
2314
  cwd,
2304
2315
  env: {
2305
2316
  ...process.env,
@@ -2326,6 +2337,15 @@ var WindowsConPtyStrategy = class _WindowsConPtyStrategy {
2326
2337
  }
2327
2338
  process.stdin.resume();
2328
2339
  process.stdin.on("data", this.stdinHandler);
2340
+ this.resizeHandler = () => {
2341
+ const c2 = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : cols;
2342
+ const r = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : rows;
2343
+ try {
2344
+ this.pty?.resize(c2, r);
2345
+ } catch {
2346
+ }
2347
+ };
2348
+ process.stdout.on("resize", this.resizeHandler);
2329
2349
  }
2330
2350
  write(data) {
2331
2351
  if (!this.pty) return;
@@ -2344,6 +2364,10 @@ var WindowsConPtyStrategy = class _WindowsConPtyStrategy {
2344
2364
  this.dataSub = null;
2345
2365
  this.exitSub = null;
2346
2366
  process.stdin.removeListener("data", this.stdinHandler);
2367
+ if (this.resizeHandler) {
2368
+ process.stdout.removeListener("resize", this.resizeHandler);
2369
+ this.resizeHandler = null;
2370
+ }
2347
2371
  if (this.rawModeSet && process.stdin.isTTY) {
2348
2372
  try {
2349
2373
  process.stdin.setRawMode(false);
@@ -4351,6 +4375,26 @@ async function ensureClaudeInstalled() {
4351
4375
  return true;
4352
4376
  }
4353
4377
 
4378
+ // src/services/claude-resolver.ts
4379
+ var path6 = __toESM(require("path"));
4380
+ function buildClaudeLaunch(extraArgs = []) {
4381
+ const found = findInPath("claude") ?? findInPath("claude-code");
4382
+ if (!found) return null;
4383
+ if (process.platform === "win32") {
4384
+ const ext = path6.extname(found).toLowerCase();
4385
+ if (ext === ".cmd" || ext === ".bat") {
4386
+ return { cmd: "cmd.exe", args: ["/c", found, ...extraArgs] };
4387
+ }
4388
+ if (ext === ".ps1") {
4389
+ return {
4390
+ cmd: "powershell.exe",
4391
+ args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", found, ...extraArgs]
4392
+ };
4393
+ }
4394
+ }
4395
+ return { cmd: found, args: extraArgs };
4396
+ }
4397
+
4354
4398
  // src/services/claude.service.ts
4355
4399
  var ClaudeService = class {
4356
4400
  constructor(opts) {
@@ -4368,9 +4412,11 @@ var ClaudeService = class {
4368
4412
  strategy = null;
4369
4413
  strategyOpts;
4370
4414
  async spawn() {
4371
- if (!findInPath("claude") && !findInPath("claude-code")) {
4415
+ let launch = buildClaudeLaunch();
4416
+ if (!launch) {
4372
4417
  const installed = await ensureClaudeInstalled();
4373
- if (!installed) {
4418
+ if (installed) launch = buildClaudeLaunch();
4419
+ if (!launch) {
4374
4420
  const cmd = process.platform === "win32" ? "irm https://claude.ai/install.ps1 | iex" : "curl -fsSL https://claude.ai/install.sh | bash";
4375
4421
  console.error(
4376
4422
  `
@@ -4382,12 +4428,11 @@ var ClaudeService = class {
4382
4428
  process.exit(1);
4383
4429
  }
4384
4430
  }
4385
- const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
4386
4431
  if (process.platform === "win32") {
4387
4432
  const conpty = WindowsConPtyStrategy.tryCreate(this.strategyOpts);
4388
4433
  if (conpty) {
4389
4434
  try {
4390
- conpty.spawn(claudeCmd, this.opts.cwd);
4435
+ conpty.spawn(launch.cmd, this.opts.cwd, launch.args);
4391
4436
  this.strategy = conpty;
4392
4437
  return;
4393
4438
  } catch (err) {
@@ -4406,12 +4451,12 @@ var ClaudeService = class {
4406
4451
  );
4407
4452
  }
4408
4453
  const pipe = new WindowsPtyStrategy(this.strategyOpts);
4409
- pipe.spawn(claudeCmd, this.opts.cwd);
4454
+ pipe.spawn(launch.cmd, this.opts.cwd, launch.args);
4410
4455
  this.strategy = pipe;
4411
4456
  return;
4412
4457
  }
4413
4458
  const unix = new UnixPtyStrategy(this.strategyOpts);
4414
- unix.spawn(claudeCmd, this.opts.cwd);
4459
+ unix.spawn(launch.cmd, this.opts.cwd, launch.args);
4415
4460
  this.strategy = unix;
4416
4461
  }
4417
4462
  /**
@@ -4489,11 +4534,12 @@ var ClaudeService = class {
4489
4534
  */
4490
4535
  restart(sessionId, auto = false) {
4491
4536
  if (!this.strategy) return;
4492
- const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
4537
+ const extraArgs = ["--resume", sessionId];
4538
+ if (auto) extraArgs.push("--dangerously-skip-permissions");
4539
+ const launch = buildClaudeLaunch(extraArgs);
4540
+ if (!launch) return;
4493
4541
  this.strategy.kill();
4494
- const args2 = ["--resume", sessionId];
4495
- if (auto) args2.push("--dangerously-skip-permissions");
4496
- this.strategy.spawn(claudeCmd, this.opts.cwd, args2);
4542
+ this.strategy.spawn(launch.cmd, this.opts.cwd, launch.args);
4497
4543
  }
4498
4544
  };
4499
4545
 
@@ -5175,7 +5221,7 @@ function _sendOutputChunk(url, headers, payload) {
5175
5221
 
5176
5222
  // src/services/history.service.ts
5177
5223
  var fs4 = __toESM(require("fs"));
5178
- var path6 = __toESM(require("path"));
5224
+ var path7 = __toESM(require("path"));
5179
5225
  var os5 = __toESM(require("os"));
5180
5226
  var https3 = __toESM(require("https"));
5181
5227
  var http3 = __toESM(require("http"));
@@ -5331,7 +5377,7 @@ var HistoryService = class {
5331
5377
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
5332
5378
  }
5333
5379
  get projectDir() {
5334
- return path6.join(os5.homedir(), ".claude", "projects", encodeCwd(this.cwd));
5380
+ return path7.join(os5.homedir(), ".claude", "projects", encodeCwd(this.cwd));
5335
5381
  }
5336
5382
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
5337
5383
  setCurrentConversationId(id) {
@@ -5343,7 +5389,7 @@ var HistoryService = class {
5343
5389
  /** Return the current message count in the active conversation. */
5344
5390
  getCurrentMessageCount() {
5345
5391
  if (!this.currentConversationId) return 0;
5346
- const filePath = path6.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5392
+ const filePath = path7.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5347
5393
  return parseJsonl(filePath).length;
5348
5394
  }
5349
5395
  /**
@@ -5354,7 +5400,7 @@ var HistoryService = class {
5354
5400
  const deadline = Date.now() + timeoutMs;
5355
5401
  while (Date.now() < deadline) {
5356
5402
  if (!this.currentConversationId) return null;
5357
- const filePath = path6.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5403
+ const filePath = path7.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5358
5404
  const messages = parseJsonl(filePath);
5359
5405
  if (messages.length > previousCount) {
5360
5406
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -5371,13 +5417,13 @@ var HistoryService = class {
5371
5417
  try {
5372
5418
  const files = fs4.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
5373
5419
  try {
5374
- return { name: e.name, mtime: fs4.statSync(path6.join(dir, e.name)).mtimeMs };
5420
+ return { name: e.name, mtime: fs4.statSync(path7.join(dir, e.name)).mtimeMs };
5375
5421
  } catch {
5376
5422
  return { name: e.name, mtime: 0 };
5377
5423
  }
5378
5424
  }).sort((a, b) => b.mtime - a.mtime);
5379
5425
  if (files.length > 0) {
5380
- this.currentConversationId = path6.basename(files[0].name, ".jsonl");
5426
+ this.currentConversationId = path7.basename(files[0].name, ".jsonl");
5381
5427
  }
5382
5428
  } catch {
5383
5429
  }
@@ -5415,7 +5461,7 @@ var HistoryService = class {
5415
5461
  }
5416
5462
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
5417
5463
  try {
5418
- return { name: e.name, mtime: fs4.statSync(path6.join(dir, e.name)).mtimeMs };
5464
+ return { name: e.name, mtime: fs4.statSync(path7.join(dir, e.name)).mtimeMs };
5419
5465
  } catch {
5420
5466
  return { name: e.name, mtime: 0 };
5421
5467
  }
@@ -5423,7 +5469,7 @@ var HistoryService = class {
5423
5469
  if (files.length === 0) return null;
5424
5470
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
5425
5471
  if (!files.some((f) => f.name === targetFile)) return null;
5426
- return this.extractUsageFromFile(path6.join(dir, targetFile));
5472
+ return this.extractUsageFromFile(path7.join(dir, targetFile));
5427
5473
  }
5428
5474
  extractUsageFromFile(filePath) {
5429
5475
  let raw;
@@ -5475,7 +5521,7 @@ var HistoryService = class {
5475
5521
  try {
5476
5522
  files = fs4.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
5477
5523
  try {
5478
- return fs4.statSync(path6.join(projectDir, f)).mtimeMs >= monthStartMs;
5524
+ return fs4.statSync(path7.join(projectDir, f)).mtimeMs >= monthStartMs;
5479
5525
  } catch {
5480
5526
  return false;
5481
5527
  }
@@ -5486,7 +5532,7 @@ var HistoryService = class {
5486
5532
  for (const file of files) {
5487
5533
  let raw;
5488
5534
  try {
5489
- raw = fs4.readFileSync(path6.join(projectDir, file), "utf8");
5535
+ raw = fs4.readFileSync(path7.join(projectDir, file), "utf8");
5490
5536
  } catch {
5491
5537
  continue;
5492
5538
  }
@@ -5528,8 +5574,8 @@ var HistoryService = class {
5528
5574
  const sessions2 = [];
5529
5575
  for (const entry of entries) {
5530
5576
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
5531
- const id = path6.basename(entry.name, ".jsonl");
5532
- const filePath = path6.join(dir, entry.name);
5577
+ const id = path7.basename(entry.name, ".jsonl");
5578
+ const filePath = path7.join(dir, entry.name);
5533
5579
  let mtime = Date.now();
5534
5580
  try {
5535
5581
  mtime = fs4.statSync(filePath).mtimeMs;
@@ -5570,7 +5616,7 @@ var HistoryService = class {
5570
5616
  * showing an empty conversation.
5571
5617
  */
5572
5618
  async loadConversation(sessionId) {
5573
- const filePath = path6.join(this.projectDir, `${sessionId}.jsonl`);
5619
+ const filePath = path7.join(this.projectDir, `${sessionId}.jsonl`);
5574
5620
  const messages = parseJsonl(filePath);
5575
5621
  if (messages.length === 0) return;
5576
5622
  const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
@@ -5626,7 +5672,7 @@ function parsePayload(schema, raw) {
5626
5672
 
5627
5673
  // src/services/file-ops.service.ts
5628
5674
  var fs5 = __toESM(require("fs/promises"));
5629
- var path7 = __toESM(require("path"));
5675
+ var path8 = __toESM(require("path"));
5630
5676
  var MAX_FILE_BYTES = 5 * 1024 * 1024;
5631
5677
  var MAX_WALK_DEPTH = 6;
5632
5678
  var MAX_VISITED_DIRS = 5e3;
@@ -5661,8 +5707,8 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
5661
5707
  "__pycache__"
5662
5708
  ]);
5663
5709
  function isUnder(parent, candidate) {
5664
- const rel = path7.relative(parent, candidate);
5665
- return rel === "" || !rel.startsWith("..") && !path7.isAbsolute(rel);
5710
+ const rel = path8.relative(parent, candidate);
5711
+ return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
5666
5712
  }
5667
5713
  async function isExistingFile(absPath) {
5668
5714
  try {
@@ -5685,7 +5731,7 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
5685
5731
  }
5686
5732
  for (const e of entries) {
5687
5733
  if (!e.isFile()) continue;
5688
- const full = path7.join(dir, e.name);
5734
+ const full = path8.join(dir, e.name);
5689
5735
  if (needleVariants.some((needle) => full.endsWith(needle))) {
5690
5736
  ctx.matches.push(full);
5691
5737
  if (ctx.matches.length >= ctx.cap) return;
@@ -5695,21 +5741,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
5695
5741
  if (!e.isDirectory()) continue;
5696
5742
  if (SUBDIR_IGNORE.has(e.name)) continue;
5697
5743
  if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
5698
- await walkForSuffix(path7.join(dir, e.name), needleVariants, depth + 1, ctx);
5744
+ await walkForSuffix(path8.join(dir, e.name), needleVariants, depth + 1, ctx);
5699
5745
  if (ctx.matches.length >= ctx.cap) return;
5700
5746
  }
5701
5747
  }
5702
5748
  async function findFile(rawPath) {
5703
5749
  const cwd = process.cwd();
5704
- if (path7.isAbsolute(rawPath)) {
5705
- const abs = path7.normalize(rawPath);
5750
+ if (path8.isAbsolute(rawPath)) {
5751
+ const abs = path8.normalize(rawPath);
5706
5752
  if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
5707
5753
  }
5708
- const direct = path7.resolve(cwd, rawPath);
5754
+ const direct = path8.resolve(cwd, rawPath);
5709
5755
  if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
5710
- const normalized = path7.normalize(rawPath).replace(/^[./\\]+/, "");
5756
+ const normalized = path8.normalize(rawPath).replace(/^[./\\]+/, "");
5711
5757
  const needles = [
5712
- `${path7.sep}${normalized}`,
5758
+ `${path8.sep}${normalized}`,
5713
5759
  `/${normalized}`
5714
5760
  ].filter((v, i, a) => a.indexOf(v) === i);
5715
5761
  const ctx = { visited: 0, matches: [], cap: 16 };
@@ -5723,7 +5769,7 @@ async function findWriteTarget(rawPath) {
5723
5769
  const found = await findFile(rawPath);
5724
5770
  if (found) return found;
5725
5771
  const cwd = process.cwd();
5726
- const fallback = path7.isAbsolute(rawPath) ? path7.normalize(rawPath) : path7.resolve(cwd, rawPath);
5772
+ const fallback = path8.isAbsolute(rawPath) ? path8.normalize(rawPath) : path8.resolve(cwd, rawPath);
5727
5773
  if (!isUnder(cwd, fallback)) return null;
5728
5774
  return fallback;
5729
5775
  }
@@ -5763,7 +5809,7 @@ async function writeProjectFile(rawPath, content) {
5763
5809
  if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
5764
5810
  return { error: "Content too large." };
5765
5811
  }
5766
- await fs5.mkdir(path7.dirname(abs), { recursive: true });
5812
+ await fs5.mkdir(path8.dirname(abs), { recursive: true });
5767
5813
  await fs5.writeFile(abs, content, "utf-8");
5768
5814
  return { ok: true };
5769
5815
  } catch (e) {
@@ -5776,7 +5822,7 @@ async function writeProjectFile(rawPath, content) {
5776
5822
  var import_child_process4 = require("child_process");
5777
5823
  var import_util = require("util");
5778
5824
  var fs6 = __toESM(require("fs/promises"));
5779
- var path8 = __toESM(require("path"));
5825
+ var path9 = __toESM(require("path"));
5780
5826
  var execFileP = (0, import_util.promisify)(import_child_process4.execFile);
5781
5827
  var PROJECT_IGNORE = /* @__PURE__ */ new Set([
5782
5828
  "node_modules",
@@ -5834,12 +5880,12 @@ async function listProjectFiles(opts = {}) {
5834
5880
  return;
5835
5881
  }
5836
5882
  if (PROJECT_IGNORE.has(e.name)) continue;
5837
- const full = path8.join(dir, e.name);
5883
+ const full = path9.join(dir, e.name);
5838
5884
  if (e.isDirectory()) {
5839
5885
  if (depth >= 12) continue;
5840
5886
  await walk(full, depth + 1);
5841
5887
  } else if (e.isFile()) {
5842
- const rel = path8.relative(root, full);
5888
+ const rel = path9.relative(root, full);
5843
5889
  if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
5844
5890
  continue;
5845
5891
  }
@@ -5947,7 +5993,7 @@ async function gitStatus(cwd) {
5947
5993
  let hasMergeInProgress = false;
5948
5994
  try {
5949
5995
  const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
5950
- const mergeHead = path8.isAbsolute(gitDir) ? path8.join(gitDir, "MERGE_HEAD") : path8.join(root, gitDir, "MERGE_HEAD");
5996
+ const mergeHead = path9.isAbsolute(gitDir) ? path9.join(gitDir, "MERGE_HEAD") : path9.join(root, gitDir, "MERGE_HEAD");
5951
5997
  await fs6.access(mergeHead);
5952
5998
  hasMergeInProgress = true;
5953
5999
  } catch {
@@ -6025,7 +6071,7 @@ async function gitResolve(file, side, cwd) {
6025
6071
  function saveFilesTemp(files) {
6026
6072
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
6027
6073
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
6028
- const tmpPath = path9.join(os6.tmpdir(), `codeam-${(0, import_crypto.randomUUID)()}-${safeName}`);
6074
+ const tmpPath = path10.join(os6.tmpdir(), `codeam-${(0, import_crypto.randomUUID)()}-${safeName}`);
6029
6075
  fs7.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
6030
6076
  return tmpPath;
6031
6077
  });
@@ -6099,7 +6145,7 @@ try:
6099
6145
  sys.exit((st>>8)&0xFF)
6100
6146
  except Exception:sys.exit(0)
6101
6147
  `;
6102
- const helperPath = path9.join(os6.tmpdir(), "codeam-quota-helper.py");
6148
+ const helperPath = path10.join(os6.tmpdir(), "codeam-quota-helper.py");
6103
6149
  fs7.writeFileSync(helperPath, helperScript, { mode: 420 });
6104
6150
  const python = findInPath("python3") ?? findInPath("python");
6105
6151
  if (!python) {
@@ -6702,7 +6748,7 @@ async function logout() {
6702
6748
  var import_child_process10 = require("child_process");
6703
6749
  var fs8 = __toESM(require("fs"));
6704
6750
  var os7 = __toESM(require("os"));
6705
- var path14 = __toESM(require("path"));
6751
+ var path15 = __toESM(require("path"));
6706
6752
  var import_util6 = require("util");
6707
6753
  var import_picocolors9 = __toESM(require("picocolors"));
6708
6754
 
@@ -6710,7 +6756,7 @@ var import_picocolors9 = __toESM(require("picocolors"));
6710
6756
  var import_child_process6 = require("child_process");
6711
6757
  var import_util2 = require("util");
6712
6758
  var import_picocolors7 = __toESM(require("picocolors"));
6713
- var path10 = __toESM(require("path"));
6759
+ var path11 = __toESM(require("path"));
6714
6760
  var execFileP2 = (0, import_util2.promisify)(import_child_process6.execFile);
6715
6761
  var MAX_BUFFER = 8 * 1024 * 1024;
6716
6762
  function resetStdinForChild() {
@@ -7199,7 +7245,7 @@ var GitHubCodespacesProvider = class {
7199
7245
  });
7200
7246
  }
7201
7247
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
7202
- const remoteDir = path10.posix.dirname(remotePath);
7248
+ const remoteDir = path11.posix.dirname(remotePath);
7203
7249
  const parts = [
7204
7250
  `mkdir -p ${shellQuote(remoteDir)}`,
7205
7251
  `cat > ${shellQuote(remotePath)}`
@@ -7269,7 +7315,7 @@ function shellQuote(s) {
7269
7315
  // src/services/providers/gitpod.ts
7270
7316
  var import_child_process7 = require("child_process");
7271
7317
  var import_util3 = require("util");
7272
- var path11 = __toESM(require("path"));
7318
+ var path12 = __toESM(require("path"));
7273
7319
  var import_picocolors8 = __toESM(require("picocolors"));
7274
7320
  var execFileP3 = (0, import_util3.promisify)(import_child_process7.execFile);
7275
7321
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -7509,7 +7555,7 @@ var GitpodProvider = class {
7509
7555
  });
7510
7556
  }
7511
7557
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
7512
- const remoteDir = path11.posix.dirname(remotePath);
7558
+ const remoteDir = path12.posix.dirname(remotePath);
7513
7559
  const parts = [
7514
7560
  `mkdir -p ${shellQuote2(remoteDir)}`,
7515
7561
  `cat > ${shellQuote2(remotePath)}`
@@ -7545,7 +7591,7 @@ function shellQuote2(s) {
7545
7591
  // src/services/providers/gitlab-workspaces.ts
7546
7592
  var import_child_process8 = require("child_process");
7547
7593
  var import_util4 = require("util");
7548
- var path12 = __toESM(require("path"));
7594
+ var path13 = __toESM(require("path"));
7549
7595
  var execFileP4 = (0, import_util4.promisify)(import_child_process8.execFile);
7550
7596
  var MAX_BUFFER3 = 8 * 1024 * 1024;
7551
7597
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -7805,7 +7851,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
7805
7851
  }
7806
7852
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
7807
7853
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
7808
- const remoteDir = path12.posix.dirname(remotePath);
7854
+ const remoteDir = path13.posix.dirname(remotePath);
7809
7855
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
7810
7856
  if (options.mode != null) {
7811
7857
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -7873,7 +7919,7 @@ function shellQuote3(s) {
7873
7919
  // src/services/providers/railway.ts
7874
7920
  var import_child_process9 = require("child_process");
7875
7921
  var import_util5 = require("util");
7876
- var path13 = __toESM(require("path"));
7922
+ var path14 = __toESM(require("path"));
7877
7923
  var execFileP5 = (0, import_util5.promisify)(import_child_process9.execFile);
7878
7924
  var MAX_BUFFER4 = 8 * 1024 * 1024;
7879
7925
  function resetStdinForChild4() {
@@ -8109,7 +8155,7 @@ var RailwayProvider = class {
8109
8155
  if (!projectId || !serviceId) {
8110
8156
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
8111
8157
  }
8112
- const remoteDir = path13.posix.dirname(remotePath);
8158
+ const remoteDir = path14.posix.dirname(remotePath);
8113
8159
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
8114
8160
  if (options.mode != null) {
8115
8161
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -8301,7 +8347,7 @@ async function deploy() {
8301
8347
  process.exit(1);
8302
8348
  }
8303
8349
  }
8304
- const localClaudeDir = path14.join(os7.homedir(), ".claude");
8350
+ const localClaudeDir = path15.join(os7.homedir(), ".claude");
8305
8351
  const localCredsKind = await detectLocalClaudeCredentials(localClaudeDir);
8306
8352
  let bridged = "none";
8307
8353
  if (localCredsKind !== "none") {
@@ -8399,7 +8445,7 @@ async function deploy() {
8399
8445
  }
8400
8446
  }
8401
8447
  if (bridged !== "none") {
8402
- const localClaudeJson = path14.join(os7.homedir(), ".claude.json");
8448
+ const localClaudeJson = path15.join(os7.homedir(), ".claude.json");
8403
8449
  if (fs8.existsSync(localClaudeJson)) {
8404
8450
  try {
8405
8451
  const contents = fs8.readFileSync(localClaudeJson);
@@ -8592,7 +8638,7 @@ async function runRemoteClaudeLogin(provider, workspaceId) {
8592
8638
  }
8593
8639
  }
8594
8640
  async function detectLocalClaudeCredentials(localClaudeDir) {
8595
- if (fs8.existsSync(path14.join(localClaudeDir, ".credentials.json"))) {
8641
+ if (fs8.existsSync(path15.join(localClaudeDir, ".credentials.json"))) {
8596
8642
  return "flat-file";
8597
8643
  }
8598
8644
  if (process.platform === "darwin") {
@@ -8625,7 +8671,7 @@ async function verifyClaudeAuth(provider, workspaceId) {
8625
8671
  }
8626
8672
  }
8627
8673
  async function bridgeClaudeCredentials(provider, workspaceId, localClaudeDir) {
8628
- const fileBased = path14.join(localClaudeDir, ".credentials.json");
8674
+ const fileBased = path15.join(localClaudeDir, ".credentials.json");
8629
8675
  if (fs8.existsSync(fileBased)) return "flat-file";
8630
8676
  if (process.platform === "darwin") {
8631
8677
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.4.31",
3
+ "version": "2.4.33",
4
4
  "description": "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands — from anywhere.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {