codeam-cli 2.49.5 → 2.50.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 +397 -206
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -522,9 +522,9 @@ var _default = makeConfig();
522
522
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
523
523
 
524
524
  // src/commands/pair-auto.ts
525
- var fs41 = __toESM(require("fs"));
526
- var os34 = __toESM(require("os"));
527
- var path47 = __toESM(require("path"));
525
+ var fs42 = __toESM(require("fs"));
526
+ var os35 = __toESM(require("os"));
527
+ var path48 = __toESM(require("path"));
528
528
  var import_crypto4 = require("crypto");
529
529
 
530
530
  // src/services/telemetry.service.ts
@@ -560,8 +560,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
560
560
  return decodedFile;
561
561
  };
562
562
  }
563
- function normalizeWindowsPath(path60) {
564
- return path60.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
563
+ function normalizeWindowsPath(path61) {
564
+ return path61.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
565
565
  }
566
566
 
567
567
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3041,9 +3041,9 @@ async function addSourceContext(frames) {
3041
3041
  LRU_FILE_CONTENTS_CACHE.reduce();
3042
3042
  return frames;
3043
3043
  }
3044
- function getContextLinesFromFile(path60, ranges, output) {
3044
+ function getContextLinesFromFile(path61, ranges, output) {
3045
3045
  return new Promise((resolve7) => {
3046
- const stream = (0, import_node_fs.createReadStream)(path60);
3046
+ const stream = (0, import_node_fs.createReadStream)(path61);
3047
3047
  const lineReaded = (0, import_node_readline.createInterface)({
3048
3048
  input: stream
3049
3049
  });
@@ -3058,7 +3058,7 @@ function getContextLinesFromFile(path60, ranges, output) {
3058
3058
  let rangeStart = range[0];
3059
3059
  let rangeEnd = range[1];
3060
3060
  function onStreamError() {
3061
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path60, 1);
3061
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path61, 1);
3062
3062
  lineReaded.close();
3063
3063
  lineReaded.removeAllListeners();
3064
3064
  destroyStreamAndResolve();
@@ -3119,8 +3119,8 @@ function clearLineContext(frame) {
3119
3119
  delete frame.context_line;
3120
3120
  delete frame.post_context;
3121
3121
  }
3122
- function shouldSkipContextLinesForFile(path60) {
3123
- return path60.startsWith("node:") || path60.endsWith(".min.js") || path60.endsWith(".min.cjs") || path60.endsWith(".min.mjs") || path60.startsWith("data:");
3122
+ function shouldSkipContextLinesForFile(path61) {
3123
+ return path61.startsWith("node:") || path61.endsWith(".min.js") || path61.endsWith(".min.cjs") || path61.endsWith(".min.mjs") || path61.startsWith("data:");
3124
3124
  }
3125
3125
  function shouldSkipContextLinesForFrame(frame) {
3126
3126
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5397,7 +5397,7 @@ function readAnonId() {
5397
5397
  }
5398
5398
  function superProperties() {
5399
5399
  return {
5400
- cliVersion: true ? "2.49.5" : "0.0.0-dev",
5400
+ cliVersion: true ? "2.50.0" : "0.0.0-dev",
5401
5401
  nodeVersion: process.version,
5402
5402
  platform: process.platform,
5403
5403
  arch: process.arch,
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
5578
5578
  // package.json
5579
5579
  var package_default = {
5580
5580
  name: "codeam-cli",
5581
- version: "2.49.5",
5581
+ version: "2.50.0",
5582
5582
  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.",
5583
5583
  type: "commonjs",
5584
5584
  main: "dist/index.js",
@@ -5871,6 +5871,28 @@ async function postHeadroomEvent(input) {
5871
5871
  };
5872
5872
  }
5873
5873
  }
5874
+ async function postBeadsEvent(input) {
5875
+ try {
5876
+ await _transport.postJsonAuthed(
5877
+ `${API_BASE}/api/beads/events`,
5878
+ {
5879
+ sessionId: input.sessionId,
5880
+ pluginId: input.pluginId,
5881
+ type: input.type,
5882
+ payload: input.payload ?? {}
5883
+ },
5884
+ input.pluginAuthToken
5885
+ );
5886
+ return { ok: true };
5887
+ } catch (err) {
5888
+ const e = err;
5889
+ return {
5890
+ ok: false,
5891
+ status: typeof e.statusCode === "number" ? e.statusCode : 0,
5892
+ message: e.message || "unknown"
5893
+ };
5894
+ }
5895
+ }
5874
5896
  async function postBeadsProvisioning(input) {
5875
5897
  try {
5876
5898
  await _transport.postJsonAuthed(
@@ -7706,9 +7728,9 @@ function closeAllTerminals() {
7706
7728
  }
7707
7729
 
7708
7730
  // src/commands/start/handlers.ts
7709
- var fs40 = __toESM(require("fs"));
7710
- var os33 = __toESM(require("os"));
7711
- var path46 = __toESM(require("path"));
7731
+ var fs41 = __toESM(require("fs"));
7732
+ var os34 = __toESM(require("os"));
7733
+ var path47 = __toESM(require("path"));
7712
7734
  var import_crypto3 = require("crypto");
7713
7735
  var import_child_process20 = require("child_process");
7714
7736
  var import_which2 = __toESM(require("which"));
@@ -11142,10 +11164,10 @@ function buildForPlatform(platform3) {
11142
11164
  var import_node_crypto4 = require("crypto");
11143
11165
 
11144
11166
  // src/agents/claude/resolver.ts
11145
- function buildClaudeLaunch(extraArgs = [], os40 = createOsStrategy()) {
11146
- const found = os40.findInPath("claude") ?? os40.findInPath("claude-code");
11167
+ function buildClaudeLaunch(extraArgs = [], os41 = createOsStrategy()) {
11168
+ const found = os41.findInPath("claude") ?? os41.findInPath("claude-code");
11147
11169
  if (!found) return null;
11148
- return os40.buildLaunch(found, extraArgs);
11170
+ return os41.buildLaunch(found, extraArgs);
11149
11171
  }
11150
11172
 
11151
11173
  // src/agents/claude/installer.ts
@@ -11738,8 +11760,8 @@ var ClaudeRuntimeStrategy = class {
11738
11760
  meta = getAgent("claude");
11739
11761
  mode = "interactive";
11740
11762
  os;
11741
- constructor(os40) {
11742
- this.os = os40;
11763
+ constructor(os41) {
11764
+ this.os = os41;
11743
11765
  }
11744
11766
  /**
11745
11767
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -12416,8 +12438,8 @@ function codexCredentialLocator() {
12416
12438
  function codexLoginLauncher() {
12417
12439
  return {
12418
12440
  async ensureInstalled() {
12419
- const os40 = createOsStrategy();
12420
- return os40.findInPath("codex") !== null;
12441
+ const os41 = createOsStrategy();
12442
+ return os41.findInPath("codex") !== null;
12421
12443
  },
12422
12444
  launch() {
12423
12445
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -12440,8 +12462,8 @@ var CodexRuntimeStrategy = class {
12440
12462
  meta = getAgent("codex");
12441
12463
  mode = "interactive";
12442
12464
  os;
12443
- constructor(os40) {
12444
- this.os = os40;
12465
+ constructor(os41) {
12466
+ this.os = os41;
12445
12467
  }
12446
12468
  async prepareLaunch() {
12447
12469
  let binary = this.os.findInPath("codex");
@@ -12540,12 +12562,12 @@ var CodexRuntimeStrategy = class {
12540
12562
  });
12541
12563
  }
12542
12564
  };
12543
- function resolveNpm(os40) {
12544
- return os40.id === "win32" ? "npm.cmd" : "npm";
12565
+ function resolveNpm(os41) {
12566
+ return os41.id === "win32" ? "npm.cmd" : "npm";
12545
12567
  }
12546
- async function installCodexViaNpm(os40) {
12568
+ async function installCodexViaNpm(os41) {
12547
12569
  return new Promise((resolve7, reject) => {
12548
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os40), ["install", "-g", "@openai/codex"], {
12570
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os41), ["install", "-g", "@openai/codex"], {
12549
12571
  stdio: "inherit"
12550
12572
  });
12551
12573
  proc.on("close", (code) => {
@@ -12562,16 +12584,16 @@ async function installCodexViaNpm(os40) {
12562
12584
  });
12563
12585
  });
12564
12586
  }
12565
- function augmentNpmGlobalBin(os40) {
12587
+ function augmentNpmGlobalBin(os41) {
12566
12588
  try {
12567
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os40), ["prefix", "-g"], {
12589
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os41), ["prefix", "-g"], {
12568
12590
  stdio: ["ignore", "pipe", "ignore"]
12569
12591
  });
12570
12592
  if (result.status !== 0) return;
12571
12593
  const prefix = result.stdout.toString().trim();
12572
12594
  if (!prefix) return;
12573
- const binDir = os40.id === "win32" ? prefix : path22.join(prefix, "bin");
12574
- os40.augmentPath([binDir]);
12595
+ const binDir = os41.id === "win32" ? prefix : path22.join(prefix, "bin");
12596
+ os41.augmentPath([binDir]);
12575
12597
  } catch {
12576
12598
  }
12577
12599
  }
@@ -12655,9 +12677,9 @@ var import_node_child_process7 = require("child_process");
12655
12677
  // src/agents/coderabbit/installer.ts
12656
12678
  var import_node_child_process5 = require("child_process");
12657
12679
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
12658
- async function ensureCoderabbitInstalled(os40) {
12659
- if (os40.findInPath("coderabbit")) return true;
12660
- if (os40.id === "win32") {
12680
+ async function ensureCoderabbitInstalled(os41) {
12681
+ if (os41.findInPath("coderabbit")) return true;
12682
+ if (os41.id === "win32") {
12661
12683
  console.error(
12662
12684
  "\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"
12663
12685
  );
@@ -12672,8 +12694,8 @@ async function ensureCoderabbitInstalled(os40) {
12672
12694
  proc.on("error", () => resolve7(false));
12673
12695
  });
12674
12696
  if (!ok) return false;
12675
- os40.augmentPath([`${os40.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12676
- return os40.findInPath("coderabbit") !== null;
12697
+ os41.augmentPath([`${os41.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12698
+ return os41.findInPath("coderabbit") !== null;
12677
12699
  }
12678
12700
 
12679
12701
  // src/agents/coderabbit/link.ts
@@ -12708,10 +12730,10 @@ function coderabbitCredentialLocator() {
12708
12730
  validate: validateNonEmptyCredential
12709
12731
  };
12710
12732
  }
12711
- function coderabbitLoginLauncher(os40) {
12733
+ function coderabbitLoginLauncher(os41) {
12712
12734
  return {
12713
12735
  async ensureInstalled() {
12714
- return ensureCoderabbitInstalled(os40);
12736
+ return ensureCoderabbitInstalled(os41);
12715
12737
  },
12716
12738
  launch() {
12717
12739
  return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -12734,11 +12756,11 @@ function parseReview(stdout) {
12734
12756
  for (const line of lines) {
12735
12757
  const m = line.match(HUNK_LINE_RE);
12736
12758
  if (!m) continue;
12737
- const [, path60, lineNo, sevToken, message] = m;
12738
- if (!path60 || !lineNo || !message) continue;
12759
+ const [, path61, lineNo, sevToken, message] = m;
12760
+ if (!path61 || !lineNo || !message) continue;
12739
12761
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
12740
12762
  hunks.push({
12741
- path: path60.trim(),
12763
+ path: path61.trim(),
12742
12764
  line: Number(lineNo),
12743
12765
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
12744
12766
  message: cleanedMessage
@@ -12757,8 +12779,8 @@ var CoderabbitRuntimeStrategy = class {
12757
12779
  meta = getAgent("coderabbit");
12758
12780
  mode = "batch";
12759
12781
  os;
12760
- constructor(os40) {
12761
- this.os = os40;
12782
+ constructor(os41) {
12783
+ this.os = os41;
12762
12784
  }
12763
12785
  getDefaultArgs() {
12764
12786
  return ["review"];
@@ -12874,10 +12896,10 @@ function cursorCredentialLocator() {
12874
12896
  validate: validateNonEmptyCredential
12875
12897
  };
12876
12898
  }
12877
- function cursorLoginLauncher(os40) {
12899
+ function cursorLoginLauncher(os41) {
12878
12900
  return {
12879
12901
  async ensureInstalled() {
12880
- if (os40.findInPath("cursor-agent")) return true;
12902
+ if (os41.findInPath("cursor-agent")) return true;
12881
12903
  console.error(
12882
12904
  "\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"
12883
12905
  );
@@ -12939,8 +12961,8 @@ var CursorRuntimeStrategy = class {
12939
12961
  meta = getAgent("cursor");
12940
12962
  mode = "interactive";
12941
12963
  os;
12942
- constructor(os40) {
12943
- this.os = os40;
12964
+ constructor(os41) {
12965
+ this.os = os41;
12944
12966
  }
12945
12967
  async prepareLaunch() {
12946
12968
  const binary = this.os.findInPath("cursor-agent");
@@ -13079,10 +13101,10 @@ function aiderCredentialLocator() {
13079
13101
  validate: validateNonEmptyCredential
13080
13102
  };
13081
13103
  }
13082
- function aiderLoginLauncher(os40) {
13104
+ function aiderLoginLauncher(os41) {
13083
13105
  return {
13084
13106
  async ensureInstalled() {
13085
- if (os40.findInPath("aider")) return true;
13107
+ if (os41.findInPath("aider")) return true;
13086
13108
  console.error(
13087
13109
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13088
13110
  );
@@ -13092,7 +13114,7 @@ function aiderLoginLauncher(os40) {
13092
13114
  console.error(
13093
13115
  "\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"
13094
13116
  );
13095
- return (0, import_node_child_process9.spawn)(os40.id === "win32" ? "cmd.exe" : "sh", os40.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13117
+ return (0, import_node_child_process9.spawn)(os41.id === "win32" ? "cmd.exe" : "sh", os41.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13096
13118
  stdio: "ignore"
13097
13119
  });
13098
13120
  }
@@ -13164,8 +13186,8 @@ var AiderRuntimeStrategy = class {
13164
13186
  meta = getAgent("aider");
13165
13187
  mode = "interactive";
13166
13188
  os;
13167
- constructor(os40) {
13168
- this.os = os40;
13189
+ constructor(os41) {
13190
+ this.os = os41;
13169
13191
  }
13170
13192
  async prepareLaunch() {
13171
13193
  const binary = this.os.findInPath("aider");
@@ -13294,8 +13316,8 @@ function geminiCredentialLocator() {
13294
13316
  function geminiLoginLauncher() {
13295
13317
  return {
13296
13318
  async ensureInstalled() {
13297
- const os40 = createOsStrategy();
13298
- return os40.findInPath("gemini") !== null;
13319
+ const os41 = createOsStrategy();
13320
+ return os41.findInPath("gemini") !== null;
13299
13321
  },
13300
13322
  launch() {
13301
13323
  return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -13328,8 +13350,8 @@ var GeminiRuntimeStrategy = class {
13328
13350
  meta = getAgent("gemini");
13329
13351
  mode = "interactive";
13330
13352
  os;
13331
- constructor(os40) {
13332
- this.os = os40;
13353
+ constructor(os41) {
13354
+ this.os = os41;
13333
13355
  }
13334
13356
  async prepareLaunch() {
13335
13357
  const binary = this.os.findInPath("gemini");
@@ -13428,18 +13450,18 @@ var GeminiRuntimeStrategy = class {
13428
13450
 
13429
13451
  // src/agents/registry.ts
13430
13452
  var runtimeBuilders = {
13431
- claude: (os40) => new ClaudeRuntimeStrategy(os40),
13432
- codex: (os40) => new CodexRuntimeStrategy(os40),
13433
- coderabbit: (os40) => new CoderabbitRuntimeStrategy(os40),
13434
- cursor: (os40) => new CursorRuntimeStrategy(os40),
13435
- aider: (os40) => new AiderRuntimeStrategy(os40),
13436
- gemini: (os40) => new GeminiRuntimeStrategy(os40)
13453
+ claude: (os41) => new ClaudeRuntimeStrategy(os41),
13454
+ codex: (os41) => new CodexRuntimeStrategy(os41),
13455
+ coderabbit: (os41) => new CoderabbitRuntimeStrategy(os41),
13456
+ cursor: (os41) => new CursorRuntimeStrategy(os41),
13457
+ aider: (os41) => new AiderRuntimeStrategy(os41),
13458
+ gemini: (os41) => new GeminiRuntimeStrategy(os41)
13437
13459
  };
13438
13460
  var deployBuilders = {
13439
13461
  claude: () => new ClaudeDeployStrategy(),
13440
13462
  codex: () => new CodexDeployStrategy()
13441
13463
  };
13442
- function createAgentStrategy(agent, os40 = createOsStrategy()) {
13464
+ function createAgentStrategy(agent, os41 = createOsStrategy()) {
13443
13465
  if (!AGENT_REGISTRY[agent]?.enabled) {
13444
13466
  throw new Error(
13445
13467
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -13449,10 +13471,10 @@ function createAgentStrategy(agent, os40 = createOsStrategy()) {
13449
13471
  if (!build) {
13450
13472
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
13451
13473
  }
13452
- return build(os40);
13474
+ return build(os41);
13453
13475
  }
13454
- function createInteractiveAgentStrategy(agent, os40 = createOsStrategy()) {
13455
- const s = createAgentStrategy(agent, os40);
13476
+ function createInteractiveAgentStrategy(agent, os41 = createOsStrategy()) {
13477
+ const s = createAgentStrategy(agent, os41);
13456
13478
  if (s.mode !== "interactive") {
13457
13479
  throw new Error(
13458
13480
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -14747,7 +14769,7 @@ async function autoUpgradeBeforeCriticalCommand() {
14747
14769
  if (process.env.NODE_ENV === "test") return;
14748
14770
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14749
14771
  if (process.env.CI) return;
14750
- const current = true ? "2.49.5" : null;
14772
+ const current = true ? "2.50.0" : null;
14751
14773
  if (!current) return;
14752
14774
  const cache = readCache();
14753
14775
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -14764,7 +14786,7 @@ function checkForUpdates() {
14764
14786
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14765
14787
  if (process.env.CI) return;
14766
14788
  if (!process.stdout.isTTY) return;
14767
- const current = true ? "2.49.5" : null;
14789
+ const current = true ? "2.50.0" : null;
14768
14790
  if (!current) return;
14769
14791
  const cache = readCache();
14770
14792
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -15445,7 +15467,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.s
15445
15467
  detached: false
15446
15468
  });
15447
15469
  function currentCliVersion() {
15448
- return true ? "2.49.5" : null;
15470
+ return true ? "2.50.0" : null;
15449
15471
  }
15450
15472
  function runCmd(cmd, args2, timeoutMs) {
15451
15473
  return new Promise((resolve7) => {
@@ -17126,11 +17148,11 @@ function resolveDoltInstallStrategy(platform3) {
17126
17148
  }
17127
17149
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
17128
17150
  function doltPlatformTuple(platform3, arch2) {
17129
- const os40 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17151
+ const os41 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17130
17152
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
17131
17153
  if (!a) return null;
17132
- if (os40 === "windows" && a !== "amd64") return null;
17133
- return `${os40}-${a}`;
17154
+ if (os41 === "windows" && a !== "amd64") return null;
17155
+ return `${os41}-${a}`;
17134
17156
  }
17135
17157
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
17136
17158
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -18009,6 +18031,30 @@ async function handleBeadsActionCommand(action, started) {
18009
18031
  });
18010
18032
  }
18011
18033
 
18034
+ // src/beads/config-store.ts
18035
+ var import_node_fs5 = __toESM(require("fs"));
18036
+ var import_node_os3 = __toESM(require("os"));
18037
+ var import_node_path4 = __toESM(require("path"));
18038
+ function beadsConfigPath() {
18039
+ return import_node_path4.default.join(import_node_os3.default.homedir(), ".codeam", "beads-config.json");
18040
+ }
18041
+ function readBeadsEnabled() {
18042
+ try {
18043
+ const raw = import_node_fs5.default.readFileSync(beadsConfigPath(), "utf8");
18044
+ const cfg = JSON.parse(raw);
18045
+ return cfg.enabled !== false;
18046
+ } catch {
18047
+ return true;
18048
+ }
18049
+ }
18050
+ function persistBeadsConfig(cfg) {
18051
+ const file = beadsConfigPath();
18052
+ import_node_fs5.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
18053
+ const tmp = `${file}.tmp`;
18054
+ import_node_fs5.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
18055
+ import_node_fs5.default.renameSync(tmp, file);
18056
+ }
18057
+
18012
18058
  // src/beads/wiring.ts
18013
18059
  function beadsKilled() {
18014
18060
  const v = process.env.CODEAM_BEADS_DISABLED;
@@ -18019,6 +18065,10 @@ async function provisionBeadsForStart(ctx) {
18019
18065
  log.trace("beads", "CODEAM_BEADS_DISABLED set \u2014 beads off this run");
18020
18066
  return null;
18021
18067
  }
18068
+ if (readBeadsEnabled() === false) {
18069
+ log.trace("beads", "beads disabled by persisted config \u2014 beads off this run");
18070
+ return null;
18071
+ }
18022
18072
  delete process.env.BEADS_DIR;
18023
18073
  process.env.BEADS_DOLT_SHARED_SERVER = "1";
18024
18074
  if (!ctx.pluginAuthToken) {
@@ -18079,12 +18129,69 @@ function beadsActionFromPayload(payload) {
18079
18129
  };
18080
18130
  }
18081
18131
 
18132
+ // src/beads/configure.ts
18133
+ var _probeSeam = {
18134
+ resolveBd: (cwd) => new BdAdapter({ cwd }).isAvailable(),
18135
+ doltOnPath: () => ensureDoltResolvable(),
18136
+ ping: async (cwd) => {
18137
+ const adapter = new BdAdapter({ cwd });
18138
+ if (!adapter.isAvailable()) return false;
18139
+ const r = await adapter.run(["ping"]);
18140
+ return r.code === 0;
18141
+ },
18142
+ derivePrefix: (cwd) => {
18143
+ try {
18144
+ const { projectKey } = deriveProjectIdentity(cwd);
18145
+ return prefixForProjectKey(projectKey);
18146
+ } catch {
18147
+ return null;
18148
+ }
18149
+ }
18150
+ };
18151
+ async function probeBeadsStatus(cwd = process.cwd()) {
18152
+ const bdAvailable = _probeSeam.resolveBd(cwd);
18153
+ const doltAvailable = _probeSeam.doltOnPath();
18154
+ const serverUp = bdAvailable && doltAvailable ? await _probeSeam.ping(cwd) : false;
18155
+ const prefix = _probeSeam.derivePrefix(cwd);
18156
+ return { bdAvailable, doltAvailable, serverUp, prefix };
18157
+ }
18158
+ async function configureBeads(action, ctx, deps) {
18159
+ if (action === "status") {
18160
+ if (deps.readEnabled() === false) {
18161
+ deps.emit({ type: "beads_status", state: "disabled", running: false });
18162
+ return { enabled: false, running: false };
18163
+ }
18164
+ const p3 = await deps.probe();
18165
+ const running2 = p3.serverUp && p3.bdAvailable;
18166
+ deps.emit({ type: "beads_status", state: running2 ? "enabled" : "disabled", running: running2, ...p3 });
18167
+ return { enabled: running2, running: running2, ...p3 };
18168
+ }
18169
+ if (action === "disable") {
18170
+ deps.persist({ enabled: false });
18171
+ await deps.stopWatcher().catch(() => void 0);
18172
+ await deps.revertAgentHook(ctx.agent).catch(() => void 0);
18173
+ deps.emit({ type: "beads_status", state: "disabled" });
18174
+ return { enabled: false };
18175
+ }
18176
+ deps.persist({ enabled: true });
18177
+ deps.emit({ type: "beads_status", state: "provisioning" });
18178
+ const p2 = await deps.provision();
18179
+ if (!p2.serverUp || !p2.bdAvailable) {
18180
+ deps.emit({ type: "beads_status", state: "error", error: "Beads provisioning failed", ...p2 });
18181
+ return { enabled: false, ...p2 };
18182
+ }
18183
+ await deps.startWatcher().catch(() => void 0);
18184
+ const running = true;
18185
+ deps.emit({ type: "beads_status", state: "enabled", running, ...p2 });
18186
+ return { enabled: true, running, ...p2 };
18187
+ }
18188
+
18082
18189
  // src/commands/start/handlers.ts
18083
18190
  var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18084
18191
  function cleanupAttachmentTempFiles() {
18085
18192
  for (const p2 of pendingAttachmentFiles) {
18086
18193
  try {
18087
- fs40.unlinkSync(p2);
18194
+ fs41.unlinkSync(p2);
18088
18195
  } catch {
18089
18196
  }
18090
18197
  }
@@ -18093,8 +18200,8 @@ function cleanupAttachmentTempFiles() {
18093
18200
  function saveFilesTemp(files) {
18094
18201
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18095
18202
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18096
- const tmpPath = path46.join(os33.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18097
- fs40.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18203
+ const tmpPath = path47.join(os34.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18204
+ fs41.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18098
18205
  pendingAttachmentFiles.add(tmpPath);
18099
18206
  return tmpPath;
18100
18207
  });
@@ -18114,7 +18221,7 @@ var startTask = (ctx, _cmd, parsed) => {
18114
18221
  setTimeout(() => {
18115
18222
  for (const p2 of paths) {
18116
18223
  try {
18117
- fs40.unlinkSync(p2);
18224
+ fs41.unlinkSync(p2);
18118
18225
  } catch {
18119
18226
  }
18120
18227
  pendingAttachmentFiles.delete(p2);
@@ -18315,9 +18422,9 @@ var listFiles = async (ctx, cmd, parsed) => {
18315
18422
  await ctx.relay.sendResult(cmd.id, "completed", result);
18316
18423
  };
18317
18424
  var envReadH = async (ctx, cmd) => {
18318
- const envPath = path46.join(process.cwd(), ".env");
18425
+ const envPath = path47.join(process.cwd(), ".env");
18319
18426
  try {
18320
- const raw = await fs40.promises.readFile(envPath, "utf8");
18427
+ const raw = await fs41.promises.readFile(envPath, "utf8");
18321
18428
  await ctx.relay.sendResult(cmd.id, "completed", {
18322
18429
  exists: true,
18323
18430
  vars: parseDotenv(raw)
@@ -18348,14 +18455,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
18348
18455
  }
18349
18456
  seen.add(v.key);
18350
18457
  }
18351
- const envPath = path46.join(process.cwd(), ".env");
18352
- const tmpPath = path46.join(process.cwd(), ".env.codeam.tmp");
18458
+ const envPath = path47.join(process.cwd(), ".env");
18459
+ const tmpPath = path47.join(process.cwd(), ".env.codeam.tmp");
18353
18460
  try {
18354
- await fs40.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18355
- await fs40.promises.rename(tmpPath, envPath);
18461
+ await fs41.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18462
+ await fs41.promises.rename(tmpPath, envPath);
18356
18463
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
18357
18464
  } catch (err) {
18358
- await fs40.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18465
+ await fs41.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18359
18466
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
18360
18467
  }
18361
18468
  };
@@ -18373,7 +18480,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18373
18480
  let configuredAgent = rawAgentId;
18374
18481
  if (!configuredAgent) {
18375
18482
  try {
18376
- const raw = JSON.parse(fs40.readFileSync(headroomConfigPath(), "utf8"));
18483
+ const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
18377
18484
  configuredAgent = raw.agent ?? "";
18378
18485
  } catch {
18379
18486
  }
@@ -18407,7 +18514,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18407
18514
  persist: persistHeadroomConfig,
18408
18515
  readEnabled: () => {
18409
18516
  try {
18410
- const raw = JSON.parse(fs40.readFileSync(headroomConfigPath(), "utf8"));
18517
+ const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
18411
18518
  return raw.enabled === true;
18412
18519
  } catch {
18413
18520
  return false;
@@ -18480,6 +18587,65 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18480
18587
  });
18481
18588
  await ctx.relay.sendResult(cmd.id, "completed", result);
18482
18589
  };
18590
+ var _beadsEmitChain = Promise.resolve();
18591
+ var beadsConfigureH = async (ctx, cmd, parsed) => {
18592
+ const action = parsed.action;
18593
+ if (action !== "enable" && action !== "disable" && action !== "status") {
18594
+ await ctx.relay.sendResult(cmd.id, "failed", { error: "action must be enable|disable|status" });
18595
+ return;
18596
+ }
18597
+ let rawAgentId = ctx.agentId || (typeof parsed.agentId === "string" ? parsed.agentId : "");
18598
+ if (rawAgentId === "claude_code") rawAgentId = "claude";
18599
+ const agentIds = rawAgentId && isKnownAgentId(rawAgentId) ? [rawAgentId] : [];
18600
+ const deps = {
18601
+ provision: async () => {
18602
+ const r = await provisionBeads({ cwd: process.cwd(), agents: agentIds });
18603
+ return { bdAvailable: r.bdAvailable, doltAvailable: r.doltAvailable, serverUp: r.serverUp, prefix: r.prefix };
18604
+ },
18605
+ probe: async () => probeBeadsStatus(process.cwd()),
18606
+ startWatcher: async () => {
18607
+ if (!ctx.pluginAuthToken) return;
18608
+ const started = await startBeads({
18609
+ sessionId: ctx.sessionId,
18610
+ pluginId: ctx.pluginId,
18611
+ pluginAuthToken: ctx.pluginAuthToken,
18612
+ cwd: process.cwd(),
18613
+ agents: agentIds
18614
+ });
18615
+ if (started) {
18616
+ ctx.beads = started;
18617
+ }
18618
+ },
18619
+ stopWatcher: async () => {
18620
+ if (ctx.beads) {
18621
+ await ctx.beads.watcher.stop();
18622
+ ctx.beads = null;
18623
+ }
18624
+ },
18625
+ revertAgentHook: async (agent) => {
18626
+ log.info("beads", `revertAgentHook: bd has no --remove flag \u2014 leaving ${agent} hook in place (no-op disable path)`);
18627
+ },
18628
+ persist: (cfg) => persistBeadsConfig(cfg),
18629
+ readEnabled: () => readBeadsEnabled(),
18630
+ emit: (event) => {
18631
+ const token = ctx.pluginAuthToken;
18632
+ if (!token) return;
18633
+ _beadsEmitChain = _beadsEmitChain.then(
18634
+ () => postBeadsEvent({
18635
+ sessionId: ctx.sessionId,
18636
+ pluginId: ctx.pluginId,
18637
+ pluginAuthToken: token,
18638
+ type: "beads_status",
18639
+ payload: Object.fromEntries(
18640
+ Object.entries(event).filter(([k2]) => k2 !== "type")
18641
+ )
18642
+ })
18643
+ );
18644
+ }
18645
+ };
18646
+ const result = await configureBeads(action, { agent: rawAgentId, cwd: process.cwd(), pluginAuthToken: ctx.pluginAuthToken }, deps);
18647
+ await ctx.relay.sendResult(cmd.id, "completed", result);
18648
+ };
18483
18649
  var terminalOpenH = async (ctx, cmd, parsed) => {
18484
18650
  const r = openTerminal({
18485
18651
  cols: typeof parsed.cols === "number" ? parsed.cols : void 0,
@@ -18916,8 +19082,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
18916
19082
  if (args2.length === 0) return detection;
18917
19083
  const binName = args2[0];
18918
19084
  if (binName.startsWith("-")) return detection;
18919
- const binPath = path46.join(cwd, "node_modules", ".bin", binName);
18920
- if (!fs40.existsSync(binPath)) return detection;
19085
+ const binPath = path47.join(cwd, "node_modules", ".bin", binName);
19086
+ if (!fs41.existsSync(binPath)) return detection;
18921
19087
  return {
18922
19088
  ...detection,
18923
19089
  command: binPath,
@@ -19465,7 +19631,8 @@ var handlers = {
19465
19631
  save_preview_config: savePreviewConfigH,
19466
19632
  env_read: envReadH,
19467
19633
  env_write: envWriteH,
19468
- headroom_configure: headroomConfigureH
19634
+ headroom_configure: headroomConfigureH,
19635
+ beads_configure: beadsConfigureH
19469
19636
  };
19470
19637
  async function dispatchCommand(ctx, cmd) {
19471
19638
  if (cmd.type === "beads_action") {
@@ -19733,12 +19900,12 @@ function readTokenFromArgs(args2) {
19733
19900
  }
19734
19901
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
19735
19902
  if (fileFlag) {
19736
- const path60 = fileFlag.slice("--token-file=".length);
19903
+ const path61 = fileFlag.slice("--token-file=".length);
19737
19904
  try {
19738
- const content = fs41.readFileSync(path60, "utf8").trim();
19739
- if (content.length === 0) fail(`--token-file ${path60} is empty`);
19905
+ const content = fs42.readFileSync(path61, "utf8").trim();
19906
+ if (content.length === 0) fail(`--token-file ${path61} is empty`);
19740
19907
  try {
19741
- fs41.unlinkSync(path60);
19908
+ fs42.unlinkSync(path61);
19742
19909
  } catch {
19743
19910
  }
19744
19911
  return content;
@@ -19764,7 +19931,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
19764
19931
  pluginId,
19765
19932
  ideName: "codeam-cli (codespace)",
19766
19933
  ideVersion: process.env.npm_package_version ?? "unknown",
19767
- hostname: os34.hostname(),
19934
+ hostname: os35.hostname(),
19768
19935
  codespaceName: process.env.CODESPACE_NAME ?? "",
19769
19936
  // Current git branch of the codespace's working directory, so the
19770
19937
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -19825,7 +19992,7 @@ async function claim(token, pluginId, pluginSecretHash) {
19825
19992
  }
19826
19993
  }
19827
19994
  function pairAutoLockPath() {
19828
- return path47.join(os34.homedir(), ".codeam", "pair-auto.lock");
19995
+ return path48.join(os35.homedir(), ".codeam", "pair-auto.lock");
19829
19996
  }
19830
19997
  function isLivePairAuto(pid) {
19831
19998
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -19835,7 +20002,7 @@ function isLivePairAuto(pid) {
19835
20002
  if (e.code !== "EPERM") return false;
19836
20003
  }
19837
20004
  try {
19838
- return fs41.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20005
+ return fs42.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
19839
20006
  } catch {
19840
20007
  return true;
19841
20008
  }
@@ -19845,24 +20012,24 @@ function isLiveCodeam(pid) {
19845
20012
  }
19846
20013
  function daemonLockPath(sessionId) {
19847
20014
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
19848
- return path47.join(os34.homedir(), ".codeam", `daemon-${safe}.lock`);
20015
+ return path48.join(os35.homedir(), ".codeam", `daemon-${safe}.lock`);
19849
20016
  }
19850
20017
  function acquireDaemonLock(sessionId) {
19851
20018
  const lockPath = daemonLockPath(sessionId);
19852
20019
  try {
19853
- fs41.mkdirSync(path47.dirname(lockPath), { recursive: true });
20020
+ fs42.mkdirSync(path48.dirname(lockPath), { recursive: true });
19854
20021
  try {
19855
- fs41.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20022
+ fs42.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
19856
20023
  } catch (e) {
19857
20024
  if (e.code !== "EEXIST") throw e;
19858
- const holder = Number(fs41.readFileSync(lockPath, "utf8").trim());
20025
+ const holder = Number(fs42.readFileSync(lockPath, "utf8").trim());
19859
20026
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
19860
- fs41.writeFileSync(lockPath, String(process.pid));
20027
+ fs42.writeFileSync(lockPath, String(process.pid));
19861
20028
  }
19862
20029
  const release3 = () => {
19863
20030
  try {
19864
- if (fs41.existsSync(lockPath) && Number(fs41.readFileSync(lockPath, "utf8").trim()) === process.pid) {
19865
- fs41.unlinkSync(lockPath);
20031
+ if (fs42.existsSync(lockPath) && Number(fs42.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20032
+ fs42.unlinkSync(lockPath);
19866
20033
  }
19867
20034
  } catch {
19868
20035
  }
@@ -19884,19 +20051,19 @@ function acquireDaemonLock(sessionId) {
19884
20051
  function acquireSingletonLock() {
19885
20052
  const lockPath = pairAutoLockPath();
19886
20053
  try {
19887
- fs41.mkdirSync(path47.dirname(lockPath), { recursive: true });
20054
+ fs42.mkdirSync(path48.dirname(lockPath), { recursive: true });
19888
20055
  try {
19889
- fs41.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20056
+ fs42.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
19890
20057
  } catch (e) {
19891
20058
  if (e.code !== "EEXIST") throw e;
19892
- const holder = Number(fs41.readFileSync(lockPath, "utf8").trim());
20059
+ const holder = Number(fs42.readFileSync(lockPath, "utf8").trim());
19893
20060
  if (isLivePairAuto(holder)) return false;
19894
- fs41.writeFileSync(lockPath, String(process.pid));
20061
+ fs42.writeFileSync(lockPath, String(process.pid));
19895
20062
  }
19896
20063
  process.once("exit", () => {
19897
20064
  try {
19898
- if (fs41.existsSync(lockPath) && Number(fs41.readFileSync(lockPath, "utf8").trim()) === process.pid) {
19899
- fs41.unlinkSync(lockPath);
20065
+ if (fs42.existsSync(lockPath) && Number(fs42.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20066
+ fs42.unlinkSync(lockPath);
19900
20067
  }
19901
20068
  } catch {
19902
20069
  }
@@ -20341,19 +20508,19 @@ var AgentService = class _AgentService {
20341
20508
  };
20342
20509
 
20343
20510
  // src/agents/acp/adapters.ts
20344
- var path48 = __toESM(require("path"));
20511
+ var path49 = __toESM(require("path"));
20345
20512
  var require_ = require;
20346
20513
  function resolveBin(pkgName, binName) {
20347
20514
  try {
20348
20515
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
20349
20516
  const manifest = require_(`${pkgName}/package.json`);
20350
- const pkgDir = path48.dirname(manifestPath);
20517
+ const pkgDir = path49.dirname(manifestPath);
20351
20518
  const bin = manifest.bin;
20352
20519
  if (!bin) return null;
20353
- if (typeof bin === "string") return path48.resolve(pkgDir, bin);
20520
+ if (typeof bin === "string") return path49.resolve(pkgDir, bin);
20354
20521
  const target = binName ?? Object.keys(bin)[0];
20355
20522
  if (!target || !bin[target]) return null;
20356
- return path48.resolve(pkgDir, bin[target]);
20523
+ return path49.resolve(pkgDir, bin[target]);
20357
20524
  } catch {
20358
20525
  return null;
20359
20526
  }
@@ -20423,9 +20590,9 @@ function requiresAcp(agent) {
20423
20590
  var import_node_crypto7 = require("crypto");
20424
20591
 
20425
20592
  // src/services/history.service.ts
20426
- var fs42 = __toESM(require("fs"));
20427
- var path49 = __toESM(require("path"));
20428
- var os35 = __toESM(require("os"));
20593
+ var fs43 = __toESM(require("fs"));
20594
+ var path50 = __toESM(require("path"));
20595
+ var os36 = __toESM(require("os"));
20429
20596
  var https7 = __toESM(require("https"));
20430
20597
  var http6 = __toESM(require("http"));
20431
20598
  var import_zod2 = require("zod");
@@ -20452,7 +20619,7 @@ function parseJsonl(filePath) {
20452
20619
  const messages = [];
20453
20620
  let raw;
20454
20621
  try {
20455
- raw = fs42.readFileSync(filePath, "utf8");
20622
+ raw = fs43.readFileSync(filePath, "utf8");
20456
20623
  } catch (err) {
20457
20624
  if (err.code !== "ENOENT") {
20458
20625
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -20593,7 +20760,7 @@ var HistoryService = class _HistoryService {
20593
20760
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
20594
20761
  }
20595
20762
  get projectDir() {
20596
- return this.runtime.resolveHistoryDir(this.cwd) ?? path49.join(os35.homedir(), ".claude", "projects", encodeCwd(this.cwd));
20763
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path50.join(os36.homedir(), ".claude", "projects", encodeCwd(this.cwd));
20597
20764
  }
20598
20765
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
20599
20766
  setCurrentConversationId(id) {
@@ -20605,7 +20772,7 @@ var HistoryService = class _HistoryService {
20605
20772
  /** Return the current message count in the active conversation. */
20606
20773
  getCurrentMessageCount() {
20607
20774
  if (!this.currentConversationId) return 0;
20608
- const filePath = path49.join(this.projectDir, `${this.currentConversationId}.jsonl`);
20775
+ const filePath = path50.join(this.projectDir, `${this.currentConversationId}.jsonl`);
20609
20776
  return parseJsonl(filePath).length;
20610
20777
  }
20611
20778
  /**
@@ -20616,7 +20783,7 @@ var HistoryService = class _HistoryService {
20616
20783
  const deadline = Date.now() + timeoutMs;
20617
20784
  while (Date.now() < deadline) {
20618
20785
  if (!this.currentConversationId) return null;
20619
- const filePath = path49.join(this.projectDir, `${this.currentConversationId}.jsonl`);
20786
+ const filePath = path50.join(this.projectDir, `${this.currentConversationId}.jsonl`);
20620
20787
  const messages = parseJsonl(filePath);
20621
20788
  if (messages.length > previousCount) {
20622
20789
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -20642,16 +20809,16 @@ var HistoryService = class _HistoryService {
20642
20809
  const dir = this.projectDir;
20643
20810
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
20644
20811
  try {
20645
- const files = fs42.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20812
+ const files = fs43.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20646
20813
  try {
20647
- const stat3 = fs42.statSync(path49.join(dir, e.name));
20814
+ const stat3 = fs43.statSync(path50.join(dir, e.name));
20648
20815
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
20649
20816
  } catch {
20650
20817
  return { name: e.name, mtime: 0, birthtime: 0 };
20651
20818
  }
20652
20819
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
20653
20820
  if (files.length > 0) {
20654
- this.currentConversationId = path49.basename(files[0].name, ".jsonl");
20821
+ this.currentConversationId = path50.basename(files[0].name, ".jsonl");
20655
20822
  }
20656
20823
  } catch {
20657
20824
  }
@@ -20685,13 +20852,13 @@ var HistoryService = class _HistoryService {
20685
20852
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
20686
20853
  let entries;
20687
20854
  try {
20688
- entries = fs42.readdirSync(dir, { withFileTypes: true });
20855
+ entries = fs43.readdirSync(dir, { withFileTypes: true });
20689
20856
  } catch {
20690
20857
  return null;
20691
20858
  }
20692
20859
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20693
20860
  try {
20694
- const stat3 = fs42.statSync(path49.join(dir, e.name));
20861
+ const stat3 = fs43.statSync(path50.join(dir, e.name));
20695
20862
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
20696
20863
  } catch {
20697
20864
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -20700,12 +20867,12 @@ var HistoryService = class _HistoryService {
20700
20867
  if (files.length === 0) return null;
20701
20868
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
20702
20869
  if (!files.some((f) => f.name === targetFile)) return null;
20703
- return this.extractUsageFromFile(path49.join(dir, targetFile));
20870
+ return this.extractUsageFromFile(path50.join(dir, targetFile));
20704
20871
  }
20705
20872
  extractUsageFromFile(filePath) {
20706
20873
  let raw;
20707
20874
  try {
20708
- raw = fs42.readFileSync(filePath, "utf8");
20875
+ raw = fs43.readFileSync(filePath, "utf8");
20709
20876
  } catch {
20710
20877
  return null;
20711
20878
  }
@@ -20750,9 +20917,9 @@ var HistoryService = class _HistoryService {
20750
20917
  let totalCost = 0;
20751
20918
  let files;
20752
20919
  try {
20753
- files = fs42.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
20920
+ files = fs43.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
20754
20921
  try {
20755
- return fs42.statSync(path49.join(projectDir, f)).mtimeMs >= monthStartMs;
20922
+ return fs43.statSync(path50.join(projectDir, f)).mtimeMs >= monthStartMs;
20756
20923
  } catch {
20757
20924
  return false;
20758
20925
  }
@@ -20763,7 +20930,7 @@ var HistoryService = class _HistoryService {
20763
20930
  for (const file of files) {
20764
20931
  let raw;
20765
20932
  try {
20766
- raw = fs42.readFileSync(path49.join(projectDir, file), "utf8");
20933
+ raw = fs43.readFileSync(path50.join(projectDir, file), "utf8");
20767
20934
  } catch {
20768
20935
  continue;
20769
20936
  }
@@ -20842,7 +21009,7 @@ var HistoryService = class _HistoryService {
20842
21009
  if (this.runtime.resolveHistoryFile) {
20843
21010
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
20844
21011
  }
20845
- return path49.join(this.projectDir, `${sessionId}.jsonl`);
21012
+ return path50.join(this.projectDir, `${sessionId}.jsonl`);
20846
21013
  }
20847
21014
  /**
20848
21015
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -20876,7 +21043,7 @@ var HistoryService = class _HistoryService {
20876
21043
  };
20877
21044
  });
20878
21045
  }
20879
- return parseJsonl(path49.join(this.projectDir, `${sessionId}.jsonl`));
21046
+ return parseJsonl(path50.join(this.projectDir, `${sessionId}.jsonl`));
20880
21047
  }
20881
21048
  async loadConversation(sessionId) {
20882
21049
  const messages = this.readConversation(sessionId);
@@ -20932,7 +21099,7 @@ var HistoryService = class _HistoryService {
20932
21099
  if (!filePath) return false;
20933
21100
  let mtimeMs;
20934
21101
  try {
20935
- mtimeMs = fs42.statSync(filePath).mtimeMs;
21102
+ mtimeMs = fs43.statSync(filePath).mtimeMs;
20936
21103
  } catch {
20937
21104
  return false;
20938
21105
  }
@@ -21001,10 +21168,10 @@ var HistoryService = class _HistoryService {
21001
21168
 
21002
21169
  // src/agents/acp/client.ts
21003
21170
  var import_node_child_process16 = require("child_process");
21004
- var fs43 = __toESM(require("fs/promises"));
21171
+ var fs44 = __toESM(require("fs/promises"));
21005
21172
  var fsSync = __toESM(require("fs"));
21006
- var os36 = __toESM(require("os"));
21007
- var path50 = __toESM(require("path"));
21173
+ var os37 = __toESM(require("os"));
21174
+ var path51 = __toESM(require("path"));
21008
21175
  var import_node_stream = require("stream");
21009
21176
 
21010
21177
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -23837,7 +24004,7 @@ var AcpClient = class {
23837
24004
  },
23838
24005
  readTextFile: async (params) => {
23839
24006
  try {
23840
- const content = await fs43.readFile(params.path, "utf8");
24007
+ const content = await fs44.readFile(params.path, "utf8");
23841
24008
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
23842
24009
  } catch (err) {
23843
24010
  const code = err.code;
@@ -23857,7 +24024,7 @@ var AcpClient = class {
23857
24024
  },
23858
24025
  writeTextFile: async (params) => {
23859
24026
  try {
23860
- await fs43.writeFile(params.path, params.content, "utf8");
24027
+ await fs44.writeFile(params.path, params.content, "utf8");
23861
24028
  return {};
23862
24029
  } catch (err) {
23863
24030
  const code = err.code;
@@ -23906,25 +24073,25 @@ function applyLineRange(content, line, limit) {
23906
24073
  return { content: lines.slice(start2, end).join("\n") };
23907
24074
  }
23908
24075
  function knownAgentBinaryDirs() {
23909
- const home = os36.homedir();
24076
+ const home = os37.homedir();
23910
24077
  const out2 = [];
23911
24078
  out2.push("/tmp/codeam-node20/bin");
23912
24079
  for (const root of [
23913
24080
  "/usr/local/share/nvm/versions/node",
23914
- path50.join(home, ".nvm/versions/node")
24081
+ path51.join(home, ".nvm/versions/node")
23915
24082
  ]) {
23916
24083
  try {
23917
24084
  for (const child of fsSync.readdirSync(root)) {
23918
- out2.push(path50.join(root, child, "bin"));
24085
+ out2.push(path51.join(root, child, "bin"));
23919
24086
  }
23920
24087
  } catch {
23921
24088
  }
23922
24089
  }
23923
- out2.push(path50.join(home, ".volta/bin"));
24090
+ out2.push(path51.join(home, ".volta/bin"));
23924
24091
  out2.push("/usr/local/bin");
23925
24092
  out2.push("/usr/bin");
23926
- out2.push(path50.join(home, ".local/bin"));
23927
- out2.push(path50.join(home, "bin"));
24093
+ out2.push(path51.join(home, ".local/bin"));
24094
+ out2.push(path51.join(home, "bin"));
23928
24095
  return out2.filter((p2) => {
23929
24096
  try {
23930
24097
  return fsSync.statSync(p2).isDirectory();
@@ -23935,7 +24102,7 @@ function knownAgentBinaryDirs() {
23935
24102
  }
23936
24103
  function expandPathForAgentBinaries(existingPath) {
23937
24104
  const existing = new Set(
23938
- existingPath.split(path50.delimiter).filter((p2) => p2.length > 0)
24105
+ existingPath.split(path51.delimiter).filter((p2) => p2.length > 0)
23939
24106
  );
23940
24107
  const additions = [];
23941
24108
  for (const dir of knownAgentBinaryDirs()) {
@@ -23945,7 +24112,7 @@ function expandPathForAgentBinaries(existingPath) {
23945
24112
  }
23946
24113
  }
23947
24114
  if (additions.length === 0) return existingPath;
23948
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path50.delimiter);
24115
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path51.delimiter);
23949
24116
  }
23950
24117
 
23951
24118
  // src/services/streaming/transport.ts
@@ -24357,15 +24524,15 @@ function commonPrefixLength(a, b) {
24357
24524
 
24358
24525
  // src/agents/acp/onboarding.ts
24359
24526
  var import_child_process22 = require("child_process");
24360
- var fs44 = __toESM(require("fs"));
24361
- var os37 = __toESM(require("os"));
24362
- var path51 = __toESM(require("path"));
24527
+ var fs45 = __toESM(require("fs"));
24528
+ var os38 = __toESM(require("os"));
24529
+ var path52 = __toESM(require("path"));
24363
24530
  var _onboardingSeam = {
24364
- markerPath: (sessionId) => path51.join(os37.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
24365
- exists: (p2) => fs44.existsSync(p2),
24531
+ markerPath: (sessionId) => path52.join(os38.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
24532
+ exists: (p2) => fs45.existsSync(p2),
24366
24533
  write: (p2) => {
24367
- fs44.mkdirSync(path51.dirname(p2), { recursive: true });
24368
- fs44.writeFileSync(p2, "");
24534
+ fs45.mkdirSync(path52.dirname(p2), { recursive: true });
24535
+ fs45.writeFileSync(p2, "");
24369
24536
  },
24370
24537
  disabled: () => {
24371
24538
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -24402,7 +24569,7 @@ function resolveRepoName(cwd) {
24402
24569
  if (name) return name;
24403
24570
  }
24404
24571
  }
24405
- const base = path51.basename(cwd || "");
24572
+ const base = path52.basename(cwd || "");
24406
24573
  if (base && !isUuid(base)) return base;
24407
24574
  return "this project";
24408
24575
  }
@@ -24675,13 +24842,28 @@ function extractSelectPrompt(text) {
24675
24842
  };
24676
24843
  }
24677
24844
 
24845
+ // src/agents/acp/inputSuggestion.ts
24846
+ var MIN_LEN = 8;
24847
+ var MAX_LEN = 200;
24848
+ function deriveInputSuggestion(finalText) {
24849
+ if (finalText.length === 0) return null;
24850
+ const lines = finalText.split("\n");
24851
+ let i = lines.length - 1;
24852
+ while (i >= 0 && lines[i].trim() === "") i--;
24853
+ if (i < 0) return null;
24854
+ const lastLine = lines[i].trim();
24855
+ if (!lastLine.endsWith("?")) return null;
24856
+ if (lastLine.length < MIN_LEN || lastLine.length > MAX_LEN) return null;
24857
+ return lastLine;
24858
+ }
24859
+
24678
24860
  // src/services/turn-files/turn-file-aggregator.ts
24679
24861
  var import_crypto5 = require("crypto");
24680
24862
 
24681
24863
  // src/services/turn-files/git-changeset.ts
24682
24864
  var import_child_process23 = require("child_process");
24683
- var fs45 = __toESM(require("fs/promises"));
24684
- var path52 = __toESM(require("path"));
24865
+ var fs46 = __toESM(require("fs/promises"));
24866
+ var path53 = __toESM(require("path"));
24685
24867
  async function collectRepoChangeset(opts) {
24686
24868
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
24687
24869
  if (status2 === null) return null;
@@ -24699,7 +24881,7 @@ async function collectRepoChangeset(opts) {
24699
24881
  let stats;
24700
24882
  if (row.fileStatus === "added" && numstatEntry === void 0) {
24701
24883
  const lineCount = await readUntrackedLineCount(
24702
- path52.join(opts.repoRoot, row.filePath)
24884
+ path53.join(opts.repoRoot, row.filePath)
24703
24885
  );
24704
24886
  stats = { added: lineCount, removed: 0 };
24705
24887
  } else {
@@ -24730,7 +24912,7 @@ function readUntrackedLineCount(absPath) {
24730
24912
  }
24731
24913
  async function defaultReadUntrackedLineCount(absPath) {
24732
24914
  try {
24733
- const content = await fs45.readFile(absPath, "utf8");
24915
+ const content = await fs46.readFile(absPath, "utf8");
24734
24916
  let count = 0;
24735
24917
  let pos = -1;
24736
24918
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -24822,7 +25004,7 @@ function defaultRunGit(cwd, args2) {
24822
25004
  });
24823
25005
  }
24824
25006
  async function discoverRepos(workingDir, maxDepth = 4) {
24825
- const fs49 = await import("fs/promises");
25007
+ const fs50 = await import("fs/promises");
24826
25008
  const out2 = [];
24827
25009
  await walk(workingDir, 0);
24828
25010
  return out2;
@@ -24830,7 +25012,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
24830
25012
  if (depth > maxDepth) return;
24831
25013
  let entries = [];
24832
25014
  try {
24833
- const dirents = await fs49.readdir(dir, { withFileTypes: true });
25015
+ const dirents = await fs50.readdir(dir, { withFileTypes: true });
24834
25016
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
24835
25017
  } catch {
24836
25018
  return;
@@ -24841,8 +25023,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
24841
25023
  if (hasGit) {
24842
25024
  out2.push({
24843
25025
  repoRoot: dir,
24844
- repoPath: path52.relative(workingDir, dir),
24845
- repoName: path52.basename(dir)
25026
+ repoPath: path53.relative(workingDir, dir),
25027
+ repoName: path53.basename(dir)
24846
25028
  });
24847
25029
  return;
24848
25030
  }
@@ -24850,14 +25032,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
24850
25032
  if (!entry.isDirectory) continue;
24851
25033
  if (entry.name === "node_modules") continue;
24852
25034
  if (entry.name === "dist" || entry.name === "build") continue;
24853
- await walk(path52.join(dir, entry.name), depth + 1);
25035
+ await walk(path53.join(dir, entry.name), depth + 1);
24854
25036
  }
24855
25037
  }
24856
25038
  }
24857
25039
 
24858
25040
  // src/services/turn-files/files-outbox.ts
24859
- var fs46 = __toESM(require("fs/promises"));
24860
- var path53 = __toESM(require("path"));
25041
+ var fs47 = __toESM(require("fs/promises"));
25042
+ var path54 = __toESM(require("path"));
24861
25043
  var import_os7 = require("os");
24862
25044
  var HOME_OUTBOX_DIR = ".codeam/outbox";
24863
25045
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -24890,16 +25072,16 @@ var FilesOutbox = class {
24890
25072
  backoffIndex = 0;
24891
25073
  stopped = false;
24892
25074
  constructor(opts) {
24893
- const base = opts.baseDir ?? path53.join(homeDir(), HOME_OUTBOX_DIR);
24894
- this.filePath = path53.join(base, `${opts.sessionId}.jsonl`);
25075
+ const base = opts.baseDir ?? path54.join(homeDir(), HOME_OUTBOX_DIR);
25076
+ this.filePath = path54.join(base, `${opts.sessionId}.jsonl`);
24895
25077
  this.post = opts.post;
24896
25078
  this.autoSchedule = opts.autoSchedule !== false;
24897
25079
  }
24898
25080
  /** Persist the entry to disk and trigger a flush. Returns once the
24899
25081
  * line is durable on disk (not once the POST succeeds). */
24900
25082
  async enqueue(entry) {
24901
- await fs46.mkdir(path53.dirname(this.filePath), { recursive: true });
24902
- await fs46.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25083
+ await fs47.mkdir(path54.dirname(this.filePath), { recursive: true });
25084
+ await fs47.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
24903
25085
  this.backoffIndex = 0;
24904
25086
  if (this.autoSchedule) this.scheduleFlush(0);
24905
25087
  }
@@ -24988,7 +25170,7 @@ var FilesOutbox = class {
24988
25170
  async readAll() {
24989
25171
  let raw = "";
24990
25172
  try {
24991
- raw = await fs46.readFile(this.filePath, "utf8");
25173
+ raw = await fs47.readFile(this.filePath, "utf8");
24992
25174
  } catch {
24993
25175
  return [];
24994
25176
  }
@@ -25012,12 +25194,12 @@ var FilesOutbox = class {
25012
25194
  async rewrite(entries) {
25013
25195
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
25014
25196
  if (entries.length === 0) {
25015
- await fs46.unlink(this.filePath).catch(() => void 0);
25197
+ await fs47.unlink(this.filePath).catch(() => void 0);
25016
25198
  return;
25017
25199
  }
25018
25200
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
25019
- await fs46.writeFile(tmpPath, payload, "utf8");
25020
- await fs46.rename(tmpPath, this.filePath);
25201
+ await fs47.writeFile(tmpPath, payload, "utf8");
25202
+ await fs47.rename(tmpPath, this.filePath);
25021
25203
  }
25022
25204
  };
25023
25205
  function applyJitter(ms) {
@@ -25546,7 +25728,7 @@ var StreamingState = class {
25546
25728
  this.publisher.publishOutput({ type: "text", content: finalText, done: true }),
25547
25729
  flushSc
25548
25730
  ]);
25549
- return;
25731
+ return false;
25550
25732
  }
25551
25733
  log.info(
25552
25734
  "acpRunner",
@@ -25573,6 +25755,7 @@ var StreamingState = class {
25573
25755
  done: true
25574
25756
  });
25575
25757
  await flushSc;
25758
+ return true;
25576
25759
  }
25577
25760
  };
25578
25761
  var PERMISSION_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -25946,7 +26129,9 @@ async function runAcpSession(opts) {
25946
26129
  flushHistory: () => void history.flush(),
25947
26130
  beginTurn: () => streaming.beginTurn(),
25948
26131
  getCurrentText: () => streaming.getCurrentText(),
25949
- closeTurn: () => streaming.closeTurnWithInteractiveDetection(),
26132
+ closeTurn: async () => {
26133
+ await streaming.closeTurnWithInteractiveDetection();
26134
+ },
25950
26135
  recoverFromFailedTurn: () => recoverFromFailedTurn(client2, streaming),
25951
26136
  reconnectWith1mDisabled,
25952
26137
  promptAgent: (blocks) => client2.prompt(blocks),
@@ -26147,13 +26332,19 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
26147
26332
  } else if (shouldOfferOneMRecovery({ detail: "", recentStderr: recentStderr.join("\n"), finalText })) {
26148
26333
  await oneMRecovery.offer(cmd.id, blocks);
26149
26334
  } else {
26150
- await streaming.closeTurnWithInteractiveDetection();
26335
+ const emittedSelectPrompt = await streaming.closeTurnWithInteractiveDetection();
26151
26336
  const replyLine = formatAgentReplyLine(finalText);
26152
26337
  if (replyLine.length > 0) {
26153
26338
  showInfo(replyLine);
26154
26339
  }
26155
26340
  history.appendAgentReply(finalText);
26156
26341
  void history.flush();
26342
+ if (!emittedSelectPrompt) {
26343
+ const suggestion = deriveInputSuggestion(finalText);
26344
+ if (suggestion !== null) {
26345
+ void publisher.publishOutput({ type: "input_suggestion", content: suggestion, done: true });
26346
+ }
26347
+ }
26157
26348
  turnFiles.flushTurn().catch((err) => {
26158
26349
  log.warn("acpRunner", `turnFiles.flushTurn failed: ${describeError(err)}`);
26159
26350
  });
@@ -27527,15 +27718,15 @@ function fetchQuotaUsage(runtime, historySvc) {
27527
27718
  }
27528
27719
 
27529
27720
  // src/agents/claude/onboarding.ts
27530
- var fs47 = __toESM(require("fs"));
27531
- var os38 = __toESM(require("os"));
27532
- var path54 = __toESM(require("path"));
27721
+ var fs48 = __toESM(require("fs"));
27722
+ var os39 = __toESM(require("os"));
27723
+ var path55 = __toESM(require("path"));
27533
27724
  function ensureClaudeOnboarded() {
27534
27725
  try {
27535
- const file = path54.join(os38.homedir(), ".claude.json");
27726
+ const file = path55.join(os39.homedir(), ".claude.json");
27536
27727
  let config = {};
27537
27728
  try {
27538
- config = JSON.parse(fs47.readFileSync(file, "utf8"));
27729
+ config = JSON.parse(fs48.readFileSync(file, "utf8"));
27539
27730
  } catch {
27540
27731
  }
27541
27732
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -27546,8 +27737,8 @@ function ensureClaudeOnboarded() {
27546
27737
  if (typeof config.lastOnboardingVersion !== "string") {
27547
27738
  config.lastOnboardingVersion = "2.1.177";
27548
27739
  }
27549
- fs47.mkdirSync(path54.dirname(file), { recursive: true });
27550
- fs47.writeFileSync(file, JSON.stringify(config, null, 2));
27740
+ fs48.mkdirSync(path55.dirname(file), { recursive: true });
27741
+ fs48.writeFileSync(file, JSON.stringify(config, null, 2));
27551
27742
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
27552
27743
  } catch (err) {
27553
27744
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -28197,7 +28388,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
28197
28388
  var import_child_process24 = require("child_process");
28198
28389
  var import_util4 = require("util");
28199
28390
  var import_picocolors9 = __toESM(require("picocolors"));
28200
- var path55 = __toESM(require("path"));
28391
+ var path56 = __toESM(require("path"));
28201
28392
  var execFileP6 = (0, import_util4.promisify)(import_child_process24.execFile);
28202
28393
  var MAX_BUFFER = 8 * 1024 * 1024;
28203
28394
  function resetStdinForChild() {
@@ -28686,7 +28877,7 @@ var GitHubCodespacesProvider = class {
28686
28877
  });
28687
28878
  }
28688
28879
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
28689
- const remoteDir = path55.posix.dirname(remotePath);
28880
+ const remoteDir = path56.posix.dirname(remotePath);
28690
28881
  const parts = [
28691
28882
  `mkdir -p ${shellQuote(remoteDir)}`,
28692
28883
  `cat > ${shellQuote(remotePath)}`
@@ -28756,7 +28947,7 @@ function shellQuote(s) {
28756
28947
  // src/services/providers/gitpod.ts
28757
28948
  var import_child_process25 = require("child_process");
28758
28949
  var import_util5 = require("util");
28759
- var path56 = __toESM(require("path"));
28950
+ var path57 = __toESM(require("path"));
28760
28951
  var import_picocolors10 = __toESM(require("picocolors"));
28761
28952
  var execFileP7 = (0, import_util5.promisify)(import_child_process25.execFile);
28762
28953
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -28996,7 +29187,7 @@ var GitpodProvider = class {
28996
29187
  });
28997
29188
  }
28998
29189
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
28999
- const remoteDir = path56.posix.dirname(remotePath);
29190
+ const remoteDir = path57.posix.dirname(remotePath);
29000
29191
  const parts = [
29001
29192
  `mkdir -p ${shellQuote2(remoteDir)}`,
29002
29193
  `cat > ${shellQuote2(remotePath)}`
@@ -29032,7 +29223,7 @@ function shellQuote2(s) {
29032
29223
  // src/services/providers/gitlab-workspaces.ts
29033
29224
  var import_child_process26 = require("child_process");
29034
29225
  var import_util6 = require("util");
29035
- var path57 = __toESM(require("path"));
29226
+ var path58 = __toESM(require("path"));
29036
29227
  var execFileP8 = (0, import_util6.promisify)(import_child_process26.execFile);
29037
29228
  var MAX_BUFFER3 = 8 * 1024 * 1024;
29038
29229
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -29292,7 +29483,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
29292
29483
  }
29293
29484
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29294
29485
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
29295
- const remoteDir = path57.posix.dirname(remotePath);
29486
+ const remoteDir = path58.posix.dirname(remotePath);
29296
29487
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
29297
29488
  if (options.mode != null) {
29298
29489
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -29360,7 +29551,7 @@ function shellQuote3(s) {
29360
29551
  // src/services/providers/railway.ts
29361
29552
  var import_child_process27 = require("child_process");
29362
29553
  var import_util7 = require("util");
29363
- var path58 = __toESM(require("path"));
29554
+ var path59 = __toESM(require("path"));
29364
29555
  var execFileP9 = (0, import_util7.promisify)(import_child_process27.execFile);
29365
29556
  var MAX_BUFFER4 = 8 * 1024 * 1024;
29366
29557
  function resetStdinForChild4() {
@@ -29596,7 +29787,7 @@ var RailwayProvider = class {
29596
29787
  if (!projectId || !serviceId) {
29597
29788
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
29598
29789
  }
29599
- const remoteDir = path58.posix.dirname(remotePath);
29790
+ const remoteDir = path59.posix.dirname(remotePath);
29600
29791
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
29601
29792
  if (options.mode != null) {
29602
29793
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -30242,8 +30433,8 @@ async function invite() {
30242
30433
  var import_node_dns = require("dns");
30243
30434
  var import_node_util5 = require("util");
30244
30435
  var import_node_crypto8 = require("crypto");
30245
- var fs48 = __toESM(require("fs"));
30246
- var path59 = __toESM(require("path"));
30436
+ var fs49 = __toESM(require("fs"));
30437
+ var path60 = __toESM(require("path"));
30247
30438
  var import_picocolors14 = __toESM(require("picocolors"));
30248
30439
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
30249
30440
  async function checkDns(apiBase2) {
@@ -30299,13 +30490,13 @@ async function checkHealth(apiBase2) {
30299
30490
  }
30300
30491
  }
30301
30492
  function checkConfigDir() {
30302
- const dir = path59.join(require("os").homedir(), ".codeam");
30493
+ const dir = path60.join(require("os").homedir(), ".codeam");
30303
30494
  try {
30304
- fs48.mkdirSync(dir, { recursive: true, mode: 448 });
30305
- const probe = path59.join(dir, ".doctor-probe");
30306
- fs48.writeFileSync(probe, "ok", { mode: 384 });
30307
- const read2 = fs48.readFileSync(probe, "utf8");
30308
- fs48.unlinkSync(probe);
30495
+ fs49.mkdirSync(dir, { recursive: true, mode: 448 });
30496
+ const probe = path60.join(dir, ".doctor-probe");
30497
+ fs49.writeFileSync(probe, "ok", { mode: 384 });
30498
+ const read2 = fs49.readFileSync(probe, "utf8");
30499
+ fs49.unlinkSync(probe);
30309
30500
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
30310
30501
  return {
30311
30502
  id: "config-dir",
@@ -30345,9 +30536,9 @@ function checkSessions() {
30345
30536
  }
30346
30537
  }
30347
30538
  function checkAgentBinaries() {
30348
- const os40 = createOsStrategy();
30539
+ const os41 = createOsStrategy();
30349
30540
  return getEnabledAgents().map((meta) => {
30350
- const found = os40.findInPath(meta.binaryName);
30541
+ const found = os41.findInPath(meta.binaryName);
30351
30542
  return {
30352
30543
  id: `agent-${meta.id}`,
30353
30544
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -30369,7 +30560,7 @@ function checkNodePty() {
30369
30560
  detail: "not required on this platform"
30370
30561
  };
30371
30562
  }
30372
- const vendoredPath = path59.join(__dirname, "vendor", "node-pty");
30563
+ const vendoredPath = path60.join(__dirname, "vendor", "node-pty");
30373
30564
  for (const target of [vendoredPath, "node-pty"]) {
30374
30565
  try {
30375
30566
  require(target);
@@ -30411,7 +30602,7 @@ function checkChokidar() {
30411
30602
  }
30412
30603
  async function doctor(args2 = []) {
30413
30604
  const json = args2.includes("--json");
30414
- const cliVersion = true ? "2.49.5" : "0.0.0-dev";
30605
+ const cliVersion = true ? "2.50.0" : "0.0.0-dev";
30415
30606
  const apiBase2 = resolveApiBaseUrl();
30416
30607
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
30417
30608
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -30610,7 +30801,7 @@ async function completion(args2) {
30610
30801
  // src/commands/version.ts
30611
30802
  var import_picocolors15 = __toESM(require("picocolors"));
30612
30803
  function version2() {
30613
- const v = true ? "2.49.5" : "unknown";
30804
+ const v = true ? "2.50.0" : "unknown";
30614
30805
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
30615
30806
  }
30616
30807
 
@@ -30759,10 +30950,10 @@ var EXIT_CODE_NAMES = {
30759
30950
  };
30760
30951
 
30761
30952
  // src/index.ts
30762
- var os39 = __toESM(require("os"));
30953
+ var os40 = __toESM(require("os"));
30763
30954
  if (!process.env.HOME) {
30764
30955
  try {
30765
- const home = os39.homedir();
30956
+ const home = os40.homedir();
30766
30957
  if (home) process.env.HOME = home;
30767
30958
  } catch {
30768
30959
  }