codeam-cli 2.60.70 → 2.61.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/index.js +112 -92
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,35 @@ 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.61.0] — 2026-07-15
8
+
9
+ ### Added
10
+
11
+ - **cli:** Dynamic host label at enroll (hostname / CODEAM_HOST_LABEL) instead of my-server
12
+
13
+ ## [2.60.70] — 2026-07-15
14
+
15
+ ### Added
16
+
17
+ - **cli:** Fleet control plane — DockerRunner + fleet_* box handlers
18
+ - **box:** Production codeam-box rescue-fleet runtime image
19
+
20
+ ### Chore
21
+
22
+ - **meta:** Register box/test commitlint scopes for the fleet work
23
+
24
+ ### Documentation
25
+
26
+ - **fleet:** CLAUDE.md fleet CLI section
27
+
28
+ ### Fixed
29
+
30
+ - **cli:** Deliver fleet box enroll token via env passthrough, not docker argv
31
+
32
+ ### Tests
33
+
34
+ - **test:** Real-Docker integration gate for the fleet control plane
35
+
7
36
  ## [2.60.69] — 2026-07-15
8
37
 
9
38
  ### Fixed
package/dist/index.js CHANGED
@@ -5970,7 +5970,7 @@ function readAnonId() {
5970
5970
  }
