codeam-cli 2.39.0 → 2.39.1

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 +10 -0
  2. package/dist/index.js +154 -356
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ 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.0] — 2026-06-12
8
+
9
+ ### Added
10
+
11
+ - **cli:** Auto-provision project dependencies in codespaces + preview_failed
12
+
13
+ ### Fixed
14
+
15
+ - **cli:** Emit preview_error (not a new type) with stderr tail on dev-server failure
16
+
7
17
  ## [2.38.0] — 2026-06-12
8
18
 
9
19
  ### 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.39.0",
501
+ version: "2.39.1",
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(path53) {
1190
- return path53.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1189
+ function normalizeWindowsPath(path52) {
1190
+ return path52.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(path53, ranges, output) {
3670
+ function getContextLinesFromFile(path52, ranges, output) {
3671
3671
  return new Promise((resolve7) => {
3672
- const stream = (0, import_node_fs.createReadStream)(path53);
3672
+ const stream = (0, import_node_fs.createReadStream)(path52);
3673
3673
  const lineReaded = (0, import_node_readline.createInterface)({
3674
3674
  input: stream
3675
3675
  });
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path53, 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(path53, 1);
3687
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path52, 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(path53) {
3749
- return path53.startsWith("node:") || path53.endsWith(".min.js") || path53.endsWith(".min.cjs") || path53.endsWith(".min.mjs") || path53.startsWith("data:");
3748
+ function shouldSkipContextLinesForFile(path52) {
3749
+ return path52.startsWith("node:") || path52.endsWith(".min.js") || path52.endsWith(".min.cjs") || path52.endsWith(".min.mjs") || path52.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.39.0" : "0.0.0-dev",
5903
+ cliVersion: true ? "2.39.1" : "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 path53 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
9981
+ const path52 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
9982
9982
  return {
9983
9983
  title: "",
9984
9984
  subtitle: lines[metaIdx].trim(),
9985
- path: path53,
9985
+ path: path52,
9986
9986
  startIdx: artStart,
9987
- endIdx: metaIdx + (path53 ? 1 : 0)
9987
+ endIdx: metaIdx + (path52 ? 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 [, path53, lineNo, sevToken, message] = m;
11346
- if (!path53 || !lineNo || !message) continue;
11345
+ const [, path52, lineNo, sevToken, message] = m;
11346
+ if (!path52 || !lineNo || !message) continue;
11347
11347
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
11348
11348
  hunks.push({
11349
- path: path53.trim(),
11349
+ path: path52.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 fs35 = __toESM(require("fs"));
15914
+ var fs34 = __toESM(require("fs"));
15915
15915
  var os27 = __toESM(require("os"));
15916
- var path42 = __toESM(require("path"));
15916
+ var path41 = __toESM(require("path"));
15917
15917
  var import_crypto3 = require("crypto");
15918
15918
  var import_child_process18 = require("child_process");
15919
15919
 
@@ -17364,10 +17364,6 @@ 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
-
17371
17367
  // src/services/preview/run-setup.ts
17372
17368
  var import_child_process12 = require("child_process");
17373
17369
  function runSetupCommand(cmd, args2, cwd, env, opts) {
@@ -17412,215 +17408,19 @@ function runSetupCommand(cmd, args2, cwd, env, opts) {
17412
17408
  });
17413
17409
  }
17414
17410
 
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
-
17611
17411
  // src/services/preview/setup-deps.ts
17612
- var import_fs3 = __toESM(require("fs"));
17613
- var import_path7 = __toESM(require("path"));
17412
+ var import_fs2 = __toESM(require("fs"));
17413
+ var import_path6 = __toESM(require("path"));
17614
17414
  function detectMissingNodeDeps(cwd) {
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"))) {
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"))) {
17618
17418
  return { cmd: "pnpm", args: ["install"] };
17619
17419
  }
17620
- if (import_fs3.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
17420
+ if (import_fs2.default.existsSync(import_path6.default.join(cwd, "yarn.lock"))) {
17621
17421
  return { cmd: "yarn", args: ["install"] };
17622
17422
  }
17623
- if (import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lockb")) || import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lock"))) {
17423
+ if (import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lockb")) || import_fs2.default.existsSync(import_path6.default.join(cwd, "bun.lock"))) {
17624
17424
  return { cmd: "bun", args: ["install"] };
17625
17425
  }
17626
17426
  return { cmd: "npm", args: ["install"] };
@@ -17675,8 +17475,8 @@ function activePreviewSessionIds() {
17675
17475
 
17676
17476
  // src/beads/bd-adapter.ts
17677
17477
  var import_child_process13 = require("child_process");
17678
- var fs31 = __toESM(require("fs"));
17679
- var path37 = __toESM(require("path"));
17478
+ var fs30 = __toESM(require("fs"));
17479
+ var path36 = __toESM(require("path"));
17680
17480
  var BD_PACKAGE = "@beads/bd";
17681
17481
  function resolveBundledBdBinary() {
17682
17482
  return _resolveSeam.resolveBundled();
@@ -17688,11 +17488,11 @@ function _defaultResolveBundled() {
17688
17488
  } catch {
17689
17489
  return null;
17690
17490
  }
17691
- const binDir = path37.join(path37.dirname(pkgJsonPath), "bin");
17491
+ const binDir = path36.join(path36.dirname(pkgJsonPath), "bin");
17692
17492
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
17693
- const binaryPath = path37.join(binDir, binaryName);
17493
+ const binaryPath = path36.join(binDir, binaryName);
17694
17494
  try {
17695
- fs31.accessSync(binaryPath, fs31.constants.F_OK);
17495
+ fs30.accessSync(binaryPath, fs30.constants.F_OK);
17696
17496
  return binaryPath;
17697
17497
  } catch {
17698
17498
  return null;
@@ -17702,13 +17502,13 @@ function resolveBdOnPath() {
17702
17502
  return _resolveSeam.resolveOnPath();
17703
17503
  }
17704
17504
  function _defaultResolveOnPath() {
17705
- const dirs = (process.env.PATH ?? "").split(path37.delimiter).filter(Boolean);
17505
+ const dirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
17706
17506
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
17707
17507
  for (const dir of dirs) {
17708
17508
  for (const candidate of candidates) {
17709
- const full = path37.join(dir, candidate);
17509
+ const full = path36.join(dir, candidate);
17710
17510
  try {
17711
- fs31.accessSync(full, fs31.constants.F_OK);
17511
+ fs30.accessSync(full, fs30.constants.F_OK);
17712
17512
  return full;
17713
17513
  } catch {
17714
17514
  }
@@ -17874,9 +17674,9 @@ function coerceIssue(row, projectKey) {
17874
17674
 
17875
17675
  // src/beads/provisioner.ts
17876
17676
  var import_child_process17 = require("child_process");
17877
- var fs34 = __toESM(require("fs"));
17677
+ var fs33 = __toESM(require("fs"));
17878
17678
  var os26 = __toESM(require("os"));
17879
- var path40 = __toESM(require("path"));
17679
+ var path39 = __toESM(require("path"));
17880
17680
 
17881
17681
  // src/beads/install-bd.ts
17882
17682
  var import_child_process14 = require("child_process");
@@ -17941,9 +17741,9 @@ async function installBd(platform2 = process.platform) {
17941
17741
 
17942
17742
  // src/beads/install-dolt.ts
17943
17743
  var import_child_process15 = require("child_process");
17944
- var fs32 = __toESM(require("fs"));
17744
+ var fs31 = __toESM(require("fs"));
17945
17745
  var os25 = __toESM(require("os"));
17946
- var path38 = __toESM(require("path"));
17746
+ var path37 = __toESM(require("path"));
17947
17747
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17948
17748
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
17949
17749
  function resolveDoltInstallStrategy(platform2) {
@@ -18039,7 +17839,7 @@ var _doltPathSeam = {
18039
17839
  },
18040
17840
  exists: (p2) => {
18041
17841
  try {
18042
- fs32.accessSync(p2, fs32.constants.F_OK);
17842
+ fs31.accessSync(p2, fs31.constants.F_OK);
18043
17843
  return true;
18044
17844
  } catch {
18045
17845
  return false;
@@ -18050,7 +17850,7 @@ function doltBinaryNames(platform2) {
18050
17850
  return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
18051
17851
  }
18052
17852
  function knownDoltDirs(platform2) {
18053
- const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
17853
+ const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
18054
17854
  const home = _doltPathSeam.homedir();
18055
17855
  if (platform2 === "win32") {
18056
17856
  return [
@@ -18066,7 +17866,7 @@ function knownDoltDirs(platform2) {
18066
17866
  ].filter(Boolean);
18067
17867
  }
18068
17868
  function ensureDoltResolvable(platform2 = process.platform) {
18069
- const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
17869
+ const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
18070
17870
  const delim = platform2 === "win32" ? ";" : ":";
18071
17871
  const names = doltBinaryNames(platform2);
18072
17872
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -18177,8 +17977,8 @@ async function ensureSharedServer(adapter) {
18177
17977
  // src/beads/project-key.ts
18178
17978
  var import_child_process16 = require("child_process");
18179
17979
  var crypto2 = __toESM(require("crypto"));
18180
- var fs33 = __toESM(require("fs"));
18181
- var path39 = __toESM(require("path"));
17980
+ var fs32 = __toESM(require("fs"));
17981
+ var path38 = __toESM(require("path"));
18182
17982
  function normalizeOrigin(raw) {
18183
17983
  const trimmed = raw.trim();
18184
17984
  if (!trimmed) return null;
@@ -18204,17 +18004,17 @@ function normalizeOrigin(raw) {
18204
18004
  return `${host}/${pathPart}`;
18205
18005
  }
18206
18006
  function findRepoRoot(cwd) {
18207
- let dir = path39.resolve(cwd);
18007
+ let dir = path38.resolve(cwd);
18208
18008
  const seen = /* @__PURE__ */ new Set();
18209
18009
  for (let i = 0; i < 256; i++) {
18210
18010
  if (seen.has(dir)) return null;
18211
18011
  seen.add(dir);
18212
18012
  try {
18213
- const stat3 = fs33.statSync(path39.join(dir, ".git"), { throwIfNoEntry: false });
18013
+ const stat3 = fs32.statSync(path38.join(dir, ".git"), { throwIfNoEntry: false });
18214
18014
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
18215
18015
  } catch {
18216
18016
  }
18217
- const parent = path39.dirname(dir);
18017
+ const parent = path38.dirname(dir);
18218
18018
  if (parent === dir) return null;
18219
18019
  dir = parent;
18220
18020
  }
@@ -18225,7 +18025,7 @@ var _execSeam2 = {
18225
18025
  const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
18226
18026
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
18227
18027
  },
18228
- realpath: (p2) => fs33.realpathSync(p2)
18028
+ realpath: (p2) => fs32.realpathSync(p2)
18229
18029
  };
18230
18030
  function readOrigin(cwd) {
18231
18031
  try {
@@ -18254,7 +18054,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
18254
18054
  } catch {
18255
18055
  }
18256
18056
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
18257
- return { projectKey: `path:${hash}`, projectLabel: path39.basename(real) || "project" };
18057
+ return { projectKey: `path:${hash}`, projectLabel: path38.basename(real) || "project" };
18258
18058
  }
18259
18059
 
18260
18060
  // src/beads/project-prefix.ts
@@ -18299,14 +18099,14 @@ var _linkSeam = {
18299
18099
  homedir: () => os26.homedir(),
18300
18100
  isWritableDir: (dir) => {
18301
18101
  try {
18302
- fs34.accessSync(dir, fs34.constants.W_OK);
18102
+ fs33.accessSync(dir, fs33.constants.W_OK);
18303
18103
  return true;
18304
18104
  } catch {
18305
18105
  return false;
18306
18106
  }
18307
18107
  },
18308
18108
  ensureDir: (dir) => {
18309
- fs34.mkdirSync(dir, { recursive: true });
18109
+ fs33.mkdirSync(dir, { recursive: true });
18310
18110
  },
18311
18111
  /**
18312
18112
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -18327,12 +18127,12 @@ var _linkSeam = {
18327
18127
  * which `linkBdOntoPath` creates if missing.
18328
18128
  */
18329
18129
  cliBinDir: () => {
18330
- const pathDirs = (process.env.PATH ?? "").split(path40.delimiter).filter(Boolean);
18130
+ const pathDirs = (process.env.PATH ?? "").split(path39.delimiter).filter(Boolean);
18331
18131
  const home = _linkSeam.homedir();
18332
- const localBin = home ? path40.join(home, ".local", "bin") : null;
18132
+ const localBin = home ? path39.join(home, ".local", "bin") : null;
18333
18133
  const candidates = [];
18334
18134
  try {
18335
- candidates.push(path40.dirname(process.execPath));
18135
+ candidates.push(path39.dirname(process.execPath));
18336
18136
  } catch {
18337
18137
  }
18338
18138
  if (localBin) candidates.push(localBin);
@@ -18340,9 +18140,9 @@ var _linkSeam = {
18340
18140
  const entry = process.argv[1];
18341
18141
  if (entry) {
18342
18142
  try {
18343
- candidates.push(path40.dirname(fs34.realpathSync(entry)));
18143
+ candidates.push(path39.dirname(fs33.realpathSync(entry)));
18344
18144
  } catch {
18345
- candidates.push(path40.dirname(entry));
18145
+ candidates.push(path39.dirname(entry));
18346
18146
  }
18347
18147
  }
18348
18148
  const onPathWritable = candidates.find(
@@ -18354,20 +18154,20 @@ var _linkSeam = {
18354
18154
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
18355
18155
  readlink: (linkPath) => {
18356
18156
  try {
18357
- return fs34.readlinkSync(linkPath);
18157
+ return fs33.readlinkSync(linkPath);
18358
18158
  } catch {
18359
18159
  return null;
18360
18160
  }
18361
18161
  },
18362
- unlink: (linkPath) => fs34.unlinkSync(linkPath),
18363
- symlink: (target, linkPath) => fs34.symlinkSync(target, linkPath)
18162
+ unlink: (linkPath) => fs33.unlinkSync(linkPath),
18163
+ symlink: (target, linkPath) => fs33.symlinkSync(target, linkPath)
18364
18164
  };
18365
18165
  function linkBdOntoPath(binaryPath) {
18366
18166
  if (_linkSeam.platform() === "win32") return;
18367
18167
  const binDir = _linkSeam.cliBinDir();
18368
18168
  if (!binDir) return;
18369
18169
  _linkSeam.ensureDir(binDir);
18370
- const linkPath = path40.join(binDir, "bd");
18170
+ const linkPath = path39.join(binDir, "bd");
18371
18171
  if (linkPath === binaryPath) return;
18372
18172
  const current = _linkSeam.readlink(linkPath);
18373
18173
  if (current === binaryPath) return;
@@ -18508,7 +18308,7 @@ function dedupeRecipes(agents) {
18508
18308
 
18509
18309
  // src/beads/watcher.ts
18510
18310
  var crypto4 = __toESM(require("crypto"));
18511
- var path41 = __toESM(require("path"));
18311
+ var path40 = __toESM(require("path"));
18512
18312
 
18513
18313
  // src/services/file-watcher/transport.ts
18514
18314
  var http5 = __toESM(require("http"));
@@ -18583,7 +18383,7 @@ var BeadsWatcher = class {
18583
18383
  constructor(opts) {
18584
18384
  this.opts = opts;
18585
18385
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
18586
- this.feedPath = opts.feedPath ?? path41.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
18386
+ this.feedPath = opts.feedPath ?? path40.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
18587
18387
  this.apiBase = opts.apiBaseUrl ?? API_BASE4;
18588
18388
  }
18589
18389
  opts;
@@ -18906,7 +18706,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18906
18706
  function cleanupAttachmentTempFiles() {
18907
18707
  for (const p2 of pendingAttachmentFiles) {
18908
18708
  try {
18909
- fs35.unlinkSync(p2);
18709
+ fs34.unlinkSync(p2);
18910
18710
  } catch {
18911
18711
  }
18912
18712
  }
@@ -18915,8 +18715,8 @@ function cleanupAttachmentTempFiles() {
18915
18715
  function saveFilesTemp(files) {
18916
18716
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18917
18717
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18918
- const tmpPath = path42.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18919
- fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18718
+ const tmpPath = path41.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18719
+ fs34.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18920
18720
  pendingAttachmentFiles.add(tmpPath);
18921
18721
  return tmpPath;
18922
18722
  });
@@ -18936,7 +18736,7 @@ var startTask = (ctx, _cmd, parsed) => {
18936
18736
  setTimeout(() => {
18937
18737
  for (const p2 of paths) {
18938
18738
  try {
18939
- fs35.unlinkSync(p2);
18739
+ fs34.unlinkSync(p2);
18940
18740
  } catch {
18941
18741
  }
18942
18742
  pendingAttachmentFiles.delete(p2);
@@ -19519,8 +19319,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
19519
19319
  if (args2.length === 0) return detection;
19520
19320
  const binName = args2[0];
19521
19321
  if (binName.startsWith("-")) return detection;
19522
- const binPath = path42.join(cwd, "node_modules", ".bin", binName);
19523
- if (!fs35.existsSync(binPath)) return detection;
19322
+ const binPath = path41.join(cwd, "node_modules", ".bin", binName);
19323
+ if (!fs34.existsSync(binPath)) return detection;
19524
19324
  return {
19525
19325
  ...detection,
19526
19326
  command: binPath,
@@ -19957,9 +19757,9 @@ async function dispatchCommand(ctx, cmd) {
19957
19757
 
19958
19758
  // src/services/file-watcher.service.ts
19959
19759
  var import_child_process19 = require("child_process");
19960
- var fs36 = __toESM(require("fs"));
19760
+ var fs35 = __toESM(require("fs"));
19961
19761
  var os28 = __toESM(require("os"));
19962
- var path43 = __toESM(require("path"));
19762
+ var path42 = __toESM(require("path"));
19963
19763
  var import_ignore = __toESM(require("ignore"));
19964
19764
 
19965
19765
  // src/services/file-watcher/diff-parser.ts
@@ -20102,18 +19902,18 @@ var _findGitRootSeam = {
20102
19902
  resolve: _defaultFindGitRoot
20103
19903
  };
20104
19904
  function _defaultFindGitRoot(startDir) {
20105
- let dir = path43.resolve(startDir);
19905
+ let dir = path42.resolve(startDir);
20106
19906
  const seen = /* @__PURE__ */ new Set();
20107
19907
  for (let i = 0; i < 256; i++) {
20108
19908
  if (seen.has(dir)) return null;
20109
19909
  seen.add(dir);
20110
19910
  try {
20111
- const gitPath = path43.join(dir, ".git");
20112
- const stat3 = fs36.statSync(gitPath, { throwIfNoEntry: false });
19911
+ const gitPath = path42.join(dir, ".git");
19912
+ const stat3 = fs35.statSync(gitPath, { throwIfNoEntry: false });
20113
19913
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
20114
19914
  } catch {
20115
19915
  }
20116
- const parent = path43.dirname(dir);
19916
+ const parent = path42.dirname(dir);
20117
19917
  if (parent === dir) return null;
20118
19918
  dir = parent;
20119
19919
  }
@@ -20358,7 +20158,7 @@ var FileWatcherService = class {
20358
20158
  }
20359
20159
  async emitForFile(absPath, changeType) {
20360
20160
  if (this.stopped) return;
20361
- const fileDir = path43.dirname(absPath);
20161
+ const fileDir = path42.dirname(absPath);
20362
20162
  let gitRoot = this.gitRootByDir.get(fileDir);
20363
20163
  if (gitRoot === void 0) {
20364
20164
  gitRoot = findGitRoot2(fileDir);
@@ -20371,19 +20171,19 @@ var FileWatcherService = class {
20371
20171
  );
20372
20172
  return;
20373
20173
  }
20374
- const relPathInRepo = path43.relative(gitRoot, absPath);
20174
+ const relPathInRepo = path42.relative(gitRoot, absPath);
20375
20175
  if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
20376
20176
  const matcher = this.getGitIgnoreMatcher(gitRoot);
20377
20177
  if (matcher && matcher.ignores(relPathInRepo)) {
20378
20178
  log.trace(
20379
20179
  "fileWatcher",
20380
- `${relPathInRepo} ignored by ${path43.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
20180
+ `${relPathInRepo} ignored by ${path42.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
20381
20181
  );
20382
20182
  return;
20383
20183
  }
20384
20184
  this.opts.onRepoDirty?.(gitRoot);
20385
- const repoPath = path43.relative(this.opts.workingDir, gitRoot);
20386
- const repoName = path43.basename(gitRoot);
20185
+ const repoPath = path42.relative(this.opts.workingDir, gitRoot);
20186
+ const repoName = path42.basename(gitRoot);
20387
20187
  let diffText = "";
20388
20188
  let fileStatus = "modified";
20389
20189
  if (changeType === "unlink") {
@@ -20558,7 +20358,7 @@ var FileWatcherService = class {
20558
20358
  collectGitignoreFiles(repoRoot, dir, matcher) {
20559
20359
  let entries;
20560
20360
  try {
20561
- entries = fs36.readdirSync(dir, { withFileTypes: true });
20361
+ entries = fs35.readdirSync(dir, { withFileTypes: true });
20562
20362
  } catch {
20563
20363
  return;
20564
20364
  }
@@ -20567,16 +20367,16 @@ var FileWatcherService = class {
20567
20367
  );
20568
20368
  if (gitignoreEntry) {
20569
20369
  try {
20570
- const body = fs36.readFileSync(path43.join(dir, ".gitignore"), "utf8");
20571
- const rel = path43.relative(repoRoot, dir).replace(/\\/g, "/");
20370
+ const body = fs35.readFileSync(path42.join(dir, ".gitignore"), "utf8");
20371
+ const rel = path42.relative(repoRoot, dir).replace(/\\/g, "/");
20572
20372
  const prefixed = body.split(/\r?\n/).map((line) => {
20573
20373
  const trimmed = line.trim();
20574
20374
  if (!trimmed || trimmed.startsWith("#")) return line;
20575
20375
  if (!rel) return line;
20576
20376
  if (trimmed.startsWith("!")) {
20577
- return "!" + path43.posix.join(rel, trimmed.slice(1));
20377
+ return "!" + path42.posix.join(rel, trimmed.slice(1));
20578
20378
  }
20579
- return path43.posix.join(rel, trimmed);
20379
+ return path42.posix.join(rel, trimmed);
20580
20380
  }).join("\n");
20581
20381
  matcher.add(prefixed);
20582
20382
  } catch {
@@ -20585,7 +20385,7 @@ var FileWatcherService = class {
20585
20385
  for (const entry of entries) {
20586
20386
  if (!entry.isDirectory()) continue;
20587
20387
  if (entry.name === ".git") continue;
20588
- const childAbs = path43.join(dir, entry.name);
20388
+ const childAbs = path42.join(dir, entry.name);
20589
20389
  if (isIgnoredFilePath(childAbs)) continue;
20590
20390
  this.collectGitignoreFiles(repoRoot, childAbs, matcher);
20591
20391
  }
@@ -20755,7 +20555,7 @@ var import_crypto4 = require("crypto");
20755
20555
 
20756
20556
  // src/services/turn-files/git-changeset.ts
20757
20557
  var import_child_process20 = require("child_process");
20758
- var path44 = __toESM(require("path"));
20558
+ var path43 = __toESM(require("path"));
20759
20559
  async function collectRepoChangeset(opts) {
20760
20560
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
20761
20561
  if (status2 === null) return null;
@@ -20866,7 +20666,7 @@ function defaultRunGit(cwd, args2) {
20866
20666
  });
20867
20667
  }
20868
20668
  async function discoverRepos(workingDir, maxDepth = 4) {
20869
- const fs42 = await import("fs/promises");
20669
+ const fs41 = await import("fs/promises");
20870
20670
  const out2 = [];
20871
20671
  await walk(workingDir, 0);
20872
20672
  return out2;
@@ -20874,7 +20674,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20874
20674
  if (depth > maxDepth) return;
20875
20675
  let entries = [];
20876
20676
  try {
20877
- const dirents = await fs42.readdir(dir, { withFileTypes: true });
20677
+ const dirents = await fs41.readdir(dir, { withFileTypes: true });
20878
20678
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
20879
20679
  } catch {
20880
20680
  return;
@@ -20885,8 +20685,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20885
20685
  if (hasGit) {
20886
20686
  out2.push({
20887
20687
  repoRoot: dir,
20888
- repoPath: path44.relative(workingDir, dir),
20889
- repoName: path44.basename(dir)
20688
+ repoPath: path43.relative(workingDir, dir),
20689
+ repoName: path43.basename(dir)
20890
20690
  });
20891
20691
  return;
20892
20692
  }
@@ -20894,14 +20694,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20894
20694
  if (!entry.isDirectory) continue;
20895
20695
  if (entry.name === "node_modules") continue;
20896
20696
  if (entry.name === "dist" || entry.name === "build") continue;
20897
- await walk(path44.join(dir, entry.name), depth + 1);
20697
+ await walk(path43.join(dir, entry.name), depth + 1);
20898
20698
  }
20899
20699
  }
20900
20700
  }
20901
20701
 
20902
20702
  // src/services/turn-files/files-outbox.ts
20903
- var fs37 = __toESM(require("fs/promises"));
20904
- var path45 = __toESM(require("path"));
20703
+ var fs36 = __toESM(require("fs/promises"));
20704
+ var path44 = __toESM(require("path"));
20905
20705
  var import_os7 = require("os");
20906
20706
  var HOME_OUTBOX_DIR = ".codeam/outbox";
20907
20707
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -20934,16 +20734,16 @@ var FilesOutbox = class {
20934
20734
  backoffIndex = 0;
20935
20735
  stopped = false;
20936
20736
  constructor(opts) {
20937
- const base = opts.baseDir ?? path45.join(homeDir(), HOME_OUTBOX_DIR);
20938
- this.filePath = path45.join(base, `${opts.sessionId}.jsonl`);
20737
+ const base = opts.baseDir ?? path44.join(homeDir(), HOME_OUTBOX_DIR);
20738
+ this.filePath = path44.join(base, `${opts.sessionId}.jsonl`);
20939
20739
  this.post = opts.post;
20940
20740
  this.autoSchedule = opts.autoSchedule !== false;
20941
20741
  }
20942
20742
  /** Persist the entry to disk and trigger a flush. Returns once the
20943
20743
  * line is durable on disk (not once the POST succeeds). */
20944
20744
  async enqueue(entry) {
20945
- await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
20946
- await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20745
+ await fs36.mkdir(path44.dirname(this.filePath), { recursive: true });
20746
+ await fs36.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20947
20747
  this.backoffIndex = 0;
20948
20748
  if (this.autoSchedule) this.scheduleFlush(0);
20949
20749
  }
@@ -21032,7 +20832,7 @@ var FilesOutbox = class {
21032
20832
  async readAll() {
21033
20833
  let raw = "";
21034
20834
  try {
21035
- raw = await fs37.readFile(this.filePath, "utf8");
20835
+ raw = await fs36.readFile(this.filePath, "utf8");
21036
20836
  } catch {
21037
20837
  return [];
21038
20838
  }
@@ -21056,12 +20856,12 @@ var FilesOutbox = class {
21056
20856
  async rewrite(entries) {
21057
20857
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
21058
20858
  if (entries.length === 0) {
21059
- await fs37.unlink(this.filePath).catch(() => void 0);
20859
+ await fs36.unlink(this.filePath).catch(() => void 0);
21060
20860
  return;
21061
20861
  }
21062
20862
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
21063
- await fs37.writeFile(tmpPath, payload, "utf8");
21064
- await fs37.rename(tmpPath, this.filePath);
20863
+ await fs36.writeFile(tmpPath, payload, "utf8");
20864
+ await fs36.rename(tmpPath, this.filePath);
21065
20865
  }
21066
20866
  };
21067
20867
  function applyJitter(ms) {
@@ -22158,10 +21958,10 @@ var ChromeStepTracker = class {
22158
21958
  const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
22159
21959
  if (visible.length === 0) return;
22160
21960
  for (const step of visible) {
22161
- const exists2 = this.history.some(
21961
+ const exists = this.history.some(
22162
21962
  (s) => s.tool === step.tool && s.label === step.label
22163
21963
  );
22164
- if (!exists2) this.history.push(step);
21964
+ if (!exists) this.history.push(step);
22165
21965
  }
22166
21966
  }
22167
21967
  /**
@@ -22906,8 +22706,8 @@ var OutputService = class _OutputService {
22906
22706
  };
22907
22707
 
22908
22708
  // src/services/history.service.ts
22909
- var fs38 = __toESM(require("fs"));
22910
- var path46 = __toESM(require("path"));
22709
+ var fs37 = __toESM(require("fs"));
22710
+ var path45 = __toESM(require("path"));
22911
22711
  var os29 = __toESM(require("os"));
22912
22712
  var https7 = __toESM(require("https"));
22913
22713
  var http7 = __toESM(require("http"));
@@ -22935,7 +22735,7 @@ function parseJsonl(filePath) {
22935
22735
  const messages = [];
22936
22736
  let raw;
22937
22737
  try {
22938
- raw = fs38.readFileSync(filePath, "utf8");
22738
+ raw = fs37.readFileSync(filePath, "utf8");
22939
22739
  } catch (err) {
22940
22740
  if (err.code !== "ENOENT") {
22941
22741
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -23070,7 +22870,7 @@ var HistoryService = class _HistoryService {
23070
22870
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
23071
22871
  }
23072
22872
  get projectDir() {
23073
- return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22873
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path45.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
23074
22874
  }
23075
22875
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
23076
22876
  setCurrentConversationId(id) {
@@ -23082,7 +22882,7 @@ var HistoryService = class _HistoryService {
23082
22882
  /** Return the current message count in the active conversation. */
23083
22883
  getCurrentMessageCount() {
23084
22884
  if (!this.currentConversationId) return 0;
23085
- const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22885
+ const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23086
22886
  return parseJsonl(filePath).length;
23087
22887
  }
23088
22888
  /**
@@ -23093,7 +22893,7 @@ var HistoryService = class _HistoryService {
23093
22893
  const deadline = Date.now() + timeoutMs;
23094
22894
  while (Date.now() < deadline) {
23095
22895
  if (!this.currentConversationId) return null;
23096
- const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22896
+ const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23097
22897
  const messages = parseJsonl(filePath);
23098
22898
  if (messages.length > previousCount) {
23099
22899
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -23119,16 +22919,16 @@ var HistoryService = class _HistoryService {
23119
22919
  const dir = this.projectDir;
23120
22920
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
23121
22921
  try {
23122
- const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22922
+ const files = fs37.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23123
22923
  try {
23124
- const stat3 = fs38.statSync(path46.join(dir, e.name));
22924
+ const stat3 = fs37.statSync(path45.join(dir, e.name));
23125
22925
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
23126
22926
  } catch {
23127
22927
  return { name: e.name, mtime: 0, birthtime: 0 };
23128
22928
  }
23129
22929
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
23130
22930
  if (files.length > 0) {
23131
- this.currentConversationId = path46.basename(files[0].name, ".jsonl");
22931
+ this.currentConversationId = path45.basename(files[0].name, ".jsonl");
23132
22932
  }
23133
22933
  } catch {
23134
22934
  }
@@ -23162,13 +22962,13 @@ var HistoryService = class _HistoryService {
23162
22962
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
23163
22963
  let entries;
23164
22964
  try {
23165
- entries = fs38.readdirSync(dir, { withFileTypes: true });
22965
+ entries = fs37.readdirSync(dir, { withFileTypes: true });
23166
22966
  } catch {
23167
22967
  return null;
23168
22968
  }
23169
22969
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23170
22970
  try {
23171
- const stat3 = fs38.statSync(path46.join(dir, e.name));
22971
+ const stat3 = fs37.statSync(path45.join(dir, e.name));
23172
22972
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
23173
22973
  } catch {
23174
22974
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -23177,12 +22977,12 @@ var HistoryService = class _HistoryService {
23177
22977
  if (files.length === 0) return null;
23178
22978
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
23179
22979
  if (!files.some((f) => f.name === targetFile)) return null;
23180
- return this.extractUsageFromFile(path46.join(dir, targetFile));
22980
+ return this.extractUsageFromFile(path45.join(dir, targetFile));
23181
22981
  }
23182
22982
  extractUsageFromFile(filePath) {
23183
22983
  let raw;
23184
22984
  try {
23185
- raw = fs38.readFileSync(filePath, "utf8");
22985
+ raw = fs37.readFileSync(filePath, "utf8");
23186
22986
  } catch {
23187
22987
  return null;
23188
22988
  }
@@ -23227,9 +23027,9 @@ var HistoryService = class _HistoryService {
23227
23027
  let totalCost = 0;
23228
23028
  let files;
23229
23029
  try {
23230
- files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23030
+ files = fs37.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23231
23031
  try {
23232
- return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
23032
+ return fs37.statSync(path45.join(projectDir, f)).mtimeMs >= monthStartMs;
23233
23033
  } catch {
23234
23034
  return false;
23235
23035
  }
@@ -23240,7 +23040,7 @@ var HistoryService = class _HistoryService {
23240
23040
  for (const file of files) {
23241
23041
  let raw;
23242
23042
  try {
23243
- raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
23043
+ raw = fs37.readFileSync(path45.join(projectDir, file), "utf8");
23244
23044
  } catch {
23245
23045
  continue;
23246
23046
  }
@@ -23304,7 +23104,7 @@ var HistoryService = class _HistoryService {
23304
23104
  * showing an empty conversation.
23305
23105
  */
23306
23106
  async loadConversation(sessionId) {
23307
- const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
23107
+ const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
23308
23108
  const messages = parseJsonl(filePath);
23309
23109
  if (messages.length === 0) return;
23310
23110
  const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
@@ -23358,7 +23158,7 @@ var HistoryService = class _HistoryService {
23358
23158
  if (!this.currentConversationId) return 0;
23359
23159
  }
23360
23160
  const sessionId = this.currentConversationId;
23361
- const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
23161
+ const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
23362
23162
  const messages = parseJsonl(filePath);
23363
23163
  if (messages.length === 0) return 0;
23364
23164
  const marker = this.lastUploadedUuid.get(sessionId);
@@ -24279,7 +24079,7 @@ async function autoLinkAfterPair(opts) {
24279
24079
  }
24280
24080
 
24281
24081
  // src/commands/pair-auto.ts
24282
- var fs39 = __toESM(require("fs"));
24082
+ var fs38 = __toESM(require("fs"));
24283
24083
  var os30 = __toESM(require("os"));
24284
24084
  var import_crypto7 = require("crypto");
24285
24085
 
@@ -24475,12 +24275,12 @@ function readTokenFromArgs(args2) {
24475
24275
  }
24476
24276
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
24477
24277
  if (fileFlag) {
24478
- const path53 = fileFlag.slice("--token-file=".length);
24278
+ const path52 = fileFlag.slice("--token-file=".length);
24479
24279
  try {
24480
- const content = fs39.readFileSync(path53, "utf8").trim();
24481
- if (content.length === 0) fail(`--token-file ${path53} is empty`);
24280
+ const content = fs38.readFileSync(path52, "utf8").trim();
24281
+ if (content.length === 0) fail(`--token-file ${path52} is empty`);
24482
24282
  try {
24483
- fs39.unlinkSync(path53);
24283
+ fs38.unlinkSync(path52);
24484
24284
  } catch {
24485
24285
  }
24486
24286
  return content;
@@ -24598,8 +24398,6 @@ async function pairAuto(args2) {
24598
24398
  codespaceName: process.env.CODESPACE_NAME ?? void 0
24599
24399
  });
24600
24400
  console.log(` Paired with ${claimed.user.name} (${claimed.user.plan})`);
24601
- void provisionProjectDependencies(process.cwd()).catch(() => {
24602
- });
24603
24401
  if (process.env.CODEAM_SKIP_AGENT_LAUNCH === "true") {
24604
24402
  capture("pair_auto_skipped_launch", {
24605
24403
  sessionId: claimed.sessionId,
@@ -24748,7 +24546,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
24748
24546
  var import_child_process22 = require("child_process");
24749
24547
  var import_util4 = require("util");
24750
24548
  var import_picocolors8 = __toESM(require("picocolors"));
24751
- var path47 = __toESM(require("path"));
24549
+ var path46 = __toESM(require("path"));
24752
24550
  var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
24753
24551
  var MAX_BUFFER = 8 * 1024 * 1024;
24754
24552
  function resetStdinForChild() {
@@ -25237,7 +25035,7 @@ var GitHubCodespacesProvider = class {
25237
25035
  });
25238
25036
  }
25239
25037
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
25240
- const remoteDir = path47.posix.dirname(remotePath);
25038
+ const remoteDir = path46.posix.dirname(remotePath);
25241
25039
  const parts = [
25242
25040
  `mkdir -p ${shellQuote(remoteDir)}`,
25243
25041
  `cat > ${shellQuote(remotePath)}`
@@ -25307,7 +25105,7 @@ function shellQuote(s) {
25307
25105
  // src/services/providers/gitpod.ts
25308
25106
  var import_child_process23 = require("child_process");
25309
25107
  var import_util5 = require("util");
25310
- var path48 = __toESM(require("path"));
25108
+ var path47 = __toESM(require("path"));
25311
25109
  var import_picocolors9 = __toESM(require("picocolors"));
25312
25110
  var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
25313
25111
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -25547,7 +25345,7 @@ var GitpodProvider = class {
25547
25345
  });
25548
25346
  }
25549
25347
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
25550
- const remoteDir = path48.posix.dirname(remotePath);
25348
+ const remoteDir = path47.posix.dirname(remotePath);
25551
25349
  const parts = [
25552
25350
  `mkdir -p ${shellQuote2(remoteDir)}`,
25553
25351
  `cat > ${shellQuote2(remotePath)}`
@@ -25583,7 +25381,7 @@ function shellQuote2(s) {
25583
25381
  // src/services/providers/gitlab-workspaces.ts
25584
25382
  var import_child_process24 = require("child_process");
25585
25383
  var import_util6 = require("util");
25586
- var path49 = __toESM(require("path"));
25384
+ var path48 = __toESM(require("path"));
25587
25385
  var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
25588
25386
  var MAX_BUFFER3 = 8 * 1024 * 1024;
25589
25387
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -25843,7 +25641,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25843
25641
  }
25844
25642
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
25845
25643
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
25846
- const remoteDir = path49.posix.dirname(remotePath);
25644
+ const remoteDir = path48.posix.dirname(remotePath);
25847
25645
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
25848
25646
  if (options.mode != null) {
25849
25647
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -25911,7 +25709,7 @@ function shellQuote3(s) {
25911
25709
  // src/services/providers/railway.ts
25912
25710
  var import_child_process25 = require("child_process");
25913
25711
  var import_util7 = require("util");
25914
- var path50 = __toESM(require("path"));
25712
+ var path49 = __toESM(require("path"));
25915
25713
  var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
25916
25714
  var MAX_BUFFER4 = 8 * 1024 * 1024;
25917
25715
  function resetStdinForChild4() {
@@ -26147,7 +25945,7 @@ var RailwayProvider = class {
26147
25945
  if (!projectId || !serviceId) {
26148
25946
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
26149
25947
  }
26150
- const remoteDir = path50.posix.dirname(remotePath);
25948
+ const remoteDir = path49.posix.dirname(remotePath);
26151
25949
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
26152
25950
  if (options.mode != null) {
26153
25951
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -26690,8 +26488,8 @@ async function stopWorkspaceFromLocal(target) {
26690
26488
  var import_node_dns = require("dns");
26691
26489
  var import_node_util4 = require("util");
26692
26490
  var import_node_crypto8 = require("crypto");
26693
- var fs40 = __toESM(require("fs"));
26694
- var path51 = __toESM(require("path"));
26491
+ var fs39 = __toESM(require("fs"));
26492
+ var path50 = __toESM(require("path"));
26695
26493
  var import_picocolors12 = __toESM(require("picocolors"));
26696
26494
  var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
26697
26495
  async function checkDns(apiBase) {
@@ -26747,13 +26545,13 @@ async function checkHealth(apiBase) {
26747
26545
  }
26748
26546
  }
26749
26547
  function checkConfigDir() {
26750
- const dir = path51.join(require("os").homedir(), ".codeam");
26548
+ const dir = path50.join(require("os").homedir(), ".codeam");
26751
26549
  try {
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);
26550
+ fs39.mkdirSync(dir, { recursive: true, mode: 448 });
26551
+ const probe = path50.join(dir, ".doctor-probe");
26552
+ fs39.writeFileSync(probe, "ok", { mode: 384 });
26553
+ const read = fs39.readFileSync(probe, "utf8");
26554
+ fs39.unlinkSync(probe);
26757
26555
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
26758
26556
  return {
26759
26557
  id: "config-dir",
@@ -26817,7 +26615,7 @@ function checkNodePty() {
26817
26615
  detail: "not required on this platform"
26818
26616
  };
26819
26617
  }
26820
- const vendoredPath = path51.join(__dirname, "vendor", "node-pty");
26618
+ const vendoredPath = path50.join(__dirname, "vendor", "node-pty");
26821
26619
  for (const target of [vendoredPath, "node-pty"]) {
26822
26620
  try {
26823
26621
  require(target);
@@ -26859,7 +26657,7 @@ function checkChokidar() {
26859
26657
  }
26860
26658
  async function doctor(args2 = []) {
26861
26659
  const json = args2.includes("--json");
26862
- const cliVersion = true ? "2.39.0" : "0.0.0-dev";
26660
+ const cliVersion = true ? "2.39.1" : "0.0.0-dev";
26863
26661
  const apiBase = resolveApiBaseUrl();
26864
26662
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
26865
26663
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -27058,7 +26856,7 @@ async function completion(args2) {
27058
26856
  // src/commands/version.ts
27059
26857
  var import_picocolors13 = __toESM(require("picocolors"));
27060
26858
  function version2() {
27061
- const v = true ? "2.39.0" : "unknown";
26859
+ const v = true ? "2.39.1" : "unknown";
27062
26860
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
27063
26861
  }
27064
26862
 
@@ -27186,9 +26984,9 @@ function tryShowSubcommandHelp(cmd, args2) {
27186
26984
  var _subcommandHelpKeys = Object.keys(HELPS);
27187
26985
 
27188
26986
  // src/lib/updateNotifier.ts
27189
- var fs41 = __toESM(require("fs"));
26987
+ var fs40 = __toESM(require("fs"));
27190
26988
  var os31 = __toESM(require("os"));
27191
- var path52 = __toESM(require("path"));
26989
+ var path51 = __toESM(require("path"));
27192
26990
  var https8 = __toESM(require("https"));
27193
26991
  var import_node_child_process12 = require("child_process");
27194
26992
  var import_picocolors16 = __toESM(require("picocolors"));
@@ -27197,12 +26995,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
27197
26995
  var TTL_MS = 24 * 60 * 60 * 1e3;
27198
26996
  var REQUEST_TIMEOUT_MS = 1500;
27199
26997
  function cachePath() {
27200
- const dir = path52.join(os31.homedir(), ".codeam");
27201
- return path52.join(dir, "update-check.json");
26998
+ const dir = path51.join(os31.homedir(), ".codeam");
26999
+ return path51.join(dir, "update-check.json");
27202
27000
  }
27203
27001
  function readCache() {
27204
27002
  try {
27205
- const raw = fs41.readFileSync(cachePath(), "utf8");
27003
+ const raw = fs40.readFileSync(cachePath(), "utf8");
27206
27004
  const parsed = JSON.parse(raw);
27207
27005
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
27208
27006
  return parsed;
@@ -27213,10 +27011,10 @@ function readCache() {
27213
27011
  function writeCache(cache) {
27214
27012
  try {
27215
27013
  const file = cachePath();
27216
- fs41.mkdirSync(path52.dirname(file), { recursive: true });
27014
+ fs40.mkdirSync(path51.dirname(file), { recursive: true });
27217
27015
  const tmp = `${file}.${process.pid}.tmp`;
27218
- fs41.writeFileSync(tmp, JSON.stringify(cache));
27219
- fs41.renameSync(tmp, file);
27016
+ fs40.writeFileSync(tmp, JSON.stringify(cache));
27017
+ fs40.renameSync(tmp, file);
27220
27018
  } catch {
27221
27019
  }
27222
27020
  }
@@ -27290,8 +27088,8 @@ function isLinkedInstall() {
27290
27088
  timeout: 2e3
27291
27089
  }).trim();
27292
27090
  if (!root) return false;
27293
- const pkgPath = path52.join(root, PKG_NAME);
27294
- return fs41.lstatSync(pkgPath).isSymbolicLink();
27091
+ const pkgPath = path51.join(root, PKG_NAME);
27092
+ return fs40.lstatSync(pkgPath).isSymbolicLink();
27295
27093
  } catch {
27296
27094
  return false;
27297
27095
  }
@@ -27327,7 +27125,7 @@ function maybeAutoUpdate(currentVersion, latest) {
27327
27125
  return;
27328
27126
  }
27329
27127
  try {
27330
- fs41.unlinkSync(cachePath());
27128
+ fs40.unlinkSync(cachePath());
27331
27129
  } catch {
27332
27130
  }
27333
27131
  process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
@@ -27344,7 +27142,7 @@ function checkForUpdates() {
27344
27142
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
27345
27143
  if (process.env.CI) return;
27346
27144
  if (!process.stdout.isTTY) return;
27347
- const current = true ? "2.39.0" : null;
27145
+ const current = true ? "2.39.1" : null;
27348
27146
  if (!current) return;
27349
27147
  const cache = readCache();
27350
27148
  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.0",
3
+ "version": "2.39.1",
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",