codeam-cli 2.27.4 → 2.27.6
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 +18 -0
- package/dist/index.js +75 -24
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ 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.5] — 2026-06-06
|
|
8
|
+
|
|
9
|
+
### Chore
|
|
10
|
+
|
|
11
|
+
- **cli:** Drop cursor-agent-acp — pulls deprecated SDK
|
|
12
|
+
|
|
13
|
+
## [2.27.4] — 2026-06-06
|
|
14
|
+
|
|
15
|
+
### Tests
|
|
16
|
+
|
|
17
|
+
- **cli:** Fix gemini local-token tests on Windows
|
|
18
|
+
|
|
19
|
+
## [2.27.3] — 2026-06-06
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **cli:** Finish e2e Gemini support — link flow + runtime
|
|
24
|
+
|
|
7
25
|
## [2.27.2] — 2026-06-06
|
|
8
26
|
|
|
9
27
|
### Added
|
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.6",
|
|
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",
|
|
@@ -573,7 +573,6 @@ var package_default = {
|
|
|
573
573
|
"@agentclientprotocol/sdk": "^0.25.0",
|
|
574
574
|
"@clack/prompts": "^1.2.0",
|
|
575
575
|
chokidar: "^3.6.0",
|
|
576
|
-
"cursor-agent-acp": "^0.1.1",
|
|
577
576
|
picocolors: "^1.1.0",
|
|
578
577
|
"qrcode-terminal": "^0.12.0",
|
|
579
578
|
which: "^5.0.0",
|
|
@@ -5874,7 +5873,7 @@ function readAnonId() {
|
|
|
5874
5873
|
}
|
|
5875
5874
|
function superProperties() {
|
|
5876
5875
|
return {
|
|
5877
|
-
cliVersion: true ? "2.27.
|
|
5876
|
+
cliVersion: true ? "2.27.6" : "0.0.0-dev",
|
|
5878
5877
|
nodeVersion: process.version,
|
|
5879
5878
|
platform: process.platform,
|
|
5880
5879
|
arch: process.arch,
|
|
@@ -12013,15 +12012,28 @@ var REGISTRY = {
|
|
|
12013
12012
|
requiresAgentBinary: "codex"
|
|
12014
12013
|
};
|
|
12015
12014
|
},
|
|
12016
|
-
|
|
12017
|
-
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12015
|
+
// Cursor is intentionally NOT bundled right now. The only published
|
|
12016
|
+
// ACP adapter (`cursor-agent-acp@0.1.1`) still depends on the
|
|
12017
|
+
// deprecated `@zed-industries/agent-client-protocol` SDK; pulling it
|
|
12018
|
+
// back into the install would surface the deprecation warning to
|
|
12019
|
+
// every user of `codeam-cli`. The community forks (`cursor-acp`,
|
|
12020
|
+
// `fzx-cursor-acp`) use the current `@agentclientprotocol/sdk` but
|
|
12021
|
+
// are single-maintainer with no security track record we trust to
|
|
12022
|
+
// auto-bundle.
|
|
12023
|
+
//
|
|
12024
|
+
// Re-add this entry the moment an `@agentclientprotocol/cursor-acp`
|
|
12025
|
+
// ships under the official namespace, or upstream cursor-agent-acp
|
|
12026
|
+
// publishes a release that uses the new SDK:
|
|
12027
|
+
//
|
|
12028
|
+
// cursor: () => {
|
|
12029
|
+
// const bin = resolveBin('@agentclientprotocol/cursor-acp', 'cursor-acp');
|
|
12030
|
+
// if (!bin) return null;
|
|
12031
|
+
// return { command: process.execPath, args: [bin], requiresAgentBinary: 'cursor-agent' };
|
|
12032
|
+
// },
|
|
12033
|
+
//
|
|
12034
|
+
// Until then `getAcpAdapter('cursor')` returns null and the dispatch
|
|
12035
|
+
// in start.ts falls back to the legacy PTY runtime — same behaviour
|
|
12036
|
+
// cursor users had before ACP was added.
|
|
12025
12037
|
// Gemini speaks ACP natively via `gemini --acp` — no npm adapter
|
|
12026
12038
|
// package, just the user-installed `gemini` binary on PATH. Same
|
|
12027
12039
|
// {@link AdapterSpec} shape; the only difference is `command` is
|
|
@@ -12312,6 +12324,21 @@ var AcpPublisher = class {
|
|
|
12312
12324
|
opts;
|
|
12313
12325
|
apiBase;
|
|
12314
12326
|
headers;
|
|
12327
|
+
/**
|
|
12328
|
+
* Wrap the event with `sessionId` + `pluginId` at the top level.
|
|
12329
|
+
* The backend's `PluginAuthGuard` reads both fields from the JSON
|
|
12330
|
+
* body even when `X-Plugin-Auth-Token` is set on the header and
|
|
12331
|
+
* `:sessionId` is on the URL path. Without the body fields it
|
|
12332
|
+
* rejects every POST with `PLUGIN_TOKEN_REQUIRED` — same shape the
|
|
12333
|
+
* legacy `streaming-emitter.service.ts` `postWithRetries` uses.
|
|
12334
|
+
*/
|
|
12335
|
+
envelope(event) {
|
|
12336
|
+
return JSON.stringify({
|
|
12337
|
+
sessionId: this.opts.sessionId,
|
|
12338
|
+
pluginId: this.opts.pluginId,
|
|
12339
|
+
...event
|
|
12340
|
+
});
|
|
12341
|
+
}
|
|
12315
12342
|
/**
|
|
12316
12343
|
* Fire-and-forget chunk POST. The backend's per-user SSE bus
|
|
12317
12344
|
* forwards each chunk to mobile/landing within ~20 ms (PRO) /
|
|
@@ -12324,7 +12351,7 @@ var AcpPublisher = class {
|
|
|
12324
12351
|
const { statusCode, body } = await _transport2.post(
|
|
12325
12352
|
url,
|
|
12326
12353
|
this.headers,
|
|
12327
|
-
|
|
12354
|
+
this.envelope(event)
|
|
12328
12355
|
);
|
|
12329
12356
|
if (statusCode < 200 || statusCode >= 300) {
|
|
12330
12357
|
log.warn("acpPublisher", `chunk status=${statusCode} body=${body.slice(0, 200)}`);
|
|
@@ -12345,7 +12372,7 @@ var AcpPublisher = class {
|
|
|
12345
12372
|
const { statusCode, body } = await _transport2.post(
|
|
12346
12373
|
url,
|
|
12347
12374
|
this.headers,
|
|
12348
|
-
|
|
12375
|
+
this.envelope(event)
|
|
12349
12376
|
);
|
|
12350
12377
|
if (statusCode < 200 || statusCode >= 300) {
|
|
12351
12378
|
log.warn("acpPublisher", `awaiting-answer status=${statusCode} body=${body.slice(0, 200)}`);
|
|
@@ -12587,10 +12614,13 @@ async function runAcpSession(opts) {
|
|
|
12587
12614
|
"acpRunner",
|
|
12588
12615
|
`adapter handshake ok protocolVersion=${initialize.protocolVersion} sessionId=${acpSessionId.slice(0, 8)}`
|
|
12589
12616
|
);
|
|
12617
|
+
showSuccess(`${opts.agent} online (ACP) \u2014 awaiting prompts from mobile.`);
|
|
12618
|
+
const runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
|
|
12619
|
+
const models = await runtime.listModels();
|
|
12590
12620
|
const relay = new CommandRelayService(
|
|
12591
12621
|
opts.pluginId,
|
|
12592
12622
|
async (cmd) => {
|
|
12593
|
-
await handleCommand(cmd, client2);
|
|
12623
|
+
await handleCommand(cmd, client2, relay, acpSessionId, models);
|
|
12594
12624
|
},
|
|
12595
12625
|
{ id: opts.agent, name: opts.agent, displayName: opts.agent }
|
|
12596
12626
|
);
|
|
@@ -12607,19 +12637,22 @@ async function runAcpSession(opts) {
|
|
|
12607
12637
|
await new Promise(() => {
|
|
12608
12638
|
});
|
|
12609
12639
|
}
|
|
12610
|
-
async function handleCommand(cmd, client2) {
|
|
12640
|
+
async function handleCommand(cmd, client2, relay, acpSessionId, models) {
|
|
12611
12641
|
switch (cmd.type) {
|
|
12612
12642
|
case "start_task": {
|
|
12613
12643
|
const payload = cmd.payload;
|
|
12614
12644
|
const prompt = payload?.prompt?.trim();
|
|
12615
12645
|
if (!prompt) {
|
|
12616
12646
|
log.warn("acpRunner", "start_task with empty prompt; ignoring");
|
|
12647
|
+
await relay.sendResult(cmd.id, "failed", { error: "empty prompt" });
|
|
12617
12648
|
return;
|
|
12618
12649
|
}
|
|
12619
12650
|
try {
|
|
12620
|
-
await client2.prompt(prompt);
|
|
12651
|
+
const reply = await client2.prompt(prompt);
|
|
12652
|
+
await relay.sendResult(cmd.id, "completed", { stopReason: reply.stopReason });
|
|
12621
12653
|
} catch (err) {
|
|
12622
12654
|
log.warn("acpRunner", `prompt failed: ${describeError(err)}`);
|
|
12655
|
+
await relay.sendResult(cmd.id, "failed", { error: describeError(err) });
|
|
12623
12656
|
}
|
|
12624
12657
|
return;
|
|
12625
12658
|
}
|
|
@@ -12627,13 +12660,31 @@ async function handleCommand(cmd, client2) {
|
|
|
12627
12660
|
case "escape_key": {
|
|
12628
12661
|
try {
|
|
12629
12662
|
await client2.cancel();
|
|
12663
|
+
await relay.sendResult(cmd.id, "completed", {});
|
|
12630
12664
|
} catch (err) {
|
|
12631
12665
|
log.warn("acpRunner", `cancel failed: ${describeError(err)}`);
|
|
12666
|
+
await relay.sendResult(cmd.id, "failed", { error: describeError(err) });
|
|
12632
12667
|
}
|
|
12633
12668
|
return;
|
|
12634
12669
|
}
|
|
12670
|
+
case "get_conversation": {
|
|
12671
|
+
await relay.sendResult(cmd.id, "completed", { conversationId: acpSessionId });
|
|
12672
|
+
return;
|
|
12673
|
+
}
|
|
12674
|
+
case "list_models": {
|
|
12675
|
+
await relay.sendResult(cmd.id, "completed", { models });
|
|
12676
|
+
return;
|
|
12677
|
+
}
|
|
12678
|
+
case "set_keep_alive":
|
|
12679
|
+
case "get_context": {
|
|
12680
|
+
await relay.sendResult(cmd.id, "completed", {});
|
|
12681
|
+
return;
|
|
12682
|
+
}
|
|
12635
12683
|
default:
|
|
12636
12684
|
log.trace("acpRunner", `command type "${cmd.type}" not supported in Phase 1 ACP mode`);
|
|
12685
|
+
await relay.sendResult(cmd.id, "failed", {
|
|
12686
|
+
error: `Command "${cmd.type}" is not supported in Phase 1 ACP mode.`
|
|
12687
|
+
});
|
|
12637
12688
|
return;
|
|
12638
12689
|
}
|
|
12639
12690
|
}
|
|
@@ -14804,7 +14855,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
14804
14855
|
// src/services/turn-files/files-outbox.ts
|
|
14805
14856
|
var fs24 = __toESM(require("fs/promises"));
|
|
14806
14857
|
var path29 = __toESM(require("path"));
|
|
14807
|
-
var
|
|
14858
|
+
var import_os8 = require("os");
|
|
14808
14859
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
14809
14860
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
14810
14861
|
var BACKOFF_STEPS_MS = [
|
|
@@ -14971,7 +15022,7 @@ function applyJitter(ms) {
|
|
|
14971
15022
|
return Math.round(ms * factor);
|
|
14972
15023
|
}
|
|
14973
15024
|
function homeDir() {
|
|
14974
|
-
return process.env.HOME ?? process.env.USERPROFILE ?? (0,
|
|
15025
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os8.tmpdir)();
|
|
14975
15026
|
}
|
|
14976
15027
|
|
|
14977
15028
|
// src/services/turn-files/turn-file-aggregator.ts
|
|
@@ -16920,11 +16971,11 @@ async function linkDryRunPreflight(ctx) {
|
|
|
16920
16971
|
var import_promises = require("dns/promises");
|
|
16921
16972
|
var import_fs = require("fs");
|
|
16922
16973
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
16923
|
-
var
|
|
16974
|
+
var import_os9 = __toESM(require("os"));
|
|
16924
16975
|
var import_path4 = __toESM(require("path"));
|
|
16925
16976
|
var import_promises3 = require("stream/promises");
|
|
16926
16977
|
var import_which = __toESM(require("which"));
|
|
16927
|
-
var CACHED_BINARY = import_path4.default.join(
|
|
16978
|
+
var CACHED_BINARY = import_path4.default.join(import_os9.default.homedir(), ".codeam", "bin", "cloudflared");
|
|
16928
16979
|
async function waitForCloudflaredReady(url, timeoutMs = 6e4) {
|
|
16929
16980
|
const hostname3 = new URL(url).hostname;
|
|
16930
16981
|
const resolver = new import_promises.Resolver();
|
|
@@ -21120,7 +21171,7 @@ function checkChokidar() {
|
|
|
21120
21171
|
}
|
|
21121
21172
|
async function doctor(args2 = []) {
|
|
21122
21173
|
const json = args2.includes("--json");
|
|
21123
|
-
const cliVersion = true ? "2.27.
|
|
21174
|
+
const cliVersion = true ? "2.27.6" : "0.0.0-dev";
|
|
21124
21175
|
const apiBase = resolveApiBaseUrl();
|
|
21125
21176
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
21126
21177
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -21319,7 +21370,7 @@ async function completion(args2) {
|
|
|
21319
21370
|
// src/commands/version.ts
|
|
21320
21371
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
21321
21372
|
function version2() {
|
|
21322
|
-
const v = true ? "2.27.
|
|
21373
|
+
const v = true ? "2.27.6" : "unknown";
|
|
21323
21374
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
21324
21375
|
}
|
|
21325
21376
|
|
|
@@ -21547,7 +21598,7 @@ function checkForUpdates() {
|
|
|
21547
21598
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21548
21599
|
if (process.env.CI) return;
|
|
21549
21600
|
if (!process.stdout.isTTY) return;
|
|
21550
|
-
const current = true ? "2.27.
|
|
21601
|
+
const current = true ? "2.27.6" : null;
|
|
21551
21602
|
if (!current) return;
|
|
21552
21603
|
const cache = readCache();
|
|
21553
21604
|
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.6",
|
|
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",
|
|
@@ -75,7 +75,6 @@
|
|
|
75
75
|
"@agentclientprotocol/sdk": "^0.25.0",
|
|
76
76
|
"@clack/prompts": "^1.2.0",
|
|
77
77
|
"chokidar": "^3.6.0",
|
|
78
|
-
"cursor-agent-acp": "^0.1.1",
|
|
79
78
|
"picocolors": "^1.1.0",
|
|
80
79
|
"qrcode-terminal": "^0.12.0",
|
|
81
80
|
"which": "^5.0.0",
|