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.
- package/CHANGELOG.md +13 -0
- package/dist/index.js +309 -50
- 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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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)(
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
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.
|
|
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.
|
|
18187
|
+
return true ? "2.61.20" : null;
|
|
17990
18188
|
}
|
|
17991
18189
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17992
18190
|
return new Promise((resolve8) => {
|
|
17993
|
-
(0,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
38190
|
-
const child =
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
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.
|
|
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",
|