codeam-cli 2.76.36 → 2.76.37

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,17 @@ 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.76.36] — 2026-10-25
8
+
9
+ ### Added
10
+
11
+ - **shared:** One Point-at-it picker for Remix and the Preview
12
+ - **cli:** The Preview picker is Remix's Point at it
13
+
14
+ ### Fixed
15
+
16
+ - **shared:** Point picker swallows the post-pick click, valid selectors, reload-safe mark ids
17
+
7
18
  ## [2.76.35] — 2026-10-22
8
19
 
9
20
  ### Fixed
package/dist/index.js CHANGED
@@ -11354,7 +11354,7 @@ function readAnonId() {
11354
11354
  }
11355
11355
  function superProperties() {
11356
11356
  return {
11357
- cliVersion: true ? "2.76.36" : "0.0.0-dev",
11357
+ cliVersion: true ? "2.76.37" : "0.0.0-dev",
11358
11358
  nodeVersion: process.version,
11359
11359
  platform: process.platform,
11360
11360
  arch: process.arch,
@@ -11603,7 +11603,7 @@ var http = __toESM(require("http"));
11603
11603
  // package.json
11604
11604
  var package_default = {
11605
11605
  name: "codeam-cli",
11606
- version: "2.76.36",
11606
+ version: "2.76.37",
11607
11607
  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.",
11608
11608
  type: "commonjs",
11609
11609
  main: "dist/index.js",
@@ -12979,7 +12979,7 @@ var CommandRelayService = class _CommandRelayService {
12979
12979
  // fresh + clear the "CLI update available" banner after a self-update
12980
12980
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
12981
12981
  // pair/reconnect). Older backends ignore the extra field.
12982
- ..."2.76.36" ? { ideVersion: "2.76.36" } : {}
12982
+ ..."2.76.37" ? { ideVersion: "2.76.37" } : {}
12983
12983
  };
12984
12984
  try {
12985
12985
  const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body, this.pollSecretHeader());
@@ -24113,27 +24113,153 @@ var import_os10 = __toESM(require("os"));
24113
24113
  var import_path5 = __toESM(require("path"));
24114
24114
  var import_promises3 = require("stream/promises");
24115
24115
  var import_which = __toESM(require("which"));
24116
- var CACHED_BINARY = import_path5.default.join(import_os10.default.homedir(), ".codeam", "bin", "cloudflared");
24116
+ var CACHE_DIR = import_path5.default.join(import_os10.default.homedir(), ".codeam", "bin");
24117
+ var LEGACY_CACHED_BINARY = import_path5.default.join(CACHE_DIR, "cloudflared");
24118
+ function cachedCloudflaredPath(platform3 = process.platform) {
24119
+ return platform3 === "win32" ? import_path5.default.join(CACHE_DIR, "cloudflared.exe") : LEGACY_CACHED_BINARY;
24120
+ }
24121
+ var MIN_CLOUDFLARED_VERSION = [2026, 10, 2];
24122
+ var MIN_CLOUDFLARED_VERSION_DARWIN_NON_BREW = [2026, 10, 3];
24123
+ var DEFAULT_HOMEBREW_PREFIXES = [
24124
+ "/opt/homebrew/",
24125
+ "/usr/local/Cellar/",
24126
+ "/usr/local/Homebrew/",
24127
+ "/home/linuxbrew/"
24128
+ ];
24129
+ function homebrewPrefixes(env = process.env) {
24130
+ const custom = env.HOMEBREW_PREFIX?.replace(/\/+$/, "");
24131
+ return custom ? [...DEFAULT_HOMEBREW_PREFIXES, `${custom}/`, `${custom}/Cellar/`] : [...DEFAULT_HOMEBREW_PREFIXES];
24132
+ }
24133
+ function parseCloudflaredVersion(output) {
24134
+ const m = /cloudflared version (\d+)\.(\d+)\.(\d+)/.exec(output);
24135
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
24136
+ }
24137
+ function isHomebrewPath(bin, prefixes = homebrewPrefixes()) {
24138
+ return prefixes.some((prefix) => bin.startsWith(prefix));
24139
+ }
24140
+ function formatCloudflaredVersion(v) {
24141
+ return v.join(".");
24142
+ }
24143
+ function minimumCloudflaredVersion(bin, platform3 = process.platform, prefixes = homebrewPrefixes()) {
24144
+ return platform3 === "darwin" && !isHomebrewPath(bin, prefixes) ? MIN_CLOUDFLARED_VERSION_DARWIN_NON_BREW : MIN_CLOUDFLARED_VERSION;
24145
+ }
24146
+ function compareVersions(a, b) {
24147
+ for (let i = 0; i < 3; i++) {
24148
+ if (a[i] !== b[i]) return a[i] - b[i];
24149
+ }
24150
+ return 0;
24151
+ }
24152
+ function meetsMinimumCloudflaredVersion(version3, bin, platform3 = process.platform, prefixes = homebrewPrefixes()) {
24153
+ if (!version3) return false;
24154
+ return compareVersions(version3, minimumCloudflaredVersion(bin, platform3, prefixes)) >= 0;
24155
+ }
24156
+ var versionCache = /* @__PURE__ */ new Map();
24157
+ var warnedOutdated = /* @__PURE__ */ new Set();
24158
+ function readCloudflaredVersion(bin) {
24159
+ let cached2 = versionCache.get(bin);
24160
+ if (!cached2) {
24161
+ const pending2 = new Promise((resolve13) => {
24162
+ (0, import_child_process14.execFile)(bin, ["--version"], { timeout: 1e4 }, (err, stdout, stderr) => {
24163
+ resolve13(err ? null : parseCloudflaredVersion(`${stdout}
24164
+ ${stderr}`));
24165
+ });
24166
+ }).then((version3) => {
24167
+ if (!version3 && versionCache.get(bin) === pending2) versionCache.delete(bin);
24168
+ return version3;
24169
+ });
24170
+ cached2 = pending2;
24171
+ versionCache.set(bin, pending2);
24172
+ }
24173
+ return cached2;
24174
+ }
24175
+ async function realpathOrSelf(p2) {
24176
+ try {
24177
+ return await import_promises2.default.realpath(p2);
24178
+ } catch {
24179
+ return p2;
24180
+ }
24181
+ }
24182
+ async function checkCloudflaredVersion(bin) {
24183
+ const version3 = await readCloudflaredVersion(bin);
24184
+ const real = await realpathOrSelf(bin);
24185
+ const prefixes = homebrewPrefixes();
24186
+ const customPrefix = process.env.HOMEBREW_PREFIX?.replace(/\/+$/, "");
24187
+ if (customPrefix) {
24188
+ const realPrefix = await realpathOrSelf(customPrefix);
24189
+ if (realPrefix !== customPrefix) prefixes.push(`${realPrefix}/`, `${realPrefix}/Cellar/`);
24190
+ }
24191
+ const brewBin = isHomebrewPath(bin, prefixes) ? bin : real;
24192
+ return {
24193
+ ok: meetsMinimumCloudflaredVersion(version3, brewBin, process.platform, prefixes),
24194
+ version: version3,
24195
+ min: minimumCloudflaredVersion(brewBin, process.platform, prefixes)
24196
+ };
24197
+ }
24198
+ async function migrateLegacyWindowsCache(target) {
24199
+ if (target === LEGACY_CACHED_BINARY) return;
24200
+ try {
24201
+ await import_promises2.default.access(target);
24202
+ return;
24203
+ } catch {
24204
+ }
24205
+ try {
24206
+ await import_promises2.default.access(LEGACY_CACHED_BINARY);
24207
+ await import_promises2.default.rename(LEGACY_CACHED_BINARY, target);
24208
+ } catch {
24209
+ }
24210
+ }
24211
+ function describeVersion(v) {
24212
+ return v ? formatCloudflaredVersion(v) : "an unknown version";
24213
+ }
24117
24214
  async function resolveCloudflared(opts = {}) {
24215
+ let pathBin;
24118
24216
  try {
24119
- return await (0, import_which.default)("cloudflared");
24217
+ pathBin = await (0, import_which.default)("cloudflared");
24120
24218
  } catch {
24121
24219
  }
24220
+ if (pathBin) {
24221
+ const check2 = await checkCloudflaredVersion(pathBin);
24222
+ if (check2.ok) return pathBin;
24223
+ if (!warnedOutdated.has(pathBin)) {
24224
+ warnedOutdated.add(pathBin);
24225
+ log.warn(
24226
+ "preview",
24227
+ `ignoring ${pathBin} (${describeVersion(check2.version)}): previews need cloudflared >= ${formatCloudflaredVersion(check2.min)}; upgrade cloudflared with your package manager (e.g. \`brew upgrade cloudflared\`). Using a CodeAgent-managed copy instead.`
24228
+ );
24229
+ }
24230
+ }
24231
+ const cached2 = cachedCloudflaredPath();
24232
+ await migrateLegacyWindowsCache(cached2);
24233
+ let staleCache = false;
24122
24234
  try {
24123
- await import_promises2.default.access(CACHED_BINARY);
24124
- if (await isExecutableBinary(CACHED_BINARY)) {
24125
- return CACHED_BINARY;
24235
+ await import_promises2.default.access(cached2);
24236
+ if (!await isExecutableBinary(cached2)) {
24237
+ await import_promises2.default.rm(cached2, { force: true });
24238
+ } else if ((await checkCloudflaredVersion(cached2)).ok) {
24239
+ return cached2;
24240
+ } else {
24241
+ staleCache = true;
24126
24242
  }
24127
- await import_promises2.default.rm(CACHED_BINARY, { force: true });
24128
24243
  } catch {
24129
24244
  }
24130
24245
  if (opts.skipDownload) {
24131
24246
  throw new Error(
24132
- "cloudflared not installed. Install via `brew install cloudflared` (macOS) or download from https://github.com/cloudflare/cloudflared/releases."
24247
+ `cloudflared not installed (or older than ${formatCloudflaredVersion(minimumCloudflaredVersion(cached2))}). Install or upgrade via \`brew install cloudflared\` (macOS) or download from https://github.com/cloudflare/cloudflared/releases.`
24248
+ );
24249
+ }
24250
+ if (staleCache) await import_promises2.default.rm(cached2, { force: true });
24251
+ versionCache.delete(cached2);
24252
+ await downloadCloudflared(cached2);
24253
+ versionCache.delete(cached2);
24254
+ const check = await checkCloudflaredVersion(cached2);
24255
+ if (!check.ok) {
24256
+ await import_promises2.default.rm(cached2, { force: true });
24257
+ versionCache.delete(cached2);
24258
+ throw new Error(
24259
+ `Downloaded cloudflared reports ${describeVersion(check.version)}, but previews need cloudflared >= ${formatCloudflaredVersion(check.min)}. Install the latest version manually via \`brew install cloudflared\` (macOS) or from https://github.com/cloudflare/cloudflared/releases.`
24133
24260
  );
24134
24261
  }
24135
- await downloadCloudflared(CACHED_BINARY);
24136
- return CACHED_BINARY;
24262
+ return cached2;
24137
24263
  }
24138
24264
  async function downloadCloudflared(target) {
24139
24265
  const url2 = downloadUrlForPlatform();
@@ -51037,9 +51163,9 @@ async function probeCodeamPair(provider, workspace) {
51037
51163
  }
51038
51164
  async function stopWorkspaceFromLocal(target) {
51039
51165
  if (target.provider.id === "github-codespaces") {
51040
- const { execFile: execFile21 } = await import("child_process");
51166
+ const { execFile: execFile22 } = await import("child_process");
51041
51167
  const { promisify: promisify17 } = await import("util");
51042
- const execFileP10 = promisify17(execFile21);
51168
+ const execFileP10 = promisify17(execFile22);
51043
51169
  await execFileP10("gh", ["codespace", "stop", "-c", target.id], { maxBuffer: 8 * 1024 * 1024 });
51044
51170
  return;
51045
51171
  }
@@ -51937,7 +52063,7 @@ async function autoUpgradeBeforeCriticalCommand() {
51937
52063
  if (process.env.NODE_ENV === "test") return;
51938
52064
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
51939
52065
  if (process.env.CI) return;
51940
- const current2 = true ? "2.76.36" : null;
52066
+ const current2 = true ? "2.76.37" : null;
51941
52067
  if (!current2) return;
51942
52068
  const cache = readCache();
51943
52069
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -51954,7 +52080,7 @@ function checkForUpdates() {
51954
52080
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
51955
52081
  if (process.env.CI) return;
51956
52082
  if (!process.stdout.isTTY) return;
51957
- const current2 = true ? "2.76.36" : null;
52083
+ const current2 = true ? "2.76.37" : null;
51958
52084
  if (!current2) return;
51959
52085
  const cache = readCache();
51960
52086
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -52260,7 +52386,7 @@ var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
52260
52386
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
52261
52387
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
52262
52388
  function currentCliVersion() {
52263
- return true ? "2.76.36" : null;
52389
+ return true ? "2.76.37" : null;
52264
52390
  }
52265
52391
  async function installedVersion(deps) {
52266
52392
  const ls = await deps.run(
@@ -52483,7 +52609,7 @@ function signalHostReady(send = process.send?.bind(process)) {
52483
52609
  }
52484
52610
  function defaultDeps() {
52485
52611
  return {
52486
- ownVersion: true ? "2.76.36" : null,
52612
+ ownVersion: true ? "2.76.37" : null,
52487
52613
  root: cliVersionsRoot(),
52488
52614
  args: process.argv.slice(3),
52489
52615
  execPath: process.execPath,
@@ -55021,7 +55147,7 @@ function checkChokidar() {
55021
55147
  }
55022
55148
  async function doctor(args2 = []) {
55023
55149
  const json = args2.includes("--json");
55024
- const cliVersion = true ? "2.76.36" : "0.0.0-dev";
55150
+ const cliVersion = true ? "2.76.37" : "0.0.0-dev";
55025
55151
  const apiBase2 = resolveApiBaseUrl();
55026
55152
  const diagnosticId = (0, import_node_crypto17.randomUUID)();
55027
55153
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -55557,7 +55683,7 @@ async function mcpWarm(argv = [], opts = {}) {
55557
55683
  // src/commands/version.ts
55558
55684
  var import_picocolors15 = __toESM(require("picocolors"));
55559
55685
  function version2() {
55560
- const v = true ? "2.76.36" : "unknown";
55686
+ const v = true ? "2.76.37" : "unknown";
55561
55687
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
55562
55688
  }
55563
55689
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.76.36",
3
+ "version": "2.76.37",
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",
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- // src/postinstall.ts
5
- var c = {
6
- reset: "\x1B[0m",
7
- bold: "\x1B[1m",
8
- dim: "\x1B[2m",
9
- green: "\x1B[32m",
10
- cyan: "\x1B[36m",
11
- violet: "\x1B[35m",
12
- white: "\x1B[97m"
13
- };
14
- var lines = [
15
- "",
16
- ` ${c.violet}${c.bold}codeam-cli${c.reset} ${c.dim}\u2014 Claude Code remote control${c.reset}`,
17
- "",
18
- ` ${c.dim}1.${c.reset} Pair your phone:`,
19
- ` ${c.cyan}codeam pair${c.reset}`,
20
- "",
21
- ` ${c.dim}2.${c.reset} Launch Claude Code with mobile control:`,
22
- ` ${c.cyan}codeam${c.reset}`,
23
- "",
24
- ` ${c.dim}Other commands:${c.reset}`,
25
- ` ${c.white}codeam sessions${c.reset} ${c.dim}list paired devices${c.reset}`,
26
- ` ${c.white}codeam status${c.reset} ${c.dim}show connection info${c.reset}`,
27
- ` ${c.white}codeam logout${c.reset} ${c.dim}remove all sessions${c.reset}`,
28
- "",
29
- ` ${c.dim}Requires Claude Code:${c.reset} ${c.green}npm install -g @anthropic-ai/claude-code${c.reset}`,
30
- ` ${c.dim}Mobile app:${c.reset} ${c.green}https://www.codeagent-mobile.com${c.reset}`,
31
- ""
32
- ];
33
- process.stdout.write(lines.join("\n") + "\n");