codeam-cli 2.76.1 → 2.76.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 +25 -0
  2. package/dist/index.js +558 -346
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -90,11 +90,11 @@ var require_src = __commonJS({
90
90
  });
91
91
 
92
92
  // src/integrations/stdio-proxy.ts
93
- var import_node_child_process34, import_node_readline3, RESTART_CHECK_INTERVAL_MS, SIGKILL_ESCALATION_MS, TOOL_CALL_TIMEOUT_MS, REPLAY_INIT_ID, RestartableStdioProxy;
93
+ var import_node_child_process36, import_node_readline3, RESTART_CHECK_INTERVAL_MS, SIGKILL_ESCALATION_MS, TOOL_CALL_TIMEOUT_MS, REPLAY_INIT_ID, RestartableStdioProxy;
94
94
  var init_stdio_proxy = __esm({
95
95
  "src/integrations/stdio-proxy.ts"() {
96
96
  "use strict";
97
- import_node_child_process34 = require("child_process");
97
+ import_node_child_process36 = require("child_process");
98
98
  import_node_readline3 = __toESM(require("readline"));
99
99
  RESTART_CHECK_INTERVAL_MS = 3e4;
100
100
  SIGKILL_ESCALATION_MS = 2e3;
@@ -271,7 +271,7 @@ var init_stdio_proxy = __esm({
271
271
  }
272
272
  async spawnChild(stdout, preResolved) {
273
273
  const spec = preResolved ?? await this.opts.spawnSpec();
274
- const spawn46 = this.opts.spawnImpl ?? import_node_child_process34.spawn;
274
+ const spawn46 = this.opts.spawnImpl ?? import_node_child_process36.spawn;
275
275
  const child = spawn46(spec.command, spec.args, {
276
276
  env: { ...process.env, ...spec.env },
277
277
  // env only — never argv
@@ -324,7 +324,7 @@ function defaultSpawn(timeoutMs) {
324
324
  };
325
325
  let child;
326
326
  try {
327
- child = (0, import_node_child_process35.spawn)(cmd, args2, { cwd: opts.cwd, env: opts.env, stdio: ["ignore", "pipe", "pipe"] });
327
+ child = (0, import_node_child_process37.spawn)(cmd, args2, { cwd: opts.cwd, env: opts.env, stdio: ["ignore", "pipe", "pipe"] });
328
328
  } catch (e) {
329
329
  finish(1);
330
330
  err = e instanceof Error ? e.message : String(e);
@@ -357,8 +357,8 @@ function defaultSpawn(timeoutMs) {
357
357
  });
358
358
  }
359
359
  function resolveConvexBin(cwd) {
360
- const local = path102.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
361
- if (fs88.existsSync(local)) return { cmd: local, args: [] };
360
+ const local = path103.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
361
+ if (fs89.existsSync(local)) return { cmd: local, args: [] };
362
362
  return { cmd: "npx", args: ["--yes", "convex"] };
363
363
  }
364
364
  function redact(text, key) {
@@ -489,13 +489,13 @@ async function runConvexAdminMcp(client3, id) {
489
489
  });
490
490
  await server.connect(new StdioServerTransport());
491
491
  }
492
- var import_node_child_process35, fs88, path102, TOOLS;
492
+ var import_node_child_process37, fs89, path103, TOOLS;
493
493
  var init_convex_admin_mcp = __esm({
494
494
  "src/integrations/convex-admin-mcp.ts"() {
495
495
  "use strict";
496
- import_node_child_process35 = require("child_process");
497
- fs88 = __toESM(require("fs"));
498
- path102 = __toESM(require("path"));
496
+ import_node_child_process37 = require("child_process");
497
+ fs89 = __toESM(require("fs"));
498
+ path103 = __toESM(require("path"));
499
499
  TOOLS = [
500
500
  {
501
501
  name: "tables",
@@ -3595,11 +3595,11 @@ function quiet(fn) {
3595
3595
  log.debug(TAG, "ignored sync error", err);
3596
3596
  }
3597
3597
  }
3598
- function rmIfExistsQuiet(path104) {
3598
+ function rmIfExistsQuiet(path105) {
3599
3599
  try {
3600
- fs2.rmSync(path104, { force: true });
3600
+ fs2.rmSync(path105, { force: true });
3601
3601
  } catch (err) {
3602
- log.debug(TAG, `rmIfExists failed for ${path104}`, err);
3602
+ log.debug(TAG, `rmIfExists failed for ${path105}`, err);
3603
3603
  }
3604
3604
  }
3605
3605
  function killQuiet(target, signal = "SIGTERM") {
@@ -3803,8 +3803,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3803
3803
  return decodedFile;
3804
3804
  };
3805
3805
  }
3806
- function normalizeWindowsPath(path104) {
3807
- return path104.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3806
+ function normalizeWindowsPath(path105) {
3807
+ return path105.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3808
3808
  }
3809
3809
 
3810
3810
  // ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
@@ -6537,13 +6537,13 @@ var PostHogCoreStateless = class {
6537
6537
  sentFromRoute += batchMessages.length;
6538
6538
  }
6539
6539
  }
6540
- async _sendOtlpBatch({ path: path104, payload }) {
6540
+ async _sendOtlpBatch({ path: path105, payload }) {
6541
6541
  if (this.disabled) return {
6542
6542
  kind: "fatal",
6543
6543
  error: new Error("The client is disabled")
6544
6544
  };
6545
6545
  const serialized = JSON.stringify(payload);
6546
- const url2 = `${this.host}/i/v1/${path104}?token=${encodeURIComponent(this.apiKey)}`;
6546
+ const url2 = `${this.host}/i/v1/${path105}?token=${encodeURIComponent(this.apiKey)}`;
6547
6547
  const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
6548
6548
  const fetchOptions = {
6549
6549
  method: "POST",
@@ -7783,14 +7783,14 @@ async function addSourceContext(frames, openSourceFile = import_promises.open, l
7783
7783
  LRU_FILE_CONTENTS_CACHE.reduce();
7784
7784
  return frames;
7785
7785
  }
7786
- async function openRegularSourceFile(path104, openSourceFile, logger) {
7786
+ async function openRegularSourceFile(path105, openSourceFile, logger) {
7787
7787
  let fileHandle;
7788
7788
  let isValid = false;
7789
7789
  try {
7790
- fileHandle = await openSourceFile(path104, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
7790
+ fileHandle = await openSourceFile(path105, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
7791
7791
  const fileStat = await fileHandle.stat();
7792
7792
  if (!fileStat.isFile()) return;
7793
- if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path104}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
7793
+ if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path105}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
7794
7794
  isValid = true;
7795
7795
  return fileHandle;
7796
7796
  } catch {
@@ -7800,8 +7800,8 @@ async function openRegularSourceFile(path104, openSourceFile, logger) {
7800
7800
  });
7801
7801
  }
7802
7802
  }
7803
- async function getContextLinesFromFile(path104, ranges, output, cacheKey, openSourceFile, logger) {
7804
- const fileHandle = await openRegularSourceFile(path104, openSourceFile, logger);
7803
+ async function getContextLinesFromFile(path105, ranges, output, cacheKey, openSourceFile, logger) {
7804
+ const fileHandle = await openRegularSourceFile(path105, openSourceFile, logger);
7805
7805
  if (void 0 === fileHandle) return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
7806
7806
  const openedFileHandle = fileHandle;
7807
7807
  return new Promise((resolve12) => {
@@ -7903,22 +7903,22 @@ function clearLineContext(frame) {
7903
7903
  delete frame.context_line;
7904
7904
  delete frame.post_context;
7905
7905
  }
7906
- function shouldSkipContextLinesForFile(path104) {
7907
- return path104.startsWith("node:") || path104.endsWith(".min.js") || path104.endsWith(".min.cjs") || path104.endsWith(".min.mjs") || path104.startsWith("data:");
7906
+ function shouldSkipContextLinesForFile(path105) {
7907
+ return path105.startsWith("node:") || path105.endsWith(".min.js") || path105.endsWith(".min.cjs") || path105.endsWith(".min.mjs") || path105.startsWith("data:");
7908
7908
  }
7909
7909
  function shouldSkipContextLinesForFrame(frame) {
7910
7910
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
7911
7911
  if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
7912
7912
  return false;
7913
7913
  }
7914
- function makeSourceCacheKey(path104, basePath) {
7915
- if ((0, import_node_path.isAbsolute)(path104)) return JSON.stringify([
7914
+ function makeSourceCacheKey(path105, basePath) {
7915
+ if ((0, import_node_path.isAbsolute)(path105)) return JSON.stringify([
7916
7916
  null,
7917
- path104
7917
+ path105
7918
7918
  ]);
7919
7919
  return void 0 === basePath ? void 0 : JSON.stringify([
7920
7920
  basePath,
7921
- path104
7921
+ path105
7922
7922
  ]);
7923
7923
  }
7924
7924
  function rangeExistsInContentCache(cacheKey, range) {
@@ -10579,7 +10579,7 @@ function readAnonId() {
10579
10579
  }
10580
10580
  function superProperties() {
10581
10581
  return {
10582
- cliVersion: true ? "2.76.1" : "0.0.0-dev",
10582
+ cliVersion: true ? "2.76.2" : "0.0.0-dev",
10583
10583
  nodeVersion: process.version,
10584
10584
  platform: process.platform,
10585
10585
  arch: process.arch,
@@ -10824,7 +10824,7 @@ var http = __toESM(require("http"));
10824
10824
  // package.json
10825
10825
  var package_default = {
10826
10826
  name: "codeam-cli",
10827
- version: "2.76.1",
10827
+ version: "2.76.2",
10828
10828
  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.",
10829
10829
  type: "commonjs",
10830
10830
  main: "dist/index.js",
@@ -12160,7 +12160,7 @@ var CommandRelayService = class _CommandRelayService {
12160
12160
  // fresh + clear the "CLI update available" banner after a self-update
12161
12161
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
12162
12162
  // pair/reconnect). Older backends ignore the extra field.
12163
- ..."2.76.1" ? { ideVersion: "2.76.1" } : {}
12163
+ ..."2.76.2" ? { ideVersion: "2.76.2" } : {}
12164
12164
  };
12165
12165
  try {
12166
12166
  const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
@@ -19724,8 +19724,8 @@ function pickLine(obj) {
19724
19724
  function toHunk(raw, groupSeverity) {
19725
19725
  if (!raw || typeof raw !== "object") return null;
19726
19726
  const o = raw;
19727
- const path104 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
19728
- if (!path104) return null;
19727
+ const path105 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
19728
+ if (!path105) return null;
19729
19729
  const message = asString(
19730
19730
  pick(o, [
19731
19731
  "comment",
@@ -19742,7 +19742,7 @@ function toHunk(raw, groupSeverity) {
19742
19742
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
19743
19743
  const locObj = pick(o, ["location"]) ?? o;
19744
19744
  return {
19745
- path: path104.trim(),
19745
+ path: path105.trim(),
19746
19746
  line: pickLine(o) ?? pickLine(locObj),
19747
19747
  severity,
19748
19748
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -19825,10 +19825,10 @@ function parsePlain(stdout) {
19825
19825
  for (const line of stdout.split(/\r?\n/)) {
19826
19826
  const m = line.match(HUNK_LINE_RE);
19827
19827
  if (!m) continue;
19828
- const [, path104, lineNo, sevToken, message] = m;
19829
- if (!path104 || !lineNo || !message) continue;
19828
+ const [, path105, lineNo, sevToken, message] = m;
19829
+ if (!path105 || !lineNo || !message) continue;
19830
19830
  hunks.push({
19831
- path: path104.trim(),
19831
+ path: path105.trim(),
19832
19832
  line: Number(lineNo),
19833
19833
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
19834
19834
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -24771,62 +24771,17 @@ async function postZipDownloaded(ctx, fetchImpl = fetch) {
24771
24771
  }
24772
24772
 
24773
24773
  // src/scratch/save-github.ts
24774
+ var import_node_child_process23 = require("child_process");
24775
+ var import_node_util9 = require("util");
24776
+
24777
+ // src/scratch/push-clean.ts
24774
24778
  var import_node_child_process22 = require("child_process");
24775
24779
  var import_node_fs11 = __toESM(require("fs"));
24776
24780
  var import_node_os5 = __toESM(require("os"));
24777
24781
  var import_node_path9 = __toESM(require("path"));
24778
24782
  var import_node_util8 = require("util");
24779
- var GH = "https://api.github.com";
24780
- async function saveToGithub(cwd, input, deps = {}) {
24781
- const f = deps.fetchImpl ?? fetch;
24783
+ async function pushCleanCopy(cwd, cloneUrl, authorizationHeader, deps) {
24782
24784
  const exec2 = (0, import_node_util8.promisify)(deps.exec ?? import_node_child_process22.execFile);
24783
- const headers = {
24784
- Authorization: `Bearer ${input.token}`,
24785
- Accept: "application/vnd.github+json",
24786
- "User-Agent": "codeam-cli"
24787
- };
24788
- const env = { ...process.env, ...nonInteractiveGitEnv() };
24789
- const git2 = (...args2) => exec2("git", ["-C", cwd, ...args2], { env });
24790
- const meRes = await f(`${GH}/user`, { headers });
24791
- const meBody = await meRes.json();
24792
- if (!meRes.ok || typeof meBody.login !== "string" || typeof meBody.id !== "number") {
24793
- throw Object.assign(
24794
- new Error("GitHub rejected the token \u2014 reconnect GitHub and try again."),
24795
- { code: "SAVE_FAILED" }
24796
- );
24797
- }
24798
- const me2 = { login: meBody.login, id: meBody.id };
24799
- await git2("config", "user.name", me2.login);
24800
- await git2("config", "user.email", `${me2.id}+${me2.login}@users.noreply.github.com`);
24801
- const { stdout } = await git2("status", "--porcelain");
24802
- if (stdout.trim()) {
24803
- await git2("add", "-A");
24804
- await git2("commit", "-m", "Save project from CodeAgent");
24805
- }
24806
- const res = await f(`${GH}/user/repos`, {
24807
- method: "POST",
24808
- headers: { ...headers, "Content-Type": "application/json" },
24809
- body: JSON.stringify({ name: input.repoName, private: input.private, auto_init: false })
24810
- });
24811
- const body = await res.json();
24812
- if (res.status === 422 && body.errors?.some((e) => /already exists/i.test(e.message ?? ""))) {
24813
- throw Object.assign(new Error("A repository with that name already exists."), {
24814
- code: "REPO_NAME_TAKEN"
24815
- });
24816
- }
24817
- if (!res.ok || !body.full_name || !body.clone_url) {
24818
- throw Object.assign(new Error(`GitHub answered ${res.status}`), { code: "SAVE_FAILED" });
24819
- }
24820
- await git2("remote", "remove", "origin").catch(() => void 0);
24821
- await git2("remote", "add", "origin", body.clone_url);
24822
- const branch = await git2("symbolic-ref", "-q", "--short", "HEAD").then(
24823
- (r) => r.stdout.trim(),
24824
- () => ""
24825
- );
24826
- if (branch) {
24827
- await git2("config", `branch.${branch}.remote`, "origin");
24828
- await git2("config", `branch.${branch}.merge`, "refs/heads/main");
24829
- }
24830
24785
  let tmp;
24831
24786
  let home;
24832
24787
  try {
@@ -24834,7 +24789,7 @@ async function saveToGithub(cwd, input, deps = {}) {
24834
24789
  home = import_node_fs11.default.mkdtempSync(import_node_path9.default.join(import_node_os5.default.tmpdir(), "codeam-push-home-"));
24835
24790
  const bare = import_node_path9.default.join(tmp, "repo.git");
24836
24791
  const cleanEnv = {
24837
- ...env,
24792
+ ...deps.env,
24838
24793
  HOME: home,
24839
24794
  GIT_CONFIG_NOSYSTEM: "1",
24840
24795
  GIT_CONFIG_GLOBAL: "/dev/null",
@@ -24844,9 +24799,13 @@ async function saveToGithub(cwd, input, deps = {}) {
24844
24799
  await exec2("git", ["clone", "--bare", "--no-hardlinks", "--template=", "-q", cwd, bare], {
24845
24800
  env: cleanEnv
24846
24801
  });
24847
- const { stdout: keys } = await exec2("git", ["-C", bare, "config", "--local", "--list", "--name-only"], {
24848
- env: cleanEnv
24849
- });
24802
+ const { stdout: keys } = await exec2(
24803
+ "git",
24804
+ ["-C", bare, "config", "--local", "--list", "--name-only"],
24805
+ {
24806
+ env: cleanEnv
24807
+ }
24808
+ );
24850
24809
  const hostile = keys.split("\n").filter((k2) => /^(http|url|credential|include|includeif)\./i.test(k2));
24851
24810
  if (hostile.length > 0) {
24852
24811
  throw new Error(`the clean copy carries unexpected git config (${hostile.join(", ")})`);
@@ -24854,9 +24813,8 @@ async function saveToGithub(cwd, input, deps = {}) {
24854
24813
  const pushEnv = {
24855
24814
  ...cleanEnv,
24856
24815
  GIT_CONFIG_COUNT: "1",
24857
- // Scoped to this exact repo URL: the header goes nowhere else.
24858
- GIT_CONFIG_KEY_0: `http.${body.clone_url}.extraheader`,
24859
- GIT_CONFIG_VALUE_0: `AUTHORIZATION: basic ${Buffer.from(`x-access-token:${input.token}`).toString("base64")}`
24816
+ GIT_CONFIG_KEY_0: `http.${cloneUrl}.extraheader`,
24817
+ GIT_CONFIG_VALUE_0: `AUTHORIZATION: ${authorizationHeader}`
24860
24818
  };
24861
24819
  await exec2(
24862
24820
  "git",
@@ -24874,7 +24832,7 @@ async function saveToGithub(cwd, input, deps = {}) {
24874
24832
  "-c",
24875
24833
  "http.proxy=",
24876
24834
  "push",
24877
- body.clone_url,
24835
+ cloneUrl,
24878
24836
  "HEAD:main"
24879
24837
  ],
24880
24838
  { env: pushEnv }
@@ -24887,7 +24845,141 @@ async function saveToGithub(cwd, input, deps = {}) {
24887
24845
  if (tmp) import_node_fs11.default.rmSync(tmp, { recursive: true, force: true });
24888
24846
  if (home) import_node_fs11.default.rmSync(home, { recursive: true, force: true });
24889
24847
  }
24890
- return { repoFullName: body.full_name, htmlUrl: body.html_url ?? `https://github.com/${body.full_name}` };
24848
+ }
24849
+
24850
+ // src/scratch/save-github.ts
24851
+ var GH = "https://api.github.com";
24852
+ async function saveToGithub(cwd, input, deps = {}) {
24853
+ const f = deps.fetchImpl ?? fetch;
24854
+ const exec2 = (0, import_node_util9.promisify)(deps.exec ?? import_node_child_process23.execFile);
24855
+ const headers = {
24856
+ Authorization: `Bearer ${input.token}`,
24857
+ Accept: "application/vnd.github+json",
24858
+ "User-Agent": "codeam-cli"
24859
+ };
24860
+ const env = { ...process.env, ...nonInteractiveGitEnv() };
24861
+ const git2 = (...args2) => exec2("git", ["-C", cwd, ...args2], { env });
24862
+ const meRes = await f(`${GH}/user`, { headers });
24863
+ const meBody = await meRes.json();
24864
+ if (!meRes.ok || typeof meBody.login !== "string" || typeof meBody.id !== "number") {
24865
+ throw Object.assign(new Error("GitHub rejected the token \u2014 reconnect GitHub and try again."), {
24866
+ code: "SAVE_FAILED"
24867
+ });
24868
+ }
24869
+ const me2 = { login: meBody.login, id: meBody.id };
24870
+ await git2("config", "user.name", me2.login);
24871
+ await git2("config", "user.email", `${me2.id}+${me2.login}@users.noreply.github.com`);
24872
+ const { stdout } = await git2("status", "--porcelain");
24873
+ if (stdout.trim()) {
24874
+ await git2("add", "-A");
24875
+ await git2("commit", "-m", "Save project from CodeAgent");
24876
+ }
24877
+ const res = await f(`${GH}/user/repos`, {
24878
+ method: "POST",
24879
+ headers: { ...headers, "Content-Type": "application/json" },
24880
+ body: JSON.stringify({ name: input.repoName, private: input.private, auto_init: false })
24881
+ });
24882
+ const body = await res.json();
24883
+ if (res.status === 422 && body.errors?.some((e) => /already exists/i.test(e.message ?? ""))) {
24884
+ throw Object.assign(new Error("A repository with that name already exists."), {
24885
+ code: "REPO_NAME_TAKEN"
24886
+ });
24887
+ }
24888
+ if (!res.ok || !body.full_name || !body.clone_url) {
24889
+ throw Object.assign(new Error(`GitHub answered ${res.status}`), { code: "SAVE_FAILED" });
24890
+ }
24891
+ await git2("remote", "remove", "origin").catch(() => void 0);
24892
+ await git2("remote", "add", "origin", body.clone_url);
24893
+ const branch = await git2("symbolic-ref", "-q", "--short", "HEAD").then(
24894
+ (r) => r.stdout.trim(),
24895
+ () => ""
24896
+ );
24897
+ if (branch) {
24898
+ await git2("config", `branch.${branch}.remote`, "origin");
24899
+ await git2("config", `branch.${branch}.merge`, "refs/heads/main");
24900
+ }
24901
+ await pushCleanCopy(
24902
+ cwd,
24903
+ body.clone_url,
24904
+ `basic ${Buffer.from(`x-access-token:${input.token}`).toString("base64")}`,
24905
+ {
24906
+ exec: deps.exec,
24907
+ env
24908
+ }
24909
+ );
24910
+ return {
24911
+ repoFullName: body.full_name,
24912
+ htmlUrl: body.html_url ?? `https://github.com/${body.full_name}`
24913
+ };
24914
+ }
24915
+
24916
+ // src/scratch/save-gitlab.ts
24917
+ var import_node_child_process24 = require("child_process");
24918
+ var import_node_util10 = require("util");
24919
+ var GL = "https://gitlab.com/api/v4";
24920
+ async function saveToGitlab(cwd, input, deps = {}) {
24921
+ const f = deps.fetchImpl ?? fetch;
24922
+ const exec2 = (0, import_node_util10.promisify)(deps.exec ?? import_node_child_process24.execFile);
24923
+ const headers = { Authorization: `Bearer ${input.token}`, "User-Agent": "codeam-cli" };
24924
+ const env = { ...process.env, ...nonInteractiveGitEnv() };
24925
+ const git2 = (...args2) => exec2("git", ["-C", cwd, ...args2], { env });
24926
+ const meRes = await f(`${GL}/user`, { headers });
24927
+ const meBody = await meRes.json();
24928
+ if (!meRes.ok || typeof meBody.username !== "string" || typeof meBody.id !== "number") {
24929
+ throw Object.assign(new Error("GitLab rejected the token \u2014 reconnect GitLab and try again."), {
24930
+ code: "SAVE_FAILED"
24931
+ });
24932
+ }
24933
+ const me2 = { username: meBody.username, id: meBody.id };
24934
+ await git2("config", "user.name", me2.username);
24935
+ await git2("config", "user.email", `${me2.id}-${me2.username}@users.noreply.gitlab.com`);
24936
+ const { stdout } = await git2("status", "--porcelain");
24937
+ if (stdout.trim()) {
24938
+ await git2("add", "-A");
24939
+ await git2("commit", "-m", "Save project from CodeAgent");
24940
+ }
24941
+ const res = await f(`${GL}/projects`, {
24942
+ method: "POST",
24943
+ headers: { ...headers, "Content-Type": "application/json" },
24944
+ body: JSON.stringify({
24945
+ name: input.repoName,
24946
+ path: input.repoName,
24947
+ visibility: input.private ? "private" : "public",
24948
+ initialize_with_readme: false
24949
+ })
24950
+ });
24951
+ const body = await res.json();
24952
+ if (res.status === 400 && /already been taken/i.test(JSON.stringify(body.message ?? ""))) {
24953
+ throw Object.assign(new Error("A project with that name already exists."), {
24954
+ code: "REPO_NAME_TAKEN"
24955
+ });
24956
+ }
24957
+ if (!res.ok || !body.path_with_namespace || !body.http_url_to_repo) {
24958
+ throw Object.assign(new Error(`GitLab answered ${res.status}`), { code: "SAVE_FAILED" });
24959
+ }
24960
+ await git2("remote", "remove", "origin").catch(() => void 0);
24961
+ await git2("remote", "add", "origin", body.http_url_to_repo);
24962
+ const branch = await git2("symbolic-ref", "-q", "--short", "HEAD").then(
24963
+ (r) => r.stdout.trim(),
24964
+ () => ""
24965
+ );
24966
+ if (branch) {
24967
+ await git2("config", `branch.${branch}.remote`, "origin");
24968
+ await git2("config", `branch.${branch}.merge`, "refs/heads/main");
24969
+ }
24970
+ await pushCleanCopy(
24971
+ cwd,
24972
+ body.http_url_to_repo,
24973
+ `basic ${Buffer.from(`oauth2:${input.token}`).toString("base64")}`,
24974
+ {
24975
+ exec: deps.exec,
24976
+ env
24977
+ }
24978
+ );
24979
+ return {
24980
+ repoFullName: body.path_with_namespace,
24981
+ htmlUrl: body.web_url ?? `https://gitlab.com/${body.path_with_namespace}`
24982
+ };
24891
24983
  }
24892
24984
 
24893
24985
  // src/scratch/handlers.ts
@@ -24953,12 +25045,19 @@ async function scratchExportZipH(ctx) {
24953
25045
  }
24954
25046
  await relay.sendResult(cmd.id, "completed", ready);
24955
25047
  }
24956
- async function scratchSaveGithubH(ctx) {
25048
+ function scratchSaveGithubH(ctx) {
25049
+ return saveToProviderH(ctx, "github");
25050
+ }
25051
+ function scratchSaveGitlabH(ctx) {
25052
+ return saveToProviderH(ctx, "gitlab");
25053
+ }
25054
+ var SAVE_LABEL = { github: "GitHub", gitlab: "GitLab" };
25055
+ async function saveToProviderH(ctx, provider) {
24957
25056
  const { cmd, relay } = ctx;
24958
25057
  if (!isScratchWorkspace(process.cwd())) {
24959
25058
  await relay.sendResult(cmd.id, "failed", {
24960
25059
  code: "SAVE_FAILED",
24961
- error: "Save to GitHub is only available for projects started from scratch."
25060
+ error: `Save to ${SAVE_LABEL[provider]} is only available for projects started from scratch.`
24962
25061
  });
24963
25062
  return;
24964
25063
  }
@@ -24971,11 +25070,8 @@ async function scratchSaveGithubH(ctx) {
24971
25070
  return;
24972
25071
  }
24973
25072
  try {
24974
- const out2 = await saveToGithub(process.cwd(), {
24975
- repoName: p2.repoName,
24976
- private: p2.private !== false,
24977
- token: p2.token
24978
- });
25073
+ const input = { repoName: p2.repoName, private: p2.private !== false, token: p2.token };
25074
+ const out2 = provider === "github" ? await saveToGithub(process.cwd(), input) : await saveToGitlab(process.cwd(), input);
24979
25075
  await relay.sendResult(cmd.id, "completed", out2);
24980
25076
  } catch (err) {
24981
25077
  const code = err.code === "REPO_NAME_TAKEN" ? "REPO_NAME_TAKEN" : "SAVE_FAILED";
@@ -28373,7 +28469,16 @@ var getContext = async (ctx, cmd) => {
28373
28469
  const monthlyCost = ctx.historySvc.getMonthlyEstimatedCost();
28374
28470
  const rateLimitReset = ctx.historySvc.getRateLimitReset();
28375
28471
  const quotaPercent = ctx.historySvc.getQuotaPercent();
28376
- const base = usage ? { ...usage, monthlyCost } : { used: 0, total: 2e5, percent: 0, model: null, outputTokens: 0, cacheReadTokens: 0, monthlyCost, error: "No usage data found" };
28472
+ const base = usage ? { ...usage, monthlyCost } : {
28473
+ used: 0,
28474
+ total: 2e5,
28475
+ percent: 0,
28476
+ model: null,
28477
+ outputTokens: 0,
28478
+ cacheReadTokens: 0,
28479
+ monthlyCost,
28480
+ error: "No usage data found"
28481
+ };
28377
28482
  const result = {
28378
28483
  ...base,
28379
28484
  ...rateLimitReset ? { rateLimitReset } : {},
@@ -28416,7 +28521,9 @@ var changeModel = async (ctx, cmd) => {
28416
28521
  }
28417
28522
  ctx.agent.sendRawPtyInput(instr.ptyInput);
28418
28523
  } else if (instr.type === "restart") {
28419
- await ctx.relay.sendResult(cmd.id, "failed", { error: "restart-mode change_model not supported in Phase 1" });
28524
+ await ctx.relay.sendResult(cmd.id, "failed", {
28525
+ error: "restart-mode change_model not supported in Phase 1"
28526
+ });
28420
28527
  return;
28421
28528
  }
28422
28529
  await ctx.relay.sendResult(cmd.id, "completed", {});
@@ -28432,15 +28539,11 @@ var setKeepAlive = async (ctx, cmd) => {
28432
28539
  const enabled = !!cmd.payload.enabled;
28433
28540
  ctx.setKeepAlive(enabled);
28434
28541
  try {
28435
- await ctx.relay.sendResult(
28436
- cmd.id,
28437
- "success",
28438
- {
28439
- enabled,
28440
- applied: enabled && ctx.keepAliveCtx.inCodespace,
28441
- runtime: ctx.keepAliveCtx.inCodespace ? "github-codespaces" : "local"
28442
- }
28443
- );
28542
+ await ctx.relay.sendResult(cmd.id, "success", {
28543
+ enabled,
28544
+ applied: enabled && ctx.keepAliveCtx.inCodespace,
28545
+ runtime: ctx.keepAliveCtx.inCodespace ? "github-codespaces" : "local"
28546
+ });
28444
28547
  } catch {
28445
28548
  }
28446
28549
  };
@@ -28477,7 +28580,10 @@ var shutdownSession = async (ctx, cmd) => {
28477
28580
  try {
28478
28581
  const stopProc = (0, import_child_process25.spawn)(
28479
28582
  "bash",
28480
- ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
28583
+ [
28584
+ "-lc",
28585
+ `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`
28586
+ ],
28481
28587
  { detached: true, stdio: "ignore" }
28482
28588
  );
28483
28589
  stopProc.unref();
@@ -28760,7 +28866,10 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
28760
28866
  });
28761
28867
  void (async () => {
28762
28868
  try {
28763
- const result2 = await configureCoderabbit({ action: "link_oauth" }, { onEvent, uploadCredential });
28869
+ const result2 = await configureCoderabbit(
28870
+ { action: "link_oauth" },
28871
+ { onEvent, uploadCredential }
28872
+ );
28764
28873
  emit2("coderabbit_status", {
28765
28874
  installed: result2.installed,
28766
28875
  loggedIn: result2.loggedIn,
@@ -28800,7 +28909,11 @@ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
28800
28909
  });
28801
28910
  }
28802
28911
  await emitChain;
28803
- await ctx.relay.sendResult(cmd.id, result.error && action !== "review" ? "failed" : "completed", result);
28912
+ await ctx.relay.sendResult(
28913
+ cmd.id,
28914
+ result.error && action !== "review" ? "failed" : "completed",
28915
+ result
28916
+ );
28804
28917
  };
28805
28918
  var vcsAgentReviewH = async (ctx, cmd, parsed) => {
28806
28919
  const pr = parsed.pr;
@@ -28872,7 +28985,12 @@ var beadsConfigureH = async (ctx, cmd, parsed) => {
28872
28985
  const deps = {
28873
28986
  provision: async () => {
28874
28987
  const r = await provisionBeads({ cwd: process.cwd(), agents: agentIds });
28875
- return { bdAvailable: r.bdAvailable, doltAvailable: r.doltAvailable, serverUp: r.serverUp, prefix: r.prefix };
28988
+ return {
28989
+ bdAvailable: r.bdAvailable,
28990
+ doltAvailable: r.doltAvailable,
28991
+ serverUp: r.serverUp,
28992
+ prefix: r.prefix
28993
+ };
28876
28994
  },
28877
28995
  probe: async () => probeBeadsStatus(process.cwd()),
28878
28996
  startWatcher: async () => {
@@ -28895,7 +29013,10 @@ var beadsConfigureH = async (ctx, cmd, parsed) => {
28895
29013
  }
28896
29014
  },
28897
29015
  revertAgentHook: async (agent) => {
28898
- log.info("beads", `revertAgentHook: bd has no --remove flag \u2014 leaving ${agent} hook in place (no-op disable path)`);
29016
+ log.info(
29017
+ "beads",
29018
+ `revertAgentHook: bd has no --remove flag \u2014 leaving ${agent} hook in place (no-op disable path)`
29019
+ );
28899
29020
  },
28900
29021
  persist: (cfg) => persistBeadsConfig(cfg),
28901
29022
  readEnabled: () => readBeadsEnabled(),
@@ -28908,14 +29029,16 @@ var beadsConfigureH = async (ctx, cmd, parsed) => {
28908
29029
  pluginId: ctx.pluginId,
28909
29030
  pluginAuthToken: token,
28910
29031
  type: USER_EVENTS.BEADS_STATUS,
28911
- payload: Object.fromEntries(
28912
- Object.entries(event).filter(([k2]) => k2 !== "type")
28913
- )
29032
+ payload: Object.fromEntries(Object.entries(event).filter(([k2]) => k2 !== "type"))
28914
29033
  })
28915
29034
  );
28916
29035
  }
28917
29036
  };
28918
- const result = await configureBeads(action, { agent: rawAgentId, cwd: process.cwd(), pluginAuthToken: ctx.pluginAuthToken }, deps);
29037
+ const result = await configureBeads(
29038
+ action,
29039
+ { agent: rawAgentId, cwd: process.cwd(), pluginAuthToken: ctx.pluginAuthToken },
29040
+ deps
29041
+ );
28919
29042
  await ctx.relay.sendResult(cmd.id, "completed", result);
28920
29043
  };
28921
29044
  var defaultCliUpdateDeps = {
@@ -28948,10 +29071,7 @@ function buildNpmInstallInvocation(opts) {
28948
29071
  const marker = "/lib/node_modules/codeam-cli/";
28949
29072
  const markerIdx = normalized.indexOf(marker);
28950
29073
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
28951
- const siblingNpm = p2.join(
28952
- p2.dirname(execPath),
28953
- platform3 === "win32" ? "npm.cmd" : "npm"
28954
- );
29074
+ const siblingNpm = p2.join(p2.dirname(execPath), platform3 === "win32" ? "npm.cmd" : "npm");
28955
29075
  const npmCommand = exists2(siblingNpm) ? siblingNpm : "npm";
28956
29076
  const npmArgs = prefix ? ["install", "-g", "--prefix", prefix, "codeam-cli@latest"] : ["install", "-g", "codeam-cli@latest"];
28957
29077
  if (opts?.sudo) {
@@ -29087,7 +29207,11 @@ var terminalWriteH = async (ctx, cmd, parsed) => {
29087
29207
  return;
29088
29208
  }
29089
29209
  const r = writeTerminal(parsed.sessionId, parsed.data);
29090
- await ctx.relay.sendResult(cmd.id, r.ok ? "completed" : "failed", r);
29210
+ await ctx.relay.sendResult(
29211
+ cmd.id,
29212
+ r.ok ? "completed" : "failed",
29213
+ r
29214
+ );
29091
29215
  };
29092
29216
  var terminalResizeH = async (ctx, cmd, parsed) => {
29093
29217
  if (typeof parsed.sessionId !== "string" || typeof parsed.cols !== "number" || typeof parsed.rows !== "number") {
@@ -29095,7 +29219,11 @@ var terminalResizeH = async (ctx, cmd, parsed) => {
29095
29219
  return;
29096
29220
  }
29097
29221
  const r = resizeTerminal(parsed.sessionId, parsed.cols, parsed.rows);
29098
- await ctx.relay.sendResult(cmd.id, r.ok ? "completed" : "failed", r);
29222
+ await ctx.relay.sendResult(
29223
+ cmd.id,
29224
+ r.ok ? "completed" : "failed",
29225
+ r
29226
+ );
29099
29227
  };
29100
29228
  var terminalCloseH = async (ctx, cmd, parsed) => {
29101
29229
  if (typeof parsed.sessionId !== "string") {
@@ -29169,11 +29297,7 @@ var applyFileReviewH = async (ctx, cmd, parsed) => {
29169
29297
  });
29170
29298
  return;
29171
29299
  }
29172
- const result = await applyFileReview(
29173
- process.cwd(),
29174
- parsed.filePath,
29175
- reviewAction
29176
- );
29300
+ const result = await applyFileReview(process.cwd(), parsed.filePath, reviewAction);
29177
29301
  await ctx.relay.sendResult(
29178
29302
  cmd.id,
29179
29303
  result.ok ? "completed" : "failed",
@@ -29263,7 +29387,10 @@ var requestAiSummaryH = (ctx, _cmd, parsed) => {
29263
29387
  log.info("ai-summary", `generateOneShot returned null after ${tookMs}ms \u2014 skipping POST`);
29264
29388
  return;
29265
29389
  }
29266
- log.info("ai-summary", `generateOneShot ok turnId=${turnId} took=${tookMs}ms textLen=${text.length}`);
29390
+ log.info(
29391
+ "ai-summary",
29392
+ `generateOneShot ok turnId=${turnId} took=${tookMs}ms textLen=${text.length}`
29393
+ );
29267
29394
  const result = await postAiResult({
29268
29395
  sessionId: ctx.sessionId,
29269
29396
  pluginId: ctx.pluginId,
@@ -29300,7 +29427,10 @@ var requestAiInsightH = (ctx, _cmd, parsed) => {
29300
29427
  const fileChangeId = parsed.fileChangeId;
29301
29428
  const pluginAuthToken = ctx.pluginAuthToken;
29302
29429
  void (async () => {
29303
- log.info("ai-insight", `generateOneShot start fileChangeId=${fileChangeId} promptLen=${prompt.length}`);
29430
+ log.info(
29431
+ "ai-insight",
29432
+ `generateOneShot start fileChangeId=${fileChangeId} promptLen=${prompt.length}`
29433
+ );
29304
29434
  const startedAt = Date.now();
29305
29435
  const text = await ctx.runtime.generateOneShot(prompt).catch((err) => {
29306
29436
  log.info("ai-insight", `generateOneShot threw: ${String(err)}`);
@@ -29311,7 +29441,10 @@ var requestAiInsightH = (ctx, _cmd, parsed) => {
29311
29441
  log.info("ai-insight", `generateOneShot returned null after ${tookMs}ms \u2014 skipping POST`);
29312
29442
  return;
29313
29443
  }
29314
- log.info("ai-insight", `generateOneShot ok fileChangeId=${fileChangeId} took=${tookMs}ms textLen=${text.length}`);
29444
+ log.info(
29445
+ "ai-insight",
29446
+ `generateOneShot ok fileChangeId=${fileChangeId} took=${tookMs}ms textLen=${text.length}`
29447
+ );
29315
29448
  const { summary, reasoning, securityNote } = parseInsightText(text);
29316
29449
  const result = await postAiResult({
29317
29450
  sessionId: ctx.sessionId,
@@ -29565,6 +29698,17 @@ var previewStartH = (ctx, _cmd, parsed) => {
29565
29698
  }
29566
29699
  void startPreviewFromDetection(ctx, rawDetection, ctx.pluginAuthToken);
29567
29700
  };
29701
+ var scratchOfferedSessions = /* @__PURE__ */ new Set();
29702
+ async function offerScratchSaveOnce(ctx, pluginAuthToken) {
29703
+ if (!isScratchWorkspace(process.cwd()) || scratchOfferedSessions.has(ctx.sessionId)) return;
29704
+ scratchOfferedSessions.add(ctx.sessionId);
29705
+ const offered = await postScratchOffer({
29706
+ sessionId: ctx.sessionId,
29707
+ pluginId: ctx.pluginId,
29708
+ pluginAuthToken
29709
+ });
29710
+ if (!offered) scratchOfferedSessions.delete(ctx.sessionId);
29711
+ }
29568
29712
  function startPreviewFromDetection(ctx, detection, pluginAuthToken, opts = {}) {
29569
29713
  previewRequestedInProcess = true;
29570
29714
  const emit2 = (type, payload) => {
@@ -29577,6 +29721,9 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken, opts = {}) {
29577
29721
  type,
29578
29722
  payload: tagged
29579
29723
  });
29724
+ if (type === USER_EVENTS.PREVIEW_READY) {
29725
+ void offerScratchSaveOnce(ctx, pluginAuthToken);
29726
+ }
29580
29727
  };
29581
29728
  return runPreviewStart({
29582
29729
  sessionId: ctx.sessionId,
@@ -29680,12 +29827,29 @@ var guardrailConfigureH = async (ctx, cmd) => {
29680
29827
  var scratchExportZip = (ctx, cmd) => scratchExportZipH({
29681
29828
  cmd,
29682
29829
  relay: ctx.relay,
29683
- opts: { sessionId: ctx.sessionId, pluginId: ctx.pluginId, pluginAuthToken: ctx.pluginAuthToken }
29830
+ opts: {
29831
+ sessionId: ctx.sessionId,
29832
+ pluginId: ctx.pluginId,
29833
+ pluginAuthToken: ctx.pluginAuthToken
29834
+ }
29684
29835
  });
29685
29836
  var scratchSaveGithub = (ctx, cmd) => scratchSaveGithubH({
29686
29837
  cmd,
29687
29838
  relay: ctx.relay,
29688
- opts: { sessionId: ctx.sessionId, pluginId: ctx.pluginId, pluginAuthToken: ctx.pluginAuthToken }
29839
+ opts: {
29840
+ sessionId: ctx.sessionId,
29841
+ pluginId: ctx.pluginId,
29842
+ pluginAuthToken: ctx.pluginAuthToken
29843
+ }
29844
+ });
29845
+ var scratchSaveGitlab = (ctx, cmd) => scratchSaveGitlabH({
29846
+ cmd,
29847
+ relay: ctx.relay,
29848
+ opts: {
29849
+ sessionId: ctx.sessionId,
29850
+ pluginId: ctx.pluginId,
29851
+ pluginAuthToken: ctx.pluginAuthToken
29852
+ }
29689
29853
  });
29690
29854
  var handlers = {
29691
29855
  start_task: startTask,
@@ -29740,7 +29904,8 @@ var handlers = {
29740
29904
  guardrail_configure: guardrailConfigureH,
29741
29905
  cli_self_update: cliSelfUpdateH(),
29742
29906
  scratch_export_zip: scratchExportZip,
29743
- scratch_save_github: scratchSaveGithub
29907
+ scratch_save_github: scratchSaveGithub,
29908
+ scratch_save_gitlab: scratchSaveGitlab
29744
29909
  };
29745
29910
  async function dispatchCommand(ctx, cmd) {
29746
29911
  if (cmd.type === "beads_action") {
@@ -30043,11 +30208,11 @@ function resolveTokenValue(args2) {
30043
30208
  }
30044
30209
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
30045
30210
  if (fileFlag) {
30046
- const path104 = fileFlag.slice("--token-file=".length);
30211
+ const path105 = fileFlag.slice("--token-file=".length);
30047
30212
  try {
30048
- const content = fs61.readFileSync(path104, "utf8").trim();
30049
- if (content.length === 0) fail(`--token-file ${path104} is empty`);
30050
- rmIfExistsQuiet(path104);
30213
+ const content = fs61.readFileSync(path105, "utf8").trim();
30214
+ if (content.length === 0) fail(`--token-file ${path105} is empty`);
30215
+ rmIfExistsQuiet(path105);
30051
30216
  return content;
30052
30217
  } catch (err) {
30053
30218
  fail(`Could not read --token-file: ${err.message}`);
@@ -30730,7 +30895,7 @@ var AgentService = class _AgentService {
30730
30895
  var path70 = __toESM(require("path"));
30731
30896
 
30732
30897
  // src/agents/kimi/installer.ts
30733
- var import_node_child_process23 = require("child_process");
30898
+ var import_node_child_process25 = require("child_process");
30734
30899
  var import_node_os10 = require("os");
30735
30900
  var import_node_path14 = require("path");
30736
30901
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
@@ -30738,7 +30903,7 @@ function kimiBinDir() {
30738
30903
  return (0, import_node_path14.join)(process.env.KIMI_CODE_HOME || (0, import_node_path14.join)((0, import_node_os10.homedir)(), ".kimi-code"), "bin");
30739
30904
  }
30740
30905
  function kimiRuns() {
30741
- const r = (0, import_node_child_process23.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
30906
+ const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
30742
30907
  return !r.error && r.status === 0;
30743
30908
  }
30744
30909
  function augmentKimiPath() {
@@ -30749,7 +30914,7 @@ function augmentKimiPath() {
30749
30914
  var augmentPath2 = augmentKimiPath;
30750
30915
  async function runInstaller2() {
30751
30916
  return new Promise((resolve12) => {
30752
- const proc = (0, import_node_child_process23.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
30917
+ const proc = (0, import_node_child_process25.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
30753
30918
  proc.on("close", (code) => resolve12(code === 0));
30754
30919
  proc.on("error", () => resolve12(false));
30755
30920
  });
@@ -30783,7 +30948,7 @@ async function ensureKimiInstalled() {
30783
30948
  }
30784
30949
 
30785
30950
  // src/agents/opencode/installer.ts
30786
- var import_node_child_process24 = require("child_process");
30951
+ var import_node_child_process26 = require("child_process");
30787
30952
  var import_node_os11 = require("os");
30788
30953
  var import_node_path15 = require("path");
30789
30954
  var INSTALL_URL3 = "https://opencode.ai/install";
@@ -30791,7 +30956,7 @@ function opencodeBinDir() {
30791
30956
  return (0, import_node_path15.join)(process.env.OPENCODE_HOME || (0, import_node_path15.join)((0, import_node_os11.homedir)(), ".opencode"), "bin");
30792
30957
  }
30793
30958
  function opencodeRuns() {
30794
- const r = (0, import_node_child_process24.spawnSync)("opencode", ["--version"], { stdio: "ignore", timeout: 15e3 });
30959
+ const r = (0, import_node_child_process26.spawnSync)("opencode", ["--version"], { stdio: "ignore", timeout: 15e3 });
30795
30960
  return !r.error && r.status === 0;
30796
30961
  }
30797
30962
  function augmentOpencodePath() {
@@ -30802,7 +30967,7 @@ function augmentOpencodePath() {
30802
30967
  var augmentPath3 = augmentOpencodePath;
30803
30968
  async function runInstaller3() {
30804
30969
  return new Promise((resolve12) => {
30805
- const proc = (0, import_node_child_process24.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL3} | bash`], { stdio: "inherit" });
30970
+ const proc = (0, import_node_child_process26.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL3} | bash`], { stdio: "inherit" });
30806
30971
  proc.on("close", (code) => resolve12(code === 0));
30807
30972
  proc.on("error", () => resolve12(false));
30808
30973
  });
@@ -31735,7 +31900,7 @@ var HistoryService = class _HistoryService {
31735
31900
  };
31736
31901
 
31737
31902
  // src/agents/acp/client.ts
31738
- var import_node_child_process25 = require("child_process");
31903
+ var import_node_child_process27 = require("child_process");
31739
31904
  var fs63 = __toESM(require("fs/promises"));
31740
31905
  var fsSync = __toESM(require("fs"));
31741
31906
  var os48 = __toESM(require("os"));
@@ -36112,7 +36277,7 @@ var AcpClient = class {
36112
36277
  "acpClient",
36113
36278
  `provider routing ${formatProviderRouting(describeProviderRouting(childEnv, { cwd }), adapter.command)}`
36114
36279
  );
36115
- const child = (0, import_node_child_process25.spawn)(adapter.command, adapter.args, {
36280
+ const child = (0, import_node_child_process27.spawn)(adapter.command, adapter.args, {
36116
36281
  cwd,
36117
36282
  env: childEnv,
36118
36283
  stdio: ["pipe", "pipe", "pipe"],
@@ -36797,7 +36962,7 @@ var AcpClient = class {
36797
36962
  try {
36798
36963
  const pid = child.pid;
36799
36964
  if (process.platform === "win32") {
36800
- if (pid) (0, import_node_child_process25.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pid)], { stdio: "ignore" });
36965
+ if (pid) (0, import_node_child_process27.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pid)], { stdio: "ignore" });
36801
36966
  } else if (pid) {
36802
36967
  killQuiet(-pid, "SIGTERM");
36803
36968
  } else {
@@ -38966,7 +39131,7 @@ function defaultRunGit(cwd, args2) {
38966
39131
  });
38967
39132
  }
38968
39133
  async function discoverRepos(workingDir, maxDepth = 4) {
38969
- const fs89 = await import("fs/promises");
39134
+ const fs90 = await import("fs/promises");
38970
39135
  const out2 = [];
38971
39136
  await walk2(workingDir, 0);
38972
39137
  return out2;
@@ -38974,7 +39139,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
38974
39139
  if (depth2 > maxDepth) return;
38975
39140
  let entries2 = [];
38976
39141
  try {
38977
- const dirents = await fs89.readdir(dir, { withFileTypes: true });
39142
+ const dirents = await fs90.readdir(dir, { withFileTypes: true });
38978
39143
  entries2 = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
38979
39144
  } catch {
38980
39145
  return;
@@ -39530,11 +39695,11 @@ function isProcessMidTurn(pid, home) {
39530
39695
  }
39531
39696
 
39532
39697
  // src/packs/gates.ts
39533
- var import_node_child_process26 = require("child_process");
39698
+ var import_node_child_process28 = require("child_process");
39534
39699
  var fs72 = __toESM(require("fs"));
39535
39700
  var path83 = __toESM(require("path"));
39536
39701
  var defaultCommandRunner = (file, args2, cwd, timeoutMs, env) => new Promise((resolve12) => {
39537
- (0, import_node_child_process26.execFile)(
39702
+ (0, import_node_child_process28.execFile)(
39538
39703
  file,
39539
39704
  args2,
39540
39705
  {
@@ -40799,11 +40964,11 @@ function previewMcpServer(bridge) {
40799
40964
  };
40800
40965
  }
40801
40966
  function httpCall(baseUrl, token) {
40802
- return async (path104, method, body, timeoutMs) => {
40967
+ return async (path105, method, body, timeoutMs) => {
40803
40968
  const ac = new AbortController();
40804
40969
  const timer = setTimeout(() => ac.abort(), timeoutMs);
40805
40970
  try {
40806
- const res = await fetch(`${baseUrl}${path104}`, {
40971
+ const res = await fetch(`${baseUrl}${path105}`, {
40807
40972
  method,
40808
40973
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
40809
40974
  ...method === "POST" ? { body: JSON.stringify(body ?? {}) } : {},
@@ -40930,11 +41095,11 @@ function scratchMcpServer(bridge) {
40930
41095
  };
40931
41096
  }
40932
41097
  function httpCall2(baseUrl, token) {
40933
- return async (path104, method, body, timeoutMs) => {
41098
+ return async (path105, method, body, timeoutMs) => {
40934
41099
  const ac = new AbortController();
40935
41100
  const timer = setTimeout(() => ac.abort(), timeoutMs);
40936
41101
  try {
40937
- const res = await fetch(`${baseUrl}${path104}`, {
41102
+ const res = await fetch(`${baseUrl}${path105}`, {
40938
41103
  method,
40939
41104
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
40940
41105
  ...method === "POST" ? { body: JSON.stringify(body ?? {}) } : {},
@@ -41624,7 +41789,7 @@ function logMentionOutcome(result) {
41624
41789
  }
41625
41790
 
41626
41791
  // src/agents/acp/command-handlers.ts
41627
- var import_node_child_process27 = require("child_process");
41792
+ var import_node_child_process29 = require("child_process");
41628
41793
 
41629
41794
  // src/agents/acp/buildAcpPromptBlocks.ts
41630
41795
  var MIME_FROM_EXT = {
@@ -42035,7 +42200,9 @@ async function startTaskH(ctx) {
42035
42200
  log.warn("acpRunner", `turnFiles.flushTurn failed: ${describeError(err)}`);
42036
42201
  });
42037
42202
  log.info("acpRunner", `start_task \u2190 byo-provider-billing id=${cmd.id.slice(0, 8)}`);
42038
- await relay.sendResult(cmd.id, "failed", { error: "provider account has no credits (402)" });
42203
+ await relay.sendResult(cmd.id, "failed", {
42204
+ error: "provider account has no credits (402)"
42205
+ });
42039
42206
  return;
42040
42207
  } else if (replyIsAuthFailure(finalText)) {
42041
42208
  await streaming.closeWithBubble(AUTH_FAILURE_MESSAGE);
@@ -42587,7 +42754,7 @@ async function prewarmNewMcpEntries(manifest, previousIds) {
42587
42754
  fresh.map(
42588
42755
  (e) => new Promise((resolve12) => {
42589
42756
  const mcp = e.delivery.mcp;
42590
- const child = (0, import_node_child_process27.execFile)(
42757
+ const child = (0, import_node_child_process29.execFile)(
42591
42758
  mcp.command,
42592
42759
  [...mcp.args, "--help"],
42593
42760
  { timeout: 9e4 },
@@ -42704,7 +42871,8 @@ var ACP_COMMAND_HANDLERS = {
42704
42871
  [SQUAD_CONFIGURE_COMMAND]: squadConfigureH,
42705
42872
  [SQUAD_STATS_COMMAND]: squadStatsH,
42706
42873
  scratch_export_zip: scratchExportZipH,
42707
- scratch_save_github: scratchSaveGithubH
42874
+ scratch_save_github: scratchSaveGithubH,
42875
+ scratch_save_gitlab: scratchSaveGitlabH
42708
42876
  };
42709
42877
  async function dispatchAcpCommand(ctx) {
42710
42878
  const handler = ACP_COMMAND_HANDLERS[ctx.cmd.type];
@@ -45027,6 +45195,45 @@ function startClaudeCredentialSync(opts) {
45027
45195
  };
45028
45196
  }
45029
45197
 
45198
+ // src/scratch/workflow-hint.ts
45199
+ var import_node_fs19 = __toESM(require("fs"));
45200
+ var import_node_path19 = __toESM(require("path"));
45201
+ var SCRATCH_HINT_MARKER = "<!-- codeam:scratch-workflow -->";
45202
+ var SCRATCH_HINT = `${SCRATCH_HINT_MARKER}
45203
+ # From-scratch projects (CodeAgent Box)
45204
+
45205
+ When the working directory is a project started from scratch (no git remote,
45206
+ a \`.git/codeam-scratch\` marker):
45207
+
45208
+ - Build something small, visible and working first. As soon as it can be
45209
+ seen, start it with the \`codeagent_preview\` \`start_preview\` tool and tell the
45210
+ user the preview is open.
45211
+ - Saving is the user's choice in the app (Save to GitHub / GitLab, or a ZIP).
45212
+ Never push, create repositories or ask for git credentials yourself. Once the
45213
+ user has seen something working, call \`suggest_save_project\` ONCE if the
45214
+ app has not offered to save yet.
45215
+ ${SCRATCH_HINT_MARKER}`;
45216
+ function ensureScratchWorkflowHint(homeDir2, file = claudeMemoryFile(homeDir2)) {
45217
+ try {
45218
+ let existing = "";
45219
+ try {
45220
+ existing = import_node_fs19.default.readFileSync(file, "utf8");
45221
+ } catch {
45222
+ }
45223
+ if (existing.includes(SCRATCH_HINT)) return;
45224
+ import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
45225
+ const open = existing.indexOf(SCRATCH_HINT_MARKER);
45226
+ const close = open === -1 ? -1 : existing.indexOf(SCRATCH_HINT_MARKER, open + SCRATCH_HINT_MARKER.length);
45227
+ const next = open !== -1 && close !== -1 ? existing.slice(0, open) + SCRATCH_HINT + existing.slice(close + SCRATCH_HINT_MARKER.length) : existing.trim() ? `${existing.trimEnd()}
45228
+
45229
+ ${SCRATCH_HINT}
45230
+ ` : `${SCRATCH_HINT}
45231
+ `;
45232
+ import_node_fs19.default.writeFileSync(file, next);
45233
+ } catch {
45234
+ }
45235
+ }
45236
+
45030
45237
  // src/commands/start/pick-session.ts
45031
45238
  function pickPinnedSession(pinnedId, listSessions2) {
45032
45239
  const id = pinnedId?.trim();
@@ -45042,8 +45249,8 @@ function pickPinnedSession(pinnedId, listSessions2) {
45042
45249
  }
45043
45250
 
45044
45251
  // src/agents/retired-proxy-cleanup.ts
45045
- var fs79 = __toESM(require("fs"));
45046
- var path90 = __toESM(require("path"));
45252
+ var fs80 = __toESM(require("fs"));
45253
+ var path91 = __toESM(require("path"));
45047
45254
  var os59 = __toESM(require("os"));
45048
45255
  var RETIRED_PROXY_RE = /^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):8787(?:[/?#]|$)/i;
45049
45256
  var HEADROOM_CMD_RE = /(^|[\s/"'])headroom(\s|$)/i;
@@ -45055,10 +45262,10 @@ function isHeadroomHook(group) {
45055
45262
  }
45056
45263
  function sanitizeRetiredProxyConfig(homeDir2 = os59.homedir()) {
45057
45264
  const out2 = { inspected: false, changed: false, removed: [] };
45058
- const file = path90.join(homeDir2, ".claude", "settings.json");
45265
+ const file = path91.join(homeDir2, ".claude", "settings.json");
45059
45266
  let parsed;
45060
45267
  try {
45061
- parsed = JSON.parse(fs79.readFileSync(file, "utf8"));
45268
+ parsed = JSON.parse(fs80.readFileSync(file, "utf8"));
45062
45269
  } catch {
45063
45270
  return out2;
45064
45271
  }
@@ -45100,9 +45307,9 @@ function sanitizeRetiredProxyConfig(homeDir2 = os59.homedir()) {
45100
45307
  if (!out2.changed) return out2;
45101
45308
  try {
45102
45309
  const tmp = `${file}.codeam.tmp`;
45103
- fs79.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
45310
+ fs80.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
45104
45311
  `, { mode: 384 });
45105
- fs79.renameSync(tmp, file);
45312
+ fs80.renameSync(tmp, file);
45106
45313
  } catch {
45107
45314
  out2.changed = false;
45108
45315
  }
@@ -45634,7 +45841,7 @@ var AcpDriver = class {
45634
45841
  };
45635
45842
 
45636
45843
  // src/baton/transcript-mirror.ts
45637
- var fs80 = __toESM(require("fs"));
45844
+ var fs81 = __toESM(require("fs"));
45638
45845
  var TranscriptMirror = class {
45639
45846
  constructor(deps) {
45640
45847
  this.deps = deps;
@@ -45728,7 +45935,7 @@ var TranscriptMirror = class {
45728
45935
  }
45729
45936
  };
45730
45937
  function defaultWatch(file, onChange) {
45731
- const w3 = fs80.watch(file, { persistent: false }, () => onChange());
45938
+ const w3 = fs81.watch(file, { persistent: false }, () => onChange());
45732
45939
  return () => w3.close();
45733
45940
  }
45734
45941
 
@@ -46038,7 +46245,7 @@ function toEpochMs(ts) {
46038
46245
  }
46039
46246
 
46040
46247
  // src/services/keep-awake.ts
46041
- var import_node_child_process28 = require("child_process");
46248
+ var import_node_child_process30 = require("child_process");
46042
46249
  function keepDeviceAwake(deps = {}) {
46043
46250
  const env = deps.env ?? process.env;
46044
46251
  const isLocal = deps.isLocal ?? isLocalSession(env);
@@ -46048,7 +46255,7 @@ function keepDeviceAwake(deps = {}) {
46048
46255
  if (env.CODEAM_NO_KEEP_AWAKE === "1") return noop;
46049
46256
  const command2 = deps.command !== void 0 ? deps.command : createOsStrategy().keepAwakeCommand(deps.pid ?? process.pid);
46050
46257
  if (!command2) return noop;
46051
- const spawnFn = deps.spawnFn ?? import_node_child_process28.spawn;
46258
+ const spawnFn = deps.spawnFn ?? import_node_child_process30.spawn;
46052
46259
  let child = null;
46053
46260
  try {
46054
46261
  child = spawnFn(command2.cmd, command2.args, { stdio: "ignore", detached: true });
@@ -46074,16 +46281,16 @@ function keepDeviceAwake(deps = {}) {
46074
46281
  }
46075
46282
 
46076
46283
  // src/agents/claude/onboarding.ts
46077
- var fs81 = __toESM(require("fs"));
46284
+ var fs82 = __toESM(require("fs"));
46078
46285
  var os61 = __toESM(require("os"));
46079
- var path91 = __toESM(require("path"));
46286
+ var path92 = __toESM(require("path"));
46080
46287
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
46081
46288
  function ensureClaudeOnboarded(cwd) {
46082
46289
  try {
46083
- const file = path91.join(os61.homedir(), ".claude.json");
46290
+ const file = path92.join(os61.homedir(), ".claude.json");
46084
46291
  let config = {};
46085
46292
  try {
46086
- config = JSON.parse(fs81.readFileSync(file, "utf8"));
46293
+ config = JSON.parse(fs82.readFileSync(file, "utf8"));
46087
46294
  } catch {
46088
46295
  }
46089
46296
  let changed = false;
@@ -46108,8 +46315,8 @@ function ensureClaudeOnboarded(cwd) {
46108
46315
  }
46109
46316
  }
46110
46317
  if (!changed) return;
46111
- fs81.mkdirSync(path91.dirname(file), { recursive: true });
46112
- fs81.writeFileSync(file, JSON.stringify(config, null, 2));
46318
+ fs82.mkdirSync(path92.dirname(file), { recursive: true });
46319
+ fs82.writeFileSync(file, JSON.stringify(config, null, 2));
46113
46320
  log.info(
46114
46321
  "claude",
46115
46322
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -46123,9 +46330,14 @@ function ensureClaudeOnboarded(cwd) {
46123
46330
  async function start(requestedAgent, presetSession) {
46124
46331
  installRelayCrashGuards();
46125
46332
  showIntro();
46126
- const pinned = pickPinnedSession(process.env.CODEAM_RESUME_SESSION_ID, () => loadCliConfig().sessions);
46333
+ const pinned = pickPinnedSession(
46334
+ process.env.CODEAM_RESUME_SESSION_ID,
46335
+ () => loadCliConfig().sessions
46336
+ );
46127
46337
  if (pinned.kind === "missing") {
46128
- console.log(` ${import_picocolors3.default.dim(`Pinned session ${pinned.id.slice(0, 8)} is no longer paired \u2014 nothing to resume.`)}`);
46338
+ console.log(
46339
+ ` ${import_picocolors3.default.dim(`Pinned session ${pinned.id.slice(0, 8)} is no longer paired \u2014 nothing to resume.`)}`
46340
+ );
46129
46341
  process.exit(0);
46130
46342
  }
46131
46343
  const session = presetSession ? presetSession : pinned.kind === "found" ? pinned.session : requestedAgent ? getActiveSessionForAgent(requestedAgent) : getActiveSession();
@@ -46145,7 +46357,9 @@ async function start(requestedAgent, presetSession) {
46145
46357
  process.exit(0);
46146
46358
  }
46147
46359
  if (!acquireDaemonLock(session.id)) {
46148
- console.log(` ${import_picocolors3.default.dim("A codeam daemon for this session is already running \u2014 deferring to it.")}`);
46360
+ console.log(
46361
+ ` ${import_picocolors3.default.dim("A codeam daemon for this session is already running \u2014 deferring to it.")}`
46362
+ );
46149
46363
  process.exit(0);
46150
46364
  }
46151
46365
  if (!session.agent) {
@@ -46170,11 +46384,7 @@ async function start(requestedAgent, presetSession) {
46170
46384
  requestedAgent: requestedAgent ?? null
46171
46385
  });
46172
46386
  const cwd = process.cwd();
46173
- const refreshed = await fetchCurrentPluginAuthToken(
46174
- session.id,
46175
- pluginId,
46176
- session.pollSecret
46177
- );
46387
+ const refreshed = await fetchCurrentPluginAuthToken(session.id, pluginId, session.pollSecret);
46178
46388
  if (refreshed && refreshed !== session.pluginAuthToken) {
46179
46389
  addSession({ ...session, pluginAuthToken: refreshed });
46180
46390
  session.pluginAuthToken = refreshed;
@@ -46200,6 +46410,7 @@ async function start(requestedAgent, presetSession) {
46200
46410
  let beads = null;
46201
46411
  const getBeads = () => beads;
46202
46412
  ensureBeadsWorkflowHint();
46413
+ if (isScratchWorkspace(process.cwd())) ensureScratchWorkflowHint();
46203
46414
  if (!isLocalSession() && session.agent === "claude") {
46204
46415
  ensureAgentStandard();
46205
46416
  }
@@ -46252,7 +46463,11 @@ async function start(requestedAgent, presetSession) {
46252
46463
  );
46253
46464
  if (isScratchWorkspace(process.cwd())) {
46254
46465
  const deployId = deployIdFromWorkspace(process.cwd());
46255
- if (deployId) void registerScratchProject({ sessionId: session.id, pluginId, pluginAuthToken: session.pluginAuthToken }, deployId);
46466
+ if (deployId)
46467
+ void registerScratchProject(
46468
+ { sessionId: session.id, pluginId, pluginAuthToken: session.pluginAuthToken },
46469
+ deployId
46470
+ );
46256
46471
  }
46257
46472
  provisionSkillsForStart();
46258
46473
  const managedBox = !isLocalSession();
@@ -46416,32 +46631,29 @@ async function start(requestedAgent, presetSession) {
46416
46631
  dirtyTracker: dirtyTracker ?? void 0
46417
46632
  }) : null;
46418
46633
  let streamingEmitter = null;
46419
- const agent = new AgentService(
46420
- runtime,
46421
- {
46422
- cwd,
46423
- onData(raw) {
46424
- outputSvc.push(raw);
46425
- streamingEmitter?.push(raw);
46426
- },
46427
- async onExit(code) {
46428
- process.removeListener("SIGINT", sigintHandler);
46429
- process.removeListener("SIGTERM", sigintHandler);
46430
- process.removeListener("SIGHUP", sigintHandler);
46431
- outputSvc.dispose();
46432
- await stopRelayWithGoodbye(relay);
46433
- void fileWatcher?.stop();
46434
- turnFiles?.stop();
46435
- void beads?.watcher.stop();
46436
- void streamingEmitter?.stop();
46437
- closeAllTerminals();
46438
- cleanupAttachmentTempFiles();
46439
- killActiveSpawnAndCaptureChildren();
46440
- await reapPreviewsAndExportTunnel();
46441
- process.exit(code);
46442
- }
46634
+ const agent = new AgentService(runtime, {
46635
+ cwd,
46636
+ onData(raw) {
46637
+ outputSvc.push(raw);
46638
+ streamingEmitter?.push(raw);
46639
+ },
46640
+ async onExit(code) {
46641
+ process.removeListener("SIGINT", sigintHandler);
46642
+ process.removeListener("SIGTERM", sigintHandler);
46643
+ process.removeListener("SIGHUP", sigintHandler);
46644
+ outputSvc.dispose();
46645
+ await stopRelayWithGoodbye(relay);
46646
+ void fileWatcher?.stop();
46647
+ turnFiles?.stop();
46648
+ void beads?.watcher.stop();
46649
+ void streamingEmitter?.stop();
46650
+ closeAllTerminals();
46651
+ cleanupAttachmentTempFiles();
46652
+ killActiveSpawnAndCaptureChildren();
46653
+ await reapPreviewsAndExportTunnel();
46654
+ process.exit(code);
46443
46655
  }
46444
- );
46656
+ });
46445
46657
  if (session.pluginAuthToken) {
46446
46658
  streamingEmitter = new StreamingEmitterService({
46447
46659
  sessionId: session.id,
@@ -46890,7 +47102,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
46890
47102
  var import_child_process30 = require("child_process");
46891
47103
  var import_util4 = require("util");
46892
47104
  var import_picocolors8 = __toESM(require("picocolors"));
46893
- var path92 = __toESM(require("path"));
47105
+ var path93 = __toESM(require("path"));
46894
47106
  var execFileP6 = (0, import_util4.promisify)(import_child_process30.execFile);
46895
47107
  var MAX_BUFFER = 8 * 1024 * 1024;
46896
47108
  function resetStdinForChild() {
@@ -47379,7 +47591,7 @@ var GitHubCodespacesProvider = class {
47379
47591
  });
47380
47592
  }
47381
47593
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
47382
- const remoteDir = path92.posix.dirname(remotePath);
47594
+ const remoteDir = path93.posix.dirname(remotePath);
47383
47595
  const parts = [
47384
47596
  `mkdir -p ${shellQuote(remoteDir)}`,
47385
47597
  `cat > ${shellQuote(remotePath)}`
@@ -47449,7 +47661,7 @@ function shellQuote(s) {
47449
47661
  // src/services/providers/gitpod.ts
47450
47662
  var import_child_process31 = require("child_process");
47451
47663
  var import_util5 = require("util");
47452
- var path93 = __toESM(require("path"));
47664
+ var path94 = __toESM(require("path"));
47453
47665
  var import_picocolors9 = __toESM(require("picocolors"));
47454
47666
  var execFileP7 = (0, import_util5.promisify)(import_child_process31.execFile);
47455
47667
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -47689,7 +47901,7 @@ var GitpodProvider = class {
47689
47901
  });
47690
47902
  }
47691
47903
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
47692
- const remoteDir = path93.posix.dirname(remotePath);
47904
+ const remoteDir = path94.posix.dirname(remotePath);
47693
47905
  const parts = [
47694
47906
  `mkdir -p ${shellQuote2(remoteDir)}`,
47695
47907
  `cat > ${shellQuote2(remotePath)}`
@@ -47725,7 +47937,7 @@ function shellQuote2(s) {
47725
47937
  // src/services/providers/gitlab-workspaces.ts
47726
47938
  var import_child_process32 = require("child_process");
47727
47939
  var import_util6 = require("util");
47728
- var path94 = __toESM(require("path"));
47940
+ var path95 = __toESM(require("path"));
47729
47941
  var execFileP8 = (0, import_util6.promisify)(import_child_process32.execFile);
47730
47942
  var MAX_BUFFER3 = 8 * 1024 * 1024;
47731
47943
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -47985,7 +48197,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
47985
48197
  }
47986
48198
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
47987
48199
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
47988
- const remoteDir = path94.posix.dirname(remotePath);
48200
+ const remoteDir = path95.posix.dirname(remotePath);
47989
48201
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
47990
48202
  if (options.mode != null) {
47991
48203
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -48053,7 +48265,7 @@ function shellQuote3(s) {
48053
48265
  // src/services/providers/railway.ts
48054
48266
  var import_child_process33 = require("child_process");
48055
48267
  var import_util7 = require("util");
48056
- var path95 = __toESM(require("path"));
48268
+ var path96 = __toESM(require("path"));
48057
48269
  var execFileP9 = (0, import_util7.promisify)(import_child_process33.execFile);
48058
48270
  var MAX_BUFFER4 = 8 * 1024 * 1024;
48059
48271
  function resetStdinForChild4() {
@@ -48289,7 +48501,7 @@ var RailwayProvider = class {
48289
48501
  if (!projectId || !serviceId) {
48290
48502
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
48291
48503
  }
48292
- const remoteDir = path95.posix.dirname(remotePath);
48504
+ const remoteDir = path96.posix.dirname(remotePath);
48293
48505
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
48294
48506
  if (options.mode != null) {
48295
48507
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -48820,18 +49032,18 @@ async function probeCodeamPair(provider, workspace) {
48820
49032
  }
48821
49033
  async function stopWorkspaceFromLocal(target) {
48822
49034
  if (target.provider.id === "github-codespaces") {
48823
- const { execFile: execFile18 } = await import("child_process");
48824
- const { promisify: promisify15 } = await import("util");
48825
- const execFileP10 = promisify15(execFile18);
49035
+ const { execFile: execFile20 } = await import("child_process");
49036
+ const { promisify: promisify17 } = await import("util");
49037
+ const execFileP10 = promisify17(execFile20);
48826
49038
  await execFileP10("gh", ["codespace", "stop", "-c", target.id], { maxBuffer: 8 * 1024 * 1024 });
48827
49039
  return;
48828
49040
  }
48829
49041
  }
48830
49042
 
48831
49043
  // src/commands/host/host-client.ts
48832
- var fs82 = __toESM(require("fs"));
49044
+ var fs83 = __toESM(require("fs"));
48833
49045
  var os62 = __toESM(require("os"));
48834
- var path96 = __toESM(require("path"));
49046
+ var path97 = __toESM(require("path"));
48835
49047
  var import_node_crypto13 = require("crypto");
48836
49048
  function sampleCpuTimes() {
48837
49049
  let idle = 0;
@@ -48880,7 +49092,7 @@ function apiBase() {
48880
49092
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
48881
49093
  }
48882
49094
  function hostIdentityPath() {
48883
- return path96.join(os62.homedir(), ".codeam", "host-agent.json");
49095
+ return path97.join(os62.homedir(), ".codeam", "host-agent.json");
48884
49096
  }
48885
49097
  function collectOsInfo() {
48886
49098
  return {
@@ -48892,7 +49104,7 @@ function collectOsInfo() {
48892
49104
  }
48893
49105
  function loadHostIdentity() {
48894
49106
  try {
48895
- const raw = fs82.readFileSync(hostIdentityPath(), "utf8");
49107
+ const raw = fs83.readFileSync(hostIdentityPath(), "utf8");
48896
49108
  const parsed = JSON.parse(raw);
48897
49109
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
48898
49110
  const p2 = parsed;
@@ -48920,8 +49132,8 @@ function ensureControlPollSecret(identity, save = saveHostIdentity) {
48920
49132
  }
48921
49133
  function saveHostIdentity(identity) {
48922
49134
  const file = hostIdentityPath();
48923
- fs82.mkdirSync(path96.dirname(file), { recursive: true, mode: 448 });
48924
- fs82.writeFileSync(file, JSON.stringify(identity, null, 2), {
49135
+ fs83.mkdirSync(path97.dirname(file), { recursive: true, mode: 448 });
49136
+ fs83.writeFileSync(file, JSON.stringify(identity, null, 2), {
48925
49137
  encoding: "utf8",
48926
49138
  mode: 384
48927
49139
  });
@@ -48966,7 +49178,7 @@ function isTerminalEnrollError(err) {
48966
49178
  }
48967
49179
  function deleteHostIdentity() {
48968
49180
  try {
48969
- fs82.rmSync(hostIdentityPath(), { force: true });
49181
+ fs83.rmSync(hostIdentityPath(), { force: true });
48970
49182
  } catch {
48971
49183
  }
48972
49184
  }
@@ -49182,10 +49394,10 @@ async function host(args2) {
49182
49394
  }
49183
49395
 
49184
49396
  // src/commands/host-agent.ts
49185
- var import_node_child_process33 = require("child_process");
49397
+ var import_node_child_process35 = require("child_process");
49186
49398
  var os66 = __toESM(require("os"));
49187
- var fs86 = __toESM(require("fs"));
49188
- var path100 = __toESM(require("path"));
49399
+ var fs87 = __toESM(require("fs"));
49400
+ var path101 = __toESM(require("path"));
49189
49401
 
49190
49402
  // src/skills/persist-from-payload.ts
49191
49403
  function persistOrClearSkillsFromPayload(skills) {
@@ -49194,13 +49406,13 @@ function persistOrClearSkillsFromPayload(skills) {
49194
49406
  }
49195
49407
 
49196
49408
  // src/commands/host/session-state.ts
49197
- var fs83 = __toESM(require("fs"));
49409
+ var fs84 = __toESM(require("fs"));
49198
49410
  var os63 = __toESM(require("os"));
49199
- var path97 = __toESM(require("path"));
49411
+ var path98 = __toESM(require("path"));
49200
49412
  function hostSessionStatePath(env = process.env) {
49201
49413
  const override = env.CODEAM_HOST_SESSION_STATE_FILE;
49202
49414
  if (override && override.trim()) return override.trim();
49203
- return path97.join(os63.homedir(), ".codeam", "host-agent-sessions.json");
49415
+ return path98.join(os63.homedir(), ".codeam", "host-agent-sessions.json");
49204
49416
  }
49205
49417
  function isRecord5(v) {
49206
49418
  if (typeof v !== "object" || v === null) return false;
@@ -49211,7 +49423,7 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
49211
49423
  return {
49212
49424
  load() {
49213
49425
  try {
49214
- const raw = JSON.parse(fs83.readFileSync(file, "utf8"));
49426
+ const raw = JSON.parse(fs84.readFileSync(file, "utf8"));
49215
49427
  return Array.isArray(raw?.sessions) ? raw.sessions.filter(isRecord5) : null;
49216
49428
  } catch {
49217
49429
  return null;
@@ -49219,18 +49431,18 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
49219
49431
  },
49220
49432
  save(list) {
49221
49433
  try {
49222
- fs83.mkdirSync(path97.dirname(file), { recursive: true, mode: 448 });
49434
+ fs84.mkdirSync(path98.dirname(file), { recursive: true, mode: 448 });
49223
49435
  const tmp = `${file}.${process.pid}.tmp`;
49224
- fs83.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
49436
+ fs84.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
49225
49437
  mode: 384
49226
49438
  });
49227
- fs83.renameSync(tmp, file);
49439
+ fs84.renameSync(tmp, file);
49228
49440
  } catch {
49229
49441
  }
49230
49442
  },
49231
49443
  clear() {
49232
49444
  try {
49233
- fs83.rmSync(file, { force: true });
49445
+ fs84.rmSync(file, { force: true });
49234
49446
  } catch {
49235
49447
  }
49236
49448
  }
@@ -49253,10 +49465,10 @@ function planSessionResume(records, max) {
49253
49465
  return { resume: ordered.slice(0, bound), dropped: ordered.slice(bound) };
49254
49466
  }
49255
49467
  function pickSavedSessionForWorkspace(sessions3, cwd, deployId) {
49256
- const target = path97.resolve(cwd);
49468
+ const target = path98.resolve(cwd);
49257
49469
  const reconnectable = (s) => !!s.pluginId && !!s.pollSecret && !!s.agent;
49258
49470
  const matches = sessions3.filter(
49259
- (s) => !!s.cwd && path97.resolve(s.cwd) === target && reconnectable(s)
49471
+ (s) => !!s.cwd && path98.resolve(s.cwd) === target && reconnectable(s)
49260
49472
  );
49261
49473
  if (matches.length > 0) {
49262
49474
  matches.sort((a, b) => b.pairedAt - a.pairedAt);
@@ -49267,12 +49479,12 @@ function pickSavedSessionForWorkspace(sessions3, cwd, deployId) {
49267
49479
  }
49268
49480
 
49269
49481
  // src/commands/host/git-tooling.ts
49270
- var import_node_child_process29 = require("child_process");
49271
- var fs84 = __toESM(require("fs"));
49482
+ var import_node_child_process31 = require("child_process");
49483
+ var fs85 = __toESM(require("fs"));
49272
49484
  var os64 = __toESM(require("os"));
49273
- var path98 = __toESM(require("path"));
49485
+ var path99 = __toESM(require("path"));
49274
49486
  function codeamBinDir() {
49275
- return process.env.CODEAM_BIN_DIR ?? path98.join(os64.homedir(), ".codeam", "bin");
49487
+ return process.env.CODEAM_BIN_DIR ?? path99.join(os64.homedir(), ".codeam", "bin");
49276
49488
  }
49277
49489
  var FALLBACK_GH_VERSION = "2.62.0";
49278
49490
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -49304,7 +49516,7 @@ async function download(url2, dest) {
49304
49516
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
49305
49517
  if (!res.ok || !res.body) return false;
49306
49518
  const buf = Buffer.from(await res.arrayBuffer());
49307
- fs84.writeFileSync(dest, buf);
49519
+ fs85.writeFileSync(dest, buf);
49308
49520
  return true;
49309
49521
  } catch {
49310
49522
  return false;
@@ -49327,8 +49539,8 @@ async function ensureGhCli(runner, token, deps = {}) {
49327
49539
  const version3 = await resolveVersionFn(token);
49328
49540
  const asset = `gh_${version3}_${osToken}_${arch2}`;
49329
49541
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
49330
- const tmpRoot = fs84.mkdtempSync(path98.join(os64.tmpdir(), "codeam-gh-"));
49331
- const archive = path98.join(tmpRoot, `${asset}.${ext}`);
49542
+ const tmpRoot = fs85.mkdtempSync(path99.join(os64.tmpdir(), "codeam-gh-"));
49543
+ const archive = path99.join(tmpRoot, `${asset}.${ext}`);
49332
49544
  if (!await downloadFn(url2, archive)) {
49333
49545
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
49334
49546
  return null;
@@ -49338,16 +49550,16 @@ async function ensureGhCli(runner, token, deps = {}) {
49338
49550
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
49339
49551
  return null;
49340
49552
  }
49341
- const extractedBin = path98.join(tmpRoot, asset, "bin", binaryName);
49342
- if (!fs84.existsSync(extractedBin)) {
49553
+ const extractedBin = path99.join(tmpRoot, asset, "bin", binaryName);
49554
+ if (!fs85.existsSync(extractedBin)) {
49343
49555
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
49344
49556
  return null;
49345
49557
  }
49346
49558
  const binDir = codeamBinDir();
49347
- fs84.mkdirSync(binDir, { recursive: true });
49348
- const target = path98.join(binDir, binaryName);
49349
- fs84.copyFileSync(extractedBin, target);
49350
- fs84.chmodSync(target, 493);
49559
+ fs85.mkdirSync(binDir, { recursive: true });
49560
+ const target = path99.join(binDir, binaryName);
49561
+ fs85.copyFileSync(extractedBin, target);
49562
+ fs85.chmodSync(target, 493);
49351
49563
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
49352
49564
  return target;
49353
49565
  } catch (e) {
@@ -49384,19 +49596,19 @@ async function ensureGhAuth(runner, ghCmd, token) {
49384
49596
  }
49385
49597
  function ghConfigDir() {
49386
49598
  if (process.env.GH_CONFIG_DIR) return process.env.GH_CONFIG_DIR;
49387
- if (process.env.XDG_CONFIG_HOME) return path98.join(process.env.XDG_CONFIG_HOME, "gh");
49599
+ if (process.env.XDG_CONFIG_HOME) return path99.join(process.env.XDG_CONFIG_HOME, "gh");
49388
49600
  if (process.platform === "win32" && process.env.APPDATA) {
49389
- return path98.join(process.env.APPDATA, "GitHub CLI");
49601
+ return path99.join(process.env.APPDATA, "GitHub CLI");
49390
49602
  }
49391
- return path98.join(os64.homedir(), ".config", "gh");
49603
+ return path99.join(os64.homedir(), ".config", "gh");
49392
49604
  }
49393
49605
  function writeGhHostsToken(token) {
49394
49606
  try {
49395
49607
  const dir = ghConfigDir();
49396
- const file = path98.join(dir, "hosts.yml");
49397
- if (fs84.existsSync(file)) return false;
49398
- fs84.mkdirSync(dir, { recursive: true, mode: 448 });
49399
- fs84.writeFileSync(
49608
+ const file = path99.join(dir, "hosts.yml");
49609
+ if (fs85.existsSync(file)) return false;
49610
+ fs85.mkdirSync(dir, { recursive: true, mode: 448 });
49611
+ fs85.writeFileSync(
49400
49612
  file,
49401
49613
  `github.com:
49402
49614
  oauth_token: ${token}
@@ -49439,8 +49651,8 @@ async function ensureGlabCli(runner, deps = {}) {
49439
49651
  const version3 = await resolveLatestGlabVersion();
49440
49652
  const asset = `glab_${version3}_${osToken}_${arch2}`;
49441
49653
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
49442
- const tmpRoot = fs84.mkdtempSync(path98.join(os64.tmpdir(), "codeam-glab-"));
49443
- const archive = path98.join(tmpRoot, `${asset}.${ext}`);
49654
+ const tmpRoot = fs85.mkdtempSync(path99.join(os64.tmpdir(), "codeam-glab-"));
49655
+ const archive = path99.join(tmpRoot, `${asset}.${ext}`);
49444
49656
  if (!await downloadFn(url2, archive)) {
49445
49657
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
49446
49658
  return null;
@@ -49451,20 +49663,20 @@ async function ensureGlabCli(runner, deps = {}) {
49451
49663
  return null;
49452
49664
  }
49453
49665
  const candidates = [
49454
- path98.join(tmpRoot, "bin", binaryName),
49455
- path98.join(tmpRoot, asset, "bin", binaryName),
49456
- path98.join(tmpRoot, binaryName)
49666
+ path99.join(tmpRoot, "bin", binaryName),
49667
+ path99.join(tmpRoot, asset, "bin", binaryName),
49668
+ path99.join(tmpRoot, binaryName)
49457
49669
  ];
49458
- const extractedBin = candidates.find((c2) => fs84.existsSync(c2));
49670
+ const extractedBin = candidates.find((c2) => fs85.existsSync(c2));
49459
49671
  if (!extractedBin) {
49460
49672
  log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
49461
49673
  return null;
49462
49674
  }
49463
49675
  const binDir = codeamBinDir();
49464
- fs84.mkdirSync(binDir, { recursive: true });
49465
- const target = path98.join(binDir, binaryName);
49466
- fs84.copyFileSync(extractedBin, target);
49467
- fs84.chmodSync(target, 493);
49676
+ fs85.mkdirSync(binDir, { recursive: true });
49677
+ const target = path99.join(binDir, binaryName);
49678
+ fs85.copyFileSync(extractedBin, target);
49679
+ fs85.chmodSync(target, 493);
49468
49680
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
49469
49681
  return target;
49470
49682
  } catch (e) {
@@ -49499,7 +49711,7 @@ var defaultGitToolingRunner = {
49499
49711
  which(cmd) {
49500
49712
  try {
49501
49713
  const probe = process.platform === "win32" ? "where" : "which";
49502
- (0, import_node_child_process29.execFileSync)(probe, [cmd], { stdio: "ignore" });
49714
+ (0, import_node_child_process31.execFileSync)(probe, [cmd], { stdio: "ignore" });
49503
49715
  return true;
49504
49716
  } catch {
49505
49717
  return false;
@@ -49507,7 +49719,7 @@ var defaultGitToolingRunner = {
49507
49719
  },
49508
49720
  run(cmd, args2, opts = {}) {
49509
49721
  return new Promise((resolve12) => {
49510
- const child = (0, import_node_child_process29.spawn)(cmd, args2, {
49722
+ const child = (0, import_node_child_process31.spawn)(cmd, args2, {
49511
49723
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
49512
49724
  });
49513
49725
  let stderr = "";
@@ -49543,26 +49755,26 @@ var defaultGitToolingRunner = {
49543
49755
  };
49544
49756
 
49545
49757
  // src/commands/host/self-update.ts
49546
- var import_node_child_process31 = require("child_process");
49758
+ var import_node_child_process33 = require("child_process");
49547
49759
 
49548
49760
  // src/lib/updateNotifier.ts
49549
- var fs85 = __toESM(require("fs"));
49761
+ var fs86 = __toESM(require("fs"));
49550
49762
  var os65 = __toESM(require("os"));
49551
- var path99 = __toESM(require("path"));
49763
+ var path100 = __toESM(require("path"));
49552
49764
  var https8 = __toESM(require("https"));
49553
- var import_node_child_process30 = require("child_process");
49765
+ var import_node_child_process32 = require("child_process");
49554
49766
  var import_picocolors12 = __toESM(require("picocolors"));
49555
49767
  var PKG_NAME = "codeam-cli";
49556
49768
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
49557
49769
  var TTL_MS = 24 * 60 * 60 * 1e3;
49558
49770
  var REQUEST_TIMEOUT_MS = 1500;
49559
49771
  function cachePath() {
49560
- const dir = path99.join(os65.homedir(), ".codeam");
49561
- return path99.join(dir, "update-check.json");
49772
+ const dir = path100.join(os65.homedir(), ".codeam");
49773
+ return path100.join(dir, "update-check.json");
49562
49774
  }
49563
49775
  function readCache() {
49564
49776
  try {
49565
- const raw = fs85.readFileSync(cachePath(), "utf8");
49777
+ const raw = fs86.readFileSync(cachePath(), "utf8");
49566
49778
  const parsed = JSON.parse(raw);
49567
49779
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
49568
49780
  return parsed;
@@ -49573,10 +49785,10 @@ function readCache() {
49573
49785
  function writeCache(cache) {
49574
49786
  try {
49575
49787
  const file = cachePath();
49576
- fs85.mkdirSync(path99.dirname(file), { recursive: true });
49788
+ fs86.mkdirSync(path100.dirname(file), { recursive: true });
49577
49789
  const tmp = `${file}.${process.pid}.tmp`;
49578
- fs85.writeFileSync(tmp, JSON.stringify(cache));
49579
- fs85.renameSync(tmp, file);
49790
+ fs86.writeFileSync(tmp, JSON.stringify(cache));
49791
+ fs86.renameSync(tmp, file);
49580
49792
  } catch {
49581
49793
  }
49582
49794
  }
@@ -49644,14 +49856,14 @@ function notifyIfStale(currentVersion, latest) {
49644
49856
  }
49645
49857
  function isLinkedInstall() {
49646
49858
  try {
49647
- const root = (0, import_node_child_process30.execSync)("npm root -g", {
49859
+ const root = (0, import_node_child_process32.execSync)("npm root -g", {
49648
49860
  encoding: "utf8",
49649
49861
  stdio: ["ignore", "pipe", "ignore"],
49650
49862
  timeout: 2e3
49651
49863
  }).trim();
49652
49864
  if (!root) return false;
49653
- const pkgPath = path99.join(root, PKG_NAME);
49654
- return fs85.lstatSync(pkgPath).isSymbolicLink();
49865
+ const pkgPath = path100.join(root, PKG_NAME);
49866
+ return fs86.lstatSync(pkgPath).isSymbolicLink();
49655
49867
  } catch {
49656
49868
  return false;
49657
49869
  }
@@ -49672,7 +49884,7 @@ function maybeAutoUpdate(currentVersion, latest) {
49672
49884
 
49673
49885
  `
49674
49886
  );
49675
- const install = (0, import_node_child_process30.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
49887
+ const install = (0, import_node_child_process32.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
49676
49888
  stdio: "inherit",
49677
49889
  env: process.env
49678
49890
  });
@@ -49687,13 +49899,13 @@ function maybeAutoUpdate(currentVersion, latest) {
49687
49899
  return;
49688
49900
  }
49689
49901
  try {
49690
- fs85.unlinkSync(cachePath());
49902
+ fs86.unlinkSync(cachePath());
49691
49903
  } catch {
49692
49904
  }
49693
49905
  process.stderr.write(` ${import_picocolors12.default.green("\u2713")} Updated. Resuming session...
49694
49906
 
49695
49907
  `);
49696
- const child = (0, import_node_child_process30.spawnSync)("codeam", process.argv.slice(2), {
49908
+ const child = (0, import_node_child_process32.spawnSync)("codeam", process.argv.slice(2), {
49697
49909
  stdio: "inherit",
49698
49910
  env: process.env
49699
49911
  });
@@ -49703,7 +49915,7 @@ async function autoUpgradeBeforeCriticalCommand() {
49703
49915
  if (process.env.NODE_ENV === "test") return;
49704
49916
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
49705
49917
  if (process.env.CI) return;
49706
- const current2 = true ? "2.76.1" : null;
49918
+ const current2 = true ? "2.76.2" : null;
49707
49919
  if (!current2) return;
49708
49920
  const cache = readCache();
49709
49921
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -49720,7 +49932,7 @@ function checkForUpdates() {
49720
49932
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
49721
49933
  if (process.env.CI) return;
49722
49934
  if (!process.stdout.isTTY) return;
49723
- const current2 = true ? "2.76.1" : null;
49935
+ const current2 = true ? "2.76.2" : null;
49724
49936
  if (!current2) return;
49725
49937
  const cache = readCache();
49726
49938
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -49743,7 +49955,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
49743
49955
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
49744
49956
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
49745
49957
  function currentCliVersion() {
49746
- return true ? "2.76.1" : null;
49958
+ return true ? "2.76.2" : null;
49747
49959
  }
49748
49960
  async function installedVersion(deps) {
49749
49961
  const ls = await deps.run(
@@ -49760,7 +49972,7 @@ async function installedVersion(deps) {
49760
49972
  }
49761
49973
  function runCmd(cmd, args2, timeoutMs) {
49762
49974
  return new Promise((resolve12) => {
49763
- (0, import_node_child_process31.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
49975
+ (0, import_node_child_process33.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
49764
49976
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
49765
49977
  resolve12({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
49766
49978
  });
@@ -49844,10 +50056,10 @@ async function runSelfUpdateWith(deps) {
49844
50056
  }
49845
50057
 
49846
50058
  // src/commands/host/teardown.ts
49847
- var import_node_child_process32 = require("child_process");
50059
+ var import_node_child_process34 = require("child_process");
49848
50060
  var defaultDisableService = () => {
49849
50061
  try {
49850
- (0, import_node_child_process32.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
50062
+ (0, import_node_child_process34.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
49851
50063
  } catch {
49852
50064
  }
49853
50065
  };
@@ -50019,7 +50231,7 @@ var DOCKER_RUN_WITH_PULL_TIMEOUT_MS = 6e5;
50019
50231
  var defaultDockerRunner = {
50020
50232
  run(args2, opts = {}) {
50021
50233
  return new Promise((resolve12) => {
50022
- const child = (0, import_node_child_process33.spawn)("docker", args2, {
50234
+ const child = (0, import_node_child_process35.spawn)("docker", args2, {
50023
50235
  stdio: ["ignore", "pipe", "pipe"],
50024
50236
  env: { ...process.env, ...opts.env }
50025
50237
  });
@@ -50064,13 +50276,13 @@ var CONTROL_AGENT_META = {
50064
50276
  // Synthetic control channel — capability flags are moot (no agent runs).
50065
50277
  acp: false
50066
50278
  };
50067
- var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process33.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
50279
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process35.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
50068
50280
  cwd,
50069
50281
  env: { ...process.env, ...env },
50070
50282
  stdio: ["ignore", "pipe", "pipe"],
50071
50283
  detached: false
50072
50284
  });
50073
- var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process33.spawn)(process.execPath, [process.argv[1]], {
50285
+ var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process35.spawn)(process.execPath, [process.argv[1]], {
50074
50286
  cwd,
50075
50287
  // CODEAM_AUTO_APPROVE=1 → ACP path (baton off). CODEAM_RESUME_LATEST=1 →
50076
50288
  // continue the user's most-recent conversation instead of opening an empty
@@ -50096,7 +50308,7 @@ var ORPHAN_KILL_SETTLE_MS = 500;
50096
50308
  function needsSelfRelaunch(env = process.env, pid = process.pid) {
50097
50309
  return !env.INVOCATION_ID && pid !== 1;
50098
50310
  }
50099
- function isContainerEnvironment(existsSyncFn = fs86.existsSync, readFileSyncFn = (p2) => fs86.readFileSync(p2, "utf8")) {
50311
+ function isContainerEnvironment(existsSyncFn = fs87.existsSync, readFileSyncFn = (p2) => fs87.readFileSync(p2, "utf8")) {
50100
50312
  try {
50101
50313
  if (existsSyncFn("/.dockerenv")) return true;
50102
50314
  } catch {
@@ -50119,7 +50331,7 @@ var defaultOnUpdated = (version3) => {
50119
50331
  );
50120
50332
  if (relaunch) {
50121
50333
  try {
50122
- (0, import_node_child_process33.spawn)("/bin/sh", relaunchArgv(process.execPath, process.argv), {
50334
+ (0, import_node_child_process35.spawn)("/bin/sh", relaunchArgv(process.execPath, process.argv), {
50123
50335
  cwd: process.cwd(),
50124
50336
  env: process.env,
50125
50337
  detached: true,
@@ -50561,13 +50773,13 @@ var HostAgentSupervisor = class {
50561
50773
  const relay = this.relay;
50562
50774
  if (!relay) return;
50563
50775
  const raw = cmd.payload?.path;
50564
- const target = typeof raw === "string" && raw.trim() ? path100.resolve(raw.trim()) : os66.homedir();
50776
+ const target = typeof raw === "string" && raw.trim() ? path101.resolve(raw.trim()) : os66.homedir();
50565
50777
  try {
50566
- const dirents = await fs86.promises.readdir(target, { withFileTypes: true });
50778
+ const dirents = await fs87.promises.readdir(target, { withFileTypes: true });
50567
50779
  const entries2 = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
50568
50780
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
50569
50781
  );
50570
- const parent = path100.dirname(target);
50782
+ const parent = path101.dirname(target);
50571
50783
  await relay.sendResult(cmd.id, "completed", {
50572
50784
  path: target,
50573
50785
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -50915,14 +51127,14 @@ var HostAgentSupervisor = class {
50915
51127
  ...buildHouseProxyChildEnv({ baseUrl, token, openRouter: openRouter === true }),
50916
51128
  CODEAM_AUTO_TOKEN: payload.autoPairToken
50917
51129
  };
50918
- const houseConfigDir = path100.join(
51130
+ const houseConfigDir = path101.join(
50919
51131
  os66.homedir(),
50920
51132
  ".codeam",
50921
51133
  "house-claude",
50922
51134
  payload.deployId
50923
51135
  );
50924
51136
  try {
50925
- fs86.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
51137
+ fs87.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
50926
51138
  } catch {
50927
51139
  }
50928
51140
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -50956,13 +51168,13 @@ var HostAgentSupervisor = class {
50956
51168
  if ((payload.repoProvider ?? "github") === "gitlab") {
50957
51169
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
50958
51170
  if (glabCmd) {
50959
- childEnv.PATH = `${codeamBinDir()}${path100.delimiter}${childEnv.PATH}`;
51171
+ childEnv.PATH = `${codeamBinDir()}${path101.delimiter}${childEnv.PATH}`;
50960
51172
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
50961
51173
  }
50962
51174
  } else {
50963
51175
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
50964
51176
  if (ghCmd) {
50965
- childEnv.PATH = `${codeamBinDir()}${path100.delimiter}${childEnv.PATH}`;
51177
+ childEnv.PATH = `${codeamBinDir()}${path101.delimiter}${childEnv.PATH}`;
50966
51178
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
50967
51179
  }
50968
51180
  }
@@ -50990,9 +51202,9 @@ var HostAgentSupervisor = class {
50990
51202
  );
50991
51203
  if (!payload.suppressOnboardingWelcome) {
50992
51204
  try {
50993
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path100.join(os66.homedir(), ".claude");
50994
- const projectDir = path100.join(cfgDir, "projects", encodeCwd(cwd));
50995
- const hasPriorConversation = fs86.existsSync(projectDir) && fs86.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
51205
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path101.join(os66.homedir(), ".claude");
51206
+ const projectDir = path101.join(cfgDir, "projects", encodeCwd(cwd));
51207
+ const hasPriorConversation = fs87.existsSync(projectDir) && fs87.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
50996
51208
  if (hasPriorConversation) {
50997
51209
  childEnv.CODEAM_RESUME_LATEST = "1";
50998
51210
  log.info(
@@ -51146,7 +51358,7 @@ var HostAgentSupervisor = class {
51146
51358
  fallbackResumeTarget() {
51147
51359
  const session = getActiveSession();
51148
51360
  if (!session || !session.pluginId || !session.pollSecret || !session.agent) return null;
51149
- const cwd = session.cwd && fs86.existsSync(session.cwd) ? session.cwd : process.cwd();
51361
+ const cwd = session.cwd && fs87.existsSync(session.cwd) ? session.cwd : process.cwd();
51150
51362
  if (isFilesystemRoot(cwd)) {
51151
51363
  log.warn(
51152
51364
  "host-agent",
@@ -51186,7 +51398,7 @@ var HostAgentSupervisor = class {
51186
51398
  log.warn("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: no saved pairing on this box`);
51187
51399
  return;
51188
51400
  }
51189
- if (!session.cwd || !fs86.existsSync(session.cwd)) {
51401
+ if (!session.cwd || !fs87.existsSync(session.cwd)) {
51190
51402
  log.warn("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: workspace is gone`);
51191
51403
  return;
51192
51404
  }
@@ -51228,7 +51440,7 @@ var HostAgentSupervisor = class {
51228
51440
  const persisted = new Map((this.sessionStore.load() ?? []).map((r) => [r.deployId, r.agent]));
51229
51441
  for (const c2 of this.children.values()) persisted.set(c2.deployId, c2.agent);
51230
51442
  return this.listSavedSessions().map((s) => ({ s, deployId: deployIdFromWorkspace(s.cwd) })).filter(
51231
- (x) => x.deployId !== null && !!x.s.cwd && fs86.existsSync(x.s.cwd)
51443
+ (x) => x.deployId !== null && !!x.s.cwd && fs87.existsSync(x.s.cwd)
51232
51444
  ).map(({ s, deployId }) => {
51233
51445
  const agent = persisted.get(deployId);
51234
51446
  return { deployId, sessionId: s.id, ...agent ? { agent } : {} };
@@ -51280,7 +51492,7 @@ var HostAgentSupervisor = class {
51280
51492
  if (this.children.has(deployId)) return;
51281
51493
  const st3 = this.resumeStateFor(target);
51282
51494
  try {
51283
- const cwd = fs86.existsSync(target.cwd) ? target.cwd : process.cwd();
51495
+ const cwd = fs87.existsSync(target.cwd) ? target.cwd : process.cwd();
51284
51496
  const proc = this.resumeSpawner(
51285
51497
  { ...readHouseProxyChildEnv(deployId), CODEAM_RESUME_SESSION_ID: session.id },
51286
51498
  cwd
@@ -51499,12 +51711,12 @@ var HostAgentSupervisor = class {
51499
51711
  this.untrackChild(deployId);
51500
51712
  }
51501
51713
  const dirs = [
51502
- path100.join(selfHostedWorkspaceRoot(), deployId),
51503
- path100.join(os66.homedir(), ".codeam", "house-claude", deployId)
51714
+ path101.join(selfHostedWorkspaceRoot(), deployId),
51715
+ path101.join(os66.homedir(), ".codeam", "house-claude", deployId)
51504
51716
  ];
51505
51717
  for (const dir of dirs) {
51506
51718
  try {
51507
- fs86.rmSync(dir, { recursive: true, force: true });
51719
+ fs87.rmSync(dir, { recursive: true, force: true });
51508
51720
  } catch (err) {
51509
51721
  log.warn(
51510
51722
  "host-agent",
@@ -51662,12 +51874,12 @@ async function invite() {
51662
51874
 
51663
51875
  // src/commands/doctor.ts
51664
51876
  var import_node_dns = require("dns");
51665
- var import_node_util9 = require("util");
51877
+ var import_node_util11 = require("util");
51666
51878
  var import_node_crypto14 = require("crypto");
51667
- var fs87 = __toESM(require("fs"));
51668
- var path101 = __toESM(require("path"));
51879
+ var fs88 = __toESM(require("fs"));
51880
+ var path102 = __toESM(require("path"));
51669
51881
  var import_picocolors14 = __toESM(require("picocolors"));
51670
- var dnsResolveP = (0, import_node_util9.promisify)(import_node_dns.resolve);
51882
+ var dnsResolveP = (0, import_node_util11.promisify)(import_node_dns.resolve);
51671
51883
  async function checkDns(apiBase2) {
51672
51884
  const host2 = (() => {
51673
51885
  try {
@@ -51721,13 +51933,13 @@ async function checkHealth(apiBase2) {
51721
51933
  }
51722
51934
  }
51723
51935
  function checkConfigDir() {
51724
- const dir = path101.join(require("os").homedir(), ".codeam");
51936
+ const dir = path102.join(require("os").homedir(), ".codeam");
51725
51937
  try {
51726
- fs87.mkdirSync(dir, { recursive: true, mode: 448 });
51727
- const probe = path101.join(dir, ".doctor-probe");
51728
- fs87.writeFileSync(probe, "ok", { mode: 384 });
51729
- const read = fs87.readFileSync(probe, "utf8");
51730
- fs87.unlinkSync(probe);
51938
+ fs88.mkdirSync(dir, { recursive: true, mode: 448 });
51939
+ const probe = path102.join(dir, ".doctor-probe");
51940
+ fs88.writeFileSync(probe, "ok", { mode: 384 });
51941
+ const read = fs88.readFileSync(probe, "utf8");
51942
+ fs88.unlinkSync(probe);
51731
51943
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
51732
51944
  return {
51733
51945
  id: "config-dir",
@@ -51791,7 +52003,7 @@ function checkNodePty() {
51791
52003
  detail: "not required on this platform"
51792
52004
  };
51793
52005
  }
51794
- const vendoredPath = path101.join(__dirname, "vendor", "node-pty");
52006
+ const vendoredPath = path102.join(__dirname, "vendor", "node-pty");
51795
52007
  for (const target of [vendoredPath, "node-pty"]) {
51796
52008
  try {
51797
52009
  require(target);
@@ -51833,7 +52045,7 @@ function checkChokidar() {
51833
52045
  }
51834
52046
  async function doctor(args2 = []) {
51835
52047
  const json = args2.includes("--json");
51836
- const cliVersion = true ? "2.76.1" : "0.0.0-dev";
52048
+ const cliVersion = true ? "2.76.2" : "0.0.0-dev";
51837
52049
  const apiBase2 = resolveApiBaseUrl();
51838
52050
  const diagnosticId = (0, import_node_crypto14.randomUUID)();
51839
52051
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -52030,7 +52242,7 @@ async function completion(args2) {
52030
52242
  }
52031
52243
 
52032
52244
  // src/integrations/mcp-run.ts
52033
- var import_node_child_process36 = require("child_process");
52245
+ var import_node_child_process38 = require("child_process");
52034
52246
 
52035
52247
  // src/integrations/launcher-env.ts
52036
52248
  var LAUNCHER_ENV = Object.freeze({
@@ -52040,9 +52252,9 @@ var LAUNCHER_ENV = Object.freeze({
52040
52252
  });
52041
52253
 
52042
52254
  // src/integrations/mcp-run.ts
52043
- var import_node_fs19 = require("fs");
52255
+ var import_node_fs20 = require("fs");
52044
52256
  var import_node_os15 = __toESM(require("os"));
52045
- var import_node_path19 = __toESM(require("path"));
52257
+ var import_node_path20 = __toESM(require("path"));
52046
52258
 
52047
52259
  // src/integrations/token-client.ts
52048
52260
  var REFRESH_AHEAD_MS = 5 * 60 * 1e3;
@@ -52114,7 +52326,7 @@ function resolveDelivery(id) {
52114
52326
  function commandExists(command2) {
52115
52327
  try {
52116
52328
  const probe = process.platform === "win32" ? "where" : "which";
52117
- (0, import_node_child_process36.execFileSync)(probe, [command2], { stdio: "ignore" });
52329
+ (0, import_node_child_process38.execFileSync)(probe, [command2], { stdio: "ignore" });
52118
52330
  return true;
52119
52331
  } catch {
52120
52332
  return false;
@@ -52122,13 +52334,13 @@ function commandExists(command2) {
52122
52334
  }
52123
52335
  function localBinCandidates(command2) {
52124
52336
  return [
52125
- import_node_path19.default.join(import_node_os15.default.homedir(), ".local", "bin", command2),
52126
- import_node_path19.default.join(import_node_os15.default.homedir(), ".cargo", "bin", command2)
52337
+ import_node_path20.default.join(import_node_os15.default.homedir(), ".local", "bin", command2),
52338
+ import_node_path20.default.join(import_node_os15.default.homedir(), ".cargo", "bin", command2)
52127
52339
  ];
52128
52340
  }
52129
52341
  function resolveLauncherPath(command2, deps = {
52130
52342
  commandExists,
52131
- existsSync: import_node_fs19.existsSync
52343
+ existsSync: import_node_fs20.existsSync
52132
52344
  }) {
52133
52345
  if (deps.commandExists(command2)) return command2;
52134
52346
  for (const candidate of localBinCandidates(command2)) {
@@ -52147,7 +52359,7 @@ function ensureCommand(command2) {
52147
52359
  }
52148
52360
  if (command2 === "uvx") {
52149
52361
  try {
52150
- (0, import_node_child_process36.execSync)("curl -LsSf https://astral.sh/uv/install.sh | sh", {
52362
+ (0, import_node_child_process38.execSync)("curl -LsSf https://astral.sh/uv/install.sh | sh", {
52151
52363
  stdio: ["ignore", process.stderr, process.stderr],
52152
52364
  timeout: 18e4,
52153
52365
  env: { ...process.env, UV_NO_MODIFY_PATH: "1" }
@@ -52156,7 +52368,7 @@ function ensureCommand(command2) {
52156
52368
  }
52157
52369
  if (resolveLauncherPath(command2) !== command2) return;
52158
52370
  try {
52159
- (0, import_node_child_process36.execSync)("python3 -m pip install --user --quiet uv", {
52371
+ (0, import_node_child_process38.execSync)("python3 -m pip install --user --quiet uv", {
52160
52372
  stdio: ["ignore", process.stderr, process.stderr],
52161
52373
  timeout: 18e4
52162
52374
  });
@@ -52234,7 +52446,7 @@ async function mcpRun(args2) {
52234
52446
  }
52235
52447
 
52236
52448
  // src/integrations/mcp-warm.ts
52237
- var import_node_child_process37 = require("child_process");
52449
+ var import_node_child_process39 = require("child_process");
52238
52450
  function specOf(delivery) {
52239
52451
  if (!delivery.command) return null;
52240
52452
  const spec = (delivery.args ?? []).find((a) => !a.startsWith("-"));
@@ -52278,7 +52490,7 @@ var WARM_TOTAL_BUDGET_MS = 10 * 6e4;
52278
52490
  var WARM_CONCURRENCY = 4;
52279
52491
  function runCapturing(command2, args2, timeoutMs) {
52280
52492
  return new Promise((resolve12) => {
52281
- const child = (0, import_node_child_process37.spawn)(command2, args2, {
52493
+ const child = (0, import_node_child_process39.spawn)(command2, args2, {
52282
52494
  env: { ...process.env, ...LAUNCHER_ENV },
52283
52495
  stdio: ["ignore", "ignore", "pipe"],
52284
52496
  // `npx`/`uv` are `.cmd` shims on Windows; Node ≥ 20.12 refuses to spawn a
@@ -52357,7 +52569,7 @@ async function mcpWarm(argv = [], opts = {}) {
52357
52569
  // src/commands/version.ts
52358
52570
  var import_picocolors15 = __toESM(require("picocolors"));
52359
52571
  function version2() {
52360
- const v = true ? "2.76.1" : "unknown";
52572
+ const v = true ? "2.76.2" : "unknown";
52361
52573
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
52362
52574
  }
52363
52575