codeam-cli 2.61.32 → 2.61.34

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.61.33] — 2026-07-24
8
+
9
+ ### Added
10
+
11
+ - **cli:** GitLab deploy support on the box — glab + gitlab.com clone
12
+
13
+ ## [2.61.32] — 2026-07-24
14
+
15
+ ### Added
16
+
17
+ - **shared:** Add GitLab as a version_control integration
18
+
7
19
  ## [2.61.31] — 2026-07-24
8
20
 
9
21
  ### Added
package/dist/index.js CHANGED
@@ -1604,7 +1604,7 @@ var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, ge
1604
1604
 
1605
1605
  // src/commands/pair-auto.ts
1606
1606
  var fs58 = __toESM(require("fs"));
1607
- var os48 = __toESM(require("os"));
1607
+ var os49 = __toESM(require("os"));
1608
1608
  var path62 = __toESM(require("path"));
1609
1609
  var import_crypto4 = require("crypto");
1610
1610
 
@@ -6355,7 +6355,7 @@ function readAnonId() {
6355
6355
  }
6356
6356
  function superProperties() {
6357
6357
  return {
6358
- cliVersion: true ? "2.61.32" : "0.0.0-dev",
6358
+ cliVersion: true ? "2.61.34" : "0.0.0-dev",
6359
6359
  nodeVersion: process.version,
6360
6360
  platform: process.platform,
6361
6361
  arch: process.arch,
@@ -6536,7 +6536,7 @@ var os4 = __toESM(require("os"));
6536
6536
  // package.json
6537
6537
  var package_default = {
6538
6538
  name: "codeam-cli",
6539
- version: "2.61.32",
6539
+ version: "2.61.34",
6540
6540
  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.",
6541
6541
  type: "commonjs",
6542
6542
  main: "dist/index.js",
@@ -7707,7 +7707,7 @@ var CommandRelayService = class _CommandRelayService {
7707
7707
  // fresh + clear the "CLI update available" banner after a self-update
7708
7708
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
7709
7709
  // pair/reconnect). Older backends ignore the extra field.
7710
- ..."2.61.32" ? { ideVersion: "2.61.32" } : {}
7710
+ ..."2.61.34" ? { ideVersion: "2.61.34" } : {}
7711
7711
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
7712
7712
  }
7713
7713
  /**
@@ -7934,10 +7934,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
7934
7934
  /[\\/]Start Menu([\\/]|$)/i,
7935
7935
  /[\\/]Templates([\\/]|$)/i
7936
7936
  ];
7937
- function isUnsafeWindowsWatchRoot(dir, homedir44) {
7937
+ function isUnsafeWindowsWatchRoot(dir, homedir45) {
7938
7938
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
7939
7939
  const cwd = norm(dir);
7940
- const home = norm(homedir44);
7940
+ const home = norm(homedir45);
7941
7941
  if (cwd === home) return true;
7942
7942
  if (/^[a-z]:$/.test(cwd)) return true;
7943
7943
  const sysRoots = [
@@ -9082,7 +9082,7 @@ function closeAllTerminals() {
9082
9082
 
9083
9083
  // src/commands/start/handlers.ts
9084
9084
  var fs57 = __toESM(require("fs"));
9085
- var os47 = __toESM(require("os"));
9085
+ var os48 = __toESM(require("os"));
9086
9086
  var path61 = __toESM(require("path"));
9087
9087
  var import_crypto3 = require("crypto");
9088
9088
  var import_child_process24 = require("child_process");
@@ -12563,10 +12563,10 @@ function buildForPlatform(platform3) {
12563
12563
  var import_node_crypto4 = require("crypto");
12564
12564
 
12565
12565
  // src/agents/claude/resolver.ts
12566
- function buildClaudeLaunch(extraArgs = [], os57 = createOsStrategy()) {
12567
- const found = os57.findInPath("claude") ?? os57.findInPath("claude-code");
12566
+ function buildClaudeLaunch(extraArgs = [], os58 = createOsStrategy()) {
12567
+ const found = os58.findInPath("claude") ?? os58.findInPath("claude-code");
12568
12568
  if (!found) return null;
12569
- return os57.buildLaunch(found, extraArgs);
12569
+ return os58.buildLaunch(found, extraArgs);
12570
12570
  }
12571
12571
 
12572
12572
  // src/agents/claude/installer.ts
@@ -13156,8 +13156,8 @@ var ClaudeRuntimeStrategy = class {
13156
13156
  meta = getAgent("claude");
13157
13157
  mode = "interactive";
13158
13158
  os;
13159
- constructor(os57) {
13160
- this.os = os57;
13159
+ constructor(os58) {
13160
+ this.os = os58;
13161
13161
  }
13162
13162
  /**
13163
13163
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -13937,8 +13937,8 @@ function codexCredentialLocator() {
13937
13937
  function codexLoginLauncher() {
13938
13938
  return {
13939
13939
  async ensureInstalled() {
13940
- const os57 = createOsStrategy();
13941
- return os57.findInPath("codex") !== null;
13940
+ const os58 = createOsStrategy();
13941
+ return os58.findInPath("codex") !== null;
13942
13942
  },
13943
13943
  launch() {
13944
13944
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -13961,8 +13961,8 @@ var CodexRuntimeStrategy = class {
13961
13961
  meta = getAgent("codex");
13962
13962
  mode = "interactive";
13963
13963
  os;
13964
- constructor(os57) {
13965
- this.os = os57;
13964
+ constructor(os58) {
13965
+ this.os = os58;
13966
13966
  }
13967
13967
  async prepareLaunch() {
13968
13968
  let binary = this.os.findInPath("codex");
@@ -14071,12 +14071,12 @@ var CodexRuntimeStrategy = class {
14071
14071
  });
14072
14072
  }
14073
14073
  };
14074
- function resolveNpm(os57) {
14075
- return os57.id === "win32" ? "npm.cmd" : "npm";
14074
+ function resolveNpm(os58) {
14075
+ return os58.id === "win32" ? "npm.cmd" : "npm";
14076
14076
  }
14077
- async function installCodexViaNpm(os57) {
14077
+ async function installCodexViaNpm(os58) {
14078
14078
  return new Promise((resolve8, reject) => {
14079
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os57), ["install", "-g", "@openai/codex"], {
14079
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os58), ["install", "-g", "@openai/codex"], {
14080
14080
  stdio: "inherit"
14081
14081
  });
14082
14082
  proc.on("close", (code) => {
@@ -14093,16 +14093,16 @@ async function installCodexViaNpm(os57) {
14093
14093
  });
14094
14094
  });
14095
14095
  }
14096
- function augmentNpmGlobalBin(os57) {
14096
+ function augmentNpmGlobalBin(os58) {
14097
14097
  try {
14098
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os57), ["prefix", "-g"], {
14098
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os58), ["prefix", "-g"], {
14099
14099
  stdio: ["ignore", "pipe", "ignore"]
14100
14100
  });
14101
14101
  if (result.status !== 0) return;
14102
14102
  const prefix = result.stdout.toString().trim();
14103
14103
  if (!prefix) return;
14104
- const binDir = os57.id === "win32" ? prefix : path24.join(prefix, "bin");
14105
- os57.augmentPath([binDir]);
14104
+ const binDir = os58.id === "win32" ? prefix : path24.join(prefix, "bin");
14105
+ os58.augmentPath([binDir]);
14106
14106
  } catch {
14107
14107
  }
14108
14108
  }
@@ -14186,9 +14186,9 @@ var import_node_child_process8 = require("child_process");
14186
14186
  // src/agents/coderabbit/installer.ts
14187
14187
  var import_node_child_process6 = require("child_process");
14188
14188
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
14189
- async function ensureCoderabbitInstalled(os57) {
14190
- if (os57.findInPath("coderabbit")) return true;
14191
- if (os57.id === "win32") {
14189
+ async function ensureCoderabbitInstalled(os58) {
14190
+ if (os58.findInPath("coderabbit")) return true;
14191
+ if (os58.id === "win32") {
14192
14192
  console.error(
14193
14193
  "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
14194
14194
  );
@@ -14221,8 +14221,8 @@ async function ensureCoderabbitInstalled(os57) {
14221
14221
  proc.on("error", () => finish(false));
14222
14222
  });
14223
14223
  if (!ok) return false;
14224
- os57.augmentPath([`${os57.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
14225
- return os57.findInPath("coderabbit") !== null;
14224
+ os58.augmentPath([`${os58.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
14225
+ return os58.findInPath("coderabbit") !== null;
14226
14226
  }
14227
14227
 
14228
14228
  // src/agents/coderabbit/link.ts
@@ -14257,10 +14257,10 @@ function coderabbitCredentialLocator() {
14257
14257
  validate: validateNonEmptyCredential
14258
14258
  };
14259
14259
  }
14260
- function coderabbitLoginLauncher(os57) {
14260
+ function coderabbitLoginLauncher(os58) {
14261
14261
  return {
14262
14262
  async ensureInstalled() {
14263
- return ensureCoderabbitInstalled(os57);
14263
+ return ensureCoderabbitInstalled(os58);
14264
14264
  },
14265
14265
  launch() {
14266
14266
  return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
@@ -14480,8 +14480,8 @@ var CoderabbitRuntimeStrategy = class {
14480
14480
  meta = getAgent("coderabbit");
14481
14481
  mode = "batch";
14482
14482
  os;
14483
- constructor(os57) {
14484
- this.os = os57;
14483
+ constructor(os58) {
14484
+ this.os = os58;
14485
14485
  }
14486
14486
  getDefaultArgs() {
14487
14487
  return ["review", "--agent"];
@@ -14752,10 +14752,10 @@ function cursorCredentialLocator() {
14752
14752
  validate: validateNonEmptyCredential
14753
14753
  };
14754
14754
  }
14755
- function cursorLoginLauncher(os57) {
14755
+ function cursorLoginLauncher(os58) {
14756
14756
  return {
14757
14757
  async ensureInstalled() {
14758
- if (os57.findInPath("cursor-agent")) return true;
14758
+ if (os58.findInPath("cursor-agent")) return true;
14759
14759
  console.error(
14760
14760
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
14761
14761
  );
@@ -14819,8 +14819,8 @@ var CursorRuntimeStrategy = class {
14819
14819
  meta = getAgent("cursor");
14820
14820
  mode = "interactive";
14821
14821
  os;
14822
- constructor(os57) {
14823
- this.os = os57;
14822
+ constructor(os58) {
14823
+ this.os = os58;
14824
14824
  }
14825
14825
  async prepareLaunch() {
14826
14826
  const binary = this.os.findInPath("cursor-agent");
@@ -15036,10 +15036,10 @@ function aiderCredentialLocator() {
15036
15036
  validate: validateNonEmptyCredential
15037
15037
  };
15038
15038
  }
15039
- function aiderLoginLauncher(os57) {
15039
+ function aiderLoginLauncher(os58) {
15040
15040
  return {
15041
15041
  async ensureInstalled() {
15042
- if (os57.findInPath("aider")) return true;
15042
+ if (os58.findInPath("aider")) return true;
15043
15043
  console.error(
15044
15044
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
15045
15045
  );
@@ -15049,7 +15049,7 @@ function aiderLoginLauncher(os57) {
15049
15049
  console.error(
15050
15050
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
15051
15051
  );
15052
- return (0, import_node_child_process11.spawn)(os57.id === "win32" ? "cmd.exe" : "sh", os57.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
15052
+ return (0, import_node_child_process11.spawn)(os58.id === "win32" ? "cmd.exe" : "sh", os58.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
15053
15053
  stdio: "ignore"
15054
15054
  });
15055
15055
  }
@@ -15121,8 +15121,8 @@ var AiderRuntimeStrategy = class {
15121
15121
  meta = getAgent("aider");
15122
15122
  mode = "interactive";
15123
15123
  os;
15124
- constructor(os57) {
15125
- this.os = os57;
15124
+ constructor(os58) {
15125
+ this.os = os58;
15126
15126
  }
15127
15127
  async prepareLaunch() {
15128
15128
  const binary = this.os.findInPath("aider");
@@ -15254,8 +15254,8 @@ function geminiCredentialLocator() {
15254
15254
  function geminiLoginLauncher() {
15255
15255
  return {
15256
15256
  async ensureInstalled() {
15257
- const os57 = createOsStrategy();
15258
- return os57.findInPath("gemini") !== null;
15257
+ const os58 = createOsStrategy();
15258
+ return os58.findInPath("gemini") !== null;
15259
15259
  },
15260
15260
  launch() {
15261
15261
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -15445,8 +15445,8 @@ var GeminiRuntimeStrategy = class {
15445
15445
  meta = getAgent("gemini");
15446
15446
  mode = "interactive";
15447
15447
  os;
15448
- constructor(os57) {
15449
- this.os = os57;
15448
+ constructor(os58) {
15449
+ this.os = os58;
15450
15450
  }
15451
15451
  async prepareLaunch() {
15452
15452
  const binary = this.os.findInPath("gemini");
@@ -15737,8 +15737,8 @@ var KimiRuntimeStrategy = class {
15737
15737
  meta = getAgent("kimi");
15738
15738
  mode = "interactive";
15739
15739
  os;
15740
- constructor(os57) {
15741
- this.os = os57;
15740
+ constructor(os58) {
15741
+ this.os = os58;
15742
15742
  }
15743
15743
  async prepareLaunch() {
15744
15744
  const binary = this.os.findInPath("kimi");
@@ -15851,19 +15851,19 @@ var KimiRuntimeStrategy = class {
15851
15851
 
15852
15852
  // src/agents/registry.ts
15853
15853
  var runtimeBuilders = {
15854
- claude: (os57) => new ClaudeRuntimeStrategy(os57),
15855
- codex: (os57) => new CodexRuntimeStrategy(os57),
15856
- coderabbit: (os57) => new CoderabbitRuntimeStrategy(os57),
15857
- cursor: (os57) => new CursorRuntimeStrategy(os57),
15858
- aider: (os57) => new AiderRuntimeStrategy(os57),
15859
- gemini: (os57) => new GeminiRuntimeStrategy(os57),
15860
- kimi: (os57) => new KimiRuntimeStrategy(os57)
15854
+ claude: (os58) => new ClaudeRuntimeStrategy(os58),
15855
+ codex: (os58) => new CodexRuntimeStrategy(os58),
15856
+ coderabbit: (os58) => new CoderabbitRuntimeStrategy(os58),
15857
+ cursor: (os58) => new CursorRuntimeStrategy(os58),
15858
+ aider: (os58) => new AiderRuntimeStrategy(os58),
15859
+ gemini: (os58) => new GeminiRuntimeStrategy(os58),
15860
+ kimi: (os58) => new KimiRuntimeStrategy(os58)
15861
15861
  };
15862
15862
  var deployBuilders = {
15863
15863
  claude: () => new ClaudeDeployStrategy(),
15864
15864
  codex: () => new CodexDeployStrategy()
15865
15865
  };
15866
- function createAgentStrategy(agent, os57 = createOsStrategy()) {
15866
+ function createAgentStrategy(agent, os58 = createOsStrategy()) {
15867
15867
  if (!AGENT_REGISTRY[agent]?.enabled) {
15868
15868
  throw new Error(
15869
15869
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -15873,10 +15873,10 @@ function createAgentStrategy(agent, os57 = createOsStrategy()) {
15873
15873
  if (!build) {
15874
15874
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
15875
15875
  }
15876
- return build(os57);
15876
+ return build(os58);
15877
15877
  }
15878
- function createInteractiveAgentStrategy(agent, os57 = createOsStrategy()) {
15879
- const s = createAgentStrategy(agent, os57);
15878
+ function createInteractiveAgentStrategy(agent, os58 = createOsStrategy()) {
15879
+ const s = createAgentStrategy(agent, os58);
15880
15880
  if (s.mode !== "interactive") {
15881
15881
  throw new Error(
15882
15882
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -16573,26 +16573,26 @@ function restoreCoderabbitOauthBlob(value) {
16573
16573
  (0, import_node_fs5.writeFileSync)(path36.join(dir, file), contents, { mode: 384 });
16574
16574
  }
16575
16575
  async function configureCoderabbit(input, deps = {}) {
16576
- const os57 = deps.os ?? createOsStrategy();
16576
+ const os58 = deps.os ?? createOsStrategy();
16577
16577
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
16578
16578
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
16579
16579
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
16580
16580
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
16581
16581
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
16582
16582
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
16583
- const home = os57.homeDir();
16584
- os57.augmentPath(
16585
- os57.id === "win32" ? [
16583
+ const home = os58.homeDir();
16584
+ os58.augmentPath(
16585
+ os58.id === "win32" ? [
16586
16586
  path36.join(home, ".local", "bin"),
16587
16587
  path36.join(process.env.APPDATA ?? path36.join(home, "AppData", "Roaming"), "npm"),
16588
16588
  path36.join(home, "scoop", "shims")
16589
16589
  ] : [path36.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
16590
16590
  );
16591
- const installed2 = os57.findInPath("coderabbit") !== null;
16591
+ const installed2 = os58.findInPath("coderabbit") !== null;
16592
16592
  const base = () => ({
16593
16593
  action: input.action,
16594
16594
  supported: true,
16595
- installed: os57.findInPath("coderabbit") !== null,
16595
+ installed: os58.findInPath("coderabbit") !== null,
16596
16596
  loggedIn: false
16597
16597
  });
16598
16598
  if (input.action === "status") {
@@ -16606,7 +16606,7 @@ async function configureCoderabbit(input, deps = {}) {
16606
16606
  const key = (input.apiKey ?? "").trim();
16607
16607
  if (!key) return { ...res2, error: "No API key provided" };
16608
16608
  if (!res2.installed) {
16609
- const ok = await ensureInstalled(os57);
16609
+ const ok = await ensureInstalled(os58);
16610
16610
  res2.installed = ok;
16611
16611
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
16612
16612
  }
@@ -16630,7 +16630,7 @@ async function configureCoderabbit(input, deps = {}) {
16630
16630
  }
16631
16631
  if (!res2.installed) {
16632
16632
  deps.onEvent?.({ kind: "installing" });
16633
- const ok = await ensureInstalled(os57);
16633
+ const ok = await ensureInstalled(os58);
16634
16634
  res2.installed = ok;
16635
16635
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
16636
16636
  }
@@ -16660,7 +16660,7 @@ async function configureCoderabbit(input, deps = {}) {
16660
16660
  const res2 = base();
16661
16661
  if (!installed2) {
16662
16662
  deps.onEvent?.({ kind: "installing" });
16663
- const ok = await ensureInstalled(os57);
16663
+ const ok = await ensureInstalled(os58);
16664
16664
  res2.installed = ok;
16665
16665
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
16666
16666
  }
@@ -16700,7 +16700,7 @@ async function configureCoderabbit(input, deps = {}) {
16700
16700
  }
16701
16701
  const res = base();
16702
16702
  if (!res.installed) {
16703
- const ok = await ensureInstalled(os57);
16703
+ const ok = await ensureInstalled(os58);
16704
16704
  res.installed = ok;
16705
16705
  if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
16706
16706
  }
@@ -16884,7 +16884,7 @@ function defaultRunGh(args2) {
16884
16884
 
16885
16885
  // src/commands/host-agent.ts
16886
16886
  var import_node_child_process24 = require("child_process");
16887
- var os37 = __toESM(require("os"));
16887
+ var os38 = __toESM(require("os"));
16888
16888
  var fs43 = __toESM(require("fs"));
16889
16889
  var path46 = __toESM(require("path"));
16890
16890
 
@@ -17324,8 +17324,24 @@ function githubOwnerRepo(repoRef) {
17324
17324
  if (httpsMatch) return { owner: httpsMatch[1], repo: httpsMatch[2] };
17325
17325
  return null;
17326
17326
  }
17327
- function repoCloneUrl(repoRef, cloneToken) {
17327
+ function gitlabProjectPath(repoRef) {
17328
17328
  const trimmed = repoRef.trim();
17329
+ const https9 = /^https?:\/\/gitlab\.com\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
17330
+ if (https9) return https9[1];
17331
+ if (!/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@") && trimmed.includes("/")) {
17332
+ return trimmed.replace(/\.git$/, "");
17333
+ }
17334
+ return null;
17335
+ }
17336
+ function repoCloneUrl(repoRef, cloneToken, provider = "github") {
17337
+ const trimmed = repoRef.trim();
17338
+ if (provider === "gitlab") {
17339
+ const glPath = gitlabProjectPath(trimmed);
17340
+ if (glPath) {
17341
+ return cloneToken ? `https://oauth2:${cloneToken}@gitlab.com/${glPath}.git` : `https://gitlab.com/${glPath}.git`;
17342
+ }
17343
+ if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
17344
+ }
17329
17345
  if (cloneToken) {
17330
17346
  const gh = githubOwnerRepo(trimmed);
17331
17347
  if (gh) {
@@ -17354,12 +17370,15 @@ async function fetchGithubIdentity(token) {
17354
17370
  return null;
17355
17371
  }
17356
17372
  }
17357
- async function configureGitCredentials(dest, repoRef, cloneToken) {
17358
- const gh = githubOwnerRepo(repoRef.trim());
17359
- if (!gh || !cloneToken) return;
17373
+ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "github") {
17374
+ const isGitlab = provider === "gitlab";
17375
+ if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
17376
+ if (!cloneToken) return;
17360
17377
  const credFile = path40.join(dest, ".git", "codeam-credentials");
17361
- fs36.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
17362
- `, { mode: 384 });
17378
+ const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
17379
+ ` : `https://x-access-token:${cloneToken}@github.com
17380
+ `;
17381
+ fs36.writeFileSync(credFile, credLine, { mode: 384 });
17363
17382
  restrictToOwner(credFile);
17364
17383
  const env = nonInteractiveGitEnv();
17365
17384
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
@@ -17374,20 +17393,17 @@ async function configureGitCredentials(dest, repoRef, cloneToken) {
17374
17393
  `store --file=${credFilePosix}`
17375
17394
  ]).catch(() => {
17376
17395
  });
17377
- await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef)]).catch(() => {
17396
+ await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef, void 0, provider)]).catch(() => {
17378
17397
  });
17379
17398
  const hasIdentity = await git2(["config", "user.email"]).then(() => true).catch(() => false);
17380
17399
  if (!hasIdentity) {
17381
- const who = await fetchGithubIdentity(cloneToken);
17382
- if (who?.login) {
17383
- await git2(["config", "--local", "user.name", who.login]).catch(() => {
17384
- });
17385
- }
17386
- const email = who?.email ?? (who?.login ? `${who.login}@users.noreply.github.com` : void 0);
17387
- if (email) {
17388
- await git2(["config", "--local", "user.email", email]).catch(() => {
17389
- });
17390
- }
17400
+ const who = isGitlab ? null : await fetchGithubIdentity(cloneToken);
17401
+ const login = who?.login ?? "CodeAgent";
17402
+ await git2(["config", "--local", "user.name", login]).catch(() => {
17403
+ });
17404
+ const email = who?.email ?? (isGitlab ? "agent@codeagent-mobile.com" : `${login}@users.noreply.github.com`);
17405
+ await git2(["config", "--local", "user.email", email]).catch(() => {
17406
+ });
17391
17407
  }
17392
17408
  }
17393
17409
  function maskToken(text, cloneToken) {
@@ -17397,7 +17413,7 @@ function maskToken(text, cloneToken) {
17397
17413
  }
17398
17414
  return masked;
17399
17415
  }
17400
- async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
17416
+ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github") {
17401
17417
  if (isAbsolutePathTarget(repoOrPath)) {
17402
17418
  if (!fs36.existsSync(repoOrPath)) {
17403
17419
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
@@ -17406,11 +17422,11 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
17406
17422
  }
17407
17423
  const dest = path40.join(selfHostedWorkspaceRoot(), deployId);
17408
17424
  if (fs36.existsSync(path40.join(dest, ".git"))) {
17409
- if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
17425
+ if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
17410
17426
  return dest;
17411
17427
  }
17412
17428
  fs36.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
17413
- const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
17429
+ const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
17414
17430
  try {
17415
17431
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
17416
17432
  timeout: 12e4,
@@ -17421,7 +17437,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
17421
17437
  const reason = err instanceof Error ? err.message : String(err);
17422
17438
  throw new Error(`git clone failed for ${maskCloneUrl(cloneUrl)}: ${maskToken(reason, cloneToken)}`);
17423
17439
  }
17424
- if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
17440
+ if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
17425
17441
  return dest;
17426
17442
  }
17427
17443
 
@@ -17722,6 +17738,92 @@ async function ensureGhAuth(runner, ghCmd, token) {
17722
17738
  log.warn("host-agent", `gh auth errored: ${e instanceof Error ? e.message : String(e)}`);
17723
17739
  }
17724
17740
  }
17741
+ var FALLBACK_GLAB_VERSION = "1.54.0";
17742
+ var GLAB_RELEASE_API = "https://gitlab.com/api/v4/projects/gitlab-org%2Fcli/releases/permalink/latest";
17743
+ async function resolveLatestGlabVersion() {
17744
+ try {
17745
+ const res = await fetch(GLAB_RELEASE_API, { headers: { Accept: "application/json" } });
17746
+ if (res.ok) {
17747
+ const body = await res.json();
17748
+ const tag = (body.tag_name ?? "").replace(/^v/, "");
17749
+ if (/^\d+\.\d+\.\d+$/.test(tag)) return tag;
17750
+ }
17751
+ } catch {
17752
+ }
17753
+ return FALLBACK_GLAB_VERSION;
17754
+ }
17755
+ async function ensureGlabCli(runner, deps = {}) {
17756
+ if (runner.which("glab")) return "glab";
17757
+ const arch2 = ghArch();
17758
+ const platform3 = process.platform;
17759
+ if (arch2 === null || platform3 !== "linux" && platform3 !== "darwin" && platform3 !== "win32") {
17760
+ log.warn("host-agent", `glab auto-install unsupported on ${platform3}/${process.arch} \u2014 skipping`);
17761
+ return null;
17762
+ }
17763
+ const osToken = platform3 === "darwin" ? "darwin" : platform3 === "win32" ? "windows" : "linux";
17764
+ const ext = platform3 === "win32" ? "zip" : "tar.gz";
17765
+ const binaryName = platform3 === "win32" ? "glab.exe" : "glab";
17766
+ const downloadFn = deps.downloadFn ?? download;
17767
+ try {
17768
+ const version3 = await resolveLatestGlabVersion();
17769
+ const asset = `glab_${version3}_${osToken}_${arch2}`;
17770
+ const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
17771
+ const tmpRoot = fs38.mkdtempSync(path42.join(os34.tmpdir(), "codeam-glab-"));
17772
+ const archive = path42.join(tmpRoot, `${asset}.${ext}`);
17773
+ if (!await downloadFn(url2, archive)) {
17774
+ log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
17775
+ return null;
17776
+ }
17777
+ const extract = await runner.run("tar", ["-xf", archive, "-C", tmpRoot], { timeoutMs: 6e4 });
17778
+ if (extract.code !== 0) {
17779
+ log.warn("host-agent", `glab archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
17780
+ return null;
17781
+ }
17782
+ const candidates = [
17783
+ path42.join(tmpRoot, "bin", binaryName),
17784
+ path42.join(tmpRoot, asset, "bin", binaryName),
17785
+ path42.join(tmpRoot, binaryName)
17786
+ ];
17787
+ const extractedBin = candidates.find((c2) => fs38.existsSync(c2));
17788
+ if (!extractedBin) {
17789
+ log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
17790
+ return null;
17791
+ }
17792
+ const binDir = codeamBinDir();
17793
+ fs38.mkdirSync(binDir, { recursive: true });
17794
+ const target = path42.join(binDir, binaryName);
17795
+ fs38.copyFileSync(extractedBin, target);
17796
+ fs38.chmodSync(target, 493);
17797
+ log.info("host-agent", `glab installed to ${target} (v${version3})`);
17798
+ return target;
17799
+ } catch (e) {
17800
+ log.warn("host-agent", `glab auto-install errored: ${e instanceof Error ? e.message : String(e)} \u2014 skipping`);
17801
+ return null;
17802
+ }
17803
+ }
17804
+ async function ensureGlabAuth(runner, glabCmd, token) {
17805
+ if (!token) return;
17806
+ try {
17807
+ const status2 = await runner.run(glabCmd, ["auth", "status"], { timeoutMs: 15e3 });
17808
+ if (status2.code === 0) {
17809
+ log.info("host-agent", "glab already authenticated \u2014 leaving the existing login untouched");
17810
+ return;
17811
+ }
17812
+ const login = await runner.run(
17813
+ glabCmd,
17814
+ ["auth", "login", "--hostname", "gitlab.com", "--stdin"],
17815
+ { timeoutMs: 2e4, input: `${token}
17816
+ ` }
17817
+ );
17818
+ if (login.code === 0) {
17819
+ log.info("host-agent", "glab authenticated with the linked GitLab token");
17820
+ } else {
17821
+ log.warn("host-agent", `glab auth login failed (code=${String(login.code)}) \u2014 glab unauthenticated`);
17822
+ }
17823
+ } catch (e) {
17824
+ log.warn("host-agent", `glab auth errored: ${e instanceof Error ? e.message : String(e)}`);
17825
+ }
17826
+ }
17725
17827
  var defaultGitToolingRunner = {
17726
17828
  which(cmd) {
17727
17829
  try {
@@ -18181,6 +18283,7 @@ async function ensureModernPython(runner) {
18181
18283
  // src/commands/host/headroom-bootstrap.ts
18182
18284
  var fs40 = __toESM(require("fs"));
18183
18285
  var path44 = __toESM(require("path"));
18286
+ var os36 = __toESM(require("os"));
18184
18287
 
18185
18288
  // src/commands/host/headroom-config.ts
18186
18289
  var fs39 = __toESM(require("fs"));
@@ -18321,6 +18424,15 @@ async function getFreeDiskBytes(dir) {
18321
18424
  return null;
18322
18425
  }
18323
18426
  }
18427
+ function headroomModelsCached() {
18428
+ const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path44.join(
18429
+ process.env.HF_HOME || path44.join(os36.homedir(), ".cache", "huggingface"),
18430
+ "hub"
18431
+ );
18432
+ return HEADROOM_MODELS.every(
18433
+ (m) => fs40.existsSync(path44.join(hubDir, `models--${m.repo.replace("/", "--")}`))
18434
+ );
18435
+ }
18324
18436
  async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
18325
18437
  const extras = opts.extras ?? [...HEADROOM_EXTRAS_BY_SURFACE.selfHosted];
18326
18438
  const onProgress = opts.onProgress ?? (() => {
@@ -18349,23 +18461,33 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
18349
18461
  }
18350
18462
  return false;
18351
18463
  };
18352
- onProgress("pip");
18353
- const headroomPkg = headroomPipPackage(extras);
18354
- const installOk = await pipInstall([headroomPkg, ...SERVER_DEPS], [], ENGINE_INSTALL_TIMEOUT_MS);
18355
- if (!installOk) {
18356
- log.warn("host-agent", `headroom engine install failed (${headroomPkg}) \u2014 skipping Headroom`);
18357
- return false;
18464
+ const modelsCached = opts.modelsCached ?? headroomModelsCached;
18465
+ if (runner.which("headroom") !== null && modelsCached()) {
18466
+ log.info(
18467
+ "host-agent",
18468
+ "headroom + Kompress model already present (baked image) \u2014 skipping pip install + model download"
18469
+ );
18470
+ onProgress("pip");
18471
+ onProgress("model");
18472
+ } else {
18473
+ onProgress("pip");
18474
+ const headroomPkg = headroomPipPackage(extras);
18475
+ const installOk = await pipInstall([headroomPkg, ...SERVER_DEPS], [], ENGINE_INSTALL_TIMEOUT_MS);
18476
+ if (!installOk) {
18477
+ log.warn("host-agent", `headroom engine install failed (${headroomPkg}) \u2014 skipping Headroom`);
18478
+ return false;
18479
+ }
18480
+ log.info("host-agent", `headroom + ONNX engines installed (${headroomPkg})`);
18481
+ onProgress("model");
18482
+ const predownloadPy = headroomModelPredownloadScript();
18483
+ const dl = await runner.run(py, ["-c", predownloadPy], {
18484
+ timeoutMs: ENGINE_INSTALL_TIMEOUT_MS
18485
+ });
18486
+ log.info(
18487
+ "host-agent",
18488
+ dl.code === 0 ? "Kompress model pre-downloaded \u2014 first prompt will be fast" : "Kompress model pre-download failed (best-effort) \u2014 first prompt may be slow"
18489
+ );
18358
18490
  }
18359
- log.info("host-agent", `headroom + ONNX engines installed (${headroomPkg})`);
18360
- onProgress("model");
18361
- const predownloadPy = headroomModelPredownloadScript();
18362
- const dl = await runner.run(py, ["-c", predownloadPy], {
18363
- timeoutMs: ENGINE_INSTALL_TIMEOUT_MS
18364
- });
18365
- log.info(
18366
- "host-agent",
18367
- dl.code === 0 ? "Kompress model pre-downloaded \u2014 first prompt will be fast" : "Kompress model pre-download failed (best-effort) \u2014 first prompt may be slow"
18368
- );
18369
18491
  if (!runner.which("headroom")) {
18370
18492
  log.warn("host-agent", "headroom not found on PATH after install \u2014 skipping init");
18371
18493
  return false;
@@ -18413,7 +18535,7 @@ var import_node_child_process22 = require("child_process");
18413
18535
 
18414
18536
  // src/lib/updateNotifier.ts
18415
18537
  var fs41 = __toESM(require("fs"));
18416
- var os36 = __toESM(require("os"));
18538
+ var os37 = __toESM(require("os"));
18417
18539
  var path45 = __toESM(require("path"));
18418
18540
  var https6 = __toESM(require("https"));
18419
18541
  var import_node_child_process21 = require("child_process");
@@ -18423,7 +18545,7 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
18423
18545
  var TTL_MS = 24 * 60 * 60 * 1e3;
18424
18546
  var REQUEST_TIMEOUT_MS = 1500;
18425
18547
  function cachePath() {
18426
- const dir = path45.join(os36.homedir(), ".codeam");
18548
+ const dir = path45.join(os37.homedir(), ".codeam");
18427
18549
  return path45.join(dir, "update-check.json");
18428
18550
  }
18429
18551
  function readCache() {
@@ -18569,7 +18691,7 @@ async function autoUpgradeBeforeCriticalCommand() {
18569
18691
  if (process.env.NODE_ENV === "test") return;
18570
18692
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
18571
18693
  if (process.env.CI) return;
18572
- const current = true ? "2.61.32" : null;
18694
+ const current = true ? "2.61.34" : null;
18573
18695
  if (!current) return;
18574
18696
  const cache = readCache();
18575
18697
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -18586,7 +18708,7 @@ function checkForUpdates() {
18586
18708
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
18587
18709
  if (process.env.CI) return;
18588
18710
  if (!process.stdout.isTTY) return;
18589
- const current = true ? "2.61.32" : null;
18711
+ const current = true ? "2.61.34" : null;
18590
18712
  if (!current) return;
18591
18713
  const cache = readCache();
18592
18714
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -18606,7 +18728,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
18606
18728
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
18607
18729
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
18608
18730
  function currentCliVersion() {
18609
- return true ? "2.61.32" : null;
18731
+ return true ? "2.61.34" : null;
18610
18732
  }
18611
18733
  function runCmd(cmd, args2, timeoutMs) {
18612
18734
  return new Promise((resolve8) => {
@@ -18815,6 +18937,9 @@ function isDeployPayload(p2) {
18815
18937
  if (p2.cloneToken !== void 0 && typeof p2.cloneToken !== "string") {
18816
18938
  return false;
18817
18939
  }
18940
+ if (p2.repoProvider !== void 0 && p2.repoProvider !== "github" && p2.repoProvider !== "gitlab") {
18941
+ return false;
18942
+ }
18818
18943
  if (p2.headroomEnabled !== void 0 && typeof p2.headroomEnabled !== "boolean") {
18819
18944
  return false;
18820
18945
  }
@@ -19257,7 +19382,7 @@ var HostAgentSupervisor = class {
19257
19382
  const relay = this.relay;
19258
19383
  if (!relay) return;
19259
19384
  const raw = cmd.payload?.path;
19260
- const target = typeof raw === "string" && raw.trim() ? path46.resolve(raw.trim()) : os37.homedir();
19385
+ const target = typeof raw === "string" && raw.trim() ? path46.resolve(raw.trim()) : os38.homedir();
19261
19386
  try {
19262
19387
  const dirents = await fs43.promises.readdir(target, { withFileTypes: true });
19263
19388
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
@@ -19463,7 +19588,12 @@ var HostAgentSupervisor = class {
19463
19588
  if (!isAbsolutePathTarget(payload.repoOrPath)) {
19464
19589
  report("cloning", "cloning repository");
19465
19590
  }
19466
- const cwd = await prepareWorkspace(payload.repoOrPath, payload.deployId, payload.cloneToken);
19591
+ const cwd = await prepareWorkspace(
19592
+ payload.repoOrPath,
19593
+ payload.deployId,
19594
+ payload.cloneToken,
19595
+ payload.repoProvider ?? "github"
19596
+ );
19467
19597
  let childEnv;
19468
19598
  let extraArgs = [];
19469
19599
  if (payload.houseProxy) {
@@ -19479,7 +19609,7 @@ var HostAgentSupervisor = class {
19479
19609
  API_TIMEOUT_MS: "3000000",
19480
19610
  CODEAM_AUTO_TOKEN: payload.autoPairToken
19481
19611
  };
19482
- const houseConfigDir = path46.join(os37.homedir(), ".codeam", "house-claude");
19612
+ const houseConfigDir = path46.join(os38.homedir(), ".codeam", "house-claude");
19483
19613
  try {
19484
19614
  fs43.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
19485
19615
  } catch {
@@ -19499,20 +19629,28 @@ var HostAgentSupervisor = class {
19499
19629
  report("installing", "installing agent CLI");
19500
19630
  await this.runAgentInstall(payload.agentInstallScript);
19501
19631
  }
19502
- const home = process.env.HOME || os37.homedir();
19632
+ const home = process.env.HOME || os38.homedir();
19503
19633
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
19504
19634
  if (payload.cloneToken) {
19505
19635
  try {
19506
19636
  report("preparing", "configuring git tooling");
19507
- const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
19508
- if (ghCmd) {
19509
- childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
19510
- await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
19637
+ if ((payload.repoProvider ?? "github") === "gitlab") {
19638
+ const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
19639
+ if (glabCmd) {
19640
+ childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
19641
+ await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
19642
+ }
19643
+ } else {
19644
+ const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
19645
+ if (ghCmd) {
19646
+ childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
19647
+ await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
19648
+ }
19511
19649
  }
19512
19650
  } catch (e) {
19513
19651
  log.warn(
19514
19652
  "host-agent",
19515
- `gh tooling setup skipped: ${e instanceof Error ? e.message : String(e)}`
19653
+ `git tooling setup skipped: ${e instanceof Error ? e.message : String(e)}`
19516
19654
  );
19517
19655
  }
19518
19656
  }
@@ -19522,7 +19660,7 @@ var HostAgentSupervisor = class {
19522
19660
  }
19523
19661
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
19524
19662
  report("headroom", "setting up Headroom proxy");
19525
- const freeBytes = await this.getFreeDisk(os37.homedir());
19663
+ const freeBytes = await this.getFreeDisk(os38.homedir());
19526
19664
  const alreadyInstalled = this.isHeadroomInstalled();
19527
19665
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
19528
19666
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -19706,7 +19844,7 @@ var HostAgentSupervisor = class {
19706
19844
  */
19707
19845
  runAgentInstall(script) {
19708
19846
  return new Promise((resolve8) => {
19709
- const home = process.env.HOME || os37.homedir();
19847
+ const home = process.env.HOME || os38.homedir();
19710
19848
  const child = (0, import_node_child_process24.spawn)("sh", ["-c", script], {
19711
19849
  env: { ...process.env, HOME: home },
19712
19850
  stdio: ["ignore", "pipe", "pipe"]
@@ -19899,7 +20037,7 @@ async function configureHeadroom(action, ctx, deps) {
19899
20037
 
19900
20038
  // src/services/headroom/budget-relaunch.ts
19901
20039
  var fs44 = __toESM(require("fs"));
19902
- var os38 = __toESM(require("os"));
20040
+ var os39 = __toESM(require("os"));
19903
20041
  var path47 = __toESM(require("path"));
19904
20042
  var import_child_process13 = require("child_process");
19905
20043
  function amendDeploymentManifestBudget(manifest, budget) {
@@ -20006,7 +20144,7 @@ function spawnProxyReal2(_budget) {
20006
20144
  });
20007
20145
  }
20008
20146
  function makeRealApplyBudgetDeps() {
20009
- const homeDir2 = os38.homedir();
20147
+ const homeDir2 = os39.homedir();
20010
20148
  return {
20011
20149
  findDeployments: () => findHeadroomDeployments(homeDir2, {
20012
20150
  readDir: (dir) => fs44.readdirSync(dir),
@@ -20021,11 +20159,11 @@ function makeRealApplyBudgetDeps() {
20021
20159
 
20022
20160
  // src/services/preview/port-registry.ts
20023
20161
  var fs45 = __toESM(require("fs"));
20024
- var os39 = __toESM(require("os"));
20162
+ var os40 = __toESM(require("os"));
20025
20163
  var path48 = __toESM(require("path"));
20026
20164
  var import_child_process14 = require("child_process");
20027
20165
  function registryPath() {
20028
- return path48.join(os39.homedir(), ".codeam", "preview-ports.json");
20166
+ return path48.join(os40.homedir(), ".codeam", "preview-ports.json");
20029
20167
  }
20030
20168
  function readRegistry() {
20031
20169
  try {
@@ -21212,7 +21350,7 @@ async function establishTunnel(ctx, dev) {
21212
21350
  // src/beads/bd-adapter.ts
21213
21351
  var import_child_process19 = require("child_process");
21214
21352
  var fs51 = __toESM(require("fs"));
21215
- var os41 = __toESM(require("os"));
21353
+ var os42 = __toESM(require("os"));
21216
21354
  var path54 = __toESM(require("path"));
21217
21355
  var BD_PACKAGE = "@beads/bd";
21218
21356
  function resolveBundledBdBinary() {
@@ -21330,7 +21468,7 @@ var BdAdapter = class {
21330
21468
  const env = { ...process.env };
21331
21469
  if (!env.HOME) {
21332
21470
  try {
21333
- const home = os41.homedir();
21471
+ const home = os42.homedir();
21334
21472
  if (home) env.HOME = home;
21335
21473
  } catch {
21336
21474
  }
@@ -21423,7 +21561,7 @@ function coerceIssue(row, projectKey) {
21423
21561
  // src/beads/provisioner.ts
21424
21562
  var import_child_process23 = require("child_process");
21425
21563
  var fs54 = __toESM(require("fs"));
21426
- var os43 = __toESM(require("os"));
21564
+ var os44 = __toESM(require("os"));
21427
21565
  var path57 = __toESM(require("path"));
21428
21566
 
21429
21567
  // src/beads/install-bd.ts
@@ -21490,7 +21628,7 @@ async function installBd(platform3 = process.platform) {
21490
21628
  // src/beads/install-dolt.ts
21491
21629
  var import_child_process21 = require("child_process");
21492
21630
  var fs52 = __toESM(require("fs"));
21493
- var os42 = __toESM(require("os"));
21631
+ var os43 = __toESM(require("os"));
21494
21632
  var path55 = __toESM(require("path"));
21495
21633
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
21496
21634
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
@@ -21531,11 +21669,11 @@ function resolveDoltInstallStrategy(platform3) {
21531
21669
  }
21532
21670
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
21533
21671
  function doltPlatformTuple(platform3, arch2) {
21534
- const os57 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
21672
+ const os58 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
21535
21673
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
21536
21674
  if (!a) return null;
21537
- if (os57 === "windows" && a !== "amd64") return null;
21538
- return `${os57}-${a}`;
21675
+ if (os58 === "windows" && a !== "amd64") return null;
21676
+ return `${os58}-${a}`;
21539
21677
  }
21540
21678
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
21541
21679
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -21580,7 +21718,7 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
21580
21718
  return result;
21581
21719
  }
21582
21720
  var _doltPathSeam = {
21583
- homedir: () => os42.homedir(),
21721
+ homedir: () => os43.homedir(),
21584
21722
  getPath: () => process.env.PATH ?? "",
21585
21723
  setPath: (p2) => {
21586
21724
  process.env.PATH = p2;
@@ -21872,7 +22010,7 @@ var _provisionSeam = {
21872
22010
  };
21873
22011
  var _linkSeam = {
21874
22012
  platform: () => process.platform,
21875
- homedir: () => os43.homedir(),
22013
+ homedir: () => os44.homedir(),
21876
22014
  isWritableDir: (dir) => {
21877
22015
  try {
21878
22016
  fs54.accessSync(dir, fs54.constants.W_OK);
@@ -22667,7 +22805,7 @@ function cleanupAttachmentTempFiles() {
22667
22805
  function saveFilesTemp(files) {
22668
22806
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
22669
22807
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
22670
- const tmpPath = path61.join(os47.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
22808
+ const tmpPath = path61.join(os48.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
22671
22809
  fs57.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
22672
22810
  pendingAttachmentFiles.add(tmpPath);
22673
22811
  return tmpPath;
@@ -23260,7 +23398,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
23260
23398
  });
23261
23399
  const token = ctx.pluginAuthToken;
23262
23400
  void (async () => {
23263
- const os57 = createOsStrategy();
23401
+ const os58 = createOsStrategy();
23264
23402
  try {
23265
23403
  const report = await reviewPullRequest(
23266
23404
  {
@@ -23269,7 +23407,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
23269
23407
  baseBranch: parsed.baseBranch
23270
23408
  },
23271
23409
  {
23272
- runReview: (input) => new CoderabbitRuntimeStrategy(os57).runOneShot(input),
23410
+ runReview: (input) => new CoderabbitRuntimeStrategy(os58).runOneShot(input),
23273
23411
  runGh: (args2) => defaultRunGh(args2),
23274
23412
  postReport: async (r) => {
23275
23413
  if (!token) return;
@@ -24328,7 +24466,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
24328
24466
  pluginId,
24329
24467
  ideName: "codeam-cli (codespace)",
24330
24468
  ideVersion: process.env.npm_package_version ?? "unknown",
24331
- hostname: os48.hostname(),
24469
+ hostname: os49.hostname(),
24332
24470
  codespaceName: process.env.CODESPACE_NAME ?? "",
24333
24471
  // Current git branch of the codespace's working directory, so the
24334
24472
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -24389,7 +24527,7 @@ async function claim(token, pluginId, pluginSecretHash) {
24389
24527
  }
24390
24528
  }
24391
24529
  function pairAutoLockPath() {
24392
- return path62.join(os48.homedir(), ".codeam", "pair-auto.lock");
24530
+ return path62.join(os49.homedir(), ".codeam", "pair-auto.lock");
24393
24531
  }
24394
24532
  function isLivePairAuto(pid) {
24395
24533
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -24409,7 +24547,7 @@ function isLiveCodeam(pid) {
24409
24547
  }
24410
24548
  function daemonLockPath(sessionId) {
24411
24549
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
24412
- return path62.join(os48.homedir(), ".codeam", `daemon-${safe}.lock`);
24550
+ return path62.join(os49.homedir(), ".codeam", `daemon-${safe}.lock`);
24413
24551
  }
24414
24552
  function acquireDaemonLock(sessionId) {
24415
24553
  const lockPath = daemonLockPath(sessionId);
@@ -25292,7 +25430,7 @@ var import_node_crypto11 = require("crypto");
25292
25430
  // src/services/history.service.ts
25293
25431
  var fs60 = __toESM(require("fs"));
25294
25432
  var path65 = __toESM(require("path"));
25295
- var os50 = __toESM(require("os"));
25433
+ var os51 = __toESM(require("os"));
25296
25434
  var https7 = __toESM(require("https"));
25297
25435
  var http6 = __toESM(require("http"));
25298
25436
  var import_zod2 = require("zod");
@@ -25460,7 +25598,7 @@ var HistoryService = class _HistoryService {
25460
25598
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
25461
25599
  }
25462
25600
  get projectDir() {
25463
- return this.runtime.resolveHistoryDir(this.cwd) ?? path65.join(os50.homedir(), ".claude", "projects", encodeCwd(this.cwd));
25601
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path65.join(os51.homedir(), ".claude", "projects", encodeCwd(this.cwd));
25464
25602
  }
25465
25603
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
25466
25604
  setCurrentConversationId(id) {
@@ -25888,7 +26026,7 @@ var HistoryService = class _HistoryService {
25888
26026
  var import_node_child_process27 = require("child_process");
25889
26027
  var fs61 = __toESM(require("fs/promises"));
25890
26028
  var fsSync = __toESM(require("fs"));
25891
- var os51 = __toESM(require("os"));
26029
+ var os52 = __toESM(require("os"));
25892
26030
  var path66 = __toESM(require("path"));
25893
26031
  var import_node_stream = require("stream");
25894
26032
 
@@ -30754,7 +30892,7 @@ function applyLineRange(content, line, limit) {
30754
30892
  return { content: lines.slice(start2, end).join("\n") };
30755
30893
  }
30756
30894
  function knownAgentBinaryDirs() {
30757
- const home = os51.homedir();
30895
+ const home = os52.homedir();
30758
30896
  const out2 = [];
30759
30897
  out2.push("/tmp/codeam-node20/bin");
30760
30898
  for (const root of [
@@ -31281,10 +31419,10 @@ function commonPrefixLength(a, b) {
31281
31419
  // src/agents/acp/onboarding.ts
31282
31420
  var import_child_process27 = require("child_process");
31283
31421
  var fs62 = __toESM(require("fs"));
31284
- var os52 = __toESM(require("os"));
31422
+ var os53 = __toESM(require("os"));
31285
31423
  var path67 = __toESM(require("path"));
31286
31424
  var _onboardingSeam = {
31287
- markerPath: (sessionId) => path67.join(os52.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
31425
+ markerPath: (sessionId) => path67.join(os53.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
31288
31426
  exists: (p2) => fs62.existsSync(p2),
31289
31427
  write: (p2) => {
31290
31428
  fs62.mkdirSync(path67.dirname(p2), { recursive: true });
@@ -35634,12 +35772,12 @@ function toEpochMs(ts) {
35634
35772
 
35635
35773
  // src/agents/claude/onboarding.ts
35636
35774
  var fs67 = __toESM(require("fs"));
35637
- var os54 = __toESM(require("os"));
35775
+ var os55 = __toESM(require("os"));
35638
35776
  var path71 = __toESM(require("path"));
35639
35777
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
35640
35778
  function ensureClaudeOnboarded(cwd) {
35641
35779
  try {
35642
- const file = path71.join(os54.homedir(), ".claude.json");
35780
+ const file = path71.join(os55.homedir(), ".claude.json");
35643
35781
  let config = {};
35644
35782
  try {
35645
35783
  config = JSON.parse(fs67.readFileSync(file, "utf8"));
@@ -38533,9 +38671,9 @@ function checkSessions() {
38533
38671
  }
38534
38672
  }
38535
38673
  function checkAgentBinaries() {
38536
- const os57 = createOsStrategy();
38674
+ const os58 = createOsStrategy();
38537
38675
  return getEnabledAgents().map((meta) => {
38538
- const found = os57.findInPath(meta.binaryName);
38676
+ const found = os58.findInPath(meta.binaryName);
38539
38677
  return {
38540
38678
  id: `agent-${meta.id}`,
38541
38679
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -38599,7 +38737,7 @@ function checkChokidar() {
38599
38737
  }
38600
38738
  async function doctor(args2 = []) {
38601
38739
  const json = args2.includes("--json");
38602
- const cliVersion = true ? "2.61.32" : "0.0.0-dev";
38740
+ const cliVersion = true ? "2.61.34" : "0.0.0-dev";
38603
38741
  const apiBase2 = resolveApiBaseUrl();
38604
38742
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
38605
38743
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -39110,7 +39248,7 @@ async function mcpRun(args2) {
39110
39248
  // src/commands/version.ts
39111
39249
  var import_picocolors15 = __toESM(require("picocolors"));
39112
39250
  function version2() {
39113
- const v = true ? "2.61.32" : "unknown";
39251
+ const v = true ? "2.61.34" : "unknown";
39114
39252
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
39115
39253
  }
39116
39254
 
@@ -39259,10 +39397,10 @@ var EXIT_CODE_NAMES = {
39259
39397
  };
39260
39398
 
39261
39399
  // src/index.ts
39262
- var os56 = __toESM(require("os"));
39400
+ var os57 = __toESM(require("os"));
39263
39401
  if (!process.env.HOME) {
39264
39402
  try {
39265
- const home = os56.homedir();
39403
+ const home = os57.homedir();
39266
39404
  if (home) process.env.HOME = home;
39267
39405
  } catch {
39268
39406
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.61.32",
3
+ "version": "2.61.34",
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",
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- // src/postinstall.ts
5
- var c = {
6
- reset: "\x1B[0m",
7
- bold: "\x1B[1m",
8
- dim: "\x1B[2m",
9
- green: "\x1B[32m",
10
- cyan: "\x1B[36m",
11
- violet: "\x1B[35m",
12
- white: "\x1B[97m"
13
- };
14
- var lines = [
15
- "",
16
- ` ${c.violet}${c.bold}codeam-cli${c.reset} ${c.dim}\u2014 Claude Code remote control${c.reset}`,
17
- "",
18
- ` ${c.dim}1.${c.reset} Pair your phone:`,
19
- ` ${c.cyan}codeam pair${c.reset}`,
20
- "",
21
- ` ${c.dim}2.${c.reset} Launch Claude Code with mobile control:`,
22
- ` ${c.cyan}codeam${c.reset}`,
23
- "",
24
- ` ${c.dim}Other commands:${c.reset}`,
25
- ` ${c.white}codeam sessions${c.reset} ${c.dim}list paired devices${c.reset}`,
26
- ` ${c.white}codeam status${c.reset} ${c.dim}show connection info${c.reset}`,
27
- ` ${c.white}codeam logout${c.reset} ${c.dim}remove all sessions${c.reset}`,
28
- "",
29
- ` ${c.dim}Requires Claude Code:${c.reset} ${c.green}npm install -g @anthropic-ai/claude-code${c.reset}`,
30
- ` ${c.dim}Mobile app:${c.reset} ${c.green}https://www.codeagent-mobile.com${c.reset}`,
31
- ""
32
- ];
33
- process.stdout.write(lines.join("\n") + "\n");