codeam-cli 2.39.39 → 2.39.40

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.39.39] — 2026-06-19
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Gate preview tunnel on cloudflared 'Registered tunnel connection', not a host DNS probe
12
+
7
13
  ## [2.39.38] — 2026-06-19
8
14
 
9
15
  ### Added
package/dist/index.js CHANGED
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
498
498
  // package.json
499
499
  var package_default = {
500
500
  name: "codeam-cli",
501
- version: "2.39.39",
501
+ version: "2.39.40",
502
502
  description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
503
503
  type: "commonjs",
504
504
  main: "dist/index.js",
@@ -5908,7 +5908,7 @@ function readAnonId() {
5908
5908
  }
5909
5909
  function superProperties() {
5910
5910
  return {
5911
- cliVersion: true ? "2.39.39" : "0.0.0-dev",
5911
+ cliVersion: true ? "2.39.40" : "0.0.0-dev",
5912
5912
  nodeVersion: process.version,
5913
5913
  platform: process.platform,
5914
5914
  arch: process.arch,
@@ -15259,7 +15259,7 @@ var fs35 = __toESM(require("fs"));
15259
15259
  var os28 = __toESM(require("os"));
15260
15260
  var path42 = __toESM(require("path"));
15261
15261
  var import_crypto3 = require("crypto");
15262
- var import_child_process18 = require("child_process");
15262
+ var import_child_process19 = require("child_process");
15263
15263
 
15264
15264
  // src/lib/payload.ts
15265
15265
  var import_zod = require("zod");
@@ -16464,6 +16464,7 @@ async function linkDryRunPreflight(ctx) {
16464
16464
  }
16465
16465
 
16466
16466
  // src/services/preview/cloudflared.ts
16467
+ var import_child_process11 = require("child_process");
16467
16468
  var import_fs = require("fs");
16468
16469
  var import_promises = __toESM(require("fs/promises"));
16469
16470
  var import_os6 = __toESM(require("os"));
@@ -16516,11 +16517,38 @@ function downloadUrlForPlatform() {
16516
16517
  `cloudflared auto-install not supported on ${platform3}/${arch2}. Install manually from https://github.com/cloudflare/cloudflared/releases.`
16517
16518
  );
16518
16519
  }
16520
+ function decodeTunnelToken(token) {
16521
+ const decoded = JSON.parse(Buffer.from(token, "base64").toString("utf8"));
16522
+ if (!decoded.a || !decoded.t || !decoded.s) {
16523
+ throw new Error("cloudflared token missing accountTag/tunnelID/tunnelSecret");
16524
+ }
16525
+ return { AccountTag: decoded.a, TunnelID: decoded.t, TunnelSecret: decoded.s };
16526
+ }
16527
+ async function spawnNamedTunnel(bin, token, port) {
16528
+ const creds = decodeTunnelToken(token);
16529
+ const credDir = import_path4.default.join(import_os6.default.homedir(), ".codeam");
16530
+ await import_promises.default.mkdir(credDir, { recursive: true });
16531
+ const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
16532
+ await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
16533
+ return (0, import_child_process11.spawn)(
16534
+ bin,
16535
+ [
16536
+ "tunnel",
16537
+ "run",
16538
+ "--credentials-file",
16539
+ credFile,
16540
+ "--url",
16541
+ `http://localhost:${port}`,
16542
+ creds.TunnelID
16543
+ ],
16544
+ { stdio: ["ignore", "pipe", "pipe"] }
16545
+ );
16546
+ }
16519
16547
 
16520
16548
  // src/services/preview/codespace.ts
16521
- var import_child_process11 = require("child_process");
16549
+ var import_child_process12 = require("child_process");
16522
16550
  var import_util3 = require("util");
16523
- var execFileP4 = (0, import_util3.promisify)(import_child_process11.execFile);
16551
+ var execFileP4 = (0, import_util3.promisify)(import_child_process12.execFile);
16524
16552
 
16525
16553
  // src/services/preview/config-file.ts
16526
16554
  var import_promises3 = __toESM(require("fs/promises"));
@@ -16674,10 +16702,10 @@ var import_fs2 = require("fs");
16674
16702
  var import_path6 = __toESM(require("path"));
16675
16703
 
16676
16704
  // src/services/preview/run-setup.ts
16677
- var import_child_process12 = require("child_process");
16705
+ var import_child_process13 = require("child_process");
16678
16706
  function runSetupCommand(cmd, args2, cwd, env, opts) {
16679
16707
  return new Promise((resolve7) => {
16680
- const child = (0, import_child_process12.spawn)(cmd, args2, {
16708
+ const child = (0, import_child_process13.spawn)(cmd, args2, {
16681
16709
  cwd,
16682
16710
  env: { ...process.env, ...env ?? {} },
16683
16711
  stdio: ["ignore", "pipe", "pipe"]
@@ -16974,7 +17002,7 @@ function activePreviewSessionIds() {
16974
17002
  }
16975
17003
 
16976
17004
  // src/beads/bd-adapter.ts
16977
- var import_child_process13 = require("child_process");
17005
+ var import_child_process14 = require("child_process");
16978
17006
  var fs31 = __toESM(require("fs"));
16979
17007
  var os25 = __toESM(require("os"));
16980
17008
  var path37 = __toESM(require("path"));
@@ -17028,7 +17056,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
17028
17056
  return new Promise((resolve7) => {
17029
17057
  let proc;
17030
17058
  try {
17031
- proc = (0, import_child_process13.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
17059
+ proc = (0, import_child_process14.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
17032
17060
  } catch (err) {
17033
17061
  resolve7({ code: -1, stdout: "", stderr: err.message });
17034
17062
  return;
@@ -17182,13 +17210,13 @@ function coerceIssue(row, projectKey) {
17182
17210
  }
17183
17211
 
17184
17212
  // src/beads/provisioner.ts
17185
- var import_child_process17 = require("child_process");
17213
+ var import_child_process18 = require("child_process");
17186
17214
  var fs34 = __toESM(require("fs"));
17187
17215
  var os27 = __toESM(require("os"));
17188
17216
  var path40 = __toESM(require("path"));
17189
17217
 
17190
17218
  // src/beads/install-bd.ts
17191
- var import_child_process14 = require("child_process");
17219
+ var import_child_process15 = require("child_process");
17192
17220
  var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
17193
17221
  var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
17194
17222
  function resolveInstallStrategy(platform3) {
@@ -17219,7 +17247,7 @@ function _defaultInstallSpawn(strategy) {
17219
17247
  return new Promise((resolve7) => {
17220
17248
  let proc;
17221
17249
  try {
17222
- proc = (0, import_child_process14.spawn)(strategy.command, strategy.args, { env: process.env });
17250
+ proc = (0, import_child_process15.spawn)(strategy.command, strategy.args, { env: process.env });
17223
17251
  } catch (err) {
17224
17252
  resolve7({ ok: false, code: -1, stderr: err.message });
17225
17253
  return;
@@ -17249,7 +17277,7 @@ async function installBd(platform3 = process.platform) {
17249
17277
  }
17250
17278
 
17251
17279
  // src/beads/install-dolt.ts
17252
- var import_child_process15 = require("child_process");
17280
+ var import_child_process16 = require("child_process");
17253
17281
  var fs32 = __toESM(require("fs"));
17254
17282
  var os26 = __toESM(require("os"));
17255
17283
  var path38 = __toESM(require("path"));
@@ -17411,7 +17439,7 @@ function _defaultDoltInstallSpawn(strategy) {
17411
17439
  };
17412
17440
  let proc;
17413
17441
  try {
17414
- proc = (0, import_child_process15.spawn)(strategy.command, strategy.args, {
17442
+ proc = (0, import_child_process16.spawn)(strategy.command, strategy.args, {
17415
17443
  env: process.env,
17416
17444
  stdio: ["ignore", "pipe", "pipe"]
17417
17445
  });
@@ -17484,7 +17512,7 @@ async function ensureSharedServer(adapter) {
17484
17512
  }
17485
17513
 
17486
17514
  // src/beads/project-key.ts
17487
- var import_child_process16 = require("child_process");
17515
+ var import_child_process17 = require("child_process");
17488
17516
  var crypto2 = __toESM(require("crypto"));
17489
17517
  var fs33 = __toESM(require("fs"));
17490
17518
  var path39 = __toESM(require("path"));
@@ -17531,7 +17559,7 @@ function findRepoRoot(cwd) {
17531
17559
  }
17532
17560
  var _execSeam2 = {
17533
17561
  exec: (file, args2, opts) => {
17534
- const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
17562
+ const out2 = (0, import_child_process17.execFileSync)(file, args2, opts);
17535
17563
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
17536
17564
  },
17537
17565
  realpath: (p2) => fs33.realpathSync(p2)
@@ -17691,7 +17719,7 @@ function linkBdOntoPath(binaryPath) {
17691
17719
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
17692
17720
  }
17693
17721
  function setGitBeadsRole() {
17694
- (0, import_child_process17.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
17722
+ (0, import_child_process18.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
17695
17723
  stdio: "ignore"
17696
17724
  });
17697
17725
  }
@@ -18377,7 +18405,7 @@ var sessionTerminated = async (ctx, cmd) => {
18377
18405
  } catch {
18378
18406
  }
18379
18407
  try {
18380
- const proc = (0, import_child_process18.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18408
+ const proc = (0, import_child_process19.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18381
18409
  detached: true,
18382
18410
  stdio: "ignore"
18383
18411
  });
@@ -18399,7 +18427,7 @@ var shutdownSession = async (ctx, cmd) => {
18399
18427
  }
18400
18428
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
18401
18429
  try {
18402
- const stopProc = (0, import_child_process18.spawn)(
18430
+ const stopProc = (0, import_child_process19.spawn)(
18403
18431
  "bash",
18404
18432
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
18405
18433
  { detached: true, stdio: "ignore" }
@@ -18409,7 +18437,7 @@ var shutdownSession = async (ctx, cmd) => {
18409
18437
  }
18410
18438
  }
18411
18439
  try {
18412
- const proc = (0, import_child_process18.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18440
+ const proc = (0, import_child_process19.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18413
18441
  detached: true,
18414
18442
  stdio: "ignore"
18415
18443
  });
@@ -19014,7 +19042,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
19014
19042
  "BOOT_SEQUENCE",
19015
19043
  `${spawnable.command} ${spawnable.args.join(" ")}`
19016
19044
  );
19017
- const devServer = (0, import_child_process18.spawn)(spawnable.command, spawnable.args, {
19045
+ const devServer = (0, import_child_process19.spawn)(spawnable.command, spawnable.args, {
19018
19046
  cwd: process.cwd(),
19019
19047
  env: { ...process.env, ...spawnable.env ?? {} },
19020
19048
  stdio: ["ignore", "pipe", "pipe"]
@@ -19117,6 +19145,47 @@ var previewStartH = (ctx, _cmd, parsed) => {
19117
19145
  const MAX_TUNNEL_ATTEMPTS = 3;
19118
19146
  let parsedUrl = null;
19119
19147
  let lastTunnelErr = "cloudflared did not emit a URL within 45s";
19148
+ const namedToken = process.env.PREVIEW_TUNNEL_TOKEN;
19149
+ const namedHostname = process.env.PREVIEW_TUNNEL_HOSTNAME;
19150
+ if (namedToken && namedHostname) {
19151
+ try {
19152
+ emitProgress("TUNNEL_STARTING", `named tunnel ${namedHostname}`);
19153
+ const candidate = await spawnNamedTunnel(bin, namedToken, detection.port);
19154
+ let registered = false;
19155
+ const onNamedChunk = (chunk) => {
19156
+ const s = chunk.toString();
19157
+ if (/Registered tunnel connection/i.test(s)) registered = true;
19158
+ const trimmed = s.replace(/\n+$/g, "");
19159
+ if (trimmed.length > 0) log.info("preview", `cloudflared: ${trimmed}`);
19160
+ };
19161
+ candidate.stderr.on("data", onNamedChunk);
19162
+ candidate.stdout.on("data", onNamedChunk);
19163
+ const namedDeadline = Date.now() + 45e3;
19164
+ while (!registered && Date.now() < namedDeadline) {
19165
+ await new Promise((r) => setTimeout(r, 250));
19166
+ }
19167
+ if (registered) {
19168
+ const namedUrl = `https://${namedHostname}`;
19169
+ log.info("preview", `named tunnel registered: ${namedUrl}`);
19170
+ tunnel = candidate;
19171
+ parsedUrl = namedUrl;
19172
+ } else {
19173
+ log.info(
19174
+ "preview",
19175
+ "named tunnel did not register within 45s \u2014 falling back to quick tunnel"
19176
+ );
19177
+ try {
19178
+ candidate.kill("SIGTERM");
19179
+ } catch {
19180
+ }
19181
+ }
19182
+ } catch (e) {
19183
+ log.info(
19184
+ "preview",
19185
+ `named tunnel failed (${e.message}) \u2014 falling back to quick tunnel`
19186
+ );
19187
+ }
19188
+ }
19120
19189
  for (let attempt = 1; attempt <= MAX_TUNNEL_ATTEMPTS && !parsedUrl; attempt += 1) {
19121
19190
  if (attempt > 1) {
19122
19191
  emitProgress(
@@ -19124,7 +19193,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
19124
19193
  `cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
19125
19194
  );
19126
19195
  }
19127
- const candidate = (0, import_child_process18.spawn)(
19196
+ const candidate = (0, import_child_process19.spawn)(
19128
19197
  bin,
19129
19198
  ["tunnel", "--url", `http://localhost:${detection.port}`],
19130
19199
  { stdio: ["ignore", "pipe", "pipe"] }
@@ -19291,7 +19360,7 @@ async function dispatchCommand(ctx, cmd) {
19291
19360
  }
19292
19361
 
19293
19362
  // src/services/file-watcher.service.ts
19294
- var import_child_process19 = require("child_process");
19363
+ var import_child_process20 = require("child_process");
19295
19364
  var fs36 = __toESM(require("fs"));
19296
19365
  var os29 = __toESM(require("os"));
19297
19366
  var path43 = __toESM(require("path"));
@@ -20057,7 +20126,7 @@ async function _runGitImpl(cwd, args2, opts = {}) {
20057
20126
  return new Promise((resolve7) => {
20058
20127
  let proc;
20059
20128
  try {
20060
- proc = (0, import_child_process19.spawn)("git", args2, { cwd, env: process.env });
20129
+ proc = (0, import_child_process20.spawn)("git", args2, { cwd, env: process.env });
20061
20130
  } catch {
20062
20131
  resolve7(null);
20063
20132
  return;
@@ -20089,7 +20158,7 @@ function _runGit(cwd, args2, opts = {}) {
20089
20158
  var import_crypto4 = require("crypto");
20090
20159
 
20091
20160
  // src/services/turn-files/git-changeset.ts
20092
- var import_child_process20 = require("child_process");
20161
+ var import_child_process21 = require("child_process");
20093
20162
  var path44 = __toESM(require("path"));
20094
20163
  async function collectRepoChangeset(opts) {
20095
20164
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
@@ -20173,7 +20242,7 @@ function defaultRunGit(cwd, args2) {
20173
20242
  return new Promise((resolve7) => {
20174
20243
  let proc;
20175
20244
  try {
20176
- proc = (0, import_child_process20.spawn)("git", args2, { cwd, env: process.env });
20245
+ proc = (0, import_child_process21.spawn)("git", args2, { cwd, env: process.env });
20177
20246
  } catch {
20178
20247
  resolve7(null);
20179
20248
  return;
@@ -23182,13 +23251,13 @@ function fetchQuotaUsage(runtime, historySvc) {
23182
23251
  }
23183
23252
 
23184
23253
  // src/commands/start/keep-alive.ts
23185
- var import_child_process21 = require("child_process");
23254
+ var import_child_process22 = require("child_process");
23186
23255
  function buildKeepAlive(ctx) {
23187
23256
  let timer = null;
23188
23257
  async function setIdleTimeout(minutes) {
23189
23258
  if (!ctx.inCodespace || !ctx.codespaceName) return;
23190
23259
  await new Promise((resolve7) => {
23191
- const proc = (0, import_child_process21.spawn)(
23260
+ const proc = (0, import_child_process22.spawn)(
23192
23261
  "gh",
23193
23262
  [
23194
23263
  "api",
@@ -24255,11 +24324,11 @@ async function logout() {
24255
24324
  var import_picocolors10 = __toESM(require("picocolors"));
24256
24325
 
24257
24326
  // src/services/providers/github-codespaces.ts
24258
- var import_child_process22 = require("child_process");
24327
+ var import_child_process23 = require("child_process");
24259
24328
  var import_util4 = require("util");
24260
24329
  var import_picocolors8 = __toESM(require("picocolors"));
24261
24330
  var path49 = __toESM(require("path"));
24262
- var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
24331
+ var execFileP5 = (0, import_util4.promisify)(import_child_process23.execFile);
24263
24332
  var MAX_BUFFER = 8 * 1024 * 1024;
24264
24333
  function resetStdinForChild() {
24265
24334
  if (process.stdin.isTTY) {
@@ -24303,7 +24372,7 @@ var GitHubCodespacesProvider = class {
24303
24372
  if (!isAuthed) {
24304
24373
  resetStdinForChild();
24305
24374
  await new Promise((resolve7, reject) => {
24306
- const proc = (0, import_child_process22.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
24375
+ const proc = (0, import_child_process23.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
24307
24376
  stdio: "inherit"
24308
24377
  });
24309
24378
  proc.on("exit", (code) => {
@@ -24337,7 +24406,7 @@ var GitHubCodespacesProvider = class {
24337
24406
  wt(noteLines.join("\n"), "One more permission needed");
24338
24407
  resetStdinForChild();
24339
24408
  const refreshCode = await new Promise((resolve7, reject) => {
24340
- const proc = (0, import_child_process22.spawn)(
24409
+ const proc = (0, import_child_process23.spawn)(
24341
24410
  "gh",
24342
24411
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
24343
24412
  { stdio: "inherit" }
@@ -24487,7 +24556,7 @@ var GitHubCodespacesProvider = class {
24487
24556
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
24488
24557
  resetStdinForChild();
24489
24558
  const ok = await new Promise((resolve7) => {
24490
- const proc = (0, import_child_process22.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
24559
+ const proc = (0, import_child_process23.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
24491
24560
  proc.on("exit", (code) => resolve7(code === 0));
24492
24561
  proc.on("error", () => resolve7(false));
24493
24562
  });
@@ -24514,7 +24583,7 @@ var GitHubCodespacesProvider = class {
24514
24583
  );
24515
24584
  resetStdinForChild();
24516
24585
  await new Promise((resolve7, reject) => {
24517
- const proc = (0, import_child_process22.spawn)(
24586
+ const proc = (0, import_child_process23.spawn)(
24518
24587
  "gh",
24519
24588
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
24520
24589
  { stdio: "inherit" }
@@ -24692,7 +24761,7 @@ var GitHubCodespacesProvider = class {
24692
24761
  async streamCommand(workspaceId, command2) {
24693
24762
  resetStdinForChild();
24694
24763
  return new Promise((resolve7, reject) => {
24695
- const proc = (0, import_child_process22.spawn)(
24764
+ const proc = (0, import_child_process23.spawn)(
24696
24765
  "gh",
24697
24766
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
24698
24767
  { stdio: "inherit" }
@@ -24719,11 +24788,11 @@ var GitHubCodespacesProvider = class {
24719
24788
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
24720
24789
  ];
24721
24790
  await new Promise((resolve7, reject) => {
24722
- const tar = (0, import_child_process22.spawn)("tar", tarArgs, {
24791
+ const tar = (0, import_child_process23.spawn)("tar", tarArgs, {
24723
24792
  stdio: ["ignore", "pipe", "pipe"],
24724
24793
  env: tarEnv
24725
24794
  });
24726
- const ssh = (0, import_child_process22.spawn)("gh", sshArgs, {
24795
+ const ssh = (0, import_child_process23.spawn)("gh", sshArgs, {
24727
24796
  stdio: [tar.stdout, "pipe", "pipe"]
24728
24797
  });
24729
24798
  let tarErr = "";
@@ -24757,7 +24826,7 @@ var GitHubCodespacesProvider = class {
24757
24826
  }
24758
24827
  const cmd = parts.join(" && ");
24759
24828
  await new Promise((resolve7, reject) => {
24760
- const proc = (0, import_child_process22.spawn)(
24829
+ const proc = (0, import_child_process23.spawn)(
24761
24830
  "gh",
24762
24831
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
24763
24832
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -24815,11 +24884,11 @@ function shellQuote(s) {
24815
24884
  }
24816
24885
 
24817
24886
  // src/services/providers/gitpod.ts
24818
- var import_child_process23 = require("child_process");
24887
+ var import_child_process24 = require("child_process");
24819
24888
  var import_util5 = require("util");
24820
24889
  var path50 = __toESM(require("path"));
24821
24890
  var import_picocolors9 = __toESM(require("picocolors"));
24822
- var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
24891
+ var execFileP6 = (0, import_util5.promisify)(import_child_process24.execFile);
24823
24892
  var MAX_BUFFER2 = 8 * 1024 * 1024;
24824
24893
  function resetStdinForChild2() {
24825
24894
  if (process.stdin.isTTY) {
@@ -24859,7 +24928,7 @@ var GitpodProvider = class {
24859
24928
  );
24860
24929
  resetStdinForChild2();
24861
24930
  await new Promise((resolve7, reject) => {
24862
- const proc = (0, import_child_process23.spawn)("gitpod", ["login"], { stdio: "inherit" });
24931
+ const proc = (0, import_child_process24.spawn)("gitpod", ["login"], { stdio: "inherit" });
24863
24932
  proc.on("exit", (code) => {
24864
24933
  if (code === 0) resolve7();
24865
24934
  else reject(new Error("gitpod login failed."));
@@ -25011,7 +25080,7 @@ var GitpodProvider = class {
25011
25080
  async streamCommand(workspaceId, command2) {
25012
25081
  resetStdinForChild2();
25013
25082
  return new Promise((resolve7, reject) => {
25014
- const proc = (0, import_child_process23.spawn)(
25083
+ const proc = (0, import_child_process24.spawn)(
25015
25084
  "gitpod",
25016
25085
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
25017
25086
  { stdio: "inherit" }
@@ -25031,11 +25100,11 @@ var GitpodProvider = class {
25031
25100
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
25032
25101
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
25033
25102
  await new Promise((resolve7, reject) => {
25034
- const tar = (0, import_child_process23.spawn)("tar", tarArgs, {
25103
+ const tar = (0, import_child_process24.spawn)("tar", tarArgs, {
25035
25104
  stdio: ["ignore", "pipe", "pipe"],
25036
25105
  env: tarEnv
25037
25106
  });
25038
- const ssh = (0, import_child_process23.spawn)(
25107
+ const ssh = (0, import_child_process24.spawn)(
25039
25108
  "gitpod",
25040
25109
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
25041
25110
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -25067,7 +25136,7 @@ var GitpodProvider = class {
25067
25136
  }
25068
25137
  const cmd = parts.join(" && ");
25069
25138
  await new Promise((resolve7, reject) => {
25070
- const proc = (0, import_child_process23.spawn)(
25139
+ const proc = (0, import_child_process24.spawn)(
25071
25140
  "gitpod",
25072
25141
  ["workspace", "ssh", workspaceId, "--", cmd],
25073
25142
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -25091,10 +25160,10 @@ function shellQuote2(s) {
25091
25160
  }
25092
25161
 
25093
25162
  // src/services/providers/gitlab-workspaces.ts
25094
- var import_child_process24 = require("child_process");
25163
+ var import_child_process25 = require("child_process");
25095
25164
  var import_util6 = require("util");
25096
25165
  var path51 = __toESM(require("path"));
25097
- var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
25166
+ var execFileP7 = (0, import_util6.promisify)(import_child_process25.execFile);
25098
25167
  var MAX_BUFFER3 = 8 * 1024 * 1024;
25099
25168
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
25100
25169
  function resetStdinForChild3() {
@@ -25136,7 +25205,7 @@ var GitLabWorkspacesProvider = class {
25136
25205
  );
25137
25206
  resetStdinForChild3();
25138
25207
  await new Promise((resolve7, reject) => {
25139
- const proc = (0, import_child_process24.spawn)(
25208
+ const proc = (0, import_child_process25.spawn)(
25140
25209
  "glab",
25141
25210
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
25142
25211
  { stdio: "inherit" }
@@ -25308,7 +25377,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25308
25377
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
25309
25378
  resetStdinForChild3();
25310
25379
  return new Promise((resolve7, reject) => {
25311
- const proc = (0, import_child_process24.spawn)(
25380
+ const proc = (0, import_child_process25.spawn)(
25312
25381
  "ssh",
25313
25382
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
25314
25383
  { stdio: "inherit" }
@@ -25329,8 +25398,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25329
25398
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
25330
25399
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
25331
25400
  await new Promise((resolve7, reject) => {
25332
- const tar = (0, import_child_process24.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25333
- const ssh = (0, import_child_process24.spawn)(
25401
+ const tar = (0, import_child_process25.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25402
+ const ssh = (0, import_child_process25.spawn)(
25334
25403
  "ssh",
25335
25404
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
25336
25405
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -25360,7 +25429,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25360
25429
  }
25361
25430
  const cmd = parts.join(" && ");
25362
25431
  await new Promise((resolve7, reject) => {
25363
- const proc = (0, import_child_process24.spawn)(
25432
+ const proc = (0, import_child_process25.spawn)(
25364
25433
  "ssh",
25365
25434
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
25366
25435
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -25419,10 +25488,10 @@ function shellQuote3(s) {
25419
25488
  }
25420
25489
 
25421
25490
  // src/services/providers/railway.ts
25422
- var import_child_process25 = require("child_process");
25491
+ var import_child_process26 = require("child_process");
25423
25492
  var import_util7 = require("util");
25424
25493
  var path52 = __toESM(require("path"));
25425
- var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
25494
+ var execFileP8 = (0, import_util7.promisify)(import_child_process26.execFile);
25426
25495
  var MAX_BUFFER4 = 8 * 1024 * 1024;
25427
25496
  function resetStdinForChild4() {
25428
25497
  if (process.stdin.isTTY) {
@@ -25463,7 +25532,7 @@ var RailwayProvider = class {
25463
25532
  );
25464
25533
  resetStdinForChild4();
25465
25534
  await new Promise((resolve7, reject) => {
25466
- const proc = (0, import_child_process25.spawn)("railway", ["login"], { stdio: "inherit" });
25535
+ const proc = (0, import_child_process26.spawn)("railway", ["login"], { stdio: "inherit" });
25467
25536
  proc.on("exit", (code) => {
25468
25537
  if (code === 0) resolve7();
25469
25538
  else reject(new Error("railway login failed."));
@@ -25606,7 +25675,7 @@ var RailwayProvider = class {
25606
25675
  }
25607
25676
  resetStdinForChild4();
25608
25677
  return new Promise((resolve7, reject) => {
25609
- const proc = (0, import_child_process25.spawn)(
25678
+ const proc = (0, import_child_process26.spawn)(
25610
25679
  "railway",
25611
25680
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
25612
25681
  { stdio: "inherit" }
@@ -25630,8 +25699,8 @@ var RailwayProvider = class {
25630
25699
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
25631
25700
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
25632
25701
  await new Promise((resolve7, reject) => {
25633
- const tar = (0, import_child_process25.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25634
- const sh = (0, import_child_process25.spawn)(
25702
+ const tar = (0, import_child_process26.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25703
+ const sh = (0, import_child_process26.spawn)(
25635
25704
  "railway",
25636
25705
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
25637
25706
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -25664,7 +25733,7 @@ var RailwayProvider = class {
25664
25733
  }
25665
25734
  const cmd = parts.join(" && ");
25666
25735
  await new Promise((resolve7, reject) => {
25667
- const proc = (0, import_child_process25.spawn)(
25736
+ const proc = (0, import_child_process26.spawn)(
25668
25737
  "railway",
25669
25738
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
25670
25739
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -26839,6 +26908,10 @@ var HostAgentSupervisor = class {
26839
26908
  }
26840
26909
  const home = process.env.HOME || os36.homedir();
26841
26910
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
26911
+ if (payload.previewTunnelToken && payload.previewHostname) {
26912
+ childEnv.PREVIEW_TUNNEL_TOKEN = payload.previewTunnelToken;
26913
+ childEnv.PREVIEW_TUNNEL_HOSTNAME = payload.previewHostname;
26914
+ }
26842
26915
  report("spawning", "starting agent");
26843
26916
  const proc = this.spawnChild(childEnv, cwd, extraArgs);
26844
26917
  const child = { deployId: payload.deployId, proc };
@@ -27167,7 +27240,7 @@ function checkChokidar() {
27167
27240
  }
27168
27241
  async function doctor(args2 = []) {
27169
27242
  const json = args2.includes("--json");
27170
- const cliVersion = true ? "2.39.39" : "0.0.0-dev";
27243
+ const cliVersion = true ? "2.39.40" : "0.0.0-dev";
27171
27244
  const apiBase2 = resolveApiBaseUrl();
27172
27245
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
27173
27246
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -27366,7 +27439,7 @@ async function completion(args2) {
27366
27439
  // src/commands/version.ts
27367
27440
  var import_picocolors13 = __toESM(require("picocolors"));
27368
27441
  function version2() {
27369
- const v = true ? "2.39.39" : "unknown";
27442
+ const v = true ? "2.39.40" : "unknown";
27370
27443
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
27371
27444
  }
27372
27445
 
@@ -27652,7 +27725,7 @@ function checkForUpdates() {
27652
27725
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
27653
27726
  if (process.env.CI) return;
27654
27727
  if (!process.stdout.isTTY) return;
27655
- const current = true ? "2.39.39" : null;
27728
+ const current = true ? "2.39.40" : null;
27656
27729
  if (!current) return;
27657
27730
  const cache = readCache();
27658
27731
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.39.39",
3
+ "version": "2.39.40",
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",