codeam-cli 2.60.49 → 2.60.51
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 +90 -8
- 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.50] — 2026-07-11
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Guard kimi ACP login-state slot + real `kimi acp` regression test
|
|
12
|
+
|
|
13
|
+
## [2.60.49] — 2026-07-11
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Write kimi managed-provider config.toml on provisioning (0.23.5 empty-response regression)
|
|
18
|
+
|
|
7
19
|
## [2.60.48] — 2026-07-11
|
|
8
20
|
|
|
9
21
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5733,7 +5733,7 @@ function readAnonId() {
|
|
|
5733
5733
|
}
|
|
5734
5734
|
function superProperties() {
|
|
5735
5735
|
return {
|
|
5736
|
-
cliVersion: true ? "2.60.
|
|
5736
|
+
cliVersion: true ? "2.60.51" : "0.0.0-dev",
|
|
5737
5737
|
nodeVersion: process.version,
|
|
5738
5738
|
platform: process.platform,
|
|
5739
5739
|
arch: process.arch,
|
|
@@ -5914,7 +5914,7 @@ var os4 = __toESM(require("os"));
|
|
|
5914
5914
|
// package.json
|
|
5915
5915
|
var package_default = {
|
|
5916
5916
|
name: "codeam-cli",
|
|
5917
|
-
version: "2.60.
|
|
5917
|
+
version: "2.60.51",
|
|
5918
5918
|
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.",
|
|
5919
5919
|
type: "commonjs",
|
|
5920
5920
|
main: "dist/index.js",
|
|
@@ -7023,7 +7023,7 @@ var CommandRelayService = class {
|
|
|
7023
7023
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
7024
7024
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
7025
7025
|
// pair/reconnect). Older backends ignore the extra field.
|
|
7026
|
-
..."2.60.
|
|
7026
|
+
..."2.60.51" ? { ideVersion: "2.60.51" } : {}
|
|
7027
7027
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
7028
7028
|
}
|
|
7029
7029
|
/**
|
|
@@ -17592,7 +17592,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17592
17592
|
if (process.env.NODE_ENV === "test") return;
|
|
17593
17593
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17594
17594
|
if (process.env.CI) return;
|
|
17595
|
-
const current = true ? "2.60.
|
|
17595
|
+
const current = true ? "2.60.51" : null;
|
|
17596
17596
|
if (!current) return;
|
|
17597
17597
|
const cache = readCache();
|
|
17598
17598
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17609,7 +17609,7 @@ function checkForUpdates() {
|
|
|
17609
17609
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17610
17610
|
if (process.env.CI) return;
|
|
17611
17611
|
if (!process.stdout.isTTY) return;
|
|
17612
|
-
const current = true ? "2.60.
|
|
17612
|
+
const current = true ? "2.60.51" : null;
|
|
17613
17613
|
if (!current) return;
|
|
17614
17614
|
const cache = readCache();
|
|
17615
17615
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17629,7 +17629,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17629
17629
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17630
17630
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17631
17631
|
function currentCliVersion() {
|
|
17632
|
-
return true ? "2.60.
|
|
17632
|
+
return true ? "2.60.51" : null;
|
|
17633
17633
|
}
|
|
17634
17634
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17635
17635
|
return new Promise((resolve7) => {
|
|
@@ -26736,6 +26736,7 @@ function createIdleTimeout(idleMs, makeError) {
|
|
|
26736
26736
|
var TRANSIENT_ADAPTER_SPAWN_RE = /ETXTBSY|ENOENT/;
|
|
26737
26737
|
var MAX_START_ATTEMPTS = 5;
|
|
26738
26738
|
var TRANSPORT_DOWN_DURING_START_RE = /connection (is )?closed|stream (is )?closed|ECONNRESET|EPIPE|write after end|premature close/i;
|
|
26739
|
+
var SESSION_CLOSED_RE = /session is closed/i;
|
|
26739
26740
|
var AdapterStartCrashError = class extends Error {
|
|
26740
26741
|
adapterExitedDuringStart = true;
|
|
26741
26742
|
constructor(message) {
|
|
@@ -26763,6 +26764,12 @@ var AcpClient = class {
|
|
|
26763
26764
|
connection = null;
|
|
26764
26765
|
stopping = false;
|
|
26765
26766
|
sessionId = null;
|
|
26767
|
+
/** Whether the agent advertised `loadSession` on `initialize`. Drives the
|
|
26768
|
+
* post-turn session-closed recovery: an agent that supports resume (kimi,
|
|
26769
|
+
* claude, codex, gemini) is re-established with `session/load` — preserving
|
|
26770
|
+
* the conversation — whereas one without it falls back to a fresh
|
|
26771
|
+
* `session/new`. Set once during {@link startOnce}. */
|
|
26772
|
+
supportsLoadSession = false;
|
|
26766
26773
|
/** Idle watchdog for the in-flight prompt. The `Client` handlers
|
|
26767
26774
|
* (`sessionUpdate` / `requestPermission`) reach for this to keep
|
|
26768
26775
|
* the turn alive while the adapter is demonstrably working. Null
|
|
@@ -26946,6 +26953,7 @@ var AcpClient = class {
|
|
|
26946
26953
|
"acpClient",
|
|
26947
26954
|
`initialize \u2190 ok protocolVersion=${initialize.protocolVersion} agentCaps=${JSON.stringify(initialize.agentCapabilities ?? {}).slice(0, 200)}`
|
|
26948
26955
|
);
|
|
26956
|
+
this.supportsLoadSession = initialize.agentCapabilities?.loadSession === true;
|
|
26949
26957
|
log.info("acpClient", "newSession \u2192 sending");
|
|
26950
26958
|
let startupTimer;
|
|
26951
26959
|
const startupFailure = new Promise((_2, reject) => {
|
|
@@ -27033,6 +27041,29 @@ var AcpClient = class {
|
|
|
27033
27041
|
throw new Error("AcpClient.prompt called before start()");
|
|
27034
27042
|
}
|
|
27035
27043
|
const blocks = typeof input === "string" ? [{ type: "text", text: input }] : input;
|
|
27044
|
+
try {
|
|
27045
|
+
return await this.sendPromptOnce(blocks);
|
|
27046
|
+
} catch (err) {
|
|
27047
|
+
if (this.isSessionClosedError(err)) {
|
|
27048
|
+
log.warn(
|
|
27049
|
+
"acpClient",
|
|
27050
|
+
"session/prompt rejected 'Session is closed' \u2014 re-establishing session and retrying once"
|
|
27051
|
+
);
|
|
27052
|
+
await this.reestablishSession();
|
|
27053
|
+
return await this.sendPromptOnce(blocks);
|
|
27054
|
+
}
|
|
27055
|
+
throw err;
|
|
27056
|
+
}
|
|
27057
|
+
}
|
|
27058
|
+
/**
|
|
27059
|
+
* Send ONE `session/prompt` round-trip with the idle watchdog. Extracted from
|
|
27060
|
+
* {@link runPrompt} so the closed-session recovery can re-invoke it for the
|
|
27061
|
+
* single retry without duplicating the watchdog / tool-ledger setup.
|
|
27062
|
+
*/
|
|
27063
|
+
async sendPromptOnce(blocks) {
|
|
27064
|
+
if (!this.connection || !this.sessionId) {
|
|
27065
|
+
throw new Error("AcpClient.sendPromptOnce called before start()");
|
|
27066
|
+
}
|
|
27036
27067
|
const textLen = blocks.reduce(
|
|
27037
27068
|
(n, b) => b.type === "text" ? n + b.text.length : n,
|
|
27038
27069
|
0
|
|
@@ -27078,6 +27109,57 @@ var AcpClient = class {
|
|
|
27078
27109
|
this.promptIdle = null;
|
|
27079
27110
|
}
|
|
27080
27111
|
}
|
|
27112
|
+
/**
|
|
27113
|
+
* True when a `session/prompt` rejection is the "the agent closed its ACP
|
|
27114
|
+
* session between turns" fact — the kimi post-turn/idle close. Keyed on the
|
|
27115
|
+
* `session is closed` phrase (in `message` / `details` / serialised `data`),
|
|
27116
|
+
* NOT on the bare `-32603` code: that generic "Internal error" code is also
|
|
27117
|
+
* used for the adapter's own transient spawn races, so matching it alone would
|
|
27118
|
+
* misfire. See {@link SESSION_CLOSED_RE}.
|
|
27119
|
+
*/
|
|
27120
|
+
isSessionClosedError(err) {
|
|
27121
|
+
if (!err || typeof err !== "object") return false;
|
|
27122
|
+
const e = err;
|
|
27123
|
+
const parts = [];
|
|
27124
|
+
if (typeof e.message === "string") parts.push(e.message);
|
|
27125
|
+
if (typeof e.details === "string") parts.push(e.details);
|
|
27126
|
+
if (e.data !== void 0) {
|
|
27127
|
+
try {
|
|
27128
|
+
parts.push(JSON.stringify(e.data));
|
|
27129
|
+
} catch {
|
|
27130
|
+
}
|
|
27131
|
+
}
|
|
27132
|
+
return SESSION_CLOSED_RE.test(parts.join(" "));
|
|
27133
|
+
}
|
|
27134
|
+
/**
|
|
27135
|
+
* Re-establish a session the agent closed out from under us (kimi post-turn),
|
|
27136
|
+
* on the SAME still-running adapter process, so the pending prompt can be
|
|
27137
|
+
* retried. Prefers `session/load` (resume) when the agent advertised
|
|
27138
|
+
* `loadSession` — proven live to re-open kimi's closed session with the
|
|
27139
|
+
* conversation context intact, and kimi's `session/load` emits NO history
|
|
27140
|
+
* replay as `session/update`, so no streaming pollution (unlike the baton's
|
|
27141
|
+
* Claude load, which is why this needs no `beginLoadReplay` bracket). Calls
|
|
27142
|
+
* `connection.loadSession` DIRECTLY — the public {@link loadSession} skips a
|
|
27143
|
+
* same-id load (a Claude relaunch-wedge guard), which is exactly the load we
|
|
27144
|
+
* MUST perform here (the closed id IS the active id). Falls back to a fresh
|
|
27145
|
+
* `session/new` (context lost) only when the agent can't resume.
|
|
27146
|
+
*/
|
|
27147
|
+
async reestablishSession() {
|
|
27148
|
+
if (!this.connection) throw new Error("AcpClient.reestablishSession: no connection");
|
|
27149
|
+
const cwd = this.opts.cwd;
|
|
27150
|
+
const mcpServers = this.opts.mcpServers ?? [];
|
|
27151
|
+
const closedSid = this.sessionId;
|
|
27152
|
+
if (this.supportsLoadSession && closedSid) {
|
|
27153
|
+
log.info("acpClient", `reestablish \u2192 loadSession(resume) sid=${closedSid.slice(0, 8)}`);
|
|
27154
|
+
await this.connection.loadSession({ sessionId: closedSid, cwd, mcpServers });
|
|
27155
|
+
log.info("acpClient", "reestablish \u2190 loadSession ok");
|
|
27156
|
+
return;
|
|
27157
|
+
}
|
|
27158
|
+
log.info("acpClient", "reestablish \u2192 newSession (agent has no loadSession capability)");
|
|
27159
|
+
const ns = await this.connection.newSession({ cwd, mcpServers });
|
|
27160
|
+
this.sessionId = ns.sessionId;
|
|
27161
|
+
log.info("acpClient", `reestablish \u2190 newSession ok sid=${ns.sessionId.slice(0, 8)}`);
|
|
27162
|
+
}
|
|
27081
27163
|
/**
|
|
27082
27164
|
* Load a previously persisted session by id. Mobile's
|
|
27083
27165
|
* `resume_session` command flows through here. Requires the
|
|
@@ -34846,7 +34928,7 @@ function checkChokidar() {
|
|
|
34846
34928
|
}
|
|
34847
34929
|
async function doctor(args2 = []) {
|
|
34848
34930
|
const json = args2.includes("--json");
|
|
34849
|
-
const cliVersion = true ? "2.60.
|
|
34931
|
+
const cliVersion = true ? "2.60.51" : "0.0.0-dev";
|
|
34850
34932
|
const apiBase2 = resolveApiBaseUrl();
|
|
34851
34933
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
34852
34934
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -35323,7 +35405,7 @@ async function mcpRun(args2) {
|
|
|
35323
35405
|
// src/commands/version.ts
|
|
35324
35406
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
35325
35407
|
function version2() {
|
|
35326
|
-
const v = true ? "2.60.
|
|
35408
|
+
const v = true ? "2.60.51" : "unknown";
|
|
35327
35409
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
35328
35410
|
}
|
|
35329
35411
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.51",
|
|
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",
|