codeam-cli 2.21.0 → 2.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/index.js +323 -211
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -441,7 +441,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
441
441
  // package.json
442
442
  var package_default = {
443
443
  name: "codeam-cli",
444
- version: "2.21.0",
444
+ version: "2.21.2",
445
445
  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.",
446
446
  type: "commonjs",
447
447
  main: "dist/index.js",
@@ -735,7 +735,7 @@ async function postLinkCredential(input) {
735
735
  }
736
736
  }
737
737
  async function _postJsonAuthed(url, body, pluginAuthToken) {
738
- return new Promise((resolve4, reject) => {
738
+ return new Promise((resolve5, reject) => {
739
739
  const data = JSON.stringify(body);
740
740
  const u2 = new URL(url);
741
741
  const transport = u2.protocol === "https:" ? https : http;
@@ -767,9 +767,9 @@ async function _postJsonAuthed(url, body, pluginAuthToken) {
767
767
  return;
768
768
  }
769
769
  try {
770
- resolve4(JSON.parse(responseBody));
770
+ resolve5(JSON.parse(responseBody));
771
771
  } catch {
772
- resolve4(null);
772
+ resolve5(null);
773
773
  }
774
774
  });
775
775
  }
@@ -784,7 +784,7 @@ async function _postJsonAuthed(url, body, pluginAuthToken) {
784
784
  });
785
785
  }
786
786
  async function _postJson(url, body) {
787
- return new Promise((resolve4, reject) => {
787
+ return new Promise((resolve5, reject) => {
788
788
  const data = JSON.stringify(body);
789
789
  const u2 = new URL(url);
790
790
  const transport = u2.protocol === "https:" ? https : http;
@@ -813,9 +813,9 @@ async function _postJson(url, body) {
813
813
  return;
814
814
  }
815
815
  try {
816
- resolve4(JSON.parse(body2));
816
+ resolve5(JSON.parse(body2));
817
817
  } catch {
818
- resolve4(null);
818
+ resolve5(null);
819
819
  }
820
820
  });
821
821
  }
@@ -830,7 +830,7 @@ async function _postJson(url, body) {
830
830
  });
831
831
  }
