codeam-cli 2.75.32 → 2.75.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 +57 -17
- 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.75.33] — 2026-09-26
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Keep a fresher Codex login; legacy hosts self-enrol their poll secret (#830)
|
|
12
|
+
|
|
13
|
+
## [2.75.32] — 2026-09-26
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Clear a preview that died with its machine on the first heartbeat (#828)
|
|
18
|
+
|
|
7
19
|
## [2.75.31] — 2026-09-26
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -10516,7 +10516,7 @@ function readAnonId() {
|
|
|
10516
10516
|
}
|
|
10517
10517
|
function superProperties() {
|
|
10518
10518
|
return {
|
|
10519
|
-
cliVersion: true ? "2.75.
|
|
10519
|
+
cliVersion: true ? "2.75.34" : "0.0.0-dev",
|
|
10520
10520
|
nodeVersion: process.version,
|
|
10521
10521
|
platform: process.platform,
|
|
10522
10522
|
arch: process.arch,
|
|
@@ -10758,7 +10758,7 @@ var http = __toESM(require("http"));
|
|
|
10758
10758
|
// package.json
|
|
10759
10759
|
var package_default = {
|
|
10760
10760
|
name: "codeam-cli",
|
|
10761
|
-
version: "2.75.
|
|
10761
|
+
version: "2.75.34",
|
|
10762
10762
|
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.",
|
|
10763
10763
|
type: "commonjs",
|
|
10764
10764
|
main: "dist/index.js",
|
|
@@ -12088,7 +12088,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12088
12088
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12089
12089
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12090
12090
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12091
|
-
..."2.75.
|
|
12091
|
+
..."2.75.34" ? { ideVersion: "2.75.34" } : {}
|
|
12092
12092
|
};
|
|
12093
12093
|
try {
|
|
12094
12094
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
|
|
@@ -36325,10 +36325,33 @@ var codexProvisioner = {
|
|
|
36325
36325
|
writeFile0600(authJson, JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: auth.value }));
|
|
36326
36326
|
return { OPENAI_API_KEY: auth.value };
|
|
36327
36327
|
}
|
|
36328
|
-
writeFile0600(authJson, auth.value);
|
|
36328
|
+
if (!keepsFresherCodexLogin(authJson, auth.value)) writeFile0600(authJson, auth.value);
|
|
36329
36329
|
return {};
|
|
36330
36330
|
}
|
|
36331
36331
|
};
|
|
36332
|
+
function codexLoginStamp(raw) {
|
|
36333
|
+
try {
|
|
36334
|
+
const blob = JSON.parse(raw);
|
|
36335
|
+
const refreshedAt = typeof blob.last_refresh === "string" ? Date.parse(blob.last_refresh) : NaN;
|
|
36336
|
+
const accountId = blob.tokens?.account_id;
|
|
36337
|
+
if (!Number.isFinite(refreshedAt) || typeof accountId !== "string" || !accountId) return null;
|
|
36338
|
+
return { refreshedAt, accountId };
|
|
36339
|
+
} catch {
|
|
36340
|
+
return null;
|
|
36341
|
+
}
|
|
36342
|
+
}
|
|
36343
|
+
function keepsFresherCodexLogin(authJsonPath, incoming) {
|
|
36344
|
+
let onDisk;
|
|
36345
|
+
try {
|
|
36346
|
+
onDisk = fs58.readFileSync(authJsonPath, "utf8");
|
|
36347
|
+
} catch {
|
|
36348
|
+
return false;
|
|
36349
|
+
}
|
|
36350
|
+
const current2 = codexLoginStamp(onDisk);
|
|
36351
|
+
const next = codexLoginStamp(incoming);
|
|
36352
|
+
if (!current2 || !next) return false;
|
|
36353
|
+
return current2.accountId === next.accountId && current2.refreshedAt > next.refreshedAt;
|
|
36354
|
+
}
|
|
36332
36355
|
var geminiProvisioner = {
|
|
36333
36356
|
write(auth, home) {
|
|
36334
36357
|
const settingsJson = path68.join(home, ".gemini", "settings.json");
|
|
@@ -47897,6 +47920,15 @@ function loadHostIdentity() {
|
|
|
47897
47920
|
return null;
|
|
47898
47921
|
}
|
|
47899
47922
|
}
|
|
47923
|
+
function pollSecretHash(secret) {
|
|
47924
|
+
return (0, import_node_crypto12.createHash)("sha256").update(secret).digest("hex");
|
|
47925
|
+
}
|
|
47926
|
+
function ensureControlPollSecret(identity, save = saveHostIdentity) {
|
|
47927
|
+
if (!identity || identity.controlPollSecret) return identity;
|
|
47928
|
+
const upgraded = { ...identity, controlPollSecret: (0, import_node_crypto12.randomBytes)(32).toString("base64url") };
|
|
47929
|
+
save(upgraded);
|
|
47930
|
+
return upgraded;
|
|
47931
|
+
}
|
|
47900
47932
|
function saveHostIdentity(identity) {
|
|
47901
47933
|
const file = hostIdentityPath();
|
|
47902
47934
|
fs75.mkdirSync(path89.dirname(file), { recursive: true, mode: 448 });
|
|
@@ -47995,7 +48027,11 @@ async function sendHostHeartbeat(identity, metrics) {
|
|
|
47995
48027
|
await postJson("/api/self-hosted/heartbeat", {
|
|
47996
48028
|
hostId: identity.hostId,
|
|
47997
48029
|
hostToken: identity.hostToken,
|
|
47998
|
-
...metrics ? { metrics } : {}
|
|
48030
|
+
...metrics ? { metrics } : {},
|
|
48031
|
+
// The backend enrols this ONLY if the control plugin has no secret yet
|
|
48032
|
+
// (first writer wins), so re-sending it every beat is idempotent — and it
|
|
48033
|
+
// is the one way a host that never had one (or lost it) gets it back.
|
|
48034
|
+
...identity.controlPollSecret ? { pluginSecretHash: pollSecretHash(identity.controlPollSecret) } : {}
|
|
47999
48035
|
});
|
|
48000
48036
|
const elapsedNs = process.hrtime.bigint() - start2;
|
|
48001
48037
|
return Math.round(Number(elapsedNs) / 1e6);
|
|
@@ -48227,14 +48263,18 @@ function planSessionResume(records, max) {
|
|
|
48227
48263
|
const bound = Math.max(0, Math.floor(max));
|
|
48228
48264
|
return { resume: ordered.slice(0, bound), dropped: ordered.slice(bound) };
|
|
48229
48265
|
}
|
|
48230
|
-
function pickSavedSessionForWorkspace(sessions3, cwd) {
|
|
48266
|
+
function pickSavedSessionForWorkspace(sessions3, cwd, deployId) {
|
|
48231
48267
|
const target = path90.resolve(cwd);
|
|
48268
|
+
const reconnectable = (s) => !!s.pluginId && !!s.pollSecret && !!s.agent;
|
|
48232
48269
|
const matches = sessions3.filter(
|
|
48233
|
-
(s) => !!s.cwd && path90.resolve(s.cwd) === target &&
|
|
48270
|
+
(s) => !!s.cwd && path90.resolve(s.cwd) === target && reconnectable(s)
|
|
48234
48271
|
);
|
|
48235
|
-
if (matches.length
|
|
48236
|
-
|
|
48237
|
-
|
|
48272
|
+
if (matches.length > 0) {
|
|
48273
|
+
matches.sort((a, b) => b.pairedAt - a.pairedAt);
|
|
48274
|
+
return matches[0];
|
|
48275
|
+
}
|
|
48276
|
+
if (!deployId) return null;
|
|
48277
|
+
return sessions3.find((s) => !s.cwd && s.id === deployId && reconnectable(s)) ?? null;
|
|
48238
48278
|
}
|
|
48239
48279
|
|
|
48240
48280
|
// src/commands/host/git-tooling.ts
|
|
@@ -48674,7 +48714,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
48674
48714
|
if (process.env.NODE_ENV === "test") return;
|
|
48675
48715
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
48676
48716
|
if (process.env.CI) return;
|
|
48677
|
-
const current2 = true ? "2.75.
|
|
48717
|
+
const current2 = true ? "2.75.34" : null;
|
|
48678
48718
|
if (!current2) return;
|
|
48679
48719
|
const cache = readCache();
|
|
48680
48720
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -48691,7 +48731,7 @@ function checkForUpdates() {
|
|
|
48691
48731
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
48692
48732
|
if (process.env.CI) return;
|
|
48693
48733
|
if (!process.stdout.isTTY) return;
|
|
48694
|
-
const current2 = true ? "2.75.
|
|
48734
|
+
const current2 = true ? "2.75.34" : null;
|
|
48695
48735
|
if (!current2) return;
|
|
48696
48736
|
const cache = readCache();
|
|
48697
48737
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -48714,7 +48754,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
48714
48754
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
48715
48755
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
48716
48756
|
function currentCliVersion() {
|
|
48717
|
-
return true ? "2.75.
|
|
48757
|
+
return true ? "2.75.34" : null;
|
|
48718
48758
|
}
|
|
48719
48759
|
async function installedVersion(deps) {
|
|
48720
48760
|
const ls = await deps.run(
|
|
@@ -50005,7 +50045,7 @@ var HostAgentSupervisor = class {
|
|
|
50005
50045
|
const saved = this.listSavedSessions();
|
|
50006
50046
|
let resumed = 0;
|
|
50007
50047
|
for (const rec of resume) {
|
|
50008
|
-
const session = pickSavedSessionForWorkspace(saved, rec.cwd);
|
|
50048
|
+
const session = pickSavedSessionForWorkspace(saved, rec.cwd, rec.deployId);
|
|
50009
50049
|
if (!session) {
|
|
50010
50050
|
log.warn(
|
|
50011
50051
|
"host-agent",
|
|
@@ -50386,7 +50426,7 @@ var HostAgentSupervisor = class {
|
|
|
50386
50426
|
}
|
|
50387
50427
|
};
|
|
50388
50428
|
async function resolveHostIdentity(enrollToken) {
|
|
50389
|
-
const existing = loadHostIdentity();
|
|
50429
|
+
const existing = ensureControlPollSecret(loadHostIdentity());
|
|
50390
50430
|
if (enrollToken) {
|
|
50391
50431
|
await reportProgress({ enrollToken }, "redeeming", "redeeming enrollment token\u2026");
|
|
50392
50432
|
try {
|
|
@@ -50679,7 +50719,7 @@ function checkChokidar() {
|
|
|
50679
50719
|
}
|
|
50680
50720
|
async function doctor(args2 = []) {
|
|
50681
50721
|
const json = args2.includes("--json");
|
|
50682
|
-
const cliVersion = true ? "2.75.
|
|
50722
|
+
const cliVersion = true ? "2.75.34" : "0.0.0-dev";
|
|
50683
50723
|
const apiBase2 = resolveApiBaseUrl();
|
|
50684
50724
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
50685
50725
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -51203,7 +51243,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
51203
51243
|
// src/commands/version.ts
|
|
51204
51244
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
51205
51245
|
function version2() {
|
|
51206
|
-
const v = true ? "2.75.
|
|
51246
|
+
const v = true ? "2.75.34" : "unknown";
|
|
51207
51247
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
51208
51248
|
}
|
|
51209
51249
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.75.
|
|
3
|
+
"version": "2.75.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",
|