codeam-cli 2.61.18 → 2.61.20

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 +13 -0
  2. package/dist/index.js +309 -50
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ 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.19] — 2026-07-18
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Omit model context window when it isn't a real catalog match (no fake 200K)
12
+
13
+ ## [2.61.18] — 2026-07-18
14
+
15
+ ### Added
16
+
17
+ - **cli:** List_models reports the in-use model (currentModelId)
18
+ - **cli:** Native ACP model + mode list/switch (single source of truth, no hardcoded/hacky)
19
+
7
20
  ## [2.61.17] — 2026-07-18
8
21
 
9
22
  ### Fixed
package/dist/index.js CHANGED
@@ -277,6 +277,10 @@ function getContextWindow(model) {
277
277
  if (!model) return DEFAULT_CONTEXT_WINDOW;
278
278
  return longestPrefixMatch(MODEL_CONTEXT_WINDOW, model) ?? DEFAULT_CONTEXT_WINDOW;
279
279
  }
280
+ function tryGetContextWindow(model) {
281
+ if (!model) return void 0;
282
+ return longestPrefixMatch(MODEL_CONTEXT_WINDOW, model);
283
+ }
280
284
 
281
285
  // ../../packages/shared/src/agents/registry.ts
282
286
  var AGENT_REGISTRY = {
@@ -931,7 +935,11 @@ var USER_EVENTS = {
931
935
  // backend re-publishes them on the per-user SSE bus (mirrored in repo A).
932
936
  CODERABBIT_PROGRESS: "coderabbit_progress",
933
937
  CODERABBIT_STATUS: "coderabbit_status",
934
- CODERABBIT_REVIEW: "coderabbit_review"
938
+ CODERABBIT_REVIEW: "coderabbit_review",
939
+ // VCS / PR Command Center — the backend publishes this after an agent finishes
940
+ // reviewing a PR (verdict + comment count + findings), driving the mobile
941
+ // completion screen + push. Mirrored in repo A's app-shared events.ts.
942
+ VCS_AGENT_REVIEW_COMPLETE: "vcs_agent_review_complete"
935
943
  };
936
944
 
937
945
  // ../../packages/shared/src/preview-prompts.ts
@@ -6024,7 +6032,7 @@ function readAnonId() {
6024
6032
  }
6025
6033
  function superProperties() {
6026
6034
  return {
6027
- cliVersion: true ? "2.61.18" : "0.0.0-dev",
6035
+ cliVersion: true ? "2.61.20" : "0.0.0-dev",
6028
6036
  nodeVersion: process.version,
6029
6037
  platform: process.platform,
6030
6038
  arch: process.arch,
@@ -6205,7 +6213,7 @@ var os4 = __toESM(require("os"));
6205
6213
  // package.json
6206
6214
  var package_default = {
6207
6215
  name: "codeam-cli",
6208
- version: "2.61.18",
6216
+ version: "2.61.20",
6209
6217
  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.",
6210
6218
  type: "commonjs",
6211
6219
  main: "dist/index.js",
@@ -6547,6 +6555,27 @@ async function fetchProvisionCredential(input) {
6547
6555
  return null;
6548
6556
  }
6549
6557
  }
6558
+ async function postAgentReviewReport(input) {
6559
+ try {
6560
+ await _transport.postJsonAuthed(
6561
+ `${API_BASE}/api/vcs/agent-review/report`,
6562
+ {
6563
+ sessionId: input.sessionId,
6564
+ pluginId: input.pluginId,
6565
+ report: input.report
6566
+ },
6567
+ input.pluginAuthToken
6568
+ );
6569
+ return { ok: true };
6570
+ } catch (err) {
6571
+ const e = err;
6572
+ return {
6573
+ ok: false,
6574
+ status: typeof e.statusCode === "number" ? e.statusCode : 0,
6575
+ message: e.message || "unknown"
6576
+ };
6577
+ }
6578
+ }
6550
6579
  async function postCoderabbitEvent(input) {
6551
6580
  try {
6552
6581
  await _transport.postJsonAuthed(
@@ -7348,7 +7377,7 @@ var CommandRelayService = class _CommandRelayService {
7348
7377
  // fresh + clear the "CLI update available" banner after a self-update
7349
7378
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
7350
7379
  // pair/reconnect). Older backends ignore the extra field.
7351
- ..."2.61.18" ? { ideVersion: "2.61.18" } : {}
7380
+ ..."2.61.20" ? { ideVersion: "2.61.20" } : {}
7352
7381
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
7353
7382
  }
7354
7383
  /**
@@ -8887,6 +8916,20 @@ var startCommandSchema = import_zod.z.object({
8887
8916
  ).max(32).optional(),
8888
8917
  notes: import_zod.z.string().max(4096).nullable().optional()
8889
8918
  }).optional(),
8919
+ // `vcs_agent_review` (Phase-2 "Ask an agent to review PR #X") — the PR the
8920
+ // review session should review + post its verdict to via `gh`. Only the
8921
+ // CodeRabbit CLI path consumes it; ACP agents get the task as an initial
8922
+ // prompt instead. `agentId` / `prompt` (declared above) carry the reviewing
8923
+ // agent + the composed review prompt. Spec:
8924
+ // docs/superpowers/specs/2026-07-18-pr-mr-command-center-design.md §6.
8925
+ pr: import_zod.z.object({
8926
+ owner: import_zod.z.string().min(1).max(255),
8927
+ repo: import_zod.z.string().min(1).max(255),
8928
+ number: import_zod.z.number().int().min(1),
8929
+ url: import_zod.z.string().max(2048).optional()
8930
+ }).optional(),
8931
+ // The PR base branch, so CodeRabbit reviews the PR diff (committed vs base).
8932
+ baseBranch: import_zod.z.string().max(255).optional(),
8890
8933
  // `env_write` carries the full desired set of environment variables
8891
8934
  // for the project `.env`. Bounded so a malformed payload can't flood
8892
8935
  // the disk-side serializer. `env_read` / `preview_restart` send no payload.
@@ -16345,8 +16388,163 @@ async function configureCoderabbit(input, deps = {}) {
16345
16388
  };
16346
16389
  }
16347
16390
 
16391
+ // src/agents/coderabbit/review-pr.ts
16392
+ var import_node_child_process16 = require("child_process");
16393
+ function repoSlug(prRef) {
16394
+ return `${prRef.owner}/${prRef.repo}`;
16395
+ }
16396
+ function decidePrVerdict(stats) {
16397
+ const critical = numStat(stats, "critical");
16398
+ const findingCount = numStat(stats, "findingCount");
16399
+ if (critical > 0) return "request_changes";
16400
+ if (findingCount > 0) return "comment";
16401
+ return "approve";
16402
+ }
16403
+ function numStat(stats, key) {
16404
+ const v = stats?.[key];
16405
+ return typeof v === "number" ? v : 0;
16406
+ }
16407
+ function severityBadge(sev) {
16408
+ if (sev === "error") return "\u{1F534} Critical";
16409
+ if (sev === "warn") return "\u{1F7E1} Warning";
16410
+ if (sev === "info") return "\u{1F535} Suggestion";
16411
+ return "Note";
16412
+ }
16413
+ function buildPrReviewBody(parsed, commentCount) {
16414
+ const head = parsed.markdown.trim().length > 0 ? parsed.markdown.trim() : parsed.hunks.length === 0 ? "No issues found \u2014 looks good to me." : `Found ${parsed.hunks.length} issue${parsed.hunks.length === 1 ? "" : "s"}.`;
16415
+ const inline = commentCount > 0 ? `
16416
+
16417
+ ${commentCount} inline comment${commentCount === 1 ? "" : "s"} posted.` : "";
16418
+ return `\u{1F407} **CodeRabbit review**
16419
+
16420
+ ${head}${inline}`;
16421
+ }
16422
+ function buildInlineCommentArgs(prRef, hunk, headSha) {
16423
+ return [
16424
+ "api",
16425
+ "--method",
16426
+ "POST",
16427
+ `/repos/${prRef.owner}/${prRef.repo}/pulls/${prRef.number}/comments`,
16428
+ "-f",
16429
+ `body=${severityBadge(hunk.severity)}: ${hunk.message}`,
16430
+ "-f",
16431
+ `commit_id=${headSha}`,
16432
+ "-f",
16433
+ `path=${hunk.path}`,
16434
+ "-F",
16435
+ `line=${hunk.line}`,
16436
+ "-f",
16437
+ "side=RIGHT"
16438
+ ];
16439
+ }
16440
+ function buildReviewVerdictArgs(prRef, verdict, body) {
16441
+ const flag = verdict === "approve" ? "--approve" : verdict === "request_changes" ? "--request-changes" : "--comment";
16442
+ return [
16443
+ "pr",
16444
+ "review",
16445
+ String(prRef.number),
16446
+ "--repo",
16447
+ repoSlug(prRef),
16448
+ flag,
16449
+ "--body",
16450
+ body
16451
+ ];
16452
+ }
16453
+ function toAgentReviewFindings(hunks) {
16454
+ return hunks.map((h) => ({
16455
+ path: h.path,
16456
+ ...typeof h.line === "number" ? { line: h.line } : {},
16457
+ ...h.severity ? { severity: h.severity } : {},
16458
+ message: h.message
16459
+ }));
16460
+ }
16461
+ function buildAgentReviewReport(prRef, agentId, verdict, hunks, commentCount) {
16462
+ const findings = toAgentReviewFindings(hunks);
16463
+ return {
16464
+ prRef,
16465
+ agentId,
16466
+ verdict,
16467
+ commentCount,
16468
+ ...findings.length > 0 ? { findings } : {}
16469
+ };
16470
+ }
16471
+ async function reviewPullRequest(params, deps) {
16472
+ const { prRef, agentId } = params;
16473
+ const out2 = await deps.runReview({
16474
+ changeSet: "committed",
16475
+ ...params.baseBranch ? { base: params.baseBranch } : {},
16476
+ structured: true
16477
+ });
16478
+ const parsed = {
16479
+ markdown: out2.markdown ?? "",
16480
+ hunks: out2.hunks ?? [],
16481
+ stats: out2.stats ?? { findingCount: 0, critical: 0, warning: 0, info: 0 }
16482
+ };
16483
+ let headSha = "";
16484
+ try {
16485
+ const meta = await deps.runGh([
16486
+ "pr",
16487
+ "view",
16488
+ String(prRef.number),
16489
+ "--repo",
16490
+ repoSlug(prRef),
16491
+ "--json",
16492
+ "headRefOid",
16493
+ "-q",
16494
+ ".headRefOid"
16495
+ ]);
16496
+ if (meta.code === 0) headSha = meta.stdout.trim();
16497
+ } catch {
16498
+ }
16499
+ let commentCount = 0;
16500
+ if (headSha) {
16501
+ for (const hunk of parsed.hunks) {
16502
+ if (typeof hunk.line !== "number") continue;
16503
+ try {
16504
+ const r = await deps.runGh(buildInlineCommentArgs(prRef, hunk, headSha));
16505
+ if (r.code === 0) commentCount += 1;
16506
+ } catch {
16507
+ }
16508
+ }
16509
+ }
16510
+ const verdict = decidePrVerdict(parsed.stats);
16511
+ const body = buildPrReviewBody(parsed, commentCount);
16512
+ try {
16513
+ await deps.runGh(buildReviewVerdictArgs(prRef, verdict, body));
16514
+ } catch {
16515
+ }
16516
+ const report = buildAgentReviewReport(prRef, agentId, verdict, parsed.hunks, commentCount);
16517
+ await deps.postReport(report);
16518
+ return report;
16519
+ }
16520
+ function defaultRunGh(args2) {
16521
+ return new Promise((resolve8) => {
16522
+ const stdout = [];
16523
+ const stderr = [];
16524
+ let proc;
16525
+ try {
16526
+ proc = (0, import_node_child_process16.spawn)("gh", args2, { stdio: ["ignore", "pipe", "pipe"] });
16527
+ } catch (err) {
16528
+ resolve8({ code: -1, stdout: "", stderr: err instanceof Error ? err.message : String(err) });
16529
+ return;
16530
+ }
16531
+ proc.stdout?.on("data", (b) => stdout.push(b));
16532
+ proc.stderr?.on("data", (b) => stderr.push(b));
16533
+ proc.on("error", (err) => {
16534
+ resolve8({ code: -1, stdout: "", stderr: err.message });
16535
+ });
16536
+ proc.on("close", (code) => {
16537
+ resolve8({
16538
+ code: code ?? 0,
16539
+ stdout: Buffer.concat(stdout).toString("utf8"),
16540
+ stderr: Buffer.concat(stderr).toString("utf8")
16541
+ });
16542
+ });
16543
+ });
16544
+ }
16545
+
16348
16546
  // src/commands/host-agent.ts
16349
- var import_node_child_process23 = require("child_process");
16547
+ var import_node_child_process24 = require("child_process");
16350
16548
  var os36 = __toESM(require("os"));
16351
16549
  var fs42 = __toESM(require("fs"));
16352
16550
  var path45 = __toESM(require("path"));
@@ -16359,7 +16557,7 @@ var import_node_path5 = __toESM(require("path"));
16359
16557
  // src/lib/restrict-to-owner.ts
16360
16558
  var import_node_fs6 = __toESM(require("fs"));
16361
16559
  var import_node_os5 = __toESM(require("os"));
16362
- var import_node_child_process16 = require("child_process");
16560
+ var import_node_child_process17 = require("child_process");
16363
16561
  var BROAD_WINDOWS_SIDS = [
16364
16562
  "*S-1-1-0",
16365
16563
  "*S-1-5-11",
@@ -16371,7 +16569,7 @@ function restrictToOwner(filePath) {
16371
16569
  try {
16372
16570
  if (process.platform === "win32") {
16373
16571
  const username = import_node_os5.default.userInfo().username;
16374
- (0, import_node_child_process16.execFileSync)(
16572
+ (0, import_node_child_process17.execFileSync)(
16375
16573
  "icacls",
16376
16574
  [
16377
16575
  filePath,
@@ -16677,9 +16875,9 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
16677
16875
  var fs35 = __toESM(require("fs"));
16678
16876
  var os31 = __toESM(require("os"));
16679
16877
  var path39 = __toESM(require("path"));
16680
- var import_node_child_process17 = require("child_process");
16878
+ var import_node_child_process18 = require("child_process");
16681
16879
  var import_node_util4 = require("util");
16682
- var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process17.execFile);
16880
+ var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process18.execFile);
16683
16881
  function isAbsolutePathTarget(target) {
16684
16882
  return path39.isAbsolute(target);
16685
16883
  }
@@ -16992,7 +17190,7 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os32.homedir(
16992
17190
  }
16993
17191
 
16994
17192
  // src/commands/host/git-tooling.ts
16995
- var import_node_child_process18 = require("child_process");
17193
+ var import_node_child_process19 = require("child_process");
16996
17194
  var fs37 = __toESM(require("fs"));
16997
17195
  var os33 = __toESM(require("os"));
16998
17196
  var path41 = __toESM(require("path"));
@@ -17106,7 +17304,7 @@ var defaultGitToolingRunner = {
17106
17304
  which(cmd) {
17107
17305
  try {
17108
17306
  const probe = process.platform === "win32" ? "where" : "which";
17109
- (0, import_node_child_process18.execFileSync)(probe, [cmd], { stdio: "ignore" });
17307
+ (0, import_node_child_process19.execFileSync)(probe, [cmd], { stdio: "ignore" });
17110
17308
  return true;
17111
17309
  } catch {
17112
17310
  return false;
@@ -17114,7 +17312,7 @@ var defaultGitToolingRunner = {
17114
17312
  },
17115
17313
  run(cmd, args2, opts = {}) {
17116
17314
  return new Promise((resolve8) => {
17117
- const child = (0, import_node_child_process18.spawn)(cmd, args2, {
17315
+ const child = (0, import_node_child_process19.spawn)(cmd, args2, {
17118
17316
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
17119
17317
  });
17120
17318
  let stderr = "";
@@ -17268,12 +17466,12 @@ var HeadroomStatsReporter = class {
17268
17466
  };
17269
17467
 
17270
17468
  // src/commands/host/os-packages.ts
17271
- var import_node_child_process19 = require("child_process");
17469
+ var import_node_child_process20 = require("child_process");
17272
17470
  var PM_INSTALL_TIMEOUT_MS = 18e4;
17273
17471
  var defaultHeadroomRunner = {
17274
17472
  which(cmd) {
17275
17473
  try {
17276
- (0, import_node_child_process19.execFileSync)("which", [cmd], { stdio: "ignore" });
17474
+ (0, import_node_child_process20.execFileSync)("which", [cmd], { stdio: "ignore" });
17277
17475
  return true;
17278
17476
  } catch {
17279
17477
  return false;
@@ -17282,7 +17480,7 @@ var defaultHeadroomRunner = {
17282
17480
  run(cmd, args2, opts = {}) {
17283
17481
  return new Promise((resolve8) => {
17284
17482
  const spawnEnv = opts.env ?? process.env;
17285
- const child = (0, import_node_child_process19.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
17483
+ const child = (0, import_node_child_process20.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
17286
17484
  let stderrBuf = "";
17287
17485
  let stdoutBuf = "";
17288
17486
  let settled = false;
@@ -17789,14 +17987,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
17789
17987
  }
17790
17988
 
17791
17989
  // src/commands/host/self-update.ts
17792
- var import_node_child_process21 = require("child_process");
17990
+ var import_node_child_process22 = require("child_process");
17793
17991
 
17794
17992
  // src/lib/updateNotifier.ts
17795
17993
  var fs40 = __toESM(require("fs"));
17796
17994
  var os35 = __toESM(require("os"));
17797
17995
  var path44 = __toESM(require("path"));
17798
17996
  var https6 = __toESM(require("https"));
17799
- var import_node_child_process20 = require("child_process");
17997
+ var import_node_child_process21 = require("child_process");
17800
17998
  var import_picocolors3 = __toESM(require("picocolors"));
17801
17999
  var PKG_NAME = "codeam-cli";
17802
18000
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
@@ -17890,7 +18088,7 @@ function notifyIfStale(currentVersion, latest) {
17890
18088
  }
17891
18089
  function isLinkedInstall() {
17892
18090
  try {
17893
- const root = (0, import_node_child_process20.execSync)("npm root -g", {
18091
+ const root = (0, import_node_child_process21.execSync)("npm root -g", {
17894
18092
  encoding: "utf8",
17895
18093
  stdio: ["ignore", "pipe", "ignore"],
17896
18094
  timeout: 2e3
@@ -17918,7 +18116,7 @@ function maybeAutoUpdate(currentVersion, latest) {
17918
18116
 
17919
18117
  `
17920
18118
  );
17921
- const install = (0, import_node_child_process20.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
18119
+ const install = (0, import_node_child_process21.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
17922
18120
  stdio: "inherit",
17923
18121
  env: process.env
17924
18122
  });
@@ -17939,7 +18137,7 @@ function maybeAutoUpdate(currentVersion, latest) {
17939
18137
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
17940
18138
 
17941
18139
  `);
17942
- const child = (0, import_node_child_process20.spawnSync)("codeam", process.argv.slice(2), {
18140
+ const child = (0, import_node_child_process21.spawnSync)("codeam", process.argv.slice(2), {
17943
18141
  stdio: "inherit",
17944
18142
  env: process.env
17945
18143
  });
@@ -17949,7 +18147,7 @@ async function autoUpgradeBeforeCriticalCommand() {
17949
18147
  if (process.env.NODE_ENV === "test") return;
17950
18148
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17951
18149
  if (process.env.CI) return;
17952
- const current = true ? "2.61.18" : null;
18150
+ const current = true ? "2.61.20" : null;
17953
18151
  if (!current) return;
17954
18152
  const cache = readCache();
17955
18153
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17966,7 +18164,7 @@ function checkForUpdates() {
17966
18164
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
17967
18165
  if (process.env.CI) return;
17968
18166
  if (!process.stdout.isTTY) return;
17969
- const current = true ? "2.61.18" : null;
18167
+ const current = true ? "2.61.20" : null;
17970
18168
  if (!current) return;
17971
18169
  const cache = readCache();
17972
18170
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -17986,11 +18184,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
17986
18184
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
17987
18185
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
17988
18186
  function currentCliVersion() {
17989
- return true ? "2.61.18" : null;
18187
+ return true ? "2.61.20" : null;
17990
18188
  }
17991
18189
  function runCmd(cmd, args2, timeoutMs) {
17992
18190
  return new Promise((resolve8) => {
17993
- (0, import_node_child_process21.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
18191
+ (0, import_node_child_process22.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
17994
18192
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
17995
18193
  resolve8({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
17996
18194
  });
@@ -18052,11 +18250,11 @@ async function runSelfUpdate() {
18052
18250
  }
18053
18251
 
18054
18252
  // src/commands/host/teardown.ts
18055
- var import_node_child_process22 = require("child_process");
18253
+ var import_node_child_process23 = require("child_process");
18056
18254
  var fs41 = __toESM(require("fs"));
18057
18255
  var defaultDisableService = () => {
18058
18256
  try {
18059
- (0, import_node_child_process22.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
18257
+ (0, import_node_child_process23.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
18060
18258
  } catch {
18061
18259
  }
18062
18260
  };
@@ -18064,7 +18262,7 @@ var defaultTeardownHeadroom = () => {
18064
18262
  try {
18065
18263
  const kind = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8")).agent;
18066
18264
  if (kind) {
18067
- (0, import_node_child_process22.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
18265
+ (0, import_node_child_process23.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
18068
18266
  }
18069
18267
  } catch {
18070
18268
  }
@@ -18251,7 +18449,7 @@ var DOCKER_RUN_TIMEOUT_MS = 12e4;
18251
18449
  var defaultDockerRunner = {
18252
18450
  run(args2, opts = {}) {
18253
18451
  return new Promise((resolve8) => {
18254
- const child = (0, import_node_child_process23.spawn)("docker", args2, {
18452
+ const child = (0, import_node_child_process24.spawn)("docker", args2, {
18255
18453
  stdio: ["ignore", "pipe", "pipe"],
18256
18454
  env: { ...process.env, ...opts.env }
18257
18455
  });
@@ -18297,13 +18495,13 @@ var CONTROL_AGENT_META = {
18297
18495
  headroomWrappable: false,
18298
18496
  acp: false
18299
18497
  };
18300
- var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process23.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
18498
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process24.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
18301
18499
  cwd,
18302
18500
  env: { ...process.env, ...env },
18303
18501
  stdio: ["ignore", "pipe", "pipe"],
18304
18502
  detached: false
18305
18503
  });
18306
- var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process23.spawn)(process.execPath, [process.argv[1]], {
18504
+ var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process24.spawn)(process.execPath, [process.argv[1]], {
18307
18505
  cwd,
18308
18506
  // CODEAM_AUTO_APPROVE=1 → ACP path (baton off). CODEAM_RESUME_LATEST=1 →
18309
18507
  // continue the user's most-recent conversation instead of opening an empty
@@ -19076,7 +19274,7 @@ var HostAgentSupervisor = class {
19076
19274
  runAgentInstall(script) {
19077
19275
  return new Promise((resolve8) => {
19078
19276
  const home = process.env.HOME || os36.homedir();
19079
- const child = (0, import_node_child_process23.spawn)("sh", ["-c", script], {
19277
+ const child = (0, import_node_child_process24.spawn)("sh", ["-c", script], {
19080
19278
  env: { ...process.env, HOME: home },
19081
19279
  stdio: ["ignore", "pipe", "pipe"]
19082
19280
  });
@@ -22515,6 +22713,63 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
22515
22713
  await emitChain;
22516
22714
  await ctx.relay.sendResult(cmd.id, result.error && action !== "review" ? "failed" : "completed", result);
22517
22715
  };
22716
+ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
22717
+ const pr = parsed.pr;
22718
+ if (!pr) {
22719
+ await ctx.relay.sendResult(cmd.id, "failed", { error: "Missing PR reference" });
22720
+ return;
22721
+ }
22722
+ const prRef = {
22723
+ owner: pr.owner,
22724
+ repo: pr.repo,
22725
+ number: pr.number,
22726
+ ...pr.url ? { url: pr.url } : {}
22727
+ };
22728
+ if (normalizeAgentId(ctx.agentId) !== "coderabbit") {
22729
+ await ctx.relay.sendResult(cmd.id, "completed", {
22730
+ action: "vcs_agent_review",
22731
+ skipped: true,
22732
+ reason: "non-coderabbit agent posts its review via the prompt + gh"
22733
+ });
22734
+ return;
22735
+ }
22736
+ await ctx.relay.sendResult(cmd.id, "completed", {
22737
+ action: "vcs_agent_review",
22738
+ started: true
22739
+ });
22740
+ const token = ctx.pluginAuthToken;
22741
+ void (async () => {
22742
+ const os53 = createOsStrategy();
22743
+ try {
22744
+ const report = await reviewPullRequest(
22745
+ {
22746
+ prRef,
22747
+ agentId: "coderabbit",
22748
+ baseBranch: parsed.baseBranch
22749
+ },
22750
+ {
22751
+ runReview: (input) => new CoderabbitRuntimeStrategy(os53).runOneShot(input),
22752
+ runGh: (args2) => defaultRunGh(args2),
22753
+ postReport: async (r) => {
22754
+ if (!token) return;
22755
+ await postAgentReviewReport({
22756
+ sessionId: ctx.sessionId,
22757
+ pluginId: ctx.pluginId,
22758
+ pluginAuthToken: token,
22759
+ report: r
22760
+ });
22761
+ }
22762
+ }
22763
+ );
22764
+ log.info(
22765
+ "vcs",
22766
+ `agent review of ${prRef.owner}/${prRef.repo}#${prRef.number} posted: ${report.verdict} (${report.commentCount} inline comment(s))`
22767
+ );
22768
+ } catch (err) {
22769
+ log.warn("vcs", "agent PR review failed (non-fatal)", err);
22770
+ }
22771
+ })();
22772
+ };
22518
22773
  var headroomBudgetH = async (ctx, cmd) => {
22519
22774
  const payload = cmd.payload;
22520
22775
  let rawAgentId = ctx.agentId || (typeof payload.agentId === "string" ? payload.agentId : "");
@@ -23246,6 +23501,7 @@ var handlers = {
23246
23501
  handback: handbackH,
23247
23502
  headroom_configure: headroomConfigureH,
23248
23503
  coderabbit_configure: coderabbitConfigureH,
23504
+ vcs_agent_review: vcsAgentReviewH,
23249
23505
  headroom_budget: headroomBudgetH,
23250
23506
  beads_configure: beadsConfigureH,
23251
23507
  cli_self_update: cliSelfUpdateH()
@@ -23788,7 +24044,7 @@ async function pairAuto(args2) {
23788
24044
  }
23789
24045
 
23790
24046
  // src/services/headroom/wrap-launch.ts
23791
- var import_node_child_process24 = require("child_process");
24047
+ var import_node_child_process25 = require("child_process");
23792
24048
  function wrapWithHeadroom(launch, opts) {
23793
24049
  if (!opts.enabled || !opts.headroomPresent) return launch;
23794
24050
  return {
@@ -23801,7 +24057,7 @@ var _present;
23801
24057
  function headroomPresent() {
23802
24058
  if (_present !== void 0) return Promise.resolve(_present);
23803
24059
  return new Promise((resolve8) => {
23804
- (0, import_node_child_process24.execFile)("headroom", ["--version"], (err) => {
24060
+ (0, import_node_child_process25.execFile)("headroom", ["--version"], (err) => {
23805
24061
  _present = !err;
23806
24062
  resolve8(_present);
23807
24063
  });
@@ -24326,7 +24582,7 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
24326
24582
  }
24327
24583
 
24328
24584
  // src/agents/kimi/installer.ts
24329
- var import_node_child_process25 = require("child_process");
24585
+ var import_node_child_process26 = require("child_process");
24330
24586
  var import_node_os8 = require("os");
24331
24587
  var import_node_path7 = require("path");
24332
24588
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
@@ -24334,7 +24590,7 @@ function kimiBinDir() {
24334
24590
  return (0, import_node_path7.join)(process.env.KIMI_CODE_HOME || (0, import_node_path7.join)((0, import_node_os8.homedir)(), ".kimi-code"), "bin");
24335
24591
  }
24336
24592
  function kimiRuns() {
24337
- const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
24593
+ const r = (0, import_node_child_process26.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
24338
24594
  return !r.error && r.status === 0;
24339
24595
  }
24340
24596
  function augmentPath2() {
@@ -24344,7 +24600,7 @@ function augmentPath2() {
24344
24600
  }
24345
24601
  async function runInstaller2() {
24346
24602
  return new Promise((resolve8) => {
24347
- const proc = (0, import_node_child_process25.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
24603
+ const proc = (0, import_node_child_process26.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
24348
24604
  proc.on("close", (code) => resolve8(code === 0));
24349
24605
  proc.on("error", () => resolve8(false));
24350
24606
  });
@@ -25130,7 +25386,7 @@ var HistoryService = class _HistoryService {
25130
25386
  };
25131
25387
 
25132
25388
  // src/agents/acp/client.ts
25133
- var import_node_child_process26 = require("child_process");
25389
+ var import_node_child_process27 = require("child_process");
25134
25390
  var fs59 = __toESM(require("fs/promises"));
25135
25391
  var fsSync = __toESM(require("fs"));
25136
25392
  var os48 = __toESM(require("os"));
@@ -29336,7 +29592,7 @@ var AcpClient = class {
29336
29592
  "acpClient",
29337
29593
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
29338
29594
  );
29339
- const child = (0, import_node_child_process26.spawn)(adapter.command, adapter.args, {
29595
+ const child = (0, import_node_child_process27.spawn)(adapter.command, adapter.args, {
29340
29596
  cwd,
29341
29597
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
29342
29598
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -29764,7 +30020,10 @@ var AcpClient = class {
29764
30020
  this.availableModels = flattenSelectOptions(modelOption.options).map((opt) => ({
29765
30021
  id: opt.value,
29766
30022
  label: opt.name,
29767
- contextWindow: getContextWindow(opt.value)
30023
+ // Only when it's a real catalog match — native ids are often opaque
30024
+ // aliases ("default"/"opus") or proxied (MiniMax house agent), for which a
30025
+ // default 200K is a fake; undefined → the UI omits the context sub-label.
30026
+ contextWindow: tryGetContextWindow(opt.value)
29768
30027
  }));
29769
30028
  }
29770
30029
  /**
@@ -30051,12 +30310,12 @@ function buildRelaunchProxyEnv(baseEnv) {
30051
30310
  return env;
30052
30311
  }
30053
30312
  var relaunchProxyWithoutBudget = async () => {
30054
- const { spawn: spawn41 } = await import("child_process");
30313
+ const { spawn: spawn42 } = await import("child_process");
30055
30314
  killHeadroomProxy();
30056
30315
  await new Promise((r) => setTimeout(r, 500));
30057
30316
  const proxyEnv = buildRelaunchProxyEnv(process.env);
30058
30317
  try {
30059
- const proxy = spawn41(
30318
+ const proxy = spawn42(
30060
30319
  "headroom",
30061
30320
  ["proxy", "--port", "8787"],
30062
30321
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -37812,7 +38071,7 @@ function checkChokidar() {
37812
38071
  }
37813
38072
  async function doctor(args2 = []) {
37814
38073
  const json = args2.includes("--json");
37815
- const cliVersion = true ? "2.61.18" : "0.0.0-dev";
38074
+ const cliVersion = true ? "2.61.20" : "0.0.0-dev";
37816
38075
  const apiBase2 = resolveApiBaseUrl();
37817
38076
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
37818
38077
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -38009,7 +38268,7 @@ async function completion(args2) {
38009
38268
  }
38010
38269
 
38011
38270
  // src/integrations/mcp-run.ts
38012
- var import_node_child_process28 = require("child_process");
38271
+ var import_node_child_process29 = require("child_process");
38013
38272
  var import_node_fs9 = require("fs");
38014
38273
  var import_node_os9 = __toESM(require("os"));
38015
38274
  var import_node_path8 = __toESM(require("path"));
@@ -38065,7 +38324,7 @@ var IntegrationTokenClient = class {
38065
38324
  };
38066
38325
 
38067
38326
  // src/integrations/stdio-proxy.ts
38068
- var import_node_child_process27 = require("child_process");
38327
+ var import_node_child_process28 = require("child_process");
38069
38328
  var import_node_readline3 = __toESM(require("readline"));
38070
38329
  var RESTART_CHECK_INTERVAL_MS = 3e4;
38071
38330
  var SIGKILL_ESCALATION_MS = 2e3;
@@ -38186,8 +38445,8 @@ var RestartableStdioProxy = class {
38186
38445
  }
38187
38446
  async spawnChild(stdout, preResolved) {
38188
38447
  const spec = preResolved ?? await this.opts.spawnSpec();
38189
- const spawn41 = this.opts.spawnImpl ?? import_node_child_process27.spawn;
38190
- const child = spawn41(spec.command, spec.args, {
38448
+ const spawn42 = this.opts.spawnImpl ?? import_node_child_process28.spawn;
38449
+ const child = spawn42(spec.command, spec.args, {
38191
38450
  env: { ...process.env, ...spec.env },
38192
38451
  // env only — never argv
38193
38452
  stdio: ["pipe", "pipe", "inherit"]
@@ -38226,7 +38485,7 @@ function resolveDelivery(id) {
38226
38485
  function commandExists(command2) {
38227
38486
  try {
38228
38487
  const probe = process.platform === "win32" ? "where" : "which";
38229
- (0, import_node_child_process28.execFileSync)(probe, [command2], { stdio: "ignore" });
38488
+ (0, import_node_child_process29.execFileSync)(probe, [command2], { stdio: "ignore" });
38230
38489
  return true;
38231
38490
  } catch {
38232
38491
  return false;
@@ -38259,7 +38518,7 @@ function ensureCommand(command2) {
38259
38518
  }
38260
38519
  if (command2 === "uvx") {
38261
38520
  try {
38262
- (0, import_node_child_process28.execSync)("curl -LsSf https://astral.sh/uv/install.sh | sh", {
38521
+ (0, import_node_child_process29.execSync)("curl -LsSf https://astral.sh/uv/install.sh | sh", {
38263
38522
  stdio: ["ignore", process.stderr, process.stderr],
38264
38523
  timeout: 18e4,
38265
38524
  env: { ...process.env, UV_NO_MODIFY_PATH: "1" }
@@ -38268,7 +38527,7 @@ function ensureCommand(command2) {
38268
38527
  }
38269
38528
  if (resolveLauncherPath(command2) !== command2) return;
38270
38529
  try {
38271
- (0, import_node_child_process28.execSync)("python3 -m pip install --user --quiet uv", {
38530
+ (0, import_node_child_process29.execSync)("python3 -m pip install --user --quiet uv", {
38272
38531
  stdio: ["ignore", process.stderr, process.stderr],
38273
38532
  timeout: 18e4
38274
38533
  });
@@ -38323,7 +38582,7 @@ async function mcpRun(args2) {
38323
38582
  // src/commands/version.ts
38324
38583
  var import_picocolors15 = __toESM(require("picocolors"));
38325
38584
  function version2() {
38326
- const v = true ? "2.61.18" : "unknown";
38585
+ const v = true ? "2.61.20" : "unknown";
38327
38586
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
38328
38587
  }
38329
38588
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.61.18",
3
+ "version": "2.61.20",
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",