832
832
  async function _getJson(url) {
833
- return new Promise((resolve4, reject) => {
833
+ return new Promise((resolve5, reject) => {
834
834
  const u2 = new URL(url);
835
835
  const transport = u2.protocol === "https:" ? https : http;
836
836
  const req = transport.request(
@@ -854,9 +854,9 @@ async function _getJson(url) {
854
854
  return;
855
855
  }
856
856
  try {
857
- resolve4(JSON.parse(body));
857
+ resolve5(JSON.parse(body));
858
858
  } catch {
859
- resolve4(null);
859
+ resolve5(null);
860
860
  }
861
861
  });
862
862
  }
@@ -1026,8 +1026,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
1026
1026
  return decodedFile;
1027
1027
  };
1028
1028
  }
1029
- function normalizeWindowsPath(path39) {
1030
- return path39.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1029
+ function normalizeWindowsPath(path40) {
1030
+ return path40.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1031
1031
  }
1032
1032
 
1033
1033
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3507,15 +3507,15 @@ async function addSourceContext(frames) {
3507
3507
  LRU_FILE_CONTENTS_CACHE.reduce();
3508
3508
  return frames;
3509
3509
  }
3510
- function getContextLinesFromFile(path39, ranges, output) {
3511
- return new Promise((resolve4) => {
3512
- const stream = (0, import_node_fs.createReadStream)(path39);
3510
+ function getContextLinesFromFile(path40, ranges, output) {
3511
+ return new Promise((resolve5) => {
3512
+ const stream = (0, import_node_fs.createReadStream)(path40);
3513
3513
  const lineReaded = (0, import_node_readline.createInterface)({
3514
3514
  input: stream
3515
3515
  });
3516
3516
  function destroyStreamAndResolve() {
3517
3517
  stream.destroy();
3518
- resolve4();
3518
+ resolve5();
3519
3519
  }
3520
3520
  let lineNumber = 0;
3521
3521
  let currentRangeIndex = 0;
@@ -3524,7 +3524,7 @@ function getContextLinesFromFile(path39, ranges, output) {
3524
3524
  let rangeStart = range[0];
3525
3525
  let rangeEnd = range[1];
3526
3526
  function onStreamError() {
3527
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path39, 1);
3527
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path40, 1);
3528
3528
  lineReaded.close();
3529
3529
  lineReaded.removeAllListeners();
3530
3530
  destroyStreamAndResolve();
@@ -3585,8 +3585,8 @@ function clearLineContext(frame) {
3585
3585
  delete frame.context_line;
3586
3586
  delete frame.post_context;
3587
3587
  }
3588
- function shouldSkipContextLinesForFile(path39) {
3589
- return path39.startsWith("node:") || path39.endsWith(".min.js") || path39.endsWith(".min.cjs") || path39.endsWith(".min.mjs") || path39.startsWith("data:");
3588
+ function shouldSkipContextLinesForFile(path40) {
3589
+ return path40.startsWith("node:") || path40.endsWith(".min.js") || path40.endsWith(".min.cjs") || path40.endsWith(".min.mjs") || path40.startsWith("data:");
3590
3590
  }
3591
3591
  function shouldSkipContextLinesForFrame(frame) {
3592
3592
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -4802,9 +4802,9 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4802
4802
  if (!waitUntil) return;
4803
4803
  if (this.disabled || this.optedOut) return;
4804
4804
  if (!this._waitUntilCycle) {
4805
- let resolve4;
4805
+ let resolve5;
4806
4806
  const promise = new Promise((r) => {
4807
- resolve4 = r;
4807
+ resolve5 = r;
4808
4808
  });
4809
4809
  try {
4810
4810
  waitUntil(promise);
@@ -4812,7 +4812,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4812
4812
  return;
4813
4813
  }
4814
4814
  this._waitUntilCycle = {
4815
- resolve: resolve4,
4815
+ resolve: resolve5,
4816
4816
  startedAt: Date.now(),
4817
4817
  timer: void 0
4818
4818
  };
@@ -4836,12 +4836,12 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4836
4836
  return cycle?.resolve;
4837
4837
  }
4838
4838
  async resolveWaitUntilFlush() {
4839
- const resolve4 = this._consumeWaitUntilCycle();
4839
+ const resolve5 = this._consumeWaitUntilCycle();
4840
4840
  try {
4841
4841
  await super.flush();
4842
4842
  } catch {
4843
4843
  } finally {
4844
- resolve4?.();
4844
+ resolve5?.();
4845
4845
  }
4846
4846
  }
4847
4847
  getPersistedProperty(key) {
@@ -4933,15 +4933,15 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4933
4933
  async waitForLocalEvaluationReady(timeoutMs = THIRTY_SECONDS) {
4934
4934
  if (this.isLocalEvaluationReady()) return true;
4935
4935
  if (void 0 === this.featureFlagsPoller) return false;
4936
- return new Promise((resolve4) => {
4936
+ return new Promise((resolve5) => {
4937
4937
  const timeout = setTimeout(() => {
4938
4938
  cleanup();
4939
- resolve4(false);
4939
+ resolve5(false);
4940
4940
  }, timeoutMs);
4941
4941
  const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
4942
4942
  clearTimeout(timeout);
4943
4943
  cleanup();
4944
- resolve4(count > 0);
4944
+ resolve5(count > 0);
4945
4945
  });
4946
4946
  });
4947
4947
  }
@@ -5378,13 +5378,13 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5378
5378
  this.context?.enter(data, options);
5379
5379
  }
5380
5380
  async _shutdown(shutdownTimeoutMs) {
5381
- const resolve4 = this._consumeWaitUntilCycle();
5381
+ const resolve5 = this._consumeWaitUntilCycle();
5382
5382
  await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
5383
5383
  this.errorTracking.shutdown();
5384
5384
  try {
5385
5385
  return await super._shutdown(shutdownTimeoutMs);
5386
5386
  } finally {
5387
- resolve4?.();
5387
+ resolve5?.();
5388
5388
  }
5389
5389
  }
5390
5390
  async _requestRemoteConfigPayload(flagKey) {
@@ -5740,7 +5740,7 @@ function readAnonId() {
5740
5740
  }
5741
5741
  function superProperties() {
5742
5742
  return {
5743
- cliVersion: true ? "2.21.0" : "0.0.0-dev",
5743
+ cliVersion: true ? "2.21.2" : "0.0.0-dev",
5744
5744
  nodeVersion: process.version,
5745
5745
  platform: process.platform,
5746
5746
  arch: process.arch,
@@ -8874,15 +8874,15 @@ function runInstaller() {
8874
8874
  "-Command",
8875
8875
  "irm https://claude.ai/install.ps1 | iex"
8876
8876
  ] : ["-c", "curl -fsSL https://claude.ai/install.sh | bash"];
8877
- return new Promise((resolve4) => {
8877
+ return new Promise((resolve5) => {
8878
8878
  const proc = (0, import_child_process4.spawn)(cmd, args2, { stdio: "inherit" });
8879
8879
  proc.on("error", (err) => {
8880
8880
  console.error(`
8881
8881
  \u2717 Installer failed to launch: ${err.message}`);
8882
- resolve4(false);
8882
+ resolve5(false);
8883
8883
  });
8884
8884
  proc.on("exit", (code) => {
8885
- resolve4(code === 0);
8885
+ resolve5(code === 0);
8886
8886
  });
8887
8887
  });
8888
8888
  }
@@ -9045,17 +9045,17 @@ function parseUsageOutput(raw) {
9045
9045
  return { percent, resetAt };
9046
9046
  }
9047
9047
  async function fetchClaudeQuota() {
9048
- return new Promise((resolve4) => {
9048
+ return new Promise((resolve5) => {
9049
9049
  const claudeCmd = findInPath("claude") ? "claude" : "claude-code";
9050
9050
  if (!claudeCmd) {
9051
- resolve4(null);
9051
+ resolve5(null);
9052
9052
  return;
9053
9053
  }
9054
9054
  const helperPath = path11.join(os10.tmpdir(), "codeam-quota-helper.py");
9055
9055
  fs8.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
9056
9056
  const python = findInPath("python3") ?? findInPath("python");
9057
9057
  if (!python) {
9058
- resolve4(null);
9058
+ resolve5(null);
9059
9059
  return;
9060
9060
  }
9061
9061
  const proc = (0, import_child_process5.spawn)(python, [helperPath, claudeCmd, "--tools", ""], {
@@ -9082,13 +9082,13 @@ async function fetchClaudeQuota() {
9082
9082
  fs8.unlinkSync(helperPath);
9083
9083
  } catch {
9084
9084
  }
9085
- resolve4(result);
9085
+ resolve5(result);
9086
9086
  }, 5e3);
9087
9087
  }, 8e3);
9088
9088
  setTimeout(() => {
9089
9089
  if (!resolved) {
9090
9090
  resolved = true;
9091
- resolve4(null);
9091
+ resolve5(null);
9092
9092
  }
9093
9093
  try {
9094
9094
  proc.kill();
@@ -10428,12 +10428,12 @@ function resolveNpm(os26) {
10428
10428
  return os26.id === "win32" ? "npm.cmd" : "npm";
10429
10429
  }
10430
10430
  async function installCodexViaNpm(os26) {
10431
- return new Promise((resolve4, reject) => {
10431
+ return new Promise((resolve5, reject) => {
10432
10432
  const proc = (0, import_node_child_process4.spawn)(resolveNpm(os26), ["install", "-g", "@openai/codex"], {
10433
10433
  stdio: "inherit"
10434
10434
  });
10435
10435
  proc.on("close", (code) => {
10436
- if (code === 0) resolve4();
10436
+ if (code === 0) resolve5();
10437
10437
  else reject(new Error(`npm install -g @openai/codex exited ${code}`));
10438
10438
  });
10439
10439
  proc.on("error", (err) => {
@@ -10548,12 +10548,12 @@ async function ensureCoderabbitInstalled(os26) {
10548
10548
  return false;
10549
10549
  }
10550
10550
  console.log("\n CodeRabbit CLI not found \u2014 installing via the official script\u2026\n");
10551
- const ok = await new Promise((resolve4) => {
10551
+ const ok = await new Promise((resolve5) => {
10552
10552
  const proc = (0, import_node_child_process5.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL} | sh`], {
10553
10553
  stdio: "inherit"
10554
10554
  });
10555
- proc.on("close", (code) => resolve4(code === 0));
10556
- proc.on("error", () => resolve4(false));
10555
+ proc.on("close", (code) => resolve5(code === 0));
10556
+ proc.on("error", () => resolve5(false));
10557
10557
  });
10558
10558
  if (!ok) return false;
10559
10559
  os26.augmentPath([`${os26.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
@@ -10610,11 +10610,11 @@ function parseReview(stdout) {
10610
10610
  for (const line of lines) {
10611
10611
  const m = line.match(HUNK_LINE_RE);
10612
10612
  if (!m) continue;
10613
- const [, path39, lineNo, sevToken, message] = m;
10614
- if (!path39 || !lineNo || !message) continue;
10613
+ const [, path40, lineNo, sevToken, message] = m;
10614
+ if (!path40 || !lineNo || !message) continue;
10615
10615
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
10616
10616
  hunks.push({
10617
- path: path39.trim(),
10617
+ path: path40.trim(),
10618
10618
  line: Number(lineNo),
10619
10619
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
10620
10620
  message: cleanedMessage
@@ -10672,7 +10672,7 @@ var CoderabbitRuntimeStrategy = class {
10672
10672
  }
10673
10673
  async runOneShot(input) {
10674
10674
  const launch = await this.prepareInvocation(input);
10675
- return new Promise((resolve4, reject) => {
10675
+ return new Promise((resolve5, reject) => {
10676
10676
  const stdoutBuf = [];
10677
10677
  const stderrBuf = [];
10678
10678
  const proc = (0, import_node_child_process7.spawn)(launch.cmd, launch.args, {
@@ -10683,7 +10683,7 @@ var CoderabbitRuntimeStrategy = class {
10683
10683
  proc.stderr?.on("data", (b) => stderrBuf.push(b));
10684
10684
  proc.on("error", (err) => reject(err));
10685
10685
  proc.on("close", (code) => {
10686
- resolve4(
10686
+ resolve5(
10687
10687
  this.parseOutput({
10688
10688
  exitCode: code ?? 0,
10689
10689
  stdout: Buffer.concat(stdoutBuf).toString("utf8"),
@@ -11216,14 +11216,14 @@ var ChunkEmitter = class {
11216
11216
  "chunkEmitter",
11217
11217
  `send type=${body.type ?? "(clear)"} bytes=${payload.length} done=${body.done === true}`
11218
11218
  );
11219
- return new Promise((resolve4) => {
11219
+ return new Promise((resolve5) => {
11220
11220
  const attempt = (attemptsLeft) => {
11221
11221
  _transport2.post(this.url, this.headers, payload).then(({ statusCode, body: resBody }) => {
11222
11222
  const tookMs = Date.now() - t0;
11223
11223
  if (statusCode === 410 || statusCode === 404 && /SESSION_NOT_FOUND|SESSION_GONE/.test(resBody)) {
11224
11224
  process.stderr.write("[codeam] session was deleted/disconnected \u2014 stopping output stream.\n");
11225
11225
  log.info("chunkEmitter", `dead status=${statusCode} took=${tookMs}ms`);
11226
- resolve4({ dead: true });
11226
+ resolve5({ dead: true });
11227
11227
  return;
11228
11228
  }
11229
11229
  if (statusCode >= 400) {
@@ -11233,7 +11233,7 @@ var ChunkEmitter = class {
11233
11233
  } else {
11234
11234
  log.info("chunkEmitter", `ok status=${statusCode} took=${tookMs}ms`);
11235
11235
  }
11236
- resolve4({ dead: false });
11236
+ resolve5({ dead: false });
11237
11237
  }).catch((err) => {
11238
11238
  log.warn(
11239
11239
  "chunkEmitter",
@@ -11244,7 +11244,7 @@ var ChunkEmitter = class {
11244
11244
  const delay = 200 * (maxRetries - attemptsLeft + 1);
11245
11245
  setTimeout(() => attempt(attemptsLeft - 1), delay);
11246
11246
  } else {
11247
- resolve4({ dead: false });
11247
+ resolve5({ dead: false });
11248
11248
  }
11249
11249
  });
11250
11250
  };
@@ -11256,7 +11256,7 @@ var _transport2 = {
11256
11256
  post: _post
11257
11257
  };
11258
11258
  function _post(url, headers, payload) {
11259
- return new Promise((resolve4, reject) => {
11259
+ return new Promise((resolve5, reject) => {
11260
11260
  let settled = false;
11261
11261
  const u2 = new URL(url);
11262
11262
  const transport = u2.protocol === "https:" ? https3 : http3;
@@ -11280,7 +11280,7 @@ function _post(url, headers, payload) {
11280
11280
  res.on("end", () => {
11281
11281
  if (settled) return;
11282
11282
  settled = true;
11283
- resolve4({ statusCode: res.statusCode ?? 0, body: resData });
11283
+ resolve5({ statusCode: res.statusCode ?? 0, body: resData });
11284
11284
  });
11285
11285
  }
11286
11286
  );
@@ -11781,7 +11781,7 @@ function parseJsonl(filePath) {
11781
11781
  return messages;
11782
11782
  }
11783
11783
  function post(endpoint, body) {
11784
- return new Promise((resolve4) => {
11784
+ return new Promise((resolve5) => {
11785
11785
  const payload = JSON.stringify(body);
11786
11786
  const u2 = new URL(`${API_BASE4}${endpoint}`);
11787
11787
  const transport = u2.protocol === "https:" ? https4 : http4;
@@ -11802,17 +11802,17 @@ function post(endpoint, body) {
11802
11802
  res.resume();
11803
11803
  const ok = res.statusCode !== void 0 && res.statusCode >= 200 && res.statusCode < 300;
11804
11804
  if (!ok) log.warn("history:post", `${endpoint} \u2192 HTTP ${res.statusCode}`);
11805
- resolve4(ok);
11805
+ resolve5(ok);
11806
11806
  }
11807
11807
  );
11808
11808
  req.on("error", (err) => {
11809
11809
  log.warn("history:post", `${endpoint} network error`, err);
11810
- resolve4(false);
11810
+ resolve5(false);
11811
11811
  });
11812
11812
  req.on("timeout", () => {
11813
11813
  log.warn("history:post", `${endpoint} timeout after 15s`);
11814
11814
  req.destroy();
11815
- resolve4(false);
11815
+ resolve5(false);
11816
11816
  });
11817
11817
  req.write(payload);
11818
11818
  req.end();
@@ -12296,7 +12296,7 @@ var _transport3 = {
12296
12296
  post: _post2
12297
12297
  };
12298
12298
  function _post2(url, headers, payload) {
12299
- return new Promise((resolve4, reject) => {
12299
+ return new Promise((resolve5, reject) => {
12300
12300
  let settled = false;
12301
12301
  const u2 = new URL(url);
12302
12302
  const lib = u2.protocol === "https:" ? https5 : http5;
@@ -12321,7 +12321,7 @@ function _post2(url, headers, payload) {
12321
12321
  res.on("end", () => {
12322
12322
  if (settled) return;
12323
12323
  settled = true;
12324
- resolve4({ statusCode: res.statusCode ?? 0, body });
12324
+ resolve5({ statusCode: res.statusCode ?? 0, body });
12325
12325
  });
12326
12326
  }
12327
12327
  );
@@ -12691,6 +12691,7 @@ var FileWatcherService = class {
12691
12691
  "X-Plugin-Auth-Token": this.opts.pluginAuthToken
12692
12692
  };
12693
12693
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt += 1) {
12694
+ if (this.stopped) return;
12694
12695
  try {
12695
12696
  const { statusCode, body: resBody } = await _transport3.post(url, headers, payload);
12696
12697
  if (statusCode >= 200 && statusCode < 300) {
@@ -12739,12 +12740,12 @@ var _gitSeam = {
12739
12740
  run: _runGitImpl
12740
12741
  };
12741
12742
  async function _runGitImpl(cwd, args2, opts = {}) {
12742
- return new Promise((resolve4) => {
12743
+ return new Promise((resolve5) => {
12743
12744
  let proc;
12744
12745
  try {
12745
12746
  proc = (0, import_child_process7.spawn)("git", args2, { cwd, env: process.env });
12746
12747
  } catch {
12747
- resolve4(null);
12748
+ resolve5(null);
12748
12749
  return;
12749
12750
  }
12750
12751
  let stdout = "";
@@ -12755,13 +12756,13 @@ async function _runGitImpl(cwd, args2, opts = {}) {
12755
12756
  proc.stderr?.on("data", (c2) => {
12756
12757
  stderr += c2.toString();
12757
12758
  });
12758
- proc.on("error", () => resolve4(null));
12759
+ proc.on("error", () => resolve5(null));
12759
12760
  proc.on("close", (code) => {
12760
12761
  if (code === 0 || opts.allowNonZeroExit) {
12761
- resolve4(stdout);
12762
+ resolve5(stdout);
12762
12763
  } else {
12763
12764
  log.trace("fileWatcher", `git ${args2.join(" ")} exited ${code} stderr=${stderr.slice(0, 200)}`);
12764
- resolve4(null);
12765
+ resolve5(null);
12765
12766
  }
12766
12767
  });
12767
12768
  });
@@ -12854,12 +12855,12 @@ function runGit2(cwd, args2) {
12854
12855
  return _runGitImpl2.run(cwd, args2);
12855
12856
  }
12856
12857
  function defaultRunGit(cwd, args2) {
12857
- return new Promise((resolve4) => {
12858
+ return new Promise((resolve5) => {
12858
12859
  let proc;
12859
12860
  try {
12860
12861
  proc = (0, import_child_process8.spawn)("git", args2, { cwd, env: process.env });
12861
12862
  } catch {
12862
- resolve4(null);
12863
+ resolve5(null);
12863
12864
  return;
12864
12865
  }
12865
12866
  let stdout = "";
@@ -12870,22 +12871,22 @@ function defaultRunGit(cwd, args2) {
12870
12871
  proc.stderr?.on("data", (c2) => {
12871
12872
  stderr += c2.toString();
12872
12873
  });
12873
- proc.on("error", () => resolve4(null));
12874
+ proc.on("error", () => resolve5(null));
12874
12875
  proc.on("close", (code) => {
12875
12876
  if (code === 0) {
12876
- resolve4(stdout);
12877
+ resolve5(stdout);
12877
12878
  } else {
12878
12879
  log.trace(
12879
12880
  "turnFiles",
12880
12881
  `git ${args2.join(" ")} exited ${code} stderr=${stderr.slice(0, 200)}`
12881
12882
  );
12882
- resolve4(null);
12883
+ resolve5(null);
12883
12884
  }
12884
12885
  });
12885
12886
  });
12886
12887
  }
12887
12888
  async function discoverRepos(workingDir, maxDepth = 4) {
12888
- const fs30 = await import("fs/promises");
12889
+ const fs31 = await import("fs/promises");
12889
12890
  const out2 = [];
12890
12891
  await walk(workingDir, 0);
12891
12892
  return out2;
@@ -12893,7 +12894,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
12893
12894
  if (depth > maxDepth) return;
12894
12895
  let entries = [];
12895
12896
  try {
12896
- const dirents = await fs30.readdir(dir, { withFileTypes: true });
12897
+ const dirents = await fs31.readdir(dir, { withFileTypes: true });
12897
12898
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
12898
12899
  } catch {
12899
12900
  return;
@@ -13265,7 +13266,7 @@ var _transport4 = {
13265
13266
  get: _get
13266
13267
  };
13267
13268
  function _post3(url, headers, payload) {
13268
- return new Promise((resolve4, reject) => {
13269
+ return new Promise((resolve5, reject) => {
13269
13270
  let settled = false;
13270
13271
  const u2 = new URL(url);
13271
13272
  const lib = u2.protocol === "https:" ? https6 : http6;
@@ -13290,7 +13291,7 @@ function _post3(url, headers, payload) {
13290
13291
  res.on("end", () => {
13291
13292
  if (settled) return;
13292
13293
  settled = true;
13293
- resolve4({ statusCode: res.statusCode ?? 0, body });
13294
+ resolve5({ statusCode: res.statusCode ?? 0, body });
13294
13295
  });
13295
13296
  }
13296
13297
  );
@@ -13307,7 +13308,7 @@ function _post3(url, headers, payload) {
13307
13308
  });
13308
13309
  }
13309
13310
  function _get(url, headers) {
13310
- return new Promise((resolve4, reject) => {
13311
+ return new Promise((resolve5, reject) => {
13311
13312
  let settled = false;
13312
13313
  const u2 = new URL(url);
13313
13314
  const lib = u2.protocol === "https:" ? https6 : http6;
@@ -13331,7 +13332,7 @@ function _get(url, headers) {
13331
13332
  res.on("end", () => {
13332
13333
  if (settled) return;
13333
13334
  settled = true;
13334
- resolve4({ statusCode: res.statusCode ?? 0, body });
13335
+ resolve5({ statusCode: res.statusCode ?? 0, body });
13335
13336
  });
13336
13337
  }
13337
13338
  );
@@ -13714,7 +13715,7 @@ function buildKeepAlive(ctx) {
13714
13715
  let timer = null;
13715
13716
  async function setIdleTimeout(minutes) {
13716
13717
  if (!ctx.inCodespace || !ctx.codespaceName) return;
13717
- await new Promise((resolve4) => {
13718
+ await new Promise((resolve5) => {
13718
13719
  const proc = (0, import_child_process9.spawn)(
13719
13720
  "gh",
13720
13721
  [
@@ -13728,8 +13729,8 @@ function buildKeepAlive(ctx) {
13728
13729
  { stdio: "ignore", detached: true }
13729
13730
  );
13730
13731
  proc.unref();
13731
- proc.on("exit", () => resolve4());
13732
- proc.on("error", () => resolve4());
13732
+ proc.on("exit", () => resolve5());
13733
+ proc.on("error", () => resolve5());
13733
13734
  });
13734
13735
  }
13735
13736
  return {
@@ -13752,11 +13753,11 @@ function buildKeepAlive(ctx) {
13752
13753
  }
13753
13754
 
13754
13755
  // src/commands/start/handlers.ts
13755
- var fs25 = __toESM(require("fs"));
13756
+ var fs26 = __toESM(require("fs"));
13756
13757
  var os23 = __toESM(require("os"));
13757
- var path31 = __toESM(require("path"));
13758
+ var path32 = __toESM(require("path"));
13758
13759
  var import_crypto5 = require("crypto");
13759
- var import_child_process12 = require("child_process");
13760
+ var import_child_process13 = require("child_process");
13760
13761
 
13761
13762
  // src/lib/payload.ts
13762
13763
  var import_zod2 = require("zod");
@@ -13804,7 +13805,15 @@ var startCommandSchema = import_zod2.z.object({
13804
13805
  data: import_zod2.z.string().max(64 * 1024).optional(),
13805
13806
  cwd: import_zod2.z.string().max(4096).optional(),
13806
13807
  cols: import_zod2.z.number().int().min(1).max(500).optional(),
13807
- rows: import_zod2.z.number().int().min(1).max(200).optional()
13808
+ rows: import_zod2.z.number().int().min(1).max(200).optional(),
13809
+ // `apply_file_review` (Epic B follow-up — backend pushes this when
13810
+ // the user clicks APPROVE_CHANGES / REJECT_CHANGES in the diff
13811
+ // drawer). `filePath` is relative to the enclosing git repo; the
13812
+ // handler walks up from it to find `.git/` and runs `git add` or
13813
+ // `git restore` from there. `action='approved'` stages the edit,
13814
+ // `action='rejected'` discards every worktree change on the file.
13815
+ filePath: import_zod2.z.string().min(1).max(4096).optional(),
13816
+ action: import_zod2.z.enum(["approved", "rejected"]).optional()
13808
13817
  });
13809
13818
  function parsePayload2(schema, raw) {
13810
13819
  const result = schema.safeParse(raw);
@@ -14560,12 +14569,96 @@ function closeAllTerminals() {
14560
14569
  for (const id of Array.from(sessions.keys())) closeTerminal(id);
14561
14570
  }
14562
14571
 
14572
+ // src/services/apply-file-review.service.ts
14573
+ var import_child_process12 = require("child_process");
14574
+ var fs25 = __toESM(require("fs"));
14575
+ var path31 = __toESM(require("path"));
14576
+ async function applyFileReview(workingDir, filePath, action) {
14577
+ if (filePath.includes("..") || path31.isAbsolute(filePath)) {
14578
+ return { ok: false, action, filePath, error: "invalid file path" };
14579
+ }
14580
+ const absFile = path31.resolve(workingDir, filePath);
14581
+ const repoRoot = findGitRoot2(path31.dirname(absFile));
14582
+ if (!repoRoot) {
14583
+ return {
14584
+ ok: false,
14585
+ action,
14586
+ filePath,
14587
+ error: `no enclosing git repo for ${filePath}`
14588
+ };
14589
+ }
14590
+ const relInRepo = path31.relative(repoRoot, absFile);
14591
+ if (!relInRepo || relInRepo.startsWith("..")) {
14592
+ return { ok: false, action, filePath, error: "path escapes repo root" };
14593
+ }
14594
+ const args2 = action === "approved" ? ["add", "--", relInRepo] : ["restore", "--", relInRepo];
14595
+ const result = await runGit3(repoRoot, args2);
14596
+ if (!result.ok) {
14597
+ return {
14598
+ ok: false,
14599
+ action,
14600
+ filePath,
14601
+ repoRoot,
14602
+ error: result.stderr.slice(0, 500) || `git ${args2[0]} exited ${result.code}`
14603
+ };
14604
+ }
14605
+ log.info(
14606
+ "reviewApply",
14607
+ `git ${args2[0]} ${relInRepo} in ${repoRoot} \u2014 ok`
14608
+ );
14609
+ return { ok: true, action, filePath, repoRoot };
14610
+ }
14611
+ function runGit3(cwd, args2) {
14612
+ return new Promise((resolve5) => {
14613
+ let proc;
14614
+ try {
14615
+ proc = (0, import_child_process12.spawn)("git", args2, { cwd, env: process.env });
14616
+ } catch (err) {
14617
+ resolve5({ ok: false, code: -1, stdout: "", stderr: err.message });
14618
+ return;
14619
+ }
14620
+ let stdout = "";
14621
+ let stderr = "";
14622
+ proc.stdout?.on("data", (c2) => {
14623
+ stdout += c2.toString();
14624
+ });
14625
+ proc.stderr?.on("data", (c2) => {
14626
+ stderr += c2.toString();
14627
+ });
14628
+ proc.on(
14629
+ "error",
14630
+ (err) => resolve5({ ok: false, code: -1, stdout, stderr: stderr + err.message })
14631
+ );
14632
+ proc.on(
14633
+ "close",
14634
+ (code) => resolve5({ ok: code === 0, code: code ?? -1, stdout, stderr })
14635
+ );
14636
+ });
14637
+ }
14638
+ function findGitRoot2(startDir) {
14639
+ let dir = path31.resolve(startDir);
14640
+ const seen = /* @__PURE__ */ new Set();
14641
+ for (let i = 0; i < 256; i++) {
14642
+ if (seen.has(dir)) return null;
14643
+ seen.add(dir);
14644
+ try {
14645
+ const stat3 = fs25.statSync(path31.join(dir, ".git"), { throwIfNoEntry: false });
14646
+ if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
14647
+ } catch {
14648
+ }
14649
+ const parent = path31.dirname(dir);
14650
+ if (parent === dir) return null;
14651
+ dir = parent;
14652
+ }
14653
+ return null;
14654
+ }
14655
+
14563
14656
  // src/commands/start/handlers.ts
14564
14657
  var pendingAttachmentFiles = /* @__PURE__ */ new Set();
14565
14658
  function cleanupAttachmentTempFiles() {
14566
14659
  for (const p2 of pendingAttachmentFiles) {
14567
14660
  try {
14568
- fs25.unlinkSync(p2);
14661
+ fs26.unlinkSync(p2);
14569
14662
  } catch {
14570
14663
  }
14571
14664
  }
@@ -14574,8 +14667,8 @@ function cleanupAttachmentTempFiles() {
14574
14667
  function saveFilesTemp(files) {
14575
14668
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
14576
14669
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
14577
- const tmpPath = path31.join(os23.tmpdir(), `codeam-${(0, import_crypto5.randomUUID)()}-${safeName}`);
14578
- fs25.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
14670
+ const tmpPath = path32.join(os23.tmpdir(), `codeam-${(0, import_crypto5.randomUUID)()}-${safeName}`);
14671
+ fs26.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
14579
14672
  pendingAttachmentFiles.add(tmpPath);
14580
14673
  return tmpPath;
14581
14674
  });
@@ -14595,7 +14688,7 @@ var startTask = (ctx, _cmd, parsed) => {
14595
14688
  setTimeout(() => {
14596
14689
  for (const p2 of paths) {
14597
14690
  try {
14598
- fs25.unlinkSync(p2);
14691
+ fs26.unlinkSync(p2);
14599
14692
  } catch {
14600
14693
  }
14601
14694
  pendingAttachmentFiles.delete(p2);
@@ -14708,7 +14801,7 @@ var sessionTerminated = (ctx) => {
14708
14801
  } catch {
14709
14802
  }
14710
14803
  try {
14711
- const proc = (0, import_child_process12.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
14804
+ const proc = (0, import_child_process13.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
14712
14805
  detached: true,
14713
14806
  stdio: "ignore"
14714
14807
  });
@@ -14730,7 +14823,7 @@ var shutdownSession = async (ctx, cmd) => {
14730
14823
  }
14731
14824
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
14732
14825
  try {
14733
- const stopProc = (0, import_child_process12.spawn)(
14826
+ const stopProc = (0, import_child_process13.spawn)(
14734
14827
  "bash",
14735
14828
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
14736
14829
  { detached: true, stdio: "ignore" }
@@ -14740,7 +14833,7 @@ var shutdownSession = async (ctx, cmd) => {
14740
14833
  }
14741
14834
  }
14742
14835
  try {
14743
- const proc = (0, import_child_process12.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
14836
+ const proc = (0, import_child_process13.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
14744
14837
  detached: true,
14745
14838
  stdio: "ignore"
14746
14839
  });
@@ -14863,6 +14956,24 @@ var gitResolveH = async (ctx, cmd, parsed) => {
14863
14956
  const result = await gitResolve(parsed.path, parsed.side);
14864
14957
  await ctx.relay.sendResult(cmd.id, "completed", result);
14865
14958
  };
14959
+ var applyFileReviewH = async (ctx, cmd, parsed) => {
14960
+ if (!parsed.filePath || !parsed.action) {
14961
+ await ctx.relay.sendResult(cmd.id, "failed", {
14962
+ error: "Missing filePath or action"
14963
+ });
14964
+ return;
14965
+ }
14966
+ const result = await applyFileReview(
14967
+ process.cwd(),
14968
+ parsed.filePath,
14969
+ parsed.action
14970
+ );
14971
+ await ctx.relay.sendResult(
14972
+ cmd.id,
14973
+ result.ok ? "completed" : "failed",
14974
+ result
14975
+ );
14976
+ };
14866
14977
  var handlers = {
14867
14978
  start_task: startTask,
14868
14979
  provide_input: provideInput,
@@ -14893,7 +15004,8 @@ var handlers = {
14893
15004
  git_commit: gitCommitH,
14894
15005
  git_push: gitPushH,
14895
15006
  git_pull: gitPullH,
14896
- git_resolve: gitResolveH
15007
+ git_resolve: gitResolveH,
15008
+ apply_file_review: applyFileReviewH
14897
15009
  };
14898
15010
  async function dispatchCommand(ctx, cmd) {
14899
15011
  const parsed = parsePayload2(startCommandSchema, cmd.payload);
@@ -15173,7 +15285,7 @@ async function pair(args2 = []) {
15173
15285
  waitSpin.message(waitMessage());
15174
15286
  }, 1e3);
15175
15287
  countdownInterval.unref?.();
15176
- await new Promise((resolve4) => {
15288
+ await new Promise((resolve5) => {
15177
15289
  let stopPolling = null;
15178
15290
  function sigintHandler() {
15179
15291
  clearInterval(countdownInterval);
@@ -15213,7 +15325,7 @@ async function pair(args2 = []) {
15213
15325
  });
15214
15326
  showSuccess(`Paired with ${info.userName} (${info.plan})`);
15215
15327
  console.log("");
15216
- resolve4();
15328
+ resolve5();
15217
15329
  },
15218
15330
  () => {
15219
15331
  clearInterval(countdownInterval);
@@ -15229,7 +15341,7 @@ async function pair(args2 = []) {
15229
15341
  }
15230
15342
 
15231
15343
  // src/commands/pair-auto.ts
15232
- var fs26 = __toESM(require("fs"));
15344
+ var fs27 = __toESM(require("fs"));
15233
15345
  var os24 = __toESM(require("os"));
15234
15346
  var import_crypto7 = require("crypto");
15235
15347
  var API_BASE8 = resolveApiBaseUrl();
@@ -15247,12 +15359,12 @@ function readTokenFromArgs(args2) {
15247
15359
  }
15248
15360
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
15249
15361
  if (fileFlag) {
15250
- const path39 = fileFlag.slice("--token-file=".length);
15362
+ const path40 = fileFlag.slice("--token-file=".length);
15251
15363
  try {
15252
- const content = fs26.readFileSync(path39, "utf8").trim();
15253
- if (content.length === 0) fail(`--token-file ${path39} is empty`);
15364
+ const content = fs27.readFileSync(path40, "utf8").trim();
15365
+ if (content.length === 0) fail(`--token-file ${path40} is empty`);
15254
15366
  try {
15255
- fs26.unlinkSync(path39);
15367
+ fs27.unlinkSync(path40);
15256
15368
  } catch {
15257
15369
  }
15258
15370
  return content;
@@ -15502,11 +15614,11 @@ async function logout() {
15502
15614
  var import_picocolors9 = __toESM(require("picocolors"));
15503
15615
 
15504
15616
  // src/services/providers/github-codespaces.ts
15505
- var import_child_process13 = require("child_process");
15617
+ var import_child_process14 = require("child_process");
15506
15618
  var import_util3 = require("util");
15507
15619
  var import_picocolors7 = __toESM(require("picocolors"));
15508
- var path32 = __toESM(require("path"));
15509
- var execFileP4 = (0, import_util3.promisify)(import_child_process13.execFile);
15620
+ var path33 = __toESM(require("path"));
15621
+ var execFileP4 = (0, import_util3.promisify)(import_child_process14.execFile);
15510
15622
  var MAX_BUFFER = 8 * 1024 * 1024;
15511
15623
  function resetStdinForChild() {
15512
15624
  if (process.stdin.isTTY) {
@@ -15549,12 +15661,12 @@ var GitHubCodespacesProvider = class {
15549
15661
  }
15550
15662
  if (!isAuthed) {
15551
15663
  resetStdinForChild();
15552
- await new Promise((resolve4, reject) => {
15553
- const proc = (0, import_child_process13.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
15664
+ await new Promise((resolve5, reject) => {
15665
+ const proc = (0, import_child_process14.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
15554
15666
  stdio: "inherit"
15555
15667
  });
15556
15668
  proc.on("exit", (code) => {
15557
- if (code === 0) resolve4();
15669
+ if (code === 0) resolve5();
15558
15670
  else reject(new Error("gh auth login failed."));
15559
15671
  });
15560
15672
  proc.on("error", reject);
@@ -15583,13 +15695,13 @@ var GitHubCodespacesProvider = class {
15583
15695
  }
15584
15696
  wt(noteLines.join("\n"), "One more permission needed");
15585
15697
  resetStdinForChild();
15586
- const refreshCode = await new Promise((resolve4, reject) => {
15587
- const proc = (0, import_child_process13.spawn)(
15698
+ const refreshCode = await new Promise((resolve5, reject) => {
15699
+ const proc = (0, import_child_process14.spawn)(
15588
15700
  "gh",
15589
15701
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
15590
15702
  { stdio: "inherit" }
15591
15703
  );
15592
- proc.on("exit", (code) => resolve4(code ?? 1));
15704
+ proc.on("exit", (code) => resolve5(code ?? 1));
15593
15705
  proc.on("error", reject);
15594
15706
  });
15595
15707
  if (refreshCode !== 0) {
@@ -15733,10 +15845,10 @@ var GitHubCodespacesProvider = class {
15733
15845
  if (q(proceed) || !proceed) return;
15734
15846
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
15735
15847
  resetStdinForChild();
15736
- const ok = await new Promise((resolve4) => {
15737
- const proc = (0, import_child_process13.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
15738
- proc.on("exit", (code) => resolve4(code === 0));
15739
- proc.on("error", () => resolve4(false));
15848
+ const ok = await new Promise((resolve5) => {
15849
+ const proc = (0, import_child_process14.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
15850
+ proc.on("exit", (code) => resolve5(code === 0));
15851
+ proc.on("error", () => resolve5(false));
15740
15852
  });
15741
15853
  if (ok) O2.success("gh installed");
15742
15854
  else O2.error("gh install failed");
@@ -15760,14 +15872,14 @@ var GitHubCodespacesProvider = class {
15760
15872
  "Expanding GitHub scopes"
15761
15873
  );
15762
15874
  resetStdinForChild();
15763
- await new Promise((resolve4, reject) => {
15764
- const proc = (0, import_child_process13.spawn)(
15875
+ await new Promise((resolve5, reject) => {
15876
+ const proc = (0, import_child_process14.spawn)(
15765
15877
  "gh",
15766
15878
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
15767
15879
  { stdio: "inherit" }
15768
15880
  );
15769
15881
  proc.on("exit", (code) => {
15770
- if (code === 0) resolve4();
15882
+ if (code === 0) resolve5();
15771
15883
  else reject(new Error(
15772
15884
  "gh auth refresh failed. Re-run `gh auth refresh -h github.com -s repo,read:org` manually."
15773
15885
  ));
@@ -15938,13 +16050,13 @@ var GitHubCodespacesProvider = class {
15938
16050
  }
15939
16051
  async streamCommand(workspaceId, command2) {
15940
16052
  resetStdinForChild();
15941
- return new Promise((resolve4, reject) => {
15942
- const proc = (0, import_child_process13.spawn)(
16053
+ return new Promise((resolve5, reject) => {
16054
+ const proc = (0, import_child_process14.spawn)(
15943
16055
  "gh",
15944
16056
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
15945
16057
  { stdio: "inherit" }
15946
16058
  );
15947
- proc.on("exit", (code) => resolve4({ code: code ?? 0 }));
16059
+ proc.on("exit", (code) => resolve5({ code: code ?? 0 }));
15948
16060
  proc.on("error", reject);
15949
16061
  });
15950
16062
  }
@@ -15965,12 +16077,12 @@ var GitHubCodespacesProvider = class {
15965
16077
  "--",
15966
16078
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
15967
16079
  ];
15968
- await new Promise((resolve4, reject) => {
15969
- const tar = (0, import_child_process13.spawn)("tar", tarArgs, {
16080
+ await new Promise((resolve5, reject) => {
16081
+ const tar = (0, import_child_process14.spawn)("tar", tarArgs, {
15970
16082
  stdio: ["ignore", "pipe", "pipe"],
15971
16083
  env: tarEnv
15972
16084
  });
15973
- const ssh = (0, import_child_process13.spawn)("gh", sshArgs, {
16085
+ const ssh = (0, import_child_process14.spawn)("gh", sshArgs, {
15974
16086
  stdio: [tar.stdout, "pipe", "pipe"]
15975
16087
  });
15976
16088
  let tarErr = "";
@@ -15985,7 +16097,7 @@ var GitHubCodespacesProvider = class {
15985
16097
  ssh.on("error", reject);
15986
16098
  ssh.on("exit", (code) => {
15987
16099
  if (code === 0) {
15988
- resolve4();
16100
+ resolve5();
15989
16101
  } else {
15990
16102
  const reason = (sshErr || tarErr || `exit ${code}`).trim().slice(0, 500);
15991
16103
  reject(new Error(`Remote tar failed: ${reason}`));
@@ -15994,7 +16106,7 @@ var GitHubCodespacesProvider = class {
15994
16106
  });
15995
16107
  }
15996
16108
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
15997
- const remoteDir = path32.posix.dirname(remotePath);
16109
+ const remoteDir = path33.posix.dirname(remotePath);
15998
16110
  const parts = [
15999
16111
  `mkdir -p ${shellQuote(remoteDir)}`,
16000
16112
  `cat > ${shellQuote(remotePath)}`
@@ -16003,8 +16115,8 @@ var GitHubCodespacesProvider = class {
16003
16115
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote(remotePath)}`);
16004
16116
  }
16005
16117
  const cmd = parts.join(" && ");
16006
- await new Promise((resolve4, reject) => {
16007
- const proc = (0, import_child_process13.spawn)(
16118
+ await new Promise((resolve5, reject) => {
16119
+ const proc = (0, import_child_process14.spawn)(
16008
16120
  "gh",
16009
16121
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
16010
16122
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -16015,7 +16127,7 @@ var GitHubCodespacesProvider = class {
16015
16127
  });
16016
16128
  proc.on("error", reject);
16017
16129
  proc.on("exit", (code) => {
16018
- if (code === 0) resolve4();
16130
+ if (code === 0) resolve5();
16019
16131
  else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
16020
16132
  });
16021
16133
  proc.stdin?.write(contents);
@@ -16062,11 +16174,11 @@ function shellQuote(s) {
16062
16174
  }
16063
16175
 
16064
16176
  // src/services/providers/gitpod.ts
16065
- var import_child_process14 = require("child_process");
16177
+ var import_child_process15 = require("child_process");
16066
16178
  var import_util4 = require("util");
16067
- var path33 = __toESM(require("path"));
16179
+ var path34 = __toESM(require("path"));
16068
16180
  var import_picocolors8 = __toESM(require("picocolors"));
16069
- var execFileP5 = (0, import_util4.promisify)(import_child_process14.execFile);
16181
+ var execFileP5 = (0, import_util4.promisify)(import_child_process15.execFile);
16070
16182
  var MAX_BUFFER2 = 8 * 1024 * 1024;
16071
16183
  function resetStdinForChild2() {
16072
16184
  if (process.stdin.isTTY) {
@@ -16105,10 +16217,10 @@ var GitpodProvider = class {
16105
16217
  "Authenticating Gitpod"
16106
16218
  );
16107
16219
  resetStdinForChild2();
16108
- await new Promise((resolve4, reject) => {
16109
- const proc = (0, import_child_process14.spawn)("gitpod", ["login"], { stdio: "inherit" });
16220
+ await new Promise((resolve5, reject) => {
16221
+ const proc = (0, import_child_process15.spawn)("gitpod", ["login"], { stdio: "inherit" });
16110
16222
  proc.on("exit", (code) => {
16111
- if (code === 0) resolve4();
16223
+ if (code === 0) resolve5();
16112
16224
  else reject(new Error("gitpod login failed."));
16113
16225
  });
16114
16226
  proc.on("error", reject);
@@ -16257,13 +16369,13 @@ var GitpodProvider = class {
16257
16369
  }
16258
16370
  async streamCommand(workspaceId, command2) {
16259
16371
  resetStdinForChild2();
16260
- return new Promise((resolve4, reject) => {
16261
- const proc = (0, import_child_process14.spawn)(
16372
+ return new Promise((resolve5, reject) => {
16373
+ const proc = (0, import_child_process15.spawn)(
16262
16374
  "gitpod",
16263
16375
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
16264
16376
  { stdio: "inherit" }
16265
16377
  );
16266
- proc.on("exit", (code) => resolve4({ code: code ?? 0 }));
16378
+ proc.on("exit", (code) => resolve5({ code: code ?? 0 }));
16267
16379
  proc.on("error", reject);
16268
16380
  });
16269
16381
  }
@@ -16277,12 +16389,12 @@ var GitpodProvider = class {
16277
16389
  tarArgs.push(".");
16278
16390
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
16279
16391
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
16280
- await new Promise((resolve4, reject) => {
16281
- const tar = (0, import_child_process14.spawn)("tar", tarArgs, {
16392
+ await new Promise((resolve5, reject) => {
16393
+ const tar = (0, import_child_process15.spawn)("tar", tarArgs, {
16282
16394
  stdio: ["ignore", "pipe", "pipe"],
16283
16395
  env: tarEnv
16284
16396
  });
16285
- const ssh = (0, import_child_process14.spawn)(
16397
+ const ssh = (0, import_child_process15.spawn)(
16286
16398
  "gitpod",
16287
16399
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
16288
16400
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -16298,13 +16410,13 @@ var GitpodProvider = class {
16298
16410
  tar.on("error", reject);
16299
16411
  ssh.on("error", reject);
16300
16412
  ssh.on("exit", (code) => {
16301
- if (code === 0) resolve4();
16413
+ if (code === 0) resolve5();
16302
16414
  else reject(new Error(`Remote tar failed: ${(sshErr || tarErr || `exit ${code}`).trim().slice(0, 500)}`));
16303
16415
  });
16304
16416
  });
16305
16417
  }
16306
16418
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
16307
- const remoteDir = path33.posix.dirname(remotePath);
16419
+ const remoteDir = path34.posix.dirname(remotePath);
16308
16420
  const parts = [
16309
16421
  `mkdir -p ${shellQuote2(remoteDir)}`,
16310
16422
  `cat > ${shellQuote2(remotePath)}`
@@ -16313,8 +16425,8 @@ var GitpodProvider = class {
16313
16425
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote2(remotePath)}`);
16314
16426
  }
16315
16427
  const cmd = parts.join(" && ");
16316
- await new Promise((resolve4, reject) => {
16317
- const proc = (0, import_child_process14.spawn)(
16428
+ await new Promise((resolve5, reject) => {
16429
+ const proc = (0, import_child_process15.spawn)(
16318
16430
  "gitpod",
16319
16431
  ["workspace", "ssh", workspaceId, "--", cmd],
16320
16432
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -16325,7 +16437,7 @@ var GitpodProvider = class {
16325
16437
  });
16326
16438
  proc.on("error", reject);
16327
16439
  proc.on("exit", (code) => {
16328
- if (code === 0) resolve4();
16440
+ if (code === 0) resolve5();
16329
16441
  else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
16330
16442
  });
16331
16443
  proc.stdin?.write(contents);
@@ -16338,10 +16450,10 @@ function shellQuote2(s) {
16338
16450
  }
16339
16451
 
16340
16452
  // src/services/providers/gitlab-workspaces.ts
16341
- var import_child_process15 = require("child_process");
16453
+ var import_child_process16 = require("child_process");
16342
16454
  var import_util5 = require("util");
16343
- var path34 = __toESM(require("path"));
16344
- var execFileP6 = (0, import_util5.promisify)(import_child_process15.execFile);
16455
+ var path35 = __toESM(require("path"));
16456
+ var execFileP6 = (0, import_util5.promisify)(import_child_process16.execFile);
16345
16457
  var MAX_BUFFER3 = 8 * 1024 * 1024;
16346
16458
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
16347
16459
  function resetStdinForChild3() {
@@ -16382,14 +16494,14 @@ var GitLabWorkspacesProvider = class {
16382
16494
  "Authenticating GitLab"
16383
16495
  );
16384
16496
  resetStdinForChild3();
16385
- await new Promise((resolve4, reject) => {
16386
- const proc = (0, import_child_process15.spawn)(
16497
+ await new Promise((resolve5, reject) => {
16498
+ const proc = (0, import_child_process16.spawn)(
16387
16499
  "glab",
16388
16500
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
16389
16501
  { stdio: "inherit" }
16390
16502
  );
16391
16503
  proc.on("exit", (code) => {
16392
- if (code === 0) resolve4();
16504
+ if (code === 0) resolve5();
16393
16505
  else reject(new Error("glab auth login failed."));
16394
16506
  });
16395
16507
  proc.on("error", reject);
@@ -16554,13 +16666,13 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
16554
16666
  async streamCommand(workspaceId, command2) {
16555
16667
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
16556
16668
  resetStdinForChild3();
16557
- return new Promise((resolve4, reject) => {
16558
- const proc = (0, import_child_process15.spawn)(
16669
+ return new Promise((resolve5, reject) => {
16670
+ const proc = (0, import_child_process16.spawn)(
16559
16671
  "ssh",
16560
16672
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
16561
16673
  { stdio: "inherit" }
16562
16674
  );
16563
- proc.on("exit", (code) => resolve4({ code: code ?? 0 }));
16675
+ proc.on("exit", (code) => resolve5({ code: code ?? 0 }));
16564
16676
  proc.on("error", reject);
16565
16677
  });
16566
16678
  }
@@ -16575,9 +16687,9 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
16575
16687
  tarArgs.push(".");
16576
16688
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
16577
16689
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
16578
- await new Promise((resolve4, reject) => {
16579
- const tar = (0, import_child_process15.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
16580
- const ssh = (0, import_child_process15.spawn)(
16690
+ await new Promise((resolve5, reject) => {
16691
+ const tar = (0, import_child_process16.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
16692
+ const ssh = (0, import_child_process16.spawn)(
16581
16693
  "ssh",
16582
16694
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
16583
16695
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -16593,21 +16705,21 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
16593
16705
  tar.on("error", reject);
16594
16706
  ssh.on("error", reject);
16595
16707
  ssh.on("exit", (code) => {
16596
- if (code === 0) resolve4();
16708
+ if (code === 0) resolve5();
16597
16709
  else reject(new Error(`Remote tar failed: ${(sshErr || tarErr || `exit ${code}`).trim().slice(0, 500)}`));
16598
16710
  });
16599
16711
  });
16600
16712
  }
16601
16713
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
16602
16714
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
16603
- const remoteDir = path34.posix.dirname(remotePath);
16715
+ const remoteDir = path35.posix.dirname(remotePath);
16604
16716
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
16605
16717
  if (options.mode != null) {
16606
16718
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
16607
16719
  }
16608
16720
  const cmd = parts.join(" && ");
16609
- await new Promise((resolve4, reject) => {
16610
- const proc = (0, import_child_process15.spawn)(
16721
+ await new Promise((resolve5, reject) => {
16722
+ const proc = (0, import_child_process16.spawn)(
16611
16723
  "ssh",
16612
16724
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
16613
16725
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -16618,7 +16730,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
16618
16730
  });
16619
16731
  proc.on("error", reject);
16620
16732
  proc.on("exit", (code) => {
16621
- if (code === 0) resolve4();
16733
+ if (code === 0) resolve5();
16622
16734
  else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
16623
16735
  });
16624
16736
  proc.stdin?.write(contents);
@@ -16666,10 +16778,10 @@ function shellQuote3(s) {
16666
16778
  }
16667
16779
 
16668
16780
  // src/services/providers/railway.ts
16669
- var import_child_process16 = require("child_process");
16781
+ var import_child_process17 = require("child_process");
16670
16782
  var import_util6 = require("util");
16671
- var path35 = __toESM(require("path"));
16672
- var execFileP7 = (0, import_util6.promisify)(import_child_process16.execFile);
16783
+ var path36 = __toESM(require("path"));
16784
+ var execFileP7 = (0, import_util6.promisify)(import_child_process17.execFile);
16673
16785
  var MAX_BUFFER4 = 8 * 1024 * 1024;
16674
16786
  function resetStdinForChild4() {
16675
16787
  if (process.stdin.isTTY) {
@@ -16709,10 +16821,10 @@ var RailwayProvider = class {
16709
16821
  "Authenticating Railway"
16710
16822
  );
16711
16823
  resetStdinForChild4();
16712
- await new Promise((resolve4, reject) => {
16713
- const proc = (0, import_child_process16.spawn)("railway", ["login"], { stdio: "inherit" });
16824
+ await new Promise((resolve5, reject) => {
16825
+ const proc = (0, import_child_process17.spawn)("railway", ["login"], { stdio: "inherit" });
16714
16826
  proc.on("exit", (code) => {
16715
- if (code === 0) resolve4();
16827
+ if (code === 0) resolve5();
16716
16828
  else reject(new Error("railway login failed."));
16717
16829
  });
16718
16830
  proc.on("error", reject);
@@ -16852,13 +16964,13 @@ var RailwayProvider = class {
16852
16964
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
16853
16965
  }
16854
16966
  resetStdinForChild4();
16855
- return new Promise((resolve4, reject) => {
16856
- const proc = (0, import_child_process16.spawn)(
16967
+ return new Promise((resolve5, reject) => {
16968
+ const proc = (0, import_child_process17.spawn)(
16857
16969
  "railway",
16858
16970
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
16859
16971
  { stdio: "inherit" }
16860
16972
  );
16861
- proc.on("exit", (code) => resolve4({ code: code ?? 0 }));
16973
+ proc.on("exit", (code) => resolve5({ code: code ?? 0 }));
16862
16974
  proc.on("error", reject);
16863
16975
  });
16864
16976
  }
@@ -16876,9 +16988,9 @@ var RailwayProvider = class {
16876
16988
  tarArgs.push(".");
16877
16989
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
16878
16990
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
16879
- await new Promise((resolve4, reject) => {
16880
- const tar = (0, import_child_process16.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
16881
- const sh = (0, import_child_process16.spawn)(
16991
+ await new Promise((resolve5, reject) => {
16992
+ const tar = (0, import_child_process17.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
16993
+ const sh = (0, import_child_process17.spawn)(
16882
16994
  "railway",
16883
16995
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
16884
16996
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -16894,7 +17006,7 @@ var RailwayProvider = class {
16894
17006
  tar.on("error", reject);
16895
17007
  sh.on("error", reject);
16896
17008
  sh.on("exit", (code) => {
16897
- if (code === 0) resolve4();
17009
+ if (code === 0) resolve5();
16898
17010
  else reject(new Error(`Remote tar failed: ${(shErr || tarErr || `exit ${code}`).trim().slice(0, 500)}`));
16899
17011
  });
16900
17012
  });
@@ -16904,14 +17016,14 @@ var RailwayProvider = class {
16904
17016
  if (!projectId || !serviceId) {
16905
17017
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
16906
17018
  }
16907
- const remoteDir = path35.posix.dirname(remotePath);
17019
+ const remoteDir = path36.posix.dirname(remotePath);
16908
17020
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
16909
17021
  if (options.mode != null) {
16910
17022
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
16911
17023
  }
16912
17024
  const cmd = parts.join(" && ");
16913
- await new Promise((resolve4, reject) => {
16914
- const proc = (0, import_child_process16.spawn)(
17025
+ await new Promise((resolve5, reject) => {
17026
+ const proc = (0, import_child_process17.spawn)(
16915
17027
  "railway",
16916
17028
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
16917
17029
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -16922,7 +17034,7 @@ var RailwayProvider = class {
16922
17034
  });
16923
17035
  proc.on("error", reject);
16924
17036
  proc.on("exit", (code) => {
16925
- if (code === 0) resolve4();
17037
+ if (code === 0) resolve5();
16926
17038
  else reject(new Error(`Remote write failed: ${(stderr || `exit ${code}`).trim().slice(0, 500)}`));
16927
17039
  });
16928
17040
  proc.stdin?.write(contents);
@@ -17445,8 +17557,8 @@ async function stopWorkspaceFromLocal(target) {
17445
17557
 
17446
17558
  // src/commands/link.ts
17447
17559
  var import_node_crypto4 = require("crypto");
17448
- var fs27 = __toESM(require("fs"));
17449
- var path36 = __toESM(require("path"));
17560
+ var fs28 = __toESM(require("fs"));
17561
+ var path37 = __toESM(require("path"));
17450
17562
  var import_chokidar = __toESM(require("chokidar"));
17451
17563
  var import_picocolors11 = __toESM(require("picocolors"));
17452
17564
  function buildLinkContext(agentId) {
@@ -17484,7 +17596,7 @@ function parseLinkArgs(args2) {
17484
17596
  if (apiKeyFileArg) {
17485
17597
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
17486
17598
  try {
17487
- apiKey = fs27.readFileSync(path36.resolve(filePath), "utf8").trim();
17599
+ apiKey = fs28.readFileSync(path37.resolve(filePath), "utf8").trim();
17488
17600
  } catch (err) {
17489
17601
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
17490
17602
  }
@@ -17529,7 +17641,7 @@ async function link(args2 = []) {
17529
17641
  waitSpin.start(waitMsg());
17530
17642
  const countdown = setInterval(() => waitSpin.message(waitMsg()), 1e3);
17531
17643
  countdown.unref?.();
17532
- const paired = await new Promise((resolve4, reject) => {
17644
+ const paired = await new Promise((resolve5, reject) => {
17533
17645
  let stopPoll = null;
17534
17646
  const sigint = () => {
17535
17647
  clearInterval(countdown);
@@ -17542,7 +17654,7 @@ async function link(args2 = []) {
17542
17654
  process.removeListener("SIGINT", sigint);
17543
17655
  clearInterval(countdown);
17544
17656
  waitSpin.stop("Paired");
17545
- resolve4(info);
17657
+ resolve5(info);
17546
17658
  },
17547
17659
  () => {
17548
17660
  clearInterval(countdown);
@@ -17578,7 +17690,7 @@ async function link(args2 = []) {
17578
17690
  return;
17579
17691
  }
17580
17692
  if (parsed.tokenFile) {
17581
- const credential = fs27.readFileSync(path36.resolve(parsed.tokenFile), "utf8").trim();
17693
+ const credential = fs28.readFileSync(path37.resolve(parsed.tokenFile), "utf8").trim();
17582
17694
  if (!credential) {
17583
17695
  showError(`--token-file ${parsed.tokenFile} is empty.`);
17584
17696
  process.exit(1);
@@ -17648,14 +17760,14 @@ async function captureFreshCredentials(ctx) {
17648
17760
  }
17649
17761
  };
17650
17762
  try {
17651
- const token = await new Promise((resolve4, reject) => {
17763
+ const token = await new Promise((resolve5, reject) => {
17652
17764
  let settled = false;
17653
17765
  const tryExtract = async () => {
17654
17766
  if (settled) return;
17655
17767
  const t2 = await ctx.locator.extract();
17656
17768
  if (t2 && !settled) {
17657
17769
  settled = true;
17658
- resolve4(t2);
17770
+ resolve5(t2);
17659
17771
  }
17660
17772
  };
17661
17773
  watcher.on("add", () => void tryExtract());
@@ -17767,8 +17879,8 @@ async function linkDryRunPreflight(ctx) {
17767
17879
  var import_node_dns = require("dns");
17768
17880
  var import_node_util4 = require("util");
17769
17881
  var import_node_crypto5 = require("crypto");
17770
- var fs28 = __toESM(require("fs"));
17771
- var path37 = __toESM(require("path"));
17882
+ var fs29 = __toESM(require("fs"));
17883
+ var path38 = __toESM(require("path"));
17772
17884
  var import_picocolors12 = __toESM(require("picocolors"));
17773
17885
  var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
17774
17886
  async function checkDns(apiBase) {
@@ -17824,13 +17936,13 @@ async function checkHealth(apiBase) {
17824
17936
  }
17825
17937
  }
17826
17938
  function checkConfigDir() {
17827
- const dir = path37.join(require("os").homedir(), ".codeam");
17939
+ const dir = path38.join(require("os").homedir(), ".codeam");
17828
17940
  try {
17829
- fs28.mkdirSync(dir, { recursive: true, mode: 448 });
17830
- const probe = path37.join(dir, ".doctor-probe");
17831
- fs28.writeFileSync(probe, "ok", { mode: 384 });
17832
- const read = fs28.readFileSync(probe, "utf8");
17833
- fs28.unlinkSync(probe);
17941
+ fs29.mkdirSync(dir, { recursive: true, mode: 448 });
17942
+ const probe = path38.join(dir, ".doctor-probe");
17943
+ fs29.writeFileSync(probe, "ok", { mode: 384 });
17944
+ const read = fs29.readFileSync(probe, "utf8");
17945
+ fs29.unlinkSync(probe);
17834
17946
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
17835
17947
  return {
17836
17948
  id: "config-dir",
@@ -17894,7 +18006,7 @@ function checkNodePty() {
17894
18006
  detail: "not required on this platform"
17895
18007
  };
17896
18008
  }
17897
- const vendoredPath = path37.join(__dirname, "vendor", "node-pty");
18009
+ const vendoredPath = path38.join(__dirname, "vendor", "node-pty");
17898
18010
  for (const target of [vendoredPath, "node-pty"]) {
17899
18011
  try {
17900
18012
  require(target);
@@ -17936,7 +18048,7 @@ function checkChokidar() {
17936
18048
  }
17937
18049
  async function doctor(args2 = []) {
17938
18050
  const json = args2.includes("--json");
17939
- const cliVersion = true ? "2.21.0" : "0.0.0-dev";
18051
+ const cliVersion = true ? "2.21.2" : "0.0.0-dev";
17940
18052
  const apiBase = resolveApiBaseUrl();
17941
18053
  const diagnosticId = (0, import_node_crypto5.randomUUID)();
17942
18054
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -18135,7 +18247,7 @@ async function completion(args2) {
18135
18247
  // src/commands/version.ts
18136
18248
  var import_picocolors13 = __toESM(require("picocolors"));
18137
18249
  function version2() {
18138
- const v = true ? "2.21.0" : "unknown";
18250
+ const v = true ? "2.21.2" : "unknown";
18139
18251
  console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
18140
18252
  }
18141
18253
 
@@ -18263,9 +18375,9 @@ function tryShowSubcommandHelp(cmd, args2) {
18263
18375
  var _subcommandHelpKeys = Object.keys(HELPS);
18264
18376
 
18265
18377
  // src/lib/updateNotifier.ts
18266
- var fs29 = __toESM(require("fs"));
18378
+ var fs30 = __toESM(require("fs"));
18267
18379
  var os25 = __toESM(require("os"));
18268
- var path38 = __toESM(require("path"));
18380
+ var path39 = __toESM(require("path"));
18269
18381
  var https7 = __toESM(require("https"));
18270
18382
  var import_picocolors16 = __toESM(require("picocolors"));
18271
18383
  var PKG_NAME = "codeam-cli";
@@ -18273,12 +18385,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
18273
18385
  var TTL_MS = 24 * 60 * 60 * 1e3;
18274
18386
  var REQUEST_TIMEOUT_MS = 1500;
18275
18387
  function cachePath() {
18276
- const dir = path38.join(os25.homedir(), ".codeam");
18277
- return path38.join(dir, "update-check.json");
18388
+ const dir = path39.join(os25.homedir(), ".codeam");
18389
+ return path39.join(dir, "update-check.json");
18278
18390
  }
18279
18391
  function readCache() {
18280
18392
  try {
18281
- const raw = fs29.readFileSync(cachePath(), "utf8");
18393
+ const raw = fs30.readFileSync(cachePath(), "utf8");
18282
18394
  const parsed = JSON.parse(raw);
18283
18395
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
18284
18396
  return parsed;
@@ -18289,10 +18401,10 @@ function readCache() {
18289
18401
  function writeCache(cache) {
18290
18402
  try {
18291
18403
  const file = cachePath();
18292
- fs29.mkdirSync(path38.dirname(file), { recursive: true });
18404
+ fs30.mkdirSync(path39.dirname(file), { recursive: true });
18293
18405
  const tmp = `${file}.${process.pid}.tmp`;
18294
- fs29.writeFileSync(tmp, JSON.stringify(cache));
18295
- fs29.renameSync(tmp, file);
18406
+ fs30.writeFileSync(tmp, JSON.stringify(cache));
18407
+ fs30.renameSync(tmp, file);
18296
18408
  } catch {
18297
18409
  }
18298
18410
  }
@@ -18310,14 +18422,14 @@ function compareSemver(a, b) {
18310
18422
  return 0;
18311
18423
  }
18312
18424
  function fetchLatest() {
18313
- return new Promise((resolve4) => {
18425
+ return new Promise((resolve5) => {
18314
18426
  const req = https7.get(
18315
18427
  REGISTRY_URL,
18316
18428
  { headers: { Accept: "application/json" }, timeout: REQUEST_TIMEOUT_MS },
18317
18429
  (res) => {
18318
18430
  if (res.statusCode !== 200) {
18319
18431
  res.resume();
18320
- resolve4(null);
18432
+ resolve5(null);
18321
18433
  return;
18322
18434
  }
18323
18435
  let buf = "";
@@ -18329,21 +18441,21 @@ function fetchLatest() {
18329
18441
  try {
18330
18442
  const json = JSON.parse(buf);
18331
18443
  if (typeof json.version === "string") {
18332
- resolve4(json.version);
18444
+ resolve5(json.version);
18333
18445
  } else {
18334
- resolve4(null);
18446
+ resolve5(null);
18335
18447
  }
18336
18448
  } catch {
18337
- resolve4(null);
18449
+ resolve5(null);
18338
18450
  }
18339
18451
  });
18340
18452
  }
18341
18453
  );
18342
18454
  req.on("timeout", () => {
18343
18455
  req.destroy();
18344
- resolve4(null);
18456
+ resolve5(null);
18345
18457
  });
18346
- req.on("error", () => resolve4(null));
18458
+ req.on("error", () => resolve5(null));
18347
18459
  });
18348
18460
  }
18349
18461
  function notifyIfStale(currentVersion, latest) {
@@ -18363,7 +18475,7 @@ function checkForUpdates() {
18363
18475
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
18364
18476
  if (process.env.CI) return;
18365
18477
  if (!process.stdout.isTTY) return;
18366
- const current = true ? "2.21.0" : null;
18478
+ const current = true ? "2.21.2" : null;
18367
18479
  if (!current) return;
18368
18480
  const cache = readCache();
18369
18481
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;