codeam-cli 2.66.1 → 2.67.0

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,13 @@ 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.66.1] — 2026-08-24
8
+
9
+ ### Fixed
10
+
11
+ - **jetbrains-plugin:** An undeliverable prompt must answer "failed", never "completed" (#650)
12
+ - **cli:** Restart onto the version already on disk instead of failing to install it
13
+
7
14
  ## [2.66.0] — 2026-08-21
8
15
 
9
16
  ### Added
package/dist/index.js CHANGED
@@ -8081,7 +8081,7 @@ function readAnonId() {
8081
8081
  }
8082
8082
  function superProperties() {
8083
8083
  return {
8084
- cliVersion: true ? "2.66.1" : "0.0.0-dev",
8084
+ cliVersion: true ? "2.67.0" : "0.0.0-dev",
8085
8085
  nodeVersion: process.version,
8086
8086
  platform: process.platform,
8087
8087
  arch: process.arch,
@@ -8323,7 +8323,7 @@ var http = __toESM(require("http"));
8323
8323
  // package.json
8324
8324
  var package_default = {
8325
8325
  name: "codeam-cli",
8326
- version: "2.66.1",
8326
+ version: "2.67.0",
8327
8327
  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.",
8328
8328
  type: "commonjs",
8329
8329
  main: "dist/index.js",
@@ -8586,6 +8586,16 @@ async function postAiResult(input) {
8586
8586
  };
8587
8587
  }
8588
8588
  }
8589
+ async function fetchNamedPreviewTunnel(input) {
8590
+ const res = await _transport.postJsonAuthed(
8591
+ `${API_BASE}/api/preview/tunnel`,
8592
+ { pluginId: input.pluginId },
8593
+ input.pluginAuthToken
8594
+ );
8595
+ const body = res;
8596
+ if (typeof body?.hostname !== "string" || typeof body?.token !== "string") return null;
8597
+ return { hostname: body.hostname, token: body.token };
8598
+ }
8589
8599
  async function postPreviewEvent(input) {
8590
8600
  try {
8591
8601
  await _transport.postJsonAuthed(
@@ -9845,7 +9855,7 @@ var CommandRelayService = class _CommandRelayService {
9845
9855
  // fresh + clear the "CLI update available" banner after a self-update
9846
9856
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9847
9857
  // pair/reconnect). Older backends ignore the extra field.
9848
- ..."2.66.1" ? { ideVersion: "2.66.1" } : {}
9858
+ ..."2.67.0" ? { ideVersion: "2.67.0" } : {}
9849
9859
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9850
9860
  }
9851
9861
  /**
@@ -22070,7 +22080,7 @@ async function autoUpgradeBeforeCriticalCommand() {
22070
22080
  if (process.env.NODE_ENV === "test") return;
22071
22081
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22072
22082
  if (process.env.CI) return;
22073
- const current2 = true ? "2.66.1" : null;
22083
+ const current2 = true ? "2.67.0" : null;
22074
22084
  if (!current2) return;
22075
22085
  const cache = readCache();
22076
22086
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22087,7 +22097,7 @@ function checkForUpdates() {
22087
22097
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22088
22098
  if (process.env.CI) return;
22089
22099
  if (!process.stdout.isTTY) return;
22090
- const current2 = true ? "2.66.1" : null;
22100
+ const current2 = true ? "2.67.0" : null;
22091
22101
  if (!current2) return;
22092
22102
  const cache = readCache();
22093
22103
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22104,12 +22114,13 @@ function checkForUpdates() {
22104
22114
  // src/commands/host/self-update.ts
22105
22115
  var SELF_UPDATE_PKG = "codeam-cli";
22106
22116
  var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
22117
+ var SELF_UPDATE_DEFER_MAX_MS = 24 * 60 * 60 * 1e3;
22107
22118
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
22108
22119
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
22109
22120
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
22110
22121
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
22111
22122
  function currentCliVersion() {
22112
- return true ? "2.66.1" : null;
22123
+ return true ? "2.67.0" : null;
22113
22124
  }
22114
22125
  async function installedVersion(deps) {
22115
22126
  const ls = await deps.run(
@@ -22578,6 +22589,7 @@ var HostAgentSupervisor = class {
22578
22589
  this.disableService = deps.disableService ?? defaultDisableService;
22579
22590
  this.teardownHeadroom = deps.teardownHeadroom ?? defaultTeardownHeadroom;
22580
22591
  this.selfUpdate = deps.selfUpdate ?? runSelfUpdate;
22592
+ this.now = deps.now ?? (() => Date.now());
22581
22593
  this.onUpdated = deps.onUpdated ?? defaultOnUpdated;
22582
22594
  this.docker = deps.docker ?? defaultDockerRunner;
22583
22595
  this.postResumeFailure = deps.postResumeFailure ?? postSessionErrorBubble;
@@ -22599,6 +22611,7 @@ var HostAgentSupervisor = class {
22599
22611
  selfUpdateTimer = null;
22600
22612
  /** Self-update check + install (injectable; defaults to runSelfUpdate). */
22601
22613
  selfUpdate;
22614
+ now;
22602
22615
  /** Restart action after a successful self-update (defaults to process.exit). */
22603
22616
  onUpdated;
22604
22617
  /** Guards against overlapping self-update ticks (a slow npm install). */
@@ -22609,6 +22622,9 @@ var HostAgentSupervisor = class {
22609
22622
  * already-installed version for the restart log.
22610
22623
  */
22611
22624
  pendingRestartVersion = null;
22625
+ /** epoch ms when the CURRENT pending restart was first owed — the ceiling
22626
+ * in {@link SELF_UPDATE_DEFER_MAX_MS} is measured from here. */
22627
+ pendingRestartSince = null;
22612
22628
  /** Guards the one-shot 'connected' telemetry on the first heartbeat. */
22613
22629
  reportedConnected = false;
22614
22630
  /** Live-metrics collector — stateful across beats (CPU delta + latency). */
@@ -22752,12 +22768,12 @@ var HostAgentSupervisor = class {
22752
22768
  this.selfUpdating = true;
22753
22769
  try {
22754
22770
  if (this.pendingRestartVersion !== null) {
22755
- this.maybeRestartForUpdate(this.pendingRestartVersion);
22756
- return;
22771
+ if (this.maybeRestartForUpdate(this.pendingRestartVersion)) return;
22757
22772
  }
22758
22773
  const result = await this.selfUpdate();
22759
22774
  if (result.status !== "updated") return;
22760
22775
  const version3 = result.version ?? "latest";
22776
+ if (this.pendingRestartVersion === null) this.pendingRestartSince = this.now();
22761
22777
  this.pendingRestartVersion = version3;
22762
22778
  this.maybeRestartForUpdate(version3);
22763
22779
  } catch (err) {
@@ -22776,13 +22792,22 @@ var HostAgentSupervisor = class {
22776
22792
  */
22777
22793
  maybeRestartForUpdate(version3) {
22778
22794
  if (this.children.size > 0) {
22779
- log.info(
22795
+ const since = this.pendingRestartSince ?? this.now();
22796
+ const waited = this.now() - since;
22797
+ if (waited < SELF_UPDATE_DEFER_MAX_MS) {
22798
+ log.info(
22799
+ "host-agent",
22800
+ `self-update: ${version3} installed but ${this.children.size} child(ren) busy \u2014 deferring restart`
22801
+ );
22802
+ return false;
22803
+ }
22804
+ log.warn(
22780
22805
  "host-agent",
22781
- `self-update: ${version3} installed but ${this.children.size} child(ren) busy \u2014 deferring restart`
22806
+ `self-update: ${version3} has been owed for ${Math.round(waited / 36e5)}h with ${this.children.size} child(ren) still running \u2014 restarting anyway rather than staying on old code`
22782
22807
  );
22783
- return;
22784
22808
  }
22785
22809
  this.onUpdated(version3);
22810
+ return true;
22786
22811
  }
22787
22812
  /** Number of live children — for tests + diagnostics. */
22788
22813
  childCount() {
@@ -25123,6 +25148,26 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
25123
25148
  }
25124
25149
  }
25125
25150
 
25151
+ // src/services/preview/named-tunnel.ts
25152
+ async function resolveNamedTunnel(ctx, fetchTunnel) {
25153
+ const envToken = process.env.PREVIEW_TUNNEL_TOKEN;
25154
+ const envHostname = process.env.PREVIEW_TUNNEL_HOSTNAME;
25155
+ if (envToken && envHostname) return { token: envToken, hostname: envHostname };
25156
+ if (!ctx.pluginAuthToken) return null;
25157
+ try {
25158
+ const minted = await fetchTunnel(ctx);
25159
+ if (!minted?.token || !minted.hostname) return null;
25160
+ log.info("preview", `named tunnel minted on demand: ${minted.hostname}`);
25161
+ return { token: minted.token, hostname: minted.hostname };
25162
+ } catch (err) {
25163
+ log.trace(
25164
+ "preview",
25165
+ `named tunnel unavailable (${err instanceof Error ? err.message : String(err)}) \u2014 quick tunnel`
25166
+ );
25167
+ return null;
25168
+ }
25169
+ }
25170
+
25126
25171
  // src/services/preview/start-orchestrator.ts
25127
25172
  var INSTALL_TIMEOUT_MS2 = 5 * 6e4;
25128
25173
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -25495,8 +25540,16 @@ async function establishTunnel(ctx, dev) {
25495
25540
  let tunnel = null;
25496
25541
  let parsedUrl = null;
25497
25542
  let lastTunnelErr = "cloudflared did not emit a URL within 45s";
25498
- const namedToken = process.env.PREVIEW_TUNNEL_TOKEN;
25499
- const namedHostname = process.env.PREVIEW_TUNNEL_HOSTNAME;
25543
+ const named = await resolveNamedTunnel(
25544
+ {
25545
+ sessionId: ctx.sessionId,
25546
+ pluginId: ctx.projectEnvAuth?.pluginId ?? "",
25547
+ pluginAuthToken: ctx.projectEnvAuth?.pluginAuthToken ?? ""
25548
+ },
25549
+ (c2) => fetchNamedPreviewTunnel({ pluginId: c2.pluginId, pluginAuthToken: c2.pluginAuthToken })
25550
+ );
25551
+ const namedToken = named?.token;
25552
+ const namedHostname = named?.hostname;
25500
25553
  if (namedToken && namedHostname) {
25501
25554
  try {
25502
25555
  emitProgress("TUNNEL_STARTING", `named tunnel ${namedHostname}`);
@@ -45671,7 +45724,7 @@ function checkChokidar() {
45671
45724
  }
45672
45725
  async function doctor(args2 = []) {
45673
45726
  const json = args2.includes("--json");
45674
- const cliVersion = true ? "2.66.1" : "0.0.0-dev";
45727
+ const cliVersion = true ? "2.67.0" : "0.0.0-dev";
45675
45728
  const apiBase2 = resolveApiBaseUrl();
45676
45729
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
45677
45730
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -46062,7 +46115,7 @@ async function mcpRun(args2) {
46062
46115
  // src/commands/version.ts
46063
46116
  var import_picocolors15 = __toESM(require("picocolors"));
46064
46117
  function version2() {
46065
- const v = true ? "2.66.1" : "unknown";
46118
+ const v = true ? "2.67.0" : "unknown";
46066
46119
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
46067
46120
  }
46068
46121
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.66.1",
3
+ "version": "2.67.0",
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",