codeam-cli 2.60.32 → 2.60.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +141 -45
- 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.33] — 2026-07-10
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Pre-accept Claude's per-workspace trust dialog on cloud sessions
|
|
12
|
+
|
|
13
|
+
## [2.60.32] — 2026-07-10
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Retry ACP adapter start on a module-load crash (ERR_MODULE_NOT_FOUND)
|
|
18
|
+
|
|
7
19
|
## [2.60.31] — 2026-07-10
|
|
8
20
|
|
|
9
21
|
### Tests
|
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.
|
|
5692
|
+
cliVersion: true ? "2.60.34" : "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.
|
|
5873
|
+
version: "2.60.34",
|
|
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",
|
|
@@ -6963,7 +6963,7 @@ var CommandRelayService = class {
|
|
|
6963
6963
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6964
6964
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6965
6965
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6966
|
-
..."2.60.
|
|
6966
|
+
..."2.60.34" ? { ideVersion: "2.60.34" } : {}
|
|
6967
6967
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6968
6968
|
}
|
|
6969
6969
|
/**
|
|
@@ -8410,6 +8410,9 @@ var startCommandSchema = import_zod.z.object({
|
|
|
8410
8410
|
"status",
|
|
8411
8411
|
// `coderabbit_configure` — link the reviewer (OAuth or API key) + run a review.
|
|
8412
8412
|
"link_oauth",
|
|
8413
|
+
// Deliver a mobile-intercepted OAuth redirect to this host's coderabbit
|
|
8414
|
+
// loopback so a remote-host `link_oauth` login completes (session-relay).
|
|
8415
|
+
"link_deliver_callback",
|
|
8413
8416
|
"link_apikey",
|
|
8414
8417
|
"review"
|
|
8415
8418
|
]).optional(),
|
|
@@ -8423,6 +8426,10 @@ var startCommandSchema = import_zod.z.object({
|
|
|
8423
8426
|
changeSet: import_zod.z.enum(["all", "committed", "uncommitted"]).optional(),
|
|
8424
8427
|
base: import_zod.z.string().max(255).optional(),
|
|
8425
8428
|
reviewDir: import_zod.z.string().max(1024).optional(),
|
|
8429
|
+
// `coderabbit_configure` (action='link_deliver_callback') — the exact loopback
|
|
8430
|
+
// redirect URL the mobile WebView intercepted (`http://127.0.0.1:<port>/callback?…`).
|
|
8431
|
+
// Replayed to the local coderabbit login server; SSRF-guarded to loopback only.
|
|
8432
|
+
callbackUrl: import_zod.z.string().max(4096).optional(),
|
|
8426
8433
|
// `request_link_credentials` — backend fires this from the
|
|
8427
8434
|
// heartbeat handler when it notices the user is running an agent
|
|
8428
8435
|
// they haven't vaulted yet. Also reused by `get_context` /
|
|
@@ -15411,6 +15418,7 @@ var path36 = __toESM(require("path"));
|
|
|
15411
15418
|
|
|
15412
15419
|
// src/agents/coderabbit/oauth.ts
|
|
15413
15420
|
var fs31 = __toESM(require("fs"));
|
|
15421
|
+
var http6 = __toESM(require("http"));
|
|
15414
15422
|
var os27 = __toESM(require("os"));
|
|
15415
15423
|
var path35 = __toESM(require("path"));
|
|
15416
15424
|
function parseCoderabbitAuthEvent(line) {
|
|
@@ -15542,6 +15550,34 @@ function diffCapturedCredential(before, home) {
|
|
|
15542
15550
|
return null;
|
|
15543
15551
|
}
|
|
15544
15552
|
}
|
|
15553
|
+
function deliverLoopbackCallback(callbackUrl, opts = {}) {
|
|
15554
|
+
return new Promise((resolve7) => {
|
|
15555
|
+
let url;
|
|
15556
|
+
try {
|
|
15557
|
+
url = new URL(callbackUrl);
|
|
15558
|
+
} catch {
|
|
15559
|
+
resolve7({ ok: false, error: "invalid callback URL" });
|
|
15560
|
+
return;
|
|
15561
|
+
}
|
|
15562
|
+
const host2 = url.hostname.replace(/^\[|\]$/g, "");
|
|
15563
|
+
const isLoopback = url.protocol === "http:" && (host2 === "127.0.0.1" || host2 === "localhost" || host2 === "::1");
|
|
15564
|
+
if (!isLoopback) {
|
|
15565
|
+
resolve7({ ok: false, error: `refusing non-loopback callback host: ${url.hostname}` });
|
|
15566
|
+
return;
|
|
15567
|
+
}
|
|
15568
|
+
const get3 = opts.get ?? http6.get;
|
|
15569
|
+
const req = get3(url, { timeout: opts.timeoutMs ?? 1e4 }, (res) => {
|
|
15570
|
+
res.resume();
|
|
15571
|
+
const status2 = res.statusCode ?? 0;
|
|
15572
|
+
resolve7({ ok: status2 >= 200 && status2 < 400, status: status2 });
|
|
15573
|
+
});
|
|
15574
|
+
req.on("timeout", () => {
|
|
15575
|
+
req.destroy();
|
|
15576
|
+
resolve7({ ok: false, error: "callback delivery timed out" });
|
|
15577
|
+
});
|
|
15578
|
+
req.on("error", (err) => resolve7({ ok: false, error: err.message }));
|
|
15579
|
+
});
|
|
15580
|
+
}
|
|
15545
15581
|
|
|
15546
15582
|
// src/agents/coderabbit/configure.ts
|
|
15547
15583
|
function defaultIsLoggedIn() {
|
|
@@ -17197,7 +17233,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17197
17233
|
if (process.env.NODE_ENV === "test") return;
|
|
17198
17234
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17199
17235
|
if (process.env.CI) return;
|
|
17200
|
-
const current = true ? "2.60.
|
|
17236
|
+
const current = true ? "2.60.34" : null;
|
|
17201
17237
|
if (!current) return;
|
|
17202
17238
|
const cache = readCache();
|
|
17203
17239
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17214,7 +17250,7 @@ function checkForUpdates() {
|
|
|
17214
17250
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17215
17251
|
if (process.env.CI) return;
|
|
17216
17252
|
if (!process.stdout.isTTY) return;
|
|
17217
|
-
const current = true ? "2.60.
|
|
17253
|
+
const current = true ? "2.60.34" : null;
|
|
17218
17254
|
if (!current) return;
|
|
17219
17255
|
const cache = readCache();
|
|
17220
17256
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17234,7 +17270,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17234
17270
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17235
17271
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17236
17272
|
function currentCliVersion() {
|
|
17237
|
-
return true ? "2.60.
|
|
17273
|
+
return true ? "2.60.34" : null;
|
|
17238
17274
|
}
|
|
17239
17275
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17240
17276
|
return new Promise((resolve7) => {
|
|
@@ -21123,7 +21159,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21123
21159
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
21124
21160
|
};
|
|
21125
21161
|
var coderabbitConfigureH = async (ctx, cmd, parsed) => {
|
|
21126
|
-
const
|
|
21162
|
+
const rawAction = parsed.action ?? "status";
|
|
21127
21163
|
const token = ctx.pluginAuthToken;
|
|
21128
21164
|
let emitChain = Promise.resolve();
|
|
21129
21165
|
const emit2 = (type, payload) => {
|
|
@@ -21138,6 +21174,70 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21138
21174
|
})
|
|
21139
21175
|
);
|
|
21140
21176
|
};
|
|
21177
|
+
if (rawAction === "link_deliver_callback") {
|
|
21178
|
+
const r = await deliverLoopbackCallback(parsed.callbackUrl ?? "");
|
|
21179
|
+
await ctx.relay.sendResult(cmd.id, r.ok ? "completed" : "failed", {
|
|
21180
|
+
action: "link_deliver_callback",
|
|
21181
|
+
supported: true,
|
|
21182
|
+
installed: true,
|
|
21183
|
+
loggedIn: false,
|
|
21184
|
+
delivered: r.ok,
|
|
21185
|
+
...r.error ? { error: r.error } : {}
|
|
21186
|
+
});
|
|
21187
|
+
return;
|
|
21188
|
+
}
|
|
21189
|
+
const action = rawAction;
|
|
21190
|
+
const onEvent = (e) => {
|
|
21191
|
+
if (e.kind === "awaiting_browser") {
|
|
21192
|
+
emit2("coderabbit_progress", {
|
|
21193
|
+
phase: "awaiting_browser",
|
|
21194
|
+
authUrl: e.authUrl,
|
|
21195
|
+
fallbackAuthUrl: e.fallbackAuthUrl
|
|
21196
|
+
});
|
|
21197
|
+
} else {
|
|
21198
|
+
emit2("coderabbit_progress", { phase: e.kind });
|
|
21199
|
+
}
|
|
21200
|
+
};
|
|
21201
|
+
const uploadCredential = token ? async (method, credential) => {
|
|
21202
|
+
const r = await postLinkCredential({
|
|
21203
|
+
agentId: "coderabbit",
|
|
21204
|
+
sessionId: ctx.sessionId,
|
|
21205
|
+
pluginId: ctx.pluginId,
|
|
21206
|
+
pluginAuthToken: token,
|
|
21207
|
+
method,
|
|
21208
|
+
credential
|
|
21209
|
+
});
|
|
21210
|
+
return r.ok === true;
|
|
21211
|
+
} : void 0;
|
|
21212
|
+
if (action === "link_oauth") {
|
|
21213
|
+
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
21214
|
+
action: "link_oauth",
|
|
21215
|
+
supported: true,
|
|
21216
|
+
installed: true,
|
|
21217
|
+
loggedIn: false,
|
|
21218
|
+
linked: false
|
|
21219
|
+
});
|
|
21220
|
+
void (async () => {
|
|
21221
|
+
try {
|
|
21222
|
+
const result2 = await configureCoderabbit({ action: "link_oauth" }, { onEvent, uploadCredential });
|
|
21223
|
+
emit2("coderabbit_status", {
|
|
21224
|
+
installed: result2.installed,
|
|
21225
|
+
loggedIn: result2.loggedIn,
|
|
21226
|
+
linked: result2.linked ?? false,
|
|
21227
|
+
...result2.error ? { error: result2.error } : {}
|
|
21228
|
+
});
|
|
21229
|
+
} catch (err) {
|
|
21230
|
+
emit2("coderabbit_status", {
|
|
21231
|
+
installed: false,
|
|
21232
|
+
loggedIn: false,
|
|
21233
|
+
linked: false,
|
|
21234
|
+
error: err instanceof Error ? err.message : "CodeRabbit login failed"
|
|
21235
|
+
});
|
|
21236
|
+
}
|
|
21237
|
+
await emitChain;
|
|
21238
|
+
})();
|
|
21239
|
+
return;
|
|
21240
|
+
}
|
|
21141
21241
|
const result = await configureCoderabbit(
|
|
21142
21242
|
{
|
|
21143
21243
|
action,
|
|
@@ -21145,28 +21245,8 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
|
|
|
21145
21245
|
review: { changeSet: parsed.changeSet, base: parsed.base, dir: parsed.reviewDir }
|
|
21146
21246
|
},
|
|
21147
21247
|
{
|
|
21148
|
-
onEvent
|
|
21149
|
-
|
|
21150
|
-
emit2("coderabbit_progress", {
|
|
21151
|
-
phase: "awaiting_browser",
|
|
21152
|
-
authUrl: e.authUrl,
|
|
21153
|
-
fallbackAuthUrl: e.fallbackAuthUrl
|
|
21154
|
-
});
|
|
21155
|
-
} else {
|
|
21156
|
-
emit2("coderabbit_progress", { phase: e.kind });
|
|
21157
|
-
}
|
|
21158
|
-
},
|
|
21159
|
-
uploadCredential: token ? async (method, credential) => {
|
|
21160
|
-
const r = await postLinkCredential({
|
|
21161
|
-
agentId: "coderabbit",
|
|
21162
|
-
sessionId: ctx.sessionId,
|
|
21163
|
-
pluginId: ctx.pluginId,
|
|
21164
|
-
pluginAuthToken: token,
|
|
21165
|
-
method,
|
|
21166
|
-
credential
|
|
21167
|
-
});
|
|
21168
|
-
return r.ok === true;
|
|
21169
|
-
} : void 0,
|
|
21248
|
+
onEvent,
|
|
21249
|
+
uploadCredential,
|
|
21170
21250
|
runReview: (input) => new CoderabbitRuntimeStrategy(createOsStrategy()).runOneShot(input)
|
|
21171
21251
|
}
|
|
21172
21252
|
);
|
|
@@ -23135,7 +23215,7 @@ var fs56 = __toESM(require("fs"));
|
|
|
23135
23215
|
var path61 = __toESM(require("path"));
|
|
23136
23216
|
var os45 = __toESM(require("os"));
|
|
23137
23217
|
var https7 = __toESM(require("https"));
|
|
23138
|
-
var
|
|
23218
|
+
var http7 = __toESM(require("http"));
|
|
23139
23219
|
var import_zod2 = require("zod");
|
|
23140
23220
|
var historyRecordSchema = import_zod2.z.object({
|
|
23141
23221
|
type: import_zod2.z.string().optional(),
|
|
@@ -23200,7 +23280,7 @@ function post(endpoint, body, pluginAuthToken) {
|
|
|
23200
23280
|
return new Promise((resolve7) => {
|
|
23201
23281
|
const payload = JSON.stringify(body);
|
|
23202
23282
|
const u2 = new URL(`${API_BASE8}${endpoint}`);
|
|
23203
|
-
const transport = u2.protocol === "https:" ? https7 :
|
|
23283
|
+
const transport = u2.protocol === "https:" ? https7 : http7;
|
|
23204
23284
|
const req = transport.request(
|
|
23205
23285
|
{
|
|
23206
23286
|
hostname: u2.hostname,
|
|
@@ -26815,7 +26895,7 @@ var relaunchProxyWithoutBudget = async () => {
|
|
|
26815
26895
|
};
|
|
26816
26896
|
|
|
26817
26897
|
// src/services/streaming/transport.ts
|
|
26818
|
-
var
|
|
26898
|
+
var http8 = __toESM(require("http"));
|
|
26819
26899
|
var https8 = __toESM(require("https"));
|
|
26820
26900
|
var _transport4 = {
|
|
26821
26901
|
post: _post3,
|
|
@@ -26825,7 +26905,7 @@ function _post3(url, headers, payload) {
|
|
|
26825
26905
|
return new Promise((resolve7, reject) => {
|
|
26826
26906
|
let settled = false;
|
|
26827
26907
|
const u2 = new URL(url);
|
|
26828
|
-
const lib = u2.protocol === "https:" ? https8 :
|
|
26908
|
+
const lib = u2.protocol === "https:" ? https8 : http8;
|
|
26829
26909
|
const req = lib.request(
|
|
26830
26910
|
{
|
|
26831
26911
|
hostname: u2.hostname,
|
|
@@ -26867,7 +26947,7 @@ function _get(url, headers) {
|
|
|
26867
26947
|
return new Promise((resolve7, reject) => {
|
|
26868
26948
|
let settled = false;
|
|
26869
26949
|
const u2 = new URL(url);
|
|
26870
|
-
const lib = u2.protocol === "https:" ? https8 :
|
|
26950
|
+
const lib = u2.protocol === "https:" ? https8 : http8;
|
|
26871
26951
|
const req = lib.request(
|
|
26872
26952
|
{
|
|
26873
26953
|
hostname: u2.hostname,
|
|
@@ -31322,7 +31402,7 @@ function toEpochMs(ts) {
|
|
|
31322
31402
|
var fs62 = __toESM(require("fs"));
|
|
31323
31403
|
var os48 = __toESM(require("os"));
|
|
31324
31404
|
var path66 = __toESM(require("path"));
|
|
31325
|
-
function ensureClaudeOnboarded() {
|
|
31405
|
+
function ensureClaudeOnboarded(cwd) {
|
|
31326
31406
|
try {
|
|
31327
31407
|
const file = path66.join(os48.homedir(), ".claude.json");
|
|
31328
31408
|
let config = {};
|
|
@@ -31330,17 +31410,33 @@ function ensureClaudeOnboarded() {
|
|
|
31330
31410
|
config = JSON.parse(fs62.readFileSync(file, "utf8"));
|
|
31331
31411
|
} catch {
|
|
31332
31412
|
}
|
|
31333
|
-
|
|
31334
|
-
|
|
31413
|
+
let changed = false;
|
|
31414
|
+
if (config.hasCompletedOnboarding !== true || typeof config.theme !== "string") {
|
|
31415
|
+
config.hasCompletedOnboarding = true;
|
|
31416
|
+
config.theme = typeof config.theme === "string" ? config.theme : "dark";
|
|
31417
|
+
if (typeof config.lastOnboardingVersion !== "string") {
|
|
31418
|
+
config.lastOnboardingVersion = "2.1.177";
|
|
31419
|
+
}
|
|
31420
|
+
changed = true;
|
|
31335
31421
|
}
|
|
31336
|
-
|
|
31337
|
-
|
|
31338
|
-
|
|
31339
|
-
|
|
31422
|
+
if (cwd) {
|
|
31423
|
+
const projects = config.projects && typeof config.projects === "object" ? config.projects : {};
|
|
31424
|
+
const entry = projects[cwd] && typeof projects[cwd] === "object" ? projects[cwd] : {};
|
|
31425
|
+
if (entry.hasTrustDialogAccepted !== true || entry.hasCompletedProjectOnboarding !== true) {
|
|
31426
|
+
entry.hasTrustDialogAccepted = true;
|
|
31427
|
+
entry.hasCompletedProjectOnboarding = true;
|
|
31428
|
+
projects[cwd] = entry;
|
|
31429
|
+
config.projects = projects;
|
|
31430
|
+
changed = true;
|
|
31431
|
+
}
|
|
31340
31432
|
}
|
|
31433
|
+
if (!changed) return;
|
|
31341
31434
|
fs62.mkdirSync(path66.dirname(file), { recursive: true });
|
|
31342
31435
|
fs62.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
31343
|
-
log.info(
|
|
31436
|
+
log.info(
|
|
31437
|
+
"claude",
|
|
31438
|
+
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
31439
|
+
);
|
|
31344
31440
|
} catch (err) {
|
|
31345
31441
|
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
31346
31442
|
}
|
|
@@ -31425,7 +31521,7 @@ async function start(requestedAgent) {
|
|
|
31425
31521
|
process.once("exit", () => {
|
|
31426
31522
|
localHeadroomReporter?.stop();
|
|
31427
31523
|
});
|
|
31428
|
-
if (
|
|
31524
|
+
if (!isLocalSession()) ensureClaudeOnboarded(cwd);
|
|
31429
31525
|
let beads = null;
|
|
31430
31526
|
const getBeads = () => beads;
|
|
31431
31527
|
const beadsReady = provisionBeadsForStart({
|
|
@@ -34227,7 +34323,7 @@ function checkChokidar() {
|
|
|
34227
34323
|
}
|
|
34228
34324
|
async function doctor(args2 = []) {
|
|
34229
34325
|
const json = args2.includes("--json");
|
|
34230
|
-
const cliVersion = true ? "2.60.
|
|
34326
|
+
const cliVersion = true ? "2.60.34" : "0.0.0-dev";
|
|
34231
34327
|
const apiBase2 = resolveApiBaseUrl();
|
|
34232
34328
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
34233
34329
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -34426,7 +34522,7 @@ async function completion(args2) {
|
|
|
34426
34522
|
// src/commands/version.ts
|
|
34427
34523
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
34428
34524
|
function version2() {
|
|
34429
|
-
const v = true ? "2.60.
|
|
34525
|
+
const v = true ? "2.60.34" : "unknown";
|
|
34430
34526
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
34431
34527
|
}
|
|
34432
34528
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.34",
|
|
4
4
|
"description": "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|