5971
5971
  function superProperties() {
5972
5972
  return {
5973
- cliVersion: true ? "2.60.70" : "0.0.0-dev",
5973
+ cliVersion: true ? "2.61.1" : "0.0.0-dev",
5974
5974
  nodeVersion: process.version,
5975
5975
  platform: process.platform,
5976
5976
  arch: process.arch,
@@ -6151,7 +6151,7 @@ var os4 = __toESM(require("os"));
6151
6151
  // package.json
6152
6152
  var package_default = {
6153
6153
  name: "codeam-cli",
6154
- version: "2.60.70",
6154
+ version: "2.61.1",
6155
6155
  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.",
6156
6156
  type: "commonjs",
6157
6157
  main: "dist/index.js",
@@ -7294,7 +7294,7 @@ var CommandRelayService = class _CommandRelayService {
7294
7294
  // fresh + clear the "CLI update available" banner after a self-update
7295
7295
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
7296
7296
  // pair/reconnect). Older backends ignore the extra field.
7297
- ..."2.60.70" ? { ideVersion: "2.60.70" } : {}
7297
+ ..."2.61.1" ? { ideVersion: "2.61.1" } : {}
7298
7298
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
7299
7299
  }
7300
7300
  /**
@@ -8672,7 +8672,7 @@ var fs55 = __toESM(require("fs"));
8672
8672
  var os44 = __toESM(require("os"));
8673
8673
  var path59 = __toESM(require("path"));
8674
8674
  var import_crypto3 = require("crypto");
8675
- var import_child_process23 = require("child_process");
8675
+ var import_child_process24 = require("child_process");
8676
8676
 
8677
8677
  // src/lib/payload.ts
8678
8678
  var import_zod = require("zod");
@@ -16494,10 +16494,16 @@ async function postJson(pathname, body) {
16494
16494
  }
16495
16495
  return json.data;
16496
16496
  }
16497
+ function resolveHostLabel(label) {
16498
+ const explicit = label?.trim();
16499
+ const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
16500
+ const resolved = explicit || envLabel || os30.hostname();
16501
+ return resolved.slice(0, 80);
16502
+ }
16497
16503
  async function redeemEnrollToken(token, label) {
16498
16504
  const data = await postJson("/api/self-hosted/redeem", {
16499
16505
  token,
16500
- ...label ? { label } : {},
16506
+ label: resolveHostLabel(label),
16501
16507
  osInfo: collectOsInfo()
16502
16508
  });
16503
16509
  return {
@@ -17871,7 +17877,7 @@ async function autoUpgradeBeforeCriticalCommand() {
17871
17877
  if (process.env.NODE_ENV === "test") return;
17872
17878
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17873
17879
  if (process.env.CI) return;
17874
- const current = true ? "2.60.70" : null;
17880
+ const current = true ? "2.61.1" : null;
17875
17881
  if (!current) return;
17876
17882
  const cache = readCache();
17877
17883
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17888,7 +17894,7 @@ function checkForUpdates() {
17888
17894
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17889
17895
  if (process.env.CI) return;
17890
17896
  if (!process.stdout.isTTY) return;
17891
- const current = true ? "2.60.70" : null;
17897
+ const current = true ? "2.61.1" : null;
17892
17898
  if (!current) return;
17893
17899
  const cache = readCache();
17894
17900
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17908,7 +17914,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
17908
17914
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
17909
17915
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
17910
17916
  function currentCliVersion() {
17911
- return true ? "2.60.70" : null;
17917
+ return true ? "2.61.1" : null;
17912
17918
  }
17913
17919
  function runCmd(cmd, args2, timeoutMs) {
17914
17920
  return new Promise((resolve7) => {
@@ -18581,6 +18587,12 @@ var HostAgentSupervisor = class {
18581
18587
  "CODEAM_ENROLL_TOKEN",
18582
18588
  "-e",
18583
18589
  `CODEAM_API_URL=${payload.apiOrigin}`,
18590
+ // User-facing label for the rescued box's "My Servers" card. Not a
18591
+ // secret → plain `-e KEY=value`. The box's host-agent reads it at
18592
+ // redeem (resolveHostLabel) so a rescued user sees "CodeAgent Box",
18593
+ // not the generic "my-server" or the ugly container cuid.
18594
+ "-e",
18595
+ "CODEAM_HOST_LABEL=CodeAgent Box",
18584
18596
  resolveFleetBoxImage()
18585
18597
  ];
18586
18598
  const res = await this.docker.run(args2, {
@@ -19172,6 +19184,7 @@ function makeRealApplyBudgetDeps() {
19172
19184
  var fs44 = __toESM(require("fs"));
19173
19185
  var os38 = __toESM(require("os"));
19174
19186
  var path47 = __toESM(require("path"));
19187
+ var import_child_process14 = require("child_process");
19175
19188
  function registryPath() {
19176
19189
  return path47.join(os38.homedir(), ".codeam", "preview-ports.json");
19177
19190
  }
@@ -19208,15 +19221,34 @@ function forgetPreviewPort(port) {
19208
19221
  writeRegistry(reg);
19209
19222
  }
19210
19223
  function groupAlive(pgid) {
19224
+ const probe = process.platform === "win32" ? pgid : -pgid;
19211
19225
  try {
19212
- process.kill(-pgid, 0);
19226
+ process.kill(probe, 0);
19213
19227
  return true;
19214
19228
  } catch (err) {
19215
19229
  return err.code === "EPERM";
19216
19230
  }
19217
19231
  }
19232
+ function killGroup(pgid) {
19233
+ if (process.platform === "win32") {
19234
+ (0, import_child_process14.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pgid)], { stdio: "ignore" });
19235
+ return;
19236
+ }
19237
+ try {
19238
+ process.kill(-pgid, "SIGTERM");
19239
+ } catch {
19240
+ }
19241
+ try {
19242
+ setTimeout(() => {
19243
+ try {
19244
+ process.kill(-pgid, "SIGKILL");
19245
+ } catch {
19246
+ }
19247
+ }, 300).unref?.();
19248
+ } catch {
19249
+ }
19250
+ }
19218
19251
  function reclaimOwnOrphanPort(port) {
19219
- if (process.platform === "win32") return false;
19220
19252
  const reg = readRegistry();
19221
19253
  const owner = reg[String(port)];
19222
19254
  if (!owner) return false;
@@ -19229,26 +19261,14 @@ function reclaimOwnOrphanPort(port) {
19229
19261
  "preview",
19230
19262
  `reclaiming OWN orphaned preview on port ${port} (pgid=${owner.pgid}, session=${owner.sessionId}) after a CLI restart`
19231
19263
  );
19232
- try {
19233
- process.kill(-owner.pgid, "SIGTERM");
19234
- } catch {
19235
- }
19236
- try {
19237
- setTimeout(() => {
19238
- try {
19239
- process.kill(-owner.pgid, "SIGKILL");
19240
- } catch {
19241
- }
19242
- }, 300).unref?.();
19243
- } catch {
19244
- }
19264
+ killGroup(owner.pgid);
19245
19265
  delete reg[String(port)];
19246
19266
  writeRegistry(reg);
19247
19267
  return true;
19248
19268
  }
19249
19269
 
19250
19270
  // src/services/preview/cloudflared.ts
19251
- var import_child_process14 = require("child_process");
19271
+ var import_child_process15 = require("child_process");
19252
19272
  var import_fs = require("fs");
19253
19273
  var import_promises = __toESM(require("fs/promises"));
19254
19274
  var import_os8 = __toESM(require("os"));
@@ -19325,7 +19345,7 @@ async function isExecutableBinary(p2) {
19325
19345
  }
19326
19346
  function extractTgz(tgzPath, destDir) {
19327
19347
  return new Promise((resolve7, reject) => {
19328
- const child = (0, import_child_process14.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
19348
+ const child = (0, import_child_process15.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
19329
19349
  child.on("error", (err) => reject(err));
19330
19350
  child.on(
19331
19351
  "exit",
@@ -19359,7 +19379,7 @@ async function spawnNamedTunnel(bin, token, port) {
19359
19379
  await import_promises.default.mkdir(credDir, { recursive: true });
19360
19380
  const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
19361
19381
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
19362
- return (0, import_child_process14.spawn)(
19382
+ return (0, import_child_process15.spawn)(
19363
19383
  bin,
19364
19384
  [
19365
19385
  "tunnel",
@@ -19375,9 +19395,9 @@ async function spawnNamedTunnel(bin, token, port) {
19375
19395
  }
19376
19396
 
19377
19397
  // src/services/preview/codespace.ts
19378
- var import_child_process15 = require("child_process");
19398
+ var import_child_process16 = require("child_process");
19379
19399
  var import_util3 = require("util");
19380
- var execFileP5 = (0, import_util3.promisify)(import_child_process15.execFile);
19400
+ var execFileP5 = (0, import_util3.promisify)(import_child_process16.execFile);
19381
19401
 
19382
19402
  // src/services/preview/config-file.ts
19383
19403
  var import_promises3 = __toESM(require("fs/promises"));
@@ -19572,10 +19592,10 @@ var import_fs2 = require("fs");
19572
19592
  var import_path6 = __toESM(require("path"));
19573
19593
 
19574
19594
  // src/services/preview/run-setup.ts
19575
- var import_child_process16 = require("child_process");
19595
+ var import_child_process17 = require("child_process");
19576
19596
  function runSetupCommand(cmd, args2, cwd, env, opts) {
19577
19597
  return new Promise((resolve7) => {
19578
- const child = (0, import_child_process16.spawn)(cmd, args2, {
19598
+ const child = (0, import_child_process17.spawn)(cmd, args2, {
19579
19599
  cwd,
19580
19600
  env: { ...process.env, ...env ?? {} },
19581
19601
  stdio: ["ignore", "pipe", "pipe"]
@@ -19836,8 +19856,8 @@ function isJsInstallCommand(cmd, args2) {
19836
19856
 
19837
19857
  // src/services/preview/tunnel-bringup.ts
19838
19858
  var TUNNEL_REGISTERED_RE = /Registered tunnel connection/i;
19839
- async function awaitTunnelRegistered(candidate, hostname3, deadlineMs) {
19840
- let url = hostname3 ? `https://${hostname3}` : null;
19859
+ async function awaitTunnelRegistered(candidate, hostname4, deadlineMs) {
19860
+ let url = hostname4 ? `https://${hostname4}` : null;
19841
19861
  let registered = false;
19842
19862
  if (candidate.exitCode != null) {
19843
19863
  return { kind: "exited", sawUrl: url != null, code: candidate.exitCode };
@@ -19918,7 +19938,7 @@ function activePreviewSessionIds() {
19918
19938
  }
19919
19939
 
19920
19940
  // src/services/preview/start-orchestrator.ts
19921
- var import_child_process17 = require("child_process");
19941
+ var import_child_process18 = require("child_process");
19922
19942
  var fs49 = __toESM(require("fs"));
19923
19943
  var path52 = __toESM(require("path"));
19924
19944
  var import_which2 = __toESM(require("which"));
@@ -20195,7 +20215,7 @@ async function startDevServer(ctx) {
20195
20215
  }
20196
20216
  const spawnable = normalizeDetectionForSpawn(detection, cwd);
20197
20217
  emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
20198
- const devServer = (0, import_child_process17.spawn)(spawnable.command, spawnable.args, {
20218
+ const devServer = (0, import_child_process18.spawn)(spawnable.command, spawnable.args, {
20199
20219
  cwd,
20200
20220
  env: { ...process.env, ...spawnable.env ?? {} },
20201
20221
  stdio: ["ignore", "pipe", "pipe"],
@@ -20320,7 +20340,7 @@ async function establishTunnel(ctx, dev) {
20320
20340
  `cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
20321
20341
  );
20322
20342
  }
20323
- const candidate = (0, import_child_process17.spawn)(
20343
+ const candidate = (0, import_child_process18.spawn)(
20324
20344
  bin,
20325
20345
  ["tunnel", "--url", `http://localhost:${detection.port}`],
20326
20346
  { stdio: ["ignore", "pipe", "pipe"] }
@@ -20351,7 +20371,7 @@ async function establishTunnel(ctx, dev) {
20351
20371
  }
20352
20372
 
20353
20373
  // src/beads/bd-adapter.ts
20354
- var import_child_process18 = require("child_process");
20374
+ var import_child_process19 = require("child_process");
20355
20375
  var fs50 = __toESM(require("fs"));
20356
20376
  var os40 = __toESM(require("os"));
20357
20377
  var path53 = __toESM(require("path"));
@@ -20405,7 +20425,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
20405
20425
  return new Promise((resolve7) => {
20406
20426
  let proc;
20407
20427
  try {
20408
- proc = (0, import_child_process18.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
20428
+ proc = (0, import_child_process19.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
20409
20429
  } catch (err) {
20410
20430
  resolve7({ code: -1, stdout: "", stderr: err.message });
20411
20431
  return;
@@ -20562,13 +20582,13 @@ function coerceIssue(row, projectKey) {
20562
20582
  }
20563
20583
 
20564
20584
  // src/beads/provisioner.ts
20565
- var import_child_process22 = require("child_process");
20585
+ var import_child_process23 = require("child_process");
20566
20586
  var fs53 = __toESM(require("fs"));
20567
20587
  var os42 = __toESM(require("os"));
20568
20588
  var path56 = __toESM(require("path"));
20569
20589
 
20570
20590
  // src/beads/install-bd.ts
20571
- var import_child_process19 = require("child_process");
20591
+ var import_child_process20 = require("child_process");
20572
20592
  var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
20573
20593
  var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
20574
20594
  function resolveInstallStrategy(platform3) {
@@ -20599,7 +20619,7 @@ function _defaultInstallSpawn(strategy) {
20599
20619
  return new Promise((resolve7) => {
20600
20620
  let proc;
20601
20621
  try {
20602
- proc = (0, import_child_process19.spawn)(strategy.command, strategy.args, { env: process.env });
20622
+ proc = (0, import_child_process20.spawn)(strategy.command, strategy.args, { env: process.env });
20603
20623
  } catch (err) {
20604
20624
  resolve7({ ok: false, code: -1, stderr: err.message });
20605
20625
  return;
@@ -20629,7 +20649,7 @@ async function installBd(platform3 = process.platform) {
20629
20649
  }
20630
20650
 
20631
20651
  // src/beads/install-dolt.ts
20632
- var import_child_process20 = require("child_process");
20652
+ var import_child_process21 = require("child_process");
20633
20653
  var fs51 = __toESM(require("fs"));
20634
20654
  var os41 = __toESM(require("os"));
20635
20655
  var path54 = __toESM(require("path"));
@@ -20791,7 +20811,7 @@ function _defaultDoltInstallSpawn(strategy) {
20791
20811
  };
20792
20812
  let proc;
20793
20813
  try {
20794
- proc = (0, import_child_process20.spawn)(strategy.command, strategy.args, {
20814
+ proc = (0, import_child_process21.spawn)(strategy.command, strategy.args, {
20795
20815
  env: process.env,
20796
20816
  stdio: ["ignore", "pipe", "pipe"]
20797
20817
  });
@@ -20889,7 +20909,7 @@ async function ensureSharedServer(adapter, options = {}) {
20889
20909
  }
20890
20910
 
20891
20911
  // src/beads/project-key.ts
20892
- var import_child_process21 = require("child_process");
20912
+ var import_child_process22 = require("child_process");
20893
20913
  var crypto2 = __toESM(require("crypto"));
20894
20914
  var fs52 = __toESM(require("fs"));
20895
20915
  var path55 = __toESM(require("path"));
@@ -20936,7 +20956,7 @@ function findRepoRoot(cwd) {
20936
20956
  }
20937
20957
  var _execSeam2 = {
20938
20958
  exec: (file, args2, opts) => {
20939
- const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
20959
+ const out2 = (0, import_child_process22.execFileSync)(file, args2, opts);
20940
20960
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
20941
20961
  },
20942
20962
  realpath: (p2) => fs52.realpathSync(p2)
@@ -21099,7 +21119,7 @@ function linkBdOntoPath(binaryPath) {
21099
21119
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
21100
21120
  }
21101
21121
  function setGitBeadsRole() {
21102
- (0, import_child_process22.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
21122
+ (0, import_child_process23.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
21103
21123
  stdio: "ignore"
21104
21124
  });
21105
21125
  }
@@ -21866,7 +21886,7 @@ var sessionTerminated = async (ctx, cmd) => {
21866
21886
  }
21867
21887
  quiet(() => ctx.agent.kill());
21868
21888
  try {
21869
- const proc = (0, import_child_process23.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
21889
+ const proc = (0, import_child_process24.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
21870
21890
  detached: true,
21871
21891
  stdio: "ignore"
21872
21892
  });
@@ -21885,7 +21905,7 @@ var shutdownSession = async (ctx, cmd) => {
21885
21905
  quiet(() => ctx.agent.kill());
21886
21906
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
21887
21907
  try {
21888
- const stopProc = (0, import_child_process23.spawn)(
21908
+ const stopProc = (0, import_child_process24.spawn)(
21889
21909
  "bash",
21890
21910
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
21891
21911
  { detached: true, stdio: "ignore" }
@@ -21895,7 +21915,7 @@ var shutdownSession = async (ctx, cmd) => {
21895
21915
  }
21896
21916
  }
21897
21917
  try {
21898
- const proc = (0, import_child_process23.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
21918
+ const proc = (0, import_child_process24.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
21899
21919
  detached: true,
21900
21920
  stdio: "ignore"
21901
21921
  });
@@ -22418,7 +22438,7 @@ var defaultCliUpdateDeps = {
22418
22438
  // Only a truly local `codeam start` (neither marker) re-execs in place below.
22419
22439
  isSupervised: () => process.env["CODEAM_AUTO_APPROVE"] === "1" || process.env["CODESPACES"] === "true",
22420
22440
  relaunch: (args2) => {
22421
- const child = (0, import_child_process23.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
22441
+ const child = (0, import_child_process24.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
22422
22442
  process.exit(child.status ?? 0);
22423
22443
  }
22424
22444
  };
@@ -22447,7 +22467,7 @@ async function runNpmInstallLatest() {
22447
22467
  const command2 = useShell && invocation.command.includes(" ") ? `"${invocation.command}"` : invocation.command;
22448
22468
  for (let attempt = 1; attempt <= CLI_UPDATE_MAX_ATTEMPTS; attempt++) {
22449
22469
  const result = await new Promise((resolve7) => {
22450
- (0, import_child_process23.execFile)(
22470
+ (0, import_child_process24.execFile)(
22451
22471
  command2,
22452
22472
  invocation.args,
22453
22473
  { timeout: CLI_UPDATE_INSTALL_TIMEOUT_MS, shell: useShell },
@@ -23039,13 +23059,13 @@ async function dispatchCommand(ctx, cmd) {
23039
23059
  }
23040
23060
 
23041
23061
  // src/commands/start/keep-alive.ts
23042
- var import_child_process24 = require("child_process");
23062
+ var import_child_process25 = require("child_process");
23043
23063
  function buildKeepAlive(ctx) {
23044
23064
  let timer = null;
23045
23065
  async function setIdleTimeout(minutes) {
23046
23066
  if (!ctx.inCodespace || !ctx.codespaceName) return;
23047
23067
  await new Promise((resolve7) => {
23048
- const proc = (0, import_child_process24.spawn)(
23068
+ const proc = (0, import_child_process25.spawn)(
23049
23069
  "gh",
23050
23070
  [
23051
23071
  "api",
@@ -23917,7 +23937,7 @@ var path62 = __toESM(require("path"));
23917
23937
  var import_fs4 = __toESM(require("fs"));
23918
23938
  var import_os10 = __toESM(require("os"));
23919
23939
  var import_path8 = __toESM(require("path"));
23920
- var import_child_process25 = require("child_process");
23940
+ var import_child_process26 = require("child_process");
23921
23941
  function currentPlatformKey() {
23922
23942
  return `${process.platform}-${process.arch}`;
23923
23943
  }
@@ -23980,7 +24000,7 @@ function isCommandOnPath(cmd, probe = defaultWhich) {
23980
24000
  function defaultWhich(cmd) {
23981
24001
  const finder = process.platform === "win32" ? "where" : "which";
23982
24002
  try {
23983
- const res = (0, import_child_process25.spawnSync)(finder, [cmd], { stdio: "ignore" });
24003
+ const res = (0, import_child_process26.spawnSync)(finder, [cmd], { stdio: "ignore" });
23984
24004
  return res.status === 0;
23985
24005
  } catch {
23986
24006
  return false;
@@ -24033,7 +24053,7 @@ var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_
24033
24053
  var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
24034
24054
  function probeAdapterModuleGraph(command2, args2, opts = {}) {
24035
24055
  const livenessMs = opts.livenessMs ?? 400;
24036
- const spawnFn = opts.spawnFn ?? import_child_process25.spawn;
24056
+ const spawnFn = opts.spawnFn ?? import_child_process26.spawn;
24037
24057
  return new Promise((resolve7) => {
24038
24058
  let settled = false;
24039
24059
  let stderr = "";
@@ -28520,7 +28540,7 @@ function commonPrefixLength(a, b) {
28520
28540
  }
28521
28541
 
28522
28542
  // src/agents/acp/onboarding.ts
28523
- var import_child_process26 = require("child_process");
28543
+ var import_child_process27 = require("child_process");
28524
28544
  var fs60 = __toESM(require("fs"));
28525
28545
  var os49 = __toESM(require("os"));
28526
28546
  var path65 = __toESM(require("path"));
@@ -28541,7 +28561,7 @@ var _onboardingSeam = {
28541
28561
  */
28542
28562
  gitRemoteUrl: (cwd) => {
28543
28563
  try {
28544
- return (0, import_child_process26.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
28564
+ return (0, import_child_process27.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
28545
28565
  encoding: "utf8",
28546
28566
  stdio: ["ignore", "pipe", "ignore"],
28547
28567
  timeout: 2e3
@@ -28817,7 +28837,7 @@ function extractSelectPrompt(text) {
28817
28837
  var import_crypto5 = require("crypto");
28818
28838
 
28819
28839
  // src/services/turn-files/git-changeset.ts
28820
- var import_child_process27 = require("child_process");
28840
+ var import_child_process28 = require("child_process");
28821
28841
  var fs61 = __toESM(require("fs/promises"));
28822
28842
  var path66 = __toESM(require("path"));
28823
28843
  async function collectRepoChangeset(opts) {
@@ -28932,7 +28952,7 @@ function defaultRunGit(cwd, args2) {
28932
28952
  return new Promise((resolve7) => {
28933
28953
  let proc;
28934
28954
  try {
28935
- proc = (0, import_child_process27.spawn)("git", args2, { cwd, env: process.env });
28955
+ proc = (0, import_child_process28.spawn)("git", args2, { cwd, env: process.env });
28936
28956
  } catch {
28937
28957
  resolve7(null);
28938
28958
  return;
@@ -33352,11 +33372,11 @@ async function logout() {
33352
33372
  var import_picocolors11 = __toESM(require("picocolors"));
33353
33373
 
33354
33374
  // src/services/providers/github-codespaces.ts
33355
- var import_child_process28 = require("child_process");
33375
+ var import_child_process29 = require("child_process");
33356
33376
  var import_util4 = require("util");
33357
33377
  var import_picocolors9 = __toESM(require("picocolors"));
33358
33378
  var path69 = __toESM(require("path"));
33359
- var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
33379
+ var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
33360
33380
  var MAX_BUFFER = 8 * 1024 * 1024;
33361
33381
  function resetStdinForChild() {
33362
33382
  if (process.stdin.isTTY) {
@@ -33400,7 +33420,7 @@ var GitHubCodespacesProvider = class {
33400
33420
  if (!isAuthed) {
33401
33421
  resetStdinForChild();
33402
33422
  await new Promise((resolve7, reject) => {
33403
- const proc = (0, import_child_process28.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
33423
+ const proc = (0, import_child_process29.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
33404
33424
  stdio: "inherit"
33405
33425
  });
33406
33426
  proc.on("exit", (code) => {
@@ -33434,7 +33454,7 @@ var GitHubCodespacesProvider = class {
33434
33454
  wt(noteLines.join("\n"), "One more permission needed");
33435
33455
  resetStdinForChild();
33436
33456
  const refreshCode = await new Promise((resolve7, reject) => {
33437
- const proc = (0, import_child_process28.spawn)(
33457
+ const proc = (0, import_child_process29.spawn)(
33438
33458
  "gh",
33439
33459
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
33440
33460
  { stdio: "inherit" }
@@ -33584,7 +33604,7 @@ var GitHubCodespacesProvider = class {
33584
33604
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
33585
33605
  resetStdinForChild();
33586
33606
  const ok = await new Promise((resolve7) => {
33587
- const proc = (0, import_child_process28.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
33607
+ const proc = (0, import_child_process29.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
33588
33608
  proc.on("exit", (code) => resolve7(code === 0));
33589
33609
  proc.on("error", () => resolve7(false));
33590
33610
  });
@@ -33611,7 +33631,7 @@ var GitHubCodespacesProvider = class {
33611
33631
  );
33612
33632
  resetStdinForChild();
33613
33633
  await new Promise((resolve7, reject) => {
33614
- const proc = (0, import_child_process28.spawn)(
33634
+ const proc = (0, import_child_process29.spawn)(
33615
33635
  "gh",
33616
33636
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
33617
33637
  { stdio: "inherit" }
@@ -33789,7 +33809,7 @@ var GitHubCodespacesProvider = class {
33789
33809
  async streamCommand(workspaceId, command2) {
33790
33810
  resetStdinForChild();
33791
33811
  return new Promise((resolve7, reject) => {
33792
- const proc = (0, import_child_process28.spawn)(
33812
+ const proc = (0, import_child_process29.spawn)(
33793
33813
  "gh",
33794
33814
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
33795
33815
  { stdio: "inherit" }
@@ -33816,11 +33836,11 @@ var GitHubCodespacesProvider = class {
33816
33836
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
33817
33837
  ];
33818
33838
  await new Promise((resolve7, reject) => {
33819
- const tar = (0, import_child_process28.spawn)("tar", tarArgs, {
33839
+ const tar = (0, import_child_process29.spawn)("tar", tarArgs, {
33820
33840
  stdio: ["ignore", "pipe", "pipe"],
33821
33841
  env: tarEnv
33822
33842
  });
33823
- const ssh = (0, import_child_process28.spawn)("gh", sshArgs, {
33843
+ const ssh = (0, import_child_process29.spawn)("gh", sshArgs, {
33824
33844
  stdio: [tar.stdout, "pipe", "pipe"]
33825
33845
  });
33826
33846
  let tarErr = "";
@@ -33854,7 +33874,7 @@ var GitHubCodespacesProvider = class {
33854
33874
  }
33855
33875
  const cmd = parts.join(" && ");
33856
33876
  await new Promise((resolve7, reject) => {
33857
- const proc = (0, import_child_process28.spawn)(
33877
+ const proc = (0, import_child_process29.spawn)(
33858
33878
  "gh",
33859
33879
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
33860
33880
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -33912,11 +33932,11 @@ function shellQuote(s) {
33912
33932
  }
33913
33933
 
33914
33934
  // src/services/providers/gitpod.ts
33915
- var import_child_process29 = require("child_process");
33935
+ var import_child_process30 = require("child_process");
33916
33936
  var import_util5 = require("util");
33917
33937
  var path70 = __toESM(require("path"));
33918
33938
  var import_picocolors10 = __toESM(require("picocolors"));
33919
- var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
33939
+ var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
33920
33940
  var MAX_BUFFER2 = 8 * 1024 * 1024;
33921
33941
  function resetStdinForChild2() {
33922
33942
  if (process.stdin.isTTY) {
@@ -33956,7 +33976,7 @@ var GitpodProvider = class {
33956
33976
  );
33957
33977
  resetStdinForChild2();
33958
33978
  await new Promise((resolve7, reject) => {
33959
- const proc = (0, import_child_process29.spawn)("gitpod", ["login"], { stdio: "inherit" });
33979
+ const proc = (0, import_child_process30.spawn)("gitpod", ["login"], { stdio: "inherit" });
33960
33980
  proc.on("exit", (code) => {
33961
33981
  if (code === 0) resolve7();
33962
33982
  else reject(new Error("gitpod login failed."));
@@ -34108,7 +34128,7 @@ var GitpodProvider = class {
34108
34128
  async streamCommand(workspaceId, command2) {
34109
34129
  resetStdinForChild2();
34110
34130
  return new Promise((resolve7, reject) => {
34111
- const proc = (0, import_child_process29.spawn)(
34131
+ const proc = (0, import_child_process30.spawn)(
34112
34132
  "gitpod",
34113
34133
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
34114
34134
  { stdio: "inherit" }
@@ -34128,11 +34148,11 @@ var GitpodProvider = class {
34128
34148
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
34129
34149
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
34130
34150
  await new Promise((resolve7, reject) => {
34131
- const tar = (0, import_child_process29.spawn)("tar", tarArgs, {
34151
+ const tar = (0, import_child_process30.spawn)("tar", tarArgs, {
34132
34152
  stdio: ["ignore", "pipe", "pipe"],
34133
34153
  env: tarEnv
34134
34154
  });
34135
- const ssh = (0, import_child_process29.spawn)(
34155
+ const ssh = (0, import_child_process30.spawn)(
34136
34156
  "gitpod",
34137
34157
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
34138
34158
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -34164,7 +34184,7 @@ var GitpodProvider = class {
34164
34184
  }
34165
34185
  const cmd = parts.join(" && ");
34166
34186
  await new Promise((resolve7, reject) => {
34167
- const proc = (0, import_child_process29.spawn)(
34187
+ const proc = (0, import_child_process30.spawn)(
34168
34188
  "gitpod",
34169
34189
  ["workspace", "ssh", workspaceId, "--", cmd],
34170
34190
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -34188,10 +34208,10 @@ function shellQuote2(s) {
34188
34208
  }
34189
34209
 
34190
34210
  // src/services/providers/gitlab-workspaces.ts
34191
- var import_child_process30 = require("child_process");
34211
+ var import_child_process31 = require("child_process");
34192
34212
  var import_util6 = require("util");
34193
34213
  var path71 = __toESM(require("path"));
34194
- var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
34214
+ var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
34195
34215
  var MAX_BUFFER3 = 8 * 1024 * 1024;
34196
34216
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
34197
34217
  function resetStdinForChild3() {
@@ -34233,7 +34253,7 @@ var GitLabWorkspacesProvider = class {
34233
34253
  );
34234
34254
  resetStdinForChild3();
34235
34255
  await new Promise((resolve7, reject) => {
34236
- const proc = (0, import_child_process30.spawn)(
34256
+ const proc = (0, import_child_process31.spawn)(
34237
34257
  "glab",
34238
34258
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
34239
34259
  { stdio: "inherit" }
@@ -34405,7 +34425,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
34405
34425
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
34406
34426
  resetStdinForChild3();
34407
34427
  return new Promise((resolve7, reject) => {
34408
- const proc = (0, import_child_process30.spawn)(
34428
+ const proc = (0, import_child_process31.spawn)(
34409
34429
  "ssh",
34410
34430
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
34411
34431
  { stdio: "inherit" }
@@ -34426,8 +34446,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
34426
34446
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
34427
34447
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
34428
34448
  await new Promise((resolve7, reject) => {
34429
- const tar = (0, import_child_process30.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
34430
- const ssh = (0, import_child_process30.spawn)(
34449
+ const tar = (0, import_child_process31.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
34450
+ const ssh = (0, import_child_process31.spawn)(
34431
34451
  "ssh",
34432
34452
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
34433
34453
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -34457,7 +34477,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
34457
34477
  }
34458
34478
  const cmd = parts.join(" && ");
34459
34479
  await new Promise((resolve7, reject) => {
34460
- const proc = (0, import_child_process30.spawn)(
34480
+ const proc = (0, import_child_process31.spawn)(
34461
34481
  "ssh",
34462
34482
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
34463
34483
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -34516,10 +34536,10 @@ function shellQuote3(s) {
34516
34536
  }
34517
34537
 
34518
34538
  // src/services/providers/railway.ts
34519
- var import_child_process31 = require("child_process");
34539
+ var import_child_process32 = require("child_process");
34520
34540
  var import_util7 = require("util");
34521
34541
  var path72 = __toESM(require("path"));
34522
- var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
34542
+ var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
34523
34543
  var MAX_BUFFER4 = 8 * 1024 * 1024;
34524
34544
  function resetStdinForChild4() {
34525
34545
  if (process.stdin.isTTY) {
@@ -34560,7 +34580,7 @@ var RailwayProvider = class {
34560
34580
  );
34561
34581
  resetStdinForChild4();
34562
34582
  await new Promise((resolve7, reject) => {
34563
- const proc = (0, import_child_process31.spawn)("railway", ["login"], { stdio: "inherit" });
34583
+ const proc = (0, import_child_process32.spawn)("railway", ["login"], { stdio: "inherit" });
34564
34584
  proc.on("exit", (code) => {
34565
34585
  if (code === 0) resolve7();
34566
34586
  else reject(new Error("railway login failed."));
@@ -34703,7 +34723,7 @@ var RailwayProvider = class {
34703
34723
  }
34704
34724
  resetStdinForChild4();
34705
34725
  return new Promise((resolve7, reject) => {
34706
- const proc = (0, import_child_process31.spawn)(
34726
+ const proc = (0, import_child_process32.spawn)(
34707
34727
  "railway",
34708
34728
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
34709
34729
  { stdio: "inherit" }
@@ -34727,8 +34747,8 @@ var RailwayProvider = class {
34727
34747
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
34728
34748
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
34729
34749
  await new Promise((resolve7, reject) => {
34730
- const tar = (0, import_child_process31.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
34731
- const sh = (0, import_child_process31.spawn)(
34750
+ const tar = (0, import_child_process32.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
34751
+ const sh = (0, import_child_process32.spawn)(
34732
34752
  "railway",
34733
34753
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
34734
34754
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -34761,7 +34781,7 @@ var RailwayProvider = class {
34761
34781
  }
34762
34782
  const cmd = parts.join(" && ");
34763
34783
  await new Promise((resolve7, reject) => {
34764
- const proc = (0, import_child_process31.spawn)(
34784
+ const proc = (0, import_child_process32.spawn)(
34765
34785
  "railway",
34766
34786
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
34767
34787
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -35569,7 +35589,7 @@ function checkChokidar() {
35569
35589
  }
35570
35590
  async function doctor(args2 = []) {
35571
35591
  const json = args2.includes("--json");
35572
- const cliVersion = true ? "2.60.70" : "0.0.0-dev";
35592
+ const cliVersion = true ? "2.61.1" : "0.0.0-dev";
35573
35593
  const apiBase2 = resolveApiBaseUrl();
35574
35594
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
35575
35595
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -36080,7 +36100,7 @@ async function mcpRun(args2) {
36080
36100
  // src/commands/version.ts
36081
36101
  var import_picocolors15 = __toESM(require("picocolors"));
36082
36102
  function version2() {
36083
- const v = true ? "2.60.70" : "unknown";
36103
+ const v = true ? "2.61.1" : "unknown";
36084
36104
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
36085
36105
  }
36086
36106
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.60.70",
3
+ "version": "2.61.1",
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",