codeam-cli 2.61.22 → 2.61.23

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 (2) hide show
  1. package/dist/index.js +700 -439
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -806,6 +806,91 @@ function isKnownIntegrationId(id) {
806
806
  return id in INTEGRATION_REGISTRY;
807
807
  }
808
808
 
809
+ // ../../packages/shared/src/skills/registry.ts
810
+ var CODE_REVIEW_BODY = `Use this skill when reviewing a pull request. It defines what a high-signal
811
+ review looks like so your inline comments are worth the author's time.
812
+
813
+ ## Review priorities (in order)
814
+ 1. **Correctness** \u2014 does the change do what the PR says, and only that? Trace the
815
+ changed paths for logic errors, off-by-one, null/undefined, wrong branch, and
816
+ inverted conditions. State a concrete failure scenario (inputs \u2192 wrong output)
817
+ for anything you flag as a bug.
818
+ 2. **Security** \u2014 untrusted input reaching a sink (SQL, shell, path, HTML), secrets
819
+ in code/logs, authz gaps, credentials passed via argv instead of env.
820
+ 3. **Tests** \u2014 does the change carry tests that would fail without it? Missing
821
+ coverage on a bug-prone path is a finding.
822
+ 4. **Clarity / reuse** \u2014 duplicated logic, a simpler existing helper, a name that
823
+ misleads. Only raise these when they materially affect maintainability.
824
+
825
+ ## Comment discipline
826
+ - One finding per comment, anchored to the exact line.
827
+ - Lead with severity: **blocker**, **should-fix**, or **nit**.
828
+ - Say WHY (the failure or risk), not just WHAT. Propose the fix when it is short.
829
+ - Do NOT restate the diff, praise trivially, or nitpick style a formatter owns.
830
+ - If the PR is correct and well-tested, say so plainly and approve \u2014 a clean review
831
+ is a valid outcome, not a failure to find something.
832
+
833
+ ## Scope
834
+ Review only what the diff changes and its direct blast radius. Do not demand
835
+ unrelated refactors.`;
836
+ var CODE_REVIEW_INSTRUCTION = `When reviewing this PR, prioritize correctness first, then security, then test
837
+ coverage, then clarity/reuse. One finding per inline comment, anchored to the exact
838
+ line, each led by a severity tag (blocker/should-fix/nit) and a concrete reason
839
+ (the failure scenario or risk), not a restatement of the diff. If the change is
840
+ correct and well-tested, approve and say so \u2014 finding nothing is a valid outcome.
841
+ Review only the diff and its direct blast radius; do not demand unrelated refactors.`;
842
+ var RESOLVE_CONFLICTS_BODY = `Use this skill when resolving merge conflicts on a pull request. The goal is a
843
+ merge that preserves BOTH sides' intent, not one that just makes the file compile.
844
+
845
+ ## Method
846
+ 1. Understand each conflict hunk before editing: what did HEAD change, what did the
847
+ base branch change, and WHY. Read the surrounding function, not just the markers.
848
+ 2. Prefer a union of intents. Drop a side only when the two changes are genuinely
849
+ mutually exclusive \u2014 and when you do, keep the side that matches the PR's purpose.
850
+ 3. Never leave a conflict marker (\`<<<<<<<\`, \`=======\`, \`>>>>>>>\`) behind. Grep for
851
+ them before committing.
852
+ 4. After resolving, the code must build and its tests must pass. Run them. A merge
853
+ that resolves markers but breaks the build is not done.
854
+ 5. For lockfiles/generated files, regenerate rather than hand-merge.
855
+
856
+ ## Commit
857
+ One commit that explains what was reconciled and any intent you had to choose
858
+ between. Then push the branch.`;
859
+ var RESOLVE_CONFLICTS_INSTRUCTION = `When resolving these merge conflicts, preserve both sides' intent \u2014 read each hunk's
860
+ surrounding code to understand what HEAD and the base branch each changed and why,
861
+ and prefer a union of intents; drop a side only when the two are mutually exclusive,
862
+ keeping the side that matches the PR's purpose. Leave no conflict markers behind
863
+ (grep for them). Regenerate lockfiles rather than hand-merging them. The result must
864
+ build and pass tests \u2014 run them \u2014 before you commit and push.`;
865
+ var SKILL_REGISTRY = {
866
+ "code-review": {
867
+ id: "code-review",
868
+ name: "Code Review",
869
+ description: `High-signal PR review: prioritize correctness \u2192 security \u2192 tests \u2192 clarity, one anchored finding per comment.`,
870
+ source: "curated",
871
+ delivery: {
872
+ skillFile: { body: CODE_REVIEW_BODY },
873
+ instruction: { body: CODE_REVIEW_INSTRUCTION }
874
+ }
875
+ },
876
+ "resolve-conflicts": {
877
+ id: "resolve-conflicts",
878
+ name: "Resolve Conflicts",
879
+ description: `Merge-conflict resolution that preserves both sides' intent, leaves no markers, and keeps the build green.`,
880
+ source: "curated",
881
+ delivery: {
882
+ skillFile: { body: RESOLVE_CONFLICTS_BODY },
883
+ instruction: { body: RESOLVE_CONFLICTS_INSTRUCTION }
884
+ }
885
+ }
886
+ };
887
+ function isSkillId(id) {
888
+ return Object.prototype.hasOwnProperty.call(SKILL_REGISTRY, id);
889
+ }
890
+ function getSkillDefinition(id) {
891
+ return isSkillId(id) ? SKILL_REGISTRY[id] : null;
892
+ }
893
+
809
894
  // ../../packages/shared/src/api-url.ts
810
895
  var DEFAULT_API_BASE_URL = "https://api.codeagent-mobile.com";
811
896
  var DEV_API_BASE_URL = "https://dev-api.codeagent-mobile.com";
@@ -1130,11 +1215,11 @@ function quiet(fn) {
1130
1215
  log.debug(TAG, "ignored sync error", err);
1131
1216
  }
1132
1217
  }
1133
- function rmIfExistsQuiet(path76) {
1218
+ function rmIfExistsQuiet(path78) {
1134
1219
  try {
1135
- fs2.rmSync(path76, { force: true });
1220
+ fs2.rmSync(path78, { force: true });
1136
1221
  } catch (err) {
1137
- log.debug(TAG, `rmIfExists failed for ${path76}`, err);
1222
+ log.debug(TAG, `rmIfExists failed for ${path78}`, err);
1138
1223
  }
1139
1224
  }
1140
1225
  function killQuiet(target, signal = "SIGTERM") {
@@ -1280,9 +1365,9 @@ var _default = makeConfig();
1280
1365
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
1281
1366
 
1282
1367
  // src/commands/pair-auto.ts
1283
- var fs56 = __toESM(require("fs"));
1284
- var os45 = __toESM(require("os"));
1285
- var path60 = __toESM(require("path"));
1368
+ var fs58 = __toESM(require("fs"));
1369
+ var os48 = __toESM(require("os"));
1370
+ var path62 = __toESM(require("path"));
1286
1371
  var import_crypto4 = require("crypto");
1287
1372
 
1288
1373
  // src/services/telemetry.service.ts
@@ -1318,8 +1403,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
1318
1403
  return decodedFile;
1319
1404
  };
1320
1405
  }
