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 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.4",
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.4" : "0.0.0-dev",
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
- cursor: () => {
12017
- const bin = resolveBin("cursor-agent-acp", "cursor-agent-acp");
12018
- if (!bin) return null;
12019
- return {
12020
- command: process.execPath,
12021
- args: [bin],
12022
- requiresAgentBinary: "cursor-agent"
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
- JSON.stringify(event)
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
- JSON.stringify(event)
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 import_os7 = require("os");
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, import_os7.tmpdir)();
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 import_os8 = __toESM(require("os"));
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(import_os8.default.homedir(), ".codeam", "bin", "cloudflared");
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.4" : "0.0.0-dev";
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.4" : "unknown";
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.4" : null;
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.4",
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",