codeam-cli 2.60.40 → 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.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.js +150 -23
  3. package/package.json +1 -1
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.60.41] — 2026-07-10
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Surface a clean error when a CodeRabbit review times out
12
+
13
+ ## [2.60.40] — 2026-07-10
14
+
15
+ ### Added
16
+
17
+ - **cli:** Include changed files (git numstat) in the CodeRabbit review result
18
+
7
19
  ## [2.60.39] — 2026-07-10
8
20
 
9
21
  ### Fixed
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.40" : "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.40",
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.40" ? { ideVersion: "2.60.40" } : {}
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) {
@@ -15857,6 +15929,13 @@ async function configureCoderabbit(input, deps = {}) {
15857
15929
  }
15858
15930
  if (!deps.runReview) return { ...res, error: "No reviewer available" };
15859
15931
  const out2 = await deps.runReview(input.review ?? {});
15932
+ if (out2.exitCode === 124) {
15933
+ return {
15934
+ ...res,
15935
+ loggedIn: true,
15936
+ error: "CodeRabbit's review service didn't respond in time \u2014 this is usually a temporary CodeRabbit outage. Please try again."
15937
+ };
15938
+ }
15860
15939
  const files = collectChangedFiles(process.cwd());
15861
15940
  return {
15862
15941
  ...res,
@@ -15883,8 +15962,8 @@ var os29 = __toESM(require("os"));
15883
15962
  var path37 = __toESM(require("path"));
15884
15963
 
15885
15964
  // src/lib/restrict-to-owner.ts
15886
- var import_node_fs5 = __toESM(require("fs"));
15887
- var import_node_os4 = __toESM(require("os"));
15965
+ var import_node_fs6 = __toESM(require("fs"));
15966
+ var import_node_os5 = __toESM(require("os"));
15888
15967
  var import_node_child_process16 = require("child_process");
15889
15968
  var BROAD_WINDOWS_SIDS = [
15890
15969
  "*S-1-1-0",
@@ -15896,7 +15975,7 @@ var BROAD_WINDOWS_SIDS = [
15896
15975
  function restrictToOwner(filePath) {
15897
15976
  try {
15898
15977
  if (process.platform === "win32") {
15899
- const username = import_node_os4.default.userInfo().username;
15978
+ const username = import_node_os5.default.userInfo().username;
15900
15979
  (0, import_node_child_process16.execFileSync)(
15901
15980
  "icacls",
15902
15981
  [
@@ -15909,7 +15988,7 @@ function restrictToOwner(filePath) {
15909
15988
  { stdio: "ignore" }
15910
15989
  );
15911
15990
  } else {
15912
- import_node_fs5.default.chmodSync(filePath, 384);
15991
+ import_node_fs6.default.chmodSync(filePath, 384);
15913
15992
  }
15914
15993
  } catch {
15915
15994
  }
@@ -17414,7 +17493,7 @@ async function autoUpgradeBeforeCriticalCommand() {
17414
17493
  if (process.env.NODE_ENV === "test") return;
17415
17494
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17416
17495
  if (process.env.CI) return;
17417
- const current = true ? "2.60.40" : null;
17496
+ const current = true ? "2.60.42" : null;
17418
17497
  if (!current) return;
17419
17498
  const cache = readCache();
17420
17499
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17431,7 +17510,7 @@ function checkForUpdates() {
17431
17510
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17432
17511
  if (process.env.CI) return;
17433
17512
  if (!process.stdout.isTTY) return;
17434
- const current = true ? "2.60.40" : null;
17513
+ const current = true ? "2.60.42" : null;
17435
17514
  if (!current) return;
17436
17515
  const cache = readCache();
17437
17516
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17451,7 +17530,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
17451
17530
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
17452
17531
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
17453
17532
  function currentCliVersion() {
17454
- return true ? "2.60.40" : null;
17533
+ return true ? "2.60.42" : null;
17455
17534
  }
17456
17535
  function runCmd(cmd, args2, timeoutMs) {
17457
17536
  return new Promise((resolve7) => {
@@ -20769,15 +20848,15 @@ async function handleBeadsActionCommand(action, started) {
20769
20848
  }
20770
20849
 
20771
20850
  // src/beads/config-store.ts
20772
- var import_node_fs6 = __toESM(require("fs"));
20773
- var import_node_os5 = __toESM(require("os"));
20851
+ var import_node_fs7 = __toESM(require("fs"));
20852
+ var import_node_os6 = __toESM(require("os"));
20774
20853
  var import_node_path5 = __toESM(require("path"));
20775
20854
  function beadsConfigPath() {
20776
- 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");
20777
20856
  }
20778
20857
  function readBeadsEnabled() {
20779
20858
  try {
20780
- const raw = import_node_fs6.default.readFileSync(beadsConfigPath(), "utf8");
20859
+ const raw = import_node_fs7.default.readFileSync(beadsConfigPath(), "utf8");
20781
20860
  const cfg = JSON.parse(raw);
20782
20861
  return cfg.enabled !== false;
20783
20862
  } catch {
@@ -20786,10 +20865,10 @@ function readBeadsEnabled() {
20786
20865
  }
20787
20866
  function persistBeadsConfig(cfg) {
20788
20867
  const file = beadsConfigPath();
20789
- 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 });
20790
20869
  const tmp = `${file}.tmp`;
20791
- import_node_fs6.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
20792
- 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);
20793
20872
  restrictToOwner(file);
20794
20873
  }
20795
20874
 
@@ -21397,6 +21476,54 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
21397
21476
  });
21398
21477
  return r.ok === true;
21399
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
+ }
21400
21527
  if (action === "link_oauth") {
21401
21528
  await ctx.relay.sendResult(cmd.id, "completed", {
21402
21529
  action: "link_oauth",
@@ -23222,11 +23349,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
23222
23349
 
23223
23350
  // src/agents/kimi/installer.ts
23224
23351
  var import_node_child_process25 = require("child_process");
23225
- var import_node_os6 = require("os");
23352
+ var import_node_os7 = require("os");
23226
23353
  var import_node_path6 = require("path");
23227
23354
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
23228
23355
  function kimiBinDir() {
23229
- 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");
23230
23357
  }
23231
23358
  function kimiRuns() {
23232
23359
  const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -34511,7 +34638,7 @@ function checkChokidar() {
34511
34638
  }
34512
34639
  async function doctor(args2 = []) {
34513
34640
  const json = args2.includes("--json");
34514
- const cliVersion = true ? "2.60.40" : "0.0.0-dev";
34641
+ const cliVersion = true ? "2.60.42" : "0.0.0-dev";
34515
34642
  const apiBase2 = resolveApiBaseUrl();
34516
34643
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
34517
34644
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -34710,7 +34837,7 @@ async function completion(args2) {
34710
34837
  // src/commands/version.ts
34711
34838
  var import_picocolors15 = __toESM(require("picocolors"));
34712
34839
  function version2() {
34713
- const v = true ? "2.60.40" : "unknown";
34840
+ const v = true ? "2.60.42" : "unknown";
34714
34841
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
34715
34842
  }
34716
34843
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.60.40",
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",