codeam-cli 2.65.16 → 2.65.17

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.65.16] — 2026-08-20
8
+
9
+ ### Added
10
+
11
+ - **cli:** House agent (CodeAgent Cloud) as an in-session switch target
12
+
7
13
  ## [2.65.15] — 2026-08-20
8
14
 
9
15
  ### Fixed
package/dist/index.js CHANGED
@@ -8081,7 +8081,7 @@ function readAnonId() {
8081
8081
  }
8082
8082
  function superProperties() {
8083
8083
  return {
8084
- cliVersion: true ? "2.65.16" : "0.0.0-dev",
8084
+ cliVersion: true ? "2.65.17" : "0.0.0-dev",
8085
8085
  nodeVersion: process.version,
8086
8086
  platform: process.platform,
8087
8087
  arch: process.arch,
@@ -8323,7 +8323,7 @@ var http = __toESM(require("http"));
8323
8323
  // package.json
8324
8324
  var package_default = {
8325
8325
  name: "codeam-cli",
8326
- version: "2.65.16",
8326
+ version: "2.65.17",
8327
8327
  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.",
8328
8328
  type: "commonjs",
8329
8329
  main: "dist/index.js",
@@ -9845,7 +9845,7 @@ var CommandRelayService = class _CommandRelayService {
9845
9845
  // fresh + clear the "CLI update available" banner after a self-update
9846
9846
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9847
9847
  // pair/reconnect). Older backends ignore the extra field.
9848
- ..."2.65.16" ? { ideVersion: "2.65.16" } : {}
9848
+ ..."2.65.17" ? { ideVersion: "2.65.17" } : {}
9849
9849
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9850
9850
  }
9851
9851
  /**
@@ -16995,19 +16995,31 @@ function escalateCommand(argv) {
16995
16995
  const isRoot = process.getuid?.() === 0;
16996
16996
  return isRoot ? { cmd: argv[0], args: argv.slice(1) } : { cmd: "sudo", args: argv };
16997
16997
  }
16998
- async function ensurePip(runner) {
16998
+ async function ensurePythonInstaller(runner) {
16999
16999
  if (runner.which("pip") || runner.which("pip3")) {
17000
- return true;
17000
+ return { ok: true, installer: { kind: "pip" } };
17001
+ }
17002
+ if (runner.which("uv")) {
17003
+ log.info("host-agent", "pip absent but uv is available \u2014 installing without root");
17004
+ return { ok: true, installer: { kind: "uv", bin: "uv" } };
17001
17005
  }
17002
17006
  const pm = detectPackageManager(runner);
17003
17007
  if (!pm) {
17004
- log.warn(
17005
- "host-agent",
17006
- "pip is absent and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) found \u2014 skipping Headroom"
17007
- );
17008
- return false;
17008
+ return {
17009
+ ok: false,
17010
+ reason: "Python pip is not installed and no supported package manager (apt-get/apk/dnf/yum/pacman/zypper) was found. Install pip \u2014 or uv \u2014 on this machine, then retry."
17011
+ };
17009
17012
  }
17010
17013
  const escalate = escalateCommand;
17014
+ if (process.getuid?.() !== 0) {
17015
+ const probe = await runner.run("sudo", ["-n", "true"], { timeoutMs: 1e4 });
17016
+ if (probe.code !== 0) {
17017
+ return {
17018
+ ok: false,
17019
+ reason: "Python pip is not installed here and this session cannot install it: it runs as a non-root user and sudo requires a password (there is no terminal to type it into). Install python3-pip \u2014 or uv \u2014 on the machine, then retry."
17020
+ };
17021
+ }
17022
+ }
17011
17023
  const recipe = PROVISION_RECIPES[pm];
17012
17024
  log.info(
17013
17025
  "host-agent",
@@ -17027,21 +17039,23 @@ async function ensurePip(runner) {
17027
17039
  const { cmd, args: args2 } = escalate(recipe.install);
17028
17040
  const installResult = await runner.run(cmd, args2, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
17029
17041
  if (installResult.code !== 0) {
17042
+ const detail = installResult.stderr.trim().split("\n").slice(-1)[0] ?? "";
17030
17043
  log.warn(
17031
17044
  "host-agent",
17032
17045
  `${pm} bare-box provision failed (code=${String(installResult.code)}) \u2014 skipping Headroom`
17033
17046
  );
17034
- return false;
17047
+ return {
17048
+ ok: false,
17049
+ reason: `Installing python3-pip via ${pm} failed (exit ${String(installResult.code)})${detail ? `: ${detail}` : ""}.`
17050
+ };
17035
17051
  }
17036
17052
  } catch (e) {
17037
- log.warn(
17038
- "host-agent",
17039
- `bare-box provision threw unexpectedly: ${e instanceof Error ? e.message : String(e)} \u2014 skipping Headroom`
17040
- );
17041
- return false;
17053
+ const msg = e instanceof Error ? e.message : String(e);
17054
+ log.warn("host-agent", `bare-box provision threw unexpectedly: ${msg} \u2014 skipping Headroom`);
17055
+ return { ok: false, reason: `Installing python3-pip via ${pm} threw: ${msg}` };
17042
17056
  }
17043
17057
  log.info("host-agent", `bare box provisioned via ${pm} (python3+pip+ca-certificates+curl)`);
17044
- return true;
17058
+ return { ok: true, installer: { kind: "pip" } };
17045
17059
  }
17046
17060
  async function resolveHeadroomPython(runner) {
17047
17061
  const PROBE_TIMEOUT_MS = 5e3;
@@ -21693,10 +21707,12 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
21693
21707
  const onProgress = opts.onProgress ?? (() => {
21694
21708
  });
21695
21709
  const SERVER_DEPS = HEADROOM_PIP_COMPANIONS;
21696
- const pipAvailable = await ensurePip(runner);
21697
- if (!pipAvailable) {
21710
+ const installerResult = await ensurePythonInstaller(runner);
21711
+ if (!installerResult.ok) {
21712
+ log.warn("host-agent", `Headroom: ${installerResult.reason}`);
21698
21713
  return false;
21699
21714
  }
21715
+ const installer = installerResult.installer;
21700
21716
  const py = await ensureModernPython(runner);
21701
21717
  if (py === null) {
21702
21718
  log.warn(
@@ -21707,6 +21723,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
21707
21723
  }
21708
21724
  log.info("host-agent", `Headroom will use interpreter: ${py}`);
21709
21725
  const pipInstall = async (pkgs, extraArgs, timeoutMs) => {
21726
+ if (installer.kind === "uv") {
21727
+ const r2 = await runner.run(
21728
+ installer.bin,
21729
+ ["pip", "install", "--quiet", "--python", py, "--break-system-packages", ...extraArgs, ...pkgs],
21730
+ { timeoutMs }
21731
+ );
21732
+ return r2.code === 0;
21733
+ }
21710
21734
  const base = ["-m", "pip", "install", "--quiet", ...extraArgs, ...pkgs];
21711
21735
  const r = await runner.run(py, base, { timeoutMs });
21712
21736
  if (r.code === 0) return true;
@@ -22046,7 +22070,7 @@ async function autoUpgradeBeforeCriticalCommand() {
22046
22070
  if (process.env.NODE_ENV === "test") return;
22047
22071
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22048
22072
  if (process.env.CI) return;
22049
- const current2 = true ? "2.65.16" : null;
22073
+ const current2 = true ? "2.65.17" : null;
22050
22074
  if (!current2) return;
22051
22075
  const cache = readCache();
22052
22076
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22063,7 +22087,7 @@ function checkForUpdates() {
22063
22087
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22064
22088
  if (process.env.CI) return;
22065
22089
  if (!process.stdout.isTTY) return;
22066
- const current2 = true ? "2.65.16" : null;
22090
+ const current2 = true ? "2.65.17" : null;
22067
22091
  if (!current2) return;
22068
22092
  const cache = readCache();
22069
22093
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22083,7 +22107,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
22083
22107
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
22084
22108
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
22085
22109
  function currentCliVersion() {
22086
- return true ? "2.65.16" : null;
22110
+ return true ? "2.65.17" : null;
22087
22111
  }
22088
22112
  function runCmd(cmd, args2, timeoutMs) {
22089
22113
  return new Promise((resolve10) => {
@@ -45564,7 +45588,7 @@ function checkChokidar() {
45564
45588
  }
45565
45589
  async function doctor(args2 = []) {
45566
45590
  const json = args2.includes("--json");
45567
- const cliVersion = true ? "2.65.16" : "0.0.0-dev";
45591
+ const cliVersion = true ? "2.65.17" : "0.0.0-dev";
45568
45592
  const apiBase2 = resolveApiBaseUrl();
45569
45593
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
45570
45594
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -45955,7 +45979,7 @@ async function mcpRun(args2) {
45955
45979
  // src/commands/version.ts
45956
45980
  var import_picocolors15 = __toESM(require("picocolors"));
45957
45981
  function version2() {
45958
- const v = true ? "2.65.16" : "unknown";
45982
+ const v = true ? "2.65.17" : "unknown";
45959
45983
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
45960
45984
  }
45961
45985
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.65.16",
3
+ "version": "2.65.17",
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",