1321
- function normalizeWindowsPath(path76) {
1322
- return path76.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1406
+ function normalizeWindowsPath(path78) {
1407
+ return path78.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1323
1408
  }
1324
1409
 
1325
1410
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3799,9 +3884,9 @@ async function addSourceContext(frames) {
3799
3884
  LRU_FILE_CONTENTS_CACHE.reduce();
3800
3885
  return frames;
3801
3886
  }
3802
- function getContextLinesFromFile(path76, ranges, output) {
3887
+ function getContextLinesFromFile(path78, ranges, output) {
3803
3888
  return new Promise((resolve8) => {
3804
- const stream = (0, import_node_fs.createReadStream)(path76);
3889
+ const stream = (0, import_node_fs.createReadStream)(path78);
3805
3890
  const lineReaded = (0, import_node_readline.createInterface)({
3806
3891
  input: stream
3807
3892
  });
@@ -3816,7 +3901,7 @@ function getContextLinesFromFile(path76, ranges, output) {
3816
3901
  let rangeStart = range[0];
3817
3902
  let rangeEnd = range[1];
3818
3903
  function onStreamError() {
3819
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path76, 1);
3904
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path78, 1);
3820
3905
  lineReaded.close();
3821
3906
  lineReaded.removeAllListeners();
3822
3907
  destroyStreamAndResolve();
@@ -3877,8 +3962,8 @@ function clearLineContext(frame) {
3877
3962
  delete frame.context_line;
3878
3963
  delete frame.post_context;
3879
3964
  }
3880
- function shouldSkipContextLinesForFile(path76) {
3881
- return path76.startsWith("node:") || path76.endsWith(".min.js") || path76.endsWith(".min.cjs") || path76.endsWith(".min.mjs") || path76.startsWith("data:");
3965
+ function shouldSkipContextLinesForFile(path78) {
3966
+ return path78.startsWith("node:") || path78.endsWith(".min.js") || path78.endsWith(".min.cjs") || path78.endsWith(".min.mjs") || path78.startsWith("data:");
3882
3967
  }
3883
3968
  function shouldSkipContextLinesForFrame(frame) {
3884
3969
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -6032,7 +6117,7 @@ function readAnonId() {
6032
6117
  }
6033
6118
  function superProperties() {
6034
6119
  return {
6035
- cliVersion: true ? "2.61.22" : "0.0.0-dev",
6120
+ cliVersion: true ? "2.61.23" : "0.0.0-dev",
6036
6121
  nodeVersion: process.version,
6037
6122
  platform: process.platform,
6038
6123
  arch: process.arch,
@@ -6213,7 +6298,7 @@ var os4 = __toESM(require("os"));
6213
6298
  // package.json
6214
6299
  var package_default = {
6215
6300
  name: "codeam-cli",
6216
- version: "2.61.22",
6301
+ version: "2.61.23",
6217
6302
  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.",
6218
6303
  type: "commonjs",
6219
6304
  main: "dist/index.js",
@@ -7377,7 +7462,7 @@ var CommandRelayService = class _CommandRelayService {
7377
7462
  // fresh + clear the "CLI update available" banner after a self-update
7378
7463
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
7379
7464
  // pair/reconnect). Older backends ignore the extra field.
7380
- ..."2.61.22" ? { ideVersion: "2.61.22" } : {}
7465
+ ..."2.61.23" ? { ideVersion: "2.61.23" } : {}
7381
7466
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
7382
7467
  }
7383
7468
  /**
@@ -8751,9 +8836,9 @@ function closeAllTerminals() {
8751
8836
  }
8752
8837
 
8753
8838
  // src/commands/start/handlers.ts
8754
- var fs55 = __toESM(require("fs"));
8755
- var os44 = __toESM(require("os"));
8756
- var path59 = __toESM(require("path"));
8839
+ var fs57 = __toESM(require("fs"));
8840
+ var os47 = __toESM(require("os"));
8841
+ var path61 = __toESM(require("path"));
8757
8842
  var import_crypto3 = require("crypto");
8758
8843
  var import_child_process24 = require("child_process");
8759
8844
 
@@ -8831,7 +8916,12 @@ var startCommandSchema = import_zod.z.object({
8831
8916
  // Restore the caller's already-vaulted CodeRabbit credential onto this
8832
8917
  // session (no re-login) — fetches from the backend + installs + writes it.
8833
8918
  "provision",
8834
- "review"
8919
+ "review",
8920
+ // `skills_configure` — attach/detach a curated Agent Skill on a RUNNING
8921
+ // session (Claude hot-reloads ~/.claude/skills/), or list what's installed.
8922
+ "add",
8923
+ "remove",
8924
+ "list"
8835
8925
  ]).optional(),
8836
8926
  // `headroom_configure` — savings ingest URL delivered from the session
8837
8927
  // when enabling Headroom on-demand. Bounded to 2048 chars.
@@ -8938,7 +9028,11 @@ var startCommandSchema = import_zod.z.object({
8938
9028
  key: import_zod.z.string().min(1).max(256),
8939
9029
  value: import_zod.z.string().max(32768)
8940
9030
  })
8941
- ).max(512).optional()
9031
+ ).max(512).optional(),
9032
+ // `skills_configure` — the curated `SkillId` to add/remove. `list` (and a
9033
+ // malformed/unknown id on add/remove) sends no `skillId` or an invalid one;
9034
+ // `configureSkill` itself validates against the shared registry.
9035
+ skillId: import_zod.z.string().min(1).max(128).optional()
8942
9036
  });
8943
9037
  function parsePayload2(schema, raw) {
8944
9038
  const result = schema.safeParse(raw);
@@ -12224,10 +12318,10 @@ function buildForPlatform(platform3) {
12224
12318
  var import_node_crypto4 = require("crypto");
12225
12319
 
12226
12320
  // src/agents/claude/resolver.ts
12227
- function buildClaudeLaunch(extraArgs = [], os53 = createOsStrategy()) {
12228
- const found = os53.findInPath("claude") ?? os53.findInPath("claude-code");
12321
+ function buildClaudeLaunch(extraArgs = [], os57 = createOsStrategy()) {
12322
+ const found = os57.findInPath("claude") ?? os57.findInPath("claude-code");
12229
12323
  if (!found) return null;
12230
- return os53.buildLaunch(found, extraArgs);
12324
+ return os57.buildLaunch(found, extraArgs);
12231
12325
  }
12232
12326
 
12233
12327
  // src/agents/claude/installer.ts
@@ -12817,8 +12911,8 @@ var ClaudeRuntimeStrategy = class {
12817
12911
  meta = getAgent("claude");
12818
12912
  mode = "interactive";
12819
12913
  os;
12820
- constructor(os53) {
12821
- this.os = os53;
12914
+ constructor(os57) {
12915
+ this.os = os57;
12822
12916
  }
12823
12917
  /**
12824
12918
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -13598,8 +13692,8 @@ function codexCredentialLocator() {
13598
13692
  function codexLoginLauncher() {
13599
13693
  return {
13600
13694
  async ensureInstalled() {
13601
- const os53 = createOsStrategy();
13602
- return os53.findInPath("codex") !== null;
13695
+ const os57 = createOsStrategy();
13696
+ return os57.findInPath("codex") !== null;
13603
13697
  },
13604
13698
  launch() {
13605
13699
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -13622,8 +13716,8 @@ var CodexRuntimeStrategy = class {
13622
13716
  meta = getAgent("codex");
13623
13717
  mode = "interactive";
13624
13718
  os;
13625
- constructor(os53) {
13626
- this.os = os53;
13719
+ constructor(os57) {
13720
+ this.os = os57;
13627
13721
  }
13628
13722
  async prepareLaunch() {
13629
13723
  let binary = this.os.findInPath("codex");
@@ -13732,12 +13826,12 @@ var CodexRuntimeStrategy = class {
13732
13826
  });
13733
13827
  }
13734
13828
  };
13735
- function resolveNpm(os53) {
13736
- return os53.id === "win32" ? "npm.cmd" : "npm";
13829
+ function resolveNpm(os57) {
13830
+ return os57.id === "win32" ? "npm.cmd" : "npm";
13737
13831
  }
13738
- async function installCodexViaNpm(os53) {
13832
+ async function installCodexViaNpm(os57) {
13739
13833
  return new Promise((resolve8, reject) => {
13740
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os53), ["install", "-g", "@openai/codex"], {
13834
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os57), ["install", "-g", "@openai/codex"], {
13741
13835
  stdio: "inherit"
13742
13836
  });
13743
13837
  proc.on("close", (code) => {
@@ -13754,16 +13848,16 @@ async function installCodexViaNpm(os53) {
13754
13848
  });
13755
13849
  });
13756
13850
  }
13757
- function augmentNpmGlobalBin(os53) {
13851
+ function augmentNpmGlobalBin(os57) {
13758
13852
  try {
13759
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os53), ["prefix", "-g"], {
13853
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os57), ["prefix", "-g"], {
13760
13854
  stdio: ["ignore", "pipe", "ignore"]
13761
13855
  });
13762
13856
  if (result.status !== 0) return;
13763
13857
  const prefix = result.stdout.toString().trim();
13764
13858
  if (!prefix) return;
13765
- const binDir = os53.id === "win32" ? prefix : path24.join(prefix, "bin");
13766
- os53.augmentPath([binDir]);
13859
+ const binDir = os57.id === "win32" ? prefix : path24.join(prefix, "bin");
13860
+ os57.augmentPath([binDir]);
13767
13861
  } catch {
13768
13862
  }
13769
13863
  }
@@ -13847,9 +13941,9 @@ var import_node_child_process8 = require("child_process");
13847
13941
  // src/agents/coderabbit/installer.ts
13848
13942
  var import_node_child_process6 = require("child_process");
13849
13943
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
13850
- async function ensureCoderabbitInstalled(os53) {
13851
- if (os53.findInPath("coderabbit")) return true;
13852
- if (os53.id === "win32") {
13944
+ async function ensureCoderabbitInstalled(os57) {
13945
+ if (os57.findInPath("coderabbit")) return true;
13946
+ if (os57.id === "win32") {
13853
13947
  console.error(
13854
13948
  "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
13855
13949
  );
@@ -13882,8 +13976,8 @@ async function ensureCoderabbitInstalled(os53) {
13882
13976
  proc.on("error", () => finish(false));
13883
13977
  });
13884
13978
  if (!ok) return false;
13885
- os53.augmentPath([`${os53.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13886
- return os53.findInPath("coderabbit") !== null;
13979
+ os57.augmentPath([`${os57.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13980
+ return os57.findInPath("coderabbit") !== null;
13887
13981
  }
13888
13982
 
13889
13983
  // src/agents/coderabbit/link.ts
@@ -13918,10 +14012,10 @@ function coderabbitCredentialLocator() {
13918
14012
  validate: validateNonEmptyCredential
13919
14013
  };
13920
14014
  }
13921
- function coderabbitLoginLauncher(os53) {
14015
+ function coderabbitLoginLauncher(os57) {
13922
14016
  return {
13923
14017
  async ensureInstalled() {
13924
- return ensureCoderabbitInstalled(os53);
14018
+ return ensureCoderabbitInstalled(os57);
13925
14019
  },
13926
14020
  launch() {
13927
14021
  return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
@@ -13977,8 +14071,8 @@ function pickLine(obj) {
13977
14071
  function toHunk(raw, groupSeverity) {
13978
14072
  if (!raw || typeof raw !== "object") return null;
13979
14073
  const o = raw;
13980
- const path76 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
13981
- if (!path76) return null;
14074
+ const path78 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
14075
+ if (!path78) return null;
13982
14076
  const message = asString(
13983
14077
  pick(o, [
13984
14078
  "comment",
@@ -13995,7 +14089,7 @@ function toHunk(raw, groupSeverity) {
13995
14089
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
13996
14090
  const locObj = pick(o, ["location"]) ?? o;
13997
14091
  return {
13998
- path: path76.trim(),
14092
+ path: path78.trim(),
13999
14093
  line: pickLine(o) ?? pickLine(locObj),
14000
14094
  severity,
14001
14095
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -14078,10 +14172,10 @@ function parsePlain(stdout) {
14078
14172
  for (const line of stdout.split(/\r?\n/)) {
14079
14173
  const m = line.match(HUNK_LINE_RE);
14080
14174
  if (!m) continue;
14081
- const [, path76, lineNo, sevToken, message] = m;
14082
- if (!path76 || !lineNo || !message) continue;
14175
+ const [, path78, lineNo, sevToken, message] = m;
14176
+ if (!path78 || !lineNo || !message) continue;
14083
14177
  hunks.push({
14084
- path: path76.trim(),
14178
+ path: path78.trim(),
14085
14179
  line: Number(lineNo),
14086
14180
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
14087
14181
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -14141,8 +14235,8 @@ var CoderabbitRuntimeStrategy = class {
14141
14235
  meta = getAgent("coderabbit");
14142
14236
  mode = "batch";
14143
14237
  os;
14144
- constructor(os53) {
14145
- this.os = os53;
14238
+ constructor(os57) {
14239
+ this.os = os57;
14146
14240
  }
14147
14241
  getDefaultArgs() {
14148
14242
  return ["review", "--agent"];
@@ -14413,10 +14507,10 @@ function cursorCredentialLocator() {
14413
14507
  validate: validateNonEmptyCredential
14414
14508
  };
14415
14509
  }
14416
- function cursorLoginLauncher(os53) {
14510
+ function cursorLoginLauncher(os57) {
14417
14511
  return {
14418
14512
  async ensureInstalled() {
14419
- if (os53.findInPath("cursor-agent")) return true;
14513
+ if (os57.findInPath("cursor-agent")) return true;
14420
14514
  console.error(
14421
14515
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
14422
14516
  );
@@ -14480,8 +14574,8 @@ var CursorRuntimeStrategy = class {
14480
14574
  meta = getAgent("cursor");
14481
14575
  mode = "interactive";
14482
14576
  os;
14483
- constructor(os53) {
14484
- this.os = os53;
14577
+ constructor(os57) {
14578
+ this.os = os57;
14485
14579
  }
14486
14580
  async prepareLaunch() {
14487
14581
  const binary = this.os.findInPath("cursor-agent");
@@ -14697,10 +14791,10 @@ function aiderCredentialLocator() {
14697
14791
  validate: validateNonEmptyCredential
14698
14792
  };
14699
14793
  }
14700
- function aiderLoginLauncher(os53) {
14794
+ function aiderLoginLauncher(os57) {
14701
14795
  return {
14702
14796
  async ensureInstalled() {
14703
- if (os53.findInPath("aider")) return true;
14797
+ if (os57.findInPath("aider")) return true;
14704
14798
  console.error(
14705
14799
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
14706
14800
  );
@@ -14710,7 +14804,7 @@ function aiderLoginLauncher(os53) {
14710
14804
  console.error(
14711
14805
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
14712
14806
  );
14713
- return (0, import_node_child_process11.spawn)(os53.id === "win32" ? "cmd.exe" : "sh", os53.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
14807
+ return (0, import_node_child_process11.spawn)(os57.id === "win32" ? "cmd.exe" : "sh", os57.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
14714
14808
  stdio: "ignore"
14715
14809
  });
14716
14810
  }
@@ -14782,8 +14876,8 @@ var AiderRuntimeStrategy = class {
14782
14876
  meta = getAgent("aider");
14783
14877
  mode = "interactive";
14784
14878
  os;
14785
- constructor(os53) {
14786
- this.os = os53;
14879
+ constructor(os57) {
14880
+ this.os = os57;
14787
14881
  }
14788
14882
  async prepareLaunch() {
14789
14883
  const binary = this.os.findInPath("aider");
@@ -14915,8 +15009,8 @@ function geminiCredentialLocator() {
14915
15009
  function geminiLoginLauncher() {
14916
15010
  return {
14917
15011
  async ensureInstalled() {
14918
- const os53 = createOsStrategy();
14919
- return os53.findInPath("gemini") !== null;
15012
+ const os57 = createOsStrategy();
15013
+ return os57.findInPath("gemini") !== null;
14920
15014
  },
14921
15015
  launch() {
14922
15016
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -15106,8 +15200,8 @@ var GeminiRuntimeStrategy = class {
15106
15200
  meta = getAgent("gemini");
15107
15201
  mode = "interactive";
15108
15202
  os;
15109
- constructor(os53) {
15110
- this.os = os53;
15203
+ constructor(os57) {
15204
+ this.os = os57;
15111
15205
  }
15112
15206
  async prepareLaunch() {
15113
15207
  const binary = this.os.findInPath("gemini");
@@ -15398,8 +15492,8 @@ var KimiRuntimeStrategy = class {
15398
15492
  meta = getAgent("kimi");
15399
15493
  mode = "interactive";
15400
15494
  os;
15401
- constructor(os53) {
15402
- this.os = os53;
15495
+ constructor(os57) {
15496
+ this.os = os57;
15403
15497
  }
15404
15498
  async prepareLaunch() {
15405
15499
  const binary = this.os.findInPath("kimi");
@@ -15512,19 +15606,19 @@ var KimiRuntimeStrategy = class {
15512
15606
 
15513
15607
  // src/agents/registry.ts
15514
15608
  var runtimeBuilders = {
15515
- claude: (os53) => new ClaudeRuntimeStrategy(os53),
15516
- codex: (os53) => new CodexRuntimeStrategy(os53),
15517
- coderabbit: (os53) => new CoderabbitRuntimeStrategy(os53),
15518
- cursor: (os53) => new CursorRuntimeStrategy(os53),
15519
- aider: (os53) => new AiderRuntimeStrategy(os53),
15520
- gemini: (os53) => new GeminiRuntimeStrategy(os53),
15521
- kimi: (os53) => new KimiRuntimeStrategy(os53)
15609
+ claude: (os57) => new ClaudeRuntimeStrategy(os57),
15610
+ codex: (os57) => new CodexRuntimeStrategy(os57),
15611
+ coderabbit: (os57) => new CoderabbitRuntimeStrategy(os57),
15612
+ cursor: (os57) => new CursorRuntimeStrategy(os57),
15613
+ aider: (os57) => new AiderRuntimeStrategy(os57),
15614
+ gemini: (os57) => new GeminiRuntimeStrategy(os57),
15615
+ kimi: (os57) => new KimiRuntimeStrategy(os57)
15522
15616
  };
15523
15617
  var deployBuilders = {
15524
15618
  claude: () => new ClaudeDeployStrategy(),
15525
15619
  codex: () => new CodexDeployStrategy()
15526
15620
  };
15527
- function createAgentStrategy(agent, os53 = createOsStrategy()) {
15621
+ function createAgentStrategy(agent, os57 = createOsStrategy()) {
15528
15622
  if (!AGENT_REGISTRY[agent]?.enabled) {
15529
15623
  throw new Error(
15530
15624
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -15534,10 +15628,10 @@ function createAgentStrategy(agent, os53 = createOsStrategy()) {
15534
15628
  if (!build) {
15535
15629
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
15536
15630
  }
15537
- return build(os53);
15631
+ return build(os57);
15538
15632
  }
15539
- function createInteractiveAgentStrategy(agent, os53 = createOsStrategy()) {
15540
- const s = createAgentStrategy(agent, os53);
15633
+ function createInteractiveAgentStrategy(agent, os57 = createOsStrategy()) {
15634
+ const s = createAgentStrategy(agent, os57);
15541
15635
  if (s.mode !== "interactive") {
15542
15636
  throw new Error(
15543
15637
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -16234,26 +16328,26 @@ function restoreCoderabbitOauthBlob(value) {
16234
16328
  (0, import_node_fs5.writeFileSync)(path36.join(dir, file), contents, { mode: 384 });
16235
16329
  }
16236
16330
  async function configureCoderabbit(input, deps = {}) {
16237
- const os53 = deps.os ?? createOsStrategy();
16331
+ const os57 = deps.os ?? createOsStrategy();
16238
16332
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
16239
16333
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
16240
16334
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
16241
16335
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
16242
16336
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
16243
16337
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
16244
- const home = os53.homeDir();
16245
- os53.augmentPath(
16246
- os53.id === "win32" ? [
16338
+ const home = os57.homeDir();
16339
+ os57.augmentPath(
16340
+ os57.id === "win32" ? [
16247
16341
  path36.join(home, ".local", "bin"),
16248
16342
  path36.join(process.env.APPDATA ?? path36.join(home, "AppData", "Roaming"), "npm"),
16249
16343
  path36.join(home, "scoop", "shims")
16250
16344
  ] : [path36.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
16251
16345
  );
16252
- const installed2 = os53.findInPath("coderabbit") !== null;
16346
+ const installed2 = os57.findInPath("coderabbit") !== null;
16253
16347
  const base = () => ({
16254
16348
  action: input.action,
16255
16349
  supported: true,
16256
- installed: os53.findInPath("coderabbit") !== null,
16350
+ installed: os57.findInPath("coderabbit") !== null,
16257
16351
  loggedIn: false
16258
16352
  });
16259
16353
  if (input.action === "status") {
@@ -16267,7 +16361,7 @@ async function configureCoderabbit(input, deps = {}) {
16267
16361
  const key = (input.apiKey ?? "").trim();
16268
16362
  if (!key) return { ...res2, error: "No API key provided" };
16269
16363
  if (!res2.installed) {
16270
- const ok = await ensureInstalled(os53);
16364
+ const ok = await ensureInstalled(os57);
16271
16365
  res2.installed = ok;
16272
16366
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
16273
16367
  }
@@ -16291,7 +16385,7 @@ async function configureCoderabbit(input, deps = {}) {
16291
16385
  }
16292
16386
  if (!res2.installed) {
16293
16387
  deps.onEvent?.({ kind: "installing" });
16294
- const ok = await ensureInstalled(os53);
16388
+ const ok = await ensureInstalled(os57);
16295
16389
  res2.installed = ok;
16296
16390
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
16297
16391
  }
@@ -16321,7 +16415,7 @@ async function configureCoderabbit(input, deps = {}) {
16321
16415
  const res2 = base();
16322
16416
  if (!installed2) {
16323
16417
  deps.onEvent?.({ kind: "installing" });
16324
- const ok = await ensureInstalled(os53);
16418
+ const ok = await ensureInstalled(os57);
16325
16419
  res2.installed = ok;
16326
16420
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
16327
16421
  }
@@ -16361,7 +16455,7 @@ async function configureCoderabbit(input, deps = {}) {
16361
16455
  }
16362
16456
  const res = base();
16363
16457
  if (!res.installed) {
16364
- const ok = await ensureInstalled(os53);
16458
+ const ok = await ensureInstalled(os57);
16365
16459
  res.installed = ok;
16366
16460
  if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
16367
16461
  }
@@ -16545,9 +16639,9 @@ function defaultRunGh(args2) {
16545
16639
 
16546
16640
  // src/commands/host-agent.ts
16547
16641
  var import_node_child_process24 = require("child_process");
16548
- var os36 = __toESM(require("os"));
16549
- var fs42 = __toESM(require("fs"));
16550
- var path45 = __toESM(require("path"));
16642
+ var os37 = __toESM(require("os"));
16643
+ var fs43 = __toESM(require("fs"));
16644
+ var path46 = __toESM(require("path"));
16551
16645
 
16552
16646
  // src/integrations/manifest.ts
16553
16647
  var import_node_fs7 = __toESM(require("fs"));
@@ -16622,14 +16716,61 @@ function clearIntegrationsManifest() {
16622
16716
  }
16623
16717
  }
16624
16718
 
16719
+ // src/skills/manifest.ts
16720
+ var import_node_fs8 = __toESM(require("fs"));
16721
+ var import_node_os7 = __toESM(require("os"));
16722
+ var import_node_path6 = __toESM(require("path"));
16723
+ function skillsManifestPath() {
16724
+ return import_node_path6.default.join(import_node_os7.default.homedir(), ".codeam", "skills.json");
16725
+ }
16726
+ function readSkillsManifest() {
16727
+ try {
16728
+ const raw = JSON.parse(import_node_fs8.default.readFileSync(skillsManifestPath(), "utf8"));
16729
+ if (!Array.isArray(raw?.skills)) return null;
16730
+ raw.skills = raw.skills.filter(
16731
+ (s) => Boolean(s) && typeof s === "object" && typeof s.id === "string"
16732
+ );
16733
+ return raw;
16734
+ } catch {
16735
+ return null;
16736
+ }
16737
+ }
16738
+ function persistSkillsManifest(m) {
16739
+ try {
16740
+ const file = skillsManifestPath();
16741
+ import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true, mode: 448 });
16742
+ const tmp = `${file}.tmp-${process.pid}`;
16743
+ import_node_fs8.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
16744
+ import_node_fs8.default.renameSync(tmp, file);
16745
+ restrictToOwner(file);
16746
+ } catch (err) {
16747
+ log.warn(
16748
+ "skills",
16749
+ `failed to persist skills manifest (best-effort): ${err instanceof Error ? err.message : String(err)}`
16750
+ );
16751
+ }
16752
+ }
16753
+ function clearSkillsManifest() {
16754
+ try {
16755
+ import_node_fs8.default.rmSync(skillsManifestPath(), { force: true });
16756
+ } catch {
16757
+ }
16758
+ }
16759
+
16760
+ // src/skills/persist-from-payload.ts
16761
+ function persistOrClearSkillsFromPayload(skills) {
16762
+ if (skills && skills.length > 0) persistSkillsManifest({ skills });
16763
+ else clearSkillsManifest();
16764
+ }
16765
+
16625
16766
  // src/commands/host/host-client.ts
16626
- var fs34 = __toESM(require("fs"));
16627
- var os30 = __toESM(require("os"));
16628
- var path38 = __toESM(require("path"));
16767
+ var fs35 = __toESM(require("fs"));
16768
+ var os31 = __toESM(require("os"));
16769
+ var path39 = __toESM(require("path"));
16629
16770
  function sampleCpuTimes() {
16630
16771
  let idle = 0;
16631
16772
  let total = 0;
16632
- for (const cpu of os30.cpus()) {
16773
+ for (const cpu of os31.cpus()) {
16633
16774
  const t2 = cpu.times;
16634
16775
  idle += t2.idle;
16635
16776
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -16648,8 +16789,8 @@ var MetricsCollector = class {
16648
16789
  const prev = this.prevCpu;
16649
16790
  this.prevCpu = current;
16650
16791
  if (!prev) {
16651
- const cores = os30.cpus().length || 1;
16652
- const proxy = os30.loadavg()[0] / cores * 100;
16792
+ const cores = os31.cpus().length || 1;
16793
+ const proxy = os31.loadavg()[0] / cores * 100;
16653
16794
  return Math.min(100, Math.max(0, Math.round(proxy)));
16654
16795
  }
16655
16796
  const idleDelta = current.idle - prev.idle;
@@ -16662,8 +16803,8 @@ var MetricsCollector = class {
16662
16803
  collect() {
16663
16804
  return {
16664
16805
  cpuPct: this.cpuPct(),
16665
- ramUsedMb: Math.round((os30.totalmem() - os30.freemem()) / 1048576),
16666
- ramTotalMb: Math.round(os30.totalmem() / 1048576),
16806
+ ramUsedMb: Math.round((os31.totalmem() - os31.freemem()) / 1048576),
16807
+ ramTotalMb: Math.round(os31.totalmem() / 1048576),
16667
16808
  latencyMs: this.lastLatencyMs
16668
16809
  };
16669
16810
  }
@@ -16672,19 +16813,19 @@ function apiBase() {
16672
16813
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
16673
16814
  }
16674
16815
  function hostIdentityPath() {
16675
- return path38.join(os30.homedir(), ".codeam", "host-agent.json");
16816
+ return path39.join(os31.homedir(), ".codeam", "host-agent.json");
16676
16817
  }
16677
16818
  function collectOsInfo() {
16678
16819
  return {
16679
- distro: os30.platform(),
16680
- arch: os30.arch(),
16681
- kernel: os30.release(),
16820
+ distro: os31.platform(),
16821
+ arch: os31.arch(),
16822
+ kernel: os31.release(),
16682
16823
  nodeVersion: process.versions.node
16683
16824
  };
16684
16825
  }
16685
16826
  function loadHostIdentity() {
16686
16827
  try {
16687
- const raw = fs34.readFileSync(hostIdentityPath(), "utf8");
16828
+ const raw = fs35.readFileSync(hostIdentityPath(), "utf8");
16688
16829
  const parsed = JSON.parse(raw);
16689
16830
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
16690
16831
  const p2 = parsed;
@@ -16697,8 +16838,8 @@ function loadHostIdentity() {
16697
16838
  }
16698
16839
  function saveHostIdentity(identity) {
16699
16840
  const file = hostIdentityPath();
16700
- fs34.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
16701
- fs34.writeFileSync(file, JSON.stringify(identity, null, 2), {
16841
+ fs35.mkdirSync(path39.dirname(file), { recursive: true, mode: 448 });
16842
+ fs35.writeFileSync(file, JSON.stringify(identity, null, 2), {
16702
16843
  encoding: "utf8",
16703
16844
  mode: 384
16704
16845
  });
@@ -16743,7 +16884,7 @@ function isTerminalEnrollError(err) {
16743
16884
  }
16744
16885
  function deleteHostIdentity() {
16745
16886
  try {
16746
- fs34.rmSync(hostIdentityPath(), { force: true });
16887
+ fs35.rmSync(hostIdentityPath(), { force: true });
16747
16888
  } catch {
16748
16889
  }
16749
16890
  }
@@ -16767,7 +16908,7 @@ async function postJson(pathname, body) {
16767
16908
  function resolveHostLabel(label) {
16768
16909
  const explicit = label?.trim();
16769
16910
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
16770
- const resolved = explicit || envLabel || os30.hostname();
16911
+ const resolved = explicit || envLabel || os31.hostname();
16771
16912
  return resolved.slice(0, 80);
16772
16913
  }
16773
16914
  async function redeemEnrollToken(token, label) {
@@ -16872,17 +17013,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
16872
17013
  }
16873
17014
 
16874
17015
  // src/commands/host/workspace.ts
16875
- var fs35 = __toESM(require("fs"));
16876
- var os31 = __toESM(require("os"));
16877
- var path39 = __toESM(require("path"));
17016
+ var fs36 = __toESM(require("fs"));
17017
+ var os32 = __toESM(require("os"));
17018
+ var path40 = __toESM(require("path"));
16878
17019
  var import_node_child_process18 = require("child_process");
16879
17020
  var import_node_util4 = require("util");
16880
17021
  var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process18.execFile);
16881
17022
  function isAbsolutePathTarget(target) {
16882
- return path39.isAbsolute(target);
17023
+ return path40.isAbsolute(target);
16883
17024
  }
16884
17025
  function selfHostedWorkspaceRoot() {
16885
- return path39.join(os31.homedir(), ".codeam", "self-hosted");
17026
+ return path40.join(os32.homedir(), ".codeam", "self-hosted");
16886
17027
  }
16887
17028
  function nonInteractiveGitEnv() {
16888
17029
  return {
@@ -16935,13 +17076,13 @@ async function fetchGithubIdentity(token) {
16935
17076
  async function configureGitCredentials(dest, repoRef, cloneToken) {
16936
17077
  const gh = githubOwnerRepo(repoRef.trim());
16937
17078
  if (!gh || !cloneToken) return;
16938
- const credFile = path39.join(dest, ".git", "codeam-credentials");
16939
- fs35.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
17079
+ const credFile = path40.join(dest, ".git", "codeam-credentials");
17080
+ fs36.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
16940
17081
  `, { mode: 384 });
16941
17082
  restrictToOwner(credFile);
16942
17083
  const env = nonInteractiveGitEnv();
16943
17084
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
16944
- const credFilePosix = credFile.split(path39.sep).join("/");
17085
+ const credFilePosix = credFile.split(path40.sep).join("/");
16945
17086
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
16946
17087
  });
16947
17088
  await git2([
@@ -16977,17 +17118,17 @@ function maskToken(text, cloneToken) {
16977
17118
  }
16978
17119
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
16979
17120
  if (isAbsolutePathTarget(repoOrPath)) {
16980
- if (!fs35.existsSync(repoOrPath)) {
17121
+ if (!fs36.existsSync(repoOrPath)) {
16981
17122
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
16982
17123
  }
16983
17124
  return repoOrPath;
16984
17125
  }
16985
- const dest = path39.join(selfHostedWorkspaceRoot(), deployId);
16986
- if (fs35.existsSync(path39.join(dest, ".git"))) {
17126
+ const dest = path40.join(selfHostedWorkspaceRoot(), deployId);
17127
+ if (fs36.existsSync(path40.join(dest, ".git"))) {
16987
17128
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
16988
17129
  return dest;
16989
17130
  }
16990
- fs35.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
17131
+ fs36.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
16991
17132
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
16992
17133
  try {
16993
17134
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -17004,9 +17145,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
17004
17145
  }
17005
17146
 
17006
17147
  // src/commands/host/agent-provisioning.ts
17007
- var fs36 = __toESM(require("fs"));
17008
- var os32 = __toESM(require("os"));
17009
- var path40 = __toESM(require("path"));
17148
+ var fs37 = __toESM(require("fs"));
17149
+ var os33 = __toESM(require("os"));
17150
+ var path41 = __toESM(require("path"));
17010
17151
  var PUBLIC_TO_INTERNAL_AGENT = {
17011
17152
  claude_code: "claude",
17012
17153
  claude: "claude",
@@ -17022,22 +17163,22 @@ function toInternalAgentId(publicAgentId) {
17022
17163
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
17023
17164
  }
17024
17165
  function ensureDir(dir) {
17025
- fs36.mkdirSync(dir, { recursive: true, mode: 448 });
17166
+ fs37.mkdirSync(dir, { recursive: true, mode: 448 });
17026
17167
  }
17027
17168
  function writeFile0600(filePath, contents) {
17028
- ensureDir(path40.dirname(filePath));
17029
- fs36.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
17169
+ ensureDir(path41.dirname(filePath));
17170
+ fs37.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
17030
17171
  restrictToOwner(filePath);
17031
17172
  }
17032
17173
  function rmIfExists(filePath) {
17033
17174
  try {
17034
- fs36.rmSync(filePath, { force: true });
17175
+ fs37.rmSync(filePath, { force: true });
17035
17176
  } catch {
17036
17177
  }
17037
17178
  }
17038
17179
  var claudeProvisioner = {
17039
17180
  write(auth, home) {
17040
- const credentialsJson = path40.join(home, ".claude", ".credentials.json");
17181
+ const credentialsJson = path41.join(home, ".claude", ".credentials.json");
17041
17182
  if (auth.kind === "api_key") {
17042
17183
  rmIfExists(credentialsJson);
17043
17184
  return { ANTHROPIC_API_KEY: auth.value };
@@ -17049,8 +17190,8 @@ var claudeProvisioner = {
17049
17190
  } else {
17050
17191
  rmIfExists(credentialsJson);
17051
17192
  }
17052
- const claudeJson = path40.join(home, ".claude.json");
17053
- if (!fs36.existsSync(claudeJson)) {
17193
+ const claudeJson = path41.join(home, ".claude.json");
17194
+ if (!fs37.existsSync(claudeJson)) {
17054
17195
  writeFile0600(
17055
17196
  claudeJson,
17056
17197
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -17061,7 +17202,7 @@ var claudeProvisioner = {
17061
17202
  };
17062
17203
  var codexProvisioner = {
17063
17204
  write(auth, home) {
17064
- const authJson = path40.join(home, ".codex", "auth.json");
17205
+ const authJson = path41.join(home, ".codex", "auth.json");
17065
17206
  if (auth.kind === "api_key") {
17066
17207
  rmIfExists(authJson);
17067
17208
  return { OPENAI_API_KEY: auth.value };
@@ -17072,8 +17213,8 @@ var codexProvisioner = {
17072
17213
  };
17073
17214
  var geminiProvisioner = {
17074
17215
  write(auth, home) {
17075
- const settingsJson = path40.join(home, ".gemini", "settings.json");
17076
- const oauthCreds = path40.join(home, ".gemini", "oauth_creds.json");
17216
+ const settingsJson = path41.join(home, ".gemini", "settings.json");
17217
+ const oauthCreds = path41.join(home, ".gemini", "oauth_creds.json");
17077
17218
  if (auth.kind === "api_key") {
17078
17219
  rmIfExists(oauthCreds);
17079
17220
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -17086,7 +17227,7 @@ var geminiProvisioner = {
17086
17227
  };
17087
17228
  var cursorProvisioner = {
17088
17229
  write(auth, home) {
17089
- const authJson = path40.join(home, ".config", "cursor", "auth.json");
17230
+ const authJson = path41.join(home, ".config", "cursor", "auth.json");
17090
17231
  if (auth.kind === "api_key") {
17091
17232
  rmIfExists(authJson);
17092
17233
  return { CURSOR_API_KEY: auth.value };
@@ -17128,22 +17269,22 @@ max_context_size = 262144
17128
17269
  var kimiProvisioner = {
17129
17270
  write(auth, home) {
17130
17271
  const credentialsFiles = [
17131
- path40.join(home, ".kimi", "credentials", "kimi-code.json"),
17132
- path40.join(home, ".kimi-code", "credentials", "kimi-code.json")
17272
+ path41.join(home, ".kimi", "credentials", "kimi-code.json"),
17273
+ path41.join(home, ".kimi-code", "credentials", "kimi-code.json")
17133
17274
  ];
17134
17275
  if (auth.kind === "api_key") {
17135
17276
  credentialsFiles.forEach(rmIfExists);
17136
17277
  return { KIMI_API_KEY: auth.value };
17137
17278
  }
17138
17279
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
17139
- writeFile0600(path40.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
17280
+ writeFile0600(path41.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
17140
17281
  return {};
17141
17282
  }
17142
17283
  };
17143
17284
  var coderabbitProvisioner = {
17144
17285
  write(auth, home) {
17145
- const dir = path40.join(home, ".coderabbit");
17146
- const authJson = path40.join(dir, "auth.json");
17286
+ const dir = path41.join(home, ".coderabbit");
17287
+ const authJson = path41.join(dir, "auth.json");
17147
17288
  if (auth.kind === "api_key") {
17148
17289
  rmIfExists(authJson);
17149
17290
  return { CODERABBIT_API_KEY: auth.value };
@@ -17155,13 +17296,13 @@ var coderabbitProvisioner = {
17155
17296
  try {
17156
17297
  const parsed = JSON.parse(value);
17157
17298
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
17158
- file = path40.basename(parsed.file);
17299
+ file = path41.basename(parsed.file);
17159
17300
  contents = parsed.contents;
17160
17301
  }
17161
17302
  } catch {
17162
17303
  }
17163
17304
  }
17164
- writeFile0600(path40.join(dir, file), contents);
17305
+ writeFile0600(path41.join(dir, file), contents);
17165
17306
  return {};
17166
17307
  }
17167
17308
  };
@@ -17181,7 +17322,7 @@ var UnsupportedAgentError = class extends Error {
17181
17322
  this.agentId = agentId;
17182
17323
  }
17183
17324
  };
17184
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os32.homedir()) {
17325
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os33.homedir()) {
17185
17326
  const internal = toInternalAgentId(publicAgentId);
17186
17327
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
17187
17328
  const provisioner = PROVISIONERS[internal];
@@ -17191,11 +17332,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os32.homedir(
17191
17332
 
17192
17333
  // src/commands/host/git-tooling.ts
17193
17334
  var import_node_child_process19 = require("child_process");
17194
- var fs37 = __toESM(require("fs"));
17195
- var os33 = __toESM(require("os"));
17196
- var path41 = __toESM(require("path"));
17335
+ var fs38 = __toESM(require("fs"));
17336
+ var os34 = __toESM(require("os"));
17337
+ var path42 = __toESM(require("path"));
17197
17338
  function codeamBinDir() {
17198
- return process.env.CODEAM_BIN_DIR ?? path41.join(os33.homedir(), ".codeam", "bin");
17339
+ return process.env.CODEAM_BIN_DIR ?? path42.join(os34.homedir(), ".codeam", "bin");
17199
17340
  }
17200
17341
  var FALLBACK_GH_VERSION = "2.62.0";
17201
17342
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -17227,7 +17368,7 @@ async function download(url2, dest) {
17227
17368
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
17228
17369
  if (!res.ok || !res.body) return false;
17229
17370
  const buf = Buffer.from(await res.arrayBuffer());
17230
- fs37.writeFileSync(dest, buf);
17371
+ fs38.writeFileSync(dest, buf);
17231
17372
  return true;
17232
17373
  } catch {
17233
17374
  return false;
@@ -17250,8 +17391,8 @@ async function ensureGhCli(runner, token, deps = {}) {
17250
17391
  const version3 = await resolveVersionFn(token);
17251
17392
  const asset = `gh_${version3}_${osToken}_${arch2}`;
17252
17393
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
17253
- const tmpRoot = fs37.mkdtempSync(path41.join(os33.tmpdir(), "codeam-gh-"));
17254
- const archive = path41.join(tmpRoot, `${asset}.${ext}`);
17394
+ const tmpRoot = fs38.mkdtempSync(path42.join(os34.tmpdir(), "codeam-gh-"));
17395
+ const archive = path42.join(tmpRoot, `${asset}.${ext}`);
17255
17396
  if (!await downloadFn(url2, archive)) {
17256
17397
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
17257
17398
  return null;
@@ -17261,16 +17402,16 @@ async function ensureGhCli(runner, token, deps = {}) {
17261
17402
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
17262
17403
  return null;
17263
17404
  }
17264
- const extractedBin = path41.join(tmpRoot, asset, "bin", binaryName);
17265
- if (!fs37.existsSync(extractedBin)) {
17405
+ const extractedBin = path42.join(tmpRoot, asset, "bin", binaryName);
17406
+ if (!fs38.existsSync(extractedBin)) {
17266
17407
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
17267
17408
  return null;
17268
17409
  }
17269
17410
  const binDir = codeamBinDir();
17270
- fs37.mkdirSync(binDir, { recursive: true });
17271
- const target = path41.join(binDir, binaryName);
17272
- fs37.copyFileSync(extractedBin, target);
17273
- fs37.chmodSync(target, 493);
17411
+ fs38.mkdirSync(binDir, { recursive: true });
17412
+ const target = path42.join(binDir, binaryName);
17413
+ fs38.copyFileSync(extractedBin, target);
17414
+ fs38.chmodSync(target, 493);
17274
17415
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
17275
17416
  return target;
17276
17417
  } catch (e) {
@@ -17757,23 +17898,23 @@ async function ensureModernPython(runner) {
17757
17898
  }
17758
17899
 
17759
17900
  // src/commands/host/headroom-bootstrap.ts
17760
- var fs39 = __toESM(require("fs"));
17761
- var path43 = __toESM(require("path"));
17901
+ var fs40 = __toESM(require("fs"));
17902
+ var path44 = __toESM(require("path"));
17762
17903
 
17763
17904
  // src/commands/host/headroom-config.ts
17764
- var fs38 = __toESM(require("fs"));
17765
- var os34 = __toESM(require("os"));
17766
- var path42 = __toESM(require("path"));
17905
+ var fs39 = __toESM(require("fs"));
17906
+ var os35 = __toESM(require("os"));
17907
+ var path43 = __toESM(require("path"));
17767
17908
  function headroomConfigPath() {
17768
- return path42.join(os34.homedir(), ".codeam", "headroom-config.json");
17909
+ return path43.join(os35.homedir(), ".codeam", "headroom-config.json");
17769
17910
  }
17770
17911
  function persistHeadroomConfig(config) {
17771
17912
  try {
17772
17913
  const file = headroomConfigPath();
17773
- fs38.mkdirSync(path42.dirname(file), { recursive: true, mode: 448 });
17914
+ fs39.mkdirSync(path43.dirname(file), { recursive: true, mode: 448 });
17774
17915
  const tmp = `${file}.tmp-${process.pid}`;
17775
- fs38.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
17776
- fs38.renameSync(tmp, file);
17916
+ fs39.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
17917
+ fs39.renameSync(tmp, file);
17777
17918
  restrictToOwner(file);
17778
17919
  } catch (err) {
17779
17920
  log.warn(
@@ -17783,21 +17924,21 @@ function persistHeadroomConfig(config) {
17783
17924
  }
17784
17925
  }
17785
17926
  function agentSettingsPath(kind) {
17786
- const home = os34.homedir();
17787
- if (kind === "claude") return path42.join(home, ".claude", "settings.json");
17788
- if (kind === "codex") return path42.join(home, ".codex", "auth.json");
17789
- if (kind === "copilot") return path42.join(home, ".config", "github-copilot", "hosts.json");
17927
+ const home = os35.homedir();
17928
+ if (kind === "claude") return path43.join(home, ".claude", "settings.json");
17929
+ if (kind === "codex") return path43.join(home, ".codex", "auth.json");
17930
+ if (kind === "copilot") return path43.join(home, ".config", "github-copilot", "hosts.json");
17790
17931
  return null;
17791
17932
  }
17792
17933
  function backupAgentHeadroomConfig(kind) {
17793
17934
  const src = agentSettingsPath(kind);
17794
17935
  if (!src) return;
17795
17936
  try {
17796
- if (!fs38.existsSync(src)) return;
17797
- const dest = path42.join(os34.homedir(), ".codeam", `headroom-backup-${kind}.json`);
17798
- fs38.mkdirSync(path42.dirname(dest), { recursive: true, mode: 448 });
17799
- fs38.copyFileSync(src, dest);
17800
- fs38.chmodSync(dest, 384);
17937
+ if (!fs39.existsSync(src)) return;
17938
+ const dest = path43.join(os35.homedir(), ".codeam", `headroom-backup-${kind}.json`);
17939
+ fs39.mkdirSync(path43.dirname(dest), { recursive: true, mode: 448 });
17940
+ fs39.copyFileSync(src, dest);
17941
+ fs39.chmodSync(dest, 384);
17801
17942
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
17802
17943
  } catch (err) {
17803
17944
  log.warn(
@@ -17809,12 +17950,12 @@ function backupAgentHeadroomConfig(kind) {
17809
17950
  function restoreAgentHeadroomConfig(kind) {
17810
17951
  const dest = agentSettingsPath(kind);
17811
17952
  if (!dest) return false;
17812
- const src = path42.join(os34.homedir(), ".codeam", `headroom-backup-${kind}.json`);
17813
- if (!fs38.existsSync(src)) return false;
17953
+ const src = path43.join(os35.homedir(), ".codeam", `headroom-backup-${kind}.json`);
17954
+ if (!fs39.existsSync(src)) return false;
17814
17955
  try {
17815
- fs38.mkdirSync(path42.dirname(dest), { recursive: true, mode: 448 });
17816
- fs38.copyFileSync(src, dest);
17817
- fs38.chmodSync(dest, 384);
17956
+ fs39.mkdirSync(path43.dirname(dest), { recursive: true, mode: 448 });
17957
+ fs39.copyFileSync(src, dest);
17958
+ fs39.chmodSync(dest, 384);
17818
17959
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
17819
17960
  return true;
17820
17961
  } catch (err) {
@@ -17827,7 +17968,7 @@ function restoreAgentHeadroomConfig(kind) {
17827
17968
  }
17828
17969
  function readHeadroomChildEnv() {
17829
17970
  try {
17830
- const raw = fs38.readFileSync(headroomConfigPath(), "utf8");
17971
+ const raw = fs39.readFileSync(headroomConfigPath(), "utf8");
17831
17972
  const parsed = JSON.parse(raw);
17832
17973
  if (typeof parsed !== "object" || parsed === null) return {};
17833
17974
  const o = parsed;
@@ -17863,37 +18004,37 @@ function bundledClaudeBinDir() {
17863
18004
  const roots = /* @__PURE__ */ new Set();
17864
18005
  let dir = __dirname;
17865
18006
  for (let i = 0; i < 6; i++) {
17866
- roots.add(path43.join(dir, "node_modules"));
17867
- const parent = path43.dirname(dir);
18007
+ roots.add(path44.join(dir, "node_modules"));
18008
+ const parent = path44.dirname(dir);
17868
18009
  if (parent === dir) break;
17869
18010
  dir = parent;
17870
18011
  }
17871
18012
  try {
17872
18013
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
17873
- const marker = `${path43.sep}@anthropic-ai${path43.sep}`;
18014
+ const marker = `${path44.sep}@anthropic-ai${path44.sep}`;
17874
18015
  const idx = main2.lastIndexOf(marker);
17875
18016
  if (idx !== -1) roots.add(main2.slice(0, idx));
17876
18017
  } catch {
17877
18018
  }
17878
18019
  for (const nm of roots) {
17879
- const atAnthropic = path43.join(nm, "@anthropic-ai");
18020
+ const atAnthropic = path44.join(nm, "@anthropic-ai");
17880
18021
  let entries;
17881
18022
  try {
17882
- entries = fs39.readdirSync(atAnthropic);
18023
+ entries = fs40.readdirSync(atAnthropic);
17883
18024
  } catch {
17884
18025
  continue;
17885
18026
  }
17886
18027
  for (const entry of entries) {
17887
18028
  if (!entry.startsWith("claude-agent-sdk-")) continue;
17888
- const bin = path43.join(atAnthropic, entry, "claude");
17889
- if (fs39.existsSync(bin)) return path43.dirname(bin);
18029
+ const bin = path44.join(atAnthropic, entry, "claude");
18030
+ if (fs40.existsSync(bin)) return path44.dirname(bin);
17890
18031
  }
17891
18032
  }
17892
18033
  return null;
17893
18034
  }
17894
18035
  async function getFreeDiskBytes(dir) {
17895
18036
  try {
17896
- const s = await fs39.promises.statfs(dir);
18037
+ const s = await fs40.promises.statfs(dir);
17897
18038
  return s.bsize * s.bavail;
17898
18039
  } catch {
17899
18040
  return null;
@@ -17955,7 +18096,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
17955
18096
  if (initKind === "claude") {
17956
18097
  const claudeDir = bundledClaudeBinDir();
17957
18098
  if (claudeDir) {
17958
- initEnv.PATH = `${claudeDir}${path43.delimiter}${process.env["PATH"] ?? ""}`;
18099
+ initEnv.PATH = `${claudeDir}${path44.delimiter}${process.env["PATH"] ?? ""}`;
17959
18100
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
17960
18101
  } else {
17961
18102
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -17990,9 +18131,9 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
17990
18131
  var import_node_child_process22 = require("child_process");
17991
18132
 
17992
18133
  // src/lib/updateNotifier.ts
17993
- var fs40 = __toESM(require("fs"));
17994
- var os35 = __toESM(require("os"));
17995
- var path44 = __toESM(require("path"));
18134
+ var fs41 = __toESM(require("fs"));
18135
+ var os36 = __toESM(require("os"));
18136
+ var path45 = __toESM(require("path"));
17996
18137
  var https6 = __toESM(require("https"));
17997
18138
  var import_node_child_process21 = require("child_process");
17998
18139
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -18001,12 +18142,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
18001
18142
  var TTL_MS = 24 * 60 * 60 * 1e3;
18002
18143
  var REQUEST_TIMEOUT_MS = 1500;
18003
18144
  function cachePath() {
18004
- const dir = path44.join(os35.homedir(), ".codeam");
18005
- return path44.join(dir, "update-check.json");
18145
+ const dir = path45.join(os36.homedir(), ".codeam");
18146
+ return path45.join(dir, "update-check.json");
18006
18147
  }
18007
18148
  function readCache() {
18008
18149
  try {
18009
- const raw = fs40.readFileSync(cachePath(), "utf8");
18150
+ const raw = fs41.readFileSync(cachePath(), "utf8");
18010
18151
  const parsed = JSON.parse(raw);
18011
18152
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
18012
18153
  return parsed;
@@ -18017,10 +18158,10 @@ function readCache() {
18017
18158
  function writeCache(cache) {
18018
18159
  try {
18019
18160
  const file = cachePath();
18020
- fs40.mkdirSync(path44.dirname(file), { recursive: true });
18161
+ fs41.mkdirSync(path45.dirname(file), { recursive: true });
18021
18162
  const tmp = `${file}.${process.pid}.tmp`;
18022
- fs40.writeFileSync(tmp, JSON.stringify(cache));
18023
- fs40.renameSync(tmp, file);
18163
+ fs41.writeFileSync(tmp, JSON.stringify(cache));
18164
+ fs41.renameSync(tmp, file);
18024
18165
  } catch {
18025
18166
  }
18026
18167
  }
@@ -18094,8 +18235,8 @@ function isLinkedInstall() {
18094
18235
  timeout: 2e3
18095
18236
  }).trim();
18096
18237
  if (!root) return false;
18097
- const pkgPath = path44.join(root, PKG_NAME);
18098
- return fs40.lstatSync(pkgPath).isSymbolicLink();
18238
+ const pkgPath = path45.join(root, PKG_NAME);
18239
+ return fs41.lstatSync(pkgPath).isSymbolicLink();
18099
18240
  } catch {
18100
18241
  return false;
18101
18242
  }
@@ -18131,7 +18272,7 @@ function maybeAutoUpdate(currentVersion, latest) {
18131
18272
  return;
18132
18273
  }
18133
18274
  try {
18134
- fs40.unlinkSync(cachePath());
18275
+ fs41.unlinkSync(cachePath());
18135
18276
  } catch {
18136
18277
  }
18137
18278
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
@@ -18147,7 +18288,7 @@ async function autoUpgradeBeforeCriticalCommand() {
18147
18288
  if (process.env.NODE_ENV === "test") return;
18148
18289
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
18149
18290
  if (process.env.CI) return;
18150
- const current = true ? "2.61.22" : null;
18291
+ const current = true ? "2.61.23" : null;
18151
18292
  if (!current) return;
18152
18293
  const cache = readCache();
18153
18294
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -18164,7 +18305,7 @@ function checkForUpdates() {
18164
18305
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
18165
18306
  if (process.env.CI) return;
18166
18307
  if (!process.stdout.isTTY) return;
18167
- const current = true ? "2.61.22" : null;
18308
+ const current = true ? "2.61.23" : null;
18168
18309
  if (!current) return;
18169
18310
  const cache = readCache();
18170
18311
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -18184,7 +18325,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
18184
18325
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
18185
18326
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
18186
18327
  function currentCliVersion() {
18187
- return true ? "2.61.22" : null;
18328
+ return true ? "2.61.23" : null;
18188
18329
  }
18189
18330
  function runCmd(cmd, args2, timeoutMs) {
18190
18331
  return new Promise((resolve8) => {
@@ -18251,7 +18392,7 @@ async function runSelfUpdate() {
18251
18392
 
18252
18393
  // src/commands/host/teardown.ts
18253
18394
  var import_node_child_process23 = require("child_process");
18254
- var fs41 = __toESM(require("fs"));
18395
+ var fs42 = __toESM(require("fs"));
18255
18396
  var defaultDisableService = () => {
18256
18397
  try {
18257
18398
  (0, import_node_child_process23.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
@@ -18260,7 +18401,7 @@ var defaultDisableService = () => {
18260
18401
  };
18261
18402
  var defaultTeardownHeadroom = () => {
18262
18403
  try {
18263
- const kind = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8")).agent;
18404
+ const kind = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8")).agent;
18264
18405
  if (kind) {
18265
18406
  (0, import_node_child_process23.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
18266
18407
  }
@@ -18328,8 +18469,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
18328
18469
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
18329
18470
  try {
18330
18471
  const file = headroomConfigPath();
18331
- if (!fs42.existsSync(file)) return null;
18332
- const cfg = JSON.parse(fs42.readFileSync(file, "utf8"));
18472
+ if (!fs43.existsSync(file)) return null;
18473
+ const cfg = JSON.parse(fs43.readFileSync(file, "utf8"));
18333
18474
  if (!cfg?.enabled) return null;
18334
18475
  const agent = cfg.agent ?? "claude";
18335
18476
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -18830,13 +18971,13 @@ var HostAgentSupervisor = class {
18830
18971
  const relay = this.relay;
18831
18972
  if (!relay) return;
18832
18973
  const raw = cmd.payload?.path;
18833
- const target = typeof raw === "string" && raw.trim() ? path45.resolve(raw.trim()) : os36.homedir();
18974
+ const target = typeof raw === "string" && raw.trim() ? path46.resolve(raw.trim()) : os37.homedir();
18834
18975
  try {
18835
- const dirents = await fs42.promises.readdir(target, { withFileTypes: true });
18976
+ const dirents = await fs43.promises.readdir(target, { withFileTypes: true });
18836
18977
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
18837
18978
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
18838
18979
  );
18839
- const parent = path45.dirname(target);
18980
+ const parent = path46.dirname(target);
18840
18981
  await relay.sendResult(cmd.id, "completed", {
18841
18982
  path: target,
18842
18983
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -19049,9 +19190,9 @@ var HostAgentSupervisor = class {
19049
19190
  API_TIMEOUT_MS: "3000000",
19050
19191
  CODEAM_AUTO_TOKEN: payload.autoPairToken
19051
19192
  };
19052
- const houseConfigDir = path45.join(os36.homedir(), ".codeam", "house-claude");
19193
+ const houseConfigDir = path46.join(os37.homedir(), ".codeam", "house-claude");
19053
19194
  try {
19054
- fs42.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
19195
+ fs43.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
19055
19196
  } catch {
19056
19197
  }
19057
19198
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -19069,14 +19210,14 @@ var HostAgentSupervisor = class {
19069
19210
  report("installing", "installing agent CLI");
19070
19211
  await this.runAgentInstall(payload.agentInstallScript);
19071
19212
  }
19072
- const home = process.env.HOME || os36.homedir();
19213
+ const home = process.env.HOME || os37.homedir();
19073
19214
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
19074
19215
  if (payload.cloneToken) {
19075
19216
  try {
19076
19217
  report("preparing", "configuring git tooling");
19077
19218
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
19078
19219
  if (ghCmd) {
19079
- childEnv.PATH = `${codeamBinDir()}${path45.delimiter}${childEnv.PATH}`;
19220
+ childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
19080
19221
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
19081
19222
  }
19082
19223
  } catch (e) {
@@ -19092,7 +19233,7 @@ var HostAgentSupervisor = class {
19092
19233
  }
19093
19234
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
19094
19235
  report("headroom", "setting up Headroom proxy");
19095
- const freeBytes = await this.getFreeDisk(os36.homedir());
19236
+ const freeBytes = await this.getFreeDisk(os37.homedir());
19096
19237
  const alreadyInstalled = this.isHeadroomInstalled();
19097
19238
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
19098
19239
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -19146,6 +19287,9 @@ var HostAgentSupervisor = class {
19146
19287
  } else {
19147
19288
  clearIntegrationsManifest();
19148
19289
  }
19290
+ persistOrClearSkillsFromPayload(
19291
+ payload.skills
19292
+ );
19149
19293
  report("spawning", "starting agent");
19150
19294
  const proc = this.spawnSessionChild(childEnv, cwd, extraArgs);
19151
19295
  const child = {
@@ -19273,7 +19417,7 @@ var HostAgentSupervisor = class {
19273
19417
  */
19274
19418
  runAgentInstall(script) {
19275
19419
  return new Promise((resolve8) => {
19276
- const home = process.env.HOME || os36.homedir();
19420
+ const home = process.env.HOME || os37.homedir();
19277
19421
  const child = (0, import_node_child_process24.spawn)("sh", ["-c", script], {
19278
19422
  env: { ...process.env, HOME: home },
19279
19423
  stdio: ["ignore", "pipe", "pipe"]
@@ -19464,9 +19608,9 @@ async function configureHeadroom(action, ctx, deps) {
19464
19608
  }
19465
19609
 
19466
19610
  // src/services/headroom/budget-relaunch.ts
19467
- var fs43 = __toESM(require("fs"));
19468
- var os37 = __toESM(require("os"));
19469
- var path46 = __toESM(require("path"));
19611
+ var fs44 = __toESM(require("fs"));
19612
+ var os38 = __toESM(require("os"));
19613
+ var path47 = __toESM(require("path"));
19470
19614
  var import_child_process13 = require("child_process");
19471
19615
  function amendDeploymentManifestBudget(manifest, budget) {
19472
19616
  const rawArgs = manifest.proxy_args ?? [];
@@ -19500,7 +19644,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
19500
19644
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
19501
19645
  }
19502
19646
  function findHeadroomDeployments(homeDir2, deps) {
19503
- const deployDir = path46.join(homeDir2, ".headroom", "deploy");
19647
+ const deployDir = path47.join(homeDir2, ".headroom", "deploy");
19504
19648
  let profiles;
19505
19649
  try {
19506
19650
  profiles = deps.readDir(deployDir);
@@ -19509,7 +19653,7 @@ function findHeadroomDeployments(homeDir2, deps) {
19509
19653
  }
19510
19654
  const results = [];
19511
19655
  for (const profile of profiles) {
19512
- const manifestPath = path46.join(deployDir, profile, "manifest.json");
19656
+ const manifestPath = path47.join(deployDir, profile, "manifest.json");
19513
19657
  let raw;
19514
19658
  try {
19515
19659
  raw = deps.readJson(manifestPath);
@@ -19541,8 +19685,8 @@ async function applyBudgetToHeadroom(budget, deps) {
19541
19685
  }
19542
19686
  function writeManifestReal(manifestPath, manifest) {
19543
19687
  const tmp = manifestPath + ".codeam.tmp";
19544
- fs43.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
19545
- fs43.renameSync(tmp, manifestPath);
19688
+ fs44.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
19689
+ fs44.renameSync(tmp, manifestPath);
19546
19690
  }
19547
19691
  function restartDeploymentReal(profile) {
19548
19692
  try {
@@ -19572,11 +19716,11 @@ function spawnProxyReal2(_budget) {
19572
19716
  });
19573
19717
  }
19574
19718
  function makeRealApplyBudgetDeps() {
19575
- const homeDir2 = os37.homedir();
19719
+ const homeDir2 = os38.homedir();
19576
19720
  return {
19577
19721
  findDeployments: () => findHeadroomDeployments(homeDir2, {
19578
- readDir: (dir) => fs43.readdirSync(dir),
19579
- readJson: (filePath) => JSON.parse(fs43.readFileSync(filePath, "utf8"))
19722
+ readDir: (dir) => fs44.readdirSync(dir),
19723
+ readJson: (filePath) => JSON.parse(fs44.readFileSync(filePath, "utf8"))
19580
19724
  }),
19581
19725
  writeManifest: writeManifestReal,
19582
19726
  restartDeployment: restartDeploymentReal,
@@ -19586,16 +19730,16 @@ function makeRealApplyBudgetDeps() {
19586
19730
  }
19587
19731
 
19588
19732
  // src/services/preview/port-registry.ts
19589
- var fs44 = __toESM(require("fs"));
19590
- var os38 = __toESM(require("os"));
19591
- var path47 = __toESM(require("path"));
19733
+ var fs45 = __toESM(require("fs"));
19734
+ var os39 = __toESM(require("os"));
19735
+ var path48 = __toESM(require("path"));
19592
19736
  var import_child_process14 = require("child_process");
19593
19737
  function registryPath() {
19594
- return path47.join(os38.homedir(), ".codeam", "preview-ports.json");
19738
+ return path48.join(os39.homedir(), ".codeam", "preview-ports.json");
19595
19739
  }
19596
19740
  function readRegistry() {
19597
19741
  try {
19598
- const raw = fs44.readFileSync(registryPath(), "utf8");
19742
+ const raw = fs45.readFileSync(registryPath(), "utf8");
19599
19743
  const parsed = JSON.parse(raw);
19600
19744
  if (parsed && typeof parsed === "object") return parsed;
19601
19745
  } catch {
@@ -19605,10 +19749,10 @@ function readRegistry() {
19605
19749
  function writeRegistry(reg) {
19606
19750
  try {
19607
19751
  const file = registryPath();
19608
- fs44.mkdirSync(path47.dirname(file), { recursive: true });
19752
+ fs45.mkdirSync(path48.dirname(file), { recursive: true });
19609
19753
  const tmp = `${file}.tmp`;
19610
- fs44.writeFileSync(tmp, JSON.stringify(reg), "utf8");
19611
- fs44.renameSync(tmp, file);
19754
+ fs45.writeFileSync(tmp, JSON.stringify(reg), "utf8");
19755
+ fs45.renameSync(tmp, file);
19612
19756
  } catch (err) {
19613
19757
  log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
19614
19758
  }
@@ -20344,8 +20488,8 @@ function activePreviewSessionIds() {
20344
20488
 
20345
20489
  // src/services/preview/start-orchestrator.ts
20346
20490
  var import_child_process18 = require("child_process");
20347
- var fs49 = __toESM(require("fs"));
20348
- var path52 = __toESM(require("path"));
20491
+ var fs50 = __toESM(require("fs"));
20492
+ var path53 = __toESM(require("path"));
20349
20493
  var import_which2 = __toESM(require("which"));
20350
20494
  var INSTALL_TIMEOUT_MS = 5 * 6e4;
20351
20495
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -20412,8 +20556,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
20412
20556
  if (args2.length === 0) return detection;
20413
20557
  const binName = args2[0];
20414
20558
  if (binName.startsWith("-")) return detection;
20415
- const binPath = path52.join(cwd, "node_modules", ".bin", binName);
20416
- if (!fs49.existsSync(binPath)) return detection;
20559
+ const binPath = path53.join(cwd, "node_modules", ".bin", binName);
20560
+ if (!fs50.existsSync(binPath)) return detection;
20417
20561
  return {
20418
20562
  ...detection,
20419
20563
  command: binPath,
@@ -20777,9 +20921,9 @@ async function establishTunnel(ctx, dev) {
20777
20921
 
20778
20922
  // src/beads/bd-adapter.ts
20779
20923
  var import_child_process19 = require("child_process");
20780
- var fs50 = __toESM(require("fs"));
20781
- var os40 = __toESM(require("os"));
20782
- var path53 = __toESM(require("path"));
20924
+ var fs51 = __toESM(require("fs"));
20925
+ var os41 = __toESM(require("os"));
20926
+ var path54 = __toESM(require("path"));
20783
20927
  var BD_PACKAGE = "@beads/bd";
20784
20928
  function resolveBundledBdBinary() {
20785
20929
  return _resolveSeam.resolveBundled();
@@ -20791,11 +20935,11 @@ function _defaultResolveBundled() {
20791
20935
  } catch {
20792
20936
  return null;
20793
20937
  }
20794
- const binDir = path53.join(path53.dirname(pkgJsonPath), "bin");
20938
+ const binDir = path54.join(path54.dirname(pkgJsonPath), "bin");
20795
20939
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
20796
- const binaryPath = path53.join(binDir, binaryName);
20940
+ const binaryPath = path54.join(binDir, binaryName);
20797
20941
  try {
20798
- fs50.accessSync(binaryPath, fs50.constants.F_OK);
20942
+ fs51.accessSync(binaryPath, fs51.constants.F_OK);
20799
20943
  return binaryPath;
20800
20944
  } catch {
20801
20945
  return null;
@@ -20805,13 +20949,13 @@ function resolveBdOnPath() {
20805
20949
  return _resolveSeam.resolveOnPath();
20806
20950
  }
20807
20951
  function _defaultResolveOnPath() {
20808
- const dirs = (process.env.PATH ?? "").split(path53.delimiter).filter(Boolean);
20952
+ const dirs = (process.env.PATH ?? "").split(path54.delimiter).filter(Boolean);
20809
20953
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
20810
20954
  for (const dir of dirs) {
20811
20955
  for (const candidate of candidates) {
20812
- const full = path53.join(dir, candidate);
20956
+ const full = path54.join(dir, candidate);
20813
20957
  try {
20814
- fs50.accessSync(full, fs50.constants.F_OK);
20958
+ fs51.accessSync(full, fs51.constants.F_OK);
20815
20959
  return full;
20816
20960
  } catch {
20817
20961
  }
@@ -20896,7 +21040,7 @@ var BdAdapter = class {
20896
21040
  const env = { ...process.env };
20897
21041
  if (!env.HOME) {
20898
21042
  try {
20899
- const home = os40.homedir();
21043
+ const home = os41.homedir();
20900
21044
  if (home) env.HOME = home;
20901
21045
  } catch {
20902
21046
  }
@@ -20988,9 +21132,9 @@ function coerceIssue(row, projectKey) {
20988
21132
 
20989
21133
  // src/beads/provisioner.ts
20990
21134
  var import_child_process23 = require("child_process");
20991
- var fs53 = __toESM(require("fs"));
20992
- var os42 = __toESM(require("os"));
20993
- var path56 = __toESM(require("path"));
21135
+ var fs54 = __toESM(require("fs"));
21136
+ var os43 = __toESM(require("os"));
21137
+ var path57 = __toESM(require("path"));
20994
21138
 
20995
21139
  // src/beads/install-bd.ts
20996
21140
  var import_child_process20 = require("child_process");
@@ -21055,9 +21199,9 @@ async function installBd(platform3 = process.platform) {
21055
21199
 
21056
21200
  // src/beads/install-dolt.ts
21057
21201
  var import_child_process21 = require("child_process");
21058
- var fs51 = __toESM(require("fs"));
21059
- var os41 = __toESM(require("os"));
21060
- var path54 = __toESM(require("path"));
21202
+ var fs52 = __toESM(require("fs"));
21203
+ var os42 = __toESM(require("os"));
21204
+ var path55 = __toESM(require("path"));
21061
21205
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
21062
21206
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
21063
21207
  function resolveDoltInstallStrategy(platform3) {
@@ -21097,11 +21241,11 @@ function resolveDoltInstallStrategy(platform3) {
21097
21241
  }
21098
21242
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
21099
21243
  function doltPlatformTuple(platform3, arch2) {
21100
- const os53 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
21244
+ const os57 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
21101
21245
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
21102
21246
  if (!a) return null;
21103
- if (os53 === "windows" && a !== "amd64") return null;
21104
- return `${os53}-${a}`;
21247
+ if (os57 === "windows" && a !== "amd64") return null;
21248
+ return `${os57}-${a}`;
21105
21249
  }
21106
21250
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
21107
21251
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -21146,14 +21290,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
21146
21290
  return result;
21147
21291
  }
21148
21292
  var _doltPathSeam = {
21149
- homedir: () => os41.homedir(),
21293
+ homedir: () => os42.homedir(),
21150
21294
  getPath: () => process.env.PATH ?? "",
21151
21295
  setPath: (p2) => {
21152
21296
  process.env.PATH = p2;
21153
21297
  },
21154
21298
  exists: (p2) => {
21155
21299
  try {
21156
- fs51.accessSync(p2, fs51.constants.F_OK);
21300
+ fs52.accessSync(p2, fs52.constants.F_OK);
21157
21301
  return true;
21158
21302
  } catch {
21159
21303
  return false;
@@ -21164,7 +21308,7 @@ function doltBinaryNames(platform3) {
21164
21308
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
21165
21309
  }
21166
21310
  function knownDoltDirs(platform3) {
21167
- const P3 = platform3 === "win32" ? path54.win32 : path54.posix;
21311
+ const P3 = platform3 === "win32" ? path55.win32 : path55.posix;
21168
21312
  const home = _doltPathSeam.homedir();
21169
21313
  if (platform3 === "win32") {
21170
21314
  return [
@@ -21180,7 +21324,7 @@ function knownDoltDirs(platform3) {
21180
21324
  ].filter(Boolean);
21181
21325
  }
21182
21326
  function ensureDoltResolvable(platform3 = process.platform) {
21183
- const P3 = platform3 === "win32" ? path54.win32 : path54.posix;
21327
+ const P3 = platform3 === "win32" ? path55.win32 : path55.posix;
21184
21328
  const delim = platform3 === "win32" ? ";" : ":";
21185
21329
  const names = doltBinaryNames(platform3);
21186
21330
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -21316,8 +21460,8 @@ async function ensureSharedServer(adapter, options = {}) {
21316
21460
  // src/beads/project-key.ts
21317
21461
  var import_child_process22 = require("child_process");
21318
21462
  var crypto2 = __toESM(require("crypto"));
21319
- var fs52 = __toESM(require("fs"));
21320
- var path55 = __toESM(require("path"));
21463
+ var fs53 = __toESM(require("fs"));
21464
+ var path56 = __toESM(require("path"));
21321
21465
  function normalizeOrigin(raw) {
21322
21466
  const trimmed = raw.trim();
21323
21467
  if (!trimmed) return null;
@@ -21343,17 +21487,17 @@ function normalizeOrigin(raw) {
21343
21487
  return `${host2}/${pathPart}`;
21344
21488
  }
21345
21489
  function findRepoRoot(cwd) {
21346
- let dir = path55.resolve(cwd);
21490
+ let dir = path56.resolve(cwd);
21347
21491
  const seen = /* @__PURE__ */ new Set();
21348
21492
  for (let i = 0; i < 256; i++) {
21349
21493
  if (seen.has(dir)) return null;
21350
21494
  seen.add(dir);
21351
21495
  try {
21352
- const stat3 = fs52.statSync(path55.join(dir, ".git"), { throwIfNoEntry: false });
21496
+ const stat3 = fs53.statSync(path56.join(dir, ".git"), { throwIfNoEntry: false });
21353
21497
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
21354
21498
  } catch {
21355
21499
  }
21356
- const parent = path55.dirname(dir);
21500
+ const parent = path56.dirname(dir);
21357
21501
  if (parent === dir) return null;
21358
21502
  dir = parent;
21359
21503
  }
@@ -21364,7 +21508,7 @@ var _execSeam2 = {
21364
21508
  const out2 = (0, import_child_process22.execFileSync)(file, args2, opts);
21365
21509
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
21366
21510
  },
21367
- realpath: (p2) => fs52.realpathSync(p2)
21511
+ realpath: (p2) => fs53.realpathSync(p2)
21368
21512
  };
21369
21513
  function readOrigin(cwd) {
21370
21514
  try {
@@ -21393,7 +21537,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
21393
21537
  } catch {
21394
21538
  }
21395
21539
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
21396
- return { projectKey: `path:${hash}`, projectLabel: path55.basename(real) || "project" };
21540
+ return { projectKey: `path:${hash}`, projectLabel: path56.basename(real) || "project" };
21397
21541
  }
21398
21542
 
21399
21543
  // src/beads/project-prefix.ts
@@ -21438,17 +21582,17 @@ var _provisionSeam = {
21438
21582
  };
21439
21583
  var _linkSeam = {
21440
21584
  platform: () => process.platform,
21441
- homedir: () => os42.homedir(),
21585
+ homedir: () => os43.homedir(),
21442
21586
  isWritableDir: (dir) => {
21443
21587
  try {
21444
- fs53.accessSync(dir, fs53.constants.W_OK);
21588
+ fs54.accessSync(dir, fs54.constants.W_OK);
21445
21589
  return true;
21446
21590
  } catch {
21447
21591
  return false;
21448
21592
  }
21449
21593
  },
21450
21594
  ensureDir: (dir) => {
21451
- fs53.mkdirSync(dir, { recursive: true });
21595
+ fs54.mkdirSync(dir, { recursive: true });
21452
21596
  },
21453
21597
  /**
21454
21598
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -21469,9 +21613,9 @@ var _linkSeam = {
21469
21613
  * which `linkBdOntoPath` creates if missing.
21470
21614
  */
21471
21615
  cliBinDir: () => {
21472
- const pathDirs = (process.env.PATH ?? "").split(path56.delimiter).filter(Boolean);
21616
+ const pathDirs = (process.env.PATH ?? "").split(path57.delimiter).filter(Boolean);
21473
21617
  const home = _linkSeam.homedir();
21474
- const localBin = home ? path56.join(home, ".local", "bin") : null;
21618
+ const localBin = home ? path57.join(home, ".local", "bin") : null;
21475
21619
  if (localBin) {
21476
21620
  try {
21477
21621
  _linkSeam.ensureDir(localBin);
@@ -21481,16 +21625,16 @@ var _linkSeam = {
21481
21625
  const candidates = [];
21482
21626
  if (localBin) candidates.push(localBin);
21483
21627
  try {
21484
- candidates.push(path56.dirname(process.execPath));
21628
+ candidates.push(path57.dirname(process.execPath));
21485
21629
  } catch {
21486
21630
  }
21487
21631
  candidates.push("/usr/local/bin");
21488
21632
  const entry = process.argv[1];
21489
21633
  if (entry) {
21490
21634
  try {
21491
- candidates.push(path56.dirname(fs53.realpathSync(entry)));
21635
+ candidates.push(path57.dirname(fs54.realpathSync(entry)));
21492
21636
  } catch {
21493
- candidates.push(path56.dirname(entry));
21637
+ candidates.push(path57.dirname(entry));
21494
21638
  }
21495
21639
  }
21496
21640
  const onPathWritable = candidates.find(
@@ -21502,20 +21646,20 @@ var _linkSeam = {
21502
21646
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
21503
21647
  readlink: (linkPath) => {
21504
21648
  try {
21505
- return fs53.readlinkSync(linkPath);
21649
+ return fs54.readlinkSync(linkPath);
21506
21650
  } catch {
21507
21651
  return null;
21508
21652
  }
21509
21653
  },
21510
- unlink: (linkPath) => fs53.unlinkSync(linkPath),
21511
- symlink: (target, linkPath) => fs53.symlinkSync(target, linkPath)
21654
+ unlink: (linkPath) => fs54.unlinkSync(linkPath),
21655
+ symlink: (target, linkPath) => fs54.symlinkSync(target, linkPath)
21512
21656
  };
21513
21657
  function linkBdOntoPath(binaryPath) {
21514
21658
  if (_linkSeam.platform() === "win32") return;
21515
21659
  const binDir = _linkSeam.cliBinDir();
21516
21660
  if (!binDir) return;
21517
21661
  _linkSeam.ensureDir(binDir);
21518
- const linkPath = path56.join(binDir, "bd");
21662
+ const linkPath = path57.join(binDir, "bd");
21519
21663
  if (linkPath === binaryPath) return;
21520
21664
  const current = _linkSeam.readlink(linkPath);
21521
21665
  if (current === binaryPath) return;
@@ -21710,7 +21854,7 @@ function dedupeRecipes(agents) {
21710
21854
 
21711
21855
  // src/beads/watcher.ts
21712
21856
  var crypto4 = __toESM(require("crypto"));
21713
- var path57 = __toESM(require("path"));
21857
+ var path58 = __toESM(require("path"));
21714
21858
  var API_BASE6 = resolveApiBaseUrl();
21715
21859
  var DEBOUNCE_MS2 = 400;
21716
21860
  var ZERO_SUMMARY = {
@@ -21734,7 +21878,7 @@ var BeadsWatcher = class {
21734
21878
  constructor(opts) {
21735
21879
  this.opts = opts;
21736
21880
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
21737
- this.feedPath = opts.feedPath ?? path57.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
21881
+ this.feedPath = opts.feedPath ?? path58.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
21738
21882
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
21739
21883
  }
21740
21884
  opts;
@@ -21985,15 +22129,15 @@ async function handleBeadsActionCommand(action, started) {
21985
22129
  }
21986
22130
 
21987
22131
  // src/beads/config-store.ts
21988
- var import_node_fs8 = __toESM(require("fs"));
21989
- var import_node_os7 = __toESM(require("os"));
21990
- var import_node_path6 = __toESM(require("path"));
22132
+ var import_node_fs9 = __toESM(require("fs"));
22133
+ var import_node_os8 = __toESM(require("os"));
22134
+ var import_node_path7 = __toESM(require("path"));
21991
22135
  function beadsConfigPath() {
21992
- return import_node_path6.default.join(import_node_os7.default.homedir(), ".codeam", "beads-config.json");
22136
+ return import_node_path7.default.join(import_node_os8.default.homedir(), ".codeam", "beads-config.json");
21993
22137
  }
21994
22138
  function readBeadsEnabled() {
21995
22139
  try {
21996
- const raw = import_node_fs8.default.readFileSync(beadsConfigPath(), "utf8");
22140
+ const raw = import_node_fs9.default.readFileSync(beadsConfigPath(), "utf8");
21997
22141
  const cfg = JSON.parse(raw);
21998
22142
  return cfg.enabled !== false;
21999
22143
  } catch {
@@ -22002,10 +22146,10 @@ function readBeadsEnabled() {
22002
22146
  }
22003
22147
  function persistBeadsConfig(cfg) {
22004
22148
  const file = beadsConfigPath();
22005
- import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true });
22149
+ import_node_fs9.default.mkdirSync(import_node_path7.default.dirname(file), { recursive: true });
22006
22150
  const tmp = `${file}.tmp`;
22007
- import_node_fs8.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
22008
- import_node_fs8.default.renameSync(tmp, file);
22151
+ import_node_fs9.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
22152
+ import_node_fs9.default.renameSync(tmp, file);
22009
22153
  restrictToOwner(file);
22010
22154
  }
22011
22155
 
@@ -22140,6 +22284,88 @@ async function configureBeads(action, ctx, deps) {
22140
22284
  return { enabled: true, running, ...p2 };
22141
22285
  }
22142
22286
 
22287
+ // src/skills/configure.ts
22288
+ var import_node_os10 = __toESM(require("os"));
22289
+
22290
+ // src/skills/materialize.ts
22291
+ var import_node_fs10 = __toESM(require("fs"));
22292
+ var import_node_os9 = __toESM(require("os"));
22293
+ var import_node_path8 = __toESM(require("path"));
22294
+ var NS = "codeam-";
22295
+ function skillDirFor(id, home = import_node_os9.default.homedir()) {
22296
+ return import_node_path8.default.join(home, ".claude", "skills", `${NS}${id}`);
22297
+ }
22298
+ function renderSkillMd(id, description, body) {
22299
+ const desc = description.replace(/\s*\n\s*/g, " ").trim();
22300
+ return `---
22301
+ name: ${NS}${id}
22302
+ description: ${JSON.stringify(desc)}
22303
+ ---
22304
+
22305
+ ${body.trim()}
22306
+ `;
22307
+ }
22308
+ function materializeSkill(id, home = import_node_os9.default.homedir()) {
22309
+ const def = getSkillDefinition(id);
22310
+ if (!def?.delivery.skillFile) return false;
22311
+ try {
22312
+ const dir = skillDirFor(id, home);
22313
+ import_node_fs10.default.mkdirSync(dir, { recursive: true, mode: 448 });
22314
+ import_node_fs10.default.writeFileSync(
22315
+ import_node_path8.default.join(dir, "SKILL.md"),
22316
+ renderSkillMd(id, def.description, def.delivery.skillFile.body),
22317
+ { encoding: "utf8", mode: 384 }
22318
+ );
22319
+ const baseDir = import_node_path8.default.resolve(dir);
22320
+ const baseDirWithSep = baseDir + import_node_path8.default.sep;
22321
+ for (const [rel, contents] of Object.entries(def.delivery.skillFile.files ?? {})) {
22322
+ const target = import_node_path8.default.join(dir, rel);
22323
+ if (!import_node_path8.default.resolve(target).startsWith(baseDirWithSep) && import_node_path8.default.resolve(target) !== baseDir) {
22324
+ continue;
22325
+ }
22326
+ import_node_fs10.default.mkdirSync(import_node_path8.default.dirname(target), { recursive: true, mode: 448 });
22327
+ import_node_fs10.default.writeFileSync(target, contents, { encoding: "utf8", mode: 384 });
22328
+ }
22329
+ return true;
22330
+ } catch (err) {
22331
+ log.warn("skills", `failed to materialize ${id} (best-effort): ${err instanceof Error ? err.message : String(err)}`);
22332
+ return false;
22333
+ }
22334
+ }
22335
+ function removeSkill(id, home = import_node_os9.default.homedir()) {
22336
+ try {
22337
+ import_node_fs10.default.rmSync(skillDirFor(id, home), { recursive: true, force: true });
22338
+ } catch {
22339
+ }
22340
+ }
22341
+
22342
+ // src/skills/configure.ts
22343
+ function currentInstalled() {
22344
+ const m = readSkillsManifest();
22345
+ return (m?.skills ?? []).map((s) => s.id).filter(isSkillId);
22346
+ }
22347
+ function configureSkill(action, skillId, home = import_node_os10.default.homedir()) {
22348
+ if (action === "list") return { ok: true, installed: currentInstalled() };
22349
+ if (!skillId || !isSkillId(skillId)) {
22350
+ return { ok: false, installed: currentInstalled(), error: `unknown skill: ${skillId ?? "(none)"}` };
22351
+ }
22352
+ const set = new Set(currentInstalled());
22353
+ if (action === "add") {
22354
+ if (!materializeSkill(skillId, home)) {
22355
+ return { ok: false, installed: [...set], error: `skill ${skillId} has no skillFile rail` };
22356
+ }
22357
+ set.add(skillId);
22358
+ } else if (action === "remove") {
22359
+ removeSkill(skillId, home);
22360
+ set.delete(skillId);
22361
+ } else {
22362
+ return { ok: false, installed: currentInstalled(), error: `unknown action: ${action}` };
22363
+ }
22364
+ const installed2 = [...set];
22365
+ persistSkillsManifest({ skills: installed2.map((id) => ({ id })) });
22366
+ return { ok: true, installed: installed2 };
22367
+ }
22368
+
22143
22369
  // src/commands/start/handlers.ts
22144
22370
  var pendingAttachmentFiles = /* @__PURE__ */ new Set();
22145
22371
  function cleanupAttachmentTempFiles() {
@@ -22151,8 +22377,8 @@ function cleanupAttachmentTempFiles() {
22151
22377
  function saveFilesTemp(files) {
22152
22378
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
22153
22379
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
22154
- const tmpPath = path59.join(os44.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
22155
- fs55.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
22380
+ const tmpPath = path61.join(os47.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
22381
+ fs57.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
22156
22382
  pendingAttachmentFiles.add(tmpPath);
22157
22383
  return tmpPath;
22158
22384
  });
@@ -22364,9 +22590,9 @@ var listFiles = async (ctx, cmd, parsed) => {
22364
22590
  await ctx.relay.sendResult(cmd.id, "completed", result);
22365
22591
  };
22366
22592
  var envReadH = async (ctx, cmd) => {
22367
- const envPath = path59.join(process.cwd(), ".env");
22593
+ const envPath = path61.join(process.cwd(), ".env");
22368
22594
  try {
22369
- const raw = await fs55.promises.readFile(envPath, "utf8");
22595
+ const raw = await fs57.promises.readFile(envPath, "utf8");
22370
22596
  await ctx.relay.sendResult(cmd.id, "completed", {
22371
22597
  exists: true,
22372
22598
  vars: parseDotenv(raw)
@@ -22397,17 +22623,22 @@ var envWriteH = async (ctx, cmd, parsed) => {
22397
22623
  }
22398
22624
  seen.add(v.key);
22399
22625
  }
22400
- const envPath = path59.join(process.cwd(), ".env");
22401
- const tmpPath = path59.join(process.cwd(), ".env.codeam.tmp");
22626
+ const envPath = path61.join(process.cwd(), ".env");
22627
+ const tmpPath = path61.join(process.cwd(), ".env.codeam.tmp");
22402
22628
  try {
22403
- await fs55.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
22404
- await fs55.promises.rename(tmpPath, envPath);
22629
+ await fs57.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
22630
+ await fs57.promises.rename(tmpPath, envPath);
22405
22631
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
22406
22632
  } catch (err) {
22407
- await fs55.promises.rm(tmpPath, { force: true }).catch(() => void 0);
22633
+ await fs57.promises.rm(tmpPath, { force: true }).catch(() => void 0);
22408
22634
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
22409
22635
  }
22410
22636
  };
22637
+ var skillsConfigureH = async (ctx, cmd, parsed) => {
22638
+ const action = parsed.action;
22639
+ const res = configureSkill(action ?? "list", parsed.skillId);
22640
+ await ctx.relay.sendResult(cmd.id, res.ok ? "completed" : "failed", res);
22641
+ };
22411
22642
  var takeControlH = async (ctx, cmd) => {
22412
22643
  if (!ctx.baton) {
22413
22644
  await ctx.relay.sendResult(cmd.id, "failed", { code: "NO_BATON" });
@@ -22448,7 +22679,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
22448
22679
  let configuredAgent = rawAgentId;
22449
22680
  if (!configuredAgent) {
22450
22681
  try {
22451
- const raw = JSON.parse(fs55.readFileSync(headroomConfigPath(), "utf8"));
22682
+ const raw = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
22452
22683
  configuredAgent = raw.agent ?? "";
22453
22684
  } catch {
22454
22685
  }
@@ -22482,7 +22713,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
22482
22713
  persist: persistHeadroomConfig,
22483
22714
  readEnabled: () => {
22484
22715
  try {
22485
- const raw = JSON.parse(fs55.readFileSync(headroomConfigPath(), "utf8"));
22716
+ const raw = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
22486
22717
  return raw.enabled === true;
22487
22718
  } catch {
22488
22719
  return false;
@@ -22739,7 +22970,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
22739
22970
  });
22740
22971
  const token = ctx.pluginAuthToken;
22741
22972
  void (async () => {
22742
- const os53 = createOsStrategy();
22973
+ const os57 = createOsStrategy();
22743
22974
  try {
22744
22975
  const report = await reviewPullRequest(
22745
22976
  {
@@ -22748,7 +22979,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
22748
22979
  baseBranch: parsed.baseBranch
22749
22980
  },
22750
22981
  {
22751
- runReview: (input) => new CoderabbitRuntimeStrategy(os53).runOneShot(input),
22982
+ runReview: (input) => new CoderabbitRuntimeStrategy(os57).runOneShot(input),
22752
22983
  runGh: (args2) => defaultRunGh(args2),
22753
22984
  postReport: async (r) => {
22754
22985
  if (!token) return;
@@ -22786,7 +23017,7 @@ var headroomBudgetH = async (ctx, cmd) => {
22786
23017
  }
22787
23018
  let headroomActive = false;
22788
23019
  try {
22789
- const raw = JSON.parse(fs55.readFileSync(headroomConfigPath(), "utf8"));
23020
+ const raw = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
22790
23021
  headroomActive = raw.enabled === true;
22791
23022
  } catch {
22792
23023
  }
@@ -22796,7 +23027,7 @@ var headroomBudgetH = async (ctx, cmd) => {
22796
23027
  }
22797
23028
  let existingConfig = { enabled: true };
22798
23029
  try {
22799
- existingConfig = JSON.parse(fs55.readFileSync(headroomConfigPath(), "utf8"));
23030
+ existingConfig = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
22800
23031
  } catch {
22801
23032
  }
22802
23033
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -22909,9 +23140,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
22909
23140
  function buildNpmInstallInvocation(opts) {
22910
23141
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
22911
23142
  const execPath = opts?.execPath ?? process.execPath;
22912
- const exists2 = opts?.existsSync ?? fs55.existsSync;
23143
+ const exists2 = opts?.existsSync ?? fs57.existsSync;
22913
23144
  const platform3 = opts?.platform ?? process.platform;
22914
- const p2 = platform3 === "win32" ? path59.win32 : path59.posix;
23145
+ const p2 = platform3 === "win32" ? path61.win32 : path61.posix;
22915
23146
  const normalized = entryScript.split(/[\\/]/).join("/");
22916
23147
  const marker = "/lib/node_modules/codeam-cli/";
22917
23148
  const markerIdx = normalized.indexOf(marker);
@@ -23497,6 +23728,7 @@ var handlers = {
23497
23728
  save_preview_config: savePreviewConfigH,
23498
23729
  env_read: envReadH,
23499
23730
  env_write: envWriteH,
23731
+ skills_configure: skillsConfigureH,
23500
23732
  take_control: takeControlH,
23501
23733
  handback: handbackH,
23502
23734
  headroom_configure: headroomConfigureH,
@@ -23796,11 +24028,11 @@ function resolveTokenValue(args2) {
23796
24028
  }
23797
24029
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
23798
24030
  if (fileFlag) {
23799
- const path76 = fileFlag.slice("--token-file=".length);
24031
+ const path78 = fileFlag.slice("--token-file=".length);
23800
24032
  try {
23801
- const content = fs56.readFileSync(path76, "utf8").trim();
23802
- if (content.length === 0) fail(`--token-file ${path76} is empty`);
23803
- rmIfExistsQuiet(path76);
24033
+ const content = fs58.readFileSync(path78, "utf8").trim();
24034
+ if (content.length === 0) fail(`--token-file ${path78} is empty`);
24035
+ rmIfExistsQuiet(path78);
23804
24036
  return content;
23805
24037
  } catch (err) {
23806
24038
  fail(`Could not read --token-file: ${err.message}`);
@@ -23829,7 +24061,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
23829
24061
  pluginId,
23830
24062
  ideName: "codeam-cli (codespace)",
23831
24063
  ideVersion: process.env.npm_package_version ?? "unknown",
23832
- hostname: os45.hostname(),
24064
+ hostname: os48.hostname(),
23833
24065
  codespaceName: process.env.CODESPACE_NAME ?? "",
23834
24066
  // Current git branch of the codespace's working directory, so the
23835
24067
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -23890,7 +24122,7 @@ async function claim(token, pluginId, pluginSecretHash) {
23890
24122
  }
23891
24123
  }
23892
24124
  function pairAutoLockPath() {
23893
- return path60.join(os45.homedir(), ".codeam", "pair-auto.lock");
24125
+ return path62.join(os48.homedir(), ".codeam", "pair-auto.lock");
23894
24126
  }
23895
24127
  function isLivePairAuto(pid) {
23896
24128
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -23900,7 +24132,7 @@ function isLivePairAuto(pid) {
23900
24132
  if (e.code !== "EPERM") return false;
23901
24133
  }
23902
24134
  try {
23903
- return fs56.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
24135
+ return fs58.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
23904
24136
  } catch {
23905
24137
  return true;
23906
24138
  }
@@ -23910,24 +24142,24 @@ function isLiveCodeam(pid) {
23910
24142
  }
23911
24143
  function daemonLockPath(sessionId) {
23912
24144
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
23913
- return path60.join(os45.homedir(), ".codeam", `daemon-${safe}.lock`);
24145
+ return path62.join(os48.homedir(), ".codeam", `daemon-${safe}.lock`);
23914
24146
  }
23915
24147
  function acquireDaemonLock(sessionId) {
23916
24148
  const lockPath = daemonLockPath(sessionId);
23917
24149
  try {
23918
- fs56.mkdirSync(path60.dirname(lockPath), { recursive: true });
24150
+ fs58.mkdirSync(path62.dirname(lockPath), { recursive: true });
23919
24151
  try {
23920
- fs56.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
24152
+ fs58.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
23921
24153
  } catch (e) {
23922
24154
  if (e.code !== "EEXIST") throw e;
23923
- const holder = Number(fs56.readFileSync(lockPath, "utf8").trim());
24155
+ const holder = Number(fs58.readFileSync(lockPath, "utf8").trim());
23924
24156
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
23925
- fs56.writeFileSync(lockPath, String(process.pid));
24157
+ fs58.writeFileSync(lockPath, String(process.pid));
23926
24158
  }
23927
24159
  const release3 = () => {
23928
24160
  try {
23929
- if (fs56.existsSync(lockPath) && Number(fs56.readFileSync(lockPath, "utf8").trim()) === process.pid) {
23930
- fs56.unlinkSync(lockPath);
24161
+ if (fs58.existsSync(lockPath) && Number(fs58.readFileSync(lockPath, "utf8").trim()) === process.pid) {
24162
+ fs58.unlinkSync(lockPath);
23931
24163
  }
23932
24164
  } catch {
23933
24165
  }
@@ -23949,19 +24181,19 @@ function acquireDaemonLock(sessionId) {
23949
24181
  function acquireSingletonLock() {
23950
24182
  const lockPath = pairAutoLockPath();
23951
24183
  try {
23952
- fs56.mkdirSync(path60.dirname(lockPath), { recursive: true });
24184
+ fs58.mkdirSync(path62.dirname(lockPath), { recursive: true });
23953
24185
  try {
23954
- fs56.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
24186
+ fs58.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
23955
24187
  } catch (e) {
23956
24188
  if (e.code !== "EEXIST") throw e;
23957
- const holder = Number(fs56.readFileSync(lockPath, "utf8").trim());
24189
+ const holder = Number(fs58.readFileSync(lockPath, "utf8").trim());
23958
24190
  if (isLivePairAuto(holder)) return false;
23959
- fs56.writeFileSync(lockPath, String(process.pid));
24191
+ fs58.writeFileSync(lockPath, String(process.pid));
23960
24192
  }
23961
24193
  process.once("exit", () => {
23962
24194
  try {
23963
- if (fs56.existsSync(lockPath) && Number(fs56.readFileSync(lockPath, "utf8").trim()) === process.pid) {
23964
- fs56.unlinkSync(lockPath);
24195
+ if (fs58.existsSync(lockPath) && Number(fs58.readFileSync(lockPath, "utf8").trim()) === process.pid) {
24196
+ fs58.unlinkSync(lockPath);
23965
24197
  }
23966
24198
  } catch {
23967
24199
  }
@@ -24407,7 +24639,7 @@ var AgentService = class _AgentService {
24407
24639
  };
24408
24640
 
24409
24641
  // src/agents/acp/adapters.ts
24410
- var path62 = __toESM(require("path"));
24642
+ var path64 = __toESM(require("path"));
24411
24643
 
24412
24644
  // src/agents/acp/agent-binary.ts
24413
24645
  var import_fs4 = __toESM(require("fs"));
@@ -24583,11 +24815,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
24583
24815
 
24584
24816
  // src/agents/kimi/installer.ts
24585
24817
  var import_node_child_process26 = require("child_process");
24586
- var import_node_os8 = require("os");
24587
- var import_node_path7 = require("path");
24818
+ var import_node_os11 = require("os");
24819
+ var import_node_path9 = require("path");
24588
24820
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
24589
24821
  function kimiBinDir() {
24590
- return (0, import_node_path7.join)(process.env.KIMI_CODE_HOME || (0, import_node_path7.join)((0, import_node_os8.homedir)(), ".kimi-code"), "bin");
24822
+ return (0, import_node_path9.join)(process.env.KIMI_CODE_HOME || (0, import_node_path9.join)((0, import_node_os11.homedir)(), ".kimi-code"), "bin");
24591
24823
  }
24592
24824
  function kimiRuns() {
24593
24825
  const r = (0, import_node_child_process26.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -24650,13 +24882,13 @@ function resolveBin(pkgName, binName) {
24650
24882
  try {
24651
24883
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
24652
24884
  const manifest = require_(`${pkgName}/package.json`);
24653
- const pkgDir = path62.dirname(manifestPath);
24885
+ const pkgDir = path64.dirname(manifestPath);
24654
24886
  const bin = manifest.bin;
24655
24887
  if (!bin) return null;
24656
- if (typeof bin === "string") return path62.resolve(pkgDir, bin);
24888
+ if (typeof bin === "string") return path64.resolve(pkgDir, bin);
24657
24889
  const target = binName ?? Object.keys(bin)[0];
24658
24890
  if (!target || !bin[target]) return null;
24659
- return path62.resolve(pkgDir, bin[target]);
24891
+ return path64.resolve(pkgDir, bin[target]);
24660
24892
  } catch {
24661
24893
  return null;
24662
24894
  }
@@ -24791,9 +25023,9 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
24791
25023
  var import_node_crypto10 = require("crypto");
24792
25024
 
24793
25025
  // src/services/history.service.ts
24794
- var fs58 = __toESM(require("fs"));
24795
- var path63 = __toESM(require("path"));
24796
- var os47 = __toESM(require("os"));
25026
+ var fs60 = __toESM(require("fs"));
25027
+ var path65 = __toESM(require("path"));
25028
+ var os50 = __toESM(require("os"));
24797
25029
  var https7 = __toESM(require("https"));
24798
25030
  var http6 = __toESM(require("http"));
24799
25031
  var import_zod2 = require("zod");
@@ -24820,7 +25052,7 @@ function parseJsonl(filePath) {
24820
25052
  const messages = [];
24821
25053
  let raw;
24822
25054
  try {
24823
- raw = fs58.readFileSync(filePath, "utf8");
25055
+ raw = fs60.readFileSync(filePath, "utf8");
24824
25056
  } catch (err) {
24825
25057
  if (err.code !== "ENOENT") {
24826
25058
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -24961,7 +25193,7 @@ var HistoryService = class _HistoryService {
24961
25193
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
24962
25194
  }
24963
25195
  get projectDir() {
24964
- return this.runtime.resolveHistoryDir(this.cwd) ?? path63.join(os47.homedir(), ".claude", "projects", encodeCwd(this.cwd));
25196
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path65.join(os50.homedir(), ".claude", "projects", encodeCwd(this.cwd));
24965
25197
  }
24966
25198
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
24967
25199
  setCurrentConversationId(id) {
@@ -24973,7 +25205,7 @@ var HistoryService = class _HistoryService {
24973
25205
  /** Return the current message count in the active conversation. */
24974
25206
  getCurrentMessageCount() {
24975
25207
  if (!this.currentConversationId) return 0;
24976
- const filePath = path63.join(this.projectDir, `${this.currentConversationId}.jsonl`);
25208
+ const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
24977
25209
  return parseJsonl(filePath).length;
24978
25210
  }
24979
25211
  /**
@@ -24984,7 +25216,7 @@ var HistoryService = class _HistoryService {
24984
25216
  const deadline = Date.now() + timeoutMs;
24985
25217
  while (Date.now() < deadline) {
24986
25218
  if (!this.currentConversationId) return null;
24987
- const filePath = path63.join(this.projectDir, `${this.currentConversationId}.jsonl`);
25219
+ const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
24988
25220
  const messages = parseJsonl(filePath);
24989
25221
  if (messages.length > previousCount) {
24990
25222
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -25010,16 +25242,16 @@ var HistoryService = class _HistoryService {
25010
25242
  const dir = this.projectDir;
25011
25243
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
25012
25244
  try {
25013
- const files = fs58.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
25245
+ const files = fs60.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
25014
25246
  try {
25015
- const stat3 = fs58.statSync(path63.join(dir, e.name));
25247
+ const stat3 = fs60.statSync(path65.join(dir, e.name));
25016
25248
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
25017
25249
  } catch {
25018
25250
  return { name: e.name, mtime: 0, birthtime: 0 };
25019
25251
  }
25020
25252
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
25021
25253
  if (files.length > 0) {
25022
- this.currentConversationId = path63.basename(files[0].name, ".jsonl");
25254
+ this.currentConversationId = path65.basename(files[0].name, ".jsonl");
25023
25255
  }
25024
25256
  } catch {
25025
25257
  }
@@ -25053,13 +25285,13 @@ var HistoryService = class _HistoryService {
25053
25285
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
25054
25286
  let entries;
25055
25287
  try {
25056
- entries = fs58.readdirSync(dir, { withFileTypes: true });
25288
+ entries = fs60.readdirSync(dir, { withFileTypes: true });
25057
25289
  } catch {
25058
25290
  return null;
25059
25291
  }
25060
25292
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
25061
25293
  try {
25062
- const stat3 = fs58.statSync(path63.join(dir, e.name));
25294
+ const stat3 = fs60.statSync(path65.join(dir, e.name));
25063
25295
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
25064
25296
  } catch {
25065
25297
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -25068,12 +25300,12 @@ var HistoryService = class _HistoryService {
25068
25300
  if (files.length === 0) return null;
25069
25301
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
25070
25302
  if (!files.some((f) => f.name === targetFile)) return null;
25071
- return this.extractUsageFromFile(path63.join(dir, targetFile));
25303
+ return this.extractUsageFromFile(path65.join(dir, targetFile));
25072
25304
  }
25073
25305
  extractUsageFromFile(filePath) {
25074
25306
  let raw;
25075
25307
  try {
25076
- raw = fs58.readFileSync(filePath, "utf8");
25308
+ raw = fs60.readFileSync(filePath, "utf8");
25077
25309
  } catch {
25078
25310
  return null;
25079
25311
  }
@@ -25118,9 +25350,9 @@ var HistoryService = class _HistoryService {
25118
25350
  let totalCost = 0;
25119
25351
  let files;
25120
25352
  try {
25121
- files = fs58.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
25353
+ files = fs60.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
25122
25354
  try {
25123
- return fs58.statSync(path63.join(projectDir, f)).mtimeMs >= monthStartMs;
25355
+ return fs60.statSync(path65.join(projectDir, f)).mtimeMs >= monthStartMs;
25124
25356
  } catch {
25125
25357
  return false;
25126
25358
  }
@@ -25131,7 +25363,7 @@ var HistoryService = class _HistoryService {
25131
25363
  for (const file of files) {
25132
25364
  let raw;
25133
25365
  try {
25134
- raw = fs58.readFileSync(path63.join(projectDir, file), "utf8");
25366
+ raw = fs60.readFileSync(path65.join(projectDir, file), "utf8");
25135
25367
  } catch {
25136
25368
  continue;
25137
25369
  }
@@ -25210,7 +25442,7 @@ var HistoryService = class _HistoryService {
25210
25442
  if (this.runtime.resolveHistoryFile) {
25211
25443
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
25212
25444
  }
25213
- return path63.join(this.projectDir, `${sessionId}.jsonl`);
25445
+ return path65.join(this.projectDir, `${sessionId}.jsonl`);
25214
25446
  }
25215
25447
  /**
25216
25448
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -25244,7 +25476,7 @@ var HistoryService = class _HistoryService {
25244
25476
  };
25245
25477
  });
25246
25478
  }
25247
- return parseJsonl(path63.join(this.projectDir, `${sessionId}.jsonl`));
25479
+ return parseJsonl(path65.join(this.projectDir, `${sessionId}.jsonl`));
25248
25480
  }
25249
25481
  async loadConversation(sessionId) {
25250
25482
  const messages = this.readConversation(sessionId);
@@ -25312,7 +25544,7 @@ var HistoryService = class _HistoryService {
25312
25544
  if (!filePath) return false;
25313
25545
  let mtimeMs;
25314
25546
  try {
25315
- mtimeMs = fs58.statSync(filePath).mtimeMs;
25547
+ mtimeMs = fs60.statSync(filePath).mtimeMs;
25316
25548
  } catch {
25317
25549
  return false;
25318
25550
  }
@@ -25387,10 +25619,10 @@ var HistoryService = class _HistoryService {
25387
25619
 
25388
25620
  // src/agents/acp/client.ts
25389
25621
  var import_node_child_process27 = require("child_process");
25390
- var fs59 = __toESM(require("fs/promises"));
25622
+ var fs61 = __toESM(require("fs/promises"));
25391
25623
  var fsSync = __toESM(require("fs"));
25392
- var os48 = __toESM(require("os"));
25393
- var path64 = __toESM(require("path"));
25624
+ var os51 = __toESM(require("os"));
25625
+ var path66 = __toESM(require("path"));
25394
25626
  var import_node_stream = require("stream");
25395
25627
 
25396
25628
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -30175,7 +30407,7 @@ var AcpClient = class {
30175
30407
  },
30176
30408
  readTextFile: async (params) => {
30177
30409
  try {
30178
- const content = await fs59.readFile(params.path, "utf8");
30410
+ const content = await fs61.readFile(params.path, "utf8");
30179
30411
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
30180
30412
  } catch (err) {
30181
30413
  const code = err.code;
@@ -30195,7 +30427,7 @@ var AcpClient = class {
30195
30427
  },
30196
30428
  writeTextFile: async (params) => {
30197
30429
  try {
30198
- await fs59.writeFile(params.path, params.content, "utf8");
30430
+ await fs61.writeFile(params.path, params.content, "utf8");
30199
30431
  return {};
30200
30432
  } catch (err) {
30201
30433
  const code = err.code;
@@ -30255,29 +30487,29 @@ function applyLineRange(content, line, limit) {
30255
30487
  return { content: lines.slice(start2, end).join("\n") };
30256
30488
  }
30257
30489
  function knownAgentBinaryDirs() {
30258
- const home = os48.homedir();
30490
+ const home = os51.homedir();
30259
30491
  const out2 = [];
30260
30492
  out2.push("/tmp/codeam-node20/bin");
30261
30493
  for (const root of [
30262
30494
  "/usr/local/share/nvm/versions/node",
30263
- path64.join(home, ".nvm/versions/node")
30495
+ path66.join(home, ".nvm/versions/node")
30264
30496
  ]) {
30265
30497
  try {
30266
30498
  for (const child of fsSync.readdirSync(root)) {
30267
- out2.push(path64.join(root, child, "bin"));
30499
+ out2.push(path66.join(root, child, "bin"));
30268
30500
  }
30269
30501
  } catch {
30270
30502
  }
30271
30503
  }
30272
- out2.push(path64.join(home, ".volta/bin"));
30504
+ out2.push(path66.join(home, ".volta/bin"));
30273
30505
  out2.push("/usr/local/bin");
30274
30506
  out2.push("/usr/bin");
30275
- out2.push(path64.join(home, ".local/bin"));
30276
- out2.push(path64.join(home, "bin"));
30507
+ out2.push(path66.join(home, ".local/bin"));
30508
+ out2.push(path66.join(home, "bin"));
30277
30509
  if (process.platform === "win32") {
30278
30510
  const { LOCALAPPDATA, APPDATA } = process.env;
30279
- if (LOCALAPPDATA) out2.push(path64.join(LOCALAPPDATA, "cursor-agent"));
30280
- if (APPDATA) out2.push(path64.join(APPDATA, "npm"));
30511
+ if (LOCALAPPDATA) out2.push(path66.join(LOCALAPPDATA, "cursor-agent"));
30512
+ if (APPDATA) out2.push(path66.join(APPDATA, "npm"));
30281
30513
  }
30282
30514
  return out2.filter((p2) => {
30283
30515
  try {
@@ -30289,7 +30521,7 @@ function knownAgentBinaryDirs() {
30289
30521
  }
30290
30522
  function expandPathForAgentBinaries(existingPath) {
30291
30523
  const existing = new Set(
30292
- existingPath.split(path64.delimiter).filter((p2) => p2.length > 0)
30524
+ existingPath.split(path66.delimiter).filter((p2) => p2.length > 0)
30293
30525
  );
30294
30526
  const additions = [];
30295
30527
  for (const dir of knownAgentBinaryDirs()) {
@@ -30299,7 +30531,7 @@ function expandPathForAgentBinaries(existingPath) {
30299
30531
  }
30300
30532
  }
30301
30533
  if (additions.length === 0) return existingPath;
30302
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path64.delimiter);
30534
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path66.delimiter);
30303
30535
  }
30304
30536
 
30305
30537
  // src/agents/acp/headroom-budget-proxy.ts
@@ -30781,15 +31013,15 @@ function commonPrefixLength(a, b) {
30781
31013
 
30782
31014
  // src/agents/acp/onboarding.ts
30783
31015
  var import_child_process27 = require("child_process");
30784
- var fs60 = __toESM(require("fs"));
30785
- var os49 = __toESM(require("os"));
30786
- var path65 = __toESM(require("path"));
31016
+ var fs62 = __toESM(require("fs"));
31017
+ var os52 = __toESM(require("os"));
31018
+ var path67 = __toESM(require("path"));
30787
31019
  var _onboardingSeam = {
30788
- markerPath: (sessionId) => path65.join(os49.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
30789
- exists: (p2) => fs60.existsSync(p2),
31020
+ markerPath: (sessionId) => path67.join(os52.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
31021
+ exists: (p2) => fs62.existsSync(p2),
30790
31022
  write: (p2) => {
30791
- fs60.mkdirSync(path65.dirname(p2), { recursive: true });
30792
- fs60.writeFileSync(p2, "");
31023
+ fs62.mkdirSync(path67.dirname(p2), { recursive: true });
31024
+ fs62.writeFileSync(p2, "");
30793
31025
  },
30794
31026
  disabled: () => {
30795
31027
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -30826,7 +31058,7 @@ function resolveRepoName(cwd) {
30826
31058
  if (name) return name;
30827
31059
  }
30828
31060
  }
30829
- const base = path65.basename(cwd || "");
31061
+ const base = path67.basename(cwd || "");
30830
31062
  if (base && !isUuid(base)) return base;
30831
31063
  return "this project";
30832
31064
  }
@@ -31078,13 +31310,13 @@ var import_crypto5 = require("crypto");
31078
31310
 
31079
31311
  // src/services/turn-files/git-changeset.ts
31080
31312
  var import_child_process28 = require("child_process");
31081
- var fs62 = __toESM(require("fs/promises"));
31082
- var path67 = __toESM(require("path"));
31313
+ var fs64 = __toESM(require("fs/promises"));
31314
+ var path69 = __toESM(require("path"));
31083
31315
 
31084
31316
  // src/services/turn-files/review-ignore.ts
31085
31317
  var import_ignore2 = __toESM(require("ignore"));
31086
- var fs61 = __toESM(require("fs"));
31087
- var path66 = __toESM(require("path"));
31318
+ var fs63 = __toESM(require("fs"));
31319
+ var path68 = __toESM(require("path"));
31088
31320
  var CURATED_REVIEW_IGNORE = [
31089
31321
  // Google Cloud SDK (the incident) — installs a huge python tree.
31090
31322
  "google-cloud-sdk/",
@@ -31123,7 +31355,7 @@ var CURATED_REVIEW_IGNORE = [
31123
31355
  function makeReviewIgnore(repoRoot) {
31124
31356
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
31125
31357
  try {
31126
- const custom = fs61.readFileSync(path66.join(repoRoot, ".codeam", "reviewignore"), "utf8");
31358
+ const custom = fs63.readFileSync(path68.join(repoRoot, ".codeam", "reviewignore"), "utf8");
31127
31359
  ig.add(custom);
31128
31360
  } catch {
31129
31361
  }
@@ -31168,7 +31400,7 @@ async function collectRepoChangeset(opts) {
31168
31400
  let stats;
31169
31401
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
31170
31402
  const lineCount = await readUntrackedLineCount(
31171
- path67.join(opts.repoRoot, row.filePath)
31403
+ path69.join(opts.repoRoot, row.filePath)
31172
31404
  );
31173
31405
  stats = { added: lineCount, removed: 0 };
31174
31406
  } else {
@@ -31199,7 +31431,7 @@ function readUntrackedLineCount(absPath) {
31199
31431
  }
31200
31432
  async function defaultReadUntrackedLineCount(absPath) {
31201
31433
  try {
31202
- const content = await fs62.readFile(absPath, "utf8");
31434
+ const content = await fs64.readFile(absPath, "utf8");
31203
31435
  let count = 0;
31204
31436
  let pos = -1;
31205
31437
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -31291,7 +31523,7 @@ function defaultRunGit(cwd, args2) {
31291
31523
  });
31292
31524
  }
31293
31525
  async function discoverRepos(workingDir, maxDepth = 4) {
31294
- const fs67 = await import("fs/promises");
31526
+ const fs69 = await import("fs/promises");
31295
31527
  const out2 = [];
31296
31528
  await walk(workingDir, 0);
31297
31529
  return out2;
@@ -31299,7 +31531,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
31299
31531
  if (depth > maxDepth) return;
31300
31532
  let entries = [];
31301
31533
  try {
31302
- const dirents = await fs67.readdir(dir, { withFileTypes: true });
31534
+ const dirents = await fs69.readdir(dir, { withFileTypes: true });
31303
31535
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
31304
31536
  } catch {
31305
31537
  return;
@@ -31310,8 +31542,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
31310
31542
  if (hasGit) {
31311
31543
  out2.push({
31312
31544
  repoRoot: dir,
31313
- repoPath: path67.relative(workingDir, dir),
31314
- repoName: path67.basename(dir)
31545
+ repoPath: path69.relative(workingDir, dir),
31546
+ repoName: path69.basename(dir)
31315
31547
  });
31316
31548
  return;
31317
31549
  }
@@ -31319,14 +31551,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
31319
31551
  if (!entry.isDirectory) continue;
31320
31552
  if (entry.name === "node_modules") continue;
31321
31553
  if (entry.name === "dist" || entry.name === "build") continue;
31322
- await walk(path67.join(dir, entry.name), depth + 1);
31554
+ await walk(path69.join(dir, entry.name), depth + 1);
31323
31555
  }
31324
31556
  }
31325
31557
  }
31326
31558
 
31327
31559
  // src/services/turn-files/files-outbox.ts
31328
- var fs63 = __toESM(require("fs/promises"));
31329
- var path68 = __toESM(require("path"));
31560
+ var fs65 = __toESM(require("fs/promises"));
31561
+ var path70 = __toESM(require("path"));
31330
31562
  var import_os11 = require("os");
31331
31563
  var HOME_OUTBOX_DIR = ".codeam/outbox";
31332
31564
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -31359,16 +31591,16 @@ var FilesOutbox = class {
31359
31591
  backoffIndex = 0;
31360
31592
  stopped = false;
31361
31593
  constructor(opts) {
31362
- const base = opts.baseDir ?? path68.join(homeDir(), HOME_OUTBOX_DIR);
31363
- this.filePath = path68.join(base, `${opts.sessionId}.jsonl`);
31594
+ const base = opts.baseDir ?? path70.join(homeDir(), HOME_OUTBOX_DIR);
31595
+ this.filePath = path70.join(base, `${opts.sessionId}.jsonl`);
31364
31596
  this.post = opts.post;
31365
31597
  this.autoSchedule = opts.autoSchedule !== false;
31366
31598
  }
31367
31599
  /** Persist the entry to disk and trigger a flush. Returns once the
31368
31600
  * line is durable on disk (not once the POST succeeds). */
31369
31601
  async enqueue(entry) {
31370
- await fs63.mkdir(path68.dirname(this.filePath), { recursive: true });
31371
- await fs63.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
31602
+ await fs65.mkdir(path70.dirname(this.filePath), { recursive: true });
31603
+ await fs65.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
31372
31604
  this.backoffIndex = 0;
31373
31605
  if (this.autoSchedule) this.scheduleFlush(0);
31374
31606
  }
@@ -31459,7 +31691,7 @@ var FilesOutbox = class {
31459
31691
  async readAll() {
31460
31692
  let raw = "";
31461
31693
  try {
31462
- raw = await fs63.readFile(this.filePath, "utf8");
31694
+ raw = await fs65.readFile(this.filePath, "utf8");
31463
31695
  } catch {
31464
31696
  return [];
31465
31697
  }
@@ -31483,12 +31715,12 @@ var FilesOutbox = class {
31483
31715
  async rewrite(entries) {
31484
31716
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
31485
31717
  if (entries.length === 0) {
31486
- await fs63.unlink(this.filePath).catch(() => void 0);
31718
+ await fs65.unlink(this.filePath).catch(() => void 0);
31487
31719
  return;
31488
31720
  }
31489
31721
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
31490
- await fs63.writeFile(tmpPath, payload, "utf8");
31491
- await fs63.rename(tmpPath, this.filePath);
31722
+ await fs65.writeFile(tmpPath, payload, "utf8");
31723
+ await fs65.rename(tmpPath, this.filePath);
31492
31724
  }
31493
31725
  };
31494
31726
  function applyJitter(ms) {
@@ -32237,6 +32469,13 @@ async function setModeH(ctx) {
32237
32469
  }
32238
32470
  return;
32239
32471
  }
32472
+ async function skillsConfigureH2(ctx) {
32473
+ const { cmd, relay } = ctx;
32474
+ const payload = cmd.payload;
32475
+ const res = configureSkill(payload?.action ?? "list", payload?.skillId);
32476
+ await relay.sendResult(cmd.id, res.ok ? "completed" : "failed", res);
32477
+ return;
32478
+ }
32240
32479
  async function ackEmptyH(ctx) {
32241
32480
  const { cmd, relay } = ctx;
32242
32481
  await relay.sendResult(cmd.id, "completed", {});
@@ -32504,7 +32743,8 @@ var ACP_COMMAND_HANDLERS = {
32504
32743
  request_preview_detect: previewH,
32505
32744
  preview_start: previewH,
32506
32745
  preview_stop: previewH,
32507
- save_preview_config: previewH
32746
+ save_preview_config: previewH,
32747
+ skills_configure: skillsConfigureH2
32508
32748
  };
32509
32749
  async function dispatchAcpCommand(ctx) {
32510
32750
  const handler = ACP_COMMAND_HANDLERS[ctx.cmd.type];
@@ -34430,6 +34670,26 @@ function buildMcpServersForStart(ctx) {
34430
34670
  return servers;
34431
34671
  }
34432
34672
 
34673
+ // src/skills/provision.ts
34674
+ var import_node_os12 = __toESM(require("os"));
34675
+ function provisionSkillsForStart(home = import_node_os12.default.homedir()) {
34676
+ const materialized = [];
34677
+ try {
34678
+ const manifest = readSkillsManifest();
34679
+ if (!manifest || manifest.skills.length === 0) return { materialized };
34680
+ for (const entry of manifest.skills) {
34681
+ if (!isSkillId(entry.id)) continue;
34682
+ if (materializeSkill(entry.id, home)) materialized.push(entry.id);
34683
+ }
34684
+ if (materialized.length) {
34685
+ log.info("skills", `materialized ${materialized.length} skill(s): ${materialized.join(", ")}`);
34686
+ }
34687
+ } catch (err) {
34688
+ log.warn("skills", `provisionSkillsForStart failed (best-effort): ${err instanceof Error ? err.message : String(err)}`);
34689
+ }
34690
+ return { materialized };
34691
+ }
34692
+
34433
34693
  // src/baton/baton-controller.ts
34434
34694
  var BatonController = class {
34435
34695
  constructor(deps) {
@@ -34777,7 +35037,7 @@ var AcpDriver = class {
34777
35037
  };
34778
35038
 
34779
35039
  // src/baton/transcript-mirror.ts
34780
- var fs64 = __toESM(require("fs"));
35040
+ var fs66 = __toESM(require("fs"));
34781
35041
  var TranscriptMirror = class {
34782
35042
  constructor(deps) {
34783
35043
  this.deps = deps;
@@ -34844,7 +35104,7 @@ var TranscriptMirror = class {
34844
35104
  }
34845
35105
  };
34846
35106
  function defaultWatch(file, onChange) {
34847
- const w3 = fs64.watch(file, { persistent: false }, () => onChange());
35107
+ const w3 = fs66.watch(file, { persistent: false }, () => onChange());
34848
35108
  return () => w3.close();
34849
35109
  }
34850
35110
 
@@ -35106,16 +35366,16 @@ function toEpochMs(ts) {
35106
35366
  }
35107
35367
 
35108
35368
  // src/agents/claude/onboarding.ts
35109
- var fs65 = __toESM(require("fs"));
35110
- var os50 = __toESM(require("os"));
35111
- var path69 = __toESM(require("path"));
35369
+ var fs67 = __toESM(require("fs"));
35370
+ var os54 = __toESM(require("os"));
35371
+ var path71 = __toESM(require("path"));
35112
35372
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
35113
35373
  function ensureClaudeOnboarded(cwd) {
35114
35374
  try {
35115
- const file = path69.join(os50.homedir(), ".claude.json");
35375
+ const file = path71.join(os54.homedir(), ".claude.json");
35116
35376
  let config = {};
35117
35377
  try {
35118
- config = JSON.parse(fs65.readFileSync(file, "utf8"));
35378
+ config = JSON.parse(fs67.readFileSync(file, "utf8"));
35119
35379
  } catch {
35120
35380
  }
35121
35381
  let changed = false;
@@ -35140,8 +35400,8 @@ function ensureClaudeOnboarded(cwd) {
35140
35400
  }
35141
35401
  }
35142
35402
  if (!changed) return;
35143
- fs65.mkdirSync(path69.dirname(file), { recursive: true });
35144
- fs65.writeFileSync(file, JSON.stringify(config, null, 2));
35403
+ fs67.mkdirSync(path71.dirname(file), { recursive: true });
35404
+ fs67.writeFileSync(file, JSON.stringify(config, null, 2));
35145
35405
  log.info(
35146
35406
  "claude",
35147
35407
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -35252,6 +35512,7 @@ async function start(requestedAgent) {
35252
35512
  pluginAuthToken: session.pluginAuthToken ?? void 0,
35253
35513
  pollSecret: session.pollSecret
35254
35514
  });
35515
+ provisionSkillsForStart();
35255
35516
  const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
35256
35517
  if (process.env.CODESPACES === "true") {
35257
35518
  const GATE_TIMEOUT_MS = 24e4;
@@ -35857,7 +36118,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
35857
36118
  var import_child_process29 = require("child_process");
35858
36119
  var import_util4 = require("util");
35859
36120
  var import_picocolors9 = __toESM(require("picocolors"));
35860
- var path70 = __toESM(require("path"));
36121
+ var path72 = __toESM(require("path"));
35861
36122
  var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
35862
36123
  var MAX_BUFFER = 8 * 1024 * 1024;
35863
36124
  function resetStdinForChild() {
@@ -36346,7 +36607,7 @@ var GitHubCodespacesProvider = class {
36346
36607
  });
36347
36608
  }
36348
36609
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
36349
- const remoteDir = path70.posix.dirname(remotePath);
36610
+ const remoteDir = path72.posix.dirname(remotePath);
36350
36611
  const parts = [
36351
36612
  `mkdir -p ${shellQuote(remoteDir)}`,
36352
36613
  `cat > ${shellQuote(remotePath)}`
@@ -36416,7 +36677,7 @@ function shellQuote(s) {
36416
36677
  // src/services/providers/gitpod.ts
36417
36678
  var import_child_process30 = require("child_process");
36418
36679
  var import_util5 = require("util");
36419
- var path71 = __toESM(require("path"));
36680
+ var path73 = __toESM(require("path"));
36420
36681
  var import_picocolors10 = __toESM(require("picocolors"));
36421
36682
  var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
36422
36683
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -36656,7 +36917,7 @@ var GitpodProvider = class {
36656
36917
  });
36657
36918
  }
36658
36919
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
36659
- const remoteDir = path71.posix.dirname(remotePath);
36920
+ const remoteDir = path73.posix.dirname(remotePath);
36660
36921
  const parts = [
36661
36922
  `mkdir -p ${shellQuote2(remoteDir)}`,
36662
36923
  `cat > ${shellQuote2(remotePath)}`
@@ -36692,7 +36953,7 @@ function shellQuote2(s) {
36692
36953
  // src/services/providers/gitlab-workspaces.ts
36693
36954
  var import_child_process31 = require("child_process");
36694
36955
  var import_util6 = require("util");
36695
- var path72 = __toESM(require("path"));
36956
+ var path74 = __toESM(require("path"));
36696
36957
  var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
36697
36958
  var MAX_BUFFER3 = 8 * 1024 * 1024;
36698
36959
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -36952,7 +37213,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
36952
37213
  }
36953
37214
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
36954
37215
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
36955
- const remoteDir = path72.posix.dirname(remotePath);
37216
+ const remoteDir = path74.posix.dirname(remotePath);
36956
37217
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
36957
37218
  if (options.mode != null) {
36958
37219
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -37020,7 +37281,7 @@ function shellQuote3(s) {
37020
37281
  // src/services/providers/railway.ts
37021
37282
  var import_child_process32 = require("child_process");
37022
37283
  var import_util7 = require("util");
37023
- var path73 = __toESM(require("path"));
37284
+ var path75 = __toESM(require("path"));
37024
37285
  var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
37025
37286
  var MAX_BUFFER4 = 8 * 1024 * 1024;
37026
37287
  function resetStdinForChild4() {
@@ -37256,7 +37517,7 @@ var RailwayProvider = class {
37256
37517
  if (!projectId || !serviceId) {
37257
37518
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
37258
37519
  }
37259
- const remoteDir = path73.posix.dirname(remotePath);
37520
+ const remoteDir = path75.posix.dirname(remotePath);
37260
37521
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
37261
37522
  if (options.mode != null) {
37262
37523
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -37902,8 +38163,8 @@ async function invite() {
37902
38163
  var import_node_dns = require("dns");
37903
38164
  var import_node_util5 = require("util");
37904
38165
  var import_node_crypto12 = require("crypto");
37905
- var fs66 = __toESM(require("fs"));
37906
- var path74 = __toESM(require("path"));
38166
+ var fs68 = __toESM(require("fs"));
38167
+ var path76 = __toESM(require("path"));
37907
38168
  var import_picocolors14 = __toESM(require("picocolors"));
37908
38169
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
37909
38170
  async function checkDns(apiBase2) {
@@ -37959,13 +38220,13 @@ async function checkHealth(apiBase2) {
37959
38220
  }
37960
38221
  }
37961
38222
  function checkConfigDir() {
37962
- const dir = path74.join(require("os").homedir(), ".codeam");
38223
+ const dir = path76.join(require("os").homedir(), ".codeam");
37963
38224
  try {
37964
- fs66.mkdirSync(dir, { recursive: true, mode: 448 });
37965
- const probe = path74.join(dir, ".doctor-probe");
37966
- fs66.writeFileSync(probe, "ok", { mode: 384 });
37967
- const read2 = fs66.readFileSync(probe, "utf8");
37968
- fs66.unlinkSync(probe);
38225
+ fs68.mkdirSync(dir, { recursive: true, mode: 448 });
38226
+ const probe = path76.join(dir, ".doctor-probe");
38227
+ fs68.writeFileSync(probe, "ok", { mode: 384 });
38228
+ const read2 = fs68.readFileSync(probe, "utf8");
38229
+ fs68.unlinkSync(probe);
37969
38230
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
37970
38231
  return {
37971
38232
  id: "config-dir",
@@ -38005,9 +38266,9 @@ function checkSessions() {
38005
38266
  }
38006
38267
  }
38007
38268
  function checkAgentBinaries() {
38008
- const os53 = createOsStrategy();
38269
+ const os57 = createOsStrategy();
38009
38270
  return getEnabledAgents().map((meta) => {
38010
- const found = os53.findInPath(meta.binaryName);
38271
+ const found = os57.findInPath(meta.binaryName);
38011
38272
  return {
38012
38273
  id: `agent-${meta.id}`,
38013
38274
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -38029,7 +38290,7 @@ function checkNodePty() {
38029
38290
  detail: "not required on this platform"
38030
38291
  };
38031
38292
  }
38032
- const vendoredPath = path74.join(__dirname, "vendor", "node-pty");
38293
+ const vendoredPath = path76.join(__dirname, "vendor", "node-pty");
38033
38294
  for (const target of [vendoredPath, "node-pty"]) {
38034
38295
  try {
38035
38296
  require(target);
@@ -38071,7 +38332,7 @@ function checkChokidar() {
38071
38332
  }
38072
38333
  async function doctor(args2 = []) {
38073
38334
  const json = args2.includes("--json");
38074
- const cliVersion = true ? "2.61.22" : "0.0.0-dev";
38335
+ const cliVersion = true ? "2.61.23" : "0.0.0-dev";
38075
38336
  const apiBase2 = resolveApiBaseUrl();
38076
38337
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
38077
38338
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -38269,9 +38530,9 @@ async function completion(args2) {
38269
38530
 
38270
38531
  // src/integrations/mcp-run.ts
38271
38532
  var import_node_child_process29 = require("child_process");
38272
- var import_node_fs9 = require("fs");
38273
- var import_node_os9 = __toESM(require("os"));
38274
- var import_node_path8 = __toESM(require("path"));
38533
+ var import_node_fs11 = require("fs");
38534
+ var import_node_os13 = __toESM(require("os"));
38535
+ var import_node_path10 = __toESM(require("path"));
38275
38536
 
38276
38537
  // src/integrations/token-client.ts
38277
38538
  var REFRESH_AHEAD_MS = 5 * 60 * 1e3;
@@ -38493,13 +38754,13 @@ function commandExists(command2) {
38493
38754
  }
38494
38755
  function localBinCandidates(command2) {
38495
38756
  return [
38496
- import_node_path8.default.join(import_node_os9.default.homedir(), ".local", "bin", command2),
38497
- import_node_path8.default.join(import_node_os9.default.homedir(), ".cargo", "bin", command2)
38757
+ import_node_path10.default.join(import_node_os13.default.homedir(), ".local", "bin", command2),
38758
+ import_node_path10.default.join(import_node_os13.default.homedir(), ".cargo", "bin", command2)
38498
38759
  ];
38499
38760
  }
38500
38761
  function resolveLauncherPath(command2, deps = {
38501
38762
  commandExists,
38502
- existsSync: import_node_fs9.existsSync
38763
+ existsSync: import_node_fs11.existsSync
38503
38764
  }) {
38504
38765
  if (deps.commandExists(command2)) return command2;
38505
38766
  for (const candidate of localBinCandidates(command2)) {
@@ -38582,7 +38843,7 @@ async function mcpRun(args2) {
38582
38843
  // src/commands/version.ts
38583
38844
  var import_picocolors15 = __toESM(require("picocolors"));
38584
38845
  function version2() {
38585
- const v = true ? "2.61.22" : "unknown";
38846
+ const v = true ? "2.61.23" : "unknown";
38586
38847
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
38587
38848
  }
38588
38849
 
@@ -38731,10 +38992,10 @@ var EXIT_CODE_NAMES = {
38731
38992
  };
38732
38993
 
38733
38994
  // src/index.ts
38734
- var os52 = __toESM(require("os"));
38995
+ var os56 = __toESM(require("os"));
38735
38996
  if (!process.env.HOME) {
38736
38997
  try {
38737
- const home = os52.homedir();
38998
+ const home = os56.homedir();
38738
38999
  if (home) process.env.HOME = home;
38739
39000
  } catch {
38740
39001
  }