codeam-cli 2.65.6 → 2.65.8

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.js +149 -37
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ 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.65.7] — 2026-08-15
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Honest credential/empty-turn errors + partial-fence holdback
12
+ - **cli:** Credential error propagation matches the real transport error shape
13
+
14
+ ## [2.65.6] — 2026-08-15
15
+
16
+ ### Fixed
17
+
18
+ - **cli:** Accumulated stream keeps post-cut deltas + unclosed trailing fence tolerated
19
+
7
20
  ## [2.65.4] — 2026-08-14
8
21
 
9
22
  ### Fixed
package/dist/index.js CHANGED
@@ -8079,7 +8079,7 @@ function readAnonId() {
8079
8079
  }
8080
8080
  function superProperties() {
8081
8081
  return {
8082
- cliVersion: true ? "2.65.6" : "0.0.0-dev",
8082
+ cliVersion: true ? "2.65.8" : "0.0.0-dev",
8083
8083
  nodeVersion: process.version,
8084
8084
  platform: process.platform,
8085
8085
  arch: process.arch,
@@ -8260,7 +8260,7 @@ var os4 = __toESM(require("os"));
8260
8260
  // package.json
8261
8261
  var package_default = {
8262
8262
  name: "codeam-cli",
8263
- version: "2.65.6",
8263
+ version: "2.65.8",
8264
8264
  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.",
8265
8265
  type: "commonjs",
8266
8266
  main: "dist/index.js",
@@ -8632,7 +8632,19 @@ async function postHeadroomEvent(input) {
8632
8632
  };
8633
8633
  }
8634
8634
  }
8635
- async function fetchProvisionCredential(input) {
8635
+ function parseBackendErrorBody(body) {
8636
+ if (!body) return null;
8637
+ try {
8638
+ const parsed = JSON.parse(body);
8639
+ const nested = parsed.error;
8640
+ const code = typeof nested?.code === "string" ? nested.code : typeof parsed.code === "string" ? parsed.code : void 0;
8641
+ const message = typeof nested?.message === "string" ? nested.message : typeof parsed.message === "string" ? parsed.message : void 0;
8642
+ return code || message ? { code, message } : null;
8643
+ } catch {
8644
+ return null;
8645
+ }
8646
+ }
8647
+ async function fetchProvisionCredentialDetailed(input) {
8636
8648
  try {
8637
8649
  const res = await _transport.postJsonAuthed(
8638
8650
  `${API_BASE}/api/plugin/agents/${input.agentId}/provision-credential`,
@@ -8646,16 +8658,29 @@ async function fetchProvisionCredential(input) {
8646
8658
  const data = res?.data;
8647
8659
  if (data && (data.method === "api_key" || data.method === "oauth") && typeof data.credential === "string" && data.credential.length > 0) {
8648
8660
  return {
8661
+ ok: true,
8649
8662
  method: data.method,
8650
8663
  credential: data.credential,
8651
8664
  ...typeof data.installScript === "string" && data.installScript.length > 0 ? { installScript: data.installScript } : {}
8652
8665
  };
8653
8666
  }
8654
- return null;
8655
- } catch {
8656
- return null;
8667
+ return { ok: false, status: 0 };
8668
+ } catch (err) {
8669
+ const e = err;
8670
+ const status2 = typeof e.statusCode === "number" ? e.statusCode : 0;
8671
+ const parsed = parseBackendErrorBody(e.body);
8672
+ return { ok: false, status: status2, code: parsed?.code, message: parsed?.message };
8657
8673
  }
8658
8674
  }
8675
+ async function fetchProvisionCredential(input) {
8676
+ const res = await fetchProvisionCredentialDetailed(input);
8677
+ if (!res.ok) return null;
8678
+ return {
8679
+ method: res.method,
8680
+ credential: res.credential,
8681
+ ...res.installScript ? { installScript: res.installScript } : {}
8682
+ };
8683
+ }
8659
8684
  async function fetchSquadRoster(input) {
8660
8685
  try {
8661
8686
  const res = await _transport.postJsonAuthed(
@@ -8860,6 +8885,7 @@ function makeHttpError(statusCode, retryAfterHeader, responseBody) {
8860
8885
  );
8861
8886
  err.statusCode = statusCode;
8862
8887
  if (typeof retryAfterSeconds === "number") err.retryAfterSeconds = retryAfterSeconds;
8888
+ if (responseBody) err.body = responseBody;
8863
8889
  return err;
8864
8890
  }
8865
8891
  async function _postJson(url2, body, extraHeaders) {
@@ -9332,18 +9358,20 @@ var API_BASE2 = resolveApiBaseUrl();
9332
9358
  var SSE_LIVENESS_TIMEOUT_MS = 45e3;
9333
9359
  var SSE_WATCHDOG_INTERVAL_MS = 1e4;
9334
9360
  var CommandRelayService = class _CommandRelayService {
9335
- constructor(pluginId, onCommand, agentMeta, agentsOverride, explicitPollSecret) {
9361
+ constructor(pluginId, onCommand, agentMeta, agentsOverride, explicitPollSecret, onHeartbeat) {
9336
9362
  this.pluginId = pluginId;
9337
9363
  this.onCommand = onCommand;
9338
9364
  this.agentMeta = agentMeta;
9339
9365
  this.agentsOverride = agentsOverride;
9340
9366
  this.explicitPollSecret = explicitPollSecret;
9367
+ this.onHeartbeat = onHeartbeat;
9341
9368
  }
9342
9369
  pluginId;
9343
9370
  onCommand;
9344
9371
  agentMeta;
9345
9372
  agentsOverride;
9346
9373
  explicitPollSecret;
9374
+ onHeartbeat;
9347
9375
  _running = false;
9348
9376
  pairingInvalid = false;
9349
9377
  heartbeatTimer = null;
@@ -9406,16 +9434,35 @@ var CommandRelayService = class _CommandRelayService {
9406
9434
  * freshness, and a punctual heartbeat matters far more.
9407
9435
  */
9408
9436
  cachedBranch = null;
9437
+ /**
9438
+ * Set whenever the command channel is (re-)established; consumed by the
9439
+ * next {@link emitHeartbeatTick}. See the `onHeartbeat` ctor param.
9440
+ */
9441
+ heartbeatFirstAfterConnect = true;
9442
+ /** Invoke the heartbeat rider (if any) exactly once per beat. Never throws. */
9443
+ emitHeartbeatTick() {
9444
+ if (!this.onHeartbeat) return;
9445
+ const firstAfterConnect = this.heartbeatFirstAfterConnect;
9446
+ this.heartbeatFirstAfterConnect = false;
9447
+ try {
9448
+ this.onHeartbeat({ firstAfterConnect });
9449
+ } catch (err) {
9450
+ log.trace("relay", "heartbeat rider threw (ignored)", err);
9451
+ }
9452
+ }
9409
9453
  start() {
9410
9454
  this.cleanup();
9411
9455
  this._running = true;
9456
+ this.heartbeatFirstAfterConnect = true;
9412
9457
  this.agentsRegistered = false;
9413
9458
  log.info("relay", `start pluginId=${this.pluginId.slice(0, 8)} agent=${this.agentMeta.id}`);
9414
9459
  this.cachedBranch = detectCurrentBranch();
9415
9460
  this.sendHeartbeat(true);
9461
+ this.emitHeartbeatTick();
9416
9462
  this.heartbeatTimer = setInterval(() => {
9417
9463
  void this.refreshBranch();
9418
9464
  this.sendHeartbeat(true);
9465
+ this.emitHeartbeatTick();
9419
9466
  }, 2e4);
9420
9467
  this.agentsTimer = setInterval(() => {
9421
9468
  if (this._running && !this.agentsRegistered) this.reportAgents();
@@ -9499,6 +9546,7 @@ var CommandRelayService = class _CommandRelayService {
9499
9546
  }
9500
9547
  log.info("relay", "sse connected");
9501
9548
  this.sseFailures = 0;
9549
+ this.heartbeatFirstAfterConnect = true;
9502
9550
  this.armSseWatchdog();
9503
9551
  let buffer = "";
9504
9552
  res.setEncoding("utf8");
@@ -9616,6 +9664,7 @@ var CommandRelayService = class _CommandRelayService {
9616
9664
  // ─── Polling fallback ────────────────────────────────────────────
9617
9665
  startPollingFallback() {
9618
9666
  if (this.pollTimer) return;
9667
+ this.heartbeatFirstAfterConnect = true;
9619
9668
  void this.pollLoop();
9620
9669
  }
9621
9670
  async pollLoop() {
@@ -9712,7 +9761,7 @@ var CommandRelayService = class _CommandRelayService {
9712
9761
  // fresh + clear the "CLI update available" banner after a self-update
9713
9762
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9714
9763
  // pair/reconnect). Older backends ignore the extra field.
9715
- ..."2.65.6" ? { ideVersion: "2.65.6" } : {}
9764
+ ..."2.65.8" ? { ideVersion: "2.65.8" } : {}
9716
9765
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9717
9766
  }
9718
9767
  /**
@@ -21641,7 +21690,7 @@ async function autoUpgradeBeforeCriticalCommand() {
21641
21690
  if (process.env.NODE_ENV === "test") return;
21642
21691
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
21643
21692
  if (process.env.CI) return;
21644
- const current2 = true ? "2.65.6" : null;
21693
+ const current2 = true ? "2.65.8" : null;
21645
21694
  if (!current2) return;
21646
21695
  const cache = readCache();
21647
21696
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21658,7 +21707,7 @@ function checkForUpdates() {
21658
21707
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
21659
21708
  if (process.env.CI) return;
21660
21709
  if (!process.stdout.isTTY) return;
21661
- const current2 = true ? "2.65.6" : null;
21710
+ const current2 = true ? "2.65.8" : null;
21662
21711
  if (!current2) return;
21663
21712
  const cache = readCache();
21664
21713
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21678,7 +21727,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
21678
21727
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
21679
21728
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
21680
21729
  function currentCliVersion() {
21681
- return true ? "2.65.6" : null;
21730
+ return true ? "2.65.8" : null;
21682
21731
  }
21683
21732
  function runCmd(cmd, args2, timeoutMs) {
21684
21733
  return new Promise((resolve9) => {
@@ -34738,6 +34787,10 @@ var NON_SWITCHABLE = /* @__PURE__ */ new Set([
34738
34787
  function displayName(id) {
34739
34788
  return isKnownAgentId(id) ? AGENT_REGISTRY[id]?.displayName ?? id : id;
34740
34789
  }
34790
+ function credentialFailureMessage(agentId, failure) {
34791
+ if (failure.message) return failure.message;
34792
+ return `No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`;
34793
+ }
34741
34794
  function resolveSwitchTarget(raw, currentAgent) {
34742
34795
  if (typeof raw !== "string" || raw.length === 0) {
34743
34796
  return { ok: false, error: "switch_agent: missing agentId" };
@@ -34854,10 +34907,8 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
34854
34907
  if (!fastPath.skipProvision) {
34855
34908
  void emitStep("credential");
34856
34909
  const cred = await deps.fetchCredential(agentId);
34857
- if (!cred) {
34858
- return fail2(
34859
- `No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`
34860
- );
34910
+ if (!cred.ok) {
34911
+ return fail2(credentialFailureMessage(agentId, cred));
34861
34912
  }
34862
34913
  try {
34863
34914
  deps.provisionCredential(agentId, toAgentAuth(cred.method, cred.credential));
@@ -35574,6 +35625,15 @@ function handoffFenceStartMasked(text) {
35574
35625
  }
35575
35626
  return -1;
35576
35627
  }
35628
+ function withholdTrailingPartialFenceMarker(text) {
35629
+ const maxLen = Math.min(text.length, FENCE_OPEN.length - 1);
35630
+ for (let len = maxLen; len > 0; len--) {
35631
+ if (FENCE_OPEN.startsWith(text.slice(text.length - len))) {
35632
+ return text.slice(0, text.length - len);
35633
+ }
35634
+ }
35635
+ return text;
35636
+ }
35577
35637
 
35578
35638
  // src/agents/acp/onboarding.ts
35579
35639
  var import_child_process28 = require("child_process");
@@ -36608,6 +36668,11 @@ var AUTH_FAILURE_MESSAGE = "\u{1F512} **Authentication failed \u2014 your agent
36608
36668
  var CURSOR_UPGRADE_MESSAGE = "\u26A1 **Cursor needs a paid plan to run the agent.**\n\nThe headless Cursor Agent requires Cursor **Pro** \u2014 your Free plan\u2019s included usage does NOT cover Agent runs, even with quota left. This is your Cursor account (not CodeAgent). Upgrade, then send your message again:\n\n[Upgrade to Cursor Pro \u2192](https://cursor.com/dashboard)";
36609
36669
  var ONE_M_CREDITS_MESSAGE = "\u{1F504} **Reconnect your Claude subscription to continue.**\n\nClaude requested 1M-context but your account doesn\u2019t have the usage credits for it on this credential. Reconnecting refreshes your subscription so the agent can keep going \u2014 disabling 1M context won\u2019t fix a credits gate.\n\nTap [Reconnect this agent](codeam://reauth) to reconnect your Claude subscription in Profile \u203A Agents, then send your message again.";
36610
36670
  var TURN_FAILURE_MESSAGE = "\u26A0\uFE0F **The agent hit an error and couldn\u2019t finish this turn.** Please send your message again.";
36671
+ function emptyReplyMessage(agent) {
36672
+ const label = isKnownAgentId(agent) ? AGENT_REGISTRY[agent].displayName : agent;
36673
+ const binary = isKnownAgentId(agent) ? AGENT_REGISTRY[agent].binaryName : agent;
36674
+ return `\u26A0\uFE0F **${label} returned an empty reply.** Its provider may be having issues \u2014 check the agent's login/subscription on this machine (e.g. run \`${binary} -p "test"\` there).`;
36675
+ }
36611
36676
  var PROVIDER_OUTAGE_RE = /overloaded_error|\boverloaded\b|service[ _]unavailable|temporarily[ _]unavailable|(?:api error|http|status)[:\s]+(?:529|503|502|504)\b|\b(?:529|503|502|504)\b[^\n]{0,40}(?:overload|unavailable|gateway|upstream|server error)|bad gateway|gateway time-?out|upstream (?:error|connect|timeout)/i;
36612
36677
  function looksLikeProviderOutage(text) {
36613
36678
  return PROVIDER_OUTAGE_RE.test(text);
@@ -36643,12 +36708,10 @@ ${recentStderr}`;
36643
36708
  if (looksLikeAuthFailure(haystack2)) return AUTH_FAILURE_MESSAGE;
36644
36709
  if (looksLikeProviderOutage(haystack2)) return providerOutageMessage(agent);
36645
36710
  const tail = recentStderr.split("\n").filter(Boolean).slice(-3).join("\n");
36646
- return [
36647
- `\u26A0\uFE0F The ${agent} agent failed to start.`,
36648
- "",
36649
- tail ? `Details:
36650
- ${tail}` : detail
36651
- ].join("\n");
36711
+ return [`\u26A0\uFE0F The ${agent} agent failed to start.`, "", tail ? `Details:
36712
+ ${tail}` : detail].join(
36713
+ "\n"
36714
+ );
36652
36715
  }
36653
36716
  function budgetBubbleMessage(agent, period) {
36654
36717
  return `\u{1F4B8} **Headroom budget reached for the ${period} period.**
@@ -38064,6 +38127,18 @@ async function startTaskH(ctx) {
38064
38127
  error: "agent reply reported 1M-context usage-credits gate"
38065
38128
  });
38066
38129
  return;
38130
+ } else if (reply.stopReason === "end_turn" && finalText.trim().length === 0 && !streaming.hasVisibleProgress()) {
38131
+ const bubble = emptyReplyMessage(opts.agent);
38132
+ await streaming.closeWithBubble(bubble);
38133
+ turnClosed = true;
38134
+ history.appendAgentReply(bubble);
38135
+ void history.flush();
38136
+ turnFiles.flushTurn().catch((err) => {
38137
+ log.warn("acpRunner", `turnFiles.flushTurn failed: ${describeError(err)}`);
38138
+ });
38139
+ log.info("acpRunner", `start_task \u2190 empty-reply id=${cmd.id.slice(0, 8)}`);
38140
+ await relay.sendResult(cmd.id, "failed", { error: "agent turn ended with an empty reply" });
38141
+ return;
38067
38142
  } else {
38068
38143
  await streaming.closeTurnWithInteractiveDetection();
38069
38144
  turnClosed = true;
@@ -38956,13 +39031,14 @@ var StreamingState = class {
38956
39031
  const cumulativeContent = reconcileCumulative(existing?.content ?? "", delta.delta);
38957
39032
  this.streamingChunks.set(chunkId, { kind: delta.kind, content: cumulativeContent });
38958
39033
  let fenceCut = -1;
39034
+ let textVisible = null;
38959
39035
  if (delta.kind === "text") {
38960
39036
  this.recomputeText();
38961
39037
  fenceCut = handoffFenceStartMasked(this.text);
38962
- const visibleText = fenceCut === -1 ? this.text : this.text.slice(0, fenceCut).trimEnd();
38963
- void this.publisher.publishOutput({ type: "text", content: visibleText, done: false });
39038
+ textVisible = fenceCut === -1 ? withholdTrailingPartialFenceMarker(this.text) : this.text.slice(0, fenceCut).trimEnd();
39039
+ void this.publisher.publishOutput({ type: "text", content: textVisible, done: false });
38964
39040
  }
38965
- const visibleChunkContent = delta.kind === "text" && fenceCut !== -1 ? cumulativeContent.slice(0, fenceCut).trimEnd() : cumulativeContent;
39041
+ const visibleChunkContent = delta.kind === "text" ? textVisible : cumulativeContent;
38966
39042
  void this.publisher.publishStreamingChunk({
38967
39043
  chunkId,
38968
39044
  kind: delta.kind,
@@ -39697,7 +39773,7 @@ async function runAcpSession(opts) {
39697
39773
  const switchDeps = {
39698
39774
  currentAgent: () => opts.agent,
39699
39775
  postEvent: emitSwitchEvent,
39700
- fetchCredential: (agentId) => fetchProvisionCredential({
39776
+ fetchCredential: (agentId) => fetchProvisionCredentialDetailed({
39701
39777
  agentId,
39702
39778
  sessionId: opts.sessionId,
39703
39779
  pluginId: opts.pluginId,
@@ -40956,6 +41032,17 @@ var BatonController = class {
40956
41032
  get conversationId() {
40957
41033
  return this._conversationId;
40958
41034
  }
41035
+ /** The exact triple the last `publishState` emitted — the CLI's current view
41036
+ * of who holds the baton. Read by the heartbeat re-affirmation rider
41037
+ * ({@link makeBatonHeartbeatReaffirm}), which re-posts it periodically so the
41038
+ * backend's 1 h Redis snapshot never expires under a live session. */
41039
+ currentState() {
41040
+ return {
41041
+ state: this._state,
41042
+ driver: this._active,
41043
+ conversationId: this._conversationId
41044
+ };
41045
+ }
40959
41046
  async begin() {
40960
41047
  this._conversationId = await this.deps.local.start(void 0);
40961
41048
  this._active = "local_tui";
@@ -41431,6 +41518,21 @@ function makeSerializedBatonPoster(post2) {
41431
41518
  void chain;
41432
41519
  };
41433
41520
  }
41521
+ var BATON_REAFFIRM_INTERVAL_MS = 5 * 6e4;
41522
+ function makeBatonHeartbeatReaffirm(deps) {
41523
+ const now = deps.now ?? Date.now;
41524
+ const intervalMs = deps.intervalMs ?? BATON_REAFFIRM_INTERVAL_MS;
41525
+ let lastAffirmedAt = null;
41526
+ return ({ firstAfterConnect }) => {
41527
+ const current2 = deps.currentState();
41528
+ if (!current2) return;
41529
+ if (current2.state === "SWITCHING") return;
41530
+ const at3 = now();
41531
+ if (!firstAfterConnect && lastAffirmedAt !== null && at3 - lastAffirmedAt < intervalMs) return;
41532
+ lastAffirmedAt = at3;
41533
+ deps.publish(current2.state, current2.driver, current2.conversationId);
41534
+ };
41535
+ }
41434
41536
  async function runBatonSession(opts) {
41435
41537
  const publisher = new AcpPublisher({
41436
41538
  sessionId: opts.sessionId,
@@ -41542,18 +41644,21 @@ async function runBatonSession(opts) {
41542
41644
  mirror.start();
41543
41645
  };
41544
41646
  const postBatonState = makeSerializedBatonPoster(postBatonEvent);
41647
+ const publishBatonState = (state, driver, conversationId) => {
41648
+ postBatonState({
41649
+ sessionId: opts.sessionId,
41650
+ pluginId: opts.pluginId,
41651
+ pluginAuthToken: opts.pluginAuthToken,
41652
+ state,
41653
+ driver,
41654
+ conversationId
41655
+ });
41656
+ };
41545
41657
  const controller = new BatonController({
41546
41658
  local: nativeDriver,
41547
41659
  mobile: mobileDriver,
41548
41660
  publishState: (state, driver, conversationId) => {
41549
- postBatonState({
41550
- sessionId: opts.sessionId,
41551
- pluginId: opts.pluginId,
41552
- pluginAuthToken: opts.pluginAuthToken,
41553
- state,
41554
- driver,
41555
- conversationId
41556
- });
41661
+ publishBatonState(state, driver, conversationId);
41557
41662
  if (state === "LOCAL_DRIVE" && conversationId) {
41558
41663
  startMirror(conversationId, firstLocalDrive);
41559
41664
  firstLocalDrive = false;
@@ -41563,6 +41668,7 @@ async function runBatonSession(opts) {
41563
41668
  }
41564
41669
  });
41565
41670
  const dispatchActive = (cmd) => controller.activeSessionDriver.dispatch(cmd);
41671
+ let torn = false;
41566
41672
  relay = new CommandRelayService(
41567
41673
  opts.pluginId,
41568
41674
  makeOnCommand({
@@ -41570,9 +41676,15 @@ async function runBatonSession(opts) {
41570
41676
  dispatchActive,
41571
41677
  ack: (id, status2, result) => relay.sendResult(id, status2, result)
41572
41678
  }),
41573
- runtime.meta
41679
+ runtime.meta,
41680
+ void 0,
41681
+ void 0,
41682
+ makeBatonHeartbeatReaffirm({
41683
+ // Nothing to affirm once the session is torn down.
41684
+ currentState: () => torn ? null : controller.currentState(),
41685
+ publish: publishBatonState
41686
+ })
41574
41687
  );
41575
- let torn = false;
41576
41688
  function teardown() {
41577
41689
  if (torn) return;
41578
41690
  torn = true;
@@ -44625,7 +44737,7 @@ function checkChokidar() {
44625
44737
  }
44626
44738
  async function doctor(args2 = []) {
44627
44739
  const json = args2.includes("--json");
44628
- const cliVersion = true ? "2.65.6" : "0.0.0-dev";
44740
+ const cliVersion = true ? "2.65.8" : "0.0.0-dev";
44629
44741
  const apiBase2 = resolveApiBaseUrl();
44630
44742
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
44631
44743
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -45016,7 +45128,7 @@ async function mcpRun(args2) {
45016
45128
  // src/commands/version.ts
45017
45129
  var import_picocolors15 = __toESM(require("picocolors"));
45018
45130
  function version2() {
45019
- const v = true ? "2.65.6" : "unknown";
45131
+ const v = true ? "2.65.8" : "unknown";
45020
45132
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
45021
45133
  }
45022
45134
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.65.6",
3
+ "version": "2.65.8",
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",