codeam-cli 2.4.31 → 2.4.32

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.32",
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:
@@ -4351,6 +4359,26 @@ async function ensureClaudeInstalled() {
4351
4359
  return true;
4352
4360
  }
4353
4361
 
4362
+ // src/services/claude-resolver.ts
4363
+ var path6 = __toESM(require("path"));
4364
+ function buildClaudeLaunch(extraArgs = []) {
4365
+ const found = findInPath("claude") ?? findInPath("claude-code");
4366
+ if (!found) return null;
4367
+ if (process.platform === "win32") {
4368
+ const ext = path6.extname(found).toLowerCase();
4369
+ if (ext === ".cmd" || ext === ".bat") {
4370
+ return { cmd: "cmd.exe", args: ["/c", found, ...extraArgs] };
4371
+ }
4372
+ if (ext === ".ps1") {
4373
+ return {
4374
+ cmd: "powershell.exe",
4375
+ args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", found, ...extraArgs]
4376
+ };
4377
+ }
4378
+ }
4379
+ return { cmd: found, args: extraArgs };
4380
+ }
4381
+
4354
4382
  // src/services/claude.service.ts
4355
4383
  var ClaudeService = class {
4356
4384
  constructor(opts) {
@@ -4368,9 +4396,11 @@ var ClaudeService = class {
4368
4396
  strategy = null;
4369
4397
  strategyOpts;
4370
4398
  async spawn() {
4371
- if (!findInPath("claude") && !findInPath("claude-code")) {
4399
+ let launch = buildClaudeLaunch();
4400
+ if (!launch) {
4372
4401
  const installed = await ensureClaudeInstalled();
4373
- if (!installed) {
4402
+ if (installed) launch = buildClaudeLaunch();
4403
+ if (!launch) {
4374
4404
  const cmd = process.platform === "win32" ? "irm https://claude.ai/install.ps1 | iex" : "curl -fsSL https://claude.ai/install.sh | bash";
4375
4405
  console.error(
4376
4406
  `
@@ -4382,12 +4412,11 @@ var ClaudeService = class {
4382
4412
  process.exit(1);
4383
4413
  }
4384
4414
  }
4385
- const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
4386
4415
  if (process.platform === "win32") {
4387
4416
  const conpty = WindowsConPtyStrategy.tryCreate(this.strategyOpts);
4388
4417
  if (conpty) {
4389
4418
  try {
4390
- conpty.spawn(claudeCmd, this.opts.cwd);
4419
+ conpty.spawn(launch.cmd, this.opts.cwd, launch.args);
4391
4420
  this.strategy = conpty;
4392
4421
  return;
4393
4422
  } catch (err) {
@@ -4406,12 +4435,12 @@ var ClaudeService = class {
4406
4435
  );
4407
4436
  }
4408
4437
  const pipe = new WindowsPtyStrategy(this.strategyOpts);
4409
- pipe.spawn(claudeCmd, this.opts.cwd);
4438
+ pipe.spawn(launch.cmd, this.opts.cwd, launch.args);
4410
4439
  this.strategy = pipe;
4411
4440
  return;
4412
4441
  }
4413
4442
  const unix = new UnixPtyStrategy(this.strategyOpts);
4414
- unix.spawn(claudeCmd, this.opts.cwd);
4443
+ unix.spawn(launch.cmd, this.opts.cwd, launch.args);
4415
4444
  this.strategy = unix;
4416
4445
  }
4417
4446
  /**
@@ -4489,11 +4518,12 @@ var ClaudeService = class {
4489
4518
  */
4490
4519
  restart(sessionId, auto = false) {
4491
4520
  if (!this.strategy) return;
4492
- const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
4521
+ const extraArgs = ["--resume", sessionId];
4522
+ if (auto) extraArgs.push("--dangerously-skip-permissions");
4523
+ const launch = buildClaudeLaunch(extraArgs);
4524
+ if (!launch) return;
4493
4525
  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);
4526
+ this.strategy.spawn(launch.cmd, this.opts.cwd, launch.args);
4497
4527
  }
4498
4528
  };
4499
4529
 
@@ -5175,7 +5205,7 @@ function _sendOutputChunk(url, headers, payload) {
5175
5205
 
5176
5206
  // src/services/history.service.ts
5177
5207
  var fs4 = __toESM(require("fs"));
5178
- var path6 = __toESM(require("path"));
5208
+ var path7 = __toESM(require("path"));
5179
5209
  var os5 = __toESM(require("os"));
5180
5210
  var https3 = __toESM(require("https"));
5181
5211
  var http3 = __toESM(require("http"));
@@ -5331,7 +5361,7 @@ var HistoryService = class {
5331
5361
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
5332
5362
  }
5333
5363
  get projectDir() {
5334
- return path6.join(os5.homedir(), ".claude", "projects", encodeCwd(this.cwd));
5364
+ return path7.join(os5.homedir(), ".claude", "projects", encodeCwd(this.cwd));
5335
5365
  }
5336
5366
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
5337
5367
  setCurrentConversationId(id) {
@@ -5343,7 +5373,7 @@ var HistoryService = class {
5343
5373
  /** Return the current message count in the active conversation. */
5344
5374
  getCurrentMessageCount() {
5345
5375
  if (!this.currentConversationId) return 0;
5346
- const filePath = path6.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5376
+ const filePath = path7.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5347
5377
  return parseJsonl(filePath).length;
5348
5378
  }
5349
5379
  /**
@@ -5354,7 +5384,7 @@ var HistoryService = class {
5354
5384
  const deadline = Date.now() + timeoutMs;
5355
5385
  while (Date.now() < deadline) {
5356
5386
  if (!this.currentConversationId) return null;
5357
- const filePath = path6.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5387
+ const filePath = path7.join(this.projectDir, `${this.currentConversationId}.jsonl`);
5358
5388
  const messages = parseJsonl(filePath);
5359
5389
  if (messages.length > previousCount) {
5360
5390
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -5371,13 +5401,13 @@ var HistoryService = class {
5371
5401
  try {
5372
5402
  const files = fs4.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
5373
5403
  try {
5374
- return { name: e.name, mtime: fs4.statSync(path6.join(dir, e.name)).mtimeMs };
5404
+ return { name: e.name, mtime: fs4.statSync(path7.join(dir, e.name)).mtimeMs };
5375
5405
  } catch {
5376
5406
  return { name: e.name, mtime: 0 };
5377
5407
  }
5378
5408
  }).sort((a, b) => b.mtime - a.mtime);
5379
5409
  if (files.length > 0) {
5380
- this.currentConversationId = path6.basename(files[0].name, ".jsonl");
5410
+ this.currentConversationId = path7.basename(files[0].name, ".jsonl");
5381
5411
  }
5382
5412
  } catch {
5383
5413
  }
@@ -5415,7 +5445,7 @@ var HistoryService = class {
5415
5445
  }
5416
5446
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
5417
5447
  try {
5418
- return { name: e.name, mtime: fs4.statSync(path6.join(dir, e.name)).mtimeMs };
5448
+ return { name: e.name, mtime: fs4.statSync(path7.join(dir, e.name)).mtimeMs };
5419
5449
  } catch {
5420
5450
  return { name: e.name, mtime: 0 };
5421
5451
  }
@@ -5423,7 +5453,7 @@ var HistoryService = class {
5423
5453
  if (files.length === 0) return null;
5424
5454
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
5425
5455
  if (!files.some((f) => f.name === targetFile)) return null;
5426
- return this.extractUsageFromFile(path6.join(dir, targetFile));
5456
+ return this.extractUsageFromFile(path7.join(dir, targetFile));
5427
5457
  }
5428
5458
  extractUsageFromFile(filePath) {
5429
5459
  let raw;
@@ -5475,7 +5505,7 @@ var HistoryService = class {
5475
5505
  try {
5476
5506
  files = fs4.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
5477
5507
  try {
5478
- return fs4.statSync(path6.join(projectDir, f)).mtimeMs >= monthStartMs;
5508
+ return fs4.statSync(path7.join(projectDir, f)).mtimeMs >= monthStartMs;
5479
5509
  } catch {
5480
5510
  return false;
5481
5511
  }
@@ -5486,7 +5516,7 @@ var HistoryService = class {
5486
5516
  for (const file of files) {
5487
5517
  let raw;
5488
5518
  try {
5489
- raw = fs4.readFileSync(path6.join(projectDir, file), "utf8");
5519
+ raw = fs4.readFileSync(path7.join(projectDir, file), "utf8");
5490
5520
  } catch {
5491
5521
  continue;
5492
5522
  }
@@ -5528,8 +5558,8 @@ var HistoryService = class {
5528
5558
  const sessions2 = [];
5529
5559
  for (const entry of entries) {
5530
5560
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
5531
- const id = path6.basename(entry.name, ".jsonl");
5532
- const filePath = path6.join(dir, entry.name);
5561
+ const id = path7.basename(entry.name, ".jsonl");
5562
+ const filePath = path7.join(dir, entry.name);
5533
5563
  let mtime = Date.now();
5534
5564
  try {
5535
5565
  mtime = fs4.statSync(filePath).mtimeMs;
@@ -5570,7 +5600,7 @@ var HistoryService = class {
5570
5600
  * showing an empty conversation.
5571
5601
  */
5572
5602
  async loadConversation(sessionId) {
5573
- const filePath = path6.join(this.projectDir, `${sessionId}.jsonl`);
5603
+ const filePath = path7.join(this.projectDir, `${sessionId}.jsonl`);
5574
5604
  const messages = parseJsonl(filePath);
5575
5605
  if (messages.length === 0) return;
5576
5606
  const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
@@ -5626,7 +5656,7 @@ function parsePayload(schema, raw) {
5626
5656
 
5627
5657
  // src/services/file-ops.service.ts
5628
5658
  var fs5 = __toESM(require("fs/promises"));
5629
- var path7 = __toESM(require("path"));
5659
+ var path8 = __toESM(require("path"));
5630
5660
  var MAX_FILE_BYTES = 5 * 1024 * 1024;
5631
5661
  var MAX_WALK_DEPTH = 6;
5632
5662
  var MAX_VISITED_DIRS = 5e3;
@@ -5661,8 +5691,8 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
5661
5691
  "__pycache__"
5662
5692
  ]);
5663
5693
  function isUnder(parent, candidate) {
5664
- const rel = path7.relative(parent, candidate);
5665
- return rel === "" || !rel.startsWith("..") && !path7.isAbsolute(rel);
5694
+ const rel = path8.relative(parent, candidate);
5695
+ return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
5666
5696
  }
5667
5697
  async function isExistingFile(absPath) {
5668
5698
  try {
@@ -5685,7 +5715,7 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
5685
5715
  }
5686
5716
  for (const e of entries) {
5687
5717
  if (!e.isFile()) continue;
5688
- const full = path7.join(dir, e.name);
5718
+ const full = path8.join(dir, e.name);
5689
5719
  if (needleVariants.some((needle) => full.endsWith(needle))) {
5690
5720
  ctx.matches.push(full);
5691
5721
  if (ctx.matches.length >= ctx.cap) return;
@@ -5695,21 +5725,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
5695
5725
  if (!e.isDirectory()) continue;
5696
5726
  if (SUBDIR_IGNORE.has(e.name)) continue;
5697
5727
  if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
5698
- await walkForSuffix(path7.join(dir, e.name), needleVariants, depth + 1, ctx);
5728
+ await walkForSuffix(path8.join(dir, e.name), needleVariants, depth + 1, ctx);
5699
5729
  if (ctx.matches.length >= ctx.cap) return;
5700
5730
  }
5701
5731
  }
5702
5732
  async function findFile(rawPath) {
5703
5733
  const cwd = process.cwd();
5704
- if (path7.isAbsolute(rawPath)) {
5705
- const abs = path7.normalize(rawPath);
5734
+ if (path8.isAbsolute(rawPath)) {
5735
+ const abs = path8.normalize(rawPath);
5706
5736
  if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
5707
5737
  }
5708
- const direct = path7.resolve(cwd, rawPath);
5738
+ const direct = path8.resolve(cwd, rawPath);
5709
5739
  if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
5710
- const normalized = path7.normalize(rawPath).replace(/^[./\\]+/, "");
5740
+ const normalized = path8.normalize(rawPath).replace(/^[./\\]+/, "");
5711
5741
  const needles = [
5712
- `${path7.sep}${normalized}`,
5742
+ `${path8.sep}${normalized}`,
5713
5743
  `/${normalized}`
5714
5744
  ].filter((v, i, a) => a.indexOf(v) === i);
5715
5745
  const ctx = { visited: 0, matches: [], cap: 16 };
@@ -5723,7 +5753,7 @@ async function findWriteTarget(rawPath) {
5723
5753
  const found = await findFile(rawPath);
5724
5754
  if (found) return found;
5725
5755
  const cwd = process.cwd();
5726
- const fallback = path7.isAbsolute(rawPath) ? path7.normalize(rawPath) : path7.resolve(cwd, rawPath);
5756
+ const fallback = path8.isAbsolute(rawPath) ? path8.normalize(rawPath) : path8.resolve(cwd, rawPath);
5727
5757
  if (!isUnder(cwd, fallback)) return null;
5728
5758
  return fallback;
5729
5759
  }
@@ -5763,7 +5793,7 @@ async function writeProjectFile(rawPath, content) {
5763
5793
  if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
5764
5794
  return { error: "Content too large." };
5765
5795
  }
5766
- await fs5.mkdir(path7.dirname(abs), { recursive: true });
5796
+ await fs5.mkdir(path8.dirname(abs), { recursive: true });
5767
5797
  await fs5.writeFile(abs, content, "utf-8");
5768
5798
  return { ok: true };
5769
5799
  } catch (e) {
@@ -5776,7 +5806,7 @@ async function writeProjectFile(rawPath, content) {
5776
5806
  var import_child_process4 = require("child_process");
5777
5807
  var import_util = require("util");
5778
5808
  var fs6 = __toESM(require("fs/promises"));
5779
- var path8 = __toESM(require("path"));
5809
+ var path9 = __toESM(require("path"));
5780
5810
  var execFileP = (0, import_util.promisify)(import_child_process4.execFile);
5781
5811
  var PROJECT_IGNORE = /* @__PURE__ */ new Set([
5782
5812
  "node_modules",
@@ -5834,12 +5864,12 @@ async function listProjectFiles(opts = {}) {
5834
5864
  return;
5835
5865
  }
5836
5866
  if (PROJECT_IGNORE.has(e.name)) continue;
5837
- const full = path8.join(dir, e.name);
5867
+ const full = path9.join(dir, e.name);
5838
5868
  if (e.isDirectory()) {
5839
5869
  if (depth >= 12) continue;
5840
5870
  await walk(full, depth + 1);
5841
5871
  } else if (e.isFile()) {
5842
- const rel = path8.relative(root, full);
5872
+ const rel = path9.relative(root, full);
5843
5873
  if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
5844
5874
  continue;
5845
5875
  }
@@ -5947,7 +5977,7 @@ async function gitStatus(cwd) {
5947
5977
  let hasMergeInProgress = false;
5948
5978
  try {
5949
5979
  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");
5980
+ const mergeHead = path9.isAbsolute(gitDir) ? path9.join(gitDir, "MERGE_HEAD") : path9.join(root, gitDir, "MERGE_HEAD");
5951
5981
  await fs6.access(mergeHead);
5952
5982
  hasMergeInProgress = true;
5953
5983
  } catch {
@@ -6025,7 +6055,7 @@ async function gitResolve(file, side, cwd) {
6025
6055
  function saveFilesTemp(files) {
6026
6056
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
6027
6057
  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}`);
6058
+ const tmpPath = path10.join(os6.tmpdir(), `codeam-${(0, import_crypto.randomUUID)()}-${safeName}`);
6029
6059
  fs7.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
6030
6060
  return tmpPath;
6031
6061
  });
@@ -6099,7 +6129,7 @@ try:
6099
6129
  sys.exit((st>>8)&0xFF)
6100
6130
  except Exception:sys.exit(0)
6101
6131
  `;
6102
- const helperPath = path9.join(os6.tmpdir(), "codeam-quota-helper.py");
6132
+ const helperPath = path10.join(os6.tmpdir(), "codeam-quota-helper.py");
6103
6133
  fs7.writeFileSync(helperPath, helperScript, { mode: 420 });
6104
6134
  const python = findInPath("python3") ?? findInPath("python");
6105
6135
  if (!python) {
@@ -6702,7 +6732,7 @@ async function logout() {
6702
6732
  var import_child_process10 = require("child_process");
6703
6733
  var fs8 = __toESM(require("fs"));
6704
6734
  var os7 = __toESM(require("os"));
6705
- var path14 = __toESM(require("path"));
6735
+ var path15 = __toESM(require("path"));
6706
6736
  var import_util6 = require("util");
6707
6737
  var import_picocolors9 = __toESM(require("picocolors"));
6708
6738
 
@@ -6710,7 +6740,7 @@ var import_picocolors9 = __toESM(require("picocolors"));
6710
6740
  var import_child_process6 = require("child_process");
6711
6741
  var import_util2 = require("util");
6712
6742
  var import_picocolors7 = __toESM(require("picocolors"));
6713
- var path10 = __toESM(require("path"));
6743
+ var path11 = __toESM(require("path"));
6714
6744
  var execFileP2 = (0, import_util2.promisify)(import_child_process6.execFile);
6715
6745
  var MAX_BUFFER = 8 * 1024 * 1024;
6716
6746
  function resetStdinForChild() {
@@ -7199,7 +7229,7 @@ var GitHubCodespacesProvider = class {
7199
7229
  });
7200
7230
  }
7201
7231
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
7202
- const remoteDir = path10.posix.dirname(remotePath);
7232
+ const remoteDir = path11.posix.dirname(remotePath);
7203
7233
  const parts = [
7204
7234
  `mkdir -p ${shellQuote(remoteDir)}`,
7205
7235
  `cat > ${shellQuote(remotePath)}`
@@ -7269,7 +7299,7 @@ function shellQuote(s) {
7269
7299
  // src/services/providers/gitpod.ts
7270
7300
  var import_child_process7 = require("child_process");
7271
7301
  var import_util3 = require("util");
7272
- var path11 = __toESM(require("path"));
7302
+ var path12 = __toESM(require("path"));
7273
7303
  var import_picocolors8 = __toESM(require("picocolors"));
7274
7304
  var execFileP3 = (0, import_util3.promisify)(import_child_process7.execFile);
7275
7305
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -7509,7 +7539,7 @@ var GitpodProvider = class {
7509
7539
  });
7510
7540
  }
7511
7541
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
7512
- const remoteDir = path11.posix.dirname(remotePath);
7542
+ const remoteDir = path12.posix.dirname(remotePath);
7513
7543
  const parts = [
7514
7544
  `mkdir -p ${shellQuote2(remoteDir)}`,
7515
7545
  `cat > ${shellQuote2(remotePath)}`
@@ -7545,7 +7575,7 @@ function shellQuote2(s) {
7545
7575
  // src/services/providers/gitlab-workspaces.ts
7546
7576
  var import_child_process8 = require("child_process");
7547
7577
  var import_util4 = require("util");
7548
- var path12 = __toESM(require("path"));
7578
+ var path13 = __toESM(require("path"));
7549
7579
  var execFileP4 = (0, import_util4.promisify)(import_child_process8.execFile);
7550
7580
  var MAX_BUFFER3 = 8 * 1024 * 1024;
7551
7581
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -7805,7 +7835,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
7805
7835
  }
7806
7836
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
7807
7837
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
7808
- const remoteDir = path12.posix.dirname(remotePath);
7838
+ const remoteDir = path13.posix.dirname(remotePath);
7809
7839
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
7810
7840
  if (options.mode != null) {
7811
7841
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -7873,7 +7903,7 @@ function shellQuote3(s) {
7873
7903
  // src/services/providers/railway.ts
7874
7904
  var import_child_process9 = require("child_process");
7875
7905
  var import_util5 = require("util");
7876
- var path13 = __toESM(require("path"));
7906
+ var path14 = __toESM(require("path"));
7877
7907
  var execFileP5 = (0, import_util5.promisify)(import_child_process9.execFile);
7878
7908
  var MAX_BUFFER4 = 8 * 1024 * 1024;
7879
7909
  function resetStdinForChild4() {
@@ -8109,7 +8139,7 @@ var RailwayProvider = class {
8109
8139
  if (!projectId || !serviceId) {
8110
8140
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
8111
8141
  }
8112
- const remoteDir = path13.posix.dirname(remotePath);
8142
+ const remoteDir = path14.posix.dirname(remotePath);
8113
8143
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
8114
8144
  if (options.mode != null) {
8115
8145
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -8301,7 +8331,7 @@ async function deploy() {
8301
8331
  process.exit(1);
8302
8332
  }
8303
8333
  }
8304
- const localClaudeDir = path14.join(os7.homedir(), ".claude");
8334
+ const localClaudeDir = path15.join(os7.homedir(), ".claude");
8305
8335
  const localCredsKind = await detectLocalClaudeCredentials(localClaudeDir);
8306
8336
  let bridged = "none";
8307
8337
  if (localCredsKind !== "none") {
@@ -8399,7 +8429,7 @@ async function deploy() {
8399
8429
  }
8400
8430
  }
8401
8431
  if (bridged !== "none") {
8402
- const localClaudeJson = path14.join(os7.homedir(), ".claude.json");
8432
+ const localClaudeJson = path15.join(os7.homedir(), ".claude.json");
8403
8433
  if (fs8.existsSync(localClaudeJson)) {
8404
8434
  try {
8405
8435
  const contents = fs8.readFileSync(localClaudeJson);
@@ -8592,7 +8622,7 @@ async function runRemoteClaudeLogin(provider, workspaceId) {
8592
8622
  }
8593
8623
  }
8594
8624
  async function detectLocalClaudeCredentials(localClaudeDir) {
8595
- if (fs8.existsSync(path14.join(localClaudeDir, ".credentials.json"))) {
8625
+ if (fs8.existsSync(path15.join(localClaudeDir, ".credentials.json"))) {
8596
8626
  return "flat-file";
8597
8627
  }
8598
8628
  if (process.platform === "darwin") {
@@ -8625,7 +8655,7 @@ async function verifyClaudeAuth(provider, workspaceId) {
8625
8655
  }
8626
8656
  }
8627
8657
  async function bridgeClaudeCredentials(provider, workspaceId, localClaudeDir) {
8628
- const fileBased = path14.join(localClaudeDir, ".credentials.json");
8658
+ const fileBased = path15.join(localClaudeDir, ".credentials.json");
8629
8659
  if (fs8.existsSync(fileBased)) return "flat-file";
8630
8660
  if (process.platform === "darwin") {
8631
8661
  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.32",
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": {