codeam-cli 2.27.6 → 2.27.7
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 +6 -0
- package/dist/index.js +69 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ 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.27.6] — 2026-06-06
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** ACP runner — ack every relay command + body envelope for auth
|
|
12
|
+
|
|
7
13
|
## [2.27.5] — 2026-06-06
|
|
8
14
|
|
|
9
15
|
### Chore
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.27.
|
|
501
|
+
version: "2.27.7",
|
|
502
502
|
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.",
|
|
503
503
|
type: "commonjs",
|
|
504
504
|
main: "dist/index.js",
|
|
@@ -5873,7 +5873,7 @@ function readAnonId() {
|
|
|
5873
5873
|
}
|
|
5874
5874
|
function superProperties() {
|
|
5875
5875
|
return {
|
|
5876
|
-
cliVersion: true ? "2.27.
|
|
5876
|
+
cliVersion: true ? "2.27.7" : "0.0.0-dev",
|
|
5877
5877
|
nodeVersion: process.version,
|
|
5878
5878
|
platform: process.platform,
|
|
5879
5879
|
arch: process.arch,
|
|
@@ -12058,6 +12058,7 @@ var fs21 = __toESM(require("fs/promises"));
|
|
|
12058
12058
|
var import_node_stream = require("stream");
|
|
12059
12059
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
12060
12060
|
var PROTOCOL_VERSION2 = 1;
|
|
12061
|
+
var PROMPT_TIMEOUT_MS = 9e4;
|
|
12061
12062
|
var CLIENT_CAPABILITIES = {
|
|
12062
12063
|
fs: { readTextFile: true, writeTextFile: true },
|
|
12063
12064
|
terminal: false
|
|
@@ -12079,6 +12080,10 @@ var AcpClient = class {
|
|
|
12079
12080
|
async start() {
|
|
12080
12081
|
if (this.child) throw new Error("AcpClient already started");
|
|
12081
12082
|
const { adapter, cwd } = this.opts;
|
|
12083
|
+
log.info(
|
|
12084
|
+
"acpClient",
|
|
12085
|
+
`spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
|
|
12086
|
+
);
|
|
12082
12087
|
const child = (0, import_node_child_process11.spawn)(adapter.command, adapter.args, {
|
|
12083
12088
|
cwd,
|
|
12084
12089
|
env: process.env,
|
|
@@ -12089,7 +12094,10 @@ var AcpClient = class {
|
|
|
12089
12094
|
child.stderr?.on("data", (chunk2) => {
|
|
12090
12095
|
for (const line of chunk2.split(/\r?\n/)) {
|
|
12091
12096
|
const trimmed = line.trim();
|
|
12092
|
-
if (trimmed)
|
|
12097
|
+
if (trimmed) {
|
|
12098
|
+
log.info("acpAdapter", trimmed);
|
|
12099
|
+
this.opts.onStderr?.(trimmed);
|
|
12100
|
+
}
|
|
12093
12101
|
}
|
|
12094
12102
|
});
|
|
12095
12103
|
child.on("exit", (code, signal) => {
|
|
@@ -12107,15 +12115,22 @@ var AcpClient = class {
|
|
|
12107
12115
|
(_agent) => this.buildClient(),
|
|
12108
12116
|
stream
|
|
12109
12117
|
);
|
|
12118
|
+
log.info("acpClient", "initialize \u2192 sending");
|
|
12110
12119
|
const initialize = await this.connection.initialize({
|
|
12111
12120
|
protocolVersion: PROTOCOL_VERSION2,
|
|
12112
12121
|
clientCapabilities: CLIENT_CAPABILITIES
|
|
12113
12122
|
});
|
|
12123
|
+
log.info(
|
|
12124
|
+
"acpClient",
|
|
12125
|
+
`initialize \u2190 ok protocolVersion=${initialize.protocolVersion} agentCaps=${JSON.stringify(initialize.agentCapabilities ?? {}).slice(0, 200)}`
|
|
12126
|
+
);
|
|
12127
|
+
log.info("acpClient", "newSession \u2192 sending");
|
|
12114
12128
|
const newSession = await this.connection.newSession({
|
|
12115
12129
|
cwd,
|
|
12116
12130
|
mcpServers: []
|
|
12117
12131
|
});
|
|
12118
12132
|
this.sessionId = newSession.sessionId;
|
|
12133
|
+
log.info("acpClient", `newSession \u2190 ok sessionId=${newSession.sessionId.slice(0, 8)}`);
|
|
12119
12134
|
return { sessionId: newSession.sessionId, initialize };
|
|
12120
12135
|
}
|
|
12121
12136
|
/**
|
|
@@ -12123,15 +12138,49 @@ var AcpClient = class {
|
|
|
12123
12138
|
* {@link PromptResponse} which carries the agent's stop reason
|
|
12124
12139
|
* once the turn finishes. Session/update notifications keep
|
|
12125
12140
|
* arriving on `onSessionUpdate` while the turn streams.
|
|
12141
|
+
*
|
|
12142
|
+
* Wrapped in a hard timeout because adapters CAN hang silently
|
|
12143
|
+
* when their underlying agent's auth/network is broken — without
|
|
12144
|
+
* a ceiling the relay command sits "pending" forever and mobile
|
|
12145
|
+
* shows a permanent "Thinking…" spinner with no way to recover.
|
|
12126
12146
|
*/
|
|
12127
12147
|
async prompt(text) {
|
|
12128
12148
|
if (!this.connection || !this.sessionId) {
|
|
12129
12149
|
throw new Error("AcpClient.prompt called before start()");
|
|
12130
12150
|
}
|
|
12131
|
-
|
|
12151
|
+
log.info(
|
|
12152
|
+
"acpClient",
|
|
12153
|
+
`prompt \u2192 session=${this.sessionId.slice(0, 8)} chars=${text.length}`
|
|
12154
|
+
);
|
|
12155
|
+
const t0 = Date.now();
|
|
12156
|
+
const send = this.connection.prompt({
|
|
12132
12157
|
sessionId: this.sessionId,
|
|
12133
12158
|
prompt: [{ type: "text", text }]
|
|
12134
12159
|
});
|
|
12160
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
12161
|
+
const id = setTimeout(() => {
|
|
12162
|
+
reject(
|
|
12163
|
+
new Error(
|
|
12164
|
+
`ACP prompt timed out after ${PROMPT_TIMEOUT_MS / 1e3}s \u2014 adapter never responded. Likely the underlying agent's auth or network is misconfigured; check the adapter stderr lines above (acpAdapter tag) for the actual error.`
|
|
12165
|
+
)
|
|
12166
|
+
);
|
|
12167
|
+
}, PROMPT_TIMEOUT_MS);
|
|
12168
|
+
void send.finally(() => clearTimeout(id));
|
|
12169
|
+
});
|
|
12170
|
+
try {
|
|
12171
|
+
const result = await Promise.race([send, timeout]);
|
|
12172
|
+
log.info(
|
|
12173
|
+
"acpClient",
|
|
12174
|
+
`prompt \u2190 ok stopReason=${result.stopReason ?? "?"} elapsedMs=${Date.now() - t0}`
|
|
12175
|
+
);
|
|
12176
|
+
return result;
|
|
12177
|
+
} catch (err) {
|
|
12178
|
+
log.warn(
|
|
12179
|
+
"acpClient",
|
|
12180
|
+
`prompt \u2190 failed elapsedMs=${Date.now() - t0} err=${err instanceof Error ? err.message : String(err)}`
|
|
12181
|
+
);
|
|
12182
|
+
throw err;
|
|
12183
|
+
}
|
|
12135
12184
|
}
|
|
12136
12185
|
/**
|
|
12137
12186
|
* Cancel the in-flight prompt turn. Notification — no response.
|
|
@@ -12568,13 +12617,22 @@ async function runAcpSession(opts) {
|
|
|
12568
12617
|
pluginId: opts.pluginId,
|
|
12569
12618
|
pluginAuthToken: opts.pluginAuthToken
|
|
12570
12619
|
});
|
|
12620
|
+
let updateCount = 0;
|
|
12571
12621
|
const client2 = new AcpClient({
|
|
12572
12622
|
adapter: opts.adapter,
|
|
12573
12623
|
cwd: opts.cwd,
|
|
12574
12624
|
onSessionUpdate: (notification) => {
|
|
12625
|
+
updateCount += 1;
|
|
12626
|
+
const variant = notification.update?.sessionUpdate ?? "unknown";
|
|
12575
12627
|
const chunks = mapSessionUpdate(notification);
|
|
12628
|
+
log.info(
|
|
12629
|
+
"acpRunner",
|
|
12630
|
+
`update #${updateCount} variant=${variant} mappedChunks=${chunks.length}`
|
|
12631
|
+
);
|
|
12576
12632
|
for (const chunk2 of chunks) {
|
|
12577
|
-
void publisher.publishChunk(chunk2)
|
|
12633
|
+
void publisher.publishChunk(chunk2).catch((err) => {
|
|
12634
|
+
log.warn("acpRunner", `publishChunk failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
12635
|
+
});
|
|
12578
12636
|
}
|
|
12579
12637
|
},
|
|
12580
12638
|
onRequestPermission: async (request) => {
|
|
@@ -12594,8 +12652,7 @@ async function runAcpSession(opts) {
|
|
|
12594
12652
|
}
|
|
12595
12653
|
return { outcome: { outcome: "selected", optionId } };
|
|
12596
12654
|
},
|
|
12597
|
-
onStderr: (
|
|
12598
|
-
log.trace("acpAdapter", line);
|
|
12655
|
+
onStderr: (_line) => {
|
|
12599
12656
|
},
|
|
12600
12657
|
onUnexpectedExit: (code, signal) => {
|
|
12601
12658
|
log.warn("acpRunner", `adapter died code=${code} signal=${signal}; shutting down session`);
|
|
@@ -12647,8 +12704,10 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models) {
|
|
|
12647
12704
|
await relay.sendResult(cmd.id, "failed", { error: "empty prompt" });
|
|
12648
12705
|
return;
|
|
12649
12706
|
}
|
|
12707
|
+
log.info("acpRunner", `start_task \u2192 forwarding prompt chars=${prompt.length} id=${cmd.id.slice(0, 8)}`);
|
|
12650
12708
|
try {
|
|
12651
12709
|
const reply = await client2.prompt(prompt);
|
|
12710
|
+
log.info("acpRunner", `start_task \u2190 done stopReason=${reply.stopReason ?? "?"} id=${cmd.id.slice(0, 8)}`);
|
|
12652
12711
|
await relay.sendResult(cmd.id, "completed", { stopReason: reply.stopReason });
|
|
12653
12712
|
} catch (err) {
|
|
12654
12713
|
log.warn("acpRunner", `prompt failed: ${describeError(err)}`);
|
|
@@ -21171,7 +21230,7 @@ function checkChokidar() {
|
|
|
21171
21230
|
}
|
|
21172
21231
|
async function doctor(args2 = []) {
|
|
21173
21232
|
const json = args2.includes("--json");
|
|
21174
|
-
const cliVersion = true ? "2.27.
|
|
21233
|
+
const cliVersion = true ? "2.27.7" : "0.0.0-dev";
|
|
21175
21234
|
const apiBase = resolveApiBaseUrl();
|
|
21176
21235
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
21177
21236
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -21370,7 +21429,7 @@ async function completion(args2) {
|
|
|
21370
21429
|
// src/commands/version.ts
|
|
21371
21430
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
21372
21431
|
function version2() {
|
|
21373
|
-
const v = true ? "2.27.
|
|
21432
|
+
const v = true ? "2.27.7" : "unknown";
|
|
21374
21433
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
21375
21434
|
}
|
|
21376
21435
|
|
|
@@ -21598,7 +21657,7 @@ function checkForUpdates() {
|
|
|
21598
21657
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21599
21658
|
if (process.env.CI) return;
|
|
21600
21659
|
if (!process.stdout.isTTY) return;
|
|
21601
|
-
const current = true ? "2.27.
|
|
21660
|
+
const current = true ? "2.27.7" : null;
|
|
21602
21661
|
if (!current) return;
|
|
21603
21662
|
const cache = readCache();
|
|
21604
21663
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.27.
|
|
3
|
+
"version": "2.27.7",
|
|
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",
|