@cleocode/adapters 2026.10.3 → 2026.10.4

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.
package/dist/index.js CHANGED
@@ -18088,8 +18088,15 @@ var init_nexus_cloud = __esm({
18088
18088
  nexusCloudProjectListItemSchema = z26.object({
18089
18089
  ...projectFields,
18090
18090
  role: z26.string(),
18091
+ /**
18092
+ * The project name sealed with the project data key (`Project.encryptedName`), base64;
18093
+ * only a holder of the account key can open it (T13102).
18094
+ */
18095
+ encryptedName: z26.string().nullable().optional(),
18091
18096
  streamId: z26.string().optional(),
18092
18097
  headSeq: z26.number().int().nonnegative().nullable().optional(),
18098
+ /** The stream's head snapshot; null when nothing was ever pushed (T13102: restorable or not). */
18099
+ headCheckpointId: z26.string().nullable().optional(),
18093
18100
  openConflicts: z26.number().int().nonnegative().optional(),
18094
18101
  replicas: z26.array(nexusCloudReplicaSchema).default([]),
18095
18102
  devices: nexusCloudDeviceCountsSchema.optional(),
@@ -18235,6 +18242,13 @@ var init_nexus_cloud = __esm({
18235
18242
  }
18236
18243
  });
18237
18244
 
18245
+ // packages/contracts/src/nexus-first-run.ts
18246
+ var init_nexus_first_run = __esm({
18247
+ "packages/contracts/src/nexus-first-run.ts"() {
18248
+ "use strict";
18249
+ }
18250
+ });
18251
+
18238
18252
  // packages/contracts/src/nexus-vault.ts
18239
18253
  import { z as z27 } from "zod";
18240
18254
  var isoTime2, uuid, nexusUserKeysSchema, nexusProjectKeysSchema, nexusLeaseSchema, nexusLeaseAcquireSchema, nexusStreamHeadSchema, nexusActivityEventSchema, nexusActivityPageSchema;
@@ -18380,6 +18394,7 @@ var init_src = __esm({
18380
18394
  init_decide_sites();
18381
18395
  init_nexus_account();
18382
18396
  init_nexus_cloud();
18397
+ init_nexus_first_run();
18383
18398
  init_nexus_vault();
18384
18399
  init_sync_schema();
18385
18400
  init_task_id();
@@ -44960,6 +44975,7 @@ import {
44960
44975
  readFileSync as readFileSync4,
44961
44976
  realpathSync,
44962
44977
  rmSync,
44978
+ statSync,
44963
44979
  writeFileSync as writeFileSync2
44964
44980
  } from "node:fs";
44965
44981
  import { homedir as homedir4, tmpdir } from "node:os";
@@ -44972,6 +44988,25 @@ function canonical(path) {
44972
44988
  return resolve2(path);
44973
44989
  }
44974
44990
  }
44991
+ function nonDirectoryAncestor(dir) {
44992
+ let cur = resolve2(dir);
44993
+ for (; ; ) {
44994
+ try {
44995
+ return statSync(cur).isDirectory() ? null : cur;
44996
+ } catch (err) {
44997
+ const code = err.code;
44998
+ if (code !== "ENOENT" && code !== "ENOTDIR") return null;
44999
+ }
45000
+ const parent = dirname2(cur);
45001
+ if (parent === cur) return null;
45002
+ cur = parent;
45003
+ }
45004
+ }
45005
+ function ensureParentDir(target) {
45006
+ const blocked = nonDirectoryAncestor(dirname2(target));
45007
+ if (blocked !== null) throw new HeavyHookPathBlockedError(blocked, target);
45008
+ mkdirSync(dirname2(target), { recursive: true });
45009
+ }
44975
45010
  function isUserHomeDir(projectDir, home = homedir4()) {
44976
45011
  return canonical(projectDir) === canonical(home);
44977
45012
  }
@@ -45083,7 +45118,7 @@ async function syncJsonHeavyCommandHook(configPath, provider, mode) {
45083
45118
  });
45084
45119
  return removed ? "removed" : "unchanged";
45085
45120
  }
45086
- mkdirSync(dirname2(configPath), { recursive: true });
45121
+ ensureParentDir(configPath);
45087
45122
  clearOlderCleoMarkers();
45088
45123
  let result = "unchanged";
45089
45124
  await updateJsonConfigFile2(configPath, (config2) => {
@@ -45120,18 +45155,19 @@ function excludeFile(projectDir) {
45120
45155
  if (path === null || path === "") return null;
45121
45156
  return isAbsolute(path) ? path : join6(projectDir, path);
45122
45157
  }
45123
- function excludeLine(projectDir) {
45158
+ function excludeLine(projectDir, relPath) {
45124
45159
  const prefix = gitOutput(projectDir, ["rev-parse", "--show-prefix"]) ?? "";
45125
- return `/${prefix}${CLAUDE_LOCAL_SETTINGS}`;
45160
+ return `/${prefix}${relPath}`;
45126
45161
  }
45127
- function excludeLocalSettingsFromGit(projectDir) {
45162
+ function excludeHookFileFromGit(projectDir, relPath, marker16 = HOOK_FILE_EXCLUDE_MARKER) {
45128
45163
  const exclude = excludeFile(projectDir);
45129
45164
  if (exclude === null) return false;
45130
- if (gitOutput(projectDir, ["check-ignore", CLAUDE_LOCAL_SETTINGS]) !== null) return false;
45131
- const line = excludeLine(projectDir);
45165
+ if (gitOutput(projectDir, ["check-ignore", relPath]) !== null) return false;
45166
+ if (gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) !== null) return false;
45167
+ const line = excludeLine(projectDir, relPath);
45132
45168
  const text = existsSync5(exclude) ? readFileSync4(exclude, "utf-8") : "";
45133
45169
  if (text.split("\n").includes(line)) return false;
45134
- const block = `${LOCAL_SETTINGS_EXCLUDE_MARKER}
45170
+ const block = `${marker16}
45135
45171
  ${line}
45136
45172
  `;
45137
45173
  mkdirSync(dirname2(exclude), { recursive: true });
@@ -45139,16 +45175,150 @@ ${line}
45139
45175
  ${block}`);
45140
45176
  return true;
45141
45177
  }
45142
- function unexcludeLocalSettingsFromGit(projectDir) {
45178
+ function unexcludeHookFileFromGit(projectDir, relPath) {
45143
45179
  const exclude = excludeFile(projectDir);
45144
45180
  if (exclude === null || !existsSync5(exclude)) return false;
45145
45181
  const lines = readFileSync4(exclude, "utf-8").split("\n");
45146
- const at = lines.indexOf(excludeLine(projectDir));
45147
- if (at < 1 || lines[at - 1] !== LOCAL_SETTINGS_EXCLUDE_MARKER) return false;
45182
+ const at = lines.indexOf(excludeLine(projectDir, relPath));
45183
+ const above = lines[at - 1];
45184
+ if (at < 1 || above !== LOCAL_SETTINGS_EXCLUDE_MARKER && above !== HOOK_FILE_EXCLUDE_MARKER) {
45185
+ return false;
45186
+ }
45148
45187
  lines.splice(at - 1, 2);
45149
45188
  writeFileSync2(exclude, lines.join("\n"));
45150
45189
  return true;
45151
45190
  }
45191
+ function hookFileVisibleToGit(projectDir, relPath) {
45192
+ if (gitOutput(projectDir, ["rev-parse", "--is-inside-work-tree"]) !== "true") return false;
45193
+ if (gitOutput(projectDir, ["check-ignore", relPath]) !== null) return false;
45194
+ return gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) === null;
45195
+ }
45196
+ function excludeLocalSettingsFromGit(projectDir) {
45197
+ return excludeHookFileFromGit(projectDir, CLAUDE_LOCAL_SETTINGS, LOCAL_SETTINGS_EXCLUDE_MARKER);
45198
+ }
45199
+ function unexcludeLocalSettingsFromGit(projectDir) {
45200
+ return unexcludeHookFileFromGit(projectDir, CLAUDE_LOCAL_SETTINGS);
45201
+ }
45202
+ function cleoCreatedConfig(config2) {
45203
+ if (!isPlainObject2(config2) || Object.keys(config2).some((k) => k !== "hooks")) return false;
45204
+ if (!isPlainObject2(config2.hooks)) return false;
45205
+ let mine = 0;
45206
+ for (const groups of Object.values(config2.hooks)) {
45207
+ if (!Array.isArray(groups)) return false;
45208
+ for (const group of groups) {
45209
+ if (!isPlainObject2(group) || !Array.isArray(group.hooks)) return false;
45210
+ for (const hook of group.hooks) {
45211
+ if (!isPlainObject2(hook) || typeof hook.command !== "string" || !hook.command.includes(CLEO_HOOK_MARKER)) {
45212
+ return false;
45213
+ }
45214
+ mine++;
45215
+ }
45216
+ }
45217
+ }
45218
+ return mine > 0;
45219
+ }
45220
+ function codexHooksSharedReason(projectDir, checkGit = true) {
45221
+ const file2 = join6(projectDir, CODEX_HOOKS_FILE);
45222
+ if (checkGit && gitOutput(projectDir, ["ls-files", "--error-unmatch", CODEX_HOOKS_FILE]) !== null) {
45223
+ return "is tracked by git (a shared team config)";
45224
+ }
45225
+ if (!existsSync5(file2)) return null;
45226
+ let config2;
45227
+ try {
45228
+ config2 = JSON.parse(readFileSync4(file2, "utf-8"));
45229
+ } catch {
45230
+ return "is the project's own Codex hook config (empty or not valid JSON)";
45231
+ }
45232
+ return cleoCreatedConfig(config2) ? null : "is the project's own Codex hook config";
45233
+ }
45234
+ function committedCodexHookHoldsCleo(projectDir) {
45235
+ const committed = gitOutput(projectDir, ["show", `HEAD:./${CODEX_HOOKS_FILE}`]);
45236
+ if (committed === null || committed === "") return false;
45237
+ try {
45238
+ const config2 = JSON.parse(committed);
45239
+ if (!isPlainObject2(config2)) return false;
45240
+ const groups = isPlainObject2(config2.hooks) ? config2.hooks.PreToolUse : void 0;
45241
+ return Array.isArray(groups) && groups.some(
45242
+ (g) => isPlainObject2(g) && Array.isArray(g.hooks) && g.hooks.some(isHeavyHookObject)
45243
+ );
45244
+ } catch {
45245
+ return false;
45246
+ }
45247
+ }
45248
+ function jsonEqual(a, b) {
45249
+ if (Array.isArray(a) || Array.isArray(b)) {
45250
+ return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => jsonEqual(v, b[i]));
45251
+ }
45252
+ if (isPlainObject2(a) && isPlainObject2(b)) {
45253
+ const keys = Object.keys(a);
45254
+ return keys.length === Object.keys(b).length && keys.every((k) => Object.hasOwn(b, k) && jsonEqual(a[k], b[k]));
45255
+ }
45256
+ return a === b;
45257
+ }
45258
+ function restoreCommittedCodexHooks(projectDir) {
45259
+ if (gitOutput(projectDir, ["ls-files", "--error-unmatch", CODEX_HOOKS_FILE]) === null)
45260
+ return false;
45261
+ const file2 = join6(projectDir, CODEX_HOOKS_FILE);
45262
+ let committed;
45263
+ let working;
45264
+ try {
45265
+ committed = execFileSync("git", ["-C", projectDir, "show", `HEAD:./${CODEX_HOOKS_FILE}`], {
45266
+ encoding: "utf-8",
45267
+ stdio: ["ignore", "pipe", "ignore"],
45268
+ timeout: 5e3
45269
+ });
45270
+ working = JSON.parse(readFileSync4(file2, "utf-8"));
45271
+ } catch {
45272
+ return false;
45273
+ }
45274
+ if (!isPlainObject2(working)) return false;
45275
+ const hooks = hookMap(working);
45276
+ if (!placeHeavyHook(hooks, null).changed) return false;
45277
+ try {
45278
+ if (!jsonEqual(working, JSON.parse(committed))) return false;
45279
+ } catch {
45280
+ return false;
45281
+ }
45282
+ writeFileSync2(file2, committed);
45283
+ return true;
45284
+ }
45285
+ function excludedByCleo(projectDir, relPath) {
45286
+ const exclude = excludeFile(projectDir);
45287
+ if (exclude === null || !existsSync5(exclude)) return false;
45288
+ const lines = readFileSync4(exclude, "utf-8").split("\n");
45289
+ const at = lines.indexOf(excludeLine(projectDir, relPath));
45290
+ const above = lines[at - 1];
45291
+ return at >= 1 && (above === LOCAL_SETTINGS_EXCLUDE_MARKER || above === HOOK_FILE_EXCLUDE_MARKER);
45292
+ }
45293
+ function codexHookSnippet() {
45294
+ return JSON.stringify(heavyCommandHookEntry("codex"));
45295
+ }
45296
+ function trackedFileModified(projectDir, relPath) {
45297
+ if (gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) === null) return false;
45298
+ return (gitOutput(projectDir, ["diff", "--name-only", "HEAD", "--", relPath]) ?? "") !== "";
45299
+ }
45300
+ async function syncCodexHeavyCommandHook(projectDir, mode) {
45301
+ const file2 = join6(projectDir, CODEX_HOOKS_FILE);
45302
+ if (mode !== "off") {
45303
+ const shared = codexHooksSharedReason(projectDir);
45304
+ if (shared !== null) {
45305
+ unexcludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
45306
+ throw new HeavyHookSharedConfigError(file2, shared);
45307
+ }
45308
+ } else if (committedCodexHookHoldsCleo(projectDir)) {
45309
+ throw new HeavyHookSharedConfigError(
45310
+ file2,
45311
+ "holds CLEO's hook as the team committed it (removing it is a team change)"
45312
+ );
45313
+ } else if (restoreCommittedCodexHooks(projectDir)) {
45314
+ unexcludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
45315
+ return "removed";
45316
+ }
45317
+ const result = await syncJsonHeavyCommandHook(file2, "codex", mode);
45318
+ if (mode === "off") unexcludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
45319
+ else excludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
45320
+ return result;
45321
+ }
45152
45322
  async function syncClaudeCodeHeavyCommandHook(projectDir, mode) {
45153
45323
  const result = await syncJsonHeavyCommandHook(
45154
45324
  join6(projectDir, CLAUDE_LOCAL_SETTINGS),
@@ -45157,11 +45327,14 @@ async function syncClaudeCodeHeavyCommandHook(projectDir, mode) {
45157
45327
  );
45158
45328
  if (mode === "off") unexcludeLocalSettingsFromGit(projectDir);
45159
45329
  else excludeLocalSettingsFromGit(projectDir);
45160
- await syncJsonHeavyCommandHook(
45161
- join6(projectDir, ".claude", "settings.json"),
45162
- "claude-code",
45163
- "off"
45164
- );
45330
+ try {
45331
+ await syncJsonHeavyCommandHook(
45332
+ join6(projectDir, ".claude", "settings.json"),
45333
+ "claude-code",
45334
+ "off"
45335
+ );
45336
+ } catch {
45337
+ }
45165
45338
  return result;
45166
45339
  }
45167
45340
  function opencodeHeavyCommandPluginSource() {
@@ -45217,20 +45390,24 @@ function opencodeHeavyCommandPluginSource() {
45217
45390
  ].join("\n");
45218
45391
  }
45219
45392
  function syncOpencodeHeavyCommandPlugin(projectDir, mode) {
45220
- const pluginPath = join6(projectDir, ".opencode", "plugins", OPENCODE_HEAVY_COMMAND_PLUGIN);
45393
+ const pluginPath = join6(projectDir, OPENCODE_PLUGIN_FILE);
45221
45394
  const exists = existsSync5(pluginPath);
45222
45395
  if (mode === "off") {
45396
+ unexcludeHookFileFromGit(projectDir, OPENCODE_PLUGIN_FILE);
45223
45397
  if (!exists) return "unchanged";
45224
45398
  rmSync(pluginPath, { force: true });
45225
45399
  return "removed";
45226
45400
  }
45227
45401
  const source = opencodeHeavyCommandPluginSource();
45228
- if (exists && readFileSync4(pluginPath, "utf-8") === source) return "unchanged";
45229
- mkdirSync(dirname2(pluginPath), { recursive: true });
45230
- writeFileSync2(pluginPath, source, "utf-8");
45231
- return exists ? "updated" : "installed";
45402
+ const current = exists && readFileSync4(pluginPath, "utf-8") === source;
45403
+ if (!current) {
45404
+ ensureParentDir(pluginPath);
45405
+ writeFileSync2(pluginPath, source, "utf-8");
45406
+ }
45407
+ excludeHookFileFromGit(projectDir, OPENCODE_PLUGIN_FILE);
45408
+ return current ? "unchanged" : exists ? "updated" : "installed";
45232
45409
  }
45233
- var HEAVY_COMMAND_HOOK_ID, HEAVY_COMMAND_HOOK_TIMEOUT_SEC, OPENCODE_HEAVY_COMMAND_PLUGIN, HEAVY_TOOL_WORDS, OLDER_CLEO_HOOK_ANSWER, OLDER_CLEO_MARKER_PREFIX, CLAUDE_LOCAL_SETTINGS, LOCAL_SETTINGS_EXCLUDE_MARKER;
45410
+ var HEAVY_COMMAND_HOOK_ID, HEAVY_COMMAND_HOOK_TIMEOUT_SEC, OPENCODE_HEAVY_COMMAND_PLUGIN, HEAVY_TOOL_WORDS, HeavyHookPathBlockedError, OLDER_CLEO_HOOK_ANSWER, OLDER_CLEO_MARKER_PREFIX, CLAUDE_LOCAL_SETTINGS, LOCAL_SETTINGS_EXCLUDE_MARKER, HOOK_FILE_EXCLUDE_MARKER, CODEX_HOOKS_FILE, OPENCODE_PLUGIN_FILE, HeavyHookSharedConfigError;
45234
45411
  var init_heavy_command_hook_install = __esm({
45235
45412
  "packages/adapters/src/providers/shared/heavy-command-hook-install.ts"() {
45236
45413
  "use strict";
@@ -45270,6 +45447,19 @@ var init_heavy_command_hook_install = __esm({
45270
45447
  "cargo",
45271
45448
  "go"
45272
45449
  ]);
45450
+ HeavyHookPathBlockedError = class extends Error {
45451
+ /** The existing path that is not a directory. */
45452
+ path;
45453
+ /**
45454
+ * @param path - the existing non-directory path.
45455
+ * @param target - the config file that would have lived under it.
45456
+ */
45457
+ constructor(path, target) {
45458
+ super(`${path} exists but is not a directory, so ${target} cannot be created under it`);
45459
+ this.name = "HeavyHookPathBlockedError";
45460
+ this.path = path;
45461
+ }
45462
+ };
45273
45463
  OLDER_CLEO_HOOK_ANSWER = JSON.stringify({
45274
45464
  hookSpecificOutput: {
45275
45465
  hookEventName: "PreToolUse",
@@ -45279,11 +45469,27 @@ var init_heavy_command_hook_install = __esm({
45279
45469
  OLDER_CLEO_MARKER_PREFIX = "cleo-hook-unsupported-";
45280
45470
  CLAUDE_LOCAL_SETTINGS = ".claude/settings.local.json";
45281
45471
  LOCAL_SETTINGS_EXCLUDE_MARKER = "# cleo-hook: keep the per-machine heavy-command hook settings out of git (T12983)";
45472
+ HOOK_FILE_EXCLUDE_MARKER = "# cleo-hook: keep a per-machine heavy-command hook file out of git (T13124)";
45473
+ CODEX_HOOKS_FILE = ".codex/hooks.json";
45474
+ OPENCODE_PLUGIN_FILE = `.opencode/plugins/${OPENCODE_HEAVY_COMMAND_PLUGIN}`;
45475
+ HeavyHookSharedConfigError = class extends Error {
45476
+ /** The project's own config file. */
45477
+ path;
45478
+ /**
45479
+ * @param path - the config file.
45480
+ * @param why - what makes it the project's own.
45481
+ */
45482
+ constructor(path, why) {
45483
+ super(`${path} ${why}, so CLEO does not write or hide it`);
45484
+ this.name = "HeavyHookSharedConfigError";
45485
+ this.path = path;
45486
+ }
45487
+ };
45282
45488
  }
45283
45489
  });
45284
45490
 
45285
45491
  // packages/adapters/src/providers/shared/hook-template-installer.ts
45286
- import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync2, statSync } from "node:fs";
45492
+ import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync2, statSync as statSync2 } from "node:fs";
45287
45493
  import { dirname as dirname3, join as join7 } from "node:path";
45288
45494
  import { fileURLToPath } from "node:url";
45289
45495
  function resolveProviderCandidates() {
@@ -45311,8 +45517,8 @@ function copyTemplate(src, dest, force) {
45311
45517
  throw new Error(`CLEO hook template missing at source: ${src}`);
45312
45518
  }
45313
45519
  if (!force && existsSync6(dest)) {
45314
- const srcStat = statSync(src);
45315
- const destStat = statSync(dest);
45520
+ const srcStat = statSync2(src);
45521
+ const destStat = statSync2(dest);
45316
45522
  if (srcStat.size === destStat.size && srcStat.mtimeMs <= destStat.mtimeMs) {
45317
45523
  return { wrote: false };
45318
45524
  }
@@ -47781,7 +47987,7 @@ var init_hooks4 = __esm({
47781
47987
  });
47782
47988
 
47783
47989
  // packages/adapters/src/providers/pi/install.ts
47784
- import { join as join28 } from "node:path";
47990
+ import { join as join29 } from "node:path";
47785
47991
  import { ensureProviderInstructionFile as ensureProviderInstructionFile7 } from "@cleocode/caamp";
47786
47992
  function getCleoReferences() {
47787
47993
  return [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"];
@@ -47808,7 +48014,7 @@ var init_install4 = __esm({
47808
48014
  });
47809
48015
  const projectUpdated = projectResult.action !== "intact";
47810
48016
  if (projectUpdated) {
47811
- details.instructionFile = join28(projectDir, projectResult.instructFile);
48017
+ details.instructionFile = join29(projectDir, projectResult.instructFile);
47812
48018
  }
47813
48019
  let globalUpdated = false;
47814
48020
  try {
@@ -47879,7 +48085,7 @@ var init_install4 = __esm({
47879
48085
  });
47880
48086
 
47881
48087
  // packages/adapters/src/providers/pi/spawn.ts
47882
- import { findOnPath as findOnPath11 } from "@cleocode/paths";
48088
+ import { findOnPath as findOnPath12 } from "@cleocode/paths";
47883
48089
  function getPiCliPath() {
47884
48090
  return process.env["PI_CLI_PATH"] ?? "pi";
47885
48091
  }
@@ -47902,7 +48108,7 @@ var init_spawn4 = __esm({
47902
48108
  */
47903
48109
  async canSpawn() {
47904
48110
  const cliPath = getPiCliPath();
47905
- return findOnPath11(cliPath) !== null;
48111
+ return findOnPath12(cliPath) !== null;
47906
48112
  }
47907
48113
  /**
47908
48114
  * Spawn a subagent via Pi CLI.
@@ -48013,22 +48219,22 @@ var init_spawn4 = __esm({
48013
48219
  });
48014
48220
 
48015
48221
  // packages/adapters/src/providers/pi/adapter.ts
48016
- import { existsSync as existsSync20 } from "node:fs";
48017
- import { homedir as homedir13 } from "node:os";
48018
- import { join as join29 } from "node:path";
48019
- import { findOnPath as findOnPath12 } from "@cleocode/paths";
48222
+ import { existsSync as existsSync21 } from "node:fs";
48223
+ import { homedir as homedir14 } from "node:os";
48224
+ import { join as join30 } from "node:path";
48225
+ import { findOnPath as findOnPath13 } from "@cleocode/paths";
48020
48226
  function getPiAgentDir() {
48021
48227
  const env = process.env["PI_CODING_AGENT_DIR"];
48022
48228
  if (env !== void 0 && env.length > 0) {
48023
- if (env === "~") return homedir13();
48024
- if (env.startsWith("~/")) return join29(homedir13(), env.slice(2));
48229
+ if (env === "~") return homedir14();
48230
+ if (env.startsWith("~/")) return join30(homedir14(), env.slice(2));
48025
48231
  return env;
48026
48232
  }
48027
48233
  const piHome = process.env["PI_HOME"];
48028
48234
  if (piHome !== void 0 && piHome.length > 0) {
48029
- return join29(piHome, "agent");
48235
+ return join30(piHome, "agent");
48030
48236
  }
48031
- return join29(homedir13(), ".pi", "agent");
48237
+ return join30(homedir14(), ".pi", "agent");
48032
48238
  }
48033
48239
  var PiAdapter;
48034
48240
  var init_adapter4 = __esm({
@@ -48131,17 +48337,17 @@ var init_adapter4 = __esm({
48131
48337
  }
48132
48338
  let cliAvailable = false;
48133
48339
  const cliPath = process.env["PI_CLI_PATH"] ?? "pi";
48134
- const resolvedCli = findOnPath12(cliPath);
48340
+ const resolvedCli = findOnPath13(cliPath);
48135
48341
  cliAvailable = resolvedCli !== null;
48136
48342
  if (resolvedCli) details.cliPath = cliPath === "pi" ? resolvedCli : cliPath;
48137
48343
  else details.cliAvailable = false;
48138
48344
  const agentDir = getPiAgentDir();
48139
- const agentDirExists = existsSync20(agentDir);
48345
+ const agentDirExists = existsSync21(agentDir);
48140
48346
  details.agentDirExists = agentDirExists;
48141
48347
  details.agentDir = agentDir;
48142
48348
  if (this.projectDir) {
48143
- const projectPiDir = join29(this.projectDir, ".pi");
48144
- details.projectPiDirExists = existsSync20(projectPiDir);
48349
+ const projectPiDir = join30(this.projectDir, ".pi");
48350
+ details.projectPiDirExists = existsSync21(projectPiDir);
48145
48351
  }
48146
48352
  details.piCodingAgentDirSet = process.env["PI_CODING_AGENT_DIR"] !== void 0;
48147
48353
  details.piHomeSet = process.env["PI_HOME"] !== void 0;
@@ -48512,9 +48718,8 @@ var CodexInstallProvider = class {
48512
48718
  details.heavyCommandHook = "skipped";
48513
48719
  } else if (options.heavyCommandHook !== void 0) {
48514
48720
  try {
48515
- details.heavyCommandHook = await syncJsonHeavyCommandHook(
48516
- join16(projectDir, ".codex", "hooks.json"),
48517
- "codex",
48721
+ details.heavyCommandHook = await syncCodexHeavyCommandHook(
48722
+ projectDir,
48518
48723
  options.heavyCommandHook
48519
48724
  );
48520
48725
  } catch (err) {
@@ -49244,20 +49449,405 @@ function createAdapter6() {
49244
49449
 
49245
49450
  // packages/adapters/src/index.ts
49246
49451
  init_opencode();
49452
+
49453
+ // packages/adapters/src/providers/shared/heavy-command-hook-delivery.ts
49454
+ init_heavy_command_hook_install();
49455
+ init_hook_config();
49456
+ import { execFileSync as execFileSync2, spawnSync as spawnSync3 } from "node:child_process";
49457
+ import { existsSync as existsSync20, lstatSync, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
49458
+ import { homedir as homedir13 } from "node:os";
49459
+ import { dirname as dirname6, join as join28 } from "node:path";
49460
+ import { JsonConfigParseError } from "@cleocode/caamp";
49461
+ import { findOnPath as findOnPath11 } from "@cleocode/paths";
49462
+ var HEAVY_HOOK_DELIVERY_PROVIDERS = Object.freeze([
49463
+ "claude-code",
49464
+ "codex",
49465
+ "opencode",
49466
+ "kimi"
49467
+ ]);
49468
+ var HEAVY_HOOK_FIX_COMMAND = "cleo doctor heavy-command-hook --fix";
49469
+ var CODEX_SHARED_REMEDY = "if the team wants Codex governed here, add CLEO's PreToolUse entry (the snippet) to .codex/hooks.json yourself and commit it deliberately; CLEO never writes or hides a project's own hook config";
49470
+ var KIMI_REASON = "Kimi reads hooks only from its global ~/.kimi/config.toml, and CLEO never writes user-global configs";
49471
+ var KIMI_REMEDY = "add a [[hooks]] entry for PreToolUse that runs `cleo hook heavy-command --provider kimi` to ~/.kimi/config.toml yourself";
49472
+ function homeOf(env) {
49473
+ return env.HOME || homedir13();
49474
+ }
49475
+ function heavyHookTarget(provider, projectDir, env = process.env) {
49476
+ switch (provider) {
49477
+ case "claude-code":
49478
+ return join28(projectDir, CLAUDE_LOCAL_SETTINGS);
49479
+ case "codex":
49480
+ return join28(projectDir, CODEX_HOOKS_FILE);
49481
+ case "opencode":
49482
+ return join28(projectDir, OPENCODE_PLUGIN_FILE);
49483
+ case "kimi":
49484
+ return join28(homeOf(env), ".kimi", "config.toml");
49485
+ }
49486
+ }
49487
+ function detectHeavyHookProvider(provider, projectDir, env = process.env) {
49488
+ const home = homeOf(env);
49489
+ const signals = provider === "claude-code" ? [
49490
+ [
49491
+ env.CLAUDECODE === "1" || Boolean(env.CLAUDE_CODE_ENTRYPOINT),
49492
+ "running inside Claude Code"
49493
+ ],
49494
+ [() => existsSync20(join28(projectDir, ".claude")), "the project has .claude/"],
49495
+ [() => findOnPath11("claude", { env }) !== null, "`claude` is on PATH"],
49496
+ [() => existsSync20(env.CLAUDE_CONFIG_DIR || join28(home, ".claude")), "~/.claude exists"]
49497
+ ] : provider === "codex" ? [
49498
+ [() => existsSync20(join28(projectDir, ".codex")), "the project has .codex"],
49499
+ [() => findOnPath11("codex", { env }) !== null, "`codex` is on PATH"],
49500
+ [() => existsSync20(env.CODEX_HOME || join28(home, ".codex")), "~/.codex exists"]
49501
+ ] : provider === "opencode" ? [
49502
+ [() => existsSync20(join28(projectDir, ".opencode")), "the project has .opencode/"],
49503
+ [
49504
+ () => existsSync20(join28(projectDir, "opencode.json")) || existsSync20(join28(projectDir, "opencode.jsonc")),
49505
+ "the project has opencode.json"
49506
+ ],
49507
+ [() => findOnPath11("opencode", { env }) !== null, "`opencode` is on PATH"],
49508
+ [
49509
+ () => existsSync20(join28(env.XDG_CONFIG_HOME || join28(home, ".config"), "opencode")),
49510
+ "~/.config/opencode exists"
49511
+ ]
49512
+ ] : [
49513
+ [() => findOnPath11("kimi", { env }) !== null, "`kimi` is on PATH"],
49514
+ [() => existsSync20(join28(home, ".kimi")), "~/.kimi exists"]
49515
+ ];
49516
+ for (const [test, why] of signals) {
49517
+ if (typeof test === "boolean" ? test : test()) return { detected: true, why };
49518
+ }
49519
+ if (provider !== "kimi" && existsSync20(heavyHookTarget(provider, projectDir, env))) {
49520
+ return { detected: true, why: "its hook config exists" };
49521
+ }
49522
+ return {
49523
+ detected: false,
49524
+ why: `${provider} is not in use here (no config directory or CLI found)`
49525
+ };
49526
+ }
49527
+ function errorText(err) {
49528
+ return err instanceof Error ? err.message : String(err);
49529
+ }
49530
+ async function syncProvider(provider, projectDir, mode, env) {
49531
+ const target = heavyHookTarget(provider, projectDir, env);
49532
+ if (provider === "kimi") {
49533
+ return mode === "off" ? { provider, status: "unchanged", target } : { provider, status: "unsupported", target, reason: KIMI_REASON, remedy: KIMI_REMEDY };
49534
+ }
49535
+ try {
49536
+ const result = provider === "claude-code" ? await syncClaudeCodeHeavyCommandHook(projectDir, mode) : provider === "codex" ? await syncCodexHeavyCommandHook(projectDir, mode) : syncOpencodeHeavyCommandPlugin(projectDir, mode);
49537
+ return { provider, status: result, target };
49538
+ } catch (err) {
49539
+ if (err instanceof HeavyHookSharedConfigError) {
49540
+ return {
49541
+ provider,
49542
+ status: "needs-consent",
49543
+ target,
49544
+ reason: err.message,
49545
+ ...mode === "off" ? {
49546
+ remedy: "the team committed CLEO's hook in .codex/hooks.json; remove it there in a team change if the team agrees"
49547
+ } : { remedy: CODEX_SHARED_REMEDY, snippet: codexHookSnippet() }
49548
+ };
49549
+ }
49550
+ if (err instanceof HeavyHookPathBlockedError) {
49551
+ return {
49552
+ provider,
49553
+ status: "blocked",
49554
+ target,
49555
+ reason: err.message,
49556
+ remedy: `remove or rename ${err.path} (it is not a directory), then run: ${HEAVY_HOOK_FIX_COMMAND}`
49557
+ };
49558
+ }
49559
+ return {
49560
+ provider,
49561
+ status: "failed",
49562
+ target,
49563
+ reason: errorText(err),
49564
+ remedy: err instanceof JsonConfigParseError ? `fix the JSON in ${err.filePath} (it was left untouched), then run: ${HEAVY_HOOK_FIX_COMMAND}` : `run: ${HEAVY_HOOK_FIX_COMMAND}`
49565
+ };
49566
+ }
49567
+ }
49568
+ async function syncProjectHeavyCommandHooks(projectDir, mode, options = {}) {
49569
+ const env = options.env ?? process.env;
49570
+ const providers = options.providers ?? HEAVY_HOOK_DELIVERY_PROVIDERS;
49571
+ const home = isUserHomeDir(projectDir, homeOf(env));
49572
+ const outcomes = [];
49573
+ for (const provider of providers) {
49574
+ const target = heavyHookTarget(provider, projectDir, env);
49575
+ if (home) {
49576
+ outcomes.push({
49577
+ provider,
49578
+ status: "skipped",
49579
+ target,
49580
+ reason: "the project is your home directory, whose provider configs are user-global"
49581
+ });
49582
+ continue;
49583
+ }
49584
+ const detection = detectHeavyHookProvider(provider, projectDir, env);
49585
+ if (mode !== "off" && !detection.detected) {
49586
+ outcomes.push({ provider, status: "skipped", target, reason: detection.why });
49587
+ continue;
49588
+ }
49589
+ outcomes.push(await syncProvider(provider, projectDir, mode, env));
49590
+ }
49591
+ return outcomes;
49592
+ }
49593
+ function jsonHookPresence(file2, provider) {
49594
+ let raw;
49595
+ try {
49596
+ raw = readFileSync12(file2, "utf-8");
49597
+ } catch (err) {
49598
+ const code = err.code;
49599
+ return code === "ENOENT" || code === "ENOTDIR" ? { kind: "absent" } : { kind: "unreadable", error: errorText(err) };
49600
+ }
49601
+ if (raw.trim() === "") return { kind: "absent" };
49602
+ let config2;
49603
+ try {
49604
+ config2 = JSON.parse(raw);
49605
+ } catch (err) {
49606
+ return { kind: "unreadable", error: errorText(err) };
49607
+ }
49608
+ if (!isPlainObject2(config2))
49609
+ return { kind: "unreadable", error: "top-level value is not an object" };
49610
+ const hooks = config2.hooks;
49611
+ const groups = isPlainObject2(hooks) ? hooks.PreToolUse : void 0;
49612
+ if (!Array.isArray(groups)) return { kind: "absent" };
49613
+ const expected = JSON.stringify(heavyCommandHookObject(provider));
49614
+ let found = { kind: "absent" };
49615
+ for (const group of groups) {
49616
+ if (!isPlainObject2(group) || !Array.isArray(group.hooks)) continue;
49617
+ for (const hook of group.hooks) {
49618
+ if (!isHeavyHookObject(hook)) continue;
49619
+ if (JSON.stringify(hook) === expected) return { kind: "present", current: true };
49620
+ found = { kind: "present", current: false };
49621
+ }
49622
+ }
49623
+ return found;
49624
+ }
49625
+ function presenceOf(provider, projectDir, target) {
49626
+ if (provider !== "opencode") {
49627
+ const local = jsonHookPresence(target, provider);
49628
+ if (provider !== "claude-code" || local.kind !== "absent") return local;
49629
+ const legacy = jsonHookPresence(join28(projectDir, ".claude", "settings.json"), provider);
49630
+ return legacy.kind === "present" ? { kind: "present", current: false } : { kind: "absent" };
49631
+ }
49632
+ if (!existsSync20(target)) return { kind: "absent" };
49633
+ try {
49634
+ return {
49635
+ kind: "present",
49636
+ current: readFileSync12(target, "utf-8") === opencodeHeavyCommandPluginSource()
49637
+ };
49638
+ } catch (err) {
49639
+ return { kind: "unreadable", error: errorText(err) };
49640
+ }
49641
+ }
49642
+ var HOOK_FILES = {
49643
+ "claude-code": CLAUDE_LOCAL_SETTINGS,
49644
+ codex: CODEX_HOOKS_FILE,
49645
+ opencode: OPENCODE_PLUGIN_FILE
49646
+ };
49647
+ function inspectProvider(provider, projectDir, mode, env, gitChecks) {
49648
+ const target = heavyHookTarget(provider, projectDir, env);
49649
+ const { detected, why } = detectHeavyHookProvider(provider, projectDir, env);
49650
+ const base = { provider, detected, target };
49651
+ if (provider === "kimi") {
49652
+ if (!detected || mode === "off") return { ...base, state: "not-detected", detail: why };
49653
+ let manual = false;
49654
+ try {
49655
+ manual = readFileSync12(target, "utf-8").includes(HEAVY_COMMAND_HOOK_ID);
49656
+ } catch {
49657
+ }
49658
+ return manual ? { ...base, state: "installed", detail: `a manual entry in ${target} runs the hook` } : { ...base, state: "unsupported", detail: `${why}; ${KIMI_REASON}`, remedy: KIMI_REMEDY };
49659
+ }
49660
+ const presence = presenceOf(provider, projectDir, target);
49661
+ if (presence.kind === "unreadable") {
49662
+ return {
49663
+ ...base,
49664
+ state: "unreadable",
49665
+ detail: `${target} cannot be read or parsed (${presence.error})`,
49666
+ remedy: `fix ${target}, then run: ${HEAVY_HOOK_FIX_COMMAND}`
49667
+ };
49668
+ }
49669
+ if (mode === "off") {
49670
+ return presence.kind === "present" ? {
49671
+ ...base,
49672
+ state: "outdated",
49673
+ detail: "resources.heavyCommandHook is off, but the hook is still installed",
49674
+ remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (removes it)`
49675
+ } : { ...base, state: "disabled", detail: "resources.heavyCommandHook is off" };
49676
+ }
49677
+ if (presence.kind === "present") {
49678
+ if (!presence.current) {
49679
+ return {
49680
+ ...base,
49681
+ state: "outdated",
49682
+ detail: `the hook in ${target} (or a legacy location) was written by another CLEO build`,
49683
+ remedy: `run: ${HEAVY_HOOK_FIX_COMMAND}`
49684
+ };
49685
+ }
49686
+ if (!gitChecks) return { ...base, state: "installed", detail: `installed in ${target}` };
49687
+ const shared2 = provider === "codex" ? codexHooksSharedReason(projectDir, true) : null;
49688
+ if (shared2 !== null && excludedByCleo(projectDir, CODEX_HOOKS_FILE)) {
49689
+ return {
49690
+ ...base,
49691
+ state: "outdated",
49692
+ detail: `CLEO's info/exclude line hides ${target}, which ${shared2}`,
49693
+ remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (removes CLEO's exclude line)`
49694
+ };
49695
+ }
49696
+ if (shared2 !== null) {
49697
+ const modified = trackedFileModified(projectDir, CODEX_HOOKS_FILE);
49698
+ if (modified || hookFileVisibleToGit(projectDir, CODEX_HOOKS_FILE)) {
49699
+ return {
49700
+ ...base,
49701
+ state: "outdated",
49702
+ detail: `CLEO's per-machine hook sits in ${target}, which ${shared2}, as ${modified ? "an uncommitted change" : "an untracked file"}: one \`git commit -a\` ships it to the team, and it widens evidence scope`,
49703
+ remedy: "remove CLEO's entry from .codex/hooks.json, or commit it deliberately if the team wants Codex governed"
49704
+ };
49705
+ }
49706
+ return { ...base, state: "installed", detail: `installed in ${target}, which ${shared2}` };
49707
+ }
49708
+ if (hookFileVisibleToGit(projectDir, HOOK_FILES[provider])) {
49709
+ return {
49710
+ ...base,
49711
+ state: "outdated",
49712
+ detail: `${target} is installed but git sees it as an untracked file (it widens evidence scope)`,
49713
+ remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (adds it to the repository's info/exclude)`
49714
+ };
49715
+ }
49716
+ return { ...base, state: "installed", detail: `installed in ${target}` };
49717
+ }
49718
+ if (!detected) return { ...base, state: "not-detected", detail: why };
49719
+ const shared = provider === "codex" ? codexHooksSharedReason(projectDir, gitChecks) : null;
49720
+ if (shared !== null && gitChecks && excludedByCleo(projectDir, CODEX_HOOKS_FILE)) {
49721
+ return {
49722
+ ...base,
49723
+ state: "outdated",
49724
+ detail: `CLEO's info/exclude line hides ${target}, which ${shared}`,
49725
+ remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (removes CLEO's exclude line)`
49726
+ };
49727
+ }
49728
+ if (shared !== null) {
49729
+ return {
49730
+ ...base,
49731
+ state: "needs-consent",
49732
+ detail: `${target} ${shared}, so CLEO does not write or hide it; Codex runs ungoverned here until the team adds the entry (${why})`,
49733
+ remedy: CODEX_SHARED_REMEDY,
49734
+ snippet: codexHookSnippet()
49735
+ };
49736
+ }
49737
+ const blocked = nonDirectoryAncestor(dirname6(target));
49738
+ if (blocked !== null) {
49739
+ return {
49740
+ ...base,
49741
+ state: "blocked",
49742
+ detail: `${blocked} exists but is not a directory, so the hook cannot be installed (${why})`,
49743
+ remedy: `remove or rename ${blocked}, then run: ${HEAVY_HOOK_FIX_COMMAND}`
49744
+ };
49745
+ }
49746
+ return {
49747
+ ...base,
49748
+ state: "missing",
49749
+ detail: `${why}, but ${target} has no heavy-command hook: agent-run tests and builds bypass the machine-wide budget`,
49750
+ remedy: `run: ${HEAVY_HOOK_FIX_COMMAND}`
49751
+ };
49752
+ }
49753
+ function inspectProjectHeavyCommandHooks(projectDir, mode, options = {}) {
49754
+ const env = options.env ?? process.env;
49755
+ const providers = options.providers ?? HEAVY_HOOK_DELIVERY_PROVIDERS;
49756
+ if (isUserHomeDir(projectDir, homeOf(env))) {
49757
+ return providers.map((provider) => ({
49758
+ provider,
49759
+ detected: false,
49760
+ state: "not-detected",
49761
+ target: heavyHookTarget(provider, projectDir, env),
49762
+ detail: "the project is your home directory; CLEO installs this hook per project only"
49763
+ }));
49764
+ }
49765
+ const gitChecks = options.gitChecks ?? true;
49766
+ return providers.map((provider) => inspectProvider(provider, projectDir, mode, env, gitChecks));
49767
+ }
49768
+ var OLDER_CLEO_MARKER_TTL_MS = 60 * 60 * 1e3;
49769
+ function olderCleoMarkerPath(cleoPath, dir, env) {
49770
+ try {
49771
+ const key = execFileSync2(
49772
+ "/bin/sh",
49773
+ ["-c", `printf '%s|%s' "$1" "$2" | cksum | tr -c '0-9' '-'`, "sh", cleoPath, dir],
49774
+ { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }
49775
+ );
49776
+ const base = env.XDG_RUNTIME_DIR || env.TMPDIR || "/tmp";
49777
+ return join28(base, `${OLDER_CLEO_MARKER_PREFIX}${key}`);
49778
+ } catch {
49779
+ return null;
49780
+ }
49781
+ }
49782
+ function hasOlderCleoMarker(cleoPath, dir, env) {
49783
+ const marker16 = olderCleoMarkerPath(cleoPath, dir, env);
49784
+ if (marker16 === null) return false;
49785
+ try {
49786
+ const st = lstatSync(marker16);
49787
+ if (!st.isFile()) return false;
49788
+ if (Date.now() - st.mtimeMs > OLDER_CLEO_MARKER_TTL_MS) return false;
49789
+ return statSync3(cleoPath).mtimeMs <= st.mtimeMs;
49790
+ } catch {
49791
+ return false;
49792
+ }
49793
+ }
49794
+ function probeHeavyHookCli(projectDir, options = {}) {
49795
+ const env = options.env ?? process.env;
49796
+ const path = findOnPath11("cleo", { env });
49797
+ if (path === null) {
49798
+ return {
49799
+ state: "missing",
49800
+ path: null,
49801
+ detail: "no `cleo` on PATH, so the hook lets every heavy command run ungoverned",
49802
+ remedy: "install CLEO so `cleo` is on PATH: npm i -g @cleocode/cleo"
49803
+ };
49804
+ }
49805
+ const older = {
49806
+ state: "older",
49807
+ path,
49808
+ detail: `${path} predates \`cleo hook\` and \`cleo run\`, so the hook lets every heavy command run ungoverned`,
49809
+ remedy: `upgrade the cleo at ${path} (npm i -g @cleocode/cleo, or your version manager), then run: ${HEAVY_HOOK_FIX_COMMAND}`
49810
+ };
49811
+ if (hasOlderCleoMarker(path, projectDir, env)) return older;
49812
+ const probe = spawnSync3(path, ["hook", "heavy-command", "--provider", "claude-code"], {
49813
+ cwd: projectDir,
49814
+ env: { ...env },
49815
+ input: "{}",
49816
+ encoding: "utf-8",
49817
+ timeout: 2e4
49818
+ });
49819
+ if (probe.status === 0) {
49820
+ return { state: "current", path, detail: `${path} answers \`cleo hook heavy-command\`` };
49821
+ }
49822
+ if (probe.status === 127 && /Unknown command/.test(probe.stderr ?? "")) return older;
49823
+ return {
49824
+ state: "unknown",
49825
+ path,
49826
+ detail: `${path} did not answer \`cleo hook heavy-command\` (${probe.error?.message ?? `exit ${probe.status ?? "none"}`}); the hook fails open, so heavy commands run ungoverned while it does not`,
49827
+ remedy: `run \`${path} hook heavy-command < /dev/null\` in ${projectDir} to see why it fails (a broken version-manager shim, say)`
49828
+ };
49829
+ }
49830
+ var heavyHookDeliveryApi = Object.freeze({
49831
+ syncProjectHeavyCommandHooks,
49832
+ inspectProjectHeavyCommandHooks,
49833
+ probeHeavyHookCli
49834
+ });
49835
+
49836
+ // packages/adapters/src/index.ts
49247
49837
  init_hook_template_installer();
49248
49838
 
49249
49839
  // packages/adapters/src/registry.ts
49250
- import { readFileSync as readFileSync12 } from "node:fs";
49251
- import { dirname as dirname6, join as join30, resolve as resolve4 } from "node:path";
49840
+ import { readFileSync as readFileSync13 } from "node:fs";
49841
+ import { dirname as dirname7, join as join31, resolve as resolve4 } from "node:path";
49252
49842
  import { fileURLToPath as fileURLToPath3 } from "node:url";
49253
49843
  var PROVIDER_IDS = ["claude-code", "opencode", "cursor", "pi"];
49254
49844
  function getProviderManifests() {
49255
49845
  const manifests = [];
49256
- const baseDir = resolve4(dirname6(fileURLToPath3(import.meta.url)), "providers");
49846
+ const baseDir = resolve4(dirname7(fileURLToPath3(import.meta.url)), "providers");
49257
49847
  for (const providerId of PROVIDER_IDS) {
49258
49848
  try {
49259
- const manifestPath = join30(baseDir, providerId, "manifest.json");
49260
- const raw = readFileSync12(manifestPath, "utf-8");
49849
+ const manifestPath = join31(baseDir, providerId, "manifest.json");
49850
+ const raw = readFileSync13(manifestPath, "utf-8");
49261
49851
  manifests.push(JSON.parse(raw));
49262
49852
  } catch {
49263
49853
  }
@@ -49305,6 +49895,8 @@ export {
49305
49895
  GeminiCliAdapter,
49306
49896
  GeminiCliHookProvider,
49307
49897
  GeminiCliInstallProvider,
49898
+ HEAVY_HOOK_DELIVERY_PROVIDERS,
49899
+ HEAVY_HOOK_FIX_COMMAND,
49308
49900
  KimiAdapter,
49309
49901
  KimiHookProvider,
49310
49902
  KimiInstallProvider,
@@ -49325,6 +49917,7 @@ export {
49325
49917
  createAdapter5 as createGeminiCliAdapter,
49326
49918
  createAdapter6 as createKimiAdapter,
49327
49919
  createAdapter7 as createOpenCodeAdapter,
49920
+ detectHeavyHookProvider,
49328
49921
  discoverProviders,
49329
49922
  extractSymbolsFromText,
49330
49923
  getProviderHookTemplatePath,
@@ -49333,8 +49926,13 @@ export {
49333
49926
  getSetupInstructions,
49334
49927
  getSharedHookCorePath,
49335
49928
  getStatuslineConfig,
49929
+ heavyHookDeliveryApi,
49930
+ heavyHookTarget,
49931
+ inspectProjectHeavyCommandHooks,
49336
49932
  installProviderHookTemplates,
49933
+ probeHeavyHookCli,
49337
49934
  resolveTools,
49338
- runNexusPostModificationCheck
49935
+ runNexusPostModificationCheck,
49936
+ syncProjectHeavyCommandHooks
49339
49937
  };
49340
49938
  //# sourceMappingURL=index.js.map