codeam-cli 2.60.41 → 2.60.42

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.60.41] — 2026-07-10
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Surface a clean error when a CodeRabbit review times out
12
+
7
13
  ## [2.60.40] — 2026-07-10
8
14
 
9
15
  ### Added
package/dist/index.js CHANGED
@@ -5689,7 +5689,7 @@ function readAnonId() {
5689
5689
  }
5690
5690
  function superProperties() {
5691
5691
  return {
5692
- cliVersion: true ? "2.60.41" : "0.0.0-dev",
5692
+ cliVersion: true ? "2.60.42" : "0.0.0-dev",
5693
5693
  nodeVersion: process.version,
5694
5694
  platform: process.platform,
5695
5695
  arch: process.arch,
@@ -5870,7 +5870,7 @@ var os4 = __toESM(require("os"));
5870
5870
  // package.json
5871
5871
  var package_default = {
5872
5872
  name: "codeam-cli",
5873
- version: "2.60.41",
5873
+ version: "2.60.42",
5874
5874
  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.",
5875
5875
  type: "commonjs",
5876
5876
  main: "dist/index.js",
@@ -6196,6 +6196,22 @@ async function postHeadroomEvent(input) {
6196
6196
  };
6197
6197
  }
6198
6198
  }
6199
+ async function fetchProvisionCredential(input) {
6200
+ try {
6201
+ const res = await _transport.postJsonAuthed(
6202
+ `${API_BASE}/api/plugin/agents/${input.agentId}/provision-credential`,
6203
+ { sessionId: input.sessionId, pluginId: input.pluginId },
6204
+ input.pluginAuthToken
6205
+ );
6206
+ const data = res?.data;
6207
+ if (data && (data.method === "api_key" || data.method === "oauth") && typeof data.credential === "string" && data.credential.length > 0) {
6208
+ return { method: data.method, credential: data.credential };
6209
+ }
6210
+ return null;
6211
+ } catch {
6212
+ return null;
6213
+ }
6214
+ }
6199
6215
  async function postCoderabbitEvent(input) {
6200
6216
  try {
6201
6217
  await _transport.postJsonAuthed(
@@ -6963,7 +6979,7 @@ var CommandRelayService = class {
6963
6979
  // fresh + clear the "CLI update available" banner after a self-update
6964
6980
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
6965
6981
  // pair/reconnect). Older backends ignore the extra field.
6966
- ..."2.60.41" ? { ideVersion: "2.60.41" } : {}
6982
+ ..."2.60.42" ? { ideVersion: "2.60.42" } : {}
6967
6983
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
6968
6984
  }
6969
6985
  /**
@@ -7190,10 +7206,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
7190
7206
  /[\\/]Start Menu([\\/]|$)/i,
7191
7207
  /[\\/]Templates([\\/]|$)/i
7192
7208
  ];
7193
- function isUnsafeWindowsWatchRoot(dir, homedir42) {
7209
+ function isUnsafeWindowsWatchRoot(dir, homedir43) {
7194
7210
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
7195
7211
  const cwd = norm(dir);
7196
- const home = norm(homedir42);
7212
+ const home = norm(homedir43);
7197
7213
  if (cwd === home) return true;
7198
7214
  if (/^[a-z]:$/.test(cwd)) return true;
7199
7215
  const sysRoots = [
@@ -8414,6 +8430,9 @@ var startCommandSchema = import_zod.z.object({
8414
8430
  // loopback so a remote-host `link_oauth` login completes (session-relay).
8415
8431
  "link_deliver_callback",
8416
8432
  "link_apikey",
8433
+ // Restore the caller's already-vaulted CodeRabbit credential onto this
8434
+ // session (no re-login) — fetches from the backend + installs + writes it.
8435
+ "provision",
8417
8436
  "review"
8418
8437
  ]).optional(),
8419
8438
  // `headroom_configure` — savings ingest URL delivered from the session
@@ -15489,6 +15508,8 @@ async function linkDryRunPreflight(ctx) {
15489
15508
 
15490
15509
  // src/agents/coderabbit/configure.ts
15491
15510
  var import_node_child_process15 = require("child_process");
15511
+ var import_node_os4 = require("os");
15512
+ var import_node_fs5 = require("fs");
15492
15513
  var path36 = __toESM(require("path"));
15493
15514
 
15494
15515
  // src/agents/coderabbit/oauth.ts
@@ -15760,6 +15781,23 @@ function collectChangedFiles(cwd) {
15760
15781
  }
15761
15782
  return [...byPath.values()];
15762
15783
  }
15784
+ function restoreCoderabbitOauthBlob(value) {
15785
+ const dir = path36.join((0, import_node_os4.homedir)(), ".coderabbit");
15786
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
15787
+ let file = "auth.json";
15788
+ let contents = value.trim();
15789
+ if (contents.startsWith("{")) {
15790
+ try {
15791
+ const parsed = JSON.parse(contents);
15792
+ if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
15793
+ file = path36.basename(parsed.file);
15794
+ contents = parsed.contents;
15795
+ }
15796
+ } catch {
15797
+ }
15798
+ }
15799
+ (0, import_node_fs5.writeFileSync)(path36.join(dir, file), contents, { mode: 384 });
15800
+ }
15763
15801
  async function configureCoderabbit(input, deps = {}) {
15764
15802
  const os50 = deps.os ?? createOsStrategy();
15765
15803
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
@@ -15810,6 +15848,40 @@ async function configureCoderabbit(input, deps = {}) {
15810
15848
  ...stored ? {} : { error: "Signed in, but storing the API key for reuse failed" }
15811
15849
  };
15812
15850
  }
15851
+ if (input.action === "provision") {
15852
+ const res2 = base();
15853
+ const cred = input.provisionCredential;
15854
+ if (!cred || !cred.credential.trim()) {
15855
+ return { ...res2, error: "No vaulted CodeRabbit credential to provision" };
15856
+ }
15857
+ if (!res2.installed) {
15858
+ deps.onEvent?.({ kind: "installing" });
15859
+ const ok = await ensureInstalled(os50);
15860
+ res2.installed = ok;
15861
+ if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
15862
+ }
15863
+ if (cred.method === "api_key") {
15864
+ const login = loginWithApiKey(cred.credential.trim());
15865
+ if (!login.ok) {
15866
+ return {
15867
+ ...res2,
15868
+ loggedIn: false,
15869
+ linked: false,
15870
+ error: login.error ?? "The vaulted CodeRabbit API key was rejected \u2014 re-link it."
15871
+ };
15872
+ }
15873
+ return { ...res2, loggedIn: true, linked: true };
15874
+ }
15875
+ try {
15876
+ restoreCoderabbitOauthBlob(cred.credential);
15877
+ } catch (err) {
15878
+ return {
15879
+ ...res2,
15880
+ error: err instanceof Error ? err.message : "Failed to restore the vaulted credential"
15881
+ };
15882
+ }
15883
+ return { ...res2, loggedIn: true, linked: true };
15884
+ }
15813
15885
  if (input.action === "link_oauth") {
15814
15886
  const res2 = base();
15815
15887
  if (!installed) {
@@ -15890,8 +15962,8 @@ var os29 = __toESM(require("os"));
15890
15962
  var path37 = __toESM(require("path"));
15891
15963
 
15892
15964
  // src/lib/restrict-to-owner.ts
15893
- var import_node_fs5 = __toESM(require("fs"));
15894
- var import_node_os4 = __toESM(require("os"));
15965
+ var import_node_fs6 = __toESM(require("fs"));
15966
+ var import_node_os5 = __toESM(require("os"));
15895
15967
  var import_node_child_process16 = require("child_process");
15896
15968
  var BROAD_WINDOWS_SIDS = [
15897
15969
  "*S-1-1-0",
@@ -15903,7 +15975,7 @@ var BROAD_WINDOWS_SIDS = [
15903
15975
  function restrictToOwner(filePath) {
15904
15976
  try {
15905
15977
  if (process.platform === "win32") {
15906
- const username = import_node_os4.default.userInfo().username;
15978
+ const username = import_node_os5.default.userInfo().username;
15907
15979
  (0, import_node_child_process16.execFileSync)(
15908
15980
  "icacls",
15909
15981
  [
@@ -15916,7 +15988,7 @@ function restrictToOwner(filePath) {
15916
15988
  { stdio: "ignore" }
15917
15989
  );
15918
15990
  } else {
15919
- import_node_fs5.default.chmodSync(filePath, 384);
15991
+ import_node_fs6.default.chmodSync(filePath, 384);
15920
15992
  }
15921
15993
  } catch {
15922
15994
  }
@@ -17421,7 +17493,7 @@ async function autoUpgradeBeforeCriticalCommand() {
17421
17493
  if (process.env.NODE_ENV === "test") return;
17422
17494
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17423
17495
  if (process.env.CI) return;
17424
- const current = true ? "2.60.41" : null;
17496
+ const current = true ? "2.60.42" : null;
17425
17497
  if (!current) return;
17426
17498
  const cache = readCache();
17427
17499
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17438,7 +17510,7 @@ function checkForUpdates() {
17438
17510
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17439
17511
  if (process.env.CI) return;
17440
17512
  if (!process.stdout.isTTY) return;
17441
- const current = true ? "2.60.41" : null;
17513
+ const current = true ? "2.60.42" : null;
17442
17514
  if (!current) return;
17443
17515
  const cache = readCache();
17444
17516
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17458,7 +17530,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
17458
17530
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
17459
17531
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
17460
17532
  function currentCliVersion() {
17461
- return true ? "2.60.41" : null;
17533
+ return true ? "2.60.42" : null;
17462
17534
  }
17463
17535
  function runCmd(cmd, args2, timeoutMs) {
17464
17536
  return new Promise((resolve7) => {
@@ -20776,15 +20848,15 @@ async function handleBeadsActionCommand(action, started) {
20776
20848
  }
20777
20849
 
20778
20850
  // src/beads/config-store.ts
20779
- var import_node_fs6 = __toESM(require("fs"));
20780
- var import_node_os5 = __toESM(require("os"));
20851
+ var import_node_fs7 = __toESM(require("fs"));
20852
+ var import_node_os6 = __toESM(require("os"));
20781
20853
  var import_node_path5 = __toESM(require("path"));
20782
20854
  function beadsConfigPath() {
20783
- return import_node_path5.default.join(import_node_os5.default.homedir(), ".codeam", "beads-config.json");
20855
+ return import_node_path5.default.join(import_node_os6.default.homedir(), ".codeam", "beads-config.json");
20784
20856
  }
20785
20857
  function readBeadsEnabled() {
20786
20858
  try {
20787
- const raw = import_node_fs6.default.readFileSync(beadsConfigPath(), "utf8");
20859
+ const raw = import_node_fs7.default.readFileSync(beadsConfigPath(), "utf8");
20788
20860
  const cfg = JSON.parse(raw);
20789
20861
  return cfg.enabled !== false;
20790
20862
  } catch {
@@ -20793,10 +20865,10 @@ function readBeadsEnabled() {
20793
20865
  }
20794
20866
  function persistBeadsConfig(cfg) {
20795
20867
  const file = beadsConfigPath();
20796
- import_node_fs6.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true });
20868
+ import_node_fs7.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true });
20797
20869
  const tmp = `${file}.tmp`;
20798
- import_node_fs6.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
20799
- import_node_fs6.default.renameSync(tmp, file);
20870
+ import_node_fs7.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
20871
+ import_node_fs7.default.renameSync(tmp, file);
20800
20872
  restrictToOwner(file);
20801
20873
  }
20802
20874
 
@@ -21404,6 +21476,54 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
21404
21476
  });
21405
21477
  return r.ok === true;
21406
21478
  } : void 0;
21479
+ if (action === "provision") {
21480
+ await ctx.relay.sendResult(cmd.id, "completed", {
21481
+ action: "provision",
21482
+ supported: true,
21483
+ installed: false,
21484
+ loggedIn: false,
21485
+ linked: false
21486
+ });
21487
+ void (async () => {
21488
+ try {
21489
+ const cred = token ? await fetchProvisionCredential({
21490
+ agentId: "coderabbit",
21491
+ sessionId: ctx.sessionId,
21492
+ pluginId: ctx.pluginId,
21493
+ pluginAuthToken: token
21494
+ }) : null;
21495
+ if (!cred) {
21496
+ emit2("coderabbit_status", {
21497
+ installed: false,
21498
+ loggedIn: false,
21499
+ linked: false,
21500
+ error: "No vaulted CodeRabbit credential \u2014 sign in once to link it."
21501
+ });
21502
+ await emitChain;
21503
+ return;
21504
+ }
21505
+ const result2 = await configureCoderabbit(
21506
+ { action: "provision", provisionCredential: cred },
21507
+ { onEvent }
21508
+ );
21509
+ emit2("coderabbit_status", {
21510
+ installed: result2.installed,
21511
+ loggedIn: result2.loggedIn,
21512
+ linked: result2.linked ?? false,
21513
+ ...result2.error ? { error: result2.error } : {}
21514
+ });
21515
+ } catch (err) {
21516
+ emit2("coderabbit_status", {
21517
+ installed: false,
21518
+ loggedIn: false,
21519
+ linked: false,
21520
+ error: err instanceof Error ? err.message : "CodeRabbit provisioning failed"
21521
+ });
21522
+ }
21523
+ await emitChain;
21524
+ })();
21525
+ return;
21526
+ }
21407
21527
  if (action === "link_oauth") {
21408
21528
  await ctx.relay.sendResult(cmd.id, "completed", {
21409
21529
  action: "link_oauth",
@@ -23229,11 +23349,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
23229
23349
 
23230
23350
  // src/agents/kimi/installer.ts
23231
23351
  var import_node_child_process25 = require("child_process");
23232
- var import_node_os6 = require("os");
23352
+ var import_node_os7 = require("os");
23233
23353
  var import_node_path6 = require("path");
23234
23354
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
23235
23355
  function kimiBinDir() {
23236
- return (0, import_node_path6.join)(process.env.KIMI_CODE_HOME || (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".kimi-code"), "bin");
23356
+ return (0, import_node_path6.join)(process.env.KIMI_CODE_HOME || (0, import_node_path6.join)((0, import_node_os7.homedir)(), ".kimi-code"), "bin");
23237
23357
  }
23238
23358
  function kimiRuns() {
23239
23359
  const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -34518,7 +34638,7 @@ function checkChokidar() {
34518
34638
  }
34519
34639
  async function doctor(args2 = []) {
34520
34640
  const json = args2.includes("--json");
34521
- const cliVersion = true ? "2.60.41" : "0.0.0-dev";
34641
+ const cliVersion = true ? "2.60.42" : "0.0.0-dev";
34522
34642
  const apiBase2 = resolveApiBaseUrl();
34523
34643
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
34524
34644
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -34717,7 +34837,7 @@ async function completion(args2) {
34717
34837
  // src/commands/version.ts
34718
34838
  var import_picocolors15 = __toESM(require("picocolors"));
34719
34839
  function version2() {
34720
- const v = true ? "2.60.41" : "unknown";
34840
+ const v = true ? "2.60.42" : "unknown";
34721
34841
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
34722
34842
  }
34723
34843
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.60.41",
3
+ "version": "2.60.42",
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",