codeam-cli 2.60.42 → 2.60.44
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 +61 -21
- 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.43] — 2026-07-10
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Keep relay daemon alive on stray unhandled rejection
|
|
12
|
+
|
|
13
|
+
## [2.60.42] — 2026-07-10
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **cli:** CodeRabbit 'provision' action — restore the vaulted credential, no re-login
|
|
18
|
+
|
|
7
19
|
## [2.60.41] — 2026-07-10
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -5689,7 +5689,7 @@ function readAnonId() {
|
|
|
5689
5689
|
}
|
|
5690
5690
|
function superProperties() {
|
|
5691
5691
|
return {
|
|
5692
|
-
cliVersion: true ? "2.60.
|
|
5692
|
+
cliVersion: true ? "2.60.44" : "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.44",
|
|
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",
|
|
@@ -6979,7 +6979,7 @@ var CommandRelayService = class {
|
|
|
6979
6979
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6980
6980
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6981
6981
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6982
|
-
..."2.60.
|
|
6982
|
+
..."2.60.44" ? { ideVersion: "2.60.44" } : {}
|
|
6983
6983
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6984
6984
|
}
|
|
6985
6985
|
/**
|
|
@@ -12438,8 +12438,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
12438
12438
|
const sessionArgs = ["--session-id", sessionId];
|
|
12439
12439
|
let launch = buildClaudeLaunch(sessionArgs, this.os);
|
|
12440
12440
|
if (!launch) {
|
|
12441
|
-
const
|
|
12442
|
-
if (
|
|
12441
|
+
const installed2 = await ensureClaudeInstalled();
|
|
12442
|
+
if (installed2) launch = buildClaudeLaunch(sessionArgs, this.os);
|
|
12443
12443
|
}
|
|
12444
12444
|
if (!launch) {
|
|
12445
12445
|
const cmd = this.os.id === "win32" ? "irm https://claude.ai/install.ps1 | iex" : "curl -fsSL https://claude.ai/install.sh | bash";
|
|
@@ -15304,8 +15304,8 @@ async function link(args2 = []) {
|
|
|
15304
15304
|
}
|
|
15305
15305
|
const installSpin = dist_exports.spinner();
|
|
15306
15306
|
installSpin.start(`Checking that ${ctx.binary} is installed...`);
|
|
15307
|
-
const
|
|
15308
|
-
if (!
|
|
15307
|
+
const installed2 = await ctx.launcher.ensureInstalled();
|
|
15308
|
+
if (!installed2) {
|
|
15309
15309
|
installSpin.stop("Failed");
|
|
15310
15310
|
showError(`Could not install ${ctx.displayName}. Install it manually then re-run.`);
|
|
15311
15311
|
process.exit(1);
|
|
@@ -15814,7 +15814,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15814
15814
|
path36.join(home, "scoop", "shims")
|
|
15815
15815
|
] : [path36.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
|
|
15816
15816
|
);
|
|
15817
|
-
const
|
|
15817
|
+
const installed2 = os50.findInPath("coderabbit") !== null;
|
|
15818
15818
|
const base = () => ({
|
|
15819
15819
|
action: input.action,
|
|
15820
15820
|
supported: true,
|
|
@@ -15884,7 +15884,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
15884
15884
|
}
|
|
15885
15885
|
if (input.action === "link_oauth") {
|
|
15886
15886
|
const res2 = base();
|
|
15887
|
-
if (!
|
|
15887
|
+
if (!installed2) {
|
|
15888
15888
|
deps.onEvent?.({ kind: "installing" });
|
|
15889
15889
|
const ok = await ensureInstalled(os50);
|
|
15890
15890
|
res2.installed = ok;
|
|
@@ -17493,7 +17493,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17493
17493
|
if (process.env.NODE_ENV === "test") return;
|
|
17494
17494
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17495
17495
|
if (process.env.CI) return;
|
|
17496
|
-
const current = true ? "2.60.
|
|
17496
|
+
const current = true ? "2.60.44" : null;
|
|
17497
17497
|
if (!current) return;
|
|
17498
17498
|
const cache = readCache();
|
|
17499
17499
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17510,7 +17510,7 @@ function checkForUpdates() {
|
|
|
17510
17510
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17511
17511
|
if (process.env.CI) return;
|
|
17512
17512
|
if (!process.stdout.isTTY) return;
|
|
17513
|
-
const current = true ? "2.60.
|
|
17513
|
+
const current = true ? "2.60.44" : null;
|
|
17514
17514
|
if (!current) return;
|
|
17515
17515
|
const cache = readCache();
|
|
17516
17516
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17530,7 +17530,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17530
17530
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17531
17531
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17532
17532
|
function currentCliVersion() {
|
|
17533
|
-
return true ? "2.60.
|
|
17533
|
+
return true ? "2.60.44" : null;
|
|
17534
17534
|
}
|
|
17535
17535
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17536
17536
|
return new Promise((resolve7) => {
|
|
@@ -17584,8 +17584,8 @@ async function runSelfUpdate() {
|
|
|
17584
17584
|
["view", SELF_UPDATE_PKG, "version"],
|
|
17585
17585
|
SELF_UPDATE_VIEW_TIMEOUT_MS
|
|
17586
17586
|
);
|
|
17587
|
-
const
|
|
17588
|
-
return { status: "updated", version:
|
|
17587
|
+
const installed2 = after.code === 0 ? after.stdout.trim() || latest : latest;
|
|
17588
|
+
return { status: "updated", version: installed2 };
|
|
17589
17589
|
} catch (err) {
|
|
17590
17590
|
log.warn(
|
|
17591
17591
|
"host-agent",
|
|
@@ -22369,6 +22369,29 @@ function buildKeepAlive(ctx) {
|
|
|
22369
22369
|
};
|
|
22370
22370
|
}
|
|
22371
22371
|
|
|
22372
|
+
// src/lib/process-guards.ts
|
|
22373
|
+
var installed = false;
|
|
22374
|
+
function installRelayCrashGuards() {
|
|
22375
|
+
if (installed) return;
|
|
22376
|
+
installed = true;
|
|
22377
|
+
process.on("unhandledRejection", (reason) => {
|
|
22378
|
+
log.error("process", `unhandledRejection \u2014 relay kept alive \u2014 ${describeReason(reason)}`);
|
|
22379
|
+
});
|
|
22380
|
+
process.on("uncaughtException", (err) => {
|
|
22381
|
+
log.error("process", `uncaughtException \u2014 relay kept alive \u2014 ${describeReason(err)}`);
|
|
22382
|
+
});
|
|
22383
|
+
}
|
|
22384
|
+
function describeReason(reason) {
|
|
22385
|
+
if (reason instanceof Error) {
|
|
22386
|
+
return reason.stack ?? `${reason.name}: ${reason.message}`;
|
|
22387
|
+
}
|
|
22388
|
+
try {
|
|
22389
|
+
return typeof reason === "string" ? reason : JSON.stringify(reason);
|
|
22390
|
+
} catch {
|
|
22391
|
+
return String(reason);
|
|
22392
|
+
}
|
|
22393
|
+
}
|
|
22394
|
+
|
|
22372
22395
|
// src/commands/start-infra-only.ts
|
|
22373
22396
|
var INFRA_ONLY_COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
22374
22397
|
// File ops (drive the dashboard's Files panel + open-file).
|
|
@@ -22402,6 +22425,7 @@ var INFRA_ONLY_COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
|
22402
22425
|
"set_keep_alive"
|
|
22403
22426
|
]);
|
|
22404
22427
|
async function startInfraOnly(agentId) {
|
|
22428
|
+
installRelayCrashGuards();
|
|
22405
22429
|
const session = getActiveSession();
|
|
22406
22430
|
if (!session?.pluginId) {
|
|
22407
22431
|
throw new Error("startInfraOnly: no active session found in config");
|
|
@@ -22740,6 +22764,7 @@ function acquireSingletonLock() {
|
|
|
22740
22764
|
}
|
|
22741
22765
|
}
|
|
22742
22766
|
async function pairAuto(args2) {
|
|
22767
|
+
installRelayCrashGuards();
|
|
22743
22768
|
if (!acquireSingletonLock()) {
|
|
22744
22769
|
capture("pair_auto_deferred_singleton", {});
|
|
22745
22770
|
console.log(" A codeam session is already running here \u2014 deferring to it.");
|
|
@@ -23292,7 +23317,8 @@ async function waitForCursorAgent(opts = {}) {
|
|
|
23292
23317
|
}
|
|
23293
23318
|
return check();
|
|
23294
23319
|
}
|
|
23295
|
-
var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_REQUIRE_ESM|ERR_UNKNOWN_BUILTIN_MODULE|SyntaxError|Unexpected (token|end|identifier)|missing \) after argument list/i;
|
|
23320
|
+
var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_REQUIRE_ESM|ERR_UNKNOWN_BUILTIN_MODULE|ERR_UNSUPPORTED_DIR_IMPORT|ERR_PACKAGE_PATH_NOT_EXPORTED|ERR_INVALID_PACKAGE_CONFIG|ERR_INVALID_PACKAGE_TARGET|ERR_INVALID_MODULE_SPECIFIER|node:internal\/modules\/|Directory import|SyntaxError|Unexpected (token|end|identifier)|missing \) after argument list/i;
|
|
23321
|
+
var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
|
|
23296
23322
|
function probeAdapterModuleGraph(command2, args2, opts = {}) {
|
|
23297
23323
|
const livenessMs = opts.livenessMs ?? 400;
|
|
23298
23324
|
const spawnFn = opts.spawnFn ?? import_child_process25.spawn;
|
|
@@ -23323,7 +23349,7 @@ function probeAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
23323
23349
|
});
|
|
23324
23350
|
child.on("error", () => finish("ok"));
|
|
23325
23351
|
child.on("exit", (code) => {
|
|
23326
|
-
if (code !== 0 && code !== null &&
|
|
23352
|
+
if (code !== 0 && code !== null && !PERMANENT_ADAPTER_STARTUP_RE.test(stderr)) {
|
|
23327
23353
|
finish("transient");
|
|
23328
23354
|
} else {
|
|
23329
23355
|
finish("ok");
|
|
@@ -26602,6 +26628,14 @@ function createIdleTimeout(idleMs, makeError) {
|
|
|
26602
26628
|
// src/agents/acp/client.ts
|
|
26603
26629
|
var TRANSIENT_ADAPTER_SPAWN_RE = /ETXTBSY|ENOENT/;
|
|
26604
26630
|
var MAX_START_ATTEMPTS = 5;
|
|
26631
|
+
var TRANSPORT_DOWN_DURING_START_RE = /connection (is )?closed|stream (is )?closed|ECONNRESET|EPIPE|write after end|premature close/i;
|
|
26632
|
+
var AdapterStartCrashError = class extends Error {
|
|
26633
|
+
adapterExitedDuringStart = true;
|
|
26634
|
+
constructor(message) {
|
|
26635
|
+
super(message);
|
|
26636
|
+
this.name = "AdapterStartCrashError";
|
|
26637
|
+
}
|
|
26638
|
+
};
|
|
26605
26639
|
var _acpStartSeam = {
|
|
26606
26640
|
sleep: (ms) => new Promise((r) => setTimeout(r, ms))
|
|
26607
26641
|
};
|
|
@@ -26706,6 +26740,7 @@ var AcpClient = class {
|
|
|
26706
26740
|
* Checks the thrown error's message/data AND the adapter stderr ring — the
|
|
26707
26741
|
* adapter logs the real cause to stderr while returning a generic error. */
|
|
26708
26742
|
isTransientAdapterSpawn(err) {
|
|
26743
|
+
if (err instanceof AdapterStartCrashError) return true;
|
|
26709
26744
|
const parts = [...this.recentStderr];
|
|
26710
26745
|
if (err instanceof Error) parts.push(err.message);
|
|
26711
26746
|
if (err && typeof err === "object") {
|
|
@@ -26717,7 +26752,9 @@ var AcpClient = class {
|
|
|
26717
26752
|
if (typeof e.details === "string") parts.push(e.details);
|
|
26718
26753
|
}
|
|
26719
26754
|
const joined = parts.join(" ");
|
|
26720
|
-
return TRANSIENT_ADAPTER_SPAWN_RE.test(joined) || ADAPTER_MODULE_LOAD_ERROR_RE.test(joined)
|
|
26755
|
+
return TRANSIENT_ADAPTER_SPAWN_RE.test(joined) || ADAPTER_MODULE_LOAD_ERROR_RE.test(joined) || // The transport dying mid-handshake = the adapter crashed starting up,
|
|
26756
|
+
// even when the child-exit handler lost the race (see the RE's doc).
|
|
26757
|
+
TRANSPORT_DOWN_DURING_START_RE.test(joined);
|
|
26721
26758
|
}
|
|
26722
26759
|
async startOnce() {
|
|
26723
26760
|
if (this.child) throw new Error("AcpClient already started");
|
|
@@ -26759,7 +26796,7 @@ var AcpClient = class {
|
|
|
26759
26796
|
if (this.startAbortReject) {
|
|
26760
26797
|
const tail = this.recentStderr.slice(-6).join(" | ");
|
|
26761
26798
|
this.startAbortReject(
|
|
26762
|
-
new
|
|
26799
|
+
new AdapterStartCrashError(
|
|
26763
26800
|
`ADAPTER_EXITED_DURING_START code=${code} signal=${signal}${tail ? ` \u2014 ${tail}` : ""}`
|
|
26764
26801
|
)
|
|
26765
26802
|
);
|
|
@@ -28195,7 +28232,9 @@ var FilesOutbox = class {
|
|
|
28195
28232
|
const jittered = delayMs === 0 ? 0 : applyJitter(delayMs);
|
|
28196
28233
|
this.flushTimer = setTimeout(() => {
|
|
28197
28234
|
this.flushTimer = null;
|
|
28198
|
-
|
|
28235
|
+
this.flush().catch((err) => {
|
|
28236
|
+
log.warn("turnFiles", `outbox flush loop threw: ${err.message}`);
|
|
28237
|
+
});
|
|
28199
28238
|
}, jittered);
|
|
28200
28239
|
}
|
|
28201
28240
|
async flush() {
|
|
@@ -31759,6 +31798,7 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
31759
31798
|
|
|
31760
31799
|
// src/commands/start.ts
|
|
31761
31800
|
async function start(requestedAgent) {
|
|
31801
|
+
installRelayCrashGuards();
|
|
31762
31802
|
showIntro();
|
|
31763
31803
|
const session = requestedAgent ? getActiveSessionForAgent(requestedAgent) : getActiveSession();
|
|
31764
31804
|
if (!session) {
|
|
@@ -34638,7 +34678,7 @@ function checkChokidar() {
|
|
|
34638
34678
|
}
|
|
34639
34679
|
async function doctor(args2 = []) {
|
|
34640
34680
|
const json = args2.includes("--json");
|
|
34641
|
-
const cliVersion = true ? "2.60.
|
|
34681
|
+
const cliVersion = true ? "2.60.44" : "0.0.0-dev";
|
|
34642
34682
|
const apiBase2 = resolveApiBaseUrl();
|
|
34643
34683
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
34644
34684
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -34837,7 +34877,7 @@ async function completion(args2) {
|
|
|
34837
34877
|
// src/commands/version.ts
|
|
34838
34878
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
34839
34879
|
function version2() {
|
|
34840
|
-
const v = true ? "2.60.
|
|
34880
|
+
const v = true ? "2.60.44" : "unknown";
|
|
34841
34881
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
34842
34882
|
}
|
|
34843
34883
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.44",
|
|
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",
|