codeam-cli 2.61.24 → 2.61.26
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 +22 -0
- package/dist/index.js +46 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,28 @@ 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.61.25] — 2026-07-23
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **host-agent:** Enrol + present a control-channel poll secret (self-hosted deploy root fix)
|
|
12
|
+
|
|
13
|
+
## [2.61.24] — 2026-07-22
|
|
14
|
+
|
|
15
|
+
### Chore
|
|
16
|
+
|
|
17
|
+
- **cli:** Declare yaml as devDependency (skills materialize test)
|
|
18
|
+
- **deps:** Bump actions/setup-node from 4 to 7 (#452)
|
|
19
|
+
- **deps-dev:** Bump typescript from 6.0.3 to 7.0.2 in /apps/cli (#432)
|
|
20
|
+
- **deps-dev:** Bump typescript from 6.0.3 to 7.0.2 in /apps/vsc-plugin (#430)
|
|
21
|
+
- **deps:** Bump org.jetbrains.kotlin.jvm in /apps/jetbrains-plugin (#453)
|
|
22
|
+
- **deps:** Bump ignore from 5.3.2 to 7.0.6 in /apps/cli (#323)
|
|
23
|
+
- **deps:** Bump org.jetbrains.intellij.platform (#454)
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **cli:** Break self-hosted enroll-token crash-loop on identity self-heal
|
|
28
|
+
|
|
7
29
|
## [2.61.23] — 2026-07-20
|
|
8
30
|
|
|
9
31
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -6117,7 +6117,7 @@ function readAnonId() {
|
|
|
6117
6117
|
}
|
|
6118
6118
|
function superProperties() {
|
|
6119
6119
|
return {
|
|
6120
|
-
cliVersion: true ? "2.61.
|
|
6120
|
+
cliVersion: true ? "2.61.26" : "0.0.0-dev",
|
|
6121
6121
|
nodeVersion: process.version,
|
|
6122
6122
|
platform: process.platform,
|
|
6123
6123
|
arch: process.arch,
|
|
@@ -6298,7 +6298,7 @@ var os4 = __toESM(require("os"));
|
|
|
6298
6298
|
// package.json
|
|
6299
6299
|
var package_default = {
|
|
6300
6300
|
name: "codeam-cli",
|
|
6301
|
-
version: "2.61.
|
|
6301
|
+
version: "2.61.26",
|
|
6302
6302
|
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.",
|
|
6303
6303
|
type: "commonjs",
|
|
6304
6304
|
main: "dist/index.js",
|
|
@@ -7089,16 +7089,18 @@ var API_BASE2 = resolveApiBaseUrl();
|
|
|
7089
7089
|
var SSE_LIVENESS_TIMEOUT_MS = 45e3;
|
|
7090
7090
|
var SSE_WATCHDOG_INTERVAL_MS = 1e4;
|
|
7091
7091
|
var CommandRelayService = class _CommandRelayService {
|
|
7092
|
-
constructor(pluginId, onCommand, agentMeta, agentsOverride) {
|
|
7092
|
+
constructor(pluginId, onCommand, agentMeta, agentsOverride, explicitPollSecret) {
|
|
7093
7093
|
this.pluginId = pluginId;
|
|
7094
7094
|
this.onCommand = onCommand;
|
|
7095
7095
|
this.agentMeta = agentMeta;
|
|
7096
7096
|
this.agentsOverride = agentsOverride;
|
|
7097
|
+
this.explicitPollSecret = explicitPollSecret;
|
|
7097
7098
|
}
|
|
7098
7099
|
pluginId;
|
|
7099
7100
|
onCommand;
|
|
7100
7101
|
agentMeta;
|
|
7101
7102
|
agentsOverride;
|
|
7103
|
+
explicitPollSecret;
|
|
7102
7104
|
_running = false;
|
|
7103
7105
|
pairingInvalid = false;
|
|
7104
7106
|
heartbeatTimer = null;
|
|
@@ -7390,6 +7392,10 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
7390
7392
|
// backends (which ignore it).
|
|
7391
7393
|
pollSecretHeader() {
|
|
7392
7394
|
const headers = { "X-Codeam-Cmd-Ack": "1" };
|
|
7395
|
+
if (this.explicitPollSecret) {
|
|
7396
|
+
headers["X-Plugin-Poll-Secret"] = this.explicitPollSecret;
|
|
7397
|
+
return headers;
|
|
7398
|
+
}
|
|
7393
7399
|
try {
|
|
7394
7400
|
const secret = loadCliConfig().sessions.find(
|
|
7395
7401
|
(s) => s.pluginId === this.pluginId
|
|
@@ -7463,7 +7469,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
7463
7469
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
7464
7470
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
7465
7471
|
// pair/reconnect). Older backends ignore the extra field.
|
|
7466
|
-
..."2.61.
|
|
7472
|
+
..."2.61.26" ? { ideVersion: "2.61.26" } : {}
|
|
7467
7473
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
7468
7474
|
}
|
|
7469
7475
|
/**
|
|
@@ -16791,6 +16797,7 @@ function describeReason(reason) {
|
|
|
16791
16797
|
var fs35 = __toESM(require("fs"));
|
|
16792
16798
|
var os31 = __toESM(require("os"));
|
|
16793
16799
|
var path39 = __toESM(require("path"));
|
|
16800
|
+
var import_node_crypto9 = require("crypto");
|
|
16794
16801
|
function sampleCpuTimes() {
|
|
16795
16802
|
let idle = 0;
|
|
16796
16803
|
let total = 0;
|
|
@@ -16853,7 +16860,13 @@ function loadHostIdentity() {
|
|
|
16853
16860
|
const parsed = JSON.parse(raw);
|
|
16854
16861
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
16855
16862
|
const p2 = parsed;
|
|
16856
|
-
return {
|
|
16863
|
+
return {
|
|
16864
|
+
hostId: p2.hostId,
|
|
16865
|
+
hostToken: p2.hostToken,
|
|
16866
|
+
controlPluginId: p2.controlPluginId,
|
|
16867
|
+
// Optional — absent on identities sealed by a pre-secret CLI.
|
|
16868
|
+
...typeof p2.controlPollSecret === "string" ? { controlPollSecret: p2.controlPollSecret } : {}
|
|
16869
|
+
};
|
|
16857
16870
|
}
|
|
16858
16871
|
return null;
|
|
16859
16872
|
} catch {
|
|
@@ -16936,15 +16949,21 @@ function resolveHostLabel(label) {
|
|
|
16936
16949
|
return resolved.slice(0, 80);
|
|
16937
16950
|
}
|
|
16938
16951
|
async function redeemEnrollToken(token, label) {
|
|
16952
|
+
const controlPollSecret = (0, import_node_crypto9.randomBytes)(32).toString("base64url");
|
|
16953
|
+
const pluginSecretHash = (0, import_node_crypto9.createHash)("sha256").update(controlPollSecret).digest("hex");
|
|
16939
16954
|
const data = await postJson("/api/self-hosted/redeem", {
|
|
16940
16955
|
token,
|
|
16941
16956
|
label: resolveHostLabel(label),
|
|
16942
|
-
osInfo: collectOsInfo()
|
|
16957
|
+
osInfo: collectOsInfo(),
|
|
16958
|
+
// OPTIONAL + backward-compatible: older backends ignore the unknown field
|
|
16959
|
+
// and keep the pre-existing (no-secret) control-channel behavior.
|
|
16960
|
+
pluginSecretHash
|
|
16943
16961
|
});
|
|
16944
16962
|
return {
|
|
16945
16963
|
hostId: data.hostId,
|
|
16946
16964
|
hostToken: data.hostToken,
|
|
16947
|
-
controlPluginId: data.controlPluginId
|
|
16965
|
+
controlPluginId: data.controlPluginId,
|
|
16966
|
+
controlPollSecret
|
|
16948
16967
|
};
|
|
16949
16968
|
}
|
|
16950
16969
|
async function sendHostHeartbeat(identity, metrics) {
|
|
@@ -18312,7 +18331,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
18312
18331
|
if (process.env.NODE_ENV === "test") return;
|
|
18313
18332
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18314
18333
|
if (process.env.CI) return;
|
|
18315
|
-
const current = true ? "2.61.
|
|
18334
|
+
const current = true ? "2.61.26" : null;
|
|
18316
18335
|
if (!current) return;
|
|
18317
18336
|
const cache = readCache();
|
|
18318
18337
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18329,7 +18348,7 @@ function checkForUpdates() {
|
|
|
18329
18348
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18330
18349
|
if (process.env.CI) return;
|
|
18331
18350
|
if (!process.stdout.isTTY) return;
|
|
18332
|
-
const current = true ? "2.61.
|
|
18351
|
+
const current = true ? "2.61.26" : null;
|
|
18333
18352
|
if (!current) return;
|
|
18334
18353
|
const cache = readCache();
|
|
18335
18354
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18349,7 +18368,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
18349
18368
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
18350
18369
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
18351
18370
|
function currentCliVersion() {
|
|
18352
|
-
return true ? "2.61.
|
|
18371
|
+
return true ? "2.61.26" : null;
|
|
18353
18372
|
}
|
|
18354
18373
|
function runCmd(cmd, args2, timeoutMs) {
|
|
18355
18374
|
return new Promise((resolve8) => {
|
|
@@ -18761,11 +18780,12 @@ var HostAgentSupervisor = class {
|
|
|
18761
18780
|
}
|
|
18762
18781
|
/** Open the control channel (reusing the relay) + start heartbeats. */
|
|
18763
18782
|
start() {
|
|
18764
|
-
const make = this.deps.makeRelay ?? ((pluginId, onCommand, meta) => new CommandRelayService(pluginId, onCommand, meta));
|
|
18783
|
+
const make = this.deps.makeRelay ?? ((pluginId, onCommand, meta, pollSecret) => new CommandRelayService(pluginId, onCommand, meta, void 0, pollSecret));
|
|
18765
18784
|
this.relay = make(
|
|
18766
18785
|
this.identity.controlPluginId,
|
|
18767
18786
|
(cmd) => this.handleCommand(cmd),
|
|
18768
|
-
CONTROL_AGENT_META
|
|
18787
|
+
CONTROL_AGENT_META,
|
|
18788
|
+
this.identity.controlPollSecret
|
|
18769
18789
|
);
|
|
18770
18790
|
this.relay.start();
|
|
18771
18791
|
void this.beat();
|
|
@@ -25029,7 +25049,7 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
|
|
|
25029
25049
|
}
|
|
25030
25050
|
|
|
25031
25051
|
// src/agents/acp/runner.ts
|
|
25032
|
-
var
|
|
25052
|
+
var import_node_crypto11 = require("crypto");
|
|
25033
25053
|
|
|
25034
25054
|
// src/services/history.service.ts
|
|
25035
25055
|
var fs60 = __toESM(require("fs"));
|
|
@@ -31130,7 +31150,7 @@ async function runOnboardingTurn(opts) {
|
|
|
31130
31150
|
}
|
|
31131
31151
|
|
|
31132
31152
|
// src/agents/acp/mappers.ts
|
|
31133
|
-
var
|
|
31153
|
+
var import_node_crypto10 = require("crypto");
|
|
31134
31154
|
function mapSessionUpdate(notification) {
|
|
31135
31155
|
const update = notification.update;
|
|
31136
31156
|
switch (update.sessionUpdate) {
|
|
@@ -31193,7 +31213,7 @@ function mapPermissionRequest(request) {
|
|
|
31193
31213
|
}
|
|
31194
31214
|
return {
|
|
31195
31215
|
event: {
|
|
31196
|
-
questionId: (0,
|
|
31216
|
+
questionId: (0, import_node_crypto10.randomUUID)(),
|
|
31197
31217
|
prompt,
|
|
31198
31218
|
options: labels.length > 0 ? labels : void 0
|
|
31199
31219
|
},
|
|
@@ -31203,7 +31223,7 @@ function mapPermissionRequest(request) {
|
|
|
31203
31223
|
}
|
|
31204
31224
|
function messageChunkId(messageId) {
|
|
31205
31225
|
if (typeof messageId === "string" && messageId.length > 0) return messageId;
|
|
31206
|
-
return (0,
|
|
31226
|
+
return (0, import_node_crypto10.randomUUID)();
|
|
31207
31227
|
}
|
|
31208
31228
|
function extractText4(content) {
|
|
31209
31229
|
if (!content || typeof content !== "object") return null;
|
|
@@ -31998,7 +32018,7 @@ function describeError(err) {
|
|
|
31998
32018
|
if (err instanceof Error) return err.message;
|
|
31999
32019
|
return String(err);
|
|
32000
32020
|
}
|
|
32001
|
-
var AUTH_FAILURE_RE = /invalid authentication credentials|authentication[_ ](?:error|required)|please run \/login|\bunauthorized\b|\binvalid x-api-key\b|oauth token (?:expired|revoked)|(?:api error|http|status)[:\s]+401|\b401\b[^\n]{0,40}(?:unauthor|authenticat|credential|api[_ ]?key|login)/i;
|
|
32021
|
+
var AUTH_FAILURE_RE = /invalid authentication credentials|failed to authenticate|authentication[_ ](?:error|required)|please run \/login|\bunauthorized\b|\binvalid x-api-key\b|oauth (?:token|session) (?:expired|revoked)|(?:session|token|credentials?|oauth)[^\n]{0,40}could not be refreshed|(?:api error|http|status)[:\s]+401|\b401\b[^\n]{0,40}(?:unauthor|authenticat|credential|api[_ ]?key|login)/i;
|
|
32002
32022
|
function looksLikeAuthFailure(text) {
|
|
32003
32023
|
return AUTH_FAILURE_RE.test(text);
|
|
32004
32024
|
}
|
|
@@ -33197,7 +33217,7 @@ var AcpHistory = class {
|
|
|
33197
33217
|
this.summary = trimmed.length > 120 ? trimmed.slice(0, 117) + "\u2026" : trimmed;
|
|
33198
33218
|
}
|
|
33199
33219
|
this.messages.push({
|
|
33200
|
-
id: (0,
|
|
33220
|
+
id: (0, import_node_crypto11.randomUUID)(),
|
|
33201
33221
|
role: "user",
|
|
33202
33222
|
text,
|
|
33203
33223
|
timestamp: Date.now()
|
|
@@ -33206,7 +33226,7 @@ var AcpHistory = class {
|
|
|
33206
33226
|
appendAgentReply(text) {
|
|
33207
33227
|
if (text.length === 0) return;
|
|
33208
33228
|
this.messages.push({
|
|
33209
|
-
id: (0,
|
|
33229
|
+
id: (0, import_node_crypto11.randomUUID)(),
|
|
33210
33230
|
role: "agent",
|
|
33211
33231
|
text,
|
|
33212
33232
|
timestamp: Date.now()
|
|
@@ -33424,7 +33444,7 @@ async function runAcpSession(opts) {
|
|
|
33424
33444
|
currentIndex: 0,
|
|
33425
33445
|
done: true
|
|
33426
33446
|
}),
|
|
33427
|
-
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0,
|
|
33447
|
+
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto11.randomUUID)(), prompt, options }),
|
|
33428
33448
|
publishRawChunk: (chunk) => publisher.publishOutput(chunk),
|
|
33429
33449
|
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
33430
33450
|
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
@@ -34911,7 +34931,7 @@ var NativeTuiDriver = class _NativeTuiDriver {
|
|
|
34911
34931
|
};
|
|
34912
34932
|
|
|
34913
34933
|
// src/baton/acp-driver.ts
|
|
34914
|
-
var
|
|
34934
|
+
var import_node_crypto12 = require("crypto");
|
|
34915
34935
|
var AcpDriver = class {
|
|
34916
34936
|
constructor(deps) {
|
|
34917
34937
|
this.deps = deps;
|
|
@@ -35004,7 +35024,7 @@ var AcpDriver = class {
|
|
|
35004
35024
|
currentIndex: 0,
|
|
35005
35025
|
done: true
|
|
35006
35026
|
}),
|
|
35007
|
-
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0,
|
|
35027
|
+
publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto12.randomUUID)(), prompt, options }),
|
|
35008
35028
|
publishRawChunk: (chunk) => publisher.publishOutput(chunk),
|
|
35009
35029
|
sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
|
|
35010
35030
|
appendAgentReply: (text) => history.appendAgentReply(text),
|
|
@@ -38171,7 +38191,7 @@ async function invite() {
|
|
|
38171
38191
|
// src/commands/doctor.ts
|
|
38172
38192
|
var import_node_dns = require("dns");
|
|
38173
38193
|
var import_node_util5 = require("util");
|
|
38174
|
-
var
|
|
38194
|
+
var import_node_crypto13 = require("crypto");
|
|
38175
38195
|
var fs68 = __toESM(require("fs"));
|
|
38176
38196
|
var path76 = __toESM(require("path"));
|
|
38177
38197
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
@@ -38341,9 +38361,9 @@ function checkChokidar() {
|
|
|
38341
38361
|
}
|
|
38342
38362
|
async function doctor(args2 = []) {
|
|
38343
38363
|
const json = args2.includes("--json");
|
|
38344
|
-
const cliVersion = true ? "2.61.
|
|
38364
|
+
const cliVersion = true ? "2.61.26" : "0.0.0-dev";
|
|
38345
38365
|
const apiBase2 = resolveApiBaseUrl();
|
|
38346
|
-
const diagnosticId = (0,
|
|
38366
|
+
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
38347
38367
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
38348
38368
|
const [dns, health] = await Promise.all([
|
|
38349
38369
|
checkDns(apiBase2),
|
|
@@ -38852,7 +38872,7 @@ async function mcpRun(args2) {
|
|
|
38852
38872
|
// src/commands/version.ts
|
|
38853
38873
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
38854
38874
|
function version2() {
|
|
38855
|
-
const v = true ? "2.61.
|
|
38875
|
+
const v = true ? "2.61.26" : "unknown";
|
|
38856
38876
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
38857
38877
|
}
|
|
38858
38878
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.61.
|
|
3
|
+
"version": "2.61.26",
|
|
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",
|