codeam-cli 2.75.31 → 2.75.33
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 +64 -11
- 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.32] — 2026-09-26
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Clear a preview that died with its machine on the first heartbeat (#828)
|
|
12
|
+
|
|
13
|
+
## [2.75.31] — 2026-09-26
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Prewarm installs yarn projects' deps at session start too (#826)
|
|
18
|
+
|
|
7
19
|
## [2.75.30] — 2026-09-25
|
|
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.33" : "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.33",
|
|
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.33" ? { ideVersion: "2.75.33" } : {}
|
|
12092
12092
|
};
|
|
12093
12093
|
try {
|
|
12094
12094
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
|
|
@@ -21910,8 +21910,12 @@ function makePreviewHeartbeatReaffirm(deps) {
|
|
|
21910
21910
|
const now = deps.now ?? Date.now;
|
|
21911
21911
|
const intervalMs = deps.intervalMs ?? PREVIEW_REAFFIRM_INTERVAL_MS;
|
|
21912
21912
|
let lastAffirmedAt = null;
|
|
21913
|
+
let firstBeat = true;
|
|
21913
21914
|
return ({ firstAfterConnect }) => {
|
|
21914
21915
|
const current2 = deps.serving();
|
|
21916
|
+
const isFirstBeat = firstBeat;
|
|
21917
|
+
firstBeat = false;
|
|
21918
|
+
if (!current2 && isFirstBeat) deps.clearStale?.();
|
|
21915
21919
|
if (!current2) {
|
|
21916
21920
|
lastAffirmedAt = null;
|
|
21917
21921
|
return;
|
|
@@ -28064,7 +28068,9 @@ ${failure?.rawExcerpt ?? ""}`
|
|
|
28064
28068
|
});
|
|
28065
28069
|
return detection;
|
|
28066
28070
|
}
|
|
28071
|
+
var previewRequestedInProcess = false;
|
|
28067
28072
|
var requestPreviewDetectH = (ctx) => {
|
|
28073
|
+
previewRequestedInProcess = true;
|
|
28068
28074
|
if (!ctx.pluginAuthToken) {
|
|
28069
28075
|
log.info("preview", "no pluginAuthToken \u2014 skipping detect");
|
|
28070
28076
|
return;
|
|
@@ -28114,6 +28120,16 @@ function makePreviewReaffirm(args2) {
|
|
|
28114
28120
|
type: USER_EVENTS.PREVIEW_READY,
|
|
28115
28121
|
payload
|
|
28116
28122
|
});
|
|
28123
|
+
},
|
|
28124
|
+
clearStale: () => {
|
|
28125
|
+
if (previewRequestedInProcess) return;
|
|
28126
|
+
emitPreviewEvent({
|
|
28127
|
+
sessionId,
|
|
28128
|
+
pluginId: args2.pluginId,
|
|
28129
|
+
pluginAuthToken: token,
|
|
28130
|
+
type: USER_EVENTS.PREVIEW_STOPPED,
|
|
28131
|
+
payload: { reason: "restart" }
|
|
28132
|
+
});
|
|
28117
28133
|
}
|
|
28118
28134
|
});
|
|
28119
28135
|
}
|
|
@@ -28158,6 +28174,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
28158
28174
|
void startPreviewFromDetection(ctx, rawDetection, ctx.pluginAuthToken);
|
|
28159
28175
|
};
|
|
28160
28176
|
function startPreviewFromDetection(ctx, detection, pluginAuthToken, opts = {}) {
|
|
28177
|
+
previewRequestedInProcess = true;
|
|
28161
28178
|
const emit2 = (type, payload) => {
|
|
28162
28179
|
const tagged = originPayload(payload, opts.origin) ?? {};
|
|
28163
28180
|
opts.onEvent?.(type, tagged);
|
|
@@ -36308,10 +36325,33 @@ var codexProvisioner = {
|
|
|
36308
36325
|
writeFile0600(authJson, JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: auth.value }));
|
|
36309
36326
|
return { OPENAI_API_KEY: auth.value };
|
|
36310
36327
|
}
|
|
36311
|
-
writeFile0600(authJson, auth.value);
|
|
36328
|
+
if (!keepsFresherCodexLogin(authJson, auth.value)) writeFile0600(authJson, auth.value);
|
|
36312
36329
|
return {};
|
|
36313
36330
|
}
|
|
36314
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
|
+
}
|
|
36315
36355
|
var geminiProvisioner = {
|
|
36316
36356
|
write(auth, home) {
|
|
36317
36357
|
const settingsJson = path68.join(home, ".gemini", "settings.json");
|
|
@@ -47880,6 +47920,15 @@ function loadHostIdentity() {
|
|
|
47880
47920
|
return null;
|
|
47881
47921
|
}
|
|
47882
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
|
+
}
|
|
47883
47932
|
function saveHostIdentity(identity) {
|
|
47884
47933
|
const file = hostIdentityPath();
|
|
47885
47934
|
fs75.mkdirSync(path89.dirname(file), { recursive: true, mode: 448 });
|
|
@@ -47978,7 +48027,11 @@ async function sendHostHeartbeat(identity, metrics) {
|
|
|
47978
48027
|
await postJson("/api/self-hosted/heartbeat", {
|
|
47979
48028
|
hostId: identity.hostId,
|
|
47980
48029
|
hostToken: identity.hostToken,
|
|
47981
|
-
...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) } : {}
|
|
47982
48035
|
});
|
|
47983
48036
|
const elapsedNs = process.hrtime.bigint() - start2;
|
|
47984
48037
|
return Math.round(Number(elapsedNs) / 1e6);
|
|
@@ -48657,7 +48710,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
48657
48710
|
if (process.env.NODE_ENV === "test") return;
|
|
48658
48711
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
48659
48712
|
if (process.env.CI) return;
|
|
48660
|
-
const current2 = true ? "2.75.
|
|
48713
|
+
const current2 = true ? "2.75.33" : null;
|
|
48661
48714
|
if (!current2) return;
|
|
48662
48715
|
const cache = readCache();
|
|
48663
48716
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -48674,7 +48727,7 @@ function checkForUpdates() {
|
|
|
48674
48727
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
48675
48728
|
if (process.env.CI) return;
|
|
48676
48729
|
if (!process.stdout.isTTY) return;
|
|
48677
|
-
const current2 = true ? "2.75.
|
|
48730
|
+
const current2 = true ? "2.75.33" : null;
|
|
48678
48731
|
if (!current2) return;
|
|
48679
48732
|
const cache = readCache();
|
|
48680
48733
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -48697,7 +48750,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
48697
48750
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
48698
48751
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
48699
48752
|
function currentCliVersion() {
|
|
48700
|
-
return true ? "2.75.
|
|
48753
|
+
return true ? "2.75.33" : null;
|
|
48701
48754
|
}
|
|
48702
48755
|
async function installedVersion(deps) {
|
|
48703
48756
|
const ls = await deps.run(
|
|
@@ -50369,7 +50422,7 @@ var HostAgentSupervisor = class {
|
|
|
50369
50422
|
}
|
|
50370
50423
|
};
|
|
50371
50424
|
async function resolveHostIdentity(enrollToken) {
|
|
50372
|
-
const existing = loadHostIdentity();
|
|
50425
|
+
const existing = ensureControlPollSecret(loadHostIdentity());
|
|
50373
50426
|
if (enrollToken) {
|
|
50374
50427
|
await reportProgress({ enrollToken }, "redeeming", "redeeming enrollment token\u2026");
|
|
50375
50428
|
try {
|
|
@@ -50662,7 +50715,7 @@ function checkChokidar() {
|
|
|
50662
50715
|
}
|
|
50663
50716
|
async function doctor(args2 = []) {
|
|
50664
50717
|
const json = args2.includes("--json");
|
|
50665
|
-
const cliVersion = true ? "2.75.
|
|
50718
|
+
const cliVersion = true ? "2.75.33" : "0.0.0-dev";
|
|
50666
50719
|
const apiBase2 = resolveApiBaseUrl();
|
|
50667
50720
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
50668
50721
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -51186,7 +51239,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
51186
51239
|
// src/commands/version.ts
|
|
51187
51240
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
51188
51241
|
function version2() {
|
|
51189
|
-
const v = true ? "2.75.
|
|
51242
|
+
const v = true ? "2.75.33" : "unknown";
|
|
51190
51243
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
51191
51244
|
}
|
|
51192
51245
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.75.
|
|
3
|
+
"version": "2.75.33",
|
|
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",
|