codeam-cli 2.76.19 → 2.76.21
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 +20 -0
- package/dist/index.js +97 -23
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ 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.76.20] — 2026-10-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** Own the Composer, feature-gate and compression-savings wire types (#934)
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **cli:** Wake recreates a fleet box whose container is gone but volume remains (#933)
|
|
16
|
+
- **cli:** Provision aider credentials on self-hosted and Box deploys (#935)
|
|
17
|
+
- **both-plugins:** Open the command SSE on the stream host, not apiBaseUrl (#936)
|
|
18
|
+
- **cli:** Keep the typed blocker tag on failure bubbles in pushed history (#937)
|
|
19
|
+
- **cli:** Point USERPROFILE at the tmp home in the re-link credential test (#938)
|
|
20
|
+
|
|
21
|
+
## [2.76.19] — 2026-10-09
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **cli:** Send sessionId on turn-events so PluginAuthGuard stops 401ing them (#929)
|
|
26
|
+
|
|
7
27
|
## [2.76.18] — 2026-10-09
|
|
8
28
|
|
|
9
29
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -10617,7 +10617,7 @@ function readAnonId() {
|
|
|
10617
10617
|
}
|
|
10618
10618
|
function superProperties() {
|
|
10619
10619
|
return {
|
|
10620
|
-
cliVersion: true ? "2.76.
|
|
10620
|
+
cliVersion: true ? "2.76.21" : "0.0.0-dev",
|
|
10621
10621
|
nodeVersion: process.version,
|
|
10622
10622
|
platform: process.platform,
|
|
10623
10623
|
arch: process.arch,
|
|
@@ -10866,7 +10866,7 @@ var http = __toESM(require("http"));
|
|
|
10866
10866
|
// package.json
|
|
10867
10867
|
var package_default = {
|
|
10868
10868
|
name: "codeam-cli",
|
|
10869
|
-
version: "2.76.
|
|
10869
|
+
version: "2.76.21",
|
|
10870
10870
|
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.",
|
|
10871
10871
|
type: "commonjs",
|
|
10872
10872
|
main: "dist/index.js",
|
|
@@ -12229,7 +12229,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12229
12229
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12230
12230
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12231
12231
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12232
|
-
..."2.76.
|
|
12232
|
+
..."2.76.21" ? { ideVersion: "2.76.21" } : {}
|
|
12233
12233
|
};
|
|
12234
12234
|
try {
|
|
12235
12235
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body, this.pollSecretHeader());
|
|
@@ -38474,7 +38474,7 @@ var coderabbitProvisioner = {
|
|
|
38474
38474
|
return {};
|
|
38475
38475
|
}
|
|
38476
38476
|
};
|
|
38477
|
-
var
|
|
38477
|
+
var providerKeyProvisioner = {
|
|
38478
38478
|
write(auth) {
|
|
38479
38479
|
const key = auth.value.trim();
|
|
38480
38480
|
const envName = key.startsWith("sk-ant-") ? "ANTHROPIC_API_KEY" : key.startsWith("AIza") ? "GEMINI_API_KEY" : "OPENAI_API_KEY";
|
|
@@ -38488,7 +38488,11 @@ var PROVISIONERS = {
|
|
|
38488
38488
|
gemini: geminiProvisioner,
|
|
38489
38489
|
cursor: cursorProvisioner,
|
|
38490
38490
|
coderabbit: coderabbitProvisioner,
|
|
38491
|
-
opencode:
|
|
38491
|
+
opencode: providerKeyProvisioner,
|
|
38492
|
+
// ⚠️ Was missing: every self-hosted / fleet-Box aider deploy failed with
|
|
38493
|
+
// "Self-hosted provisioning is not implemented for agent "aider"" (23 in
|
|
38494
|
+
// prod Cloud Run, 2026-09-10..10-08).
|
|
38495
|
+
aider: providerKeyProvisioner
|
|
38492
38496
|
};
|
|
38493
38497
|
var UnsupportedAgentError = class extends Error {
|
|
38494
38498
|
agentId;
|
|
@@ -44485,12 +44489,14 @@ var AcpHistory = class {
|
|
|
44485
44489
|
*/
|
|
44486
44490
|
appendAgentReply(text, agentId = this.opts.agent) {
|
|
44487
44491
|
if (text.length === 0) return;
|
|
44492
|
+
const blocker = failureBlocker(text);
|
|
44488
44493
|
this.messages.push({
|
|
44489
44494
|
id: (0, import_node_crypto15.randomUUID)(),
|
|
44490
44495
|
role: "agent",
|
|
44491
44496
|
text,
|
|
44492
44497
|
timestamp: Date.now(),
|
|
44493
|
-
agentId
|
|
44498
|
+
agentId,
|
|
44499
|
+
...blocker ? { blocker } : {}
|
|
44494
44500
|
});
|
|
44495
44501
|
}
|
|
44496
44502
|
/**
|
|
@@ -46376,7 +46382,7 @@ function sanitizeRetiredProxyConfig(homeDir2 = os62.homedir()) {
|
|
|
46376
46382
|
// src/integrations/refresh-manifest.ts
|
|
46377
46383
|
function fingerprint(m) {
|
|
46378
46384
|
const norm = [...m.integrations].map((e) => ({ id: e.id, delivery: e.delivery })).sort((a, b) => a.id.localeCompare(b.id));
|
|
46379
|
-
return JSON.stringify(norm);
|
|
46385
|
+
return JSON.stringify({ integrations: norm, toolRouter: m.toolRouter === true });
|
|
46380
46386
|
}
|
|
46381
46387
|
async function refreshIntegrationsManifest(ctx, fetchImpl = fetch, timeoutMs = 8e3) {
|
|
46382
46388
|
const result = await fetchAndPersist(ctx, fetchImpl, timeoutMs);
|
|
@@ -51218,7 +51224,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
51218
51224
|
if (process.env.NODE_ENV === "test") return;
|
|
51219
51225
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
51220
51226
|
if (process.env.CI) return;
|
|
51221
|
-
const current2 = true ? "2.76.
|
|
51227
|
+
const current2 = true ? "2.76.21" : null;
|
|
51222
51228
|
if (!current2) return;
|
|
51223
51229
|
const cache = readCache();
|
|
51224
51230
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -51235,7 +51241,7 @@ function checkForUpdates() {
|
|
|
51235
51241
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
51236
51242
|
if (process.env.CI) return;
|
|
51237
51243
|
if (!process.stdout.isTTY) return;
|
|
51238
|
-
const current2 = true ? "2.76.
|
|
51244
|
+
const current2 = true ? "2.76.21" : null;
|
|
51239
51245
|
if (!current2) return;
|
|
51240
51246
|
const cache = readCache();
|
|
51241
51247
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -51517,7 +51523,7 @@ var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
|
51517
51523
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
51518
51524
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
51519
51525
|
function currentCliVersion() {
|
|
51520
|
-
return true ? "2.76.
|
|
51526
|
+
return true ? "2.76.21" : null;
|
|
51521
51527
|
}
|
|
51522
51528
|
async function installedVersion(deps) {
|
|
51523
51529
|
const ls = await deps.run(
|
|
@@ -51728,7 +51734,7 @@ function signalHostReady(send = process.send?.bind(process)) {
|
|
|
51728
51734
|
}
|
|
51729
51735
|
function defaultDeps() {
|
|
51730
51736
|
return {
|
|
51731
|
-
ownVersion: true ? "2.76.
|
|
51737
|
+
ownVersion: true ? "2.76.21" : null,
|
|
51732
51738
|
root: cliVersionsRoot(),
|
|
51733
51739
|
args: process.argv.slice(3),
|
|
51734
51740
|
execPath: process.execPath,
|
|
@@ -52307,6 +52313,15 @@ var HostAgentSupervisor = class {
|
|
|
52307
52313
|
* one session's crash-loop must not spend another's retry budget).
|
|
52308
52314
|
*/
|
|
52309
52315
|
resumeStates = /* @__PURE__ */ new Map();
|
|
52316
|
+
/**
|
|
52317
|
+
* Env-delivered agent credentials per deploy (the `api_key` path:
|
|
52318
|
+
* ANTHROPIC_API_KEY / GEMINI_API_KEY / CURSOR_API_KEY / OPENAI_API_KEY).
|
|
52319
|
+
* Such a key lives ONLY in the child's spawn env — nothing on disk carries
|
|
52320
|
+
* it — so every re-spawn of the session (crash respawn, resume, a re-link
|
|
52321
|
+
* restart) must re-inject it. Memory only: credential plaintext is never
|
|
52322
|
+
* persisted by the host-agent (codeagent-5m12).
|
|
52323
|
+
*/
|
|
52324
|
+
credentialEnvByDeploy = /* @__PURE__ */ new Map();
|
|
52310
52325
|
/** Set once the bounded retries exhaust → heartbeat-ridden slow re-probe. */
|
|
52311
52326
|
/** True after stop() — no resume retries may be scheduled past teardown. */
|
|
52312
52327
|
stopped = false;
|
|
@@ -52827,6 +52842,7 @@ var HostAgentSupervisor = class {
|
|
|
52827
52842
|
async fleetMigrateBoxImage(payload) {
|
|
52828
52843
|
const { containerName } = payload;
|
|
52829
52844
|
const state = await this.docker.run([
|
|
52845
|
+
"container",
|
|
52830
52846
|
"inspect",
|
|
52831
52847
|
"--format",
|
|
52832
52848
|
"{{.State.Running}}",
|
|
@@ -52939,7 +52955,13 @@ var HostAgentSupervisor = class {
|
|
|
52939
52955
|
async fleetBoxImageStale(containerName) {
|
|
52940
52956
|
if (process.env.CODEAM_FLEET_BOX_IMAGE) return false;
|
|
52941
52957
|
const image = resolveFleetBoxImage();
|
|
52942
|
-
const cur = await this.docker.run([
|
|
52958
|
+
const cur = await this.docker.run([
|
|
52959
|
+
"container",
|
|
52960
|
+
"inspect",
|
|
52961
|
+
"--format",
|
|
52962
|
+
"{{.Image}}",
|
|
52963
|
+
containerName
|
|
52964
|
+
]);
|
|
52943
52965
|
if (cur.code !== 0) {
|
|
52944
52966
|
return isMissingContainerError(cur.stderr);
|
|
52945
52967
|
}
|
|
@@ -53216,6 +53238,8 @@ var HostAgentSupervisor = class {
|
|
|
53216
53238
|
} else {
|
|
53217
53239
|
const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
|
|
53218
53240
|
const credEnv = provisionAgentCredentials(payload.agentId, auth, void 0);
|
|
53241
|
+
if (Object.keys(credEnv).length > 0) this.credentialEnvByDeploy.set(payload.deployId, credEnv);
|
|
53242
|
+
else this.credentialEnvByDeploy.delete(payload.deployId);
|
|
53219
53243
|
childEnv = {
|
|
53220
53244
|
...credEnv,
|
|
53221
53245
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
@@ -53613,7 +53637,11 @@ var HostAgentSupervisor = class {
|
|
|
53613
53637
|
`resume: session ${session.id.slice(0, 8)} deploy=${deployId.slice(0, 8)} cwd=${cwd}`
|
|
53614
53638
|
);
|
|
53615
53639
|
const proc = this.resumeSpawner(
|
|
53616
|
-
{
|
|
53640
|
+
{
|
|
53641
|
+
...readHouseProxyChildEnv(deployId),
|
|
53642
|
+
...this.credentialEnvByDeploy.get(deployId) ?? {},
|
|
53643
|
+
CODEAM_RESUME_SESSION_ID: session.id
|
|
53644
|
+
},
|
|
53617
53645
|
cwd
|
|
53618
53646
|
);
|
|
53619
53647
|
const child = {
|
|
@@ -53821,6 +53849,7 @@ var HostAgentSupervisor = class {
|
|
|
53821
53849
|
*/
|
|
53822
53850
|
cleanupWorkspace(deployId) {
|
|
53823
53851
|
const short = deployId.slice(0, 8);
|
|
53852
|
+
this.credentialEnvByDeploy.delete(deployId);
|
|
53824
53853
|
const child = this.children.get(deployId);
|
|
53825
53854
|
if (child) {
|
|
53826
53855
|
try {
|
|
@@ -53847,20 +53876,43 @@ var HostAgentSupervisor = class {
|
|
|
53847
53876
|
}
|
|
53848
53877
|
/**
|
|
53849
53878
|
* Handle `self_hosted_refresh_credentials` (the user re-linked the agent).
|
|
53850
|
-
* Unseal the fresh credential and re-provision the agent's
|
|
53851
|
-
*
|
|
53852
|
-
*
|
|
53853
|
-
*
|
|
53854
|
-
*
|
|
53855
|
-
*
|
|
53879
|
+
* Unseal the fresh credential and re-provision the agent's auth IN PLACE.
|
|
53880
|
+
*
|
|
53881
|
+
* Two delivery shapes, two outcomes (codeagent-5m12):
|
|
53882
|
+
* - **Login-state FILE** (`oauth_token`; `provisionAgentCredentials`
|
|
53883
|
+
* returns `{}`): the file is rewritten and running children are left
|
|
53884
|
+
* alone. Claude Code and Codex re-read their auth file on a 401 (Claude's
|
|
53885
|
+
* `oauth_401_recovered_from_disk`, Codex's `UnauthorizedRecovery` Reload
|
|
53886
|
+
* step), so a 401'd session recovers without losing its turn.
|
|
53887
|
+
* - **Env var** (`api_key`; it returns e.g. `{ ANTHROPIC_API_KEY }`): the
|
|
53888
|
+
* key exists only in each child's spawn env, which a rewrite cannot reach
|
|
53889
|
+
* — the old key keeps 401ing until the process is replaced. Every running
|
|
53890
|
+
* child of THIS agent is restarted through the resume path with the new
|
|
53891
|
+
* env (same conversation, `CODEAM_RESUME_SESSION_ID`).
|
|
53892
|
+
*
|
|
53893
|
+
* Best-effort: a failure is logged, never throws (the relay dispatch must
|
|
53894
|
+
* not crash).
|
|
53856
53895
|
*/
|
|
53857
53896
|
async refreshCredentials(payload) {
|
|
53858
53897
|
try {
|
|
53859
53898
|
const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
|
|
53860
|
-
provisionAgentCredentials(payload.agentId, auth, void 0);
|
|
53899
|
+
const credEnv = provisionAgentCredentials(payload.agentId, auth, void 0);
|
|
53900
|
+
const affected = [...this.children.values()].filter((c2) => c2.agent === payload.agentId);
|
|
53901
|
+
if (Object.keys(credEnv).length === 0) {
|
|
53902
|
+
for (const c2 of affected) this.credentialEnvByDeploy.delete(c2.deployId);
|
|
53903
|
+
log.info(
|
|
53904
|
+
"host-agent",
|
|
53905
|
+
`refreshed credentials in place for agent=${payload.agentId} (${this.children.size} active child(ren))`
|
|
53906
|
+
);
|
|
53907
|
+
return;
|
|
53908
|
+
}
|
|
53909
|
+
for (const child of affected) {
|
|
53910
|
+
this.credentialEnvByDeploy.set(child.deployId, credEnv);
|
|
53911
|
+
this.restartWithFreshCredentials(child);
|
|
53912
|
+
}
|
|
53861
53913
|
log.info(
|
|
53862
53914
|
"host-agent",
|
|
53863
|
-
`refreshed
|
|
53915
|
+
`refreshed env credential for agent=${payload.agentId}; restarted ${affected.length} child(ren)`
|
|
53864
53916
|
);
|
|
53865
53917
|
} catch (err) {
|
|
53866
53918
|
log.warn(
|
|
@@ -53869,6 +53921,28 @@ var HostAgentSupervisor = class {
|
|
|
53869
53921
|
);
|
|
53870
53922
|
}
|
|
53871
53923
|
}
|
|
53924
|
+
/**
|
|
53925
|
+
* Replace one session child so it picks up a re-linked env credential.
|
|
53926
|
+
* Kill THEN untrack (an intentional stop, so its exit handler neither
|
|
53927
|
+
* reports `ended` nor crash-respawns), then resume the same conversation;
|
|
53928
|
+
* `resumeOne` waits out the dying daemon if it still holds the session.
|
|
53929
|
+
*/
|
|
53930
|
+
restartWithFreshCredentials(child) {
|
|
53931
|
+
const session = pickSavedSessionForWorkspace(this.listSavedSessions(), child.cwd, child.deployId);
|
|
53932
|
+
if (!session) {
|
|
53933
|
+
log.warn(
|
|
53934
|
+
"host-agent",
|
|
53935
|
+
`credential refresh: no saved pairing for deploy=${child.deployId.slice(0, 8)} \u2014 it keeps the old key until its next restart`
|
|
53936
|
+
);
|
|
53937
|
+
return;
|
|
53938
|
+
}
|
|
53939
|
+
try {
|
|
53940
|
+
child.proc.kill("SIGTERM");
|
|
53941
|
+
} catch {
|
|
53942
|
+
}
|
|
53943
|
+
this.untrackChild(child.deployId);
|
|
53944
|
+
this.resumeOne({ deployId: child.deployId, cwd: child.cwd, session, agent: child.agent });
|
|
53945
|
+
}
|
|
53872
53946
|
};
|
|
53873
53947
|
async function resolveHostIdentity(enrollToken) {
|
|
53874
53948
|
const existing = ensureControlPollSecret(loadHostIdentity());
|
|
@@ -54171,7 +54245,7 @@ function checkChokidar() {
|
|
|
54171
54245
|
}
|
|
54172
54246
|
async function doctor(args2 = []) {
|
|
54173
54247
|
const json = args2.includes("--json");
|
|
54174
|
-
const cliVersion = true ? "2.76.
|
|
54248
|
+
const cliVersion = true ? "2.76.21" : "0.0.0-dev";
|
|
54175
54249
|
const apiBase2 = resolveApiBaseUrl();
|
|
54176
54250
|
const diagnosticId = (0, import_node_crypto17.randomUUID)();
|
|
54177
54251
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -54707,7 +54781,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
54707
54781
|
// src/commands/version.ts
|
|
54708
54782
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
54709
54783
|
function version2() {
|
|
54710
|
-
const v = true ? "2.76.
|
|
54784
|
+
const v = true ? "2.76.21" : "unknown";
|
|
54711
54785
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
54712
54786
|
}
|
|
54713
54787
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.76.
|
|
3
|
+
"version": "2.76.21",
|
|
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",
|