codeam-cli 2.15.1 → 2.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to `codeam-cli` are documented here.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [2.15.1] — 2026-05-17
8
+
9
+ ### Fixed
10
+
11
+ - **jetbrains-plugin:** Import terminalopsservice in controllertoolwindowfactory
12
+ - **cli:** Lazy-load node-pty + vendor darwin prebuilds (cli was crashing on mac)
13
+
7
14
  ## [2.14.0] — 2026-05-17
8
15
 
9
16
  ### Added
package/dist/index.js CHANGED
@@ -386,7 +386,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
386
386
  // package.json
387
387
  var package_default = {
388
388
  name: "codeam-cli",
389
- version: "2.15.1",
389
+ version: "2.15.2",
390
390
  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.",
391
391
  type: "commonjs",
392
392
  main: "dist/index.js",
@@ -6187,7 +6187,7 @@ var fs14 = __toESM(require("fs"));
6187
6187
  var os13 = __toESM(require("os"));
6188
6188
  var path18 = __toESM(require("path"));
6189
6189
  var import_crypto2 = require("crypto");
6190
- var import_child_process8 = require("child_process");
6190
+ var import_child_process9 = require("child_process");
6191
6191
 
6192
6192
  // src/lib/payload.ts
6193
6193
  var import_zod2 = require("zod");
@@ -6735,6 +6735,7 @@ async function jsSearchFiles(opts, cwd, cap) {
6735
6735
  }
6736
6736
 
6737
6737
  // src/services/terminal-ops.service.ts
6738
+ var import_child_process8 = require("child_process");
6738
6739
  var import_crypto = require("crypto");
6739
6740
  var import_path = __toESM(require("path"));
6740
6741
  var MAX_CONCURRENT_SESSIONS = 4;
@@ -6768,6 +6769,135 @@ function defaultShell() {
6768
6769
  }
6769
6770
  return process.env.SHELL ?? "/bin/bash";
6770
6771
  }
