codeam-cli 2.39.25 → 2.39.27

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,18 @@ 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.26] — 2026-06-17
8
+
9
+ ### Documentation
10
+
11
+ - **cli:** Document the self-hosted execution plane in the npm README (#351)
12
+
13
+ ## [2.39.25] — 2026-06-17
14
+
15
+ ### Added
16
+
17
+ - **cli:** Self-hosted host-agent supervisor + Docker E2E (#330) (#350)
18
+
7
19
  ## [2.39.24] — 2026-06-17
8
20
 
9
21
  ### Changed
package/README.md CHANGED
@@ -60,6 +60,8 @@ That's it. Open the [CodeAgent Mobile app](https://codeagent-mobile.com), enter
60
60
  | `codeam deploy` | Provision a cloud workspace (GitHub Codespaces) and pair it to your phone |
61
61
  | `codeam deploy ls` (alias `list`) | List the cloud workspaces you've deployed (and which still have a session running) |
62
62
  | `codeam deploy stop` (alias `remove`) | Pick a deployed workspace and stop its codeam session (and optionally the workspace itself) |
63
+ | `codeam host enroll --token <token>` | Enroll **this machine** as a self-hosted execution target (the token is minted by the mobile/web app) |
64
+ | `codeam host-agent` | Run the self-hosted supervisor (the enroll step installs this as a systemd service — you rarely call it by hand) |
63
65
  | `codeam completion <shell>` | print shell completions for `<shell>` (`bash`, `zsh`, or `fish`) |
64
66
  | `codeam --version`, `-v` | Print the installed CLI version |
65
67
  | `codeam --help`, `-h` | Show usage and the full command list |
@@ -98,13 +100,33 @@ codeam deploy stop
98
100
 
99
101
  Stopping a workspace via `codeam deploy stop` is non-destructive: the GitHub Codespace stays around (preserving your branch, files, and dotfiles); only the running compute is paused. Re-running `codeam deploy` will offer to resume that same codespace.
100
102
 
101
- Adding more cloud backends (Gitpod, Coder, your own SSH host, …) is a single new file in `apps/cli/src/services/providers/` — the `CloudProvider` interface keeps it pluggable.
103
+ Adding more managed cloud backends (Gitpod, Coder, …) is a single new file in `apps/cli/src/services/providers/` — the `CloudProvider` interface keeps it pluggable. To run on **your own server** instead, see the next section.
104
+
105
+ ---
106
+
107
+ ## Self-hosted execution plane — run agents on your own server
108
+
109
+ Prefer to run the execution plane on **your own hardware** (a VPS, homelab, or GPU box) instead of a managed Codespace? CodeAgent can provision the same agent runtime on any Linux server you own — with **zero inbound ports, no tunnel, and without ever handing us your SSH keys**. The box only needs outbound internet.
110
+
111
+ **Setup is a one-time paste, driven from the app:**
112
+
113
+ 1. In the CodeAgent Mobile app (or web dashboard), open the deploy flow and pick **Self-hosted → Add server**. It shows a one-line install command carrying a short-lived enroll token.
114
+ 2. Paste it into an SSH session on your box:
115
+ ```bash
116
+ curl -fsSL https://api.codeagent-mobile.com/api/self-hosted/enroll.sh | sh -s -- --token=<enroll-token>
117
+ ```
118
+ That installs `codeam-cli`, registers a **systemd** service (`codeam-host-agent`), and connects it back over the same **outbound** relay everything else uses. It survives reboots.
119
+ 3. From then on it's **100% phone/web-driven**: pick the host + a repo (or an absolute path on the box) + an agent, and a session spins up on your server — supervised from your phone like any other. Stop sessions or remove the host from the app.
120
+
121
+ Under the hood the installer runs `codeam host enroll` (redeems the token, seals a long-lived host-token to `~/.codeam/host-agent.json`) and starts `codeam host-agent` (the supervisor that spawns a `codeam pair-auto` child per deploy, injecting your linked agent's credentials). You normally never invoke these by hand.
122
+
123
+ > **Deploying to and managing self-hosted servers happens in the mobile/web app, not the CLI.** The CLI's role here is the one-time enrollment plus the long-running host-agent. Requires Linux + systemd.
102
124
 
103
125
  ---
104
126
 
105
127
  ## Requirements
106
128
 
107
- - **Node.js 18+**
129
+ - **Node.js 20+**
108
130
  - **Claude Code** — see the [official quickstart](https://code.claude.com/docs/en/quickstart)
109
131
  - **OpenAI Codex** (optional) — see the [official quickstart](https://github.com/openai/codex)
110
132
  - **[CodeAgent Mobile](https://codeagent-mobile.com)** app on your phone ([iOS](https://apps.apple.com/) / [Android](https://play.google.com/store/apps/details?id=com.codeagent.mobile))
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.25",
501
+ version: "2.39.27",
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",
@@ -568,8 +568,8 @@ var package_default = {
568
568
  node: ">=20.0.0"
569
569
  },
570
570
  dependencies: {
571
- "@agentclientprotocol/claude-agent-acp": "^0.42.0",
572
- "@agentclientprotocol/codex-acp": "^0.0.45",
571
+ "@agentclientprotocol/claude-agent-acp": "^0.47.0",
572
+ "@agentclientprotocol/codex-acp": "^0.0.46",
573
573
  "@agentclientprotocol/sdk": "^0.25.0",
574
574
  "@clack/prompts": "^1.2.0",
575
575
  chokidar: "^3.6.0",
@@ -5908,7 +5908,7 @@ function readAnonId() {
5908
5908
  }
5909
5909
  function superProperties() {
5910
5910
  return {
5911
- cliVersion: true ? "2.39.25" : "0.0.0-dev",
5911
+ cliVersion: true ? "2.39.27" : "0.0.0-dev",
5912
5912
  nodeVersion: process.version,
5913
5913
  platform: process.platform,
5914
5914
  arch: process.arch,
@@ -26442,8 +26442,18 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os34.homedir(
26442
26442
 
26443
26443
  // src/commands/host-agent.ts
26444
26444
  var HEARTBEAT_INTERVAL_MS = 2e4;
26445
+ function isHouseProxy(v) {
26446
+ if (typeof v !== "object" || v === null) return false;
26447
+ const o = v;
26448
+ return typeof o.baseUrl === "string" && typeof o.token === "string" && typeof o.agentKind === "string";
26449
+ }
26445
26450
  function isDeployPayload(p2) {
26446
- return typeof p2.deployId === "string" && typeof p2.repoOrPath === "string" && typeof p2.agentId === "string" && typeof p2.sealedAgentAuth === "string" && typeof p2.autoPairToken === "string";
26451
+ if (typeof p2.deployId !== "string" || typeof p2.repoOrPath !== "string" || typeof p2.agentId !== "string" || typeof p2.autoPairToken !== "string") {
26452
+ return false;
26453
+ }
26454
+ const hasHouse = isHouseProxy(p2.houseProxy);
26455
+ const hasSealed = typeof p2.sealedAgentAuth === "string";
26456
+ return hasHouse || hasSealed;
26447
26457
  }
26448
26458
  function isStopPayload(p2) {
26449
26459
  return typeof p2.sessionId === "string";
@@ -26456,7 +26466,7 @@ var CONTROL_AGENT_META = {
26456
26466
  supportedAuthKinds: ["oauth_token"],
26457
26467
  preferredAuthKind: "oauth_token"
26458
26468
  };
26459
- var defaultSpawner = (env, cwd) => (0, import_node_child_process13.spawn)(process.execPath, [process.argv[1], "pair-auto"], {
26469
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
26460
26470
  cwd,
26461
26471
  env: { ...process.env, ...env },
26462
26472
  stdio: "ignore",
@@ -26556,13 +26566,31 @@ var HostAgentSupervisor = class {
26556
26566
  `deploy id=${payload.deployId.slice(0, 8)} agent=${payload.agentId} target=${payload.repoOrPath}`
26557
26567
  );
26558
26568
  const cwd = await prepareWorkspace(payload.repoOrPath, payload.deployId);
26559
- const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
26560
- const credEnv = provisionAgentCredentials(payload.agentId, auth, void 0);
26561
- const childEnv = {
26562
- ...credEnv,
26563
- CODEAM_AUTO_TOKEN: payload.autoPairToken
26564
- };
26565
- const proc = this.spawnChild(childEnv, cwd);
26569
+ let childEnv;
26570
+ let extraArgs = [];
26571
+ if (payload.houseProxy) {
26572
+ const { baseUrl, token, agentKind } = payload.houseProxy;
26573
+ childEnv = {
26574
+ ANTHROPIC_BASE_URL: baseUrl,
26575
+ ANTHROPIC_AUTH_TOKEN: token,
26576
+ ANTHROPIC_MODEL: "MiniMax-M3",
26577
+ ANTHROPIC_DEFAULT_SONNET_MODEL: "MiniMax-M3",
26578
+ ANTHROPIC_DEFAULT_OPUS_MODEL: "MiniMax-M3",
26579
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: "MiniMax-M3",
26580
+ CLAUDE_CODE_AUTO_COMPACT_WINDOW: "512000",
26581
+ API_TIMEOUT_MS: "3000000",
26582
+ CODEAM_AUTO_TOKEN: payload.autoPairToken
26583
+ };
26584
+ extraArgs = [`--agent=${agentKind || "claude"}`];
26585
+ } else {
26586
+ const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
26587
+ const credEnv = provisionAgentCredentials(payload.agentId, auth, void 0);
26588
+ childEnv = {
26589
+ ...credEnv,
26590
+ CODEAM_AUTO_TOKEN: payload.autoPairToken
26591
+ };
26592
+ }
26593
+ const proc = this.spawnChild(childEnv, cwd, extraArgs);
26566
26594
  const child = { deployId: payload.deployId, sessionId: payload.deployId, proc };
26567
26595
  this.children.set(payload.deployId, child);
26568
26596
  proc.once("exit", () => {
@@ -26794,7 +26822,7 @@ function checkChokidar() {
26794
26822
  }
26795
26823
  async function doctor(args2 = []) {
26796
26824
  const json = args2.includes("--json");
26797
- const cliVersion = true ? "2.39.25" : "0.0.0-dev";
26825
+ const cliVersion = true ? "2.39.27" : "0.0.0-dev";
26798
26826
  const apiBase2 = resolveApiBaseUrl();
26799
26827
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
26800
26828
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -26993,7 +27021,7 @@ async function completion(args2) {
26993
27021
  // src/commands/version.ts
26994
27022
  var import_picocolors13 = __toESM(require("picocolors"));
26995
27023
  function version2() {
26996
- const v = true ? "2.39.25" : "unknown";
27024
+ const v = true ? "2.39.27" : "unknown";
26997
27025
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
26998
27026
  }
26999
27027
 
@@ -27279,7 +27307,7 @@ function checkForUpdates() {
27279
27307
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
27280
27308
  if (process.env.CI) return;
27281
27309
  if (!process.stdout.isTTY) return;
27282
- const current = true ? "2.39.25" : null;
27310
+ const current = true ? "2.39.27" : null;
27283
27311
  if (!current) return;
27284
27312
  const cache = readCache();
27285
27313
  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.25",
3
+ "version": "2.39.27",
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",
@@ -70,8 +70,8 @@
70
70
  "node": ">=20.0.0"
71
71
  },
72
72
  "dependencies": {
73
- "@agentclientprotocol/claude-agent-acp": "^0.42.0",
74
- "@agentclientprotocol/codex-acp": "^0.0.45",
73
+ "@agentclientprotocol/claude-agent-acp": "^0.47.0",
74
+ "@agentclientprotocol/codex-acp": "^0.0.46",
75
75
  "@agentclientprotocol/sdk": "^0.25.0",
76
76
  "@clack/prompts": "^1.2.0",
77
77
  "chokidar": "^3.6.0",