codeam-cli 2.35.9 → 2.36.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 +6 -0
  2. package/dist/index.js +599 -338
  3. package/package.json +1 -1
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.35.9",
501
+ version: "2.36.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(path50) {
1190
- return path50.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1189
+ function normalizeWindowsPath(path51) {
1190
+ return path51.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(path50, ranges, output) {
3670
+ function getContextLinesFromFile(path51, ranges, output) {
3671
3671
  return new Promise((resolve7) => {
3672
- const stream = (0, import_node_fs.createReadStream)(path50);
3672
+ const stream = (0, import_node_fs.createReadStream)(path51);
3673
3673
  const lineReaded = (0, import_node_readline.createInterface)({
3674
3674
  input: stream
3675
3675
  });
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path50, 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(path50, 1);
3687
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path51, 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(path50) {
3749
- return path50.startsWith("node:") || path50.endsWith(".min.js") || path50.endsWith(".min.cjs") || path50.endsWith(".min.mjs") || path50.startsWith("data:");
3748
+ function shouldSkipContextLinesForFile(path51) {
3749
+ return path51.startsWith("node:") || path51.endsWith(".min.js") || path51.endsWith(".min.cjs") || path51.endsWith(".min.mjs") || path51.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.35.9" : "0.0.0-dev",
5903
+ cliVersion: true ? "2.36.0" : "0.0.0-dev",
5904
5904
  nodeVersion: process.version,
5905
5905
  platform: process.platform,
5906
5906
  arch: process.arch,
@@ -7248,10 +7248,10 @@ function buildForPlatform(platform2) {
7248
7248
  var import_node_crypto4 = require("crypto");
7249
7249
 
7250
7250
  // src/agents/claude/resolver.ts
7251
- function buildClaudeLaunch(extraArgs = [], os31 = createOsStrategy()) {
7252
- const found = os31.findInPath("claude") ?? os31.findInPath("claude-code");
7251
+ function buildClaudeLaunch(extraArgs = [], os32 = createOsStrategy()) {
7252
+ const found = os32.findInPath("claude") ?? os32.findInPath("claude-code");
7253
7253
  if (!found) return null;
7254
- return os31.buildLaunch(found, extraArgs);
7254
+ return os32.buildLaunch(found, extraArgs);
7255
7255
  }
7256
7256
 
7257
7257
  // src/agents/claude/installer.ts
@@ -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 path50 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
9981
+ const path51 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
9982
9982
  return {
9983
9983
  title: "",
9984
9984
  subtitle: lines[metaIdx].trim(),
9985
- path: path50,
9985
+ path: path51,
9986
9986
  startIdx: artStart,
9987
- endIdx: metaIdx + (path50 ? 1 : 0)
9987
+ endIdx: metaIdx + (path51 ? 1 : 0)
9988
9988
  };
9989
9989
  }
9990
9990
 
@@ -9994,8 +9994,8 @@ var ClaudeRuntimeStrategy = class {
9994
9994
  meta = getAgent("claude");
9995
9995
  mode = "interactive";
9996
9996
  os;
9997
- constructor(os31) {
9998
- this.os = os31;
9997
+ constructor(os32) {
9998
+ this.os = os32;
9999
9999
  }
10000
10000
  /**
10001
10001
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -11025,8 +11025,8 @@ function codexCredentialLocator() {
11025
11025
  function codexLoginLauncher() {
11026
11026
  return {
11027
11027
  async ensureInstalled() {
11028
- const os31 = createOsStrategy();
11029
- return os31.findInPath("codex") !== null;
11028
+ const os32 = createOsStrategy();
11029
+ return os32.findInPath("codex") !== null;
11030
11030
  },
11031
11031
  launch() {
11032
11032
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -11049,8 +11049,8 @@ var CodexRuntimeStrategy = class {
11049
11049
  meta = getAgent("codex");
11050
11050
  mode = "interactive";
11051
11051
  os;
11052
- constructor(os31) {
11053
- this.os = os31;
11052
+ constructor(os32) {
11053
+ this.os = os32;
11054
11054
  }
11055
11055
  async prepareLaunch() {
11056
11056
  let binary = this.os.findInPath("codex");
@@ -11156,12 +11156,12 @@ var CodexRuntimeStrategy = class {
11156
11156
  });
11157
11157
  }
11158
11158
  };
11159
- function resolveNpm(os31) {
11160
- return os31.id === "win32" ? "npm.cmd" : "npm";
11159
+ function resolveNpm(os32) {
11160
+ return os32.id === "win32" ? "npm.cmd" : "npm";
11161
11161
  }
11162
- async function installCodexViaNpm(os31) {
11162
+ async function installCodexViaNpm(os32) {
11163
11163
  return new Promise((resolve7, reject) => {
11164
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os31), ["install", "-g", "@openai/codex"], {
11164
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os32), ["install", "-g", "@openai/codex"], {
11165
11165
  stdio: "inherit"
11166
11166
  });
11167
11167
  proc.on("close", (code) => {
@@ -11178,16 +11178,16 @@ async function installCodexViaNpm(os31) {
11178
11178
  });
11179
11179
  });
11180
11180
  }
11181
- function augmentNpmGlobalBin(os31) {
11181
+ function augmentNpmGlobalBin(os32) {
11182
11182
  try {
11183
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os31), ["prefix", "-g"], {
11183
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os32), ["prefix", "-g"], {
11184
11184
  stdio: ["ignore", "pipe", "ignore"]
11185
11185
  });
11186
11186
  if (result.status !== 0) return;
11187
11187
  const prefix = result.stdout.toString().trim();
11188
11188
  if (!prefix) return;
11189
- const binDir = os31.id === "win32" ? prefix : path17.join(prefix, "bin");
11190
- os31.augmentPath([binDir]);
11189
+ const binDir = os32.id === "win32" ? prefix : path17.join(prefix, "bin");
11190
+ os32.augmentPath([binDir]);
11191
11191
  } catch {
11192
11192
  }
11193
11193
  }
@@ -11271,9 +11271,9 @@ var import_node_child_process7 = require("child_process");
11271
11271
  // src/agents/coderabbit/installer.ts
11272
11272
  var import_node_child_process5 = require("child_process");
11273
11273
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
11274
- async function ensureCoderabbitInstalled(os31) {
11275
- if (os31.findInPath("coderabbit")) return true;
11276
- if (os31.id === "win32") {
11274
+ async function ensureCoderabbitInstalled(os32) {
11275
+ if (os32.findInPath("coderabbit")) return true;
11276
+ if (os32.id === "win32") {
11277
11277
  console.error(
11278
11278
  "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
11279
11279
  );
@@ -11288,8 +11288,8 @@ async function ensureCoderabbitInstalled(os31) {
11288
11288
  proc.on("error", () => resolve7(false));
11289
11289
  });
11290
11290
  if (!ok) return false;
11291
- os31.augmentPath([`${os31.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
11292
- return os31.findInPath("coderabbit") !== null;
11291
+ os32.augmentPath([`${os32.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
11292
+ return os32.findInPath("coderabbit") !== null;
11293
11293
  }
11294
11294
 
11295
11295
  // src/agents/coderabbit/link.ts
@@ -11316,10 +11316,10 @@ function coderabbitCredentialLocator() {
11316
11316
  extract: extractLocalCoderabbitToken
11317
11317
  };
11318
11318
  }
11319
- function coderabbitLoginLauncher(os31) {
11319
+ function coderabbitLoginLauncher(os32) {
11320
11320
  return {
11321
11321
  async ensureInstalled() {
11322
- return ensureCoderabbitInstalled(os31);
11322
+ return ensureCoderabbitInstalled(os32);
11323
11323
  },
11324
11324
  launch() {
11325
11325
  return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -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 [, path50, lineNo, sevToken, message] = m;
11346
- if (!path50 || !lineNo || !message) continue;
11345
+ const [, path51, lineNo, sevToken, message] = m;
11346
+ if (!path51 || !lineNo || !message) continue;
11347
11347
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
11348
11348
  hunks.push({
11349
- path: path50.trim(),
11349
+ path: path51.trim(),
11350
11350
  line: Number(lineNo),
11351
11351
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
11352
11352
  message: cleanedMessage
@@ -11365,8 +11365,8 @@ var CoderabbitRuntimeStrategy = class {
11365
11365
  meta = getAgent("coderabbit");
11366
11366
  mode = "batch";
11367
11367
  os;
11368
- constructor(os31) {
11369
- this.os = os31;
11368
+ constructor(os32) {
11369
+ this.os = os32;
11370
11370
  }
11371
11371
  getDefaultArgs() {
11372
11372
  return ["review"];
@@ -11481,10 +11481,10 @@ function cursorCredentialLocator() {
11481
11481
  extract: extractLocalCursorToken
11482
11482
  };
11483
11483
  }
11484
- function cursorLoginLauncher(os31) {
11484
+ function cursorLoginLauncher(os32) {
11485
11485
  return {
11486
11486
  async ensureInstalled() {
11487
- if (os31.findInPath("cursor-agent")) return true;
11487
+ if (os32.findInPath("cursor-agent")) return true;
11488
11488
  console.error(
11489
11489
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
11490
11490
  );
@@ -11546,8 +11546,8 @@ var CursorRuntimeStrategy = class {
11546
11546
  meta = getAgent("cursor");
11547
11547
  mode = "interactive";
11548
11548
  os;
11549
- constructor(os31) {
11550
- this.os = os31;
11549
+ constructor(os32) {
11550
+ this.os = os32;
11551
11551
  }
11552
11552
  async prepareLaunch() {
11553
11553
  const binary = this.os.findInPath("cursor-agent");
@@ -11667,10 +11667,10 @@ function aiderCredentialLocator() {
11667
11667
  extract: extractLocalAiderToken
11668
11668
  };
11669
11669
  }
11670
- function aiderLoginLauncher(os31) {
11670
+ function aiderLoginLauncher(os32) {
11671
11671
  return {
11672
11672
  async ensureInstalled() {
11673
- if (os31.findInPath("aider")) return true;
11673
+ if (os32.findInPath("aider")) return true;
11674
11674
  console.error(
11675
11675
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
11676
11676
  );
@@ -11680,7 +11680,7 @@ function aiderLoginLauncher(os31) {
11680
11680
  console.error(
11681
11681
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
11682
11682
  );
11683
- return (0, import_node_child_process9.spawn)(os31.id === "win32" ? "cmd.exe" : "sh", os31.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
11683
+ return (0, import_node_child_process9.spawn)(os32.id === "win32" ? "cmd.exe" : "sh", os32.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
11684
11684
  stdio: "ignore"
11685
11685
  });
11686
11686
  }
@@ -11752,8 +11752,8 @@ var AiderRuntimeStrategy = class {
11752
11752
  meta = getAgent("aider");
11753
11753
  mode = "interactive";
11754
11754
  os;
11755
- constructor(os31) {
11756
- this.os = os31;
11755
+ constructor(os32) {
11756
+ this.os = os32;
11757
11757
  }
11758
11758
  async prepareLaunch() {
11759
11759
  const binary = this.os.findInPath("aider");
@@ -11882,8 +11882,8 @@ function geminiCredentialLocator() {
11882
11882
  function geminiLoginLauncher() {
11883
11883
  return {
11884
11884
  async ensureInstalled() {
11885
- const os31 = createOsStrategy();
11886
- return os31.findInPath("gemini") !== null;
11885
+ const os32 = createOsStrategy();
11886
+ return os32.findInPath("gemini") !== null;
11887
11887
  },
11888
11888
  launch() {
11889
11889
  return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -11916,8 +11916,8 @@ var GeminiRuntimeStrategy = class {
11916
11916
  meta = getAgent("gemini");
11917
11917
  mode = "interactive";
11918
11918
  os;
11919
- constructor(os31) {
11920
- this.os = os31;
11919
+ constructor(os32) {
11920
+ this.os = os32;
11921
11921
  }
11922
11922
  async prepareLaunch() {
11923
11923
  const binary = this.os.findInPath("gemini");
@@ -12017,18 +12017,18 @@ var GeminiRuntimeStrategy = class {
12017
12017
 
12018
12018
  // src/agents/registry.ts
12019
12019
  var runtimeBuilders = {
12020
- claude: (os31) => new ClaudeRuntimeStrategy(os31),
12021
- codex: (os31) => new CodexRuntimeStrategy(os31),
12022
- coderabbit: (os31) => new CoderabbitRuntimeStrategy(os31),
12023
- cursor: (os31) => new CursorRuntimeStrategy(os31),
12024
- aider: (os31) => new AiderRuntimeStrategy(os31),
12025
- gemini: (os31) => new GeminiRuntimeStrategy(os31)
12020
+ claude: (os32) => new ClaudeRuntimeStrategy(os32),
12021
+ codex: (os32) => new CodexRuntimeStrategy(os32),
12022
+ coderabbit: (os32) => new CoderabbitRuntimeStrategy(os32),
12023
+ cursor: (os32) => new CursorRuntimeStrategy(os32),
12024
+ aider: (os32) => new AiderRuntimeStrategy(os32),
12025
+ gemini: (os32) => new GeminiRuntimeStrategy(os32)
12026
12026
  };
12027
12027
  var deployBuilders = {
12028
12028
  claude: () => new ClaudeDeployStrategy(),
12029
12029
  codex: () => new CodexDeployStrategy()
12030
12030
  };
12031
- function createAgentStrategy(agent, os31 = createOsStrategy()) {
12031
+ function createAgentStrategy(agent, os32 = createOsStrategy()) {
12032
12032
  if (!AGENT_REGISTRY[agent]?.enabled) {
12033
12033
  throw new Error(
12034
12034
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -12038,10 +12038,10 @@ function createAgentStrategy(agent, os31 = createOsStrategy()) {
12038
12038
  if (!build) {
12039
12039
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
12040
12040
  }
12041
- return build(os31);
12041
+ return build(os32);
12042
12042
  }
12043
- function createInteractiveAgentStrategy(agent, os31 = createOsStrategy()) {
12044
- const s = createAgentStrategy(agent, os31);
12043
+ function createInteractiveAgentStrategy(agent, os32 = createOsStrategy()) {
12044
+ const s = createAgentStrategy(agent, os32);
12045
12045
  if (s.mode !== "interactive") {
12046
12046
  throw new Error(
12047
12047
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -15830,11 +15830,11 @@ function extractSelectPrompt(text) {
15830
15830
  }
15831
15831
 
15832
15832
  // src/commands/start/handlers.ts
15833
- var fs32 = __toESM(require("fs"));
15834
- var os26 = __toESM(require("os"));
15835
- var path39 = __toESM(require("path"));
15833
+ var fs33 = __toESM(require("fs"));
15834
+ var os27 = __toESM(require("os"));
15835
+ var path40 = __toESM(require("path"));
15836
15836
  var import_crypto3 = require("crypto");
15837
- var import_child_process17 = require("child_process");
15837
+ var import_child_process18 = require("child_process");
15838
15838
 
15839
15839
  // src/lib/payload.ts
15840
15840
  var import_zod = require("zod");
@@ -17509,7 +17509,8 @@ var BdAdapter = class {
17509
17509
  }
17510
17510
  const env = { ...process.env };
17511
17511
  env.BEADS_DIR = this.opts.beadsDir ?? defaultBeadsHomeDir();
17512
- log.trace("beads", `bd ${args2.join(" ")} (BEADS_DIR=${env.BEADS_DIR})`);
17512
+ env.BEADS_DOLT_SHARED_SERVER = "1";
17513
+ log.trace("beads", `bd ${args2.join(" ")} (BEADS_DIR=${env.BEADS_DIR}, shared-server)`);
17513
17514
  return _spawnSeam.run(binary, args2, { cwd: this.opts.cwd, env });
17514
17515
  }
17515
17516
  /**
@@ -17583,10 +17584,10 @@ function defaultBeadsHomeDir() {
17583
17584
  }
17584
17585
 
17585
17586
  // src/beads/provisioner.ts
17586
- var import_child_process15 = require("child_process");
17587
- var fs30 = __toESM(require("fs"));
17588
- var os25 = __toESM(require("os"));
17589
- var path36 = __toESM(require("path"));
17587
+ var import_child_process17 = require("child_process");
17588
+ var fs32 = __toESM(require("fs"));
17589
+ var os26 = __toESM(require("os"));
17590
+ var path38 = __toESM(require("path"));
17590
17591
 
17591
17592
  // src/beads/install-bd.ts
17592
17593
  var import_child_process14 = require("child_process");
@@ -17649,6 +17650,312 @@ async function installBd(platform2 = process.platform) {
17649
17650
  return result;
17650
17651
  }
17651
17652
 
17653
+ // src/beads/install-dolt.ts
17654
+ var import_child_process15 = require("child_process");
17655
+ var fs30 = __toESM(require("fs"));
17656
+ var os25 = __toESM(require("os"));
17657
+ var path36 = __toESM(require("path"));
17658
+ var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17659
+ var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
17660
+ function resolveDoltInstallStrategy(platform2) {
17661
+ if (platform2 === "win32") {
17662
+ const script = [
17663
+ `$ErrorActionPreference='Stop';`,
17664
+ `$u='${DOLT_MSI_URL}';`,
17665
+ `$o="$env:TEMP\\dolt-install.msi";`,
17666
+ `Invoke-WebRequest -Uri $u -OutFile $o;`,
17667
+ `Start-Process msiexec.exe -ArgumentList '/i',('"'+$o+'"'),'/quiet','/norestart' -Wait`
17668
+ ].join(" ");
17669
+ return {
17670
+ command: "powershell.exe",
17671
+ args: [
17672
+ "-NoProfile",
17673
+ "-NonInteractive",
17674
+ "-ExecutionPolicy",
17675
+ "Bypass",
17676
+ "-Command",
17677
+ script
17678
+ ],
17679
+ description: "PowerShell: download official dolt MSI + silent msiexec"
17680
+ };
17681
+ }
17682
+ if (platform2 === "darwin") {
17683
+ return {
17684
+ command: "brew",
17685
+ args: ["install", "dolt"],
17686
+ description: "brew install dolt"
17687
+ };
17688
+ }
17689
+ return {
17690
+ command: "bash",
17691
+ args: ["-c", `curl -L ${DOLT_INSTALL_SH_URL} | sudo bash`],
17692
+ description: `curl -L ${DOLT_INSTALL_SH_URL} | sudo bash (\u2192 /usr/local/bin)`
17693
+ };
17694
+ }
17695
+ var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
17696
+ function doltPlatformTuple(platform2, arch) {
17697
+ const os32 = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "darwin" : "linux";
17698
+ const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
17699
+ if (!a) return null;
17700
+ if (os32 === "windows" && a !== "amd64") return null;
17701
+ return `${os32}-${a}`;
17702
+ }
17703
+ function resolveDoltTarballStrategy(targetDir, platform2, arch) {
17704
+ const tuple = doltPlatformTuple(platform2, arch);
17705
+ if (!tuple) return null;
17706
+ if (platform2 === "win32") {
17707
+ const url2 = `${DOLT_RELEASE_BASE}/dolt-${tuple}.zip`;
17708
+ const script = [
17709
+ `$ErrorActionPreference='Stop';`,
17710
+ `New-Item -ItemType Directory -Force -Path '${targetDir}' | Out-Null;`,
17711
+ `$u='${url2}';`,
17712
+ `$o="$env:TEMP\\dolt-cs.zip";`,
17713
+ `Invoke-WebRequest -Uri $u -OutFile $o;`,
17714
+ `$x="$env:TEMP\\dolt-cs";`,
17715
+ `Expand-Archive -Path $o -DestinationPath $x -Force;`,
17716
+ `Copy-Item "$x\\dolt-${tuple}\\bin\\dolt.exe" '${targetDir}\\dolt.exe' -Force`
17717
+ ].join(" ");
17718
+ return {
17719
+ command: "powershell.exe",
17720
+ args: ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", script],
17721
+ description: `download dolt ${tuple} zip \u2192 ${targetDir} (no sudo)`
17722
+ };
17723
+ }
17724
+ const url = `${DOLT_RELEASE_BASE}/dolt-${tuple}.tar.gz`;
17725
+ const cmd = `mkdir -p "${targetDir}" && curl -fsSL "${url}" | tar -xz -C "${targetDir}" --strip-components=2 "dolt-${tuple}/bin/dolt" && chmod +x "${targetDir}/dolt"`;
17726
+ return {
17727
+ command: "bash",
17728
+ args: ["-c", cmd],
17729
+ description: `download dolt ${tuple} tarball \u2192 ${targetDir} (no sudo)`
17730
+ };
17731
+ }
17732
+ async function installDoltToDir(targetDir, platform2 = process.platform, arch = process.arch) {
17733
+ const strategy = resolveDoltTarballStrategy(targetDir, platform2, arch);
17734
+ if (!strategy) {
17735
+ log.warn("beads", `no dolt prebuilt for ${platform2}/${arch} \u2014 cannot fall back`);
17736
+ return { ok: false, code: -1, stderr: `unsupported platform ${platform2}/${arch}` };
17737
+ }
17738
+ log.info("beads", `dolt fallback: ${strategy.description}`);
17739
+ const result = await _doltInstallSpawnSeam.run(strategy);
17740
+ if (!result.ok) {
17741
+ log.warn("beads", `dolt tarball fallback failed (code=${result.code}): ${result.stderr.slice(0, 200)}`);
17742
+ }
17743
+ return result;
17744
+ }
17745
+ var _doltPathSeam = {
17746
+ homedir: () => os25.homedir(),
17747
+ getPath: () => process.env.PATH ?? "",
17748
+ setPath: (p2) => {
17749
+ process.env.PATH = p2;
17750
+ },
17751
+ exists: (p2) => {
17752
+ try {
17753
+ fs30.accessSync(p2, fs30.constants.F_OK);
17754
+ return true;
17755
+ } catch {
17756
+ return false;
17757
+ }
17758
+ }
17759
+ };
17760
+ function doltBinaryNames(platform2) {
17761
+ return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
17762
+ }
17763
+ function knownDoltDirs(platform2) {
17764
+ const P3 = platform2 === "win32" ? path36.win32 : path36.posix;
17765
+ const home = _doltPathSeam.homedir();
17766
+ if (platform2 === "win32") {
17767
+ return [
17768
+ "C:\\Program Files\\Dolt\\bin",
17769
+ home ? P3.join(home, "AppData", "Local", "Programs", "dolt", "bin") : ""
17770
+ ].filter(Boolean);
17771
+ }
17772
+ return [
17773
+ "/usr/local/bin",
17774
+ "/opt/homebrew/bin",
17775
+ home ? P3.join(home, ".local", "bin") : "",
17776
+ home ? P3.join(home, "bin") : ""
17777
+ ].filter(Boolean);
17778
+ }
17779
+ function ensureDoltResolvable(platform2 = process.platform) {
17780
+ const P3 = platform2 === "win32" ? path36.win32 : path36.posix;
17781
+ const delim = platform2 === "win32" ? ";" : ":";
17782
+ const names = doltBinaryNames(platform2);
17783
+ const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
17784
+ for (const dir of pathDirs) {
17785
+ for (const n of names) {
17786
+ if (_doltPathSeam.exists(P3.join(dir, n))) return true;
17787
+ }
17788
+ }
17789
+ for (const dir of knownDoltDirs(platform2)) {
17790
+ for (const n of names) {
17791
+ if (_doltPathSeam.exists(P3.join(dir, n))) {
17792
+ _doltPathSeam.setPath(`${dir}${delim}${_doltPathSeam.getPath()}`);
17793
+ log.info("beads", `dolt found in ${dir} (not on PATH) \u2014 prepended to process PATH`);
17794
+ return true;
17795
+ }
17796
+ }
17797
+ }
17798
+ return false;
17799
+ }
17800
+ var _doltInstallSpawnSeam = {
17801
+ run: _defaultDoltInstallSpawn
17802
+ };
17803
+ function _defaultDoltInstallSpawn(strategy) {
17804
+ return new Promise((resolve7) => {
17805
+ let proc;
17806
+ try {
17807
+ proc = (0, import_child_process15.spawn)(strategy.command, strategy.args, { env: process.env });
17808
+ } catch (err) {
17809
+ resolve7({ ok: false, code: -1, stderr: err.message });
17810
+ return;
17811
+ }
17812
+ let stderr = "";
17813
+ proc.stderr?.on("data", (c2) => {
17814
+ stderr += c2.toString();
17815
+ });
17816
+ proc.on("error", (err) => resolve7({ ok: false, code: -1, stderr: err.message }));
17817
+ proc.on("close", (code) => resolve7({ ok: code === 0, code: code ?? -1, stderr }));
17818
+ });
17819
+ }
17820
+ async function installDolt(platform2 = process.platform) {
17821
+ const strategy = resolveDoltInstallStrategy(platform2);
17822
+ log.info("beads", `installing dolt via ${strategy.description}`);
17823
+ const result = await _doltInstallSpawnSeam.run(strategy);
17824
+ if (!result.ok) {
17825
+ log.warn(
17826
+ "beads",
17827
+ `dolt install failed (code=${result.code}): ${result.stderr.slice(0, 200)}`
17828
+ );
17829
+ }
17830
+ return result;
17831
+ }
17832
+
17833
+ // src/beads/dolt-daemon.ts
17834
+ var _daemonSeam = {
17835
+ /**
17836
+ * Parse `bd dolt status` stdout. Running blocks lead with
17837
+ * `Dolt server: running`; down blocks say `Dolt server: not running`.
17838
+ * Match the affirmative form explicitly so "not running" can't false-positive.
17839
+ */
17840
+ isRunning: (statusStdout) => /Dolt server:\s*running/i.test(statusStdout)
17841
+ };
17842
+ async function ensureSharedServer(adapter) {
17843
+ const status2 = await adapter.run(["dolt", "status"]);
17844
+ if (status2.code === 0 && _daemonSeam.isRunning(status2.stdout)) {
17845
+ log.trace("beads", "shared dolt sql-server already running \u2014 reusing");
17846
+ return { up: true, started: false };
17847
+ }
17848
+ log.info("beads", "shared dolt sql-server not running \u2014 starting (detached)");
17849
+ const start2 = await adapter.run(["dolt", "start"]);
17850
+ if (start2.code !== 0) {
17851
+ log.warn(
17852
+ "beads",
17853
+ `bd dolt start failed (code=${start2.code}): ${start2.stderr.slice(0, 200)} \u2014 beads memory unavailable this run`
17854
+ );
17855
+ return { up: false, started: false };
17856
+ }
17857
+ const recheck = await adapter.run(["dolt", "status"]);
17858
+ const up = recheck.code === 0 && _daemonSeam.isRunning(recheck.stdout);
17859
+ if (!up) {
17860
+ log.warn("beads", "shared dolt sql-server still not reachable after start \u2014 non-fatal");
17861
+ }
17862
+ return { up, started: up };
17863
+ }
17864
+
17865
+ // src/beads/project-key.ts
17866
+ var import_child_process16 = require("child_process");
17867
+ var crypto2 = __toESM(require("crypto"));
17868
+ var fs31 = __toESM(require("fs"));
17869
+ var path37 = __toESM(require("path"));
17870
+ function normalizeOrigin(raw) {
17871
+ const trimmed = raw.trim();
17872
+ if (!trimmed) return null;
17873
+ let host;
17874
+ let pathPart;
17875
+ const scpLike = /^[^/@]+@([^:]+):(.+)$/.exec(trimmed);
17876
+ if (scpLike && !trimmed.includes("://")) {
17877
+ host = scpLike[1];
17878
+ pathPart = scpLike[2];
17879
+ } else {
17880
+ let url;
17881
+ try {
17882
+ url = new URL(trimmed);
17883
+ } catch {
17884
+ return null;
17885
+ }
17886
+ host = url.hostname;
17887
+ pathPart = url.pathname;
17888
+ }
17889
+ host = host.toLowerCase();
17890
+ pathPart = pathPart.replace(/^\/+/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
17891
+ if (!host || !pathPart) return null;
17892
+ return `${host}/${pathPart}`;
17893
+ }
17894
+ function findRepoRoot(cwd) {
17895
+ let dir = path37.resolve(cwd);
17896
+ const seen = /* @__PURE__ */ new Set();
17897
+ for (let i = 0; i < 256; i++) {
17898
+ if (seen.has(dir)) return null;
17899
+ seen.add(dir);
17900
+ try {
17901
+ const stat3 = fs31.statSync(path37.join(dir, ".git"), { throwIfNoEntry: false });
17902
+ if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
17903
+ } catch {
17904
+ }
17905
+ const parent = path37.dirname(dir);
17906
+ if (parent === dir) return null;
17907
+ dir = parent;
17908
+ }
17909
+ return null;
17910
+ }
17911
+ var _execSeam2 = {
17912
+ exec: (file, args2, opts) => {
17913
+ const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
17914
+ return typeof out2 === "string" ? out2 : out2.toString("utf8");
17915
+ },
17916
+ realpath: (p2) => fs31.realpathSync(p2)
17917
+ };
17918
+ function readOrigin(cwd) {
17919
+ try {
17920
+ const raw = _execSeam2.exec("git", ["remote", "get-url", "origin"], {
17921
+ cwd,
17922
+ timeout: 1e3,
17923
+ stdio: ["ignore", "pipe", "ignore"],
17924
+ encoding: "utf8"
17925
+ });
17926
+ return raw.trim() || null;
17927
+ } catch {
17928
+ return null;
17929
+ }
17930
+ }
17931
+ function deriveProjectIdentity(cwd = process.cwd()) {
17932
+ const repoRoot = findRepoRoot(cwd) ?? cwd;
17933
+ const origin = readOrigin(repoRoot);
17934
+ const normalized = origin ? normalizeOrigin(origin) : null;
17935
+ if (normalized) {
17936
+ const label = normalized.split("/").pop() || normalized;
17937
+ return { projectKey: normalized, projectLabel: label };
17938
+ }
17939
+ let real = repoRoot;
17940
+ try {
17941
+ real = _execSeam2.realpath(repoRoot);
17942
+ } catch {
17943
+ }
17944
+ const hash = crypto2.createHash("sha256").update(real).digest("hex");
17945
+ return { projectKey: `path:${hash}`, projectLabel: path37.basename(real) || "project" };
17946
+ }
17947
+
17948
+ // src/beads/project-prefix.ts
17949
+ var crypto3 = __toESM(require("crypto"));
17950
+ function prefixForProjectKey(projectKey) {
17951
+ const tail = projectKey.split("/").pop() ?? projectKey;
17952
+ let slug = tail.toLowerCase().replace(/\.git$/, "").replace(/[^a-z0-9]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
17953
+ if (!slug || !/^[a-z]/.test(slug)) slug = `p_${slug}`;
17954
+ slug = slug.replace(/_$/, "").slice(0, 24).replace(/_$/, "");
17955
+ const hash = crypto3.createHash("sha256").update(projectKey).digest("hex").slice(0, 8);
17956
+ return `${slug}_${hash}`;
17957
+ }
17958
+
17652
17959
  // src/beads/provisioner.ts
17653
17960
  var AGENT_SETUP_RECIPE = {
17654
17961
  claude: "claude",
@@ -17661,7 +17968,15 @@ var AGENT_SETUP_RECIPE = {
17661
17968
  };
17662
17969
  var _provisionSeam = {
17663
17970
  install: installBd,
17664
- homeBrainInitialized,
17971
+ installDolt,
17972
+ /** No-sudo fallback: extract the dolt tarball/zip into a user-writable dir. */
17973
+ installDoltToDir,
17974
+ // Probe dolt on PATH AND auto-prepend a known install dir if found off-PATH
17975
+ // (codespace: official install.sh drops dolt in /usr/local/bin, which the
17976
+ // bundled-node CLI's PATH can omit — mirrors the bd-on-PATH symlink fix).
17977
+ doltOnPath: ensureDoltResolvable,
17978
+ ensureSharedServer,
17979
+ deriveProjectIdentity,
17665
17980
  /** GAP 1 — symlink the resolved bd onto PATH for the agent's own shell. */
17666
17981
  linkBdOntoPath,
17667
17982
  /** Silence bd's `beads.role not configured` warning. */
@@ -17669,17 +17984,17 @@ var _provisionSeam = {
17669
17984
  };
17670
17985
  var _linkSeam = {
17671
17986
  platform: () => process.platform,
17672
- homedir: () => os25.homedir(),
17987
+ homedir: () => os26.homedir(),
17673
17988
  isWritableDir: (dir) => {
17674
17989
  try {
17675
- fs30.accessSync(dir, fs30.constants.W_OK);
17990
+ fs32.accessSync(dir, fs32.constants.W_OK);
17676
17991
  return true;
17677
17992
  } catch {
17678
17993
  return false;
17679
17994
  }
17680
17995
  },
17681
17996
  ensureDir: (dir) => {
17682
- fs30.mkdirSync(dir, { recursive: true });
17997
+ fs32.mkdirSync(dir, { recursive: true });
17683
17998
  },
17684
17999
  /**
17685
18000
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -17700,12 +18015,12 @@ var _linkSeam = {
17700
18015
  * which `linkBdOntoPath` creates if missing.
17701
18016
  */
17702
18017
  cliBinDir: () => {
17703
- const pathDirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
18018
+ const pathDirs = (process.env.PATH ?? "").split(path38.delimiter).filter(Boolean);
17704
18019
  const home = _linkSeam.homedir();
17705
- const localBin = home ? path36.join(home, ".local", "bin") : null;
18020
+ const localBin = home ? path38.join(home, ".local", "bin") : null;
17706
18021
  const candidates = [];
17707
18022
  try {
17708
- candidates.push(path36.dirname(process.execPath));
18023
+ candidates.push(path38.dirname(process.execPath));
17709
18024
  } catch {
17710
18025
  }
17711
18026
  if (localBin) candidates.push(localBin);
@@ -17713,9 +18028,9 @@ var _linkSeam = {
17713
18028
  const entry = process.argv[1];
17714
18029
  if (entry) {
17715
18030
  try {
17716
- candidates.push(path36.dirname(fs30.realpathSync(entry)));
18031
+ candidates.push(path38.dirname(fs32.realpathSync(entry)));
17717
18032
  } catch {
17718
- candidates.push(path36.dirname(entry));
18033
+ candidates.push(path38.dirname(entry));
17719
18034
  }
17720
18035
  }
17721
18036
  const onPathWritable = candidates.find(
@@ -17727,20 +18042,20 @@ var _linkSeam = {
17727
18042
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
17728
18043
  readlink: (linkPath) => {
17729
18044
  try {
17730
- return fs30.readlinkSync(linkPath);
18045
+ return fs32.readlinkSync(linkPath);
17731
18046
  } catch {
17732
18047
  return null;
17733
18048
  }
17734
18049
  },
17735
- unlink: (linkPath) => fs30.unlinkSync(linkPath),
17736
- symlink: (target, linkPath) => fs30.symlinkSync(target, linkPath)
18050
+ unlink: (linkPath) => fs32.unlinkSync(linkPath),
18051
+ symlink: (target, linkPath) => fs32.symlinkSync(target, linkPath)
17737
18052
  };
17738
18053
  function linkBdOntoPath(binaryPath) {
17739
18054
  if (_linkSeam.platform() === "win32") return;
17740
18055
  const binDir = _linkSeam.cliBinDir();
17741
18056
  if (!binDir) return;
17742
18057
  _linkSeam.ensureDir(binDir);
17743
- const linkPath = path36.join(binDir, "bd");
18058
+ const linkPath = path38.join(binDir, "bd");
17744
18059
  if (linkPath === binaryPath) return;
17745
18060
  const current = _linkSeam.readlink(linkPath);
17746
18061
  if (current === binaryPath) return;
@@ -17749,22 +18064,17 @@ function linkBdOntoPath(binaryPath) {
17749
18064
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
17750
18065
  }
17751
18066
  function setGitBeadsRole() {
17752
- (0, import_child_process15.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
18067
+ (0, import_child_process17.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
17753
18068
  stdio: "ignore"
17754
18069
  });
17755
18070
  }
17756
- function homeBrainInitialized(beadsDir) {
17757
- try {
17758
- return fs30.statSync(path36.join(beadsDir, "embeddeddolt")).isDirectory();
17759
- } catch {
17760
- return false;
17761
- }
17762
- }
17763
18071
  async function provisionBeads(opts = {}) {
17764
18072
  const bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
17765
- const beadsDir = opts.beadsDir ?? defaultBeadsHomeDir();
17766
18073
  const result = {
17767
18074
  bdAvailable: false,
18075
+ doltAvailable: false,
18076
+ serverUp: false,
18077
+ prefix: null,
17768
18078
  initialized: false,
17769
18079
  exportEnabled: false,
17770
18080
  agentsWired: []
@@ -17795,24 +18105,57 @@ async function provisionBeads(opts = {}) {
17795
18105
  } catch (err) {
17796
18106
  log.trace("beads", `git config beads.role failed (non-fatal): ${err.message}`);
17797
18107
  }
17798
- if (_provisionSeam.homeBrainInitialized(beadsDir)) {
17799
- log.trace("beads", `home brain already initialized at ${beadsDir}`);
17800
- result.initialized = true;
17801
- } else {
17802
- log.info("beads", `initializing home brain at ${beadsDir}`);
17803
- const init = await bd.run(["init", "--skip-agents", "--skip-hooks", "--non-interactive"]);
17804
- if (init.code !== 0) {
17805
- log.warn("beads", `bd init failed (code=${init.code}): ${init.stderr.slice(0, 200)}`);
17806
- return result;
18108
+ if (!_provisionSeam.doltOnPath()) {
18109
+ log.info("beads", "dolt binary missing \u2014 running per-OS dolt installer");
18110
+ await _provisionSeam.installDolt();
18111
+ }
18112
+ if (!_provisionSeam.doltOnPath()) {
18113
+ const dir = _linkSeam.cliBinDir();
18114
+ if (dir) {
18115
+ try {
18116
+ _linkSeam.ensureDir(dir);
18117
+ } catch {
18118
+ }
18119
+ log.info("beads", `dolt still missing \u2014 no-sudo tarball fallback into ${dir}`);
18120
+ await _provisionSeam.installDoltToDir(dir);
17807
18121
  }
17808
- result.initialized = true;
17809
18122
  }
18123
+ if (!_provisionSeam.doltOnPath()) {
18124
+ log.warn("beads", "dolt unavailable after install + tarball fallback \u2014 beads memory disabled this run");
18125
+ return result;
18126
+ }
18127
+ result.doltAvailable = true;
18128
+ const server = await _provisionSeam.ensureSharedServer(bd);
18129
+ result.serverUp = server.up;
18130
+ if (!server.up) {
18131
+ log.warn("beads", "shared dolt sql-server not up \u2014 beads disabled this run");
18132
+ return result;
18133
+ }
18134
+ const { projectKey } = _provisionSeam.deriveProjectIdentity(opts.cwd);
18135
+ const prefix = prefixForProjectKey(projectKey);
18136
+ result.prefix = prefix;
18137
+ log.info("beads", `initializing shared-server prefix DB '${prefix}' (projectKey=${projectKey})`);
18138
+ const init = await bd.run([
18139
+ "init",
18140
+ "-p",
18141
+ prefix,
18142
+ "--shared-server",
18143
+ "--skip-agents",
18144
+ "--skip-hooks",
18145
+ "--non-interactive"
18146
+ ]);
18147
+ const alreadyInit = /already initialized|already exists/i.test(init.stderr + init.stdout);
18148
+ if (init.code !== 0 && !alreadyInit) {
18149
+ log.warn("beads", `bd init -p ${prefix} failed (code=${init.code}): ${init.stderr.slice(0, 200)}`);
18150
+ return result;
18151
+ }
18152
+ result.initialized = true;
17810
18153
  const exp = await bd.run(["config", "set", "export.auto", "true"]);
17811
18154
  result.exportEnabled = exp.code === 0;
17812
18155
  result.agentsWired = await setupAgents(bd, opts.agents ?? []);
17813
18156
  log.info(
17814
18157
  "beads",
17815
- `provision done initialized=${result.initialized} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
18158
+ `provision done dolt=${result.doltAvailable} server=${result.serverUp} prefix=${result.prefix} initialized=${result.initialized} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
17816
18159
  );
17817
18160
  return result;
17818
18161
  }
@@ -17852,91 +18195,8 @@ function dedupeRecipes(agents) {
17852
18195
  }
17853
18196
 
17854
18197
  // src/beads/watcher.ts
17855
- var crypto3 = __toESM(require("crypto"));
17856
- var path38 = __toESM(require("path"));
17857
-
17858
- // src/beads/project-key.ts
17859
- var import_child_process16 = require("child_process");
17860
- var crypto2 = __toESM(require("crypto"));
17861
- var fs31 = __toESM(require("fs"));
17862
- var path37 = __toESM(require("path"));
17863
- function normalizeOrigin(raw) {
17864
- const trimmed = raw.trim();
17865
- if (!trimmed) return null;
17866
- let host;
17867
- let pathPart;
17868
- const scpLike = /^[^/@]+@([^:]+):(.+)$/.exec(trimmed);
17869
- if (scpLike && !trimmed.includes("://")) {
17870
- host = scpLike[1];
17871
- pathPart = scpLike[2];
17872
- } else {
17873
- let url;
17874
- try {
17875
- url = new URL(trimmed);
17876
- } catch {
17877
- return null;
17878
- }
17879
- host = url.hostname;
17880
- pathPart = url.pathname;
17881
- }
17882
- host = host.toLowerCase();
17883
- pathPart = pathPart.replace(/^\/+/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
17884
- if (!host || !pathPart) return null;
17885
- return `${host}/${pathPart}`;
17886
- }
17887
- function findRepoRoot(cwd) {
17888
- let dir = path37.resolve(cwd);
17889
- const seen = /* @__PURE__ */ new Set();
17890
- for (let i = 0; i < 256; i++) {
17891
- if (seen.has(dir)) return null;
17892
- seen.add(dir);
17893
- try {
17894
- const stat3 = fs31.statSync(path37.join(dir, ".git"), { throwIfNoEntry: false });
17895
- if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
17896
- } catch {
17897
- }
17898
- const parent = path37.dirname(dir);
17899
- if (parent === dir) return null;
17900
- dir = parent;
17901
- }
17902
- return null;
17903
- }
17904
- var _execSeam2 = {
17905
- exec: (file, args2, opts) => {
17906
- const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
17907
- return typeof out2 === "string" ? out2 : out2.toString("utf8");
17908
- },
17909
- realpath: (p2) => fs31.realpathSync(p2)
17910
- };
17911
- function readOrigin(cwd) {
17912
- try {
17913
- const raw = _execSeam2.exec("git", ["remote", "get-url", "origin"], {
17914
- cwd,
17915
- timeout: 1e3,
17916
- stdio: ["ignore", "pipe", "ignore"],
17917
- encoding: "utf8"
17918
- });
17919
- return raw.trim() || null;
17920
- } catch {
17921
- return null;
17922
- }
17923
- }
17924
- function deriveProjectIdentity(cwd = process.cwd()) {
17925
- const repoRoot = findRepoRoot(cwd) ?? cwd;
17926
- const origin = readOrigin(repoRoot);
17927
- const normalized = origin ? normalizeOrigin(origin) : null;
17928
- if (normalized) {
17929
- const label = normalized.split("/").pop() || normalized;
17930
- return { projectKey: normalized, projectLabel: label };
17931
- }
17932
- let real = repoRoot;
17933
- try {
17934
- real = _execSeam2.realpath(repoRoot);
17935
- } catch {
17936
- }
17937
- const hash = crypto2.createHash("sha256").update(real).digest("hex");
17938
- return { projectKey: `path:${hash}`, projectLabel: path37.basename(real) || "project" };
17939
- }
18198
+ var crypto4 = __toESM(require("crypto"));
18199
+ var path39 = __toESM(require("path"));
17940
18200
 
17941
18201
  // src/services/file-watcher/transport.ts
17942
18202
  var http5 = __toESM(require("http"));
@@ -18011,7 +18271,7 @@ var BeadsWatcher = class {
18011
18271
  constructor(opts) {
18012
18272
  this.opts = opts;
18013
18273
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
18014
- this.feedPath = opts.feedPath ?? path38.join(defaultBeadsHomeDir(), "issues.jsonl");
18274
+ this.feedPath = opts.feedPath ?? path39.join(defaultBeadsHomeDir(), "issues.jsonl");
18015
18275
  this.apiBase = opts.apiBaseUrl ?? API_BASE4;
18016
18276
  }
18017
18277
  opts;
@@ -18107,7 +18367,7 @@ var BeadsWatcher = class {
18107
18367
  summary: summary ?? ZERO_SUMMARY
18108
18368
  };
18109
18369
  const body = JSON.stringify(payload);
18110
- const hash = crypto3.createHash("sha256").update(body).digest("hex");
18370
+ const hash = crypto4.createHash("sha256").update(body).digest("hex");
18111
18371
  if (hash === this.lastPushedHash) {
18112
18372
  log.trace("beads", "snapshot unchanged \u2014 skipping push");
18113
18373
  return;
@@ -18225,6 +18485,7 @@ async function provisionBeadsForStart(ctx) {
18225
18485
  return null;
18226
18486
  }
18227
18487
  process.env.BEADS_DIR = defaultBeadsHomeDir();
18488
+ process.env.BEADS_DOLT_SHARED_SERVER = "1";
18228
18489
  if (!ctx.pluginAuthToken) {
18229
18490
  log.trace("beads", "no pluginAuthToken \u2014 beads off");
18230
18491
  return null;
@@ -18288,7 +18549,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18288
18549
  function cleanupAttachmentTempFiles() {
18289
18550
  for (const p2 of pendingAttachmentFiles) {
18290
18551
  try {
18291
- fs32.unlinkSync(p2);
18552
+ fs33.unlinkSync(p2);
18292
18553
  } catch {
18293
18554
  }
18294
18555
  }
@@ -18297,8 +18558,8 @@ function cleanupAttachmentTempFiles() {
18297
18558
  function saveFilesTemp(files) {
18298
18559
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18299
18560
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18300
- const tmpPath = path39.join(os26.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18301
- fs32.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18561
+ const tmpPath = path40.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18562
+ fs33.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18302
18563
  pendingAttachmentFiles.add(tmpPath);
18303
18564
  return tmpPath;
18304
18565
  });
@@ -18318,7 +18579,7 @@ var startTask = (ctx, _cmd, parsed) => {
18318
18579
  setTimeout(() => {
18319
18580
  for (const p2 of paths) {
18320
18581
  try {
18321
- fs32.unlinkSync(p2);
18582
+ fs33.unlinkSync(p2);
18322
18583
  } catch {
18323
18584
  }
18324
18585
  pendingAttachmentFiles.delete(p2);
@@ -18443,7 +18704,7 @@ var sessionTerminated = async (ctx, cmd) => {
18443
18704
  } catch {
18444
18705
  }
18445
18706
  try {
18446
- const proc = (0, import_child_process17.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18707
+ const proc = (0, import_child_process18.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18447
18708
  detached: true,
18448
18709
  stdio: "ignore"
18449
18710
  });
@@ -18465,7 +18726,7 @@ var shutdownSession = async (ctx, cmd) => {
18465
18726
  }
18466
18727
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
18467
18728
  try {
18468
- const stopProc = (0, import_child_process17.spawn)(
18729
+ const stopProc = (0, import_child_process18.spawn)(
18469
18730
  "bash",
18470
18731
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
18471
18732
  { detached: true, stdio: "ignore" }
@@ -18475,7 +18736,7 @@ var shutdownSession = async (ctx, cmd) => {
18475
18736
  }
18476
18737
  }
18477
18738
  try {
18478
- const proc = (0, import_child_process17.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18739
+ const proc = (0, import_child_process18.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18479
18740
  detached: true,
18480
18741
  stdio: "ignore"
18481
18742
  });
@@ -18901,8 +19162,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
18901
19162
  if (args2.length === 0) return detection;
18902
19163
  const binName = args2[0];
18903
19164
  if (binName.startsWith("-")) return detection;
18904
- const binPath = path39.join(cwd, "node_modules", ".bin", binName);
18905
- if (!fs32.existsSync(binPath)) return detection;
19165
+ const binPath = path40.join(cwd, "node_modules", ".bin", binName);
19166
+ if (!fs33.existsSync(binPath)) return detection;
18906
19167
  return {
18907
19168
  ...detection,
18908
19169
  command: binPath,
@@ -19028,7 +19289,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
19028
19289
  "BOOT_SEQUENCE",
19029
19290
  `${spawnable.command} ${spawnable.args.join(" ")}`
19030
19291
  );
19031
- const devServer = (0, import_child_process17.spawn)(spawnable.command, spawnable.args, {
19292
+ const devServer = (0, import_child_process18.spawn)(spawnable.command, spawnable.args, {
19032
19293
  cwd: process.cwd(),
19033
19294
  env: { ...process.env, ...spawnable.env ?? {} },
19034
19295
  stdio: ["ignore", "pipe", "pipe"]
@@ -19156,7 +19417,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
19156
19417
  });
19157
19418
  return;
19158
19419
  }
19159
- tunnel = (0, import_child_process17.spawn)(bin, ["tunnel", "--url", `http://localhost:${detection.port}`], {
19420
+ tunnel = (0, import_child_process18.spawn)(bin, ["tunnel", "--url", `http://localhost:${detection.port}`], {
19160
19421
  stdio: ["ignore", "pipe", "pipe"]
19161
19422
  });
19162
19423
  let parsedUrl = null;
@@ -19331,10 +19592,10 @@ async function dispatchCommand(ctx, cmd) {
19331
19592
  }
19332
19593
 
19333
19594
  // src/services/file-watcher.service.ts
19334
- var import_child_process18 = require("child_process");
19335
- var fs33 = __toESM(require("fs"));
19336
- var os27 = __toESM(require("os"));
19337
- var path40 = __toESM(require("path"));
19595
+ var import_child_process19 = require("child_process");
19596
+ var fs34 = __toESM(require("fs"));
19597
+ var os28 = __toESM(require("os"));
19598
+ var path41 = __toESM(require("path"));
19338
19599
  var import_ignore = __toESM(require("ignore"));
19339
19600
 
19340
19601
  // src/services/file-watcher/diff-parser.ts
@@ -19444,10 +19705,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
19444
19705
  /[\\/]Start Menu([\\/]|$)/i,
19445
19706
  /[\\/]Templates([\\/]|$)/i
19446
19707
  ];
19447
- function isUnsafeWindowsWatchRoot(dir, homedir23) {
19708
+ function isUnsafeWindowsWatchRoot(dir, homedir24) {
19448
19709
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
19449
19710
  const cwd = norm(dir);
19450
- const home = norm(homedir23);
19711
+ const home = norm(homedir24);
19451
19712
  if (cwd === home) return true;
19452
19713
  if (/^[a-z]:$/.test(cwd)) return true;
19453
19714
  const sysRoots = [
@@ -19477,18 +19738,18 @@ var _findGitRootSeam = {
19477
19738
  resolve: _defaultFindGitRoot
19478
19739
  };
19479
19740
  function _defaultFindGitRoot(startDir) {
19480
- let dir = path40.resolve(startDir);
19741
+ let dir = path41.resolve(startDir);
19481
19742
  const seen = /* @__PURE__ */ new Set();
19482
19743
  for (let i = 0; i < 256; i++) {
19483
19744
  if (seen.has(dir)) return null;
19484
19745
  seen.add(dir);
19485
19746
  try {
19486
- const gitPath = path40.join(dir, ".git");
19487
- const stat3 = fs33.statSync(gitPath, { throwIfNoEntry: false });
19747
+ const gitPath = path41.join(dir, ".git");
19748
+ const stat3 = fs34.statSync(gitPath, { throwIfNoEntry: false });
19488
19749
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
19489
19750
  } catch {
19490
19751
  }
19491
- const parent = path40.dirname(dir);
19752
+ const parent = path41.dirname(dir);
19492
19753
  if (parent === dir) return null;
19493
19754
  dir = parent;
19494
19755
  }
@@ -19546,7 +19807,7 @@ var FileWatcherService = class {
19546
19807
  throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
19547
19808
  }
19548
19809
  const isWin = process.platform === "win32";
19549
- if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os27.homedir())) {
19810
+ if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os28.homedir())) {
19550
19811
  log.warn(
19551
19812
  "fileWatcher",
19552
19813
  `refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
@@ -19733,7 +19994,7 @@ var FileWatcherService = class {
19733
19994
  }
19734
19995
  async emitForFile(absPath, changeType) {
19735
19996
  if (this.stopped) return;
19736
- const fileDir = path40.dirname(absPath);
19997
+ const fileDir = path41.dirname(absPath);
19737
19998
  let gitRoot = this.gitRootByDir.get(fileDir);
19738
19999
  if (gitRoot === void 0) {
19739
20000
  gitRoot = findGitRoot2(fileDir);
@@ -19746,19 +20007,19 @@ var FileWatcherService = class {
19746
20007
  );
19747
20008
  return;
19748
20009
  }
19749
- const relPathInRepo = path40.relative(gitRoot, absPath);
20010
+ const relPathInRepo = path41.relative(gitRoot, absPath);
19750
20011
  if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
19751
20012
  const matcher = this.getGitIgnoreMatcher(gitRoot);
19752
20013
  if (matcher && matcher.ignores(relPathInRepo)) {
19753
20014
  log.trace(
19754
20015
  "fileWatcher",
19755
- `${relPathInRepo} ignored by ${path40.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
20016
+ `${relPathInRepo} ignored by ${path41.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
19756
20017
  );
19757
20018
  return;
19758
20019
  }
19759
20020
  this.opts.onRepoDirty?.(gitRoot);
19760
- const repoPath = path40.relative(this.opts.workingDir, gitRoot);
19761
- const repoName = path40.basename(gitRoot);
20021
+ const repoPath = path41.relative(this.opts.workingDir, gitRoot);
20022
+ const repoName = path41.basename(gitRoot);
19762
20023
  let diffText = "";
19763
20024
  let fileStatus = "modified";
19764
20025
  if (changeType === "unlink") {
@@ -19933,7 +20194,7 @@ var FileWatcherService = class {
19933
20194
  collectGitignoreFiles(repoRoot, dir, matcher) {
19934
20195
  let entries;
19935
20196
  try {
19936
- entries = fs33.readdirSync(dir, { withFileTypes: true });
20197
+ entries = fs34.readdirSync(dir, { withFileTypes: true });
19937
20198
  } catch {
19938
20199
  return;
19939
20200
  }
@@ -19942,16 +20203,16 @@ var FileWatcherService = class {
19942
20203
  );
19943
20204
  if (gitignoreEntry) {
19944
20205
  try {
19945
- const body = fs33.readFileSync(path40.join(dir, ".gitignore"), "utf8");
19946
- const rel = path40.relative(repoRoot, dir).replace(/\\/g, "/");
20206
+ const body = fs34.readFileSync(path41.join(dir, ".gitignore"), "utf8");
20207
+ const rel = path41.relative(repoRoot, dir).replace(/\\/g, "/");
19947
20208
  const prefixed = body.split(/\r?\n/).map((line) => {
19948
20209
  const trimmed = line.trim();
19949
20210
  if (!trimmed || trimmed.startsWith("#")) return line;
19950
20211
  if (!rel) return line;
19951
20212
  if (trimmed.startsWith("!")) {
19952
- return "!" + path40.posix.join(rel, trimmed.slice(1));
20213
+ return "!" + path41.posix.join(rel, trimmed.slice(1));
19953
20214
  }
19954
- return path40.posix.join(rel, trimmed);
20215
+ return path41.posix.join(rel, trimmed);
19955
20216
  }).join("\n");
19956
20217
  matcher.add(prefixed);
19957
20218
  } catch {
@@ -19960,7 +20221,7 @@ var FileWatcherService = class {
19960
20221
  for (const entry of entries) {
19961
20222
  if (!entry.isDirectory()) continue;
19962
20223
  if (entry.name === ".git") continue;
19963
- const childAbs = path40.join(dir, entry.name);
20224
+ const childAbs = path41.join(dir, entry.name);
19964
20225
  if (isIgnoredFilePath(childAbs)) continue;
19965
20226
  this.collectGitignoreFiles(repoRoot, childAbs, matcher);
19966
20227
  }
@@ -20097,7 +20358,7 @@ async function _runGitImpl(cwd, args2, opts = {}) {
20097
20358
  return new Promise((resolve7) => {
20098
20359
  let proc;
20099
20360
  try {
20100
- proc = (0, import_child_process18.spawn)("git", args2, { cwd, env: process.env });
20361
+ proc = (0, import_child_process19.spawn)("git", args2, { cwd, env: process.env });
20101
20362
  } catch {
20102
20363
  resolve7(null);
20103
20364
  return;
@@ -20129,8 +20390,8 @@ function _runGit(cwd, args2, opts = {}) {
20129
20390
  var import_crypto4 = require("crypto");
20130
20391
 
20131
20392
  // src/services/turn-files/git-changeset.ts
20132
- var import_child_process19 = require("child_process");
20133
- var path41 = __toESM(require("path"));
20393
+ var import_child_process20 = require("child_process");
20394
+ var path42 = __toESM(require("path"));
20134
20395
  async function collectRepoChangeset(opts) {
20135
20396
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
20136
20397
  if (status2 === null) return null;
@@ -20213,7 +20474,7 @@ function defaultRunGit(cwd, args2) {
20213
20474
  return new Promise((resolve7) => {
20214
20475
  let proc;
20215
20476
  try {
20216
- proc = (0, import_child_process19.spawn)("git", args2, { cwd, env: process.env });
20477
+ proc = (0, import_child_process20.spawn)("git", args2, { cwd, env: process.env });
20217
20478
  } catch {
20218
20479
  resolve7(null);
20219
20480
  return;
@@ -20241,7 +20502,7 @@ function defaultRunGit(cwd, args2) {
20241
20502
  });
20242
20503
  }
20243
20504
  async function discoverRepos(workingDir, maxDepth = 4) {
20244
- const fs39 = await import("fs/promises");
20505
+ const fs40 = await import("fs/promises");
20245
20506
  const out2 = [];
20246
20507
  await walk(workingDir, 0);
20247
20508
  return out2;
@@ -20249,7 +20510,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20249
20510
  if (depth > maxDepth) return;
20250
20511
  let entries = [];
20251
20512
  try {
20252
- const dirents = await fs39.readdir(dir, { withFileTypes: true });
20513
+ const dirents = await fs40.readdir(dir, { withFileTypes: true });
20253
20514
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
20254
20515
  } catch {
20255
20516
  return;
@@ -20260,8 +20521,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20260
20521
  if (hasGit) {
20261
20522
  out2.push({
20262
20523
  repoRoot: dir,
20263
- repoPath: path41.relative(workingDir, dir),
20264
- repoName: path41.basename(dir)
20524
+ repoPath: path42.relative(workingDir, dir),
20525
+ repoName: path42.basename(dir)
20265
20526
  });
20266
20527
  return;
20267
20528
  }
@@ -20269,14 +20530,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
20269
20530
  if (!entry.isDirectory) continue;
20270
20531
  if (entry.name === "node_modules") continue;
20271
20532
  if (entry.name === "dist" || entry.name === "build") continue;
20272
- await walk(path41.join(dir, entry.name), depth + 1);
20533
+ await walk(path42.join(dir, entry.name), depth + 1);
20273
20534
  }
20274
20535
  }
20275
20536
  }
20276
20537
 
20277
20538
  // src/services/turn-files/files-outbox.ts
20278
- var fs34 = __toESM(require("fs/promises"));
20279
- var path42 = __toESM(require("path"));
20539
+ var fs35 = __toESM(require("fs/promises"));
20540
+ var path43 = __toESM(require("path"));
20280
20541
  var import_os7 = require("os");
20281
20542
  var HOME_OUTBOX_DIR = ".codeam/outbox";
20282
20543
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -20309,16 +20570,16 @@ var FilesOutbox = class {
20309
20570
  backoffIndex = 0;
20310
20571
  stopped = false;
20311
20572
  constructor(opts) {
20312
- const base = opts.baseDir ?? path42.join(homeDir(), HOME_OUTBOX_DIR);
20313
- this.filePath = path42.join(base, `${opts.sessionId}.jsonl`);
20573
+ const base = opts.baseDir ?? path43.join(homeDir(), HOME_OUTBOX_DIR);
20574
+ this.filePath = path43.join(base, `${opts.sessionId}.jsonl`);
20314
20575
  this.post = opts.post;
20315
20576
  this.autoSchedule = opts.autoSchedule !== false;
20316
20577
  }
20317
20578
  /** Persist the entry to disk and trigger a flush. Returns once the
20318
20579
  * line is durable on disk (not once the POST succeeds). */
20319
20580
  async enqueue(entry) {
20320
- await fs34.mkdir(path42.dirname(this.filePath), { recursive: true });
20321
- await fs34.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20581
+ await fs35.mkdir(path43.dirname(this.filePath), { recursive: true });
20582
+ await fs35.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
20322
20583
  this.backoffIndex = 0;
20323
20584
  if (this.autoSchedule) this.scheduleFlush(0);
20324
20585
  }
@@ -20407,7 +20668,7 @@ var FilesOutbox = class {
20407
20668
  async readAll() {
20408
20669
  let raw = "";
20409
20670
  try {
20410
- raw = await fs34.readFile(this.filePath, "utf8");
20671
+ raw = await fs35.readFile(this.filePath, "utf8");
20411
20672
  } catch {
20412
20673
  return [];
20413
20674
  }
@@ -20431,12 +20692,12 @@ var FilesOutbox = class {
20431
20692
  async rewrite(entries) {
20432
20693
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
20433
20694
  if (entries.length === 0) {
20434
- await fs34.unlink(this.filePath).catch(() => void 0);
20695
+ await fs35.unlink(this.filePath).catch(() => void 0);
20435
20696
  return;
20436
20697
  }
20437
20698
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
20438
- await fs34.writeFile(tmpPath, payload, "utf8");
20439
- await fs34.rename(tmpPath, this.filePath);
20699
+ await fs35.writeFile(tmpPath, payload, "utf8");
20700
+ await fs35.rename(tmpPath, this.filePath);
20440
20701
  }
20441
20702
  };
20442
20703
  function applyJitter(ms) {
@@ -22243,9 +22504,9 @@ var OutputService = class _OutputService {
22243
22504
  };
22244
22505
 
22245
22506
  // src/services/history.service.ts
22246
- var fs35 = __toESM(require("fs"));
22247
- var path43 = __toESM(require("path"));
22248
- var os28 = __toESM(require("os"));
22507
+ var fs36 = __toESM(require("fs"));
22508
+ var path44 = __toESM(require("path"));
22509
+ var os29 = __toESM(require("os"));
22249
22510
  var https7 = __toESM(require("https"));
22250
22511
  var http7 = __toESM(require("http"));
22251
22512
  var import_zod2 = require("zod");
@@ -22272,7 +22533,7 @@ function parseJsonl(filePath) {
22272
22533
  const messages = [];
22273
22534
  let raw;
22274
22535
  try {
22275
- raw = fs35.readFileSync(filePath, "utf8");
22536
+ raw = fs36.readFileSync(filePath, "utf8");
22276
22537
  } catch (err) {
22277
22538
  if (err.code !== "ENOENT") {
22278
22539
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -22407,7 +22668,7 @@ var HistoryService = class _HistoryService {
22407
22668
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
22408
22669
  }
22409
22670
  get projectDir() {
22410
- return this.runtime.resolveHistoryDir(this.cwd) ?? path43.join(os28.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22671
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path44.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22411
22672
  }
22412
22673
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
22413
22674
  setCurrentConversationId(id) {
@@ -22419,7 +22680,7 @@ var HistoryService = class _HistoryService {
22419
22680
  /** Return the current message count in the active conversation. */
22420
22681
  getCurrentMessageCount() {
22421
22682
  if (!this.currentConversationId) return 0;
22422
- const filePath = path43.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22683
+ const filePath = path44.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22423
22684
  return parseJsonl(filePath).length;
22424
22685
  }
22425
22686
  /**
@@ -22430,7 +22691,7 @@ var HistoryService = class _HistoryService {
22430
22691
  const deadline = Date.now() + timeoutMs;
22431
22692
  while (Date.now() < deadline) {
22432
22693
  if (!this.currentConversationId) return null;
22433
- const filePath = path43.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22694
+ const filePath = path44.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22434
22695
  const messages = parseJsonl(filePath);
22435
22696
  if (messages.length > previousCount) {
22436
22697
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -22456,16 +22717,16 @@ var HistoryService = class _HistoryService {
22456
22717
  const dir = this.projectDir;
22457
22718
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22458
22719
  try {
22459
- const files = fs35.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22720
+ const files = fs36.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22460
22721
  try {
22461
- const stat3 = fs35.statSync(path43.join(dir, e.name));
22722
+ const stat3 = fs36.statSync(path44.join(dir, e.name));
22462
22723
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22463
22724
  } catch {
22464
22725
  return { name: e.name, mtime: 0, birthtime: 0 };
22465
22726
  }
22466
22727
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22467
22728
  if (files.length > 0) {
22468
- this.currentConversationId = path43.basename(files[0].name, ".jsonl");
22729
+ this.currentConversationId = path44.basename(files[0].name, ".jsonl");
22469
22730
  }
22470
22731
  } catch {
22471
22732
  }
@@ -22499,13 +22760,13 @@ var HistoryService = class _HistoryService {
22499
22760
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22500
22761
  let entries;
22501
22762
  try {
22502
- entries = fs35.readdirSync(dir, { withFileTypes: true });
22763
+ entries = fs36.readdirSync(dir, { withFileTypes: true });
22503
22764
  } catch {
22504
22765
  return null;
22505
22766
  }
22506
22767
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22507
22768
  try {
22508
- const stat3 = fs35.statSync(path43.join(dir, e.name));
22769
+ const stat3 = fs36.statSync(path44.join(dir, e.name));
22509
22770
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22510
22771
  } catch {
22511
22772
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22514,12 +22775,12 @@ var HistoryService = class _HistoryService {
22514
22775
  if (files.length === 0) return null;
22515
22776
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
22516
22777
  if (!files.some((f) => f.name === targetFile)) return null;
22517
- return this.extractUsageFromFile(path43.join(dir, targetFile));
22778
+ return this.extractUsageFromFile(path44.join(dir, targetFile));
22518
22779
  }
22519
22780
  extractUsageFromFile(filePath) {
22520
22781
  let raw;
22521
22782
  try {
22522
- raw = fs35.readFileSync(filePath, "utf8");
22783
+ raw = fs36.readFileSync(filePath, "utf8");
22523
22784
  } catch {
22524
22785
  return null;
22525
22786
  }
@@ -22564,9 +22825,9 @@ var HistoryService = class _HistoryService {
22564
22825
  let totalCost = 0;
22565
22826
  let files;
22566
22827
  try {
22567
- files = fs35.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22828
+ files = fs36.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22568
22829
  try {
22569
- return fs35.statSync(path43.join(projectDir, f)).mtimeMs >= monthStartMs;
22830
+ return fs36.statSync(path44.join(projectDir, f)).mtimeMs >= monthStartMs;
22570
22831
  } catch {
22571
22832
  return false;
22572
22833
  }
@@ -22577,7 +22838,7 @@ var HistoryService = class _HistoryService {
22577
22838
  for (const file of files) {
22578
22839
  let raw;
22579
22840
  try {
22580
- raw = fs35.readFileSync(path43.join(projectDir, file), "utf8");
22841
+ raw = fs36.readFileSync(path44.join(projectDir, file), "utf8");
22581
22842
  } catch {
22582
22843
  continue;
22583
22844
  }
@@ -22641,7 +22902,7 @@ var HistoryService = class _HistoryService {
22641
22902
  * showing an empty conversation.
22642
22903
  */
22643
22904
  async loadConversation(sessionId) {
22644
- const filePath = path43.join(this.projectDir, `${sessionId}.jsonl`);
22905
+ const filePath = path44.join(this.projectDir, `${sessionId}.jsonl`);
22645
22906
  const messages = parseJsonl(filePath);
22646
22907
  if (messages.length === 0) return;
22647
22908
  const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
@@ -22695,7 +22956,7 @@ var HistoryService = class _HistoryService {
22695
22956
  if (!this.currentConversationId) return 0;
22696
22957
  }
22697
22958
  const sessionId = this.currentConversationId;
22698
- const filePath = path43.join(this.projectDir, `${sessionId}.jsonl`);
22959
+ const filePath = path44.join(this.projectDir, `${sessionId}.jsonl`);
22699
22960
  const messages = parseJsonl(filePath);
22700
22961
  if (messages.length === 0) return 0;
22701
22962
  const marker = this.lastUploadedUuid.get(sessionId);
@@ -23121,13 +23382,13 @@ function fetchQuotaUsage(runtime, historySvc) {
23121
23382
  }
23122
23383
 
23123
23384
  // src/commands/start/keep-alive.ts
23124
- var import_child_process20 = require("child_process");
23385
+ var import_child_process21 = require("child_process");
23125
23386
  function buildKeepAlive(ctx) {
23126
23387
  let timer = null;
23127
23388
  async function setIdleTimeout(minutes) {
23128
23389
  if (!ctx.inCodespace || !ctx.codespaceName) return;
23129
23390
  await new Promise((resolve7) => {
23130
- const proc = (0, import_child_process20.spawn)(
23391
+ const proc = (0, import_child_process21.spawn)(
23131
23392
  "gh",
23132
23393
  [
23133
23394
  "api",
@@ -23612,8 +23873,8 @@ async function autoLinkAfterPair(opts) {
23612
23873
  }
23613
23874
 
23614
23875
  // src/commands/pair-auto.ts
23615
- var fs36 = __toESM(require("fs"));
23616
- var os29 = __toESM(require("os"));
23876
+ var fs37 = __toESM(require("fs"));
23877
+ var os30 = __toESM(require("os"));
23617
23878
  var import_crypto7 = require("crypto");
23618
23879
 
23619
23880
  // src/commands/start-infra-only.ts
@@ -23808,12 +24069,12 @@ function readTokenFromArgs(args2) {
23808
24069
  }
23809
24070
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
23810
24071
  if (fileFlag) {
23811
- const path50 = fileFlag.slice("--token-file=".length);
24072
+ const path51 = fileFlag.slice("--token-file=".length);
23812
24073
  try {
23813
- const content = fs36.readFileSync(path50, "utf8").trim();
23814
- if (content.length === 0) fail(`--token-file ${path50} is empty`);
24074
+ const content = fs37.readFileSync(path51, "utf8").trim();
24075
+ if (content.length === 0) fail(`--token-file ${path51} is empty`);
23815
24076
  try {
23816
- fs36.unlinkSync(path50);
24077
+ fs37.unlinkSync(path51);
23817
24078
  } catch {
23818
24079
  }
23819
24080
  return content;
@@ -23839,7 +24100,7 @@ async function claimOnce(token, pluginId) {
23839
24100
  pluginId,
23840
24101
  ideName: "codeam-cli (codespace)",
23841
24102
  ideVersion: process.env.npm_package_version ?? "unknown",
23842
- hostname: os29.hostname(),
24103
+ hostname: os30.hostname(),
23843
24104
  codespaceName: process.env.CODESPACE_NAME ?? "",
23844
24105
  // Current git branch of the codespace's working directory, so the
23845
24106
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -24076,11 +24337,11 @@ async function logout() {
24076
24337
  var import_picocolors10 = __toESM(require("picocolors"));
24077
24338
 
24078
24339
  // src/services/providers/github-codespaces.ts
24079
- var import_child_process21 = require("child_process");
24340
+ var import_child_process22 = require("child_process");
24080
24341
  var import_util4 = require("util");
24081
24342
  var import_picocolors8 = __toESM(require("picocolors"));
24082
- var path44 = __toESM(require("path"));
24083
- var execFileP5 = (0, import_util4.promisify)(import_child_process21.execFile);
24343
+ var path45 = __toESM(require("path"));
24344
+ var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
24084
24345
  var MAX_BUFFER = 8 * 1024 * 1024;
24085
24346
  function resetStdinForChild() {
24086
24347
  if (process.stdin.isTTY) {
@@ -24124,7 +24385,7 @@ var GitHubCodespacesProvider = class {
24124
24385
  if (!isAuthed) {
24125
24386
  resetStdinForChild();
24126
24387
  await new Promise((resolve7, reject) => {
24127
- const proc = (0, import_child_process21.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
24388
+ const proc = (0, import_child_process22.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
24128
24389
  stdio: "inherit"
24129
24390
  });
24130
24391
  proc.on("exit", (code) => {
@@ -24158,7 +24419,7 @@ var GitHubCodespacesProvider = class {
24158
24419
  wt(noteLines.join("\n"), "One more permission needed");
24159
24420
  resetStdinForChild();
24160
24421
  const refreshCode = await new Promise((resolve7, reject) => {
24161
- const proc = (0, import_child_process21.spawn)(
24422
+ const proc = (0, import_child_process22.spawn)(
24162
24423
  "gh",
24163
24424
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
24164
24425
  { stdio: "inherit" }
@@ -24308,7 +24569,7 @@ var GitHubCodespacesProvider = class {
24308
24569
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
24309
24570
  resetStdinForChild();
24310
24571
  const ok = await new Promise((resolve7) => {
24311
- const proc = (0, import_child_process21.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
24572
+ const proc = (0, import_child_process22.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
24312
24573
  proc.on("exit", (code) => resolve7(code === 0));
24313
24574
  proc.on("error", () => resolve7(false));
24314
24575
  });
@@ -24335,7 +24596,7 @@ var GitHubCodespacesProvider = class {
24335
24596
  );
24336
24597
  resetStdinForChild();
24337
24598
  await new Promise((resolve7, reject) => {
24338
- const proc = (0, import_child_process21.spawn)(
24599
+ const proc = (0, import_child_process22.spawn)(
24339
24600
  "gh",
24340
24601
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
24341
24602
  { stdio: "inherit" }
@@ -24513,7 +24774,7 @@ var GitHubCodespacesProvider = class {
24513
24774
  async streamCommand(workspaceId, command2) {
24514
24775
  resetStdinForChild();
24515
24776
  return new Promise((resolve7, reject) => {
24516
- const proc = (0, import_child_process21.spawn)(
24777
+ const proc = (0, import_child_process22.spawn)(
24517
24778
  "gh",
24518
24779
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
24519
24780
  { stdio: "inherit" }
@@ -24540,11 +24801,11 @@ var GitHubCodespacesProvider = class {
24540
24801
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
24541
24802
  ];
24542
24803
  await new Promise((resolve7, reject) => {
24543
- const tar = (0, import_child_process21.spawn)("tar", tarArgs, {
24804
+ const tar = (0, import_child_process22.spawn)("tar", tarArgs, {
24544
24805
  stdio: ["ignore", "pipe", "pipe"],
24545
24806
  env: tarEnv
24546
24807
  });
24547
- const ssh = (0, import_child_process21.spawn)("gh", sshArgs, {
24808
+ const ssh = (0, import_child_process22.spawn)("gh", sshArgs, {
24548
24809
  stdio: [tar.stdout, "pipe", "pipe"]
24549
24810
  });
24550
24811
  let tarErr = "";
@@ -24568,7 +24829,7 @@ var GitHubCodespacesProvider = class {
24568
24829
  });
24569
24830
  }
24570
24831
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
24571
- const remoteDir = path44.posix.dirname(remotePath);
24832
+ const remoteDir = path45.posix.dirname(remotePath);
24572
24833
  const parts = [
24573
24834
  `mkdir -p ${shellQuote(remoteDir)}`,
24574
24835
  `cat > ${shellQuote(remotePath)}`
@@ -24578,7 +24839,7 @@ var GitHubCodespacesProvider = class {
24578
24839
  }
24579
24840
  const cmd = parts.join(" && ");
24580
24841
  await new Promise((resolve7, reject) => {
24581
- const proc = (0, import_child_process21.spawn)(
24842
+ const proc = (0, import_child_process22.spawn)(
24582
24843
  "gh",
24583
24844
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
24584
24845
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -24636,11 +24897,11 @@ function shellQuote(s) {
24636
24897
  }
24637
24898
 
24638
24899
  // src/services/providers/gitpod.ts
24639
- var import_child_process22 = require("child_process");
24900
+ var import_child_process23 = require("child_process");
24640
24901
  var import_util5 = require("util");
24641
- var path45 = __toESM(require("path"));
24902
+ var path46 = __toESM(require("path"));
24642
24903
  var import_picocolors9 = __toESM(require("picocolors"));
24643
- var execFileP6 = (0, import_util5.promisify)(import_child_process22.execFile);
24904
+ var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
24644
24905
  var MAX_BUFFER2 = 8 * 1024 * 1024;
24645
24906
  function resetStdinForChild2() {
24646
24907
  if (process.stdin.isTTY) {
@@ -24680,7 +24941,7 @@ var GitpodProvider = class {
24680
24941
  );
24681
24942
  resetStdinForChild2();
24682
24943
  await new Promise((resolve7, reject) => {
24683
- const proc = (0, import_child_process22.spawn)("gitpod", ["login"], { stdio: "inherit" });
24944
+ const proc = (0, import_child_process23.spawn)("gitpod", ["login"], { stdio: "inherit" });
24684
24945
  proc.on("exit", (code) => {
24685
24946
  if (code === 0) resolve7();
24686
24947
  else reject(new Error("gitpod login failed."));
@@ -24832,7 +25093,7 @@ var GitpodProvider = class {
24832
25093
  async streamCommand(workspaceId, command2) {
24833
25094
  resetStdinForChild2();
24834
25095
  return new Promise((resolve7, reject) => {
24835
- const proc = (0, import_child_process22.spawn)(
25096
+ const proc = (0, import_child_process23.spawn)(
24836
25097
  "gitpod",
24837
25098
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
24838
25099
  { stdio: "inherit" }
@@ -24852,11 +25113,11 @@ var GitpodProvider = class {
24852
25113
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
24853
25114
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
24854
25115
  await new Promise((resolve7, reject) => {
24855
- const tar = (0, import_child_process22.spawn)("tar", tarArgs, {
25116
+ const tar = (0, import_child_process23.spawn)("tar", tarArgs, {
24856
25117
  stdio: ["ignore", "pipe", "pipe"],
24857
25118
  env: tarEnv
24858
25119
  });
24859
- const ssh = (0, import_child_process22.spawn)(
25120
+ const ssh = (0, import_child_process23.spawn)(
24860
25121
  "gitpod",
24861
25122
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
24862
25123
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -24878,7 +25139,7 @@ var GitpodProvider = class {
24878
25139
  });
24879
25140
  }
24880
25141
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
24881
- const remoteDir = path45.posix.dirname(remotePath);
25142
+ const remoteDir = path46.posix.dirname(remotePath);
24882
25143
  const parts = [
24883
25144
  `mkdir -p ${shellQuote2(remoteDir)}`,
24884
25145
  `cat > ${shellQuote2(remotePath)}`
@@ -24888,7 +25149,7 @@ var GitpodProvider = class {
24888
25149
  }
24889
25150
  const cmd = parts.join(" && ");
24890
25151
  await new Promise((resolve7, reject) => {
24891
- const proc = (0, import_child_process22.spawn)(
25152
+ const proc = (0, import_child_process23.spawn)(
24892
25153
  "gitpod",
24893
25154
  ["workspace", "ssh", workspaceId, "--", cmd],
24894
25155
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -24912,10 +25173,10 @@ function shellQuote2(s) {
24912
25173
  }
24913
25174
 
24914
25175
  // src/services/providers/gitlab-workspaces.ts
24915
- var import_child_process23 = require("child_process");
25176
+ var import_child_process24 = require("child_process");
24916
25177
  var import_util6 = require("util");
24917
- var path46 = __toESM(require("path"));
24918
- var execFileP7 = (0, import_util6.promisify)(import_child_process23.execFile);
25178
+ var path47 = __toESM(require("path"));
25179
+ var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
24919
25180
  var MAX_BUFFER3 = 8 * 1024 * 1024;
24920
25181
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
24921
25182
  function resetStdinForChild3() {
@@ -24957,7 +25218,7 @@ var GitLabWorkspacesProvider = class {
24957
25218
  );
24958
25219
  resetStdinForChild3();
24959
25220
  await new Promise((resolve7, reject) => {
24960
- const proc = (0, import_child_process23.spawn)(
25221
+ const proc = (0, import_child_process24.spawn)(
24961
25222
  "glab",
24962
25223
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
24963
25224
  { stdio: "inherit" }
@@ -25129,7 +25390,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25129
25390
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
25130
25391
  resetStdinForChild3();
25131
25392
  return new Promise((resolve7, reject) => {
25132
- const proc = (0, import_child_process23.spawn)(
25393
+ const proc = (0, import_child_process24.spawn)(
25133
25394
  "ssh",
25134
25395
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
25135
25396
  { stdio: "inherit" }
@@ -25150,8 +25411,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25150
25411
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
25151
25412
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
25152
25413
  await new Promise((resolve7, reject) => {
25153
- const tar = (0, import_child_process23.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25154
- const ssh = (0, import_child_process23.spawn)(
25414
+ const tar = (0, import_child_process24.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25415
+ const ssh = (0, import_child_process24.spawn)(
25155
25416
  "ssh",
25156
25417
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
25157
25418
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -25174,14 +25435,14 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
25174
25435
  }
25175
25436
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
25176
25437
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
25177
- const remoteDir = path46.posix.dirname(remotePath);
25438
+ const remoteDir = path47.posix.dirname(remotePath);
25178
25439
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
25179
25440
  if (options.mode != null) {
25180
25441
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
25181
25442
  }
25182
25443
  const cmd = parts.join(" && ");
25183
25444
  await new Promise((resolve7, reject) => {
25184
- const proc = (0, import_child_process23.spawn)(
25445
+ const proc = (0, import_child_process24.spawn)(
25185
25446
  "ssh",
25186
25447
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
25187
25448
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -25240,10 +25501,10 @@ function shellQuote3(s) {
25240
25501
  }
25241
25502
 
25242
25503
  // src/services/providers/railway.ts
25243
- var import_child_process24 = require("child_process");
25504
+ var import_child_process25 = require("child_process");
25244
25505
  var import_util7 = require("util");
25245
- var path47 = __toESM(require("path"));
25246
- var execFileP8 = (0, import_util7.promisify)(import_child_process24.execFile);
25506
+ var path48 = __toESM(require("path"));
25507
+ var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
25247
25508
  var MAX_BUFFER4 = 8 * 1024 * 1024;
25248
25509
  function resetStdinForChild4() {
25249
25510
  if (process.stdin.isTTY) {
@@ -25284,7 +25545,7 @@ var RailwayProvider = class {
25284
25545
  );
25285
25546
  resetStdinForChild4();
25286
25547
  await new Promise((resolve7, reject) => {
25287
- const proc = (0, import_child_process24.spawn)("railway", ["login"], { stdio: "inherit" });
25548
+ const proc = (0, import_child_process25.spawn)("railway", ["login"], { stdio: "inherit" });
25288
25549
  proc.on("exit", (code) => {
25289
25550
  if (code === 0) resolve7();
25290
25551
  else reject(new Error("railway login failed."));
@@ -25427,7 +25688,7 @@ var RailwayProvider = class {
25427
25688
  }
25428
25689
  resetStdinForChild4();
25429
25690
  return new Promise((resolve7, reject) => {
25430
- const proc = (0, import_child_process24.spawn)(
25691
+ const proc = (0, import_child_process25.spawn)(
25431
25692
  "railway",
25432
25693
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
25433
25694
  { stdio: "inherit" }
@@ -25451,8 +25712,8 @@ var RailwayProvider = class {
25451
25712
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
25452
25713
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
25453
25714
  await new Promise((resolve7, reject) => {
25454
- const tar = (0, import_child_process24.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25455
- const sh = (0, import_child_process24.spawn)(
25715
+ const tar = (0, import_child_process25.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
25716
+ const sh = (0, import_child_process25.spawn)(
25456
25717
  "railway",
25457
25718
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
25458
25719
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -25478,14 +25739,14 @@ var RailwayProvider = class {
25478
25739
  if (!projectId || !serviceId) {
25479
25740
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
25480
25741
  }
25481
- const remoteDir = path47.posix.dirname(remotePath);
25742
+ const remoteDir = path48.posix.dirname(remotePath);
25482
25743
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
25483
25744
  if (options.mode != null) {
25484
25745
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
25485
25746
  }
25486
25747
  const cmd = parts.join(" && ");
25487
25748
  await new Promise((resolve7, reject) => {
25488
- const proc = (0, import_child_process24.spawn)(
25749
+ const proc = (0, import_child_process25.spawn)(
25489
25750
  "railway",
25490
25751
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
25491
25752
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -26021,8 +26282,8 @@ async function stopWorkspaceFromLocal(target) {
26021
26282
  var import_node_dns = require("dns");
26022
26283
  var import_node_util4 = require("util");
26023
26284
  var import_node_crypto8 = require("crypto");
26024
- var fs37 = __toESM(require("fs"));
26025
- var path48 = __toESM(require("path"));
26285
+ var fs38 = __toESM(require("fs"));
26286
+ var path49 = __toESM(require("path"));
26026
26287
  var import_picocolors12 = __toESM(require("picocolors"));
26027
26288
  var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
26028
26289
  async function checkDns(apiBase) {
@@ -26078,13 +26339,13 @@ async function checkHealth(apiBase) {
26078
26339
  }
26079
26340
  }
26080
26341
  function checkConfigDir() {
26081
- const dir = path48.join(require("os").homedir(), ".codeam");
26342
+ const dir = path49.join(require("os").homedir(), ".codeam");
26082
26343
  try {
26083
- fs37.mkdirSync(dir, { recursive: true, mode: 448 });
26084
- const probe = path48.join(dir, ".doctor-probe");
26085
- fs37.writeFileSync(probe, "ok", { mode: 384 });
26086
- const read = fs37.readFileSync(probe, "utf8");
26087
- fs37.unlinkSync(probe);
26344
+ fs38.mkdirSync(dir, { recursive: true, mode: 448 });
26345
+ const probe = path49.join(dir, ".doctor-probe");
26346
+ fs38.writeFileSync(probe, "ok", { mode: 384 });
26347
+ const read = fs38.readFileSync(probe, "utf8");
26348
+ fs38.unlinkSync(probe);
26088
26349
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
26089
26350
  return {
26090
26351
  id: "config-dir",
@@ -26124,9 +26385,9 @@ function checkSessions() {
26124
26385
  }
26125
26386
  }
26126
26387
  function checkAgentBinaries() {
26127
- const os31 = createOsStrategy();
26388
+ const os32 = createOsStrategy();
26128
26389
  return getEnabledAgents().map((meta) => {
26129
- const found = os31.findInPath(meta.binaryName);
26390
+ const found = os32.findInPath(meta.binaryName);
26130
26391
  return {
26131
26392
  id: `agent-${meta.id}`,
26132
26393
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -26148,7 +26409,7 @@ function checkNodePty() {
26148
26409
  detail: "not required on this platform"
26149
26410
  };
26150
26411
  }
26151
- const vendoredPath = path48.join(__dirname, "vendor", "node-pty");
26412
+ const vendoredPath = path49.join(__dirname, "vendor", "node-pty");
26152
26413
  for (const target of [vendoredPath, "node-pty"]) {
26153
26414
  try {
26154
26415
  require(target);
@@ -26190,7 +26451,7 @@ function checkChokidar() {
26190
26451
  }
26191
26452
  async function doctor(args2 = []) {
26192
26453
  const json = args2.includes("--json");
26193
- const cliVersion = true ? "2.35.9" : "0.0.0-dev";
26454
+ const cliVersion = true ? "2.36.0" : "0.0.0-dev";
26194
26455
  const apiBase = resolveApiBaseUrl();
26195
26456
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
26196
26457
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -26389,7 +26650,7 @@ async function completion(args2) {
26389
26650
  // src/commands/version.ts
26390
26651
  var import_picocolors13 = __toESM(require("picocolors"));
26391
26652
  function version2() {
26392
- const v = true ? "2.35.9" : "unknown";
26653
+ const v = true ? "2.36.0" : "unknown";
26393
26654
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
26394
26655
  }
26395
26656
 
@@ -26517,9 +26778,9 @@ function tryShowSubcommandHelp(cmd, args2) {
26517
26778
  var _subcommandHelpKeys = Object.keys(HELPS);
26518
26779
 
26519
26780
  // src/lib/updateNotifier.ts
26520
- var fs38 = __toESM(require("fs"));
26521
- var os30 = __toESM(require("os"));
26522
- var path49 = __toESM(require("path"));
26781
+ var fs39 = __toESM(require("fs"));
26782
+ var os31 = __toESM(require("os"));
26783
+ var path50 = __toESM(require("path"));
26523
26784
  var https8 = __toESM(require("https"));
26524
26785
  var import_node_child_process12 = require("child_process");
26525
26786
  var import_picocolors16 = __toESM(require("picocolors"));
@@ -26528,12 +26789,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
26528
26789
  var TTL_MS = 24 * 60 * 60 * 1e3;
26529
26790
  var REQUEST_TIMEOUT_MS = 1500;
26530
26791
  function cachePath() {
26531
- const dir = path49.join(os30.homedir(), ".codeam");
26532
- return path49.join(dir, "update-check.json");
26792
+ const dir = path50.join(os31.homedir(), ".codeam");
26793
+ return path50.join(dir, "update-check.json");
26533
26794
  }
26534
26795
  function readCache() {
26535
26796
  try {
26536
- const raw = fs38.readFileSync(cachePath(), "utf8");
26797
+ const raw = fs39.readFileSync(cachePath(), "utf8");
26537
26798
  const parsed = JSON.parse(raw);
26538
26799
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
26539
26800
  return parsed;
@@ -26544,10 +26805,10 @@ function readCache() {
26544
26805
  function writeCache(cache) {
26545
26806
  try {
26546
26807
  const file = cachePath();
26547
- fs38.mkdirSync(path49.dirname(file), { recursive: true });
26808
+ fs39.mkdirSync(path50.dirname(file), { recursive: true });
26548
26809
  const tmp = `${file}.${process.pid}.tmp`;
26549
- fs38.writeFileSync(tmp, JSON.stringify(cache));
26550
- fs38.renameSync(tmp, file);
26810
+ fs39.writeFileSync(tmp, JSON.stringify(cache));
26811
+ fs39.renameSync(tmp, file);
26551
26812
  } catch {
26552
26813
  }
26553
26814
  }
@@ -26621,8 +26882,8 @@ function isLinkedInstall() {
26621
26882
  timeout: 2e3
26622
26883
  }).trim();
26623
26884
  if (!root) return false;
26624
- const pkgPath = path49.join(root, PKG_NAME);
26625
- return fs38.lstatSync(pkgPath).isSymbolicLink();
26885
+ const pkgPath = path50.join(root, PKG_NAME);
26886
+ return fs39.lstatSync(pkgPath).isSymbolicLink();
26626
26887
  } catch {
26627
26888
  return false;
26628
26889
  }
@@ -26658,7 +26919,7 @@ function maybeAutoUpdate(currentVersion, latest) {
26658
26919
  return;
26659
26920
  }
26660
26921
  try {
26661
- fs38.unlinkSync(cachePath());
26922
+ fs39.unlinkSync(cachePath());
26662
26923
  } catch {
26663
26924
  }
26664
26925
  process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
@@ -26675,7 +26936,7 @@ function checkForUpdates() {
26675
26936
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
26676
26937
  if (process.env.CI) return;
26677
26938
  if (!process.stdout.isTTY) return;
26678
- const current = true ? "2.35.9" : null;
26939
+ const current = true ? "2.36.0" : null;
26679
26940
  if (!current) return;
26680
26941
  const cache = readCache();
26681
26942
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;