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.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.js +141 -45
  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.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.32" : "0.0.0-dev",
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.32",
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.32" ? { ideVersion: "2.60.32" } : {}
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.32" : null;
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.32" : null;
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.32" : null;
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 action = parsed.action ?? "status";
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: (e) => {
21149
- if (e.kind === "awaiting_browser") {
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 http6 = __toESM(require("http"));
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 : http6;
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 http7 = __toESM(require("http"));
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 : http7;
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 : http7;
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
- if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
31334
- return;
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
- config.hasCompletedOnboarding = true;
31337
- config.theme = typeof config.theme === "string" ? config.theme : "dark";
31338
- if (typeof config.lastOnboardingVersion !== "string") {
31339
- config.lastOnboardingVersion = "2.1.177";
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("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
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 (process.env.CODESPACES === "true") ensureClaudeOnboarded();
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.32" : "0.0.0-dev";
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.32" : "unknown";
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.32",
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",