6772
+ var PYTHON_TERMINAL_HELPER = `import os,pty,sys,select,signal,struct,fcntl,termios,errno,re
6773
+ m,s=pty.openpty()
6774
+ try:
6775
+ cols=int(os.environ.get('COLUMNS','80'))
6776
+ rows=int(os.environ.get('LINES','24'))
6777
+ fcntl.ioctl(s,termios.TIOCSWINSZ,struct.pack('HHHH',rows,cols,0,0))
6778
+ except Exception:pass
6779
+ pid=os.fork()
6780
+ if pid==0:
6781
+ os.close(m)
6782
+ os.setsid()
6783
+ try:fcntl.ioctl(s,termios.TIOCSCTTY,0)
6784
+ except Exception:pass
6785
+ for fd in[0,1,2]:os.dup2(s,fd)
6786
+ if s>2:os.close(s)
6787
+ os.execvp(sys.argv[1],sys.argv[1:])
6788
+ sys.exit(127)
6789
+ os.close(s)
6790
+ done=[False]
6791
+ def onchld(n,f):
6792
+ try:os.waitpid(pid,os.WNOHANG)
6793
+ except Exception:pass
6794
+ done[0]=True
6795
+ signal.signal(signal.SIGCHLD,onchld)
6796
+ signal.signal(signal.SIGHUP,signal.SIG_IGN)
6797
+ i=sys.stdin.fileno()
6798
+ o=sys.stdout.fileno()
6799
+ in_buf=b''
6800
+ resize_re=re.compile(rb'\\x00CW (\\d+) (\\d+)\\n')
6801
+ while not done[0]:
6802
+ try:r,_,_=select.select([i,m],[],[],0.1)
6803
+ except OSError as e:
6804
+ if e.errno==errno.EINTR:continue
6805
+ break
6806
+ if i in r:
6807
+ try:
6808
+ d=os.read(i,4096)
6809
+ if not d:break
6810
+ in_buf+=d
6811
+ while True:
6812
+ mo=resize_re.search(in_buf)
6813
+ if not mo:break
6814
+ try:
6815
+ rows=int(mo.group(1));cols=int(mo.group(2))
6816
+ fcntl.ioctl(m,termios.TIOCSWINSZ,struct.pack('HHHH',rows,cols,0,0))
6817
+ except Exception:pass
6818
+ in_buf=in_buf[:mo.start()]+in_buf[mo.end():]
6819
+ if in_buf:
6820
+ # Don't forward a dangling NUL that might be the
6821
+ # start of an incomplete resize marker \u2014 hold it
6822
+ # until the next read so the regex matches.
6823
+ nul=in_buf.rfind(b'\\x00')
6824
+ if nul>=0 and len(in_buf)-nul<32:
6825
+ tail=in_buf[nul:];body=in_buf[:nul]
6826
+ if body:os.write(m,body)
6827
+ in_buf=tail
6828
+ else:
6829
+ os.write(m,in_buf);in_buf=b''
6830
+ except OSError:break
6831
+ if m in r:
6832
+ try:
6833
+ d=os.read(m,4096)
6834
+ if d:os.write(o,d)
6835
+ except OSError:done[0]=True
6836
+ try:os.kill(pid,signal.SIGTERM)
6837
+ except Exception:pass
6838
+ try:
6839
+ _,st=os.waitpid(pid,0)
6840
+ sys.exit((st>>8)&0xFF)
6841
+ except Exception:sys.exit(0)
6842
+ `;
6843
+ function findPython3() {
6844
+ for (const name of ["python3", "python"]) {
6845
+ try {
6846
+ const out = require("child_process").spawnSync("which", [name], { encoding: "utf8" });
6847
+ if (out.status === 0 && out.stdout?.trim()) return out.stdout.trim();
6848
+ } catch {
6849
+ }
6850
+ }
6851
+ return null;
6852
+ }
6853
+ function createPythonSession(id, shell, cwd, env, cols, rows) {
6854
+ const python = findPython3();
6855
+ if (!python) {
6856
+ return { error: "python3 not found on PATH \u2014 required for terminal sessions on Linux/macOS without node-pty." };
6857
+ }
6858
+ let child;
6859
+ try {
6860
+ child = (0, import_child_process8.spawn)(python, ["-c", PYTHON_TERMINAL_HELPER, shell], {
6861
+ cwd,
6862
+ env: { ...env, COLUMNS: String(cols), LINES: String(rows) },
6863
+ stdio: ["pipe", "pipe", "pipe"]
6864
+ });
6865
+ } catch (e) {
6866
+ return { error: e instanceof Error ? e.message : "python spawn failed" };
6867
+ }
6868
+ child.stdout.on("data", (buf) => {
6869
+ onDataHandler?.({ sessionId: id, data: buf.toString("utf8") });
6870
+ });
6871
+ child.stderr.on("data", (buf) => {
6872
+ onDataHandler?.({ sessionId: id, data: buf.toString("utf8") });
6873
+ });
6874
+ child.on("exit", (code) => {
6875
+ onExitHandler?.({ sessionId: id, exitCode: code ?? 0 });
6876
+ sessions.delete(id);
6877
+ });
6878
+ return {
6879
+ id,
6880
+ write(data) {
6881
+ try {
6882
+ child.stdin.write(data);
6883
+ } catch {
6884
+ }
6885
+ },
6886
+ resize(cs, rs) {
6887
+ try {
6888
+ child.stdin.write(`\0CW ${rs} ${cs}
6889
+ `);
6890
+ } catch {
6891
+ }
6892
+ },
6893
+ kill() {
6894
+ try {
6895
+ child.kill("SIGTERM");
6896
+ } catch {
6897
+ }
6898
+ }
6899
+ };
6900
+ }
6771
6901
  function openTerminal(opts) {
6772
6902
  if (sessions.size >= MAX_CONCURRENT_SESSIONS) {
6773
6903
  return { error: `Too many open terminals (max ${MAX_CONCURRENT_SESSIONS})` };
@@ -6777,46 +6907,61 @@ function openTerminal(opts) {
6777
6907
  const env = {
6778
6908
  ...process.env,
6779
6909
  TERM: "xterm-256color",
6780
- COLORTERM: "truecolor"
6910
+ COLORTERM: "truecolor",
6911
+ FORCE_COLOR: "1"
6781
6912
  };
6782
- env.FORCE_COLOR = "1";
6913
+ const cols = Math.max(1, Math.min(opts.cols ?? 80, 500));
6914
+ const rows = Math.max(1, Math.min(opts.rows ?? 24, 200));
6915
+ const id = (0, import_crypto.randomUUID)();
6783
6916
  const ptyMod = loadNodePty2();
6784
- if (!ptyMod) {
6917
+ if (ptyMod) {
6918
+ try {
6919
+ const term = ptyMod.spawn(shell, [], {
6920
+ name: "xterm-256color",
6921
+ cols,
6922
+ rows,
6923
+ cwd,
6924
+ env,
6925
+ useConpty: process.platform === "win32" ? true : void 0
6926
+ });
6927
+ const dataListener = term.onData((data) => {
6928
+ onDataHandler?.({ sessionId: id, data });
6929
+ });
6930
+ const exitListener = term.onExit(({ exitCode }) => {
6931
+ onExitHandler?.({ sessionId: id, exitCode });
6932
+ sessions.delete(id);
6933
+ });
6934
+ sessions.set(id, {
6935
+ id,
6936
+ write: (d3) => term.write(d3),
6937
+ resize: (cs, rs) => term.resize(cs, rs),
6938
+ kill: () => {
6939
+ dataListener.dispose();
6940
+ exitListener.dispose();
6941
+ term.kill();
6942
+ }
6943
+ });
6944
+ return { sessionId: id };
6945
+ } catch (e) {
6946
+ if (process.platform === "win32") {
6947
+ return { error: e instanceof Error ? e.message : "spawn failed" };
6948
+ }
6949
+ }
6950
+ } else if (process.platform === "win32") {
6785
6951
  return {
6786
6952
  error: `node-pty native module unavailable on ${process.platform}-${process.arch}; terminal feature disabled for this platform`
6787
6953
  };
6788
6954
  }
6789
- try {
6790
- const term = ptyMod.spawn(shell, [], {
6791
- name: "xterm-256color",
6792
- cols: Math.max(1, Math.min(opts.cols ?? 80, 500)),
6793
- rows: Math.max(1, Math.min(opts.rows ?? 24, 200)),
6794
- cwd,
6795
- env,
6796
- // Windows-specific: ConPTY is the default on Win 10 1809+
6797
- // and is what we want. node-pty falls back to winpty
6798
- // automatically on older builds.
6799
- useConpty: process.platform === "win32" ? true : void 0
6800
- });
6801
- const id = (0, import_crypto.randomUUID)();
6802
- const dataListener = term.onData((data) => {
6803
- onDataHandler?.({ sessionId: id, data });
6804
- });
6805
- const exitListener = term.onExit(({ exitCode }) => {
6806
- onExitHandler?.({ sessionId: id, exitCode });
6807
- sessions.delete(id);
6808
- });
6809
- sessions.set(id, { id, pty: term, dataListener, exitListener });
6810
- return { sessionId: id };
6811
- } catch (e) {
6812
- return { error: e instanceof Error ? e.message : "spawn failed" };
6813
- }
6955
+ const sess = createPythonSession(id, shell, cwd, env, cols, rows);
6956
+ if ("error" in sess) return { error: sess.error };
6957
+ sessions.set(id, sess);
6958
+ return { sessionId: id };
6814
6959
  }
6815
6960
  function writeTerminal(sessionId, data) {
6816
6961
  const s = sessions.get(sessionId);
6817
6962
  if (!s) return { ok: false, error: "No such session" };
6818
6963
  try {
6819
- s.pty.write(data);
6964
+ s.write(data);
6820
6965
  return { ok: true };
6821
6966
  } catch (e) {
6822
6967
  return { ok: false, error: e instanceof Error ? e.message : "write failed" };
@@ -6826,7 +6971,7 @@ function resizeTerminal(sessionId, cols, rows) {
6826
6971
  const s = sessions.get(sessionId);
6827
6972
  if (!s) return { ok: false, error: "No such session" };
6828
6973
  try {
6829
- s.pty.resize(Math.max(1, Math.min(cols, 500)), Math.max(1, Math.min(rows, 200)));
6974
+ s.resize?.(Math.max(1, Math.min(cols, 500)), Math.max(1, Math.min(rows, 200)));
6830
6975
  return { ok: true };
6831
6976
  } catch (e) {
6832
6977
  return { ok: false, error: e instanceof Error ? e.message : "resize failed" };
@@ -6836,9 +6981,7 @@ function closeTerminal(sessionId) {
6836
6981
  const s = sessions.get(sessionId);
6837
6982
  if (!s) return { ok: true };
6838
6983
  try {
6839
- s.dataListener.dispose();
6840
- s.exitListener.dispose();
6841
- s.pty.kill();
6984
+ s.kill();
6842
6985
  } catch {
6843
6986
  }
6844
6987
  sessions.delete(sessionId);
@@ -6981,7 +7124,7 @@ var sessionTerminated = (ctx) => {
6981
7124
  } catch {
6982
7125
  }
6983
7126
  try {
6984
- const proc = (0, import_child_process8.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
7127
+ const proc = (0, import_child_process9.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
6985
7128
  detached: true,
6986
7129
  stdio: "ignore"
6987
7130
  });
@@ -7003,7 +7146,7 @@ var shutdownSession = async (ctx, cmd) => {
7003
7146
  }
7004
7147
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
7005
7148
  try {
7006
- const stopProc = (0, import_child_process8.spawn)(
7149
+ const stopProc = (0, import_child_process9.spawn)(
7007
7150
  "bash",
7008
7151
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
7009
7152
  { detached: true, stdio: "ignore" }
@@ -7013,7 +7156,7 @@ var shutdownSession = async (ctx, cmd) => {
7013
7156
  }
7014
7157
  }
7015
7158
  try {
7016
- const proc = (0, import_child_process8.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
7159
+ const proc = (0, import_child_process9.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
7017
7160
  detached: true,
7018
7161
  stdio: "ignore"
7019
7162
  });
@@ -7593,11 +7736,11 @@ async function logout() {
7593
7736
  var import_picocolors9 = __toESM(require("picocolors"));
7594
7737
 
7595
7738
  // src/services/providers/github-codespaces.ts
7596
- var import_child_process9 = require("child_process");
7739
+ var import_child_process10 = require("child_process");
7597
7740
  var import_util3 = require("util");
7598
7741
  var import_picocolors7 = __toESM(require("picocolors"));
7599
7742
  var path19 = __toESM(require("path"));
7600
- var execFileP3 = (0, import_util3.promisify)(import_child_process9.execFile);
7743
+ var execFileP3 = (0, import_util3.promisify)(import_child_process10.execFile);
7601
7744
  var MAX_BUFFER = 8 * 1024 * 1024;
7602
7745
  function resetStdinForChild() {
7603
7746
  if (process.stdin.isTTY) {
@@ -7641,7 +7784,7 @@ var GitHubCodespacesProvider = class {
7641
7784
  if (!isAuthed) {
7642
7785
  resetStdinForChild();
7643
7786
  await new Promise((resolve2, reject) => {
7644
- const proc = (0, import_child_process9.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
7787
+ const proc = (0, import_child_process10.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
7645
7788
  stdio: "inherit"
7646
7789
  });
7647
7790
  proc.on("exit", (code) => {
@@ -7675,7 +7818,7 @@ var GitHubCodespacesProvider = class {
7675
7818
  wt(noteLines.join("\n"), "One more permission needed");
7676
7819
  resetStdinForChild();
7677
7820
  const refreshCode = await new Promise((resolve2, reject) => {
7678
- const proc = (0, import_child_process9.spawn)(
7821
+ const proc = (0, import_child_process10.spawn)(
7679
7822
  "gh",
7680
7823
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
7681
7824
  { stdio: "inherit" }
@@ -7825,7 +7968,7 @@ var GitHubCodespacesProvider = class {
7825
7968
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
7826
7969
  resetStdinForChild();
7827
7970
  const ok = await new Promise((resolve2) => {
7828
- const proc = (0, import_child_process9.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
7971
+ const proc = (0, import_child_process10.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
7829
7972
  proc.on("exit", (code) => resolve2(code === 0));
7830
7973
  proc.on("error", () => resolve2(false));
7831
7974
  });
@@ -7852,7 +7995,7 @@ var GitHubCodespacesProvider = class {
7852
7995
  );
7853
7996
  resetStdinForChild();
7854
7997
  await new Promise((resolve2, reject) => {
7855
- const proc = (0, import_child_process9.spawn)(
7998
+ const proc = (0, import_child_process10.spawn)(
7856
7999
  "gh",
7857
8000
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
7858
8001
  { stdio: "inherit" }
@@ -8030,7 +8173,7 @@ var GitHubCodespacesProvider = class {
8030
8173
  async streamCommand(workspaceId, command2) {
8031
8174
  resetStdinForChild();
8032
8175
  return new Promise((resolve2, reject) => {
8033
- const proc = (0, import_child_process9.spawn)(
8176
+ const proc = (0, import_child_process10.spawn)(
8034
8177
  "gh",
8035
8178
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
8036
8179
  { stdio: "inherit" }
@@ -8057,11 +8200,11 @@ var GitHubCodespacesProvider = class {
8057
8200
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
8058
8201
  ];
8059
8202
  await new Promise((resolve2, reject) => {
8060
- const tar = (0, import_child_process9.spawn)("tar", tarArgs, {
8203
+ const tar = (0, import_child_process10.spawn)("tar", tarArgs, {
8061
8204
  stdio: ["ignore", "pipe", "pipe"],
8062
8205
  env: tarEnv
8063
8206
  });
8064
- const ssh = (0, import_child_process9.spawn)("gh", sshArgs, {
8207
+ const ssh = (0, import_child_process10.spawn)("gh", sshArgs, {
8065
8208
  stdio: [tar.stdout, "pipe", "pipe"]
8066
8209
  });
8067
8210
  let tarErr = "";
@@ -8095,7 +8238,7 @@ var GitHubCodespacesProvider = class {
8095
8238
  }
8096
8239
  const cmd = parts.join(" && ");
8097
8240
  await new Promise((resolve2, reject) => {
8098
- const proc = (0, import_child_process9.spawn)(
8241
+ const proc = (0, import_child_process10.spawn)(
8099
8242
  "gh",
8100
8243
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
8101
8244
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -8153,11 +8296,11 @@ function shellQuote(s) {
8153
8296
  }
8154
8297
 
8155
8298
  // src/services/providers/gitpod.ts
8156
- var import_child_process10 = require("child_process");
8299
+ var import_child_process11 = require("child_process");
8157
8300
  var import_util4 = require("util");
8158
8301
  var path20 = __toESM(require("path"));
8159
8302
  var import_picocolors8 = __toESM(require("picocolors"));
8160
- var execFileP4 = (0, import_util4.promisify)(import_child_process10.execFile);
8303
+ var execFileP4 = (0, import_util4.promisify)(import_child_process11.execFile);
8161
8304
  var MAX_BUFFER2 = 8 * 1024 * 1024;
8162
8305
  function resetStdinForChild2() {
8163
8306
  if (process.stdin.isTTY) {
@@ -8197,7 +8340,7 @@ var GitpodProvider = class {
8197
8340
  );
8198
8341
  resetStdinForChild2();
8199
8342
  await new Promise((resolve2, reject) => {
8200
- const proc = (0, import_child_process10.spawn)("gitpod", ["login"], { stdio: "inherit" });
8343
+ const proc = (0, import_child_process11.spawn)("gitpod", ["login"], { stdio: "inherit" });
8201
8344
  proc.on("exit", (code) => {
8202
8345
  if (code === 0) resolve2();
8203
8346
  else reject(new Error("gitpod login failed."));
@@ -8349,7 +8492,7 @@ var GitpodProvider = class {
8349
8492
  async streamCommand(workspaceId, command2) {
8350
8493
  resetStdinForChild2();
8351
8494
  return new Promise((resolve2, reject) => {
8352
- const proc = (0, import_child_process10.spawn)(
8495
+ const proc = (0, import_child_process11.spawn)(
8353
8496
  "gitpod",
8354
8497
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
8355
8498
  { stdio: "inherit" }
@@ -8369,11 +8512,11 @@ var GitpodProvider = class {
8369
8512
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
8370
8513
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
8371
8514
  await new Promise((resolve2, reject) => {
8372
- const tar = (0, import_child_process10.spawn)("tar", tarArgs, {
8515
+ const tar = (0, import_child_process11.spawn)("tar", tarArgs, {
8373
8516
  stdio: ["ignore", "pipe", "pipe"],
8374
8517
  env: tarEnv
8375
8518
  });
8376
- const ssh = (0, import_child_process10.spawn)(
8519
+ const ssh = (0, import_child_process11.spawn)(
8377
8520
  "gitpod",
8378
8521
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
8379
8522
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -8405,7 +8548,7 @@ var GitpodProvider = class {
8405
8548
  }
8406
8549
  const cmd = parts.join(" && ");
8407
8550
  await new Promise((resolve2, reject) => {
8408
- const proc = (0, import_child_process10.spawn)(
8551
+ const proc = (0, import_child_process11.spawn)(
8409
8552
  "gitpod",
8410
8553
  ["workspace", "ssh", workspaceId, "--", cmd],
8411
8554
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -8429,10 +8572,10 @@ function shellQuote2(s) {
8429
8572
  }
8430
8573
 
8431
8574
  // src/services/providers/gitlab-workspaces.ts
8432
- var import_child_process11 = require("child_process");
8575
+ var import_child_process12 = require("child_process");
8433
8576
  var import_util5 = require("util");
8434
8577
  var path21 = __toESM(require("path"));
8435
- var execFileP5 = (0, import_util5.promisify)(import_child_process11.execFile);
8578
+ var execFileP5 = (0, import_util5.promisify)(import_child_process12.execFile);
8436
8579
  var MAX_BUFFER3 = 8 * 1024 * 1024;
8437
8580
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
8438
8581
  function resetStdinForChild3() {
@@ -8474,7 +8617,7 @@ var GitLabWorkspacesProvider = class {
8474
8617
  );
8475
8618
  resetStdinForChild3();
8476
8619
  await new Promise((resolve2, reject) => {
8477
- const proc = (0, import_child_process11.spawn)(
8620
+ const proc = (0, import_child_process12.spawn)(
8478
8621
  "glab",
8479
8622
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
8480
8623
  { stdio: "inherit" }
@@ -8646,7 +8789,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
8646
8789
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
8647
8790
  resetStdinForChild3();
8648
8791
  return new Promise((resolve2, reject) => {
8649
- const proc = (0, import_child_process11.spawn)(
8792
+ const proc = (0, import_child_process12.spawn)(
8650
8793
  "ssh",
8651
8794
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
8652
8795
  { stdio: "inherit" }
@@ -8667,8 +8810,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
8667
8810
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
8668
8811
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
8669
8812
  await new Promise((resolve2, reject) => {
8670
- const tar = (0, import_child_process11.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
8671
- const ssh = (0, import_child_process11.spawn)(
8813
+ const tar = (0, import_child_process12.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
8814
+ const ssh = (0, import_child_process12.spawn)(
8672
8815
  "ssh",
8673
8816
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
8674
8817
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -8698,7 +8841,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
8698
8841
  }
8699
8842
  const cmd = parts.join(" && ");
8700
8843
  await new Promise((resolve2, reject) => {
8701
- const proc = (0, import_child_process11.spawn)(
8844
+ const proc = (0, import_child_process12.spawn)(
8702
8845
  "ssh",
8703
8846
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
8704
8847
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -8757,10 +8900,10 @@ function shellQuote3(s) {
8757
8900
  }
8758
8901
 
8759
8902
  // src/services/providers/railway.ts
8760
- var import_child_process12 = require("child_process");
8903
+ var import_child_process13 = require("child_process");
8761
8904
  var import_util6 = require("util");
8762
8905
  var path22 = __toESM(require("path"));
8763
- var execFileP6 = (0, import_util6.promisify)(import_child_process12.execFile);
8906
+ var execFileP6 = (0, import_util6.promisify)(import_child_process13.execFile);
8764
8907
  var MAX_BUFFER4 = 8 * 1024 * 1024;
8765
8908
  function resetStdinForChild4() {
8766
8909
  if (process.stdin.isTTY) {
@@ -8801,7 +8944,7 @@ var RailwayProvider = class {
8801
8944
  );
8802
8945
  resetStdinForChild4();
8803
8946
  await new Promise((resolve2, reject) => {
8804
- const proc = (0, import_child_process12.spawn)("railway", ["login"], { stdio: "inherit" });
8947
+ const proc = (0, import_child_process13.spawn)("railway", ["login"], { stdio: "inherit" });
8805
8948
  proc.on("exit", (code) => {
8806
8949
  if (code === 0) resolve2();
8807
8950
  else reject(new Error("railway login failed."));
@@ -8944,7 +9087,7 @@ var RailwayProvider = class {
8944
9087
  }
8945
9088
  resetStdinForChild4();
8946
9089
  return new Promise((resolve2, reject) => {
8947
- const proc = (0, import_child_process12.spawn)(
9090
+ const proc = (0, import_child_process13.spawn)(
8948
9091
  "railway",
8949
9092
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
8950
9093
  { stdio: "inherit" }
@@ -8968,8 +9111,8 @@ var RailwayProvider = class {
8968
9111
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
8969
9112
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
8970
9113
  await new Promise((resolve2, reject) => {
8971
- const tar = (0, import_child_process12.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
8972
- const sh = (0, import_child_process12.spawn)(
9114
+ const tar = (0, import_child_process13.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
9115
+ const sh = (0, import_child_process13.spawn)(
8973
9116
  "railway",
8974
9117
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
8975
9118
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -9002,7 +9145,7 @@ var RailwayProvider = class {
9002
9145
  }
9003
9146
  const cmd = parts.join(" && ");
9004
9147
  await new Promise((resolve2, reject) => {
9005
- const proc = (0, import_child_process12.spawn)(
9148
+ const proc = (0, import_child_process13.spawn)(
9006
9149
  "railway",
9007
9150
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
9008
9151
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -9537,7 +9680,7 @@ async function stopWorkspaceFromLocal(target) {
9537
9680
  // src/commands/version.ts
9538
9681
  var import_picocolors11 = __toESM(require("picocolors"));
9539
9682
  function version() {
9540
- const v = true ? "2.15.1" : "unknown";
9683
+ const v = true ? "2.15.2" : "unknown";
9541
9684
  console.log(`${import_picocolors11.default.bold("codeam-cli")} ${import_picocolors11.default.cyan(v)}`);
9542
9685
  }
9543
9686
 
@@ -9676,7 +9819,7 @@ function checkForUpdates() {
9676
9819
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
9677
9820
  if (process.env.CI) return;
9678
9821
  if (!process.stdout.isTTY) return;
9679
- const current = true ? "2.15.1" : null;
9822
+ const current = true ? "2.15.2" : null;
9680
9823
  if (!current) return;
9681
9824
  const cache = readCache();
9682
9825
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.15.1",
3
+ "version": "2.15.2",
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
  "type": "commonjs",
6
6
  "main": "dist/index.js",