codeam-cli 2.37.3 → 2.39.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/index.js +410 -156
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ 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.38.0] — 2026-06-12
8
+
9
+ ### Added
10
+
11
+ - **cli:** Inherit team memories into the active repo's Beads DB (P3b)
12
+
13
+ ### Chore
14
+
15
+ - **deps:** Bump com.squareup.okhttp3:okhttp in /apps/jetbrains-plugin (#326)
16
+ - **deps-dev:** Bump @vscode/test-electron from 2.5.2 to 3.0.0 in /apps/vsc-plugin (#322)
17
+
18
+ ## [2.37.3] — 2026-06-11
19
+
20
+ ### Fixed
21
+
22
+ - **cli:** Force full https:// URLs in onboarding welcome so both render as links
23
+
7
24
  ## [2.37.2] — 2026-06-11
8
25
 
9
26
  ### 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.37.3",
501
+ version: "2.39.0",
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",
@@ -1186,8 +1186,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
1186
1186
  return decodedFile;
1187
1187
  };
1188
1188
  }
1189
- function normalizeWindowsPath(path52) {
1190
- return path52.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1189
+ function normalizeWindowsPath(path53) {
1190
+ return path53.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1191
1191
  }
1192
1192
 
1193
1193
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3667,9 +3667,9 @@ async function addSourceContext(frames) {
3667
3667
  LRU_FILE_CONTENTS_CACHE.reduce();
3668
3668
  return frames;
3669
3669
  }
3670
- function getContextLinesFromFile(path52, ranges, output) {
3670
+ function getContextLinesFromFile(path53, ranges, output) {
3671
3671
  return new Promise((resolve7) => {
3672
- const stream = (0, import_node_fs.createReadStream)(path52);
3672
+ const stream = (0, import_node_fs.createReadStream)(path53);
3673
3673
  const lineReaded = (0, import_node_readline.createInterface)({
3674
3674
  input: stream
3675
3675
  });
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path52, ranges, output) {
3684
3684
  let rangeStart = range[0];
3685
3685
  let rangeEnd = range[1];
3686
3686
  function onStreamError() {
3687
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path52, 1);
3687
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path53, 1);
3688
3688
  lineReaded.close();
3689
3689
  lineReaded.removeAllListeners();
3690
3690
  destroyStreamAndResolve();
@@ -3745,8 +3745,8 @@ function clearLineContext(frame) {
3745
3745
  delete frame.context_line;
3746
3746
  delete frame.post_context;
3747
3747
  }
3748
- function shouldSkipContextLinesForFile(path52) {
3749
- return path52.startsWith("node:") || path52.endsWith(".min.js") || path52.endsWith(".min.cjs") || path52.endsWith(".min.mjs") || path52.startsWith("data:");
3748
+ function shouldSkipContextLinesForFile(path53) {
3749
+ return path53.startsWith("node:") || path53.endsWith(".min.js") || path53.endsWith(".min.cjs") || path53.endsWith(".min.mjs") || path53.startsWith("data:");
3750
3750
  }
3751
3751
  function shouldSkipContextLinesForFrame(frame) {
3752
3752
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5900,7 +5900,7 @@ function readAnonId() {
5900
5900
  }
5901
5901
  function superProperties() {
5902
5902
  return {
5903
- cliVersion: true ? "2.37.3" : "0.0.0-dev",
5903
+ cliVersion: true ? "2.39.0" : "0.0.0-dev",
5904
5904
  nodeVersion: process.version,
5905
5905
  platform: process.platform,
5906
5906
  arch: process.arch,
@@ -9978,13 +9978,13 @@ function detectStartupBanner(lines) {
9978
9978
  while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
9979
9979
  if (metaIdx - artStart < 2) return null;
9980
9980
  const pathLine = (lines[metaIdx + 1] ?? "").trim();
9981
- const path52 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
9981
+ const path53 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
9982
9982
  return {
9983
9983
  title: "",
9984
9984
  subtitle: lines[metaIdx].trim(),
9985
- path: path52,
9985
+ path: path53,
9986
9986
  startIdx: artStart,
9987
- endIdx: metaIdx + (path52 ? 1 : 0)
9987
+ endIdx: metaIdx + (path53 ? 1 : 0)
9988
9988
  };
9989
9989
  }
9990
9990
 
@@ -11342,11 +11342,11 @@ function parseReview(stdout) {
11342
11342
  for (const line of lines) {
11343
11343
  const m = line.match(HUNK_LINE_RE);
11344
11344
  if (!m) continue;
11345
- const [, path52, lineNo, sevToken, message] = m;
11346
- if (!path52 || !lineNo || !message) continue;
11345
+ const [, path53, lineNo, sevToken, message] = m;
11346
+ if (!path53 || !lineNo || !message) continue;
11347
11347
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
11348
11348
  hunks.push({
11349
- path: path52.trim(),
11349
+ path: path53.trim(),
11350
11350
  line: Number(lineNo),
11351
11351
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
11352
11352
  message: cleanedMessage
@@ -15911,9 +15911,9 @@ function extractSelectPrompt(text) {
15911
15911
  }
15912
15912
 
15913
15913
  // src/commands/start/handlers.ts
15914
- var fs34 = __toESM(require("fs"));
15914
+ var fs35 = __toESM(require("fs"));
15915
15915
  var os27 = __toESM(require("os"));
15916
- var path41 = __toESM(require("path"));
15916
+ var path42 = __toESM(require("path"));
15917
15917
  var import_crypto3 = require("crypto");
15918
15918
  var import_child_process18 = require("child_process");
15919
15919
 
@@ -17364,6 +17364,10 @@ async function waitForPortListening(port, opts) {
17364
17364
  }
17365
17365
  }
17366
17366
 
17367
+ // src/services/preview/provision-deps.ts
17368
+ var import_fs2 = require("fs");
17369
+ var import_path6 = __toESM(require("path"));
17370
+
17367
17371
  // src/services/preview/run-setup.ts
17368
17372
  var import_child_process12 = require("child_process");
17369
17373
  function runSetupCommand(cmd, args2, cwd, env, opts) {
@@ -17408,19 +17412,215 @@ function runSetupCommand(cmd, args2, cwd, env, opts) {
17408
17412
  });
17409
17413
  }
17410
17414
 
17415
+ // src/services/preview/provision-deps.ts
17416
+ var COMPOSE_FILES = [
17417
+ "docker-compose.yml",
17418
+ "docker-compose.yaml",
17419
+ "compose.yaml",
17420
+ "compose.yml"
17421
+ ];
17422
+ var ENV_SAMPLES = [".env.example", ".env.sample", ".env.local.example", ".env.template"];
17423
+ var POSTGRES = {
17424
+ name: "postgres",
17425
+ image: "postgres:16",
17426
+ port: 5432,
17427
+ environment: { POSTGRES_USER: "postgres", POSTGRES_PASSWORD: "postgres", POSTGRES_DB: "app" },
17428
+ healthTest: ["CMD-SHELL", "pg_isready -U postgres"],
17429
+ envLines: [
17430
+ "DATABASE_URL=postgresql://postgres:postgres@localhost:5432/app",
17431
+ "DB_HOST=localhost",
17432
+ "DB_PORT=5432",
17433
+ "DB_USERNAME=postgres",
17434
+ "DB_PASSWORD=postgres",
17435
+ "DB_NAME=app"
17436
+ ]
17437
+ };
17438
+ var MYSQL = {
17439
+ name: "mysql",
17440
+ image: "mysql:8",
17441
+ port: 3306,
17442
+ environment: { MYSQL_ROOT_PASSWORD: "mysql", MYSQL_DATABASE: "app" },
17443
+ healthTest: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pmysql"],
17444
+ envLines: ["DATABASE_URL=mysql://root:mysql@localhost:3306/app"]
17445
+ };
17446
+ var MONGO = {
17447
+ name: "mongo",
17448
+ image: "mongo:7",
17449
+ port: 27017,
17450
+ environment: {},
17451
+ healthTest: ["CMD", "mongosh", "--eval", 'db.adminCommand("ping")'],
17452
+ envLines: ["MONGODB_URI=mongodb://localhost:27017/app", "MONGO_URL=mongodb://localhost:27017/app"]
17453
+ };
17454
+ var REDIS = {
17455
+ name: "redis",
17456
+ image: "redis:7",
17457
+ port: 6379,
17458
+ environment: {},
17459
+ healthTest: ["CMD", "redis-cli", "ping"],
17460
+ envLines: ["REDIS_URL=redis://localhost:6379", "REDIS_HOST=localhost", "REDIS_PORT=6379"]
17461
+ };
17462
+ function detectServicesFromDeps(pkg) {
17463
+ const deps = /* @__PURE__ */ new Set([
17464
+ ...Object.keys(pkg.dependencies ?? {}),
17465
+ ...Object.keys(pkg.devDependencies ?? {})
17466
+ ]);
17467
+ const has = (...names) => names.some((n) => deps.has(n));
17468
+ const out2 = [];
17469
+ if (has("pg", "typeorm", "@nestjs/typeorm", "sequelize", "postgres", "postgres.js", "pg-promise"))
17470
+ out2.push(POSTGRES);
17471
+ if (has("mysql", "mysql2")) out2.push(MYSQL);
17472
+ if (has("mongoose", "mongodb")) out2.push(MONGO);
17473
+ if (has("ioredis", "redis", "cache-manager-ioredis-yet", "cache-manager-redis-store"))
17474
+ out2.push(REDIS);
17475
+ return out2;
17476
+ }
17477
+ function renderComposeYaml(services) {
17478
+ const blocks = services.map((s) => {
17479
+ const env = Object.entries(s.environment);
17480
+ const envYaml = env.length ? " environment:\n" + env.map(([k2, v]) => ` ${k2}: "${v}"`).join("\n") + "\n" : "";
17481
+ const health = JSON.stringify(s.healthTest);
17482
+ return ` ${s.name}:
17483
+ image: ${s.image}
17484
+ restart: unless-stopped
17485
+ ports:
17486
+ - "${s.port}:${s.port}"
17487
+ ` + envYaml + ` healthcheck:
17488
+ test: ${health}
17489
+ interval: 5s
17490
+ timeout: 3s
17491
+ retries: 12
17492
+ `;
17493
+ });
17494
+ return `# Generated by codeam \u2014 auto-provisioned project dependencies.
17495
+ # Do not edit; regenerated on each provision. See .codeam/provision/.
17496
+ services:
17497
+ ${blocks.join("")}`;
17498
+ }
17499
+ function pickMigrationScript(scripts) {
17500
+ const preferred = [
17501
+ "migration:run",
17502
+ "db:migrate",
17503
+ "migrate:deploy",
17504
+ "migrate:latest",
17505
+ "migrate:up",
17506
+ "prisma:migrate",
17507
+ "migrate"
17508
+ ];
17509
+ for (const k2 of preferred) if (scripts[k2]) return k2;
17510
+ for (const k2 of Object.keys(scripts)) {
17511
+ if (/migrat/i.test(k2) && /(run|deploy|latest|up)/i.test(k2) && !/(generate|create|revert|rollback|undo|down|reset|drop)/i.test(k2)) {
17512
+ return k2;
17513
+ }
17514
+ }
17515
+ return null;
17516
+ }
17517
+ async function exists(p2) {
17518
+ try {
17519
+ await import_fs2.promises.access(p2);
17520
+ return true;
17521
+ } catch {
17522
+ return false;
17523
+ }
17524
+ }
17525
+ async function firstExisting(cwd, names) {
17526
+ for (const n of names) if (await exists(import_path6.default.join(cwd, n))) return n;
17527
+ return null;
17528
+ }
17529
+ async function ensureEnvFile(cwd, generated) {
17530
+ if (await exists(import_path6.default.join(cwd, ".env"))) {
17531
+ log.info("provision", ".env already present \u2014 leaving it untouched");
17532
+ return;
17533
+ }
17534
+ const sample = await firstExisting(cwd, ENV_SAMPLES);
17535
+ if (sample) {
17536
+ const body = await import_fs2.promises.readFile(import_path6.default.join(cwd, sample), "utf8");
17537
+ await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
17538
+ log.info("provision", `wrote .env from ${sample}`);
17539
+ return;
17540
+ }
17541
+ if (generated.length > 0) {
17542
+ const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
17543
+ await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
17544
+ log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
17545
+ }
17546
+ }
17547
+ async function readPackageJson(cwd) {
17548
+ try {
17549
+ return JSON.parse(await import_fs2.promises.readFile(import_path6.default.join(cwd, "package.json"), "utf8"));
17550
+ } catch {
17551
+ return null;
17552
+ }
17553
+ }
17554
+ async function runMigrationsIfPresent(cwd, scripts) {
17555
+ const script = pickMigrationScript(scripts);
17556
+ if (!script) return;
17557
+ log.info("provision", `running migrations: npm run ${script}`);
17558
+ const res = await runSetupCommand("npm", ["run", script], cwd, void 0, { timeoutMs: 12e4 });
17559
+ if (res.status !== "ok") log.warn("provision", `migration script "${script}" \u2192 ${res.status} (non-fatal)`);
17560
+ }
17561
+ async function provisionProjectDependencies(cwd) {
17562
+ try {
17563
+ const docker = await runSetupCommand("docker", ["info"], cwd, void 0, { timeoutMs: 15e3 });
17564
+ if (docker.status !== "ok") {
17565
+ log.info("provision", "docker not usable \u2014 skipping dependency provisioning");
17566
+ return;
17567
+ }
17568
+ const pkg = await readPackageJson(cwd);
17569
+ let started = false;
17570
+ let generated = [];
17571
+ const composeFile = await firstExisting(cwd, COMPOSE_FILES);
17572
+ if (composeFile) {
17573
+ log.info("provision", `compose found (${composeFile}) \u2014 docker compose up -d --wait`);
17574
+ const up = await runSetupCommand("docker", ["compose", "up", "-d", "--wait"], cwd, void 0, {
17575
+ timeoutMs: 18e4
17576
+ });
17577
+ started = up.status === "ok";
17578
+ if (!started) log.warn("provision", `compose up \u2192 ${up.status} (non-fatal)`);
17579
+ } else if (pkg) {
17580
+ generated = detectServicesFromDeps(pkg);
17581
+ if (generated.length > 0) {
17582
+ const dir = import_path6.default.join(cwd, ".codeam", "provision");
17583
+ await import_fs2.promises.mkdir(dir, { recursive: true });
17584
+ const file = import_path6.default.join(dir, "compose.generated.yaml");
17585
+ await import_fs2.promises.writeFile(file, renderComposeYaml(generated));
17586
+ log.info(
17587
+ "provision",
17588
+ `no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
17589
+ );
17590
+ const up = await runSetupCommand(
17591
+ "docker",
17592
+ ["compose", "-f", file, "up", "-d", "--wait"],
17593
+ cwd,
17594
+ void 0,
17595
+ { timeoutMs: 18e4 }
17596
+ );
17597
+ started = up.status === "ok";
17598
+ if (!started) log.warn("provision", `generated compose up \u2192 ${up.status} (non-fatal)`);
17599
+ } else {
17600
+ log.info("provision", "no compose + no known service deps \u2014 nothing to provision");
17601
+ }
17602
+ }
17603
+ await ensureEnvFile(cwd, generated);
17604
+ if (started && pkg?.scripts) await runMigrationsIfPresent(cwd, pkg.scripts);
17605
+ log.info("provision", "project dependency provisioning complete");
17606
+ } catch (err) {
17607
+ log.warn("provision", "provisionProjectDependencies failed (non-fatal)", err);
17608
+ }
17609
+ }
17610
+
17411
17611
  // src/services/preview/setup-deps.ts
17412
- var import_fs2 = __toESM(require("fs"));
17413
- var import_path6 = __toESM(require("path"));
17612
+ var import_fs3 = __toESM(require("fs"));
17613
+ var import_path7 = __toESM(require("path"));
17414
17614
  function detectMissingNodeDeps(cwd) {
17415
- if (!import_fs2.default.existsSync(import_path6.default.join(cwd, "package.json"))) return null;
17416
- if (import_fs2.default.existsSync(import_path6.default.join(cwd, "node_modules"))) return null;
17417
- if (import_fs2.default.existsSync(import_path6.default.join(cwd, "pnpm-lock.yaml"))) {
17615
+ if (!import_fs3.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
17616
+ if (import_fs3.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
17617
+ if (import_fs3.default.existsSync(import_path7.default.join(cwd, "pnpm-lock.yaml"))) {
17418
17618
  return { cmd: "pnpm", args: ["install"] };
17419
17619
  }
17420
- if (import_fs2.default.existsSync(import_path6.default.join(cwd, "yarn.lock"))) {
17620
+ if (import_fs3.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
17421
17621
  return { cmd: "yarn", args: ["install"] };
17422
17622
  }
17423
- if (import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lockb")) || import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lock"))) {
17623
+ if (import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lockb")) || import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lock"))) {
17424
17624
  return { cmd: "bun", args: ["install"] };
17425
17625
  }
17426
17626
  return { cmd: "npm", args: ["install"] };
@@ -17475,8 +17675,8 @@ function activePreviewSessionIds() {
17475
17675
 
17476
17676
  // src/beads/bd-adapter.ts
17477
17677
  var import_child_process13 = require("child_process");
17478
- var fs30 = __toESM(require("fs"));
17479
- var path36 = __toESM(require("path"));
17678
+ var fs31 = __toESM(require("fs"));
17679
+ var path37 = __toESM(require("path"));
17480
17680
  var BD_PACKAGE = "@beads/bd";
17481
17681
  function resolveBundledBdBinary() {
17482
17682
  return _resolveSeam.resolveBundled();
@@ -17488,11 +17688,11 @@ function _defaultResolveBundled() {
17488
17688
  } catch {
17489
17689
  return null;
17490
17690
  }
17491
- const binDir = path36.join(path36.dirname(pkgJsonPath), "bin");
17691
+ const binDir = path37.join(path37.dirname(pkgJsonPath), "bin");
17492
17692
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
17493
- const binaryPath = path36.join(binDir, binaryName);
17693
+ const binaryPath = path37.join(binDir, binaryName);
17494
17694
  try {
17495
- fs30.accessSync(binaryPath, fs30.constants.F_OK);
17695
+ fs31.accessSync(binaryPath, fs31.constants.F_OK);
17496
17696
  return binaryPath;
17497
17697
  } catch {
17498
17698
  return null;
@@ -17502,13 +17702,13 @@ function resolveBdOnPath() {
17502
17702
  return _resolveSeam.resolveOnPath();
17503
17703
  }
17504
17704
  function _defaultResolveOnPath() {
17505
- const dirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
17705
+ const dirs = (process.env.PATH ?? "").split(path37.delimiter).filter(Boolean);
17506
17706
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
17507
17707
  for (const dir of dirs) {
17508
17708
  for (const candidate of candidates) {
17509
- const full = path36.join(dir, candidate);
17709
+ const full = path37.join(dir, candidate);
17510
17710
  try {
17511
- fs30.accessSync(full, fs30.constants.F_OK);
17711
+ fs31.accessSync(full, fs31.constants.F_OK);
17512
17712
  return full;
17513
17713
  } catch {
17514
17714
  }
@@ -17674,9 +17874,9 @@ function coerceIssue(row, projectKey) {
17674
17874
 
17675
17875
  // src/beads/provisioner.ts
17676
17876
  var import_child_process17 = require("child_process");
17677
- var fs33 = __toESM(require("fs"));
17877
+ var fs34 = __toESM(require("fs"));
17678
17878
  var os26 = __toESM(require("os"));
17679
- var path39 = __toESM(require("path"));
17879
+ var path40 = __toESM(require("path"));
17680
17880
 
17681
17881
  // src/beads/install-bd.ts
17682
17882
  var import_child_process14 = require("child_process");
@@ -17741,9 +17941,9 @@ async function installBd(platform2 = process.platform) {
17741
17941
 
17742
17942
  // src/beads/install-dolt.ts
17743
17943
  var import_child_process15 = require("child_process");
17744
- var fs31 = __toESM(require("fs"));
17944
+ var fs32 = __toESM(require("fs"));
17745
17945
  var os25 = __toESM(require("os"));
17746
- var path37 = __toESM(require("path"));
17946
+ var path38 = __toESM(require("path"));
17747
17947
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17748
17948
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
17749
17949
  function resolveDoltInstallStrategy(platform2) {
@@ -17839,7 +18039,7 @@ var _doltPathSeam = {
17839
18039
  },
17840
18040
  exists: (p2) => {
17841
18041
  try {
17842
- fs31.accessSync(p2, fs31.constants.F_OK);
18042
+ fs32.accessSync(p2, fs32.constants.F_OK);
17843
18043
  return true;
17844
18044
  } catch {
17845
18045
  return false;
@@ -17850,7 +18050,7 @@ function doltBinaryNames(platform2) {
17850
18050
  return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
17851
18051
  }
17852
18052
  function knownDoltDirs(platform2) {
17853
- const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
18053
+ const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
17854
18054
  const home = _doltPathSeam.homedir();
17855
18055
  if (platform2 === "win32") {
17856
18056
  return [
@@ -17866,7 +18066,7 @@ function knownDoltDirs(platform2) {
17866
18066
  ].filter(Boolean);
17867
18067
  }
17868
18068
  function ensureDoltResolvable(platform2 = process.platform) {
17869
- const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
18069
+ const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
17870
18070
  const delim = platform2 === "win32" ? ";" : ":";
17871
18071
  const names = doltBinaryNames(platform2);
17872
18072
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -17977,8 +18177,8 @@ async function ensureSharedServer(adapter) {
17977
18177
  // src/beads/project-key.ts
17978
18178
  var import_child_process16 = require("child_process");
17979
18179
  var crypto2 = __toESM(require("crypto"));
17980
- var fs32 = __toESM(require("fs"));
17981
- var path38 = __toESM(require("path"));
18180
+ var fs33 = __toESM(require("fs"));
18181
+ var path39 = __toESM(require("path"));
17982
18182
  function normalizeOrigin(raw) {
17983
18183
  const trimmed = raw.trim();
17984
18184
  if (!trimmed) return null;
@@ -18004,17 +18204,17 @@ function normalizeOrigin(raw) {
18004
18204
  return `${host}/${pathPart}`;
18005
18205
  }
18006
18206
  function findRepoRoot(cwd) {
18007
- let dir = path38.resolve(cwd);
18207
+ let dir = path39.resolve(cwd);
18008
18208
  const seen = /* @__PURE__ */ new Set();
18009
18209
  for (let i = 0; i < 256; i++) {
18010
18210
  if (seen.has(dir)) return null;
18011
18211
  seen.add(dir);
18012
18212
  try {
18013
- const stat3 = fs32.statSync(path38.join(dir, ".git"), { throwIfNoEntry: false });
18213
+ const stat3 = fs33.statSync(path39.join(dir, ".git"), { throwIfNoEntry: false });
18014
18214
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
18015
18215
  } catch {
18016
18216
  }
18017
- const parent = path38.dirname(dir);
18217
+ const parent = path39.dirname(dir);
18018
18218
  if (parent === dir) return null;
18019
18219
  dir = parent;
18020
18220
  }
@@ -18025,7 +18225,7 @@ var _execSeam2 = {
18025
18225
  const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
18026
18226
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
18027
18227
  },
18028
- realpath: (p2) => fs32.realpathSync(p2)
18228
+ realpath: (p2) => fs33.realpathSync(p2)
18029
18229
  };
18030
18230
  function readOrigin(cwd) {
18031
18231
  try {
@@ -18054,7 +18254,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
18054
18254
  } catch {
18055
18255
  }
18056
18256
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
18057
- return { projectKey: `path:${hash}`, projectLabel: path38.basename(real) || "project" };
18257
+ return { projectKey: `path:${hash}`, projectLabel: path39.basename(real) || "project" };
18058
18258
  }
18059
18259
 
18060
18260
  // src/beads/project-prefix.ts
@@ -18099,14 +18299,14 @@ var _linkSeam = {
18099
18299
  homedir: () => os26.homedir(),
18100
18300
  isWritableDir: (dir) => {
18101
18301
  try {
18102
- fs33.accessSync(dir, fs33.constants.W_OK);
18302
+ fs34.accessSync(dir, fs34.constants.W_OK);
18103
18303
  return true;
18104
18304
  } catch {
18105
18305
  return false;
18106
18306
  }
18107
18307
  },
18108
18308
  ensureDir: (dir) => {
18109
- fs33.mkdirSync(dir, { recursive: true });
18309
+ fs34.mkdirSync(dir, { recursive: true });
18110
18310
  },
18111
18311
  /**
18112
18312
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -18127,12 +18327,12 @@ var _linkSeam = {
18127
18327
  * which `linkBdOntoPath` creates if missing.
18128
18328
  */
18129
18329
  cliBinDir: () => {
18130
- const pathDirs = (process.env.PATH ?? "").split(path39.delimiter).filter(Boolean);
18330
+ const pathDirs = (process.env.PATH ?? "").split(path40.delimiter).filter(Boolean);
18131
18331
  const home = _linkSeam.homedir();
18132
- const localBin = home ? path39.join(home, ".local", "bin") : null;
18332
+ const localBin = home ? path40.join(home, ".local", "bin") : null;
18133
18333
  const candidates = [];
18134
18334
  try {
18135
- candidates.push(path39.dirname(process.execPath));
18335
+ candidates.push(path40.dirname(process.execPath));
18136
18336
  } catch {
18137
18337
  }
18138
18338
  if (localBin) candidates.push(localBin);
@@ -18140,9 +18340,9 @@ var _linkSeam = {
18140
18340
  const entry = process.argv[1];
18141
18341
  if (entry) {
18142
18342
  try {
18143
- candidates.push(path39.dirname(fs33.realpathSync(entry)));
18343
+ candidates.push(path40.dirname(fs34.realpathSync(entry)));
18144
18344
  } catch {
18145
- candidates.push(path39.dirname(entry));
18345
+ candidates.push(path40.dirname(entry));
18146
18346
  }
18147
18347
  }
18148
18348
  const onPathWritable = candidates.find(
@@ -18154,20 +18354,20 @@ var _linkSeam = {
18154
18354
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
18155
18355
  readlink: (linkPath) => {
18156
18356
  try {
18157
- return fs33.readlinkSync(linkPath);
18357
+ return fs34.readlinkSync(linkPath);
18158
18358
  } catch {
18159
18359
  return null;
18160
18360
  }
18161
18361
  },
18162
- unlink: (linkPath) => fs33.unlinkSync(linkPath),
18163
- symlink: (target, linkPath) => fs33.symlinkSync(target, linkPath)
18362
+ unlink: (linkPath) => fs34.unlinkSync(linkPath),
18363
+ symlink: (target, linkPath) => fs34.symlinkSync(target, linkPath)
18164
18364
  };
18165
18365
  function linkBdOntoPath(binaryPath) {
18166
18366
  if (_linkSeam.platform() === "win32") return;
18167
18367
  const binDir = _linkSeam.cliBinDir();
18168
18368
  if (!binDir) return;
18169
18369
  _linkSeam.ensureDir(binDir);
18170
- const linkPath = path39.join(binDir, "bd");
18370
+ const linkPath = path40.join(binDir, "bd");
18171
18371
  if (linkPath === binaryPath) return;
18172
18372
  const current = _linkSeam.readlink(linkPath);
18173
18373
  if (current === binaryPath) return;
@@ -18308,7 +18508,7 @@ function dedupeRecipes(agents) {
18308
18508
 
18309
18509
  // src/beads/watcher.ts
18310
18510
  var crypto4 = __toESM(require("crypto"));
18311
- var path40 = __toESM(require("path"));
18511
+ var path41 = __toESM(require("path"));
18312
18512
 
18313
18513
  // src/services/file-watcher/transport.ts
18314
18514
  var http5 = __toESM(require("http"));
@@ -18383,7 +18583,7 @@ var BeadsWatcher = class {
18383
18583
  constructor(opts) {
18384
18584
  this.opts = opts;
18385
18585
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
18386
- this.feedPath = opts.feedPath ?? path40.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
18586
+ this.feedPath = opts.feedPath ?? path41.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
18387
18587
  this.apiBase = opts.apiBaseUrl ?? API_BASE4;
18388
18588
  }
18389
18589
  opts;
@@ -18508,6 +18708,45 @@ var BeadsWatcher = class {
18508
18708
  }
18509
18709
  };
18510
18710
 
18711
+ // src/beads/inherit-team-memories.ts
18712
+ async function inheritTeamMemories(opts) {
18713
+ const apiBase = opts.apiBaseUrl ?? resolveApiBaseUrl();
18714
+ let memories = [];
18715
+ try {
18716
+ const res = await _transport3.post(
18717
+ `${apiBase}/api/beads/team-memories`,
18718
+ {
18719
+ "Content-Type": "application/json",
18720
+ "X-Codeam-Protocol-Version": "2.0.0",
18721
+ "X-Plugin-Auth-Token": opts.pluginAuthToken
18722
+ },
18723
+ JSON.stringify({ sessionId: opts.sessionId, pluginId: opts.pluginId })
18724
+ );
18725
+ if (res.statusCode < 200 || res.statusCode >= 300) {
18726
+ log.trace("beads", `team-memories fetch status=${res.statusCode}`);
18727
+ return;
18728
+ }
18729
+ const parsed = JSON.parse(res.body);
18730
+ memories = Array.isArray(parsed.data?.memories) ? parsed.data.memories : [];
18731
+ } catch (err) {
18732
+ log.warn("beads", "team-memories fetch failed (non-fatal)", err);
18733
+ return;
18734
+ }
18735
+ if (memories.length === 0) return;
18736
+ let written = 0;
18737
+ for (const m of memories) {
18738
+ const body = (m?.body ?? "").trim();
18739
+ if (!m?.id || !body) continue;
18740
+ try {
18741
+ await opts.adapter.run(["remember", "--key", `team-${m.id}`, `Team convention (read-only): ${body}`]);
18742
+ written++;
18743
+ } catch (err) {
18744
+ log.trace("beads", `team memory write failed id=${m.id}: ${err.message}`);
18745
+ }
18746
+ }
18747
+ log.info("beads", `inherited ${written}/${memories.length} team memory(ies) into the active repo`);
18748
+ }
18749
+
18511
18750
  // src/beads/apply-actions.ts
18512
18751
  function buildBdArgs(action) {
18513
18752
  switch (action.kind) {
@@ -18577,6 +18816,12 @@ async function startBeads(opts) {
18577
18816
  });
18578
18817
  watcher.start();
18579
18818
  void watcher.syncNow();
18819
+ void inheritTeamMemories({
18820
+ sessionId: opts.sessionId,
18821
+ pluginId: opts.pluginId,
18822
+ pluginAuthToken: opts.pluginAuthToken,
18823
+ adapter
18824
+ });
18580
18825
  return { watcher, adapter };
18581
18826
  }
18582
18827
  async function handleBeadsActionCommand(action, started) {
@@ -18661,7 +18906,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18661
18906
  function cleanupAttachmentTempFiles() {
18662
18907
  for (const p2 of pendingAttachmentFiles) {
18663
18908
  try {
18664
- fs34.unlinkSync(p2);
18909
+ fs35.unlinkSync(p2);
18665
18910
  } catch {
18666
18911
  }
18667
18912
  }
@@ -18670,8 +18915,8 @@ function cleanupAttachmentTempFiles() {
18670
18915
  function saveFilesTemp(files) {
18671
18916
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18672
18917
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18673
- const tmpPath = path41.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18674
- fs34.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18918
+ const tmpPath = path42.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18919
+ fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18675
18920
  pendingAttachmentFiles.add(tmpPath);
18676
18921
  return tmpPath;
18677
18922
  });
@@ -18691,7 +18936,7 @@ var startTask = (ctx, _cmd, parsed) => {
18691
18936
  setTimeout(() => {
18692
18937
  for (const p2 of paths) {
18693
18938
  try {
18694
- fs34.unlinkSync(p2);
18939
+ fs35.unlinkSync(p2);
18695
18940
  } catch {
18696
18941
  }
18697
18942
  pendingAttachmentFiles.delete(p2);
@@ -19274,8 +19519,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
19274
19519
  if (args2.length === 0) return detection;
19275
19520
  const binName = args2[0];
19276
19521
  if (binName.startsWith("-")) return detection;
19277
- const binPath = path41.join(cwd, "node_modules", ".bin", binName);
19278
- if (!fs34.existsSync(binPath)) return detection;
19522
+ const binPath = path42.join(cwd, "node_modules", ".bin", binName);
19523
+ if (!fs35.existsSync(binPath)) return detection;
19279
19524
  return {
19280
19525
  ...detection,
19281
19526
  command: binPath,
@@ -19409,11 +19654,13 @@ var previewStartH = (ctx, _cmd, parsed) => {
19409
19654
  emitProgress("BIND_PORT", String(detection.port));
19410
19655
  emitProgress("WAITING_FOR_READY", detection.ready_pattern);
19411
19656
  let expoUrl = null;
19657
+ let outputTail = "";
19412
19658
  const readyRe = compileReadyPattern(detection.ready_pattern);
19413
19659
  const isNextJs = /next/i.test(detection.framework);
19414
19660
  const outcome = await waitForDevServerReady(devServer, readyRe, {
19415
19661
  timeoutMs: 12e4,
19416
19662
  onChunk: (s) => {
19663
+ outputTail = (outputTail + s).slice(-4e3);
19417
19664
  if (!expoUrl && detection.framework === "Expo") {
19418
19665
  expoUrl = parseExpoUrl(s);
19419
19666
  }
@@ -19428,7 +19675,8 @@ var previewStartH = (ctx, _cmd, parsed) => {
19428
19675
  type: "preview_error",
19429
19676
  payload: {
19430
19677
  stage: "spawn",
19431
- message: `Dev server exited (code ${outcome.code}).`
19678
+ message: `The dev server exited (code ${outcome.code}) before it was ready. It may need a database or other services.`,
19679
+ stderrTail: outputTail.slice(-2e3)
19432
19680
  }
19433
19681
  });
19434
19682
  return;
@@ -19443,7 +19691,11 @@ var previewStartH = (ctx, _cmd, parsed) => {
19443
19691
  pluginId: ctx.pluginId,
19444
19692
  pluginAuthToken,
19445
19693
  type: "preview_error",
19446
- payload: { stage: "ready_timeout", message: "Server didn't signal ready in 120s." }
19694
+ payload: {
19695
+ stage: "ready_timeout",
19696
+ message: "The dev server didn't become ready in time. It may be stuck waiting on a database or other service.",
19697
+ stderrTail: outputTail.slice(-2e3)
19698
+ }
19447
19699
  });
19448
19700
  return;
19449
19701
  }
@@ -19705,9 +19957,9 @@ async function dispatchCommand(ctx, cmd) {
19705
19957
 
19706
19958
  // src/services/file-watcher.service.ts
19707
19959
  var import_child_process19 = require("child_process");
19708
- var fs35 = __toESM(require("fs"));
19960
+ var fs36 = __toESM(require("fs"));
19709
19961
  var os28 = __toESM(require("os"));
19710
- var path42 = __toESM(require("path"));
19962
+ var path43 = __toESM(require("path"));
19711
19963
  var import_ignore = __toESM(require("ignore"));
19712
19964
 
19713
19965
  // src/services/file-watcher/diff-parser.ts
@@ -19850,18 +20102,18 @@ var _findGitRootSeam = {
19850
20102
  resolve: _defaultFindGitRoot
19851
20103
  };
19852
20104
  function _defaultFindGitRoot(startDir) {
19853
- let dir = path42.resolve(startDir);
20105
+ let dir = path43.resolve(startDir);
19854
20106
  const seen = /* @__PURE__ */ new Set();
19855
20107
  for (let i = 0; i < 256; i++) {
19856
20108
  if (seen.has(dir)) return null;
19857
20109
  seen.add(dir);
19858
20110
  try {
19859
- const gitPath = path42.join(dir, ".git");
19860
- const stat3 = fs35.statSync(gitPath, { throwIfNoEntry: false });
20111
+ const gitPath = path43.join(dir, ".git");
20112
+ const stat3 = fs36.statSync(gitPath, { throwIfNoEntry: false });
19861
20113
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
19862
20114
  } catch {
19863
20115
  }
19864
- const parent = path42.dirname(dir);
20116
+ const parent = path43.dirname(dir);
19865
20117
  if (parent === dir) return null;
19866
20118
  dir = parent;
19867
20119
  }
@@ -20106,7 +20358,7 @@ var FileWatcherService = class {
20106
20358
  }
20107
20359
  async emitForFile(absPath, changeType) {
20108
20360
  if (this.stopped) return;
20109
- const fileDir = path42.dirname(absPath);
20361
+ const fileDir = path43.dirname(absPath);
20110
20362
  let gitRoot = this.gitRootByDir.get(fileDir);
20111
20363
  if (gitRoot === void 0) {
20112
20364
  gitRoot = findGitRoot2(fileDir);
@@ -20119,19 +20371,19 @@ var FileWatcherService = class {
20119
20371
  );
20120
20372
  return;
20121
20373
  }
20122
- const relPathInRepo = path42.relative(gitRoot, absPath);
20374
+ const relPathInRepo = path43.relative(gitRoot, absPath);
20123
20375
  if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
20124
20376
  const matcher = this.getGitIgnoreMatcher(gitRoot);
20125
20377
  if (matcher && matcher.ignores(relPathInRepo)) {
20126
20378
  log.trace(
20127
20379
  "fileWatcher",
20128
- `${relPathInRepo} ignored by ${path42.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
20380
+ `${relPathInRepo} ignored by ${path43.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
20129
20381
  );
20130
20382
  return;
20131
20383
  }
20132
20384
  this.opts.onRepoDirty?.(gitRoot);
20133
- const repoPath = path42.relative(this.opts.workingDir, gitRoot);
20134
- const repoName = path42.basename(gitRoot);
20385
+ const repoPath = path43.relative(this.opts.workingDir, gitRoot);
20386
+ const repoName = path43.basename(gitRoot);
20135
20387
  let diffText = "";
20136
20388
  let fileStatus = "modified";
20137
20389
  if (changeType === "unlink") {
@@ -20306,7 +20558,7 @@ var FileWatcherService = class {
20306
20558
  collectGitignoreFiles(repoRoot, dir, matcher) {
20307
20559
  let entries;
20308
20560
  try {
20309
- entries = fs35.readdirSync(dir, { withFileTypes: true });
20561
+ entries = fs36.readdirSync(dir, { withFileTypes: true });
20310
20562
  } catch {
20311
20563
  return;
20312
20564
  }
@@ -20315,16 +20567,16 @@ var FileWatcherService = class {
20315
20567
  );
20316
20568
  if (gitignoreEntry) {
20317
20569
  try {
20318
- const body = fs35.readFileSync(path42.join(dir, ".gitignore"), "utf8");
20319
- const rel = path42.relative(repoRoot, dir).replace(/\\/g, "/");
20570
+ const body = fs36.readFileSync(path43.join(dir, ".gitignore"), "utf8");
20571
+ const rel = path43.relative(repoRoot, dir).replace(/\\/g, "/");
20320
20572
  const prefixed = body.split(/\r?\n/).map((line) => {
20321
20573
  const trimmed = line.trim();
20322
20574
  if (!trimmed || trimmed.startsWith("#")) return line;
20323
20575
  if (!rel) return line;
20324
20576
  if (trimmed.startsWith("!")) {
20325
- return "!" + path42.posix.join(rel, trimmed.slice(1));
20577
+ return "!" + path43.posix.join(rel, trimmed.slice(1));
20326
20578
  }
20327
- return path42.posix.join(rel, trimmed);
20579
+ return path43.posix.join(rel, trimmed);
20328
20580
  }).join("\n");
20329
20581
  matcher.add(prefixed);
20330
20582
  } catch {
@@ -20333,7 +20585,7 @@ var FileWatcherService = class {
20333
20585
  for (const entry of entries) {
20334
20586
  if (!entry.isDirectory()) continue;
20335
20587
  if (entry.name === ".git") continue;
20336
- const childAbs = path42.join(dir, entry.name);
20588
+ const childAbs = path43.join(dir, entry.name);
20337
20589
  if (isIgnoredFilePath(childAbs)) continue;
20338
20590
  this.collectGitignoreFiles(repoRoot, childAbs, matcher);
20339
20591
  }
@@ -20503,7 +20755,7 @@ var import_crypto4 = require("crypto");
20503
20755
 
20504
20756
  // src/services/turn-files/git-changeset.ts
20505
20757
  var import_child_process20 = require("child_process");
20506
- var path43 = __toESM(require("path"));
20758
+ var path44 = __toESM(require("path"));
20507
20759
  async function collectRepoChangeset(opts) {
20508
20760
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
20509
20761
  if (status2 === null) return null;
@@ -20614,7 +20866,7 @@ function defaultRunGit(cwd, args2) {
20614
20866
  });
20615
20867
  }
20616
20868
  async function discoverRepos(workingDir, maxDepth = 4) {
20617
- const fs41 = await import("fs/promises");
20869
+ const fs42 = await import("fs/promises");
20618
20870
  const out2 = [];
20619
20871
  await walk(workingDir, 0);
20620
20872
  return out2;
@@ -20622,7 +20874,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20622
20874
  if (depth > maxDepth) return;
20623
20875
  let entries = [];
20624
20876
  try {
20625
- const dirents = await fs41.readdir(dir, { withFileTypes: true });
20877
+ const dirents = await fs42.readdir(dir, { withFileTypes: true });
20626
20878
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
20627
20879
  } catch {
20628
20880
  return;
@@ -20633,8 +20885,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20633
20885
  if (hasGit) {
20634
20886
  out2.push({
20635
20887
  repoRoot: dir,
20636
- repoPath: path43.relative(workingDir, dir),
20637
- repoName: path43.basename(dir)
20888
+ repoPath: path44.relative(workingDir, dir),
20889
+ repoName: path44.basename(dir)
20638
20890
  });
20639
20891
  return;
20640
20892
  }
@@ -20642,14 +20894,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20642
20894
  if (!entry.isDirectory) continue;
20643
20895
  if (entry.name === "node_modules") continue;
20644
20896
  if (entry.name === "dist" || entry.name === "build") continue;
20645
- await walk(path43.join(dir, entry.name), depth + 1);
20897
+ await walk(path44.join(dir, entry.name), depth + 1);
20646
20898
  }
20647
20899
  }
20648
20900
  }
20649
20901
 
20650
20902
  // src/services/turn-files/files-outbox.ts
20651
- var fs36 = __toESM(require("fs/promises"));
20652
- var path44 = __toESM(require("path"));
20903
+ var fs37 = __toESM(require("fs/promises"));
20904
+ var path45 = __toESM(require("path"));
20653
20905
  var import_os7 = require("os");
20654
20906
  var HOME_OUTBOX_DIR = ".codeam/outbox";
20655
20907
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -20682,16 +20934,16 @@ var FilesOutbox = class {
20682
20934
  backoffIndex = 0;
20683
20935
  stopped = false;
20684
20936
  constructor(opts) {
20685
- const base = opts.baseDir ?? path44.join(homeDir(), HOME_OUTBOX_DIR);
20686
- this.filePath = path44.join(base, `${opts.sessionId}.jsonl`);
20937
+ const base = opts.baseDir ?? path45.join(homeDir(), HOME_OUTBOX_DIR);
20938
+ this.filePath = path45.join(base, `${opts.sessionId}.jsonl`);
20687
20939
  this.post = opts.post;
20688
20940
  this.autoSchedule = opts.autoSchedule !== false;
20689
20941
  }
20690
20942
  /** Persist the entry to disk and trigger a flush. Returns once the
20691
20943
  * line is durable on disk (not once the POST succeeds). */
20692
20944
  async enqueue(entry) {
20693
- await fs36.mkdir(path44.dirname(this.filePath), { recursive: true });
20694
- await fs36.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20945
+ await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
20946
+ await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20695
20947
  this.backoffIndex = 0;
20696
20948
  if (this.autoSchedule) this.scheduleFlush(0);
20697
20949
  }
@@ -20780,7 +21032,7 @@ var FilesOutbox = class {
20780
21032
  async readAll() {
20781
21033
  let raw = "";
20782
21034
  try {
20783
- raw = await fs36.readFile(this.filePath, "utf8");
21035
+ raw = await fs37.readFile(this.filePath, "utf8");
20784
21036
  } catch {
20785
21037
  return [];
20786
21038
  }
@@ -20804,12 +21056,12 @@ var FilesOutbox = class {
20804
21056
  async rewrite(entries) {
20805
21057
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
20806
21058
  if (entries.length === 0) {
20807
- await fs36.unlink(this.filePath).catch(() => void 0);
21059
+ await fs37.unlink(this.filePath).catch(() => void 0);
20808
21060
  return;
20809
21061
  }
20810
21062
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
20811
- await fs36.writeFile(tmpPath, payload, "utf8");
20812
- await fs36.rename(tmpPath, this.filePath);
21063
+ await fs37.writeFile(tmpPath, payload, "utf8");
21064
+ await fs37.rename(tmpPath, this.filePath);
20813
21065
  }
20814
21066
  };
20815
21067
  function applyJitter(ms) {
@@ -21906,10 +22158,10 @@ var ChromeStepTracker = class {
21906
22158
  const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
21907
22159
  if (visible.length === 0) return;
21908
22160
  for (const step of visible) {
21909
- const exists = this.history.some(
22161
+ const exists2 = this.history.some(
21910
22162
  (s) => s.tool === step.tool && s.label === step.label
21911
22163
  );
21912
- if (!exists) this.history.push(step);
22164
+ if (!exists2) this.history.push(step);
21913
22165
  }
21914
22166
  }
21915
22167
  /**
@@ -22654,8 +22906,8 @@ var OutputService = class _OutputService {
22654
22906
  };
22655
22907
 
22656
22908
  // src/services/history.service.ts
22657
- var fs37 = __toESM(require("fs"));
22658
- var path45 = __toESM(require("path"));
22909
+ var fs38 = __toESM(require("fs"));
22910
+ var path46 = __toESM(require("path"));
22659
22911
  var os29 = __toESM(require("os"));
22660
22912
  var https7 = __toESM(require("https"));
22661
22913
  var http7 = __toESM(require("http"));
@@ -22683,7 +22935,7 @@ function parseJsonl(filePath) {
22683
22935
  const messages = [];
22684
22936
  let raw;
22685
22937
  try {
22686
- raw = fs37.readFileSync(filePath, "utf8");
22938
+ raw = fs38.readFileSync(filePath, "utf8");
22687
22939
  } catch (err) {
22688
22940
  if (err.code !== "ENOENT") {
22689
22941
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -22818,7 +23070,7 @@ var HistoryService = class _HistoryService {
22818
23070
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
22819
23071
  }
22820
23072
  get projectDir() {
22821
- return this.runtime.resolveHistoryDir(this.cwd) ?? path45.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
23073
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22822
23074
  }
22823
23075
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
22824
23076
  setCurrentConversationId(id) {
@@ -22830,7 +23082,7 @@ var HistoryService = class _HistoryService {
22830
23082
  /** Return the current message count in the active conversation. */
22831
23083
  getCurrentMessageCount() {
22832
23084
  if (!this.currentConversationId) return 0;
22833
- const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23085
+ const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22834
23086
  return parseJsonl(filePath).length;
22835
23087
  }
22836
23088
  /**
@@ -22841,7 +23093,7 @@ var HistoryService = class _HistoryService {
22841
23093
  const deadline = Date.now() + timeoutMs;
22842
23094
  while (Date.now() < deadline) {
22843
23095
  if (!this.currentConversationId) return null;
22844
- const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23096
+ const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22845
23097
  const messages = parseJsonl(filePath);
22846
23098
  if (messages.length > previousCount) {
22847
23099
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -22867,16 +23119,16 @@ var HistoryService = class _HistoryService {
22867
23119
  const dir = this.projectDir;
22868
23120
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22869
23121
  try {
22870
- const files = fs37.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23122
+ const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22871
23123
  try {
22872
- const stat3 = fs37.statSync(path45.join(dir, e.name));
23124
+ const stat3 = fs38.statSync(path46.join(dir, e.name));
22873
23125
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22874
23126
  } catch {
22875
23127
  return { name: e.name, mtime: 0, birthtime: 0 };
22876
23128
  }
22877
23129
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22878
23130
  if (files.length > 0) {
22879
- this.currentConversationId = path45.basename(files[0].name, ".jsonl");
23131
+ this.currentConversationId = path46.basename(files[0].name, ".jsonl");
22880
23132
  }
22881
23133
  } catch {
22882
23134
  }
@@ -22910,13 +23162,13 @@ var HistoryService = class _HistoryService {
22910
23162
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22911
23163
  let entries;
22912
23164
  try {
22913
- entries = fs37.readdirSync(dir, { withFileTypes: true });
23165
+ entries = fs38.readdirSync(dir, { withFileTypes: true });
22914
23166
  } catch {
22915
23167
  return null;
22916
23168
  }
22917
23169
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22918
23170
  try {
22919
- const stat3 = fs37.statSync(path45.join(dir, e.name));
23171
+ const stat3 = fs38.statSync(path46.join(dir, e.name));
22920
23172
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22921
23173
  } catch {
22922
23174
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22925,12 +23177,12 @@ var HistoryService = class _HistoryService {
22925
23177
  if (files.length === 0) return null;
22926
23178
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
22927
23179
  if (!files.some((f) => f.name === targetFile)) return null;
22928
- return this.extractUsageFromFile(path45.join(dir, targetFile));
23180
+ return this.extractUsageFromFile(path46.join(dir, targetFile));
22929
23181
  }
22930
23182
  extractUsageFromFile(filePath) {
22931
23183
  let raw;
22932
23184
  try {
22933
- raw = fs37.readFileSync(filePath, "utf8");
23185
+ raw = fs38.readFileSync(filePath, "utf8");
22934
23186
  } catch {
22935
23187
  return null;
22936
23188
  }
@@ -22975,9 +23227,9 @@ var HistoryService = class _HistoryService {
22975
23227
  let totalCost = 0;
22976
23228
  let files;
22977
23229
  try {
22978
- files = fs37.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23230
+ files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22979
23231
  try {
22980
- return fs37.statSync(path45.join(projectDir, f)).mtimeMs >= monthStartMs;
23232
+ return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
22981
23233
  } catch {
22982
23234
  return false;
22983
23235
  }
@@ -22988,7 +23240,7 @@ var HistoryService = class _HistoryService {
22988
23240
  for (const file of files) {
22989
23241
  let raw;
22990
23242
  try {
22991
- raw = fs37.readFileSync(path45.join(projectDir, file), "utf8");
23243
+ raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
22992
23244
  } catch {
22993
23245
  continue;
22994
23246
  }
@@ -23052,7 +23304,7 @@ var HistoryService = class _HistoryService {
23052
23304
  * showing an empty conversation.
23053
23305
  */
23054
23306
  async loadConversation(sessionId) {
23055
- const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
23307
+ const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
23056
23308
  const messages = parseJsonl(filePath);
23057
23309
  if (messages.length === 0) return;
23058
23310
  const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
@@ -23106,7 +23358,7 @@ var HistoryService = class _HistoryService {
23106
23358
  if (!this.currentConversationId) return 0;
23107
23359
  }
23108
23360
  const sessionId = this.currentConversationId;
23109
- const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
23361
+ const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
23110
23362
  const messages = parseJsonl(filePath);
23111
23363
  if (messages.length === 0) return 0;
23112
23364
  const marker = this.lastUploadedUuid.get(sessionId);
@@ -24027,7 +24279,7 @@ async function autoLinkAfterPair(opts) {
24027
24279
  }
24028
24280
 
24029
24281
  // src/commands/pair-auto.ts
24030
- var fs38 = __toESM(require("fs"));
24282
+ var fs39 = __toESM(require("fs"));
24031
24283
  var os30 = __toESM(require("os"));
24032
24284
  var import_crypto7 = require("crypto");
24033
24285
 
@@ -24223,12 +24475,12 @@ function readTokenFromArgs(args2) {
24223
24475
  }
24224
24476
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
24225
24477
  if (fileFlag) {
24226
- const path52 = fileFlag.slice("--token-file=".length);
24478
+ const path53 = fileFlag.slice("--token-file=".length);
24227
24479
  try {
24228
- const content = fs38.readFileSync(path52, "utf8").trim();
24229
- if (content.length === 0) fail(`--token-file ${path52} is empty`);
24480
+ const content = fs39.readFileSync(path53, "utf8").trim();
24481
+ if (content.length === 0) fail(`--token-file ${path53} is empty`);
24230
24482
  try {
24231
- fs38.unlinkSync(path52);
24483
+ fs39.unlinkSync(path53);
24232
24484
  } catch {
24233
24485
  }
24234
24486
  return content;
@@ -24346,6 +24598,8 @@ async function pairAuto(args2) {
24346
24598
  codespaceName: process.env.CODESPACE_NAME ?? void 0
24347
24599
  });
24348
24600
  console.log(` Paired with ${claimed.user.name} (${claimed.user.plan})`);
24601
+ void provisionProjectDependencies(process.cwd()).catch(() => {
24602
+ });
24349
24603
  if (process.env.CODEAM_SKIP_AGENT_LAUNCH === "true") {
24350
24604
  capture("pair_auto_skipped_launch", {
24351
24605
  sessionId: claimed.sessionId,
@@ -24494,7 +24748,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
24494
24748
  var import_child_process22 = require("child_process");
24495
24749
  var import_util4 = require("util");
24496
24750
  var import_picocolors8 = __toESM(require("picocolors"));
24497
- var path46 = __toESM(require("path"));
24751
+ var path47 = __toESM(require("path"));
24498
24752
  var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
24499
24753
  var MAX_BUFFER = 8 * 1024 * 1024;
24500
24754
  function resetStdinForChild() {
@@ -24983,7 +25237,7 @@ var GitHubCodespacesProvider = class {
24983
25237
  });
24984
25238
  }
24985
25239
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
24986
- const remoteDir = path46.posix.dirname(remotePath);
25240
+ const remoteDir = path47.posix.dirname(remotePath);
24987
25241
  const parts = [
24988
25242
  `mkdir -p ${shellQuote(remoteDir)}`,
24989
25243
  `cat > ${shellQuote(remotePath)}`
@@ -25053,7 +25307,7 @@ function shellQuote(s) {
25053
25307
  // src/services/providers/gitpod.ts
25054
25308
  var import_child_process23 = require("child_process");
25055
25309
  var import_util5 = require("util");
25056
- var path47 = __toESM(require("path"));
25310
+ var path48 = __toESM(require("path"));
25057
25311
  var import_picocolors9 = __toESM(require("picocolors"));
25058
25312
  var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
25059
25313
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -25293,7 +25547,7 @@ var GitpodProvider = class {
25293
25547
  });
25294
25548
  }
25295
25549
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
25296
- const remoteDir = path47.posix.dirname(remotePath);
25550
+ const remoteDir = path48.posix.dirname(remotePath);
25297
25551
  const parts = [
25298
25552
  `mkdir -p ${shellQuote2(remoteDir)}`,
25299
25553
  `cat > ${shellQuote2(remotePath)}`
@@ -25329,7 +25583,7 @@ function shellQuote2(s) {
25329
25583
  // src/services/providers/gitlab-workspaces.ts
25330
25584
  var import_child_process24 = require("child_process");
25331
25585
  var import_util6 = require("util");
25332
- var path48 = __toESM(require("path"));
25586
+ var path49 = __toESM(require("path"));
25333
25587
  var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
25334
25588
  var MAX_BUFFER3 = 8 * 1024 * 1024;
25335
25589
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -25589,7 +25843,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25589
25843
  }
25590
25844
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
25591
25845
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
25592
- const remoteDir = path48.posix.dirname(remotePath);
25846
+ const remoteDir = path49.posix.dirname(remotePath);
25593
25847
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
25594
25848
  if (options.mode != null) {
25595
25849
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -25657,7 +25911,7 @@ function shellQuote3(s) {
25657
25911
  // src/services/providers/railway.ts
25658
25912
  var import_child_process25 = require("child_process");
25659
25913
  var import_util7 = require("util");
25660
- var path49 = __toESM(require("path"));
25914
+ var path50 = __toESM(require("path"));
25661
25915
  var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
25662
25916
  var MAX_BUFFER4 = 8 * 1024 * 1024;
25663
25917
  function resetStdinForChild4() {
@@ -25893,7 +26147,7 @@ var RailwayProvider = class {
25893
26147
  if (!projectId || !serviceId) {
25894
26148
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
25895
26149
  }
25896
- const remoteDir = path49.posix.dirname(remotePath);
26150
+ const remoteDir = path50.posix.dirname(remotePath);
25897
26151
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
25898
26152
  if (options.mode != null) {
25899
26153
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -26436,8 +26690,8 @@ async function stopWorkspaceFromLocal(target) {
26436
26690
  var import_node_dns = require("dns");
26437
26691
  var import_node_util4 = require("util");
26438
26692
  var import_node_crypto8 = require("crypto");
26439
- var fs39 = __toESM(require("fs"));
26440
- var path50 = __toESM(require("path"));
26693
+ var fs40 = __toESM(require("fs"));
26694
+ var path51 = __toESM(require("path"));
26441
26695
  var import_picocolors12 = __toESM(require("picocolors"));
26442
26696
  var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
26443
26697
  async function checkDns(apiBase) {
@@ -26493,13 +26747,13 @@ async function checkHealth(apiBase) {
26493
26747
  }
26494
26748
  }
26495
26749
  function checkConfigDir() {
26496
- const dir = path50.join(require("os").homedir(), ".codeam");
26750
+ const dir = path51.join(require("os").homedir(), ".codeam");
26497
26751
  try {
26498
- fs39.mkdirSync(dir, { recursive: true, mode: 448 });
26499
- const probe = path50.join(dir, ".doctor-probe");
26500
- fs39.writeFileSync(probe, "ok", { mode: 384 });
26501
- const read = fs39.readFileSync(probe, "utf8");
26502
- fs39.unlinkSync(probe);
26752
+ fs40.mkdirSync(dir, { recursive: true, mode: 448 });
26753
+ const probe = path51.join(dir, ".doctor-probe");
26754
+ fs40.writeFileSync(probe, "ok", { mode: 384 });
26755
+ const read = fs40.readFileSync(probe, "utf8");
26756
+ fs40.unlinkSync(probe);
26503
26757
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
26504
26758
  return {
26505
26759
  id: "config-dir",
@@ -26563,7 +26817,7 @@ function checkNodePty() {
26563
26817
  detail: "not required on this platform"
26564
26818
  };
26565
26819
  }
26566
- const vendoredPath = path50.join(__dirname, "vendor", "node-pty");
26820
+ const vendoredPath = path51.join(__dirname, "vendor", "node-pty");
26567
26821
  for (const target of [vendoredPath, "node-pty"]) {
26568
26822
  try {
26569
26823
  require(target);
@@ -26605,7 +26859,7 @@ function checkChokidar() {
26605
26859
  }
26606
26860
  async function doctor(args2 = []) {
26607
26861
  const json = args2.includes("--json");
26608
- const cliVersion = true ? "2.37.3" : "0.0.0-dev";
26862
+ const cliVersion = true ? "2.39.0" : "0.0.0-dev";
26609
26863
  const apiBase = resolveApiBaseUrl();
26610
26864
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
26611
26865
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -26804,7 +27058,7 @@ async function completion(args2) {
26804
27058
  // src/commands/version.ts
26805
27059
  var import_picocolors13 = __toESM(require("picocolors"));
26806
27060
  function version2() {
26807
- const v = true ? "2.37.3" : "unknown";
27061
+ const v = true ? "2.39.0" : "unknown";
26808
27062
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
26809
27063
  }
26810
27064
 
@@ -26932,9 +27186,9 @@ function tryShowSubcommandHelp(cmd, args2) {
26932
27186
  var _subcommandHelpKeys = Object.keys(HELPS);
26933
27187
 
26934
27188
  // src/lib/updateNotifier.ts
26935
- var fs40 = __toESM(require("fs"));
27189
+ var fs41 = __toESM(require("fs"));
26936
27190
  var os31 = __toESM(require("os"));
26937
- var path51 = __toESM(require("path"));
27191
+ var path52 = __toESM(require("path"));
26938
27192
  var https8 = __toESM(require("https"));
26939
27193
  var import_node_child_process12 = require("child_process");
26940
27194
  var import_picocolors16 = __toESM(require("picocolors"));
@@ -26943,12 +27197,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
26943
27197
  var TTL_MS = 24 * 60 * 60 * 1e3;
26944
27198
  var REQUEST_TIMEOUT_MS = 1500;
26945
27199
  function cachePath() {
26946
- const dir = path51.join(os31.homedir(), ".codeam");
26947
- return path51.join(dir, "update-check.json");
27200
+ const dir = path52.join(os31.homedir(), ".codeam");
27201
+ return path52.join(dir, "update-check.json");
26948
27202
  }
26949
27203
  function readCache() {
26950
27204
  try {
26951
- const raw = fs40.readFileSync(cachePath(), "utf8");
27205
+ const raw = fs41.readFileSync(cachePath(), "utf8");
26952
27206
  const parsed = JSON.parse(raw);
26953
27207
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
26954
27208
  return parsed;
@@ -26959,10 +27213,10 @@ function readCache() {
26959
27213
  function writeCache(cache) {
26960
27214
  try {
26961
27215
  const file = cachePath();
26962
- fs40.mkdirSync(path51.dirname(file), { recursive: true });
27216
+ fs41.mkdirSync(path52.dirname(file), { recursive: true });
26963
27217
  const tmp = `${file}.${process.pid}.tmp`;
26964
- fs40.writeFileSync(tmp, JSON.stringify(cache));
26965
- fs40.renameSync(tmp, file);
27218
+ fs41.writeFileSync(tmp, JSON.stringify(cache));
27219
+ fs41.renameSync(tmp, file);
26966
27220
  } catch {
26967
27221
  }
26968
27222
  }
@@ -27036,8 +27290,8 @@ function isLinkedInstall() {
27036
27290
  timeout: 2e3
27037
27291
  }).trim();
27038
27292
  if (!root) return false;
27039
- const pkgPath = path51.join(root, PKG_NAME);
27040
- return fs40.lstatSync(pkgPath).isSymbolicLink();
27293
+ const pkgPath = path52.join(root, PKG_NAME);
27294
+ return fs41.lstatSync(pkgPath).isSymbolicLink();
27041
27295
  } catch {
27042
27296
  return false;
27043
27297
  }
@@ -27073,7 +27327,7 @@ function maybeAutoUpdate(currentVersion, latest) {
27073
27327
  return;
27074
27328
  }
27075
27329
  try {
27076
- fs40.unlinkSync(cachePath());
27330
+ fs41.unlinkSync(cachePath());
27077
27331
  } catch {
27078
27332
  }
27079
27333
  process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
@@ -27090,7 +27344,7 @@ function checkForUpdates() {
27090
27344
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
27091
27345
  if (process.env.CI) return;
27092
27346
  if (!process.stdout.isTTY) return;
27093
- const current = true ? "2.37.3" : null;
27347
+ const current = true ? "2.39.0" : null;
27094
27348
  if (!current) return;
27095
27349
  const cache = readCache();
27096
27350
  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.37.3",
3
+ "version": "2.39.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",