codeam-cli 2.39.36 → 2.39.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,12 @@ 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.39.36] — 2026-06-18
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Preview dev-server run command rewrites pnpm/bun → npm run
12
+
7
13
  ## [2.39.35] — 2026-06-18
8
14
 
9
15
  ### Fixed
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.39.36",
501
+ version: "2.39.37",
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",
@@ -5908,7 +5908,7 @@ function readAnonId() {
5908
5908
  }
5909
5909
  function superProperties() {
5910
5910
  return {
5911
- cliVersion: true ? "2.39.36" : "0.0.0-dev",
5911
+ cliVersion: true ? "2.39.37" : "0.0.0-dev",
5912
5912
  nodeVersion: process.version,
5913
5913
  platform: process.platform,
5914
5914
  arch: process.arch,
@@ -16538,34 +16538,6 @@ function downloadUrlForPlatform() {
16538
16538
  var import_child_process11 = require("child_process");
16539
16539
  var import_util3 = require("util");
16540
16540
  var execFileP4 = (0, import_util3.promisify)(import_child_process11.execFile);
16541
- function isCodespaceSession(env = process.env) {
16542
- return Boolean(env.CODESPACE_NAME);
16543
- }
16544
- function buildCodespaceUrl(codespaceName, port) {
16545
- return `https://${codespaceName}-${port}.app.github.dev`;
16546
- }
16547
- async function setPortPublic(codespaceName, port) {
16548
- await execFileP4("gh", [
16549
- "codespace",
16550
- "ports",
16551
- "visibility",
16552
- `${port}:public`,
16553
- "-c",
16554
- codespaceName
16555
- ]);
16556
- }
16557
- async function waitForCodespacePortReady(url, timeoutMs = 15e3) {
16558
- const start2 = Date.now();
16559
- while (Date.now() - start2 < timeoutMs) {
16560
- try {
16561
- const res = await fetch(url, { method: "HEAD" });
16562
- if (res.status < 500) return;
16563
- } catch {
16564
- }
16565
- await new Promise((r) => setTimeout(r, 500));
16566
- }
16567
- throw new Error(`Codespace forwarded URL ${url} not reachable after ${timeoutMs}ms.`);
16568
- }
16569
16541
 
16570
16542
  // src/services/preview/config-file.ts
16571
16543
  var import_promises4 = __toESM(require("fs/promises"));
@@ -19115,7 +19087,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
19115
19087
  emitProgress("READY_DETECTED", `port ${detection.port}`);
19116
19088
  emitProgress(
19117
19089
  "TUNNEL_STARTING",
19118
- detection.framework === "Expo" ? "Expo (self-tunnelled)" : isCodespaceSession() ? "GitHub Codespaces public port" : "cloudflared quick tunnel"
19090
+ detection.framework === "Expo" ? "Expo (self-tunnelled)" : "cloudflared quick tunnel"
19119
19091
  );
19120
19092
  let tunnel = null;
19121
19093
  let url;
@@ -19141,41 +19113,6 @@ var previewStartH = (ctx, _cmd, parsed) => {
19141
19113
  return;
19142
19114
  }
19143
19115
  url = expoUrl;
19144
- } else if (isCodespaceSession()) {
19145
- const codespaceName = process.env.CODESPACE_NAME;
19146
- try {
19147
- await setPortPublic(codespaceName, detection.port);
19148
- } catch (e) {
19149
- try {
19150
- devServer.kill("SIGTERM");
19151
- } catch {
19152
- }
19153
- void postPreviewEvent({
19154
- sessionId: ctx.sessionId,
19155
- pluginId: ctx.pluginId,
19156
- pluginAuthToken,
19157
- type: "preview_error",
19158
- payload: { stage: "tunnel", message: `Failed to flip port public: ${e.message}` }
19159
- });
19160
- return;
19161
- }
19162
- url = buildCodespaceUrl(codespaceName, detection.port);
19163
- try {
19164
- await waitForCodespacePortReady(url, 15e3);
19165
- } catch (e) {
19166
- try {
19167
- devServer.kill("SIGTERM");
19168
- } catch {
19169
- }
19170
- void postPreviewEvent({
19171
- sessionId: ctx.sessionId,
19172
- pluginId: ctx.pluginId,
19173
- pluginAuthToken,
19174
- type: "preview_error",
19175
- payload: { stage: "tunnel", message: e.message }
19176
- });
19177
- return;
19178
- }
19179
19116
  } else {
19180
19117
  let bin;
19181
19118
  try {
@@ -19194,48 +19131,56 @@ var previewStartH = (ctx, _cmd, parsed) => {
19194
19131
  });
19195
19132
  return;
19196
19133
  }
19197
- tunnel = (0, import_child_process18.spawn)(bin, ["tunnel", "--url", `http://localhost:${detection.port}`], {
19198
- stdio: ["ignore", "pipe", "pipe"]
19199
- });
19134
+ const MAX_TUNNEL_ATTEMPTS = 3;
19200
19135
  let parsedUrl = null;
19201
- const onTunnelChunk = (chunk) => {
19202
- const s = chunk.toString();
19203
- if (!parsedUrl) parsedUrl = parseCloudflaredUrl(s);
19204
- const trimmed = s.replace(/\n+$/g, "");
19205
- if (trimmed.length > 0) log.info("preview", `cloudflared: ${trimmed}`);
19206
- };
19207
- tunnel.stderr.on("data", onTunnelChunk);
19208
- tunnel.stdout.on("data", onTunnelChunk);
19209
- const tunnelDeadline = Date.now() + 45e3;
19210
- while (!parsedUrl && Date.now() < tunnelDeadline) {
19211
- await new Promise((r) => setTimeout(r, 250));
19212
- }
19213
- if (!parsedUrl) {
19214
- try {
19215
- tunnel.kill("SIGTERM");
19216
- } catch {
19136
+ let lastTunnelErr = "cloudflared did not emit a URL within 45s";
19137
+ for (let attempt = 1; attempt <= MAX_TUNNEL_ATTEMPTS && !parsedUrl; attempt += 1) {
19138
+ if (attempt > 1) {
19139
+ emitProgress(
19140
+ "TUNNEL_STARTING",
19141
+ `cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
19142
+ );
19217
19143
  }
19218
- try {
19219
- devServer.kill("SIGTERM");
19220
- } catch {
19144
+ const candidate = (0, import_child_process18.spawn)(
19145
+ bin,
19146
+ ["tunnel", "--url", `http://localhost:${detection.port}`],
19147
+ { stdio: ["ignore", "pipe", "pipe"] }
19148
+ );
19149
+ let candidateUrl = null;
19150
+ const onTunnelChunk = (chunk) => {
19151
+ const s = chunk.toString();
19152
+ if (!candidateUrl) candidateUrl = parseCloudflaredUrl(s);
19153
+ const trimmed = s.replace(/\n+$/g, "");
19154
+ if (trimmed.length > 0) log.info("preview", `cloudflared: ${trimmed}`);
19155
+ };
19156
+ candidate.stderr.on("data", onTunnelChunk);
19157
+ candidate.stdout.on("data", onTunnelChunk);
19158
+ const urlDeadline = Date.now() + 45e3;
19159
+ while (!candidateUrl && Date.now() < urlDeadline) {
19160
+ await new Promise((r) => setTimeout(r, 250));
19161
+ }
19162
+ if (!candidateUrl) {
19163
+ lastTunnelErr = "cloudflared did not emit a URL within 45s";
19164
+ try {
19165
+ candidate.kill("SIGTERM");
19166
+ } catch {
19167
+ }
19168
+ continue;
19221
19169
  }
19222
- void postPreviewEvent({
19223
- sessionId: ctx.sessionId,
19224
- pluginId: ctx.pluginId,
19225
- pluginAuthToken,
19226
- type: "preview_error",
19227
- payload: { stage: "tunnel", message: "cloudflared did not emit a URL within 45s." }
19228
- });
19229
- return;
19230
- }
19231
- try {
19232
- await waitForCloudflaredReady(parsedUrl, 6e4);
19233
- log.info("preview", `cloudflared probe: ${parsedUrl} reachable from CLI host`);
19234
- } catch (e) {
19235
19170
  try {
19236
- tunnel.kill("SIGTERM");
19237
- } catch {
19171
+ await waitForCloudflaredReady(candidateUrl, 4e4);
19172
+ log.info("preview", `cloudflared probe: ${candidateUrl} reachable from CLI host`);
19173
+ tunnel = candidate;
19174
+ parsedUrl = candidateUrl;
19175
+ } catch (e) {
19176
+ lastTunnelErr = e.message;
19177
+ try {
19178
+ candidate.kill("SIGTERM");
19179
+ } catch {
19180
+ }
19238
19181
  }
19182
+ }
19183
+ if (!parsedUrl) {
19239
19184
  try {
19240
19185
  devServer.kill("SIGTERM");
19241
19186
  } catch {
@@ -19247,7 +19192,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
19247
19192
  type: "preview_error",
19248
19193
  payload: {
19249
19194
  stage: "tunnel",
19250
- message: `Tunnel ${parsedUrl} did not become reachable within 60s (${e.message}). Cloudflare Quick Tunnels occasionally fail to register \u2014 retry usually succeeds.`
19195
+ message: `Tunnel did not become reachable after ${MAX_TUNNEL_ATTEMPTS} attempts (${lastTunnelErr}). Cloudflare Quick Tunnels occasionally fail to register \u2014 please retry.`
19251
19196
  }
19252
19197
  });
19253
19198
  return;
@@ -27187,7 +27132,7 @@ function checkChokidar() {
27187
27132
  }
27188
27133
  async function doctor(args2 = []) {
27189
27134
  const json = args2.includes("--json");
27190
- const cliVersion = true ? "2.39.36" : "0.0.0-dev";
27135
+ const cliVersion = true ? "2.39.37" : "0.0.0-dev";
27191
27136
  const apiBase2 = resolveApiBaseUrl();
27192
27137
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
27193
27138
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -27386,7 +27331,7 @@ async function completion(args2) {
27386
27331
  // src/commands/version.ts
27387
27332
  var import_picocolors13 = __toESM(require("picocolors"));
27388
27333
  function version2() {
27389
- const v = true ? "2.39.36" : "unknown";
27334
+ const v = true ? "2.39.37" : "unknown";
27390
27335
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
27391
27336
  }
27392
27337
 
@@ -27672,7 +27617,7 @@ function checkForUpdates() {
27672
27617
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
27673
27618
  if (process.env.CI) return;
27674
27619
  if (!process.stdout.isTTY) return;
27675
- const current = true ? "2.39.36" : null;
27620
+ const current = true ? "2.39.37" : null;
27676
27621
  if (!current) return;
27677
27622
  const cache = readCache();
27678
27623
  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.39.36",
3
+ "version": "2.39.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",