plugnz 0.0.22 → 0.0.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.
package/dist/plugnz.mjs CHANGED
@@ -6957,8 +6957,17 @@ var require_public_api = __commonJS(function(exports) {
6957
6957
  });
6958
6958
 
6959
6959
  // src/hooks.ts
6960
- import { existsSync as existsSync15, readFileSync as readFileSync14 } from "node:fs";
6960
+ import { lstatSync as lstatSync8, readFileSync as readFileSync14 } from "node:fs";
6961
6961
  import { isAbsolute as isAbsolute7, join as join19, resolve as resolve10 } from "node:path";
6962
+ function hookEffectGap(required, supported) {
6963
+ for (const effect of HOOK_EFFECTS) {
6964
+ if (required?.[effect] !== true)
6965
+ continue;
6966
+ if (supported?.[effect] !== true)
6967
+ return { effect, status: supported?.[effect] === false ? "unsupported" : "unverified" };
6968
+ }
6969
+ return null;
6970
+ }
6962
6971
  function record(value, label) {
6963
6972
  if (typeof value !== "object" || value === null || Array.isArray(value))
6964
6973
  throw new Error(label + " must be an object");
@@ -6977,8 +6986,9 @@ function text2(value, label, nonblank = true) {
6977
6986
  function validateHookConfig(value) {
6978
6987
  const root = record(value, "Hook configuration");
6979
6988
  keys(root, ["version", "hooks"], "Hook configuration");
6980
- if (root["version"] !== 1)
6981
- throw new Error("Hook configuration version must be 1");
6989
+ const version = root["version"];
6990
+ if (version !== 1 && version !== 2)
6991
+ throw new Error("Hook configuration version must be 1 or 2");
6982
6992
  const sourceHooks = record(root["hooks"], "hooks");
6983
6993
  keys(sourceHooks, HOOK_EVENTS, "hooks");
6984
6994
  const hooks = {};
@@ -6991,7 +7001,22 @@ function validateHookConfig(value) {
6991
7001
  hooks[event] = handlers.map((value, index) => {
6992
7002
  const label = event + "[" + index + "]";
6993
7003
  const handler = record(value, label);
6994
- keys(handler, ["command", "tools", "timeoutMs"], label);
7004
+ keys(handler, version === 1 ? ["command", "tools", "timeoutMs"] : ["command", "tools", "timeoutMs", "requires"], label);
7005
+ let requires;
7006
+ if (version === 2) {
7007
+ const effects = handler["requires"] === undefined ? {} : record(handler["requires"], label + ".requires");
7008
+ keys(effects, HOOK_EFFECTS, label + ".requires");
7009
+ for (const effect of HOOK_EFFECTS) {
7010
+ if (effects[effect] !== undefined && typeof effects[effect] !== "boolean")
7011
+ throw new Error(label + ".requires." + effect + " must be boolean");
7012
+ }
7013
+ requires = { ...effects };
7014
+ if (requires.continue === true && event !== "turn.stop")
7015
+ throw new Error(label + ": continue is only available at turn.stop");
7016
+ if (event === "turn.stop" && requires.context === true !== (requires.continue === true)) {
7017
+ throw new Error(label + ": turn.stop requires context:true and continue:true together");
7018
+ }
7019
+ }
6995
7020
  const command = handler["command"];
6996
7021
  if (!Array.isArray(command) || command.length === 0)
6997
7022
  throw new Error(label + ".command must be a nonempty argv array");
@@ -7009,15 +7034,25 @@ function validateHookConfig(value) {
7009
7034
  if (timeout !== undefined && (typeof timeout !== "number" || !Number.isInteger(timeout) || timeout < 1 || timeout > MAX_HOOK_TIMEOUT_MS)) {
7010
7035
  throw new Error(label + ".timeoutMs must be an integer from 1 to " + MAX_HOOK_TIMEOUT_MS);
7011
7036
  }
7012
- return { command: argv, ...tools === undefined ? {} : { tools }, ...timeout === undefined ? {} : { timeoutMs: timeout } };
7037
+ return { command: argv, ...tools === undefined ? {} : { tools }, ...timeout === undefined ? {} : { timeoutMs: timeout }, ...requires === undefined ? {} : { requires } };
7013
7038
  });
7014
7039
  }
7015
- return { version: 1, hooks };
7040
+ return { version, hooks };
7016
7041
  }
7017
7042
  function readHookConfig(pluginRoot) {
7018
7043
  const path = join19(pluginRoot, HOOK_CONFIG_FILE);
7019
- if (!existsSync15(path))
7020
- return;
7044
+ let stat;
7045
+ try {
7046
+ stat = lstatSync8(path);
7047
+ } catch (error) {
7048
+ if (error.code === "ENOENT")
7049
+ return;
7050
+ throw error;
7051
+ }
7052
+ if (stat.isSymbolicLink())
7053
+ throw new Error("Hook source symlinks are unsupported: " + path);
7054
+ if (!stat.isFile())
7055
+ throw new Error("Hook manifest must be a regular file: " + path);
7021
7056
  let value;
7022
7057
  try {
7023
7058
  value = JSON.parse(readFileSync14(path, "utf8"));
@@ -7026,9 +7061,10 @@ function readHookConfig(pluginRoot) {
7026
7061
  }
7027
7062
  return validateHookConfig(value);
7028
7063
  }
7029
- var HOOK_EVENTS, HOOK_CONFIG_FILE = "plugnz.hooks.json", DEFAULT_HOOK_TIMEOUT_MS = 1e4, MAX_HOOK_TIMEOUT_MS = 60000;
7064
+ var HOOK_EVENTS, HOOK_CONFIG_FILE = "plugnz.hooks.json", DEFAULT_HOOK_TIMEOUT_MS = 1e4, MAX_HOOK_TIMEOUT_MS = 60000, HOOK_EFFECTS;
7030
7065
  var init_hooks = __esm(() => {
7031
7066
  HOOK_EVENTS = ["session.start", "turn.stop", "tool.before", "tool.after"];
7067
+ HOOK_EFFECTS = ["context", "continue"];
7032
7068
  });
7033
7069
 
7034
7070
  // src/hosts/command-hooks.ts
@@ -7111,7 +7147,7 @@ var init_command_hooks = __esm(() => {
7111
7147
  });
7112
7148
 
7113
7149
  // src/hosts/command-hook-manifest.ts
7114
- import { existsSync as existsSync16, mkdirSync, readFileSync as readFileSync15, rmSync, writeFileSync } from "node:fs";
7150
+ import { existsSync as existsSync15, mkdirSync, readFileSync as readFileSync15, rmSync, writeFileSync } from "node:fs";
7115
7151
  import { dirname as dirname4, join as join20 } from "node:path";
7116
7152
  function manifest(path) {
7117
7153
  let parsed;
@@ -7134,13 +7170,13 @@ function manifest(path) {
7134
7170
  function prepareCommandHookManifest(stagingRoot, relativeNativePath, removeRoot) {
7135
7171
  const rootPath = join20(stagingRoot, "plugin.json");
7136
7172
  const nativePath = join20(stagingRoot, relativeNativePath);
7137
- const root = existsSync16(rootPath) ? manifest(rootPath) : undefined;
7173
+ const root = existsSync15(rootPath) ? manifest(rootPath) : undefined;
7138
7174
  if (root) {
7139
7175
  const unsupported = Object.keys(root).find((key) => !IDENTITY_FIELDS.includes(key));
7140
7176
  if (unsupported)
7141
7177
  throw new Error('Hook build cannot project root plugin.json field "' + unsupported + '"; use an explicit native plugin manifest');
7142
7178
  }
7143
- const native = existsSync16(nativePath) ? manifest(nativePath) : undefined;
7179
+ const native = existsSync15(nativePath) ? manifest(nativePath) : undefined;
7144
7180
  if (!native && !root)
7145
7181
  throw new Error("Hook build requires a plugin identity in plugin.json or " + relativeNativePath);
7146
7182
  if (native) {
@@ -7187,6 +7223,33 @@ var init_claude_code_hooks = __esm(() => {
7187
7223
  hookAdapter = { ...adapter, prepare: prepareHookPlugin };
7188
7224
  });
7189
7225
 
7226
+ // src/compatibility.ts
7227
+ function requireCompatible(profile, capability) {
7228
+ const status = profile.capabilities[capability];
7229
+ if (status !== "supported")
7230
+ throw new CompatibilityError(profile.id, capability, status, profile.evidence);
7231
+ }
7232
+ function compatibilityEvidenceId(evidence) {
7233
+ return typeof evidence === "string" && evidence.trim().length > 0 ? evidence : null;
7234
+ }
7235
+ var CompatibilityError;
7236
+ var init_compatibility = __esm(() => {
7237
+ CompatibilityError = class CompatibilityError extends Error {
7238
+ target;
7239
+ capability;
7240
+ status;
7241
+ evidence;
7242
+ constructor(target, capability, status, evidence, diagnostic) {
7243
+ super(diagnostic ?? `target '${target}' is ${status} for ${capability}; evidence: ${evidence}`);
7244
+ this.target = target;
7245
+ this.capability = capability;
7246
+ this.status = status;
7247
+ this.evidence = evidence;
7248
+ this.name = "CompatibilityError";
7249
+ }
7250
+ };
7251
+ });
7252
+
7190
7253
  // src/hosts/codex-hooks.ts
7191
7254
  function prepareHookPlugin2(stagingRoot) {
7192
7255
  prepareCommandHookManifest(stagingRoot, ".codex-plugin/plugin.json", true);
@@ -7530,13 +7593,13 @@ var init_zcode_cli_hooks = __esm(() => {
7530
7593
 
7531
7594
  // src/hook-build.ts
7532
7595
  import { spawnSync as spawnSync3 } from "node:child_process";
7533
- import { cpSync, existsSync as existsSync18, lstatSync as lstatSync9, mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync17, readdirSync as readdirSync10, realpathSync as realpathSync3, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
7596
+ import { cpSync, existsSync as existsSync17, lstatSync as lstatSync10, mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync17, readdirSync as readdirSync10, realpathSync as realpathSync3, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
7534
7597
  import { dirname as dirname6, isAbsolute as isAbsolute8, join as join22, relative as relative4, resolve as resolve11 } from "node:path";
7535
7598
  import { fileURLToPath } from "node:url";
7536
7599
  function hookRuntimeSource() {
7537
7600
  const moduleDir = dirname6(fileURLToPath(import.meta.url));
7538
7601
  const source = join22(moduleDir, "hooks.ts");
7539
- if (existsSync18(source) && process.versions["bun"]) {
7602
+ if (existsSync17(source) && process.versions["bun"]) {
7540
7603
  if (developmentRuntime !== undefined)
7541
7604
  return developmentRuntime;
7542
7605
  const built = spawnSync3(process.execPath, ["build", source, "--target=node", "--format=esm"], {
@@ -7553,14 +7616,14 @@ function hookRuntimeSource() {
7553
7616
  return output;
7554
7617
  }
7555
7618
  for (const path of [join22(moduleDir, RUNTIME_FILE), join22(moduleDir, "..", "dist", RUNTIME_FILE)]) {
7556
- if (existsSync18(path))
7619
+ if (existsSync17(path))
7557
7620
  return readFileSync17(path, "utf8");
7558
7621
  }
7559
7622
  throw new Error("Hook runtime is missing from the distribution; rebuild with bun run build");
7560
7623
  }
7561
7624
  function entryExists2(path) {
7562
7625
  try {
7563
- lstatSync9(path);
7626
+ lstatSync10(path);
7564
7627
  return true;
7565
7628
  } catch (error) {
7566
7629
  if (error.code === "ENOENT")
@@ -7576,7 +7639,7 @@ function artifactPath(root, path) {
7576
7639
  let current = root;
7577
7640
  for (const part of path.split("/").slice(0, -1)) {
7578
7641
  current = join22(current, part);
7579
- if (entryExists2(current) && (lstatSync9(current).isSymbolicLink() || !lstatSync9(current).isDirectory())) {
7642
+ if (entryExists2(current) && (lstatSync10(current).isSymbolicLink() || !lstatSync10(current).isDirectory())) {
7580
7643
  throw new Error("Generated hook artifact parent is not an owned directory: " + current);
7581
7644
  }
7582
7645
  }
@@ -7584,8 +7647,15 @@ function artifactPath(root, path) {
7584
7647
  }
7585
7648
  function emitHooksToDirectory(adapter, configValue, stagingRoot) {
7586
7649
  const config = validateHookConfig(configValue);
7650
+ for (const event of HOOK_EVENTS) {
7651
+ for (const [index, handler] of (config.hooks[event] ?? []).entries()) {
7652
+ const gap = hookEffectGap(handler.requires, adapter.capabilities[event]);
7653
+ if (gap !== null)
7654
+ throw new CompatibilityError(adapter.id, "hooks", gap.status, "docs/hooks.md", `${adapter.id}: ${event}[${index}] requires ${gap.effect}, but that effect is ${gap.status}`);
7655
+ }
7656
+ }
7587
7657
  const root = resolve11(stagingRoot);
7588
- if (!existsSync18(root) || lstatSync9(root).isSymbolicLink() || !lstatSync9(root).isDirectory())
7658
+ if (!existsSync17(root) || lstatSync10(root).isSymbolicLink() || !lstatSync10(root).isDirectory())
7589
7659
  throw new Error("Hook staging root must be a directory");
7590
7660
  adapter.prepare?.(root);
7591
7661
  const artifacts = adapter.emit(config);
@@ -7616,7 +7686,7 @@ function copyAuthoredTree(source, destination, top = true) {
7616
7686
  continue;
7617
7687
  const from = join22(source, name);
7618
7688
  const to = join22(destination, name);
7619
- const stat = lstatSync9(from);
7689
+ const stat = lstatSync10(from);
7620
7690
  if (stat.isSymbolicLink())
7621
7691
  throw new Error("Hook source symlinks are unsupported: " + from);
7622
7692
  if (stat.isDirectory())
@@ -7630,7 +7700,7 @@ function copyAuthoredTree(source, destination, top = true) {
7630
7700
  function prospectivePath(path) {
7631
7701
  const suffix = [];
7632
7702
  let parent = resolve11(path);
7633
- while (!existsSync18(parent)) {
7703
+ while (!existsSync17(parent)) {
7634
7704
  const next = dirname6(parent);
7635
7705
  if (next === parent)
7636
7706
  throw new Error("Cannot resolve output ancestor: " + path);
@@ -7641,7 +7711,7 @@ function prospectivePath(path) {
7641
7711
  }
7642
7712
  function buildHooks(pluginDir, targets, outputDir) {
7643
7713
  const requestedSource = resolve11(pluginDir);
7644
- if (!existsSync18(requestedSource) || lstatSync9(requestedSource).isSymbolicLink() || !lstatSync9(requestedSource).isDirectory()) {
7714
+ if (!existsSync17(requestedSource) || lstatSync10(requestedSource).isSymbolicLink() || !lstatSync10(requestedSource).isDirectory()) {
7645
7715
  throw new Error("Hook source must be a directory: " + requestedSource);
7646
7716
  }
7647
7717
  const source = realpathSync3(requestedSource);
@@ -7664,7 +7734,7 @@ function buildHooks(pluginDir, targets, outputDir) {
7664
7734
  const physicalOutput = prospectivePath(output);
7665
7735
  if (physicalOutput === source || physicalOutput.startsWith(source + "/"))
7666
7736
  throw new Error("Hook output must be outside the plugin source");
7667
- if (entryExists2(output) && (lstatSync9(output).isSymbolicLink() || !lstatSync9(output).isDirectory() || readdirSync10(output).length !== 0)) {
7737
+ if (entryExists2(output) && (lstatSync10(output).isSymbolicLink() || !lstatSync10(output).isDirectory() || readdirSync10(output).length !== 0)) {
7668
7738
  throw new Error("Hook output must be absent or an empty directory: " + output);
7669
7739
  }
7670
7740
  mkdirSync2(dirname6(output), { recursive: true });
@@ -7686,6 +7756,7 @@ function buildHooks(pluginDir, targets, outputDir) {
7686
7756
  var hookAdapters, RUNTIME_FILE = "hook-runtime.mjs", developmentRuntime;
7687
7757
  var init_hook_build = __esm(() => {
7688
7758
  init_hooks();
7759
+ init_compatibility();
7689
7760
  init_claude_code_hooks();
7690
7761
  init_codex_hooks();
7691
7762
  init_omp_hooks();
@@ -7708,6 +7779,7 @@ function runHookCli(args) {
7708
7779
  throw new Error("targets takes no arguments");
7709
7780
  console.log(JSON.stringify({
7710
7781
  version: 1,
7782
+ configVersions: [1, 2],
7711
7783
  targets: hookAdapters.map(({ id, baselineVersion, capabilities }) => ({ id, baselineVersion, capabilities }))
7712
7784
  }, null, 2));
7713
7785
  return 0;
@@ -13085,28 +13157,21 @@ function formatFinding(f) {
13085
13157
  // src/hosts/claude-code-writer.ts
13086
13158
  init_claude_code_hooks();
13087
13159
 
13088
- // src/compatibility.ts
13089
- class CompatibilityError extends Error {
13090
- target;
13091
- capability;
13092
- status;
13093
- evidence;
13094
- constructor(target, capability, status, evidence, diagnostic) {
13095
- super(diagnostic ?? `target '${target}' is ${status} for ${capability}; evidence: ${evidence}`);
13096
- this.target = target;
13097
- this.capability = capability;
13098
- this.status = status;
13099
- this.evidence = evidence;
13100
- this.name = "CompatibilityError";
13101
- }
13102
- }
13103
- function requireCompatible(profile, capability) {
13104
- const status = profile.capabilities[capability];
13105
- if (status !== "supported")
13106
- throw new CompatibilityError(profile.id, capability, status, profile.evidence);
13107
- }
13108
- function compatibilityEvidenceId(evidence) {
13109
- return typeof evidence === "string" && evidence.trim().length > 0 ? evidence : null;
13160
+ // src/capability-evidence.ts
13161
+ init_compatibility();
13162
+
13163
+ // src/installation-verification.ts
13164
+ function installationVerification(report) {
13165
+ return {
13166
+ schemaVersion: 1,
13167
+ operations: report.outcomes.filter((outcome) => outcome.coverage === "desired-pair").map((outcome) => ({
13168
+ operationId: outcome.operationId,
13169
+ compatibility: outcome.reason?.code === "capability.unsupported" ? "unsupported" : outcome.reason?.code === "capability.unverified" ? "unverified" : outcome.result === "succeeded" ? "admitted" : "unknown",
13170
+ registration: report.command.dryRun ? "not-checked" : outcome.result === "succeeded" && outcome.resourceState === "present" && outcome.activationState === "active-conforming" ? "verified" : "unknown",
13171
+ executionApproval: "not-checked",
13172
+ delivery: "not-observed"
13173
+ }))
13174
+ };
13110
13175
  }
13111
13176
 
13112
13177
  // src/error-diagnostic.ts
@@ -13209,7 +13274,7 @@ function parseLifecycleReport(value) {
13209
13274
  if (!isObject2(value)) {
13210
13275
  throw invalid4("lifecycle report must be an object");
13211
13276
  }
13212
- exactFields3(value, ["schemaVersion", "command", "plan", "outcomes", "summary", "recovery", "adoptions"], "lifecycle report");
13277
+ exactFields3(value, ["schemaVersion", "command", "plan", "outcomes", "summary", "recovery", "adoptions", "verification"], "lifecycle report");
13213
13278
  if (value["schemaVersion"] !== LIFECYCLE_REPORT_SCHEMA_VERSION) {
13214
13279
  throw invalid4("lifecycle report schemaVersion must be 1");
13215
13280
  }
@@ -13321,6 +13386,14 @@ function parseLifecycleReport(value) {
13321
13386
  assertAdoptionRecoveryStatus(receipt, modern);
13322
13387
  }
13323
13388
  assertSummary(summary, outcomes, command["dryRun"], receipts, adoptions);
13389
+ if (value["verification"] !== undefined) {
13390
+ if (commandName !== "add" && commandName !== "update")
13391
+ throw invalid4("installation verification only applies to add/update");
13392
+ const expected = installationVerification(value);
13393
+ if (canonicalAdoptionJson(value["verification"]) !== canonicalAdoptionJson(expected)) {
13394
+ throw contradiction("installation verification contradicts its outcomes or claims unobserved approval/delivery");
13395
+ }
13396
+ }
13324
13397
  return value;
13325
13398
  }
13326
13399
  function matchesAdoptionRecovery(record, receipt) {
@@ -13820,7 +13893,7 @@ function isObject2(value) {
13820
13893
 
13821
13894
  // src/semantic-inventory.ts
13822
13895
  init_hooks();
13823
- import { existsSync as existsSync17, lstatSync as lstatSync8, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "node:fs";
13896
+ import { existsSync as existsSync16, lstatSync as lstatSync9, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "node:fs";
13824
13897
  import { dirname as dirname5, join as join21, relative as relative3 } from "node:path";
13825
13898
  var PACKAGE_SEMANTICS = [
13826
13899
  "ordinary-skills",
@@ -13874,7 +13947,14 @@ function inventoryPackageSemantics(plugin) {
13874
13947
  events,
13875
13948
  handlerTypes: ["command"],
13876
13949
  handlerFacets: [],
13877
- groups: events.map((event) => ({ event, matcher: null, matcherKind: "all", handlerTypes: ["command"], handlerFacets: [] }))
13950
+ groups: portableHooks.version === 1 ? events.map((event) => ({ event, matcher: null, matcherKind: "all", handlerTypes: ["command"], handlerFacets: [] })) : events.flatMap((event) => (portableHooks.hooks[event] ?? []).map((handler) => ({
13951
+ event,
13952
+ matcher: null,
13953
+ matcherKind: "all",
13954
+ handlerTypes: ["command"],
13955
+ handlerFacets: [],
13956
+ requiredEffects: handler.requires ?? {}
13957
+ })))
13878
13958
  });
13879
13959
  }
13880
13960
  const resources = files.filter((path) => (["assets/", "references/", "resources/"].some((root) => path.startsWith(root)) || path.startsWith("skills/") && !path.endsWith("/SKILL.md") || path.startsWith("hooks/") || path.startsWith(".claude/hooks/")) && !sidecars.has(path) && !hookInventory.configPaths.has(path));
@@ -14011,7 +14091,7 @@ function inventorySkillPolicy(root, skill) {
14011
14091
  }
14012
14092
  }
14013
14093
  const sidecar = `${dirname5(skill)}/agents/openai.yaml`;
14014
- if (existsSync17(join21(root, sidecar))) {
14094
+ if (existsSync16(join21(root, sidecar))) {
14015
14095
  const parsed = parseYamlObject(readFileSync16(join21(root, sidecar), "utf8"), `Codex invocation sidecar ${sidecar}`);
14016
14096
  const policy = parsed["policy"];
14017
14097
  if (policy !== undefined) {
@@ -14095,7 +14175,7 @@ function readSemanticManifests(root) {
14095
14175
  ".plugin/plugin.json",
14096
14176
  ".claude-plugin/plugin.json",
14097
14177
  ".codex-plugin/plugin.json"
14098
- ].filter((path) => existsSync17(join21(root, path))).map((path) => ({
14178
+ ].filter((path) => existsSync16(join21(root, path))).map((path) => ({
14099
14179
  ...parseJsonObject(join21(root, path), `plugin manifest ${path}`),
14100
14180
  path
14101
14181
  }));
@@ -14183,13 +14263,13 @@ function declaredHookPath(root, declaration) {
14183
14263
  invalid5(`declared hook path must be a canonical file inside the plugin root: ${declaration}`);
14184
14264
  }
14185
14265
  const absolute = join21(root, path);
14186
- if (!existsSync17(absolute))
14266
+ if (!existsSync16(absolute))
14187
14267
  invalid5(`declared hook configuration does not exist: ${declaration}`);
14188
- const stat = lstatSync8(absolute);
14268
+ const stat = lstatSync9(absolute);
14189
14269
  if (stat.isDirectory()) {
14190
14270
  const document = `${path}/hooks.json`;
14191
14271
  const documentPath = join21(root, document);
14192
- if (!existsSync17(documentPath) || !lstatSync8(documentPath).isFile()) {
14272
+ if (!existsSync16(documentPath) || !lstatSync9(documentPath).isFile()) {
14193
14273
  invalid5(`declared hook directory must contain hooks.json: ${declaration}`);
14194
14274
  }
14195
14275
  return { path: document, directory: true };
@@ -14301,7 +14381,7 @@ function walkFiles(root) {
14301
14381
  if (entry === ".git" || entry === "node_modules" || entry === ".plgnz-install.json")
14302
14382
  continue;
14303
14383
  const path = join21(dir, entry);
14304
- const stat = lstatSync8(path);
14384
+ const stat = lstatSync9(path);
14305
14385
  if (stat.isSymbolicLink())
14306
14386
  invalid5(`package semantic inventory refuses symlink: ${portable(relative3(root, path))}`);
14307
14387
  if (stat.isDirectory())
@@ -14324,7 +14404,7 @@ var COMPONENT_ROOT_SPECS = [
14324
14404
  var UNSUPPORTED_COMPONENT_ROOTS = [".codex/commands", ".codex/agents"];
14325
14405
  function inventoryComponentRoots(root) {
14326
14406
  for (const unsupported of UNSUPPORTED_COMPONENT_ROOTS) {
14327
- if (existsSync17(join21(root, unsupported)))
14407
+ if (existsSync16(join21(root, unsupported)))
14328
14408
  invalid5(`unsupported component root: ${unsupported}`);
14329
14409
  }
14330
14410
  const definitions = [];
@@ -14332,9 +14412,9 @@ function inventoryComponentRoots(root) {
14332
14412
  const permissionPaths = new Set;
14333
14413
  for (const spec of COMPONENT_ROOT_SPECS) {
14334
14414
  const directory = join21(root, spec.root);
14335
- if (!existsSync17(directory))
14415
+ if (!existsSync16(directory))
14336
14416
  continue;
14337
- const rootStat = lstatSync8(directory);
14417
+ const rootStat = lstatSync9(directory);
14338
14418
  if (!rootStat.isDirectory())
14339
14419
  invalid5(`component root must be a directory: ${spec.root}`);
14340
14420
  const entries = readdirSync9(directory).sort();
@@ -14344,7 +14424,7 @@ function inventoryComponentRoots(root) {
14344
14424
  for (const entry of entries) {
14345
14425
  const absolute = join21(directory, entry);
14346
14426
  const path = `${spec.root}/${entry}`;
14347
- const stat = lstatSync8(absolute);
14427
+ const stat = lstatSync9(absolute);
14348
14428
  if (!stat.isFile())
14349
14429
  invalid5(`component root entries must be regular files: ${path}`);
14350
14430
  const suffix = Object.keys(spec.dialects).find((candidate) => entry.endsWith(candidate));
@@ -14474,6 +14554,8 @@ var PERMISSION_FIELDS = [
14474
14554
  ];
14475
14555
 
14476
14556
  // src/capability-evidence.ts
14557
+ init_hooks();
14558
+
14477
14559
  class PackageCapabilityError extends CompatibilityError {
14478
14560
  gaps;
14479
14561
  constructor(target, admission) {
@@ -14704,6 +14786,9 @@ function hookDeclarationProblem(declaration, selectedManifest, policy) {
14704
14786
  const unsupportedFacet = group.handlerFacets.find((facet) => policy.unsupportedHandlerFacets.includes(facet));
14705
14787
  if (unsupportedFacet !== undefined)
14706
14788
  return unsupportedHookProblem(hookHandlerFacetProblem(unsupportedFacet));
14789
+ const gap = hookEffectGap(group.requiredEffects, policy.supportedEffects?.[group.event]);
14790
+ if (gap !== null)
14791
+ return { status: gap.status, diagnostic: `event '${group.event}' requires ${gap.effect}, but that effect is ${gap.status}` };
14707
14792
  }
14708
14793
  return null;
14709
14794
  }
@@ -14737,7 +14822,16 @@ function normalizeHookPolicy(input) {
14737
14822
  const matcherlessEvents = uniqueStrings(input.matcherlessEvents, "matcherless hook event").sort();
14738
14823
  const supportedMatcherKinds = uniqueStrings(input.supportedMatcherKinds, "hook matcher kind").sort();
14739
14824
  const unsupportedHandlerFacets = uniqueStrings(input.unsupportedHandlerFacets, "unsupported hook handler facet").sort();
14825
+ let supportedEffects;
14826
+ if (input.supportedEffects !== undefined) {
14827
+ supportedEffects = Object.freeze(Object.fromEntries(Object.entries(input.supportedEffects).sort(([a], [b]) => a.localeCompare(b)).map(([event, effects]) => {
14828
+ if (!supportedEvents.includes(event) || effects === null || typeof effects !== "object" || Array.isArray(effects) || Object.keys(effects).some((key) => !HOOK_EFFECTS.includes(key)) || Object.values(effects).some((value) => typeof value !== "boolean"))
14829
+ throw new Error("Invalid hook effect evidence for " + event);
14830
+ return [event, Object.freeze(Object.fromEntries(HOOK_EFFECTS.filter((effect) => effects[effect] !== undefined).map((effect) => [effect, effects[effect]])))];
14831
+ })));
14832
+ }
14740
14833
  return Object.freeze({
14834
+ ...supportedEffects === undefined ? {} : { supportedEffects },
14741
14835
  manifestPrecedence: Object.freeze(manifestPrecedence),
14742
14836
  supportedForms: Object.freeze(supportedForms),
14743
14837
  supportedEvents: Object.freeze(supportedEvents),
@@ -14788,6 +14882,7 @@ function portableHookProfile(adapter, route, operations) {
14788
14882
  supported.has(semantic) ? "supported" : "unsupported"
14789
14883
  ])),
14790
14884
  hookPolicy: {
14885
+ supportedEffects: Object.fromEntries(HOOK_EVENTS.map((event) => [event, { context: adapter.capabilities[event].context, continue: adapter.capabilities[event].continue }])),
14791
14886
  manifestPrecedence: ["plugin.json", ".plugin/plugin.json", ".claude-plugin/plugin.json", ".codex-plugin/plugin.json", ".zcode-plugin/plugin.json"],
14792
14887
  supportedForms: ["portable-hooks"],
14793
14888
  supportedEvents: HOOK_EVENTS,
@@ -14803,7 +14898,7 @@ function portableHookProfile(adapter, route, operations) {
14803
14898
  // src/hook-install.ts
14804
14899
  init_hook_build();
14805
14900
  init_hooks();
14806
- import { cpSync as cpSync2, existsSync as existsSync19, mkdirSync as mkdirSync3, mkdtempSync as mkdtempSync2, readFileSync as readFileSync18, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
14901
+ import { cpSync as cpSync2, existsSync as existsSync18, mkdirSync as mkdirSync3, mkdtempSync as mkdtempSync2, readFileSync as readFileSync18, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
14807
14902
  import { join as join23 } from "node:path";
14808
14903
  import { tmpdir } from "node:os";
14809
14904
  function preflightPortableHooks(adapter, source) {
@@ -14820,9 +14915,9 @@ function compilePortableHooksInStage(adapter, stage, options = {}) {
14820
14915
  const config = readHookConfig(stage);
14821
14916
  if (config === undefined)
14822
14917
  return false;
14823
- if (options.retainCanonicalIdentity && existsSync19(join23(stage, "plugin.json"))) {
14918
+ if (options.retainCanonicalIdentity && existsSync18(join23(stage, "plugin.json"))) {
14824
14919
  const identity = join23(stage, ".plugin", "plugin.json");
14825
- if (!existsSync19(identity)) {
14920
+ if (!existsSync18(identity)) {
14826
14921
  mkdirSync3(join23(stage, ".plugin"), { recursive: true });
14827
14922
  cpSync2(join23(stage, "plugin.json"), identity);
14828
14923
  }
@@ -14844,18 +14939,18 @@ function registerProjectedExtension(stage, key, entry) {
14844
14939
  }
14845
14940
 
14846
14941
  // src/hosts/claude-code-writer.ts
14847
- import { cpSync as cpSync5, existsSync as existsSync22, lstatSync as lstatSync12, mkdirSync as mkdirSync6, mkdtempSync as mkdtempSync5, readFileSync as readFileSync21, readdirSync as readdirSync13, renameSync as renameSync3, rmSync as rmSync6, statSync as statSync9, writeFileSync as writeFileSync6 } from "node:fs";
14942
+ import { cpSync as cpSync5, existsSync as existsSync21, lstatSync as lstatSync13, mkdirSync as mkdirSync6, mkdtempSync as mkdtempSync5, readFileSync as readFileSync21, readdirSync as readdirSync13, renameSync as renameSync3, rmSync as rmSync6, statSync as statSync9, writeFileSync as writeFileSync6 } from "node:fs";
14848
14943
  import { dirname as dirname8, join as join27, relative as relative7, resolve as resolve15 } from "node:path";
14849
14944
  import { tmpdir as tmpdir2 } from "node:os";
14850
14945
 
14851
14946
  // src/conversion.ts
14852
- import { cpSync as cpSync4, existsSync as existsSync21, lstatSync as lstatSync11, mkdirSync as mkdirSync5, mkdtempSync as mkdtempSync4, readFileSync as readFileSync20, readdirSync as readdirSync12, rmSync as rmSync5, statSync as statSync8, writeFileSync as writeFileSync4 } from "node:fs";
14947
+ import { cpSync as cpSync4, existsSync as existsSync20, lstatSync as lstatSync12, mkdirSync as mkdirSync5, mkdtempSync as mkdtempSync4, readFileSync as readFileSync20, readdirSync as readdirSync12, rmSync as rmSync5, statSync as statSync8, writeFileSync as writeFileSync4 } from "node:fs";
14853
14948
  import { basename as basename3, dirname as dirname7, join as join25, resolve as resolve13 } from "node:path";
14854
14949
  import { spawnSync as spawnSync5 } from "node:child_process";
14855
14950
 
14856
14951
  // src/source.ts
14857
14952
  import { spawnSync as spawnSync4 } from "node:child_process";
14858
- import { cpSync as cpSync3, existsSync as existsSync20, lstatSync as lstatSync10, mkdirSync as mkdirSync4, mkdtempSync as mkdtempSync3, readFileSync as readFileSync19, readdirSync as readdirSync11, renameSync as renameSync2, rmSync as rmSync4, statSync as statSync7 } from "node:fs";
14953
+ import { cpSync as cpSync3, existsSync as existsSync19, lstatSync as lstatSync11, mkdirSync as mkdirSync4, mkdtempSync as mkdtempSync3, readFileSync as readFileSync19, readdirSync as readdirSync11, renameSync as renameSync2, rmSync as rmSync4, statSync as statSync7 } from "node:fs";
14859
14954
  import { join as join24, basename as basename2, isAbsolute as isAbsolute9, relative as relative5, resolve as resolve12 } from "node:path";
14860
14955
  function resolveSource(source) {
14861
14956
  const parsed = parseSource(source);
@@ -14870,7 +14965,7 @@ function resolveSource(source) {
14870
14965
  targetDir = freezeRemoteSource(parsed.fetchLocator, sha, parsed.binding.locator);
14871
14966
  } else {
14872
14967
  targetDir = sourceUri;
14873
- if (!existsSync20(targetDir))
14968
+ if (!existsSync19(targetDir))
14874
14969
  throw new Error(`Local source not found: ${targetDir}`);
14875
14970
  targetDir = assertSafeSourceTree(targetDir);
14876
14971
  sourceRoot = targetDir;
@@ -14895,7 +14990,7 @@ function resolveSource(source) {
14895
14990
  const mp1 = join24(targetDir, ".claude-plugin", "marketplace.json");
14896
14991
  const mp2 = join24(targetDir, ".omp-plugin", "marketplace.json");
14897
14992
  const mp3 = join24(targetDir, "marketplace.json");
14898
- const mpPath = existsSync20(mp1) ? mp1 : existsSync20(mp2) ? mp2 : existsSync20(mp3) ? mp3 : null;
14993
+ const mpPath = existsSync19(mp1) ? mp1 : existsSync19(mp2) ? mp2 : existsSync19(mp3) ? mp3 : null;
14899
14994
  if (mpPath !== null) {
14900
14995
  const data = parseMarketplace(mpPath);
14901
14996
  const marketplaceName = typeof data["name"] === "string" ? data["name"] : "local";
@@ -14912,7 +15007,7 @@ function resolveSource(source) {
14912
15007
  const pDir = resolve12(targetDir, entry["source"]);
14913
15008
  if (!isInside(targetDir, pDir))
14914
15009
  throw new Error(`Marketplace plugin source escapes collection root: ${entry["source"]}`);
14915
- if (!existsSync20(pDir) || !statSync7(pDir).isDirectory())
15010
+ if (!existsSync19(pDir) || !statSync7(pDir).isDirectory())
14916
15011
  throw new Error(`Marketplace plugin source is not a directory: ${entry["source"]}`);
14917
15012
  plugins.push(pluginFromDir(pDir, marketplaceName, targetDir, sourceRoot));
14918
15013
  }
@@ -14967,7 +15062,7 @@ function freezeLocalSource(source) {
14967
15062
  if (fingerprintTree(verification) !== fingerprint)
14968
15063
  throw new Error(`Local source changed while it was being frozen: ${source}`);
14969
15064
  const target = join24(snapshots, fingerprint);
14970
- if (existsSync20(target)) {
15065
+ if (existsSync19(target)) {
14971
15066
  if (fingerprintTree(assertSafeSourceTree(target)) !== fingerprint)
14972
15067
  throw new Error(`Cached Source snapshot is corrupt: ${target}`);
14973
15068
  return target;
@@ -14985,7 +15080,7 @@ function copySourceTree(source, destination) {
14985
15080
  continue;
14986
15081
  const from = join24(source, entry);
14987
15082
  const to = join24(destination, entry);
14988
- const stat = lstatSync10(from);
15083
+ const stat = lstatSync11(from);
14989
15084
  if (stat.isSymbolicLink())
14990
15085
  throw new Error(`Symlink resources are not supported: ${from}`);
14991
15086
  if (stat.isDirectory()) {
@@ -15034,9 +15129,9 @@ function parseSource(source) {
15034
15129
  }
15035
15130
  function canonicalLocalArgument(source) {
15036
15131
  const path = resolve12(source);
15037
- if (!existsSync20(path))
15132
+ if (!existsSync19(path))
15038
15133
  return path;
15039
- if (lstatSync10(path).isSymbolicLink())
15134
+ if (lstatSync11(path).isSymbolicLink())
15040
15135
  throw new Error(`Symlink resources are not supported: ${path}`);
15041
15136
  return realpath(path);
15042
15137
  }
@@ -15108,7 +15203,7 @@ function freezeRemoteSource(fetchLocator, revision, displayLocator) {
15108
15203
  rmSync4(join24(candidate, ".git"), { recursive: true, force: true });
15109
15204
  const fingerprint = fingerprintTree(candidate);
15110
15205
  const target = join24(snapshots, fingerprint);
15111
- if (existsSync20(target)) {
15206
+ if (existsSync19(target)) {
15112
15207
  if (fingerprintTree(assertSafeSourceTree(target)) !== fingerprint)
15113
15208
  throw new Error(`Cached Source snapshot is corrupt: ${target}`);
15114
15209
  return target;
@@ -15167,12 +15262,12 @@ function isRecord3(value) {
15167
15262
  return typeof value === "object" && value !== null && !Array.isArray(value);
15168
15263
  }
15169
15264
  function isPluginDir(dir) {
15170
- return manifestPaths(dir).some(existsSync20) || existsSync20(join24(dir, ".mcp.json")) || existsSync20(join24(dir, "mcp.json"));
15265
+ return manifestPaths(dir).some(existsSync19) || existsSync19(join24(dir, ".mcp.json")) || existsSync19(join24(dir, "mcp.json"));
15171
15266
  }
15172
15267
  function readPluginManifest(dir) {
15173
15268
  let selected;
15174
15269
  for (const path of manifestPaths(dir)) {
15175
- if (!existsSync20(path))
15270
+ if (!existsSync19(path))
15176
15271
  continue;
15177
15272
  const current = parsePluginManifest(path);
15178
15273
  if (selected === undefined) {
@@ -15221,7 +15316,7 @@ var UNSUPPORTED_CLAUDE_COMPONENTS = new Set(["agents", "hooks", "mcpServers", "o
15221
15316
  function projectPluginForCodex(sourceDir, destinationDir) {
15222
15317
  const source = resolve13(sourceDir);
15223
15318
  const destination = resolve13(destinationDir);
15224
- if (!existsSync21(source) || !statSync8(source).isDirectory())
15319
+ if (!existsSync20(source) || !statSync8(source).isDirectory())
15225
15320
  throw new Error(`plugin source is not a directory: ${source}`);
15226
15321
  if (destination === source || destination.startsWith(`${source}/`))
15227
15322
  throw new Error("destination must not be inside the plugin source");
@@ -15250,7 +15345,7 @@ function projectPluginForCodex(sourceDir, destinationDir) {
15250
15345
  function projectPluginForOmp(sourceDir, destinationDir, options) {
15251
15346
  const source = resolve13(sourceDir);
15252
15347
  const destination = resolve13(destinationDir);
15253
- if (!existsSync21(source) || !statSync8(source).isDirectory())
15348
+ if (!existsSync20(source) || !statSync8(source).isDirectory())
15254
15349
  throw new Error(`plugin source is not a directory: ${source}`);
15255
15350
  if (destination === source || destination.startsWith(`${source}/`))
15256
15351
  throw new Error("destination must not be inside the plugin source");
@@ -15275,11 +15370,11 @@ function projectPluginForOmp(sourceDir, destinationDir, options) {
15275
15370
  writeOmpCommand(destination, `${options.namespace}:${command.name}`, command.description, command.argumentHint, rewriteOmpCommandReferences(command.body, commandNames, options.namespace), join25(options.activeRoot, ".plgnz", "source", relativeCommandBase(source, command.source)), projected);
15276
15371
  }
15277
15372
  const skills = join25(source, "skills");
15278
- if (existsSync21(skills)) {
15373
+ if (existsSync20(skills)) {
15279
15374
  for (const entry of readdirSync12(skills).sort()) {
15280
15375
  const skillDir = join25(skills, entry);
15281
15376
  const skillFile = join25(skillDir, "SKILL.md");
15282
- if (!statSync8(skillDir).isDirectory() || !existsSync21(skillFile))
15377
+ if (!statSync8(skillDir).isDirectory() || !existsSync20(skillFile))
15283
15378
  continue;
15284
15379
  const parsed = parseManualSkill(skillDir);
15285
15380
  if (parsed.userInvocable === false)
@@ -15348,7 +15443,7 @@ function parseManualSkill(directory) {
15348
15443
  if (hint !== undefined && typeof hint !== "string")
15349
15444
  throw new Error(`argument hint must be text: ${path}`);
15350
15445
  const sidecar = join25(directory, "agents", "openai.yaml");
15351
- const implicit = existsSync21(sidecar) ? readImplicitPolicy(sidecar) : undefined;
15446
+ const implicit = existsSync20(sidecar) ? readImplicitPolicy(sidecar) : undefined;
15352
15447
  if (implicit !== undefined && typeof manual === "boolean" && implicit === manual)
15353
15448
  throw new Error(`conflicting invocation policy for native skill ${name}`);
15354
15449
  return { name, description, ...typeof hint === "string" ? { argumentHint: hint } : {}, ...typeof userInvocable === "boolean" ? { userInvocable } : {}, manual: manual === true || implicit === false, body: match[2] ?? "", metadata };
@@ -15369,7 +15464,7 @@ ${match[2] ?? ""}`);
15369
15464
  function projectPluginForHermes(sourceDir, destinationDir, companionDir) {
15370
15465
  const source = resolve13(sourceDir);
15371
15466
  const destination = resolve13(destinationDir);
15372
- if (!existsSync21(source) || !statSync8(source).isDirectory())
15467
+ if (!existsSync20(source) || !statSync8(source).isDirectory())
15373
15468
  throw new Error(`plugin source is not a directory: ${source}`);
15374
15469
  if (destination === source || destination.startsWith(`${source}/`))
15375
15470
  throw new Error("destination must not be inside the plugin source");
@@ -15490,11 +15585,11 @@ Use skill_view with the exact qualified name when a listed skill matches the tas
15490
15585
  }
15491
15586
  function projectHermesSkills(stage) {
15492
15587
  const root = join25(stage, "skills");
15493
- if (!existsSync21(root))
15588
+ if (!existsSync20(root))
15494
15589
  return [];
15495
15590
  const result = readdirSync12(root).sort().flatMap((entry) => {
15496
15591
  const skill = join25(root, entry, "SKILL.md");
15497
- if (!existsSync21(skill))
15592
+ if (!existsSync20(skill))
15498
15593
  return [];
15499
15594
  const match = readFileSync20(skill, "utf8").match(/^---\r?\n([\s\S]*?)\r?\n---/);
15500
15595
  if (match === null)
@@ -15515,7 +15610,7 @@ function projectHermesSkills(stage) {
15515
15610
  }
15516
15611
  function validateClaudeNativeSemantics(source, commands) {
15517
15612
  const file = join25(source, ".claude-plugin", "plugin.json");
15518
- if (!existsSync21(file))
15613
+ if (!existsSync20(file))
15519
15614
  return;
15520
15615
  const parsed = JSON.parse(readFileSync20(file, "utf8"));
15521
15616
  if (!isRecord4(parsed))
@@ -15527,7 +15622,7 @@ function validateClaudeNativeSemantics(source, commands) {
15527
15622
  if (parsed["skills"] !== undefined && parsed["skills"] !== "./skills" && parsed["skills"] !== "./skills/") {
15528
15623
  throw new Error(`Claude native skills pointer is unsupported for Codex conversion: ${file}`);
15529
15624
  }
15530
- if (parsed["skills"] !== undefined && (!existsSync21(join25(source, "skills")) || !statSync8(join25(source, "skills")).isDirectory())) {
15625
+ if (parsed["skills"] !== undefined && (!existsSync20(join25(source, "skills")) || !statSync8(join25(source, "skills")).isDirectory())) {
15531
15626
  throw new Error(`Claude native skills pointer cannot be preserved for Codex conversion: ${file}`);
15532
15627
  }
15533
15628
  if (parsed["commands"] === undefined)
@@ -15550,10 +15645,10 @@ function assertSafeTree(root) {
15550
15645
  }
15551
15646
  function discoverCommands(source) {
15552
15647
  const claude = join25(source, ".claude", "commands");
15553
- if (existsSync21(claude))
15648
+ if (existsSync20(claude))
15554
15649
  return readCommandDirectory(claude, "markdown");
15555
15650
  const root = join25(source, "commands");
15556
- if (!existsSync21(root))
15651
+ if (!existsSync20(root))
15557
15652
  return [];
15558
15653
  const markdown = readCommandDirectory(root, "markdown");
15559
15654
  return markdown.length > 0 ? markdown : readCommandDirectory(root, "toml");
@@ -15626,7 +15721,7 @@ function commandFrom(path, description, argumentHint, userInvocable, disableMode
15626
15721
  }
15627
15722
  function normalizeCommandSources(root) {
15628
15723
  const dir = join25(root, "commands");
15629
- if (!existsSync21(dir))
15724
+ if (!existsSync20(dir))
15630
15725
  return;
15631
15726
  if (!statSync8(dir).isDirectory())
15632
15727
  throw new Error(`commands path is not a directory: ${dir}`);
@@ -15635,7 +15730,7 @@ function normalizeCommandSources(root) {
15635
15730
  function normalizeCommandTree(dir) {
15636
15731
  const stats = readdirSync12(dir).sort().map((name) => {
15637
15732
  const path = join25(dir, name);
15638
- const stat = lstatSync11(path);
15733
+ const stat = lstatSync12(path);
15639
15734
  if (stat.isSymbolicLink())
15640
15735
  throw new Error(`command source contains symlink: ${path}`);
15641
15736
  return { name, path, isDirectory: stat.isDirectory(), isFile: stat.isFile() };
@@ -15673,7 +15768,7 @@ ${body}` };
15673
15768
  function projectPluginForPi(sourceDir, destinationDir, namespace) {
15674
15769
  const source = resolve13(sourceDir);
15675
15770
  const destination = resolve13(destinationDir);
15676
- if (!existsSync21(source) || !statSync8(source).isDirectory())
15771
+ if (!existsSync20(source) || !statSync8(source).isDirectory())
15677
15772
  throw new Error(`plugin source is not a directory: ${source}`);
15678
15773
  if (destination === source || destination.startsWith(`${source}/`))
15679
15774
  throw new Error("destination must not be inside the plugin source");
@@ -15691,7 +15786,7 @@ function writePiCommandSkill(stage, command, namespace, names) {
15691
15786
  if (command.userInvocable === false)
15692
15787
  throw new Error(`user-invocable: false has no proven Pi skill equivalent: ${command.source}`);
15693
15788
  const skillDir = join25(stage, "skills", command.name);
15694
- if (existsSync21(skillDir))
15789
+ if (existsSync20(skillDir))
15695
15790
  throw new Error(`collision: command ${command.name} would replace an existing skill`);
15696
15791
  const body = command.body.replace(/\$ARGUMENTS\b/gu, "the text after this /skill invocation").replace(/(^|[^A-Za-z0-9_-])\/([a-z0-9][a-z0-9-]*)(?=\s|$|[.,:;!?])/giu, (whole, prefix, name) => names.has(name) ? `${prefix}/skill:${namespace}-${name}` : whole);
15697
15792
  mkdirSync5(skillDir, { recursive: true });
@@ -15718,7 +15813,7 @@ function validateMetadata(metadata, path) {
15718
15813
  }
15719
15814
  function writeCommandSkill(stage, command, namespace, commandNames) {
15720
15815
  const skillDir = join25(stage, "skills", command.name);
15721
- if (existsSync21(skillDir))
15816
+ if (existsSync20(skillDir))
15722
15817
  throw new Error(`collision: command ${command.name} would replace an existing skill`);
15723
15818
  const body = command.body.replace(/\$ARGUMENTS\b/gu, "the invocation tail").replace(/(^|[^A-Za-z0-9_-])\/([a-z0-9][a-z0-9-]*)(?=\s|$|[.,:;!?])/giu, (whole, prefix, name) => commandNames.has(name) ? `${prefix}$${namespace}:${name}` : whole);
15724
15819
  const hint = command.argumentHint === undefined ? "" : `argument-hint: ${yamlString(command.argumentHint)}
@@ -15755,7 +15850,7 @@ function hermesSkillUserOnly(skill, metadata) {
15755
15850
  if (user === false)
15756
15851
  throw new Error(`Hermes cannot preserve user-invocable: false: ${skill}`);
15757
15852
  const sidecar = join25(dirname7(skill), "agents", "openai.yaml");
15758
- const implicit = existsSync21(sidecar) ? readImplicitPolicy(sidecar) : undefined;
15853
+ const implicit = existsSync20(sidecar) ? readImplicitPolicy(sidecar) : undefined;
15759
15854
  if (disable !== undefined && implicit !== undefined && implicit !== !disable)
15760
15855
  throw new Error(`conflicting invocation policy for Hermes skill ${skill}`);
15761
15856
  const userOnly = disable === true || implicit === false;
@@ -15781,14 +15876,14 @@ ${yamlStringify(metadata).trimEnd()}
15781
15876
  }
15782
15877
  function translateNativeSkillPolicies(stage) {
15783
15878
  const skills = join25(stage, "skills");
15784
- if (!existsSync21(skills))
15879
+ if (!existsSync20(skills))
15785
15880
  return;
15786
15881
  for (const entry of readdirSync12(skills)) {
15787
15882
  const skill = join25(skills, entry);
15788
15883
  if (!statSync8(skill).isDirectory())
15789
15884
  continue;
15790
15885
  const file = join25(skill, "SKILL.md");
15791
- if (!existsSync21(file))
15886
+ if (!existsSync20(file))
15792
15887
  continue;
15793
15888
  const source = readFileSync20(file, "utf8");
15794
15889
  const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---/);
@@ -15796,7 +15891,7 @@ function translateNativeSkillPolicies(stage) {
15796
15891
  const manual = metadata["disable-model-invocation"] === true;
15797
15892
  const automatic = metadata["disable-model-invocation"] === false;
15798
15893
  const sidecar = join25(skill, "agents", "openai.yaml");
15799
- if (existsSync21(sidecar)) {
15894
+ if (existsSync20(sidecar)) {
15800
15895
  const policy = readImplicitPolicy(sidecar);
15801
15896
  if (policy !== undefined && (manual && policy !== false || automatic && policy !== true)) {
15802
15897
  throw new Error(`conflicting invocation policy for native skill ${entry}`);
@@ -15824,7 +15919,7 @@ function readImplicitPolicy(path) {
15824
15919
  return policy["allow_implicit_invocation"];
15825
15920
  }
15826
15921
  function writePolicy(path, allowImplicit) {
15827
- const existing = existsSync21(path) ? readFileSync20(path, "utf8").replace(/\s*$/u, "") : "";
15922
+ const existing = existsSync20(path) ? readFileSync20(path, "utf8").replace(/\s*$/u, "") : "";
15828
15923
  const suffix = `policy:
15829
15924
  allow_implicit_invocation: ${allowImplicit}
15830
15925
  `;
@@ -17658,7 +17753,7 @@ var claudeCodeWriter = {
17658
17753
  const marketplacesFile = join27(pluginsDir(), "known_marketplaces.json");
17659
17754
  const snapshotRoot = resolved.snapshotDir ?? resolved.sourceUri;
17660
17755
  const frozenSource = resolved.snapshot !== undefined;
17661
- const wrapper = frozenSource || !existsSync22(join27(snapshotRoot, ".claude-plugin", "marketplace.json")) ? join27(pluginsDir(), "marketplaces", `.plgnz-${marketplace}`) : undefined;
17756
+ const wrapper = frozenSource || !existsSync21(join27(snapshotRoot, ".claude-plugin", "marketplace.json")) ? join27(pluginsDir(), "marketplaces", `.plgnz-${marketplace}`) : undefined;
17662
17757
  for (const path of [slot, registryFile, settingsFile, marketplacesFile])
17663
17758
  assertManagedPath(path);
17664
17759
  const registry = readRegistry(registryFile);
@@ -17669,9 +17764,9 @@ var claudeCodeWriter = {
17669
17764
  const owned = ownedRegistryTarget(registry, id, resolved.sourceUri, slot, version);
17670
17765
  const matchedCatalogMember = legacy === undefined && !alreadyOwned && !hasUserRegistryInstall(registry, id) && matchesNativeCatalogMember(marketplaces, marketplace, plugin, resolved);
17671
17766
  const preserveNativeMarketplace = legacy !== undefined || alreadyOwned || matchedCatalogMember;
17672
- const target = owned ?? (legacy !== undefined && existsSync22(join27(slot, version)) && readOwnership(join27(slot, version)) === null ? join27(slot, `${version}.plgnz`) : join27(slot, version));
17767
+ const target = owned ?? (legacy !== undefined && existsSync21(join27(slot, version)) && readOwnership(join27(slot, version)) === null ? join27(slot, `${version}.plgnz`) : join27(slot, version));
17673
17768
  assertManagedPath(target);
17674
- if (existsSync22(target))
17769
+ if (existsSync21(target))
17675
17770
  assertNoSymlinks2(target);
17676
17771
  const existing = readOwnership(target);
17677
17772
  assertTargetIsReplaceable(target, existing, id, resolved.sourceUri);
@@ -17742,7 +17837,7 @@ var claudeCodeWriter = {
17742
17837
  }
17743
17838
  },
17744
17839
  async pin(plugin, opts) {
17745
- if (plugin.path === undefined || !existsSync22(plugin.path))
17840
+ if (plugin.path === undefined || !existsSync21(plugin.path))
17746
17841
  return { changes: [], refusals: [] };
17747
17842
  return pinPluginMcpFiles(plugin.path, mcpCandidates(), opts);
17748
17843
  },
@@ -17752,7 +17847,7 @@ var claudeCodeWriter = {
17752
17847
  for (const path of [registryFile, settingsFile])
17753
17848
  assertManagedPath(path);
17754
17849
  const settings = readSettings(settingsFile);
17755
- if (!existsSync22(registryFile)) {
17850
+ if (!existsSync21(registryFile)) {
17756
17851
  const enabled = settings["enabledPlugins"];
17757
17852
  if (typeof enabled === "object" && enabled !== null && !Array.isArray(enabled) && enabled[id] === true)
17758
17853
  writeSettings(settingsFile, settingsWithEnabled(settings, id, false));
@@ -17803,7 +17898,7 @@ var claudeCodeWriter = {
17803
17898
  if (readOwnership(copy)?.pluginId === id) {
17804
17899
  rmSync6(copy, { recursive: true, force: true });
17805
17900
  const manifest = join27(path, ".claude-plugin", "marketplace.json");
17806
- if (existsSync22(manifest)) {
17901
+ if (existsSync21(manifest)) {
17807
17902
  const document = JSON.parse(readFileSync21(manifest, "utf8"));
17808
17903
  if (typeof document === "object" && document !== null && !Array.isArray(document)) {
17809
17904
  const current = document;
@@ -17827,14 +17922,14 @@ function stagePlugin(source, stage, fallbackName, fallbackVersion) {
17827
17922
  compilePortableHooksInStage(hookAdapter, stage);
17828
17923
  const root = join27(stage, "plugin.json");
17829
17924
  const canonical = join27(stage, ".plugin", "plugin.json");
17830
- const manifest = existsSync22(canonical) ? canonical : existsSync22(root) ? root : undefined;
17925
+ const manifest = existsSync21(canonical) ? canonical : existsSync21(root) ? root : undefined;
17831
17926
  if (manifest === undefined)
17832
17927
  throw new Error("Claude Code stage has no Agent Plugins manifest");
17833
17928
  const canonicalManifest = parseManifest(manifest, "canonical");
17834
17929
  if (canonicalManifest.name !== fallbackName)
17835
17930
  throw new Error(`Claude Code canonical manifest name ${canonicalManifest.name} does not match selected plugin ${fallbackName}`);
17836
17931
  const native = join27(stage, ".claude-plugin", "plugin.json");
17837
- if (!existsSync22(native)) {
17932
+ if (!existsSync21(native)) {
17838
17933
  mkdirSync6(dirname8(native), { recursive: true });
17839
17934
  writeFileSync6(native, JSON.stringify({ name: canonicalManifest.name, version: canonicalManifest.version ?? fallbackVersion, description: canonicalManifest.description, skills: "./skills/" }));
17840
17935
  }
@@ -17844,7 +17939,7 @@ function stagePlugin(source, stage, fallbackName, fallbackVersion) {
17844
17939
  if (nativeManifest.name !== canonicalManifest.name || canonicalManifest.version !== undefined && nativeManifest.version !== canonicalManifest.version)
17845
17940
  throw new Error("Claude Code native manifest identity does not match the canonical manifest");
17846
17941
  for (const path of [join27(stage, "skills"), join27(stage, "commands"), join27(stage, ".claude", "commands")]) {
17847
- if (existsSync22(path) && !statSync9(path).isDirectory())
17942
+ if (existsSync21(path) && !statSync9(path).isDirectory())
17848
17943
  throw new Error(`Claude Code stage native content path is not a directory: ${path}`);
17849
17944
  }
17850
17945
  if (fallbackName.length === 0)
@@ -17852,10 +17947,10 @@ function stagePlugin(source, stage, fallbackName, fallbackVersion) {
17852
17947
  }
17853
17948
  function projectRootCommandsToNative(stage) {
17854
17949
  const nativeCommands = join27(stage, ".claude", "commands");
17855
- if (existsSync22(nativeCommands))
17950
+ if (existsSync21(nativeCommands))
17856
17951
  return;
17857
17952
  const rootCommands = join27(stage, "commands");
17858
- if (!existsSync22(rootCommands))
17953
+ if (!existsSync21(rootCommands))
17859
17954
  return;
17860
17955
  const entries = readdirSync13(rootCommands).sort();
17861
17956
  const markdown = entries.filter((file) => file.endsWith(".md"));
@@ -17874,7 +17969,7 @@ function projectRootCommandsToNative(stage) {
17874
17969
  }
17875
17970
  function projectNativeCommands(stage, native) {
17876
17971
  const commandsRoot = join27(stage, ".claude", "commands");
17877
- if (!existsSync22(commandsRoot))
17972
+ if (!existsSync21(commandsRoot))
17878
17973
  return;
17879
17974
  const commands = readdirSync13(commandsRoot).filter((file) => file.endsWith(".md")).sort().map((file) => `./.claude/commands/${file}`);
17880
17975
  if (commands.length === 0)
@@ -17909,7 +18004,7 @@ function parseManifest(file, kind) {
17909
18004
  return { name: manifest["name"], ...typeof manifest["version"] === "string" ? { version: manifest["version"] } : {}, ...typeof manifest["description"] === "string" ? { description: manifest["description"] } : {} };
17910
18005
  }
17911
18006
  function readRegistry(file) {
17912
- if (!existsSync22(file))
18007
+ if (!existsSync21(file))
17913
18008
  return { version: 2, plugins: {} };
17914
18009
  let value;
17915
18010
  try {
@@ -17925,7 +18020,7 @@ function readRegistry(file) {
17925
18020
  return { version: typeof root["version"] === "number" ? root["version"] : 2, plugins: root["plugins"] };
17926
18021
  }
17927
18022
  function readSettings(file) {
17928
- if (!existsSync22(file))
18023
+ if (!existsSync21(file))
17929
18024
  return {};
17930
18025
  let value;
17931
18026
  try {
@@ -17941,7 +18036,7 @@ function readSettings(file) {
17941
18036
  return settings;
17942
18037
  }
17943
18038
  function readMarketplaces(file) {
17944
- if (!existsSync22(file))
18039
+ if (!existsSync21(file))
17945
18040
  return {};
17946
18041
  let value;
17947
18042
  try {
@@ -17972,14 +18067,14 @@ function assertLifecycleMarketplaceEnvelope(version) {
17972
18067
  function marketplacesWithLocalSource(marketplaces, name, sourcePath, sourceIdentity, plugin, forceWrapper) {
17973
18068
  const manifest = join27(sourcePath, ".claude-plugin", "marketplace.json");
17974
18069
  const catalog = validateMarketplaceRegistration(marketplaces, name, sourcePath, sourceIdentity, plugin, forceWrapper);
17975
- if (forceWrapper || !existsSync22(manifest)) {
18070
+ if (forceWrapper || !existsSync21(manifest)) {
17976
18071
  const marker = join27(catalog, OWNERSHIP);
17977
18072
  const copy = join27(catalog, "plugins", plugin.name);
17978
18073
  rmSync6(copy, { recursive: true, force: true });
17979
18074
  cpSync5(plugin.dir, copy, { recursive: true });
17980
18075
  writeFileSync6(join27(copy, OWNERSHIP), JSON.stringify({ source: sourceIdentity, pluginId: `${plugin.name}@${name}`, fingerprint: plugin.contentFingerprint ?? "" }));
17981
18076
  mkdirSync6(join27(catalog, ".claude-plugin"), { recursive: true });
17982
- const current = existsSync22(join27(catalog, ".claude-plugin", "marketplace.json")) ? JSON.parse(readFileSync21(join27(catalog, ".claude-plugin", "marketplace.json"), "utf8")) : {};
18077
+ const current = existsSync21(join27(catalog, ".claude-plugin", "marketplace.json")) ? JSON.parse(readFileSync21(join27(catalog, ".claude-plugin", "marketplace.json"), "utf8")) : {};
17983
18078
  const plugins = Array.isArray(current.plugins) ? current.plugins.filter((entry) => !(typeof entry === "object" && entry !== null && entry["name"] === plugin.name)) : [];
17984
18079
  plugins.push({ name: plugin.name, source: `./plugins/${plugin.name}` });
17985
18080
  writeFileSync6(join27(catalog, ".claude-plugin", "marketplace.json"), JSON.stringify({ name, owner: { name: "plgnz" }, plugins }));
@@ -17999,17 +18094,17 @@ function validateMarketplaceRegistration(marketplaces, name, sourcePath, sourceI
17999
18094
  if (!sourcePath.startsWith("/"))
18000
18095
  throw new Error(`Claude Code marketplace registration for remote source ${name} is unverified`);
18001
18096
  const manifest = join27(sourcePath, ".claude-plugin", "marketplace.json");
18002
- const catalog = !forceWrapper && existsSync22(manifest) ? sourcePath : join27(pluginsDir(), "marketplaces", `.plgnz-${name}`);
18003
- if (!existsSync22(manifest) && existsSync22(catalog)) {
18097
+ const catalog = !forceWrapper && existsSync21(manifest) ? sourcePath : join27(pluginsDir(), "marketplaces", `.plgnz-${name}`);
18098
+ if (!existsSync21(manifest) && existsSync21(catalog)) {
18004
18099
  assertNoSymlinks2(catalog);
18005
18100
  const wrapper = readOwnership(catalog);
18006
18101
  if (wrapper?.pluginId !== `marketplace@${name}` || wrapper.source !== "plgnz-wrapper")
18007
18102
  throw new Error(`Claude Code marketplace wrapper ${catalog} is foreign; refusing to replace it`);
18008
18103
  const copy = join27(catalog, "plugins", plugin.name);
18009
- if (existsSync22(copy) && readOwnership(copy)?.source !== sourceIdentity)
18104
+ if (existsSync21(copy) && readOwnership(copy)?.source !== sourceIdentity)
18010
18105
  throw new Error(`Claude Code marketplace wrapper plugin ${copy} is foreign; refusing to replace it`);
18011
18106
  }
18012
- if (existsSync22(join27(catalog, ".claude-plugin", "marketplace.json"))) {
18107
+ if (existsSync21(join27(catalog, ".claude-plugin", "marketplace.json"))) {
18013
18108
  let document;
18014
18109
  try {
18015
18110
  document = JSON.parse(readFileSync21(join27(catalog, ".claude-plugin", "marketplace.json"), "utf8"));
@@ -18041,7 +18136,7 @@ function restoreMetadata(registryFile, registry, settingsFile, settings, marketp
18041
18136
  }
18042
18137
  }
18043
18138
  function snapshotDirectory(directory) {
18044
- if (!existsSync22(directory))
18139
+ if (!existsSync21(directory))
18045
18140
  return;
18046
18141
  assertNoSymlinks2(directory);
18047
18142
  const snapshot = mkdtempSync5(join27(tmpdir2(), "plgnz-claude-wrapper-"));
@@ -18053,7 +18148,7 @@ function restoreDirectory(directory, snapshot) {
18053
18148
  return;
18054
18149
  rmSync6(directory, { recursive: true, force: true });
18055
18150
  const previous = snapshot === undefined ? undefined : join27(snapshot, "previous");
18056
- if (previous !== undefined && existsSync22(previous)) {
18151
+ if (previous !== undefined && existsSync21(previous)) {
18057
18152
  mkdirSync6(dirname8(directory), { recursive: true });
18058
18153
  renameSync3(previous, directory);
18059
18154
  }
@@ -18117,7 +18212,7 @@ function assertNoForeignRegistryEntry(registry, id, target, source, adoptedLegac
18117
18212
  if (typeof row !== "object" || row === null || row["scope"] !== "user")
18118
18213
  continue;
18119
18214
  const path = row["installPath"];
18120
- if (typeof path !== "string" || path === target || !existsSync22(path))
18215
+ if (typeof path !== "string" || path === target || !existsSync21(path))
18121
18216
  continue;
18122
18217
  if (path === adoptedLegacy)
18123
18218
  continue;
@@ -18135,7 +18230,7 @@ function validateLegacyUserInstall(registry, id, slot, plugin) {
18135
18230
  throw new Error(`claude-code user install ${id} is ambiguous; refusing adoption`);
18136
18231
  const row = users[0];
18137
18232
  const path = row["installPath"];
18138
- if (typeof path !== "string" || dirname8(path) !== slot || !existsSync22(path))
18233
+ if (typeof path !== "string" || dirname8(path) !== slot || !existsSync21(path))
18139
18234
  throw new Error(`claude-code user install ${id} is outside its native cache slot; refusing adoption`);
18140
18235
  assertNoSymlinks2(path);
18141
18236
  if (readOwnership(path) !== null)
@@ -18153,7 +18248,7 @@ function ownedRegistryTarget(registry, id, source, slot, version) {
18153
18248
  if (users.length !== 1)
18154
18249
  return;
18155
18250
  const path = users[0]["installPath"];
18156
- if (typeof path !== "string" || dirname8(path) !== slot || path !== join27(slot, `${version}.plgnz`) || !existsSync22(path))
18251
+ if (typeof path !== "string" || dirname8(path) !== slot || path !== join27(slot, `${version}.plgnz`) || !existsSync21(path))
18157
18252
  return;
18158
18253
  const ownership = readOwnership(path);
18159
18254
  return ownership?.pluginId === id && ownership.source === source ? path : undefined;
@@ -18164,7 +18259,7 @@ function hasAdoptedRegistryInstall(registry, id, source, slot) {
18164
18259
  if (users.length !== 1)
18165
18260
  return false;
18166
18261
  const path = users[0]["installPath"];
18167
- if (typeof path !== "string" || dirname8(path) !== slot || !existsSync22(path))
18262
+ if (typeof path !== "string" || dirname8(path) !== slot || !existsSync21(path))
18168
18263
  return false;
18169
18264
  const ownership = readOwnership(path);
18170
18265
  return ownership?.pluginId === id && ownership.source === source && ownership.adopted === true;
@@ -18188,7 +18283,7 @@ function matchesNativeCatalogMember(marketplaces, name, plugin, resolved) {
18188
18283
  if (!containedPath(resolved.sourceUri, plugin.sourceDir ?? plugin.dir))
18189
18284
  return false;
18190
18285
  const manifest = join27(catalog, ".claude-plugin", "marketplace.json");
18191
- if (!existsSync22(manifest))
18286
+ if (!existsSync21(manifest))
18192
18287
  return false;
18193
18288
  assertCatalogPath(catalog, manifest);
18194
18289
  let document;
@@ -18212,7 +18307,7 @@ function matchesNativeCatalogMember(marketplaces, name, plugin, resolved) {
18212
18307
  if (!containedPath(catalog, nativeDir) || nativeDir === resolve15(catalog))
18213
18308
  return false;
18214
18309
  assertCatalogPath(catalog, nativeDir);
18215
- if (!existsSync22(nativeDir) || !lstatSync12(nativeDir).isDirectory())
18310
+ if (!existsSync21(nativeDir) || !lstatSync13(nativeDir).isDirectory())
18216
18311
  return false;
18217
18312
  const stages = mkdtempSync5(join27(tmpdir2(), "plgnz-claude-catalog-proof-"));
18218
18313
  try {
@@ -18239,7 +18334,7 @@ function assertCatalogPath(root, path) {
18239
18334
  for (const part of ["", ...relative7(current, target).split("/").filter(Boolean)]) {
18240
18335
  if (part !== "")
18241
18336
  current = join27(current, part);
18242
- const stat = lstatSync12(current);
18337
+ const stat = lstatSync13(current);
18243
18338
  if (stat.isSymbolicLink())
18244
18339
  throw new Error(`Claude Code native catalog path contains symlink: ${current}`);
18245
18340
  if (current !== target && !stat.isDirectory())
@@ -18247,7 +18342,7 @@ function assertCatalogPath(root, path) {
18247
18342
  }
18248
18343
  }
18249
18344
  function assertTargetIsReplaceable(target, ownership, id, source) {
18250
- if (existsSync22(target) && ownership === null)
18345
+ if (existsSync21(target) && ownership === null)
18251
18346
  throw new Error(`claude-code cache slot ${target} is unowned; refusing to replace it`);
18252
18347
  if (ownership !== null && (ownership.pluginId !== id || ownership.source !== source))
18253
18348
  throw new Error(`claude-code cache slot ${target} has a different owned source identity; refusing to replace it`);
@@ -18264,7 +18359,7 @@ function assertManagedPath(path) {
18264
18359
  current = join27(current, part);
18265
18360
  let stat;
18266
18361
  try {
18267
- stat = lstatSync12(current);
18362
+ stat = lstatSync13(current);
18268
18363
  } catch (error) {
18269
18364
  if (error.code === "ENOENT")
18270
18365
  return;
@@ -18284,7 +18379,7 @@ function cleanupPriorOwnedPaths(registry, id, active, source) {
18284
18379
  if (typeof row !== "object" || row === null)
18285
18380
  continue;
18286
18381
  const path = row["installPath"];
18287
- if (typeof path !== "string" || path === active || !existsSync22(path))
18382
+ if (typeof path !== "string" || path === active || !existsSync21(path))
18288
18383
  continue;
18289
18384
  const ownership = readOwnership(path);
18290
18385
  if (ownership?.pluginId === id && ownership.source === source)
@@ -18293,7 +18388,7 @@ function cleanupPriorOwnedPaths(registry, id, active, source) {
18293
18388
  }
18294
18389
  function readOwnership(dir) {
18295
18390
  const file = join27(dir, OWNERSHIP);
18296
- if (!existsSync22(file))
18391
+ if (!existsSync21(file))
18297
18392
  return null;
18298
18393
  try {
18299
18394
  const parsed = JSON.parse(readFileSync21(file, "utf8"));
@@ -18318,7 +18413,7 @@ function readOwnership(dir) {
18318
18413
  }
18319
18414
  }
18320
18415
  function activate(stage, target, slot) {
18321
- if (!existsSync22(target)) {
18416
+ if (!existsSync21(target)) {
18322
18417
  renameSync3(stage, target);
18323
18418
  return { commit: () => {}, rollback: () => rmSync6(target, { recursive: true, force: true }) };
18324
18419
  }
@@ -18339,13 +18434,13 @@ function moveAside(path, parent = dirname8(path)) {
18339
18434
  const backup = join27(backupRoot, "previous");
18340
18435
  renameSync3(path, backup);
18341
18436
  return { commit: () => rmSync6(backupRoot, { recursive: true, force: true }), rollback: () => {
18342
- if (existsSync22(backup))
18437
+ if (existsSync21(backup))
18343
18438
  renameSync3(backup, path);
18344
18439
  rmSync6(backupRoot, { recursive: true, force: true });
18345
18440
  } };
18346
18441
  }
18347
18442
  function sameTree(left, right) {
18348
- if (!existsSync22(right))
18443
+ if (!existsSync21(right))
18349
18444
  return false;
18350
18445
  const listing = (root) => {
18351
18446
  const out = [];
@@ -18373,11 +18468,11 @@ function bytesKey(path) {
18373
18468
  return hash.digest("hex");
18374
18469
  }
18375
18470
  function assertNoSymlinks2(dir) {
18376
- if (lstatSync12(dir).isSymbolicLink())
18471
+ if (lstatSync13(dir).isSymbolicLink())
18377
18472
  throw new Error(`Claude Code cache contains symlink: ${dir}`);
18378
18473
  for (const entry of readdirSync13(dir)) {
18379
18474
  const path = join27(dir, entry);
18380
- const stat = lstatSync12(path);
18475
+ const stat = lstatSync13(path);
18381
18476
  if (stat.isSymbolicLink())
18382
18477
  throw new Error(`Claude Code cache contains symlink: ${path}`);
18383
18478
  if (stat.isDirectory())
@@ -18538,7 +18633,7 @@ function claudeCodeLifecycleDefinition(contracts) {
18538
18633
  retire: async (prepared) => {
18539
18634
  retireLifecycleCatalog(prepared.handle.nativeId, prepared.handle.scopeId);
18540
18635
  const installPath = recordedInstallPath(prepared.handle.nativeId);
18541
- const existed = installPath !== undefined && existsSync22(installPath);
18636
+ const existed = installPath !== undefined && existsSync21(installPath);
18542
18637
  if (installPath !== undefined)
18543
18638
  rmSync6(installPath, { recursive: true, force: true });
18544
18639
  dropUserRow(prepared.handle.nativeId);
@@ -18693,7 +18788,7 @@ function observeClaudeInstallations(target, version) {
18693
18788
  if (typeof recordedPath !== "string")
18694
18789
  continue;
18695
18790
  const installPath = resolve15(recordedPath);
18696
- if (!existsSync22(installPath))
18791
+ if (!existsSync21(installPath))
18697
18792
  continue;
18698
18793
  const marker = readOwnership(installPath);
18699
18794
  const digest = fingerprintTree(installPath);
@@ -18770,7 +18865,7 @@ function activationIdentity(activation) {
18770
18865
  function claudeReadback(identity, absentRoute, version) {
18771
18866
  assertLifecycleMarketplaceEnvelope(version);
18772
18867
  const installPath = recordedInstallPath(identity.nativeId);
18773
- const present = installPath !== undefined && existsSync22(installPath);
18868
+ const present = installPath !== undefined && existsSync21(installPath);
18774
18869
  const retention = {
18775
18870
  pluginData: retained(resolve15(join27(pluginsDir(), "plugin-data", identity.nativeId))),
18776
18871
  inactiveMetadata: retained(resolve15(join27(pluginsDir(), "inactive-metadata", identity.nativeId)))
@@ -18804,7 +18899,7 @@ function claudeReadback(identity, absentRoute, version) {
18804
18899
  }
18805
18900
  function installedRoute(installPath) {
18806
18901
  const file = join27(installPath, ".plgnz-lifecycle.json");
18807
- if (!existsSync22(file))
18902
+ if (!existsSync21(file))
18808
18903
  return "managed";
18809
18904
  try {
18810
18905
  const parsed = JSON.parse(readFileSync21(file, "utf8"));
@@ -18817,7 +18912,7 @@ function installedRoute(installPath) {
18817
18912
  }
18818
18913
  function observedOwnedRoute(installPath) {
18819
18914
  const file = join27(installPath, ".plgnz-lifecycle.json");
18820
- if (!existsSync22(file))
18915
+ if (!existsSync21(file))
18821
18916
  return;
18822
18917
  const value = JSON.parse(readFileSync21(file, "utf8"));
18823
18918
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -18828,7 +18923,7 @@ function observedOwnedRoute(installPath) {
18828
18923
  return route;
18829
18924
  }
18830
18925
  function retained(path) {
18831
- if (!existsSync22(path))
18926
+ if (!existsSync21(path))
18832
18927
  return { state: "absent", fingerprint: null };
18833
18928
  return { state: "present", fingerprint: fingerprintTree(path) };
18834
18929
  }
@@ -18875,14 +18970,14 @@ function registeredLifecycleCatalogMember(nativeId) {
18875
18970
  if (!isRecord6(entry) || !isRecord6(entry["source"]) || entry["source"]["source"] !== "directory" || typeof entry["source"]["path"] !== "string" || entry["installLocation"] !== entry["source"]["path"])
18876
18971
  return null;
18877
18972
  const root = entry["source"]["path"];
18878
- if (!root.startsWith("/") || resolve15(root) !== root || !existsSync22(root))
18973
+ if (!root.startsWith("/") || resolve15(root) !== root || !existsSync21(root))
18879
18974
  return null;
18880
18975
  assertCatalogPath(root, join27(root, ".claude-plugin", "marketplace.json"));
18881
18976
  const selected = catalogEntries(lifecycleCatalogDocument(root, market)).filter((item) => isCatalogMember(item, nativeId));
18882
18977
  if (selected.length !== 1 || !isRecord6(selected[0]) || typeof selected[0]["source"] !== "string" || !selected[0]["source"].startsWith("./"))
18883
18978
  return null;
18884
18979
  const member = resolve15(root, selected[0]["source"]);
18885
- if (!containedPath(root, member) || root === member || !existsSync22(member))
18980
+ if (!containedPath(root, member) || root === member || !existsSync21(member))
18886
18981
  return null;
18887
18982
  assertCatalogPath(root, member);
18888
18983
  assertNoSymlinks2(member);
@@ -18896,7 +18991,7 @@ function matchingForeignLifecycleCatalog(nativeId, scopeId, target, packageRoot,
18896
18991
  return null;
18897
18992
  if (!foreignLifecycleEntryEquivalent(catalog.entry))
18898
18993
  return null;
18899
- if (!existsSync22(join27(catalog.member, ".claude-plugin", "plugin.json")))
18994
+ if (!existsSync21(join27(catalog.member, ".claude-plugin", "plugin.json")))
18900
18995
  return null;
18901
18996
  const proof = mkdtempSync5(join27(tmpdir2(), "plgnz-claude-native-member-"));
18902
18997
  try {
@@ -18913,7 +19008,7 @@ function matchingForeignLifecycleCatalog(nativeId, scopeId, target, packageRoot,
18913
19008
  }
18914
19009
  function lifecycleCatalogDocument(root, market) {
18915
19010
  const file = join27(root, ".claude-plugin", "marketplace.json");
18916
- if (!existsSync22(file))
19011
+ if (!existsSync21(file))
18917
19012
  return null;
18918
19013
  const parsed = JSON.parse(readFileSync21(file, "utf8"));
18919
19014
  if (!isRecord6(parsed) || parsed["name"] !== market || !Array.isArray(parsed["plugins"]))
@@ -18961,7 +19056,7 @@ function validateLifecycleCatalog(nativeId, scopeId) {
18961
19056
  assertManagedPath(join27(root, ".claude-plugin", "marketplace.json"));
18962
19057
  assertManagedPath(join27(root, OWNERSHIP));
18963
19058
  assertManagedPath(copy);
18964
- if (existsSync22(root)) {
19059
+ if (existsSync21(root)) {
18965
19060
  const owner = readOwnership(root);
18966
19061
  if (owner?.source !== "plgnz-wrapper" || owner.pluginId !== `marketplace@${market}`)
18967
19062
  throw new Error(`Claude Code marketplace wrapper ${root} is foreign; refusing to replace it`);
@@ -18970,7 +19065,7 @@ function validateLifecycleCatalog(nativeId, scopeId) {
18970
19065
  const selected = catalogEntries(document).filter((entry) => isCatalogMember(entry, nativeId));
18971
19066
  if (selected.length > 1 || selected.some((entry) => !isRecord6(entry) || entry["source"] !== `./plugins/${nativeId.slice(0, nativeId.indexOf("@"))}`))
18972
19067
  throw new Error(`Claude Code marketplace member ${nativeId} is foreign or ambiguous; refusing to replace it`);
18973
- if (existsSync22(copy)) {
19068
+ if (existsSync21(copy)) {
18974
19069
  assertNoSymlinks2(copy);
18975
19070
  const owner = readOwnership(copy);
18976
19071
  if (owner?.pluginId !== nativeId || owner.scopeId !== scopeId)
@@ -19016,7 +19111,7 @@ function lifecycleCatalogConforms(nativeId, installPath, target) {
19016
19111
  if (registered !== null && registered.root !== lifecycleCatalogRoot(nativeId)) {
19017
19112
  if (owner?.scopeId === undefined)
19018
19113
  return false;
19019
- const manifest = existsSync22(join27(installPath, ".plugin", "plugin.json")) ? join27(installPath, ".plugin", "plugin.json") : join27(installPath, "plugin.json");
19114
+ const manifest = existsSync21(join27(installPath, ".plugin", "plugin.json")) ? join27(installPath, ".plugin", "plugin.json") : join27(installPath, "plugin.json");
19020
19115
  return matchingForeignLifecycleCatalog(nativeId, owner.scopeId, target, installPath, parseManifest(manifest, "canonical").version ?? "") !== null;
19021
19116
  }
19022
19117
  const known = readMarketplaces(join27(pluginsDir(), "known_marketplaces.json"))[market];
@@ -19026,7 +19121,7 @@ function lifecycleCatalogConforms(nativeId, installPath, target) {
19026
19121
  if (entries.length !== 1 || catalogEntryFingerprint(entries[0]) !== catalogEntryFingerprint(ownedLifecycleCatalogEntry(nativeId)))
19027
19122
  return false;
19028
19123
  const copy = lifecycleCatalogCopy(nativeId);
19029
- if (!existsSync22(copy))
19124
+ if (!existsSync21(copy))
19030
19125
  return false;
19031
19126
  assertManagedPath(copy);
19032
19127
  assertNoSymlinks2(copy);
@@ -19035,13 +19130,13 @@ function lifecycleCatalogConforms(nativeId, installPath, target) {
19035
19130
  }
19036
19131
  function lifecycleContentRoots(nativeId, installPath, digest) {
19037
19132
  const copy = registeredLifecycleCatalogMember(nativeId)?.member ?? lifecycleCatalogCopy(nativeId);
19038
- return [{ label: "plugin", path: installPath, fingerprint: digest }, ...existsSync22(copy) ? [{ label: "catalog-plugin", path: copy, fingerprint: fingerprintTree(copy) }] : [], ...lifecycleCatalogEntryObservation(nativeId)];
19133
+ return [{ label: "plugin", path: installPath, fingerprint: digest }, ...existsSync21(copy) ? [{ label: "catalog-plugin", path: copy, fingerprint: fingerprintTree(copy) }] : [], ...lifecycleCatalogEntryObservation(nativeId)];
19039
19134
  }
19040
19135
  function retireLifecycleCatalog(nativeId, scopeId) {
19041
19136
  validateLifecycleCatalogRetirement(nativeId, scopeId);
19042
19137
  const root = lifecycleCatalogRoot(nativeId);
19043
19138
  const copy = lifecycleCatalogCopy(nativeId);
19044
- if (!existsSync22(root))
19139
+ if (!existsSync21(root))
19045
19140
  return;
19046
19141
  assertManagedPath(root);
19047
19142
  const market = marketplaceName(nativeId);
@@ -19049,7 +19144,7 @@ function retireLifecycleCatalog(nativeId, scopeId) {
19049
19144
  if (owner?.source !== "plgnz-wrapper" || owner.pluginId !== `marketplace@${market}`)
19050
19145
  return;
19051
19146
  const document = lifecycleCatalogDocument(root, market);
19052
- if (existsSync22(copy)) {
19147
+ if (existsSync21(copy)) {
19053
19148
  const member = readOwnership(copy);
19054
19149
  if (member?.pluginId !== nativeId || member.scopeId !== scopeId)
19055
19150
  throw new Error(`Claude Code catalog retirement cannot prove ownership: ${copy}`);
@@ -19071,17 +19166,17 @@ function retireLifecycleCatalog(nativeId, scopeId) {
19071
19166
  }
19072
19167
  }
19073
19168
  function emptyOwnedCatalogContainer(root) {
19074
- if (!existsSync22(root))
19169
+ if (!existsSync21(root))
19075
19170
  return true;
19076
19171
  if (readdirSync13(root).some((name) => ![OWNERSHIP, ".claude-plugin", "plugins"].includes(name)))
19077
19172
  return false;
19078
- if (existsSync22(join27(root, ".claude-plugin")) && readdirSync13(join27(root, ".claude-plugin")).some((name) => name !== "marketplace.json"))
19173
+ if (existsSync21(join27(root, ".claude-plugin")) && readdirSync13(join27(root, ".claude-plugin")).some((name) => name !== "marketplace.json"))
19079
19174
  return false;
19080
- return !existsSync22(join27(root, "plugins")) || readdirSync13(join27(root, "plugins")).length === 0;
19175
+ return !existsSync21(join27(root, "plugins")) || readdirSync13(join27(root, "plugins")).length === 0;
19081
19176
  }
19082
19177
  function validateLifecycleCatalogRetirement(nativeId, scopeId) {
19083
19178
  const root = lifecycleCatalogRoot(nativeId);
19084
- if (!existsSync22(root))
19179
+ if (!existsSync21(root))
19085
19180
  return;
19086
19181
  assertManagedPath(root);
19087
19182
  assertManagedPath(join27(root, OWNERSHIP));
@@ -19098,7 +19193,7 @@ function validateLifecycleCatalogRetirement(nativeId, scopeId) {
19098
19193
  const selected = catalogEntries(lifecycleCatalogDocument(root, marketplaceName(nativeId))).filter((entry) => isCatalogMember(entry, nativeId));
19099
19194
  if (selected.length > 1 || selected.some((entry) => !isRecord6(entry) || entry["source"] !== `./plugins/${nativeId.slice(0, nativeId.indexOf("@"))}`))
19100
19195
  throw new Error(`Claude Code catalog retirement found a foreign or ambiguous member: ${nativeId}`);
19101
- if (existsSync22(copy)) {
19196
+ if (existsSync21(copy)) {
19102
19197
  assertNoSymlinks2(copy);
19103
19198
  const member = readOwnership(copy);
19104
19199
  if (member?.pluginId !== nativeId || member.scopeId !== scopeId)
@@ -19109,9 +19204,9 @@ function captureLifecycleCatalog(reference, nativeId) {
19109
19204
  const root = lifecycleCatalogRoot(nativeId);
19110
19205
  const market = marketplaceName(nativeId);
19111
19206
  const document = lifecycleCatalogDocument(root, market);
19112
- writeFileSync6(join27(reference, "catalog.json"), JSON.stringify({ document, selected: catalogEntries(document).filter((entry) => isCatalogMember(entry, nativeId)), marker: existsSync22(join27(root, OWNERSHIP)) ? readFileSync21(join27(root, OWNERSHIP), "utf8") : null }));
19207
+ writeFileSync6(join27(reference, "catalog.json"), JSON.stringify({ document, selected: catalogEntries(document).filter((entry) => isCatalogMember(entry, nativeId)), marker: existsSync21(join27(root, OWNERSHIP)) ? readFileSync21(join27(root, OWNERSHIP), "utf8") : null }));
19113
19208
  const copy = lifecycleCatalogCopy(nativeId);
19114
- if (existsSync22(copy)) {
19209
+ if (existsSync21(copy)) {
19115
19210
  assertNoSymlinks2(copy);
19116
19211
  cpSync5(copy, join27(reference, "catalog-plugin"), { recursive: true });
19117
19212
  }
@@ -19120,7 +19215,7 @@ function restoreLifecycleCatalog(reference, nativeId, scopeId) {
19120
19215
  const saved = JSON.parse(readFileSync21(join27(reference, "catalog.json"), "utf8"));
19121
19216
  const root = lifecycleCatalogRoot(nativeId);
19122
19217
  assertManagedPath(root);
19123
- if (existsSync22(root)) {
19218
+ if (existsSync21(root)) {
19124
19219
  assertManagedPath(join27(root, OWNERSHIP));
19125
19220
  const owner = readOwnership(root);
19126
19221
  if (owner?.source !== "plgnz-wrapper" || owner.pluginId !== `marketplace@${marketplaceName(nativeId)}`)
@@ -19132,14 +19227,14 @@ function restoreLifecycleCatalog(reference, nativeId, scopeId) {
19132
19227
  const siblings = catalogEntries(current).filter((entry) => !isCatalogMember(entry, nativeId));
19133
19228
  const copy = lifecycleCatalogCopy(nativeId);
19134
19229
  assertManagedPath(copy);
19135
- if (existsSync22(copy)) {
19230
+ if (existsSync21(copy)) {
19136
19231
  assertNoSymlinks2(copy);
19137
19232
  const owner = readOwnership(copy);
19138
19233
  if (owner?.pluginId !== nativeId || owner.scopeId !== scopeId)
19139
19234
  throw new Error(`Claude Code rollback refuses a foreign catalog member: ${copy}`);
19140
19235
  }
19141
19236
  rmSync6(copy, { recursive: true, force: true });
19142
- if (existsSync22(join27(reference, "catalog-plugin"))) {
19237
+ if (existsSync21(join27(reference, "catalog-plugin"))) {
19143
19238
  mkdirSync6(dirname8(copy), { recursive: true });
19144
19239
  cpSync5(join27(reference, "catalog-plugin"), copy, { recursive: true });
19145
19240
  }
@@ -19182,7 +19277,7 @@ function captureRollback(attemptId, operationId, nativeId) {
19182
19277
  writeFileSync6(join27(reference, "known-marketplace.json"), JSON.stringify({ marketplace: marketplace ?? null, entry: knownEntry }));
19183
19278
  captureLifecycleCatalog(reference, nativeId);
19184
19279
  const installPath = recordedInstallPath(nativeId);
19185
- if (installPath !== undefined && existsSync22(installPath)) {
19280
+ if (installPath !== undefined && existsSync21(installPath)) {
19186
19281
  cpSync5(installPath, join27(reference, "install"), { recursive: true });
19187
19282
  writeFileSync6(join27(reference, "install-path.txt"), installPath);
19188
19283
  }
@@ -19204,7 +19299,7 @@ function mutateInstall(handle, stagingRoot) {
19204
19299
  }
19205
19300
  const beforeCatalog = lifecycleSelectedMutationState(handle.nativeId);
19206
19301
  const installPath = cacheSlot(handle.nativeId, slotVersion(handle.packageVersion, handle.sourceRevision));
19207
- const before = existsSync22(installPath) ? fingerprintTree(installPath) : null;
19302
+ const before = existsSync21(installPath) ? fingerprintTree(installPath) : null;
19208
19303
  rmSync6(installPath, { recursive: true, force: true });
19209
19304
  mkdirSync6(dirname8(installPath), { recursive: true });
19210
19305
  cpSync5(stagingRoot, installPath, { recursive: true });
@@ -19239,7 +19334,7 @@ function lifecycleSelectedMutationState(nativeId) {
19239
19334
  const member = registeredLifecycleCatalogMember(nativeId)?.member ?? lifecycleCatalogCopy(nativeId);
19240
19335
  return catalogEntryFingerprint({
19241
19336
  catalogEntry: lifecycleCatalogEntryObservation(nativeId),
19242
- member: existsSync22(member) ? fingerprintTree(member) : null,
19337
+ member: existsSync21(member) ? fingerprintTree(member) : null,
19243
19338
  registration: known[market] ?? null,
19244
19339
  extraRegistration: isRecord6(extra) ? extra[market] ?? null : null,
19245
19340
  installedRows: readRegistry(join27(pluginsDir(), "installed_plugins.json")).plugins[nativeId] ?? null,
@@ -19271,15 +19366,15 @@ function restoreRollback(handle) {
19271
19366
  const registryFile = join27(pluginsDir(), "installed_plugins.json");
19272
19367
  const appliedSlot = cacheSlot(handle.nativeId, slotVersion(handle.packageVersion, handle.sourceRevision));
19273
19368
  const savedPath = join27(reference, "install-path.txt");
19274
- const previousSlot = existsSync22(savedPath) ? readFileSync21(savedPath, "utf8") : undefined;
19275
- if (previousSlot !== undefined && resolve15(previousSlot) !== appliedSlot && !existsSync22(appliedSlot)) {
19369
+ const previousSlot = existsSync21(savedPath) ? readFileSync21(savedPath, "utf8") : undefined;
19370
+ if (previousSlot !== undefined && resolve15(previousSlot) !== appliedSlot && !existsSync21(appliedSlot)) {
19276
19371
  throw new Error(`claude-code rollback cannot remove the updated cache slot: ${appliedSlot}`);
19277
19372
  }
19278
19373
  const beforeEntry = JSON.stringify(readRegistry(registryFile).plugins[handle.nativeId] ?? null);
19279
19374
  const beforeEnabled = JSON.stringify(enabledPlugins()[handle.nativeId] ?? null);
19280
- const beforeMarkets = existsSync22(join27(pluginsDir(), "known_marketplaces.json")) ? readFileSync21(join27(pluginsDir(), "known_marketplaces.json"), "utf8") : "";
19281
- const beforeApplied = existsSync22(appliedSlot) ? fingerprintTree(appliedSlot) : null;
19282
- const beforePrevious = previousSlot !== undefined && existsSync22(previousSlot) ? fingerprintTree(previousSlot) : null;
19375
+ const beforeMarkets = existsSync21(join27(pluginsDir(), "known_marketplaces.json")) ? readFileSync21(join27(pluginsDir(), "known_marketplaces.json"), "utf8") : "";
19376
+ const beforeApplied = existsSync21(appliedSlot) ? fingerprintTree(appliedSlot) : null;
19377
+ const beforePrevious = previousSlot !== undefined && existsSync21(previousSlot) ? fingerprintTree(previousSlot) : null;
19283
19378
  restoreLifecycleCatalog(reference, handle.nativeId, handle.scopeId);
19284
19379
  restorePluginSlice(handle.nativeId, reference);
19285
19380
  if (previousSlot !== undefined && resolve15(previousSlot) !== appliedSlot)
@@ -19287,15 +19382,15 @@ function restoreRollback(handle) {
19287
19382
  const installPath = previousSlot ?? recordedInstallPath(handle.nativeId) ?? appliedSlot;
19288
19383
  const backup = join27(reference, "install");
19289
19384
  rmSync6(installPath, { recursive: true, force: true });
19290
- if (existsSync22(backup)) {
19385
+ if (existsSync21(backup)) {
19291
19386
  mkdirSync6(dirname8(installPath), { recursive: true });
19292
19387
  cpSync5(backup, installPath, { recursive: true });
19293
19388
  }
19294
19389
  const afterEntry = JSON.stringify(readRegistry(registryFile).plugins[handle.nativeId] ?? null);
19295
19390
  const afterEnabled = JSON.stringify(enabledPlugins()[handle.nativeId] ?? null);
19296
- const afterMarkets = existsSync22(join27(pluginsDir(), "known_marketplaces.json")) ? readFileSync21(join27(pluginsDir(), "known_marketplaces.json"), "utf8") : "";
19297
- const afterApplied = existsSync22(appliedSlot) ? fingerprintTree(appliedSlot) : null;
19298
- const afterPrevious = previousSlot !== undefined && existsSync22(previousSlot) ? fingerprintTree(previousSlot) : null;
19391
+ const afterMarkets = existsSync21(join27(pluginsDir(), "known_marketplaces.json")) ? readFileSync21(join27(pluginsDir(), "known_marketplaces.json"), "utf8") : "";
19392
+ const afterApplied = existsSync21(appliedSlot) ? fingerprintTree(appliedSlot) : null;
19393
+ const afterPrevious = previousSlot !== undefined && existsSync21(previousSlot) ? fingerprintTree(previousSlot) : null;
19299
19394
  return {
19300
19395
  receiptId: `claude-rollback-${handle.operationId}`,
19301
19396
  changed: beforeEntry !== afterEntry || beforeEnabled !== afterEnabled || beforeMarkets !== afterMarkets || beforeApplied !== afterApplied || beforePrevious !== afterPrevious
@@ -19343,13 +19438,13 @@ function restoreKnownMarketplace(reference) {
19343
19438
  if (typeof saved.marketplace !== "string")
19344
19439
  return;
19345
19440
  const file = join27(pluginsDir(), "known_marketplaces.json");
19346
- const hadFile = existsSync22(file);
19441
+ const hadFile = existsSync21(file);
19347
19442
  const current = hadFile ? readMarketplaces(file) : {};
19348
19443
  if (saved.entry === null) {
19349
19444
  if (!hadFile || !Object.hasOwn(current, saved.marketplace))
19350
19445
  return;
19351
19446
  const root = lifecycleCatalogRoot(`rollback@${saved.marketplace}`);
19352
- if (existsSync22(root) && (catalogEntries(lifecycleCatalogDocument(root, saved.marketplace)).length > 0 || !emptyOwnedCatalogContainer(root)))
19447
+ if (existsSync21(root) && (catalogEntries(lifecycleCatalogDocument(root, saved.marketplace)).length > 0 || !emptyOwnedCatalogContainer(root)))
19353
19448
  return;
19354
19449
  const next = { ...current };
19355
19450
  delete next[saved.marketplace];
@@ -19405,7 +19500,7 @@ function hasForeignMarketplaceSibling(nativeId, marketplace) {
19405
19500
  if (!isRecord6(registration) || !isRecord6(registration["source"]) || registration["source"]["source"] !== "directory" || typeof registration["source"]["path"] !== "string")
19406
19501
  return false;
19407
19502
  const root = registration["source"]["path"];
19408
- if (!root.startsWith("/") || !existsSync22(root))
19503
+ if (!root.startsWith("/") || !existsSync21(root))
19409
19504
  return false;
19410
19505
  const document = lifecycleCatalogDocument(root, marketplace);
19411
19506
  return catalogEntries(document).some((entry) => {
@@ -19414,14 +19509,14 @@ function hasForeignMarketplaceSibling(nativeId, marketplace) {
19414
19509
  if (!isRecord6(entry) || typeof entry["name"] !== "string" || typeof entry["source"] !== "string" || !entry["source"].startsWith("./"))
19415
19510
  return true;
19416
19511
  const member = resolve15(root, entry["source"]);
19417
- if (!containedPath(root, member) || member === root || !existsSync22(member))
19512
+ if (!containedPath(root, member) || member === root || !existsSync21(member))
19418
19513
  return true;
19419
19514
  assertCatalogPath(root, member);
19420
19515
  return readOwnership(member)?.pluginId !== `${entry["name"]}@${marketplace}`;
19421
19516
  });
19422
19517
  }
19423
19518
  function plgnzOwnedInstall(id, installPath) {
19424
- if (typeof installPath !== "string" || !existsSync22(installPath))
19519
+ if (typeof installPath !== "string" || !existsSync21(installPath))
19425
19520
  return false;
19426
19521
  return readOwnership(installPath)?.pluginId === id;
19427
19522
  }
@@ -19451,19 +19546,19 @@ function disableMarketplaceAutoUpdate(nativeId) {
19451
19546
 
19452
19547
  // src/hosts/codex-writer.ts
19453
19548
  init_codex_hooks();
19454
- import { chmodSync, cpSync as cpSync6, existsSync as existsSync23, lstatSync as lstatSync14, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync6, readFileSync as readFileSync23, readdirSync as readdirSync14, renameSync as renameSync4, rmSync as rmSync7, statSync as statSync10, writeFileSync as writeFileSync7 } from "node:fs";
19549
+ import { chmodSync, cpSync as cpSync6, existsSync as existsSync22, lstatSync as lstatSync15, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync6, readFileSync as readFileSync23, readdirSync as readdirSync14, renameSync as renameSync4, rmSync as rmSync7, statSync as statSync10, writeFileSync as writeFileSync7 } from "node:fs";
19455
19550
  import { dirname as dirname9, join as join29, resolve as resolve16 } from "node:path";
19456
19551
  import { tmpdir as tmpdir3 } from "node:os";
19457
19552
 
19458
19553
  // src/hosts/codex-marketplace-proof.ts
19459
- import { lstatSync as lstatSync13, readFileSync as readFileSync22 } from "node:fs";
19554
+ import { lstatSync as lstatSync14, readFileSync as readFileSync22 } from "node:fs";
19460
19555
  import { join as join28 } from "node:path";
19461
19556
  var codexMarketplaceMetadataFile = ".codex-marketplace-install.json";
19462
19557
  function codexMarketplaceSourceFingerprint(checkout, expected) {
19463
19558
  try {
19464
19559
  let stat;
19465
19560
  try {
19466
- stat = lstatSync13(join28(checkout, codexMarketplaceMetadataFile));
19561
+ stat = lstatSync14(join28(checkout, codexMarketplaceMetadataFile));
19467
19562
  } catch (error) {
19468
19563
  if (error.code === "ENOENT")
19469
19564
  return fingerprintSourceTree(checkout);
@@ -19509,13 +19604,13 @@ var codexWriter = {
19509
19604
  validateStage(stage);
19510
19605
  writeFileSync7(join29(stage, OWNERSHIP2), JSON.stringify({ source: resolved.sourceUri, pluginId: id, fingerprint: plugin.contentFingerprint ?? "" }));
19511
19606
  assertManagedPath2(codexHome(), slot);
19512
- if (existsSync23(slot)) {
19607
+ if (existsSync22(slot)) {
19513
19608
  assertNoSymlinks3(slot);
19514
19609
  assertNoWinningForeignVersion(slot, version, id, resolved.sourceUri);
19515
19610
  const marker = readOwnership2(targetDir);
19516
19611
  if (marker !== null && (marker.source !== resolved.sourceUri || marker.pluginId !== id))
19517
19612
  throw new Error(`codex cache slot ${targetDir} has a different owned source identity; refusing to replace it`);
19518
- if (existsSync23(targetDir) && marker === null && !sameTree2(stage, targetDir)) {
19613
+ if (existsSync22(targetDir) && marker === null && !sameTree2(stage, targetDir)) {
19519
19614
  if (!opts.adoptExisting)
19520
19615
  throw new Error(`codex cache slot ${targetDir} is unowned and differs from the staged representation; pass --adopt-existing to take ownership explicitly`);
19521
19616
  validateCachedIdentity(targetDir, plugin.name, version);
@@ -19541,8 +19636,8 @@ var codexWriter = {
19541
19636
  ensureNativeManifest(stage, plugin.name, version);
19542
19637
  validateStage(stage);
19543
19638
  writeFileSync7(join29(stage, OWNERSHIP2), JSON.stringify({ source: resolved.sourceUri, pluginId: id, fingerprint: plugin.contentFingerprint ?? "" }));
19544
- const identicalUnowned = existsSync23(targetDir) && marker === null && sameTree2(stage, targetDir);
19545
- if (existsSync23(targetDir) && marker === null && !identicalUnowned) {
19639
+ const identicalUnowned = existsSync22(targetDir) && marker === null && sameTree2(stage, targetDir);
19640
+ if (existsSync22(targetDir) && marker === null && !identicalUnowned) {
19546
19641
  if (!opts?.adoptExisting)
19547
19642
  throw new Error(`codex cache slot ${targetDir} is unowned and differs from the staged representation; pass --adopt-existing to take ownership explicitly`);
19548
19643
  validateCachedIdentity(targetDir, plugin.name, version);
@@ -19579,7 +19674,7 @@ var codexWriter = {
19579
19674
  }
19580
19675
  },
19581
19676
  async pin(plugin, opts) {
19582
- if (plugin.path === undefined || !existsSync23(plugin.path))
19677
+ if (plugin.path === undefined || !existsSync22(plugin.path))
19583
19678
  return { changes: [], refusals: [] };
19584
19679
  return pinPluginMcpFiles(plugin.path, mcpCandidates2(), opts);
19585
19680
  },
@@ -19590,7 +19685,7 @@ var codexWriter = {
19590
19685
  const owned = [];
19591
19686
  if (at !== -1) {
19592
19687
  const slot = join29(codexHome(), "plugins", "cache", id.slice(at + 1), id.slice(0, at));
19593
- if (existsSync23(slot)) {
19688
+ if (existsSync22(slot)) {
19594
19689
  assertNoSymlinks3(slot);
19595
19690
  for (const version of readdirSync14(slot)) {
19596
19691
  const candidate = join29(slot, version);
@@ -19601,7 +19696,7 @@ var codexWriter = {
19601
19696
  }
19602
19697
  }
19603
19698
  }
19604
- if (existsSync23(configPath)) {
19699
+ if (existsSync22(configPath)) {
19605
19700
  const toml = readFileSync23(configPath, "utf8");
19606
19701
  const header = `[plugins."${id}"]`;
19607
19702
  const idx = toml.indexOf(header);
@@ -19623,7 +19718,7 @@ enabled = false
19623
19718
  }
19624
19719
  };
19625
19720
  function enable(configPath, id) {
19626
- let toml = existsSync23(configPath) ? readFileSync23(configPath, "utf8") : "";
19721
+ let toml = existsSync22(configPath) ? readFileSync23(configPath, "utf8") : "";
19627
19722
  parseConfigToml(toml, configPath);
19628
19723
  let newToml = toml;
19629
19724
  const header = `[plugins."${id}"]`;
@@ -19667,7 +19762,7 @@ function parseConfigToml(text, path) {
19667
19762
  }
19668
19763
  }
19669
19764
  function isEnabled(configPath, id) {
19670
- if (!existsSync23(configPath))
19765
+ if (!existsSync22(configPath))
19671
19766
  return false;
19672
19767
  const toml = readFileSync23(configPath, "utf8");
19673
19768
  const header = `[plugins."${id}"]`;
@@ -19680,7 +19775,7 @@ function isEnabled(configPath, id) {
19680
19775
  return !/^enabled\s*=\s*false\s*$/mu.test(block);
19681
19776
  }
19682
19777
  function readConfigSnapshot(path) {
19683
- if (!existsSync23(path))
19778
+ if (!existsSync22(path))
19684
19779
  return { existed: false };
19685
19780
  const read = readFileSync23;
19686
19781
  return { existed: true, bytes: read(path) };
@@ -19701,7 +19796,7 @@ function validVersionSegment(value) {
19701
19796
  }
19702
19797
  function readOwnership2(dir) {
19703
19798
  const file = join29(dir, OWNERSHIP2);
19704
- if (!existsSync23(file))
19799
+ if (!existsSync22(file))
19705
19800
  return null;
19706
19801
  try {
19707
19802
  const value = JSON.parse(readFileSync23(file, "utf8"));
@@ -19725,12 +19820,12 @@ function validateStage(stage) {
19725
19820
  if (readPluginManifest(stage) === undefined)
19726
19821
  throw new Error("Codex stage has no Agent Plugins manifest");
19727
19822
  const skills = join29(stage, "skills");
19728
- if (existsSync23(skills) && !statSync10(skills).isDirectory())
19823
+ if (existsSync22(skills) && !statSync10(skills).isDirectory())
19729
19824
  throw new Error("Codex stage skills path is not a directory");
19730
19825
  }
19731
19826
  function validateCachedIdentity(target, expectedName, expectedVersion) {
19732
19827
  const candidates = [join29(target, ".codex-plugin", "plugin.json"), join29(target, "plugin.json"), join29(target, ".plugin", "plugin.json")];
19733
- const manifest = candidates.find(existsSync23);
19828
+ const manifest = candidates.find(existsSync22);
19734
19829
  if (manifest === undefined)
19735
19830
  throw new Error(`unowned Codex cache slot has no manifest: ${target}`);
19736
19831
  const value = JSON.parse(readFileSync23(manifest, "utf8"));
@@ -19740,7 +19835,7 @@ function validateCachedIdentity(target, expectedName, expectedVersion) {
19740
19835
  if (record["name"] === expectedName && record["version"] === expectedVersion)
19741
19836
  return;
19742
19837
  if (manifest === candidates[0] && record["name"] === expectedName && nativeBuildVariant(expectedVersion, record["version"])) {
19743
- const canonical = candidates.slice(1).find(existsSync23);
19838
+ const canonical = candidates.slice(1).find(existsSync22);
19744
19839
  if (canonical !== undefined) {
19745
19840
  const canonicalValue = JSON.parse(readFileSync23(canonical, "utf8"));
19746
19841
  if (typeof canonicalValue === "object" && canonicalValue !== null && !Array.isArray(canonicalValue)) {
@@ -19765,7 +19860,7 @@ function ensureNativeManifest(stage, fallbackName, fallbackVersion) {
19765
19860
  throw new Error("Codex stage has no Agent Plugins manifest");
19766
19861
  for (const path of ["plugin.json", ".plugin/plugin.json", ".claude-plugin/plugin.json"]) {
19767
19862
  const file = join29(stage, path);
19768
- if (existsSync23(file) && JSON.parse(readFileSync23(file, "utf8")).mcpServers !== undefined) {
19863
+ if (existsSync22(file) && JSON.parse(readFileSync23(file, "utf8")).mcpServers !== undefined) {
19769
19864
  throw new Error("Codex inline manifest MCP projection is unverified; use mcp.json or .mcp.json");
19770
19865
  }
19771
19866
  }
@@ -19773,7 +19868,7 @@ function ensureNativeManifest(stage, fallbackName, fallbackVersion) {
19773
19868
  const version = sourceManifest.version ?? fallbackVersion;
19774
19869
  const description = sourceManifest.description ?? `Plugin ${name}`;
19775
19870
  let overlay = {};
19776
- if (existsSync23(native)) {
19871
+ if (existsSync22(native)) {
19777
19872
  const value = JSON.parse(readFileSync23(native, "utf8"));
19778
19873
  if (typeof value !== "object" || value === null || Array.isArray(value))
19779
19874
  throw new Error("Codex native plugin manifest must be an object");
@@ -19787,10 +19882,10 @@ function ensureNativeManifest(stage, fallbackName, fallbackVersion) {
19787
19882
  }
19788
19883
  }
19789
19884
  const pointer = overlay["mcpServers"];
19790
- if (pointer !== undefined && (typeof pointer !== "string" || !pointer.startsWith("./") || pointer.includes("\\") || pointer.split("/").includes("..") || !existsSync23(join29(stage, pointer)))) {
19885
+ if (pointer !== undefined && (typeof pointer !== "string" || !pointer.startsWith("./") || pointer.includes("\\") || pointer.split("/").includes("..") || !existsSync22(join29(stage, pointer)))) {
19791
19886
  throw new Error("Codex native MCP pointer must name an existing plugin-local file");
19792
19887
  }
19793
- const mcpFiles = ["mcp.json", ".mcp.json", ...typeof pointer === "string" ? [pointer] : []].map((path) => join29(stage, path)).filter(existsSync23);
19888
+ const mcpFiles = ["mcp.json", ".mcp.json", ...typeof pointer === "string" ? [pointer] : []].map((path) => join29(stage, path)).filter(existsSync22);
19794
19889
  const declarations = mcpFiles.map((file) => {
19795
19890
  const value = JSON.parse(readFileSync23(file, "utf8"));
19796
19891
  if (value === null || typeof value !== "object" || Array.isArray(value) || !("mcpServers" in value) || value.mcpServers === null || typeof value.mcpServers !== "object" || Array.isArray(value.mcpServers)) {
@@ -19807,7 +19902,7 @@ function ensureNativeManifest(stage, fallbackName, fallbackVersion) {
19807
19902
  version,
19808
19903
  description,
19809
19904
  skills: overlay["skills"] ?? "./skills/",
19810
- ...overlay["mcpServers"] === undefined && existsSync23(join29(stage, "mcp.json")) && !existsSync23(join29(stage, ".mcp.json")) ? { mcpServers: "./mcp.json" } : {}
19905
+ ...overlay["mcpServers"] === undefined && existsSync22(join29(stage, "mcp.json")) && !existsSync22(join29(stage, ".mcp.json")) ? { mcpServers: "./mcp.json" } : {}
19811
19906
  }));
19812
19907
  }
19813
19908
  function mcpDeclarationIdentity(value) {
@@ -19825,9 +19920,9 @@ function assertManagedPath2(root, target) {
19825
19920
  for (const part of ["", ...suffix.split("/").filter(Boolean)]) {
19826
19921
  if (part !== "")
19827
19922
  current = join29(current, part);
19828
- if (!existsSync23(current))
19923
+ if (!existsSync22(current))
19829
19924
  continue;
19830
- const stat = lstatSync14(current);
19925
+ const stat = lstatSync15(current);
19831
19926
  if (stat.isSymbolicLink())
19832
19927
  throw new Error(`Codex managed path component is a symlink: ${current}`);
19833
19928
  if (!stat.isDirectory())
@@ -19836,16 +19931,16 @@ function assertManagedPath2(root, target) {
19836
19931
  }
19837
19932
  function assertManagedConfigPath(root, path) {
19838
19933
  assertManagedPath2(root, dirname9(path));
19839
- if (!existsSync23(path))
19934
+ if (!existsSync22(path))
19840
19935
  return;
19841
- const stat = lstatSync14(path);
19936
+ const stat = lstatSync15(path);
19842
19937
  if (stat.isSymbolicLink())
19843
19938
  throw new Error(`Codex managed config is a symlink: ${path}`);
19844
19939
  if (!stat.isFile())
19845
19940
  throw new Error(`Codex managed config is not a file: ${path}`);
19846
19941
  }
19847
19942
  function activate2(stage, target, slot) {
19848
- if (!existsSync23(target)) {
19943
+ if (!existsSync22(target)) {
19849
19944
  renameSync4(stage, target);
19850
19945
  return { commit: () => {}, rollback: () => rmSync7(target, { recursive: true, force: true }) };
19851
19946
  }
@@ -19920,7 +20015,7 @@ function assertNoSymlinks3(dir) {
19920
20015
  const walk = (current) => {
19921
20016
  for (const entry of readdirSync14(current)) {
19922
20017
  const path = join29(current, entry);
19923
- const stat = lstatSync14(path);
20018
+ const stat = lstatSync15(path);
19924
20019
  if (stat.isSymbolicLink())
19925
20020
  throw new Error(`Codex managed slot contains symlink: ${path}`);
19926
20021
  if (stat.isDirectory())
@@ -20049,10 +20144,10 @@ function revalidateCodexTarget(handle) {
20049
20144
  for (const root of handle.expected.contentRoots)
20050
20145
  assertRequestedCacheOwnership(root.path, handle.prior.contentRoots);
20051
20146
  }
20052
- if (existsSync23(join29(bundle, "marketplace.json"))) {
20147
+ if (existsSync22(join29(bundle, "marketplace.json"))) {
20053
20148
  const metadata = JSON.parse(readFileSync23(join29(bundle, "marketplace.json"), "utf8"));
20054
20149
  const checkout = marketplaceCheckout(metadata.marketplace);
20055
- const actual = existsSync23(checkout) ? fingerprintTree(checkout) : null;
20150
+ const actual = existsSync22(checkout) ? fingerprintTree(checkout) : null;
20056
20151
  if (actual !== metadata.fingerprint)
20057
20152
  throw new Error("Codex marketplace checkout changed after rollback capture");
20058
20153
  }
@@ -20249,13 +20344,13 @@ async function retireCodex(prepared) {
20249
20344
  }
20250
20345
  function restampNativeUpgrade(prepared) {
20251
20346
  const markerPath = join29(prepared.stagingRoot, OWNERSHIP2);
20252
- if (!existsSync23(markerPath))
20347
+ if (!existsSync22(markerPath))
20253
20348
  return;
20254
20349
  const marker = readFileSync23(markerPath, "utf8");
20255
20350
  const version = pluginVersion(prepared.stagingRoot);
20256
20351
  if (validVersionSegment(version)) {
20257
20352
  const destination = cacheDestination(prepared.handle.nativeId, version);
20258
- if (existsSync23(destination) && statSync10(destination).isDirectory()) {
20353
+ if (existsSync22(destination) && statSync10(destination).isDirectory()) {
20259
20354
  assertManagedPath2(codexHome(), destination);
20260
20355
  writeFileSync7(join29(destination, OWNERSHIP2), marker);
20261
20356
  }
@@ -20264,7 +20359,7 @@ function restampNativeUpgrade(prepared) {
20264
20359
  if (nativeId === prepared.handle.nativeId)
20265
20360
  continue;
20266
20361
  const path = codex.listInstalled().find((plugin) => plugin.id === nativeId)?.path;
20267
- if (path === undefined || !existsSync23(path))
20362
+ if (path === undefined || !existsSync22(path))
20268
20363
  continue;
20269
20364
  const existing = readOwnership2(path);
20270
20365
  if (existing?.pluginId === nativeId)
@@ -20283,7 +20378,7 @@ function restampNativeUpgrade(prepared) {
20283
20378
  function priorInstallMarker(prepared, nativeId) {
20284
20379
  const bundle = rollbackBundle(prepared.handle.attemptId, prepared.handle.operationId);
20285
20380
  const manifestPath = join29(bundle, "manifest.json");
20286
- if (!existsSync23(manifestPath))
20381
+ if (!existsSync22(manifestPath))
20287
20382
  return null;
20288
20383
  const manifest = parseRollbackManifest(readFileSync23(manifestPath, "utf8"));
20289
20384
  const install = manifest.installs.find((item) => item.nativeId === nativeId);
@@ -20320,11 +20415,11 @@ function readCodexInstall(handle) {
20320
20415
  function cleanupCodexStage(reference) {
20321
20416
  releasePriorSourceRepair(reference);
20322
20417
  const stage = resolve16(join29(codexHome(), ".plgnz-lifecycle", `${reference.attemptId}:${reference.operationId}`));
20323
- if (existsSync23(stage))
20418
+ if (existsSync22(stage))
20324
20419
  rmSync7(stage, { recursive: true, force: true });
20325
20420
  const rollback = rollbackBundle(reference.attemptId, reference.operationId);
20326
20421
  assertManagedPath2(codexHome(), rollback);
20327
- if (existsSync23(rollback))
20422
+ if (existsSync22(rollback))
20328
20423
  rmSync7(rollback, { recursive: true, force: true });
20329
20424
  return { cleanupId: `cleanup:${reference.attemptId}:${reference.operationId}`, completed: true };
20330
20425
  }
@@ -20384,7 +20479,7 @@ function pluginDataRoots(nativeId) {
20384
20479
  ];
20385
20480
  }
20386
20481
  function retainedTree(paths) {
20387
- const present = paths.filter((path) => existsSync23(path));
20482
+ const present = paths.filter((path) => existsSync22(path));
20388
20483
  const [only, ...rest] = present;
20389
20484
  if (only === undefined)
20390
20485
  return { state: "absent", fingerprint: null };
@@ -20425,7 +20520,7 @@ function cacheDestination(nativeId, version) {
20425
20520
  }
20426
20521
  function cacheFingerprint(nativeId) {
20427
20522
  const path = codex.listInstalled().find((plugin) => plugin.id === nativeId)?.path;
20428
- if (path === undefined || !existsSync23(path))
20523
+ if (path === undefined || !existsSync22(path))
20429
20524
  return null;
20430
20525
  try {
20431
20526
  return fingerprintTree(path);
@@ -20476,7 +20571,7 @@ function codexRollbackReference(attemptId, operationId) {
20476
20571
  const reference = `codex:${attemptId}:${operationId}`;
20477
20572
  const bundle = rollbackBundle(attemptId, operationId);
20478
20573
  const capture = join29(bundle, "native-cache.json");
20479
- if (!existsSync23(capture))
20574
+ if (!existsSync22(capture))
20480
20575
  return reference;
20481
20576
  const digest = new CryptoHasher("sha256").update(readFileSync23(capture, "utf8")).update("\x00").update(readFileSync23(join29(bundle, "manifest.json"), "utf8")).digest("hex");
20482
20577
  return `${reference}:native-cache-sha256:${digest}`;
@@ -20488,14 +20583,14 @@ function nativeCacheFingerprint(root, ignoreOwnership = false) {
20488
20583
  const hash = new CryptoHasher("sha256");
20489
20584
  const read = readFileSync23;
20490
20585
  const walk = (path, relative) => {
20491
- const stat = lstatSync14(path);
20586
+ const stat = lstatSync15(path);
20492
20587
  if (stat.isSymbolicLink() || !stat.isDirectory() && !stat.isFile())
20493
20588
  throw new Error(`Codex native cache contains an unsafe resource: ${path}`);
20494
20589
  hash.update(`${stat.isDirectory() ? "d" : "f"}\x00${relative}\x00${stat.mode & 4095}\x00`);
20495
20590
  if (stat.isDirectory()) {
20496
20591
  for (const entry of readdirSync14(path).sort()) {
20497
20592
  if (ignoreOwnership && relative === "" && entry === OWNERSHIP2) {
20498
- const marker = lstatSync14(join29(path, entry));
20593
+ const marker = lstatSync15(join29(path, entry));
20499
20594
  if (marker.isSymbolicLink() || !marker.isFile())
20500
20595
  throw new Error("Codex attempted cache ownership marker is unsafe");
20501
20596
  continue;
@@ -20525,7 +20620,7 @@ function nativeSlotIsOwned(installation, source) {
20525
20620
  const activeProof = nativeCacheFingerprint(active.path);
20526
20621
  return readdirSync14(slot).every((version) => {
20527
20622
  const path = join29(slot, version);
20528
- const stat = lstatSync14(path);
20623
+ const stat = lstatSync15(path);
20529
20624
  if (stat.isSymbolicLink())
20530
20625
  throw new Error("Codex native cache slot is redirected");
20531
20626
  if (!validVersionSegment(version) || !stat.isDirectory())
@@ -20574,7 +20669,7 @@ function captureNativeCacheSnapshots(projection) {
20574
20669
  }
20575
20670
  function readNativeCacheSnapshots(handle) {
20576
20671
  const file = join29(rollbackBundle(handle.attemptId, handle.operationId), "native-cache.json");
20577
- if (!existsSync23(file))
20672
+ if (!existsSync22(file))
20578
20673
  throw new Error("Codex complete native cache rollback capture is missing");
20579
20674
  if (handle.rollbackReference !== codexRollbackReference(handle.attemptId, handle.operationId))
20580
20675
  throw new Error("Codex complete native cache authority differs from its sealed rollback reference");
@@ -20615,7 +20710,7 @@ function saveCodexRollback(attemptId, operationId, nativeIds) {
20615
20710
  assertManagedPath2(codexHome(), bundle);
20616
20711
  rmSync7(bundle, { recursive: true, force: true });
20617
20712
  mkdirSync7(bundle, { recursive: true });
20618
- const toml = existsSync23(configFile()) ? readFileSync23(configFile(), "utf8") : "";
20713
+ const toml = existsSync22(configFile()) ? readFileSync23(configFile(), "utf8") : "";
20619
20714
  const tables = nativeIds.map((nativeId) => ({ nativeId, block: extractPluginTable(toml, nativeId) }));
20620
20715
  const installs = nativeIds.map((nativeId, index) => {
20621
20716
  const slot = pluginSlot(nativeId);
@@ -20632,7 +20727,7 @@ function saveCodexRollback(attemptId, operationId, nativeIds) {
20632
20727
  function restoreCodexRollback(handle) {
20633
20728
  const bundle = rollbackBundle(handle.attemptId, handle.operationId);
20634
20729
  const manifestPath = join29(bundle, "manifest.json");
20635
- if (!existsSync23(manifestPath))
20730
+ if (!existsSync22(manifestPath))
20636
20731
  throw new Error(`codex lifecycle rollback bundle is missing: ${handle.operationId}`);
20637
20732
  const manifest = parseRollbackManifest(readFileSync23(manifestPath, "utf8"));
20638
20733
  assertMarketplaceRollbackCurrent(handle);
@@ -20669,7 +20764,7 @@ function marketplaceCheckout(marketplace) {
20669
20764
  return path;
20670
20765
  }
20671
20766
  function assertNativeRollbackSurfaces(handle, manifest, bundle) {
20672
- const config = existsSync23(configFile()) ? readFileSync23(configFile(), "utf8") : "";
20767
+ const config = existsSync22(configFile()) ? readFileSync23(configFile(), "utf8") : "";
20673
20768
  for (const table of manifest.tables) {
20674
20769
  if (extractPluginTable(config, table.nativeId) !== table.block)
20675
20770
  throw new Error("Codex affected plugin config changed outside the captured native attempt; refusing rollback before any restore write");
@@ -20684,14 +20779,14 @@ function assertNativeRollbackSurfaces(handle, manifest, bundle) {
20684
20779
  const currentFingerprint = nativeCacheFingerprint(slot.path);
20685
20780
  if (currentFingerprint === slot.fingerprint)
20686
20781
  return { ...slot, currentFingerprint };
20687
- const projected = projections.find((path) => existsSync23(path) && readOwnership2(path)?.pluginId === slot.nativeId);
20782
+ const projected = projections.find((path) => existsSync22(path) && readOwnership2(path)?.pluginId === slot.nativeId);
20688
20783
  let containsCandidate = false;
20689
20784
  for (const version of readdirSync14(slot.path)) {
20690
20785
  const path = join29(slot.path, version);
20691
- if (!validVersionSegment(version) || !lstatSync14(path).isDirectory())
20786
+ if (!validVersionSegment(version) || !lstatSync15(path).isDirectory())
20692
20787
  throw new Error("Codex complete cache contains an unproven resource; refusing rollback before any restore write");
20693
20788
  const priorVersion = join29(saved, version);
20694
- if (existsSync23(priorVersion) && nativeCacheFingerprint(path) === nativeCacheFingerprint(priorVersion))
20789
+ if (existsSync22(priorVersion) && nativeCacheFingerprint(path) === nativeCacheFingerprint(priorVersion))
20695
20790
  continue;
20696
20791
  if (projected === undefined || version !== pluginVersion(projected) || (readOwnership2(path) === null ? nativeCacheFingerprint(path, true) !== nativeCacheFingerprint(projected, true) : nativeCacheFingerprint(path) !== nativeCacheFingerprint(projected))) {
20697
20792
  throw new Error("Codex complete cache changed outside the captured native attempt; refusing rollback before any restore write");
@@ -20710,7 +20805,7 @@ function captureMarketplaceRollback(projection) {
20710
20805
  throw new Error("native Codex mutation has no bounded marketplace");
20711
20806
  const checkout = marketplaceCheckout(marketplace);
20712
20807
  const bundle = rollbackBundle(projection.attemptId, projection.operationId);
20713
- const fingerprint = existsSync23(checkout) ? fingerprintTree(checkout) : null;
20808
+ const fingerprint = existsSync22(checkout) ? fingerprintTree(checkout) : null;
20714
20809
  if (fingerprint !== null) {
20715
20810
  const snapshot = join29(bundle, "marketplace");
20716
20811
  cpSync6(checkout, snapshot, { recursive: true });
@@ -20721,13 +20816,13 @@ function captureMarketplaceRollback(projection) {
20721
20816
  }
20722
20817
  function captureAttemptedMarketplace(handle) {
20723
20818
  const metadata = join29(rollbackBundle(handle.attemptId, handle.operationId), "marketplace.json");
20724
- if (!existsSync23(metadata))
20819
+ if (!existsSync22(metadata))
20725
20820
  return;
20726
20821
  const marketplace = marketplaceOf(handle.nativeId);
20727
20822
  if (marketplace === null || handle.sourceLocator === null)
20728
20823
  return;
20729
20824
  const checkout = marketplaceCheckout(marketplace);
20730
- if (!existsSync23(checkout))
20825
+ if (!existsSync22(checkout))
20731
20826
  return;
20732
20827
  const capture = JSON.parse(readFileSync23(metadata, "utf8"));
20733
20828
  if (typeof capture["sourceFingerprint"] !== "string" || !/^[0-9a-f]{64}$/u.test(capture["sourceFingerprint"]))
@@ -20742,14 +20837,14 @@ function captureAttemptedMarketplace(handle) {
20742
20837
  }
20743
20838
  function assertMarketplaceRollbackCurrent(handle) {
20744
20839
  const metadata = join29(rollbackBundle(handle.attemptId, handle.operationId), "marketplace.json");
20745
- if (!existsSync23(metadata))
20840
+ if (!existsSync22(metadata))
20746
20841
  return;
20747
20842
  const row = JSON.parse(readFileSync23(metadata, "utf8"));
20748
20843
  const marketplace = marketplaceOf(handle.nativeId);
20749
20844
  if (marketplace === null || row["marketplace"] !== marketplace || row["fingerprint"] !== null && (typeof row["fingerprint"] !== "string" || !/^[0-9a-f]{64}$/u.test(row["fingerprint"])) || row["attemptedFingerprint"] !== undefined && (typeof row["attemptedFingerprint"] !== "string" || !/^[0-9a-f]{64}$/u.test(row["attemptedFingerprint"])))
20750
20845
  throw new Error("invalid Codex marketplace rollback capture");
20751
20846
  const checkout = marketplaceCheckout(marketplace);
20752
- const current = existsSync23(checkout) ? fingerprintTree(checkout) : null;
20847
+ const current = existsSync22(checkout) ? fingerprintTree(checkout) : null;
20753
20848
  if (current !== row["fingerprint"] && current !== row["attemptedFingerprint"]) {
20754
20849
  throw new Error("Codex marketplace checkout changed outside the captured native attempt; refusing rollback before any restore write");
20755
20850
  }
@@ -20760,7 +20855,7 @@ function assertMarketplaceRollbackCurrent(handle) {
20760
20855
  function restoreMarketplaceRollback(handle) {
20761
20856
  const bundle = rollbackBundle(handle.attemptId, handle.operationId);
20762
20857
  const metadata = join29(bundle, "marketplace.json");
20763
- if (!existsSync23(metadata))
20858
+ if (!existsSync22(metadata))
20764
20859
  return;
20765
20860
  const capture = JSON.parse(readFileSync23(metadata, "utf8"));
20766
20861
  if (typeof capture !== "object" || capture === null || Array.isArray(capture))
@@ -20771,7 +20866,7 @@ function restoreMarketplaceRollback(handle) {
20771
20866
  throw new Error("invalid Codex marketplace rollback identity");
20772
20867
  const checkout = marketplaceCheckout(marketplace);
20773
20868
  if (row["fingerprint"] === null) {
20774
- if (existsSync23(checkout))
20869
+ if (existsSync22(checkout))
20775
20870
  rmSync7(checkout, { recursive: true });
20776
20871
  return;
20777
20872
  }
@@ -20803,18 +20898,18 @@ function pluginSlot(nativeId) {
20803
20898
  return join29(codexHome(), "plugins", "cache", marketplace, name);
20804
20899
  }
20805
20900
  function slotVersions(slot) {
20806
- if (!existsSync23(slot))
20901
+ if (!existsSync22(slot))
20807
20902
  return [];
20808
20903
  return readdirSync14(slot).filter((version) => {
20809
20904
  try {
20810
- return lstatSync14(join29(slot, version)).isDirectory();
20905
+ return lstatSync15(join29(slot, version)).isDirectory();
20811
20906
  } catch {
20812
20907
  return false;
20813
20908
  }
20814
20909
  }).sort();
20815
20910
  }
20816
20911
  function removeUnsnapshotVersions(slot, versions) {
20817
- if (slot === null || !existsSync23(slot))
20912
+ if (slot === null || !existsSync22(slot))
20818
20913
  return;
20819
20914
  assertManagedPath2(codexHome(), slot);
20820
20915
  const kept = new Set(versions);
@@ -20827,10 +20922,10 @@ function removeUnsnapshotVersions(slot, versions) {
20827
20922
  }
20828
20923
  }
20829
20924
  function rollbackSurface(nativeIds) {
20830
- const config = existsSync23(configFile()) ? readFileSync23(configFile(), "utf8") : "absent";
20925
+ const config = existsSync22(configFile()) ? readFileSync23(configFile(), "utf8") : "absent";
20831
20926
  const slots = nativeIds.map((nativeId) => {
20832
20927
  const slot = pluginSlot(nativeId);
20833
- if (slot === null || !existsSync23(slot))
20928
+ if (slot === null || !existsSync22(slot))
20834
20929
  return `${nativeId}:`;
20835
20930
  return `${nativeId}:${slotVersions(slot).map((version) => {
20836
20931
  const path = join29(slot, version);
@@ -20860,7 +20955,7 @@ function extractPluginTable(toml, id) {
20860
20955
  }
20861
20956
  function restorePluginTables(tables) {
20862
20957
  const configPath = configFile();
20863
- const current = existsSync23(configPath) ? readFileSync23(configPath, "utf8") : "";
20958
+ const current = existsSync22(configPath) ? readFileSync23(configPath, "utf8") : "";
20864
20959
  let next = current;
20865
20960
  for (const table of tables)
20866
20961
  next = applyPluginTable(next, table.nativeId, table.block);
@@ -20998,7 +21093,7 @@ function nativeProjection2(request) {
20998
21093
  }
20999
21094
  if (request.pins.length > 0)
21000
21095
  return { kind: "requires-managed", reasonId: "pins-present" };
21001
- if (existsSync23(join29(request.snapshot.snapshotRoot, codexMarketplaceMetadataFile))) {
21096
+ if (existsSync22(join29(request.snapshot.snapshotRoot, codexMarketplaceMetadataFile))) {
21002
21097
  return { kind: "requires-managed", reasonId: "native-reserved-source-metadata" };
21003
21098
  }
21004
21099
  const marketplace = marketplaceOf(request.snapshot.nativeId);
@@ -21024,16 +21119,16 @@ function nativeProjection2(request) {
21024
21119
  }
21025
21120
  function assertRequestedCacheOwnership(destination, observedRoots) {
21026
21121
  assertManagedPath2(codexHome(), destination);
21027
- if (existsSync23(destination) && !observedRoots.some((root) => root.path === destination)) {
21122
+ if (existsSync22(destination) && !observedRoots.some((root) => root.path === destination)) {
21028
21123
  throw new Error("Codex inactive requested version has no captured active ownership; refusing to replace it");
21029
21124
  }
21030
21125
  const slot = dirname9(destination);
21031
- if (!existsSync23(slot))
21126
+ if (!existsSync22(slot))
21032
21127
  return;
21033
21128
  const requested = destination.slice(slot.length + 1);
21034
21129
  for (const version of readdirSync14(slot)) {
21035
21130
  const path = join29(slot, version);
21036
- if (lstatSync14(path).isDirectory() && wins(version, requested) && !observedRoots.some((root) => root.path === path)) {
21131
+ if (lstatSync15(path).isDirectory() && wins(version, requested) && !observedRoots.some((root) => root.path === path)) {
21037
21132
  throw new Error(`Codex inactive cache version ${version} has no captured retirement authority and would remain active over ${requested}`);
21038
21133
  }
21039
21134
  }
@@ -21083,7 +21178,7 @@ function marketplaceOf(nativeId) {
21083
21178
  return nativeId.slice(at + 1);
21084
21179
  }
21085
21180
  function readConfigDocument() {
21086
- if (!existsSync23(configFile()))
21181
+ if (!existsSync22(configFile()))
21087
21182
  return null;
21088
21183
  try {
21089
21184
  const parsed = parse(readFileSync23(configFile(), "utf8"));
@@ -21121,7 +21216,7 @@ function comparePrerelease2(left, right) {
21121
21216
  }
21122
21217
 
21123
21218
  // src/hosts/kimi-writer.ts
21124
- import { cpSync as cpSync7, existsSync as existsSync24, lstatSync as lstatSync15, mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync7, readFileSync as readFileSync24, readdirSync as readdirSync15, realpathSync as realpathSync4, renameSync as renameSync5, rmSync as rmSync8, statSync as statSync11, writeFileSync as writeFileSync8 } from "node:fs";
21219
+ import { cpSync as cpSync7, existsSync as existsSync23, lstatSync as lstatSync16, mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync7, readFileSync as readFileSync24, readdirSync as readdirSync15, realpathSync as realpathSync4, renameSync as renameSync5, rmSync as rmSync8, statSync as statSync11, writeFileSync as writeFileSync8 } from "node:fs";
21125
21220
  import { dirname as dirname10, isAbsolute as isAbsolute11, join as join30, resolve as resolve17 } from "node:path";
21126
21221
  import { tmpdir as tmpdir4 } from "node:os";
21127
21222
  var MARKER4 = ".plgnz-install.json";
@@ -21137,7 +21232,7 @@ var samePhysicalKimiNativeIdentity = (plugin, prior, observation) => {
21137
21232
  const managed = managedPluginPath(plugin.name);
21138
21233
  const registryFile = join30(pluginsDir2(), "installed.json");
21139
21234
  assertKimiManaged(plugin.name, managed, registryFile);
21140
- if (!existsSync24(managed))
21235
+ if (!existsSync23(managed))
21141
21236
  return null;
21142
21237
  const rows = readRegistry2(registryFile).plugins.filter((row) => row.id === plugin.name || sameRoot(row.root, managed));
21143
21238
  if (rows.length !== 1 || rows[0].id !== plugin.name || rows[0].enabled !== true || !sameRoot(rows[0].root, managed))
@@ -21188,8 +21283,8 @@ var kimiWriter = {
21188
21283
  const differentSource = marker !== null && !lifecycleLocalSource && marker.source !== resolved.sourceUri;
21189
21284
  if (marker !== null && (differentSource || !markerHasExpectedIdentity))
21190
21285
  throw new Error(`Kimi plugin ${id} belongs to another source; refusing to replace it`);
21191
- const same = existsSync24(target) && sameTree3(stage, target);
21192
- if (existsSync24(target) && marker === null && !same) {
21286
+ const same = existsSync23(target) && sameTree3(stage, target);
21287
+ if (existsSync23(target) && marker === null && !same) {
21193
21288
  if (!opts?.adoptExisting)
21194
21289
  throw new Error(`Kimi managed plugin ${id} is unowned and differs from the staged representation; pass --adopt-existing to take ownership explicitly`);
21195
21290
  validateNativeIdentity(target, id);
@@ -21207,13 +21302,13 @@ var kimiWriter = {
21207
21302
  }
21208
21303
  if (unchanged)
21209
21304
  return "unchanged";
21210
- const registryBefore = existsSync24(registryFile) ? readFileSync24(registryFile, "utf8") : undefined;
21305
+ const registryBefore = existsSync23(registryFile) ? readFileSync24(registryFile, "utf8") : undefined;
21211
21306
  const backup = moveAside2(target, managedRoot);
21212
21307
  try {
21213
21308
  await nativeInstall(stage, kimiRootPath(), resolveKimiBinary());
21214
21309
  const after = readRegistry2(registryFile);
21215
21310
  const row = after.plugins.find((candidate) => candidate.id === id);
21216
- if (row === undefined || row.enabled !== true || !sameRoot(row.root, target) || !existsSync24(target) || !sameTree3(stage, target)) {
21311
+ if (row === undefined || row.enabled !== true || !sameRoot(row.root, target) || !existsSync23(target) || !sameTree3(stage, target)) {
21217
21312
  throw new Error(`Kimi native install did not produce enabled managed plugin ${id}`);
21218
21313
  }
21219
21314
  } catch (error) {
@@ -21228,7 +21323,7 @@ var kimiWriter = {
21228
21323
  }
21229
21324
  },
21230
21325
  async pin(plugin, opts) {
21231
- if (plugin.path === undefined || !existsSync24(plugin.path))
21326
+ if (plugin.path === undefined || !existsSync23(plugin.path))
21232
21327
  return { changes: [], refusals: [] };
21233
21328
  return pinPluginMcpFiles(plugin.path, mcpCandidates3(), opts);
21234
21329
  },
@@ -21272,7 +21367,7 @@ function sameRoot(value, target) {
21272
21367
  }
21273
21368
  }
21274
21369
  function readRegistry2(path) {
21275
- if (!existsSync24(path))
21370
+ if (!existsSync23(path))
21276
21371
  return { version: 1, plugins: [] };
21277
21372
  let raw;
21278
21373
  try {
@@ -21292,18 +21387,18 @@ function restore(path, value) {
21292
21387
  }
21293
21388
  function restoreRegistryRow(registryFile, id, reference) {
21294
21389
  const rowFile = join30(reference, "registry.row.json");
21295
- const priorRow = existsSync24(rowFile) ? parseJson(rowFile, "Kimi registry row") : undefined;
21390
+ const priorRow = existsSync23(rowFile) ? parseJson(rowFile, "Kimi registry row") : undefined;
21296
21391
  if (priorRow !== undefined && priorRow.id !== id)
21297
21392
  throw new Error(`Kimi rollback row is not ${id}`);
21298
- const live = existsSync24(registryFile) ? readRegistry2(registryFile) : { version: 1, plugins: [] };
21393
+ const live = existsSync23(registryFile) ? readRegistry2(registryFile) : { version: 1, plugins: [] };
21299
21394
  const plugins = live.plugins.filter((row) => row.id !== id);
21300
21395
  if (priorRow !== undefined)
21301
21396
  plugins.push(priorRow);
21302
- if (plugins.length === 0 && existsSync24(join30(reference, "registry.absent"))) {
21397
+ if (plugins.length === 0 && existsSync23(join30(reference, "registry.absent"))) {
21303
21398
  rmSync8(registryFile, { force: true });
21304
21399
  return;
21305
21400
  }
21306
- if (!existsSync24(registryFile) && plugins.length === 0)
21401
+ if (!existsSync23(registryFile) && plugins.length === 0)
21307
21402
  return;
21308
21403
  writeFileSync8(registryFile, JSON.stringify({ version: 1, plugins }));
21309
21404
  }
@@ -21324,13 +21419,13 @@ function projectStagedKimi(stage, expectedName) {
21324
21419
  if (manifest[key] !== undefined)
21325
21420
  throw new Error(`Kimi root manifest ${key} is unsupported without an explicit native declaration`);
21326
21421
  const skills = join30(stage, "skills");
21327
- if (existsSync24(skills) && !statSync11(skills).isDirectory())
21422
+ if (existsSync23(skills) && !statSync11(skills).isDirectory())
21328
21423
  throw new Error(`Kimi skills path is not a directory: ${skills}`);
21329
- if (existsSync24(skills))
21424
+ if (existsSync23(skills))
21330
21425
  assertKimiSkillPolicies(skills);
21331
21426
  const native = join30(stage, "kimi.plugin.json");
21332
21427
  let supplied = {};
21333
- if (existsSync24(native)) {
21428
+ if (existsSync23(native)) {
21334
21429
  supplied = parseJson(native, "Kimi native manifest");
21335
21430
  if (supplied.name !== undefined && supplied.name !== expectedName)
21336
21431
  throw new Error(`Kimi native manifest name conflicts with ${expectedName}`);
@@ -21348,7 +21443,7 @@ function projectStagedKimi(stage, expectedName) {
21348
21443
  }
21349
21444
  const commands = prepareCommands(stage, typeof supplied.commands === "string" ? supplied.commands : undefined);
21350
21445
  const mcpServers = collectMcpServers(stage, manifest, supplied);
21351
- const nativeManifest = { name: expectedName, ...typeof manifest.version === "string" ? { version: manifest.version } : {}, ...typeof manifest.description === "string" ? { description: manifest.description } : {}, ...existsSync24(skills) ? { skills: "./skills/" } : {}, ...commands !== undefined ? { commands } : {}, ...mcpServers !== undefined ? { mcpServers } : {} };
21446
+ const nativeManifest = { name: expectedName, ...typeof manifest.version === "string" ? { version: manifest.version } : {}, ...typeof manifest.description === "string" ? { description: manifest.description } : {}, ...existsSync23(skills) ? { skills: "./skills/" } : {}, ...commands !== undefined ? { commands } : {}, ...mcpServers !== undefined ? { mcpServers } : {} };
21352
21447
  writeFileSync8(native, JSON.stringify(nativeManifest, null, 2));
21353
21448
  assertNoSymlinks4(stage);
21354
21449
  }
@@ -21371,12 +21466,12 @@ function collectMcpServers(stage, manifest, supplied) {
21371
21466
  };
21372
21467
  add("native manifest", supplied.mcpServers);
21373
21468
  const legacyNative = join30(stage, ".kimi-plugin", "plugin.json");
21374
- if (existsSync24(legacyNative))
21469
+ if (existsSync23(legacyNative))
21375
21470
  add(".kimi-plugin/plugin.json", parseJson(legacyNative, ".kimi-plugin/plugin.json").mcpServers);
21376
21471
  add("root plugin manifest", manifest.mcpServers);
21377
21472
  for (const file of [".mcp.json", "mcp.json"]) {
21378
21473
  const path = join30(stage, file);
21379
- if (!existsSync24(path))
21474
+ if (!existsSync23(path))
21380
21475
  continue;
21381
21476
  add(file, parseJson(path, file).mcpServers);
21382
21477
  }
@@ -21384,14 +21479,14 @@ function collectMcpServers(stage, manifest, supplied) {
21384
21479
  }
21385
21480
  function prepareCommands(stage, supplied) {
21386
21481
  const commands = join30(stage, "commands");
21387
- if (existsSync24(commands) && !statSync11(commands).isDirectory())
21482
+ if (existsSync23(commands) && !statSync11(commands).isDirectory())
21388
21483
  throw new Error(`Kimi commands path is not a directory: ${commands}`);
21389
21484
  const claude = join30(stage, ".claude", "commands");
21390
- const selected = supplied === undefined ? existsSync24(claude) ? "./.claude/commands/" : existsSync24(commands) ? "./commands/" : undefined : supplied.endsWith("/") ? supplied : `${supplied}/`;
21485
+ const selected = supplied === undefined ? existsSync23(claude) ? "./.claude/commands/" : existsSync23(commands) ? "./commands/" : undefined : supplied.endsWith("/") ? supplied : `${supplied}/`;
21391
21486
  if (selected === undefined)
21392
21487
  return;
21393
21488
  const dir = selected.startsWith("./.claude/") ? claude : commands;
21394
- if (!existsSync24(dir))
21489
+ if (!existsSync23(dir))
21395
21490
  throw new Error(`Kimi native commands pointer has no directory: ${selected}`);
21396
21491
  assertMarkdownCommandTree(dir);
21397
21492
  if (!containsMarkdown(dir))
@@ -21401,7 +21496,7 @@ function prepareCommands(stage, supplied) {
21401
21496
  function assertKimiSkillPolicies(dir) {
21402
21497
  for (const name of readdirSync15(dir)) {
21403
21498
  const path = join30(dir, name);
21404
- const stat = lstatSync15(path);
21499
+ const stat = lstatSync16(path);
21405
21500
  if (stat.isDirectory())
21406
21501
  assertKimiSkillPolicies(path);
21407
21502
  else if (stat.isFile() && name === "SKILL.md") {
@@ -21434,7 +21529,7 @@ function openingFrontmatter2(raw, path) {
21434
21529
  function assertMarkdownCommandTree(dir) {
21435
21530
  for (const name of readdirSync15(dir)) {
21436
21531
  const path = join30(dir, name);
21437
- const stat = lstatSync15(path);
21532
+ const stat = lstatSync16(path);
21438
21533
  if (stat.isSymbolicLink())
21439
21534
  throw new Error(`Kimi command source contains symlink: ${path}`);
21440
21535
  if (stat.isDirectory())
@@ -21465,7 +21560,7 @@ function containsMarkdown(dir) {
21465
21560
  });
21466
21561
  }
21467
21562
  function readSourceManifest(stage) {
21468
- const file = [join30(stage, "plugin.json"), join30(stage, ".plugin", "plugin.json")].find(existsSync24);
21563
+ const file = [join30(stage, "plugin.json"), join30(stage, ".plugin", "plugin.json")].find(existsSync23);
21469
21564
  if (file === undefined)
21470
21565
  throw new Error("Kimi stage has no Agent Plugins manifest");
21471
21566
  return parseJson(file, "Agent Plugins manifest");
@@ -21482,7 +21577,7 @@ function parseJson(path, label) {
21482
21577
  }
21483
21578
  function validateNativeIdentity(target, id) {
21484
21579
  const file = join30(target, "kimi.plugin.json");
21485
- if (!existsSync24(file) || parseJson(file, "Kimi native manifest").name !== id)
21580
+ if (!existsSync23(file) || parseJson(file, "Kimi native manifest").name !== id)
21486
21581
  throw new Error(`unowned Kimi managed plugin has no matching native manifest: ${target}`);
21487
21582
  }
21488
21583
  function readOwnership3(target) {
@@ -21514,7 +21609,7 @@ function rewriteOwnership(target, ownership) {
21514
21609
  }
21515
21610
  }
21516
21611
  function sameTree3(left, right) {
21517
- if (!existsSync24(right))
21612
+ if (!existsSync23(right))
21518
21613
  return false;
21519
21614
  const readBytes = readFileSync24;
21520
21615
  const list = (root) => {
@@ -21525,7 +21620,7 @@ function sameTree3(left, right) {
21525
21620
  continue;
21526
21621
  const path = join30(dir, name);
21527
21622
  const rel = prefix ? `${prefix}/${name}` : name;
21528
- const stat = lstatSync15(path);
21623
+ const stat = lstatSync16(path);
21529
21624
  if (stat.isSymbolicLink())
21530
21625
  throw new Error(`Kimi plugin contains symlink: ${path}`);
21531
21626
  if (stat.isDirectory())
@@ -21543,14 +21638,14 @@ function sameTree3(left, right) {
21543
21638
  }
21544
21639
  function assertNoSymlinks4(root) {
21545
21640
  const walk = (dir) => {
21546
- const stat = lstatSync15(dir);
21641
+ const stat = lstatSync16(dir);
21547
21642
  if (stat.isSymbolicLink())
21548
21643
  throw new Error(`Kimi plugin contains symlink: ${dir}`);
21549
21644
  if (!stat.isDirectory())
21550
21645
  throw new Error(`Kimi plugin path is not a directory: ${dir}`);
21551
21646
  for (const name of readdirSync15(dir)) {
21552
21647
  const path = join30(dir, name);
21553
- const child = lstatSync15(path);
21648
+ const child = lstatSync16(path);
21554
21649
  if (child.isSymbolicLink())
21555
21650
  throw new Error(`Kimi plugin contains symlink: ${path}`);
21556
21651
  if (child.isDirectory())
@@ -21562,7 +21657,7 @@ function assertNoSymlinks4(root) {
21562
21657
  walk(root);
21563
21658
  }
21564
21659
  function moveAside2(target, root) {
21565
- if (!existsSync24(target))
21660
+ if (!existsSync23(target))
21566
21661
  return { commit: () => {}, rollback: () => {} };
21567
21662
  mkdirSync8(root, { recursive: true });
21568
21663
  const dir = mkdtempSync7(join30(root, ".plgnz-kimi-backup-"));
@@ -21575,7 +21670,7 @@ function moveAside2(target, root) {
21575
21670
  }
21576
21671
  function lstatIfPresent(path) {
21577
21672
  try {
21578
- return lstatSync15(path);
21673
+ return lstatSync16(path);
21579
21674
  } catch (error) {
21580
21675
  if (error.code === "ENOENT")
21581
21676
  return;
@@ -21591,7 +21686,7 @@ function assertManagedPath3(root, target) {
21591
21686
  for (const part of selected.slice(base.length).split("/").filter(Boolean)) {
21592
21687
  if (lstatIfPresent(current) === undefined)
21593
21688
  break;
21594
- const stat = lstatSync15(current);
21689
+ const stat = lstatSync16(current);
21595
21690
  if (stat.isSymbolicLink())
21596
21691
  throw new Error(`Kimi managed path component is a symlink: ${current}`);
21597
21692
  if (!stat.isDirectory())
@@ -21632,7 +21727,7 @@ function currentKimiVersion(exitCode, version) {
21632
21727
  }
21633
21728
  function resolveKimiBinary() {
21634
21729
  const binary = kimiBinaryPath();
21635
- if (!existsSync24(binary))
21730
+ if (!existsSync23(binary))
21636
21731
  throw new Error(`current Kimi Code binary not found: ${binary}`);
21637
21732
  const probed = readKimiBinaryVersion(binary);
21638
21733
  if (currentKimiVersion(probed.exitCode, probed.version) === undefined)
@@ -21842,11 +21937,11 @@ var kimiLifecycle = {
21842
21937
  const managed = managedPluginPath(projection.packageName);
21843
21938
  const registryFile = join30(pluginsDir2(), "installed.json");
21844
21939
  assertKimiManaged(projection.packageName, managed, registryFile);
21845
- if (existsSync24(managed))
21940
+ if (existsSync23(managed))
21846
21941
  cpSync7(managed, join30(rollbackReference, "managed"), { recursive: true });
21847
- const priorRow = existsSync24(registryFile) ? readRegistry2(registryFile).plugins.find((row) => row.id === projection.packageName) : undefined;
21942
+ const priorRow = existsSync23(registryFile) ? readRegistry2(registryFile).plugins.find((row) => row.id === projection.packageName) : undefined;
21848
21943
  if (priorRow === undefined) {
21849
- if (!existsSync24(registryFile))
21944
+ if (!existsSync23(registryFile))
21850
21945
  writeFileSync8(join30(rollbackReference, "registry.absent"), "");
21851
21946
  } else
21852
21947
  writeFileSync8(join30(rollbackReference, "registry.row.json"), JSON.stringify(priorRow));
@@ -21874,10 +21969,10 @@ var kimiLifecycle = {
21874
21969
  const managed = managedPluginPath(id);
21875
21970
  const registryFile = join30(pluginsDir2(), "installed.json");
21876
21971
  assertKimiManaged(id, managed, registryFile);
21877
- const priorRow = existsSync24(registryFile) ? readRegistry2(registryFile).plugins.find((row) => row.id === id) : undefined;
21878
- const marker = existsSync24(managed) ? readOwnership3(managed) : null;
21972
+ const priorRow = existsSync23(registryFile) ? readRegistry2(registryFile).plugins.find((row) => row.id === id) : undefined;
21973
+ const marker = existsSync23(managed) ? readOwnership3(managed) : null;
21879
21974
  const legacyMarker = marker !== null && !marker.pluginId.includes("@") && prepared.handle.nativeId.startsWith(`${marker.pluginId}@`);
21880
- if (existsSync24(managed) && priorRow?.enabled === true && sameRoot(priorRow.root, managed) && sameTree3(prepared.stagingRoot, managed)) {
21975
+ if (existsSync23(managed) && priorRow?.enabled === true && sameRoot(priorRow.root, managed) && sameTree3(prepared.stagingRoot, managed)) {
21881
21976
  if (legacyMarker) {
21882
21977
  rewriteOwnership(managed, {
21883
21978
  ...marker,
@@ -21888,12 +21983,12 @@ var kimiLifecycle = {
21888
21983
  }
21889
21984
  return { receiptId: `kimi-apply:${prepared.handle.attemptId}:${prepared.handle.operationId}`, changed: false };
21890
21985
  }
21891
- const registryBefore = existsSync24(registryFile) ? readFileSync24(registryFile, "utf8") : undefined;
21986
+ const registryBefore = existsSync23(registryFile) ? readFileSync24(registryFile, "utf8") : undefined;
21892
21987
  const backup = moveAside2(managed, dirname10(managed));
21893
21988
  try {
21894
21989
  await nativeInstall(prepared.stagingRoot, kimiRootPath(), resolveKimiBinary());
21895
21990
  const row = readRegistry2(registryFile).plugins.find((candidate) => candidate.id === id);
21896
- if (row === undefined || row.enabled !== true || !sameRoot(row.root, managed) || !existsSync24(managed) || !sameTree3(prepared.stagingRoot, managed)) {
21991
+ if (row === undefined || row.enabled !== true || !sameRoot(row.root, managed) || !existsSync23(managed) || !sameTree3(prepared.stagingRoot, managed)) {
21897
21992
  throw new Error(`Kimi native install did not produce enabled managed plugin ${id}`);
21898
21993
  }
21899
21994
  backup.commit();
@@ -21916,7 +22011,7 @@ var kimiLifecycle = {
21916
22011
  const reference = handle.rollbackReference;
21917
22012
  rmSync8(managed, { recursive: true, force: true });
21918
22013
  const backup = join30(reference, "managed");
21919
- if (existsSync24(backup))
22014
+ if (existsSync23(backup))
21920
22015
  cpSync7(backup, managed, { recursive: true });
21921
22016
  restoreRegistryRow(registryFile, id, reference);
21922
22017
  return { receiptId: `kimi-rollback:${handle.attemptId}:${handle.operationId}`, changed: true };
@@ -21924,7 +22019,7 @@ var kimiLifecycle = {
21924
22019
  cleanup: async (reference) => {
21925
22020
  const root = join30(pluginsDir2(), ".plgnz-kimi-lifecycle");
21926
22021
  rmSync8(join30(root, safeSegment(reference.attemptId)), { recursive: true, force: true });
21927
- if (existsSync24(root) && readdirSync15(root).length === 0)
22022
+ if (existsSync23(root) && readdirSync15(root).length === 0)
21928
22023
  rmSync8(root, { recursive: true, force: true });
21929
22024
  return { cleanupId: `kimi-cleanup:${reference.attemptId}:${reference.operationId}`, completed: true };
21930
22025
  }
@@ -21948,8 +22043,8 @@ function assertKimiManaged(packageName, managed, registryFile) {
21948
22043
  function kimiReadback(handle) {
21949
22044
  const managed = managedPluginPath(handle.packageName);
21950
22045
  const registryFile = join30(pluginsDir2(), "installed.json");
21951
- const row = existsSync24(registryFile) ? readRegistry2(registryFile).plugins.find((candidate) => candidate.id === handle.packageName) : undefined;
21952
- const present = row !== undefined && existsSync24(managed) && sameRoot(row.root, managed);
22046
+ const row = existsSync23(registryFile) ? readRegistry2(registryFile).plugins.find((candidate) => candidate.id === handle.packageName) : undefined;
22047
+ const present = row !== undefined && existsSync23(managed) && sameRoot(row.root, managed);
21953
22048
  const enabled = present && row?.enabled === true;
21954
22049
  const digest = present ? fingerprintTree(managed) : null;
21955
22050
  return {
@@ -21970,7 +22065,7 @@ function kimiReadback(handle) {
21970
22065
  }
21971
22066
  function probeKimiBinary() {
21972
22067
  const binary = kimiBinaryPath();
21973
- if (!existsSync24(binary))
22068
+ if (!existsSync23(binary))
21974
22069
  return { kind: "unknown" };
21975
22070
  const probed = readKimiBinaryVersion(binary);
21976
22071
  const version = currentKimiVersion(probed.exitCode, probed.version);
@@ -22113,12 +22208,12 @@ function unexposed(phase) {
22113
22208
  }
22114
22209
 
22115
22210
  // src/hosts/cursor-writer.ts
22116
- import { accessSync as accessSync5, constants as constants5, cpSync as cpSync8, existsSync as existsSync25, lstatSync as lstatSync17, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync8, readFileSync as readFileSync26, readdirSync as readdirSync17, renameSync as renameSync6, rmSync as rmSync9, statSync as statSync12, writeFileSync as writeFileSync9 } from "node:fs";
22211
+ import { accessSync as accessSync5, constants as constants5, cpSync as cpSync8, existsSync as existsSync24, lstatSync as lstatSync18, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync8, readFileSync as readFileSync26, readdirSync as readdirSync17, renameSync as renameSync6, rmSync as rmSync9, statSync as statSync12, writeFileSync as writeFileSync9 } from "node:fs";
22117
22212
  import { delimiter as delimiter4, join as join32, resolve as resolve19 } from "node:path";
22118
22213
  import { tmpdir as tmpdir5 } from "node:os";
22119
22214
 
22120
22215
  // src/hosts/cursor-adoption.ts
22121
- import { accessSync as accessSync4, constants as constants4, lstatSync as lstatSync16, readFileSync as readFileSync25, readdirSync as readdirSync16 } from "node:fs";
22216
+ import { accessSync as accessSync4, constants as constants4, lstatSync as lstatSync17, readFileSync as readFileSync25, readdirSync as readdirSync16 } from "node:fs";
22122
22217
  import { dirname as dirname11, join as join31, resolve as resolve18 } from "node:path";
22123
22218
  var MARKER5 = ".plgnz-install.json";
22124
22219
  function proveCursorLegacyAdoption(request) {
@@ -22279,7 +22374,7 @@ function readTree(root) {
22279
22374
  const tree = new Map;
22280
22375
  const walk = (dir, prefix) => {
22281
22376
  for (const name of readdirSync16(dir).sort()) {
22282
- const path = join31(dir, name), relative = prefix === "" ? name : `${prefix}/${name}`, stat = lstatSync16(path);
22377
+ const path = join31(dir, name), relative = prefix === "" ? name : `${prefix}/${name}`, stat = lstatSync17(path);
22283
22378
  if (stat.isSymbolicLink())
22284
22379
  fail3(`symlink resource: ${relative}`);
22285
22380
  if (stat.isDirectory()) {
@@ -22297,7 +22392,7 @@ function readTree(root) {
22297
22392
  function safeAncestors(root, allowMissing) {
22298
22393
  for (let path = resolve18(root);; path = dirname11(path)) {
22299
22394
  if (!allowMissing || present(path)) {
22300
- const stat = lstatSync16(path);
22395
+ const stat = lstatSync17(path);
22301
22396
  if (stat.isSymbolicLink() || !stat.isDirectory())
22302
22397
  fail3(`unsafe directory: ${path}`);
22303
22398
  }
@@ -22349,7 +22444,7 @@ function parseManifest2(entry) {
22349
22444
  }
22350
22445
  function present(path) {
22351
22446
  try {
22352
- lstatSync16(path);
22447
+ lstatSync17(path);
22353
22448
  return true;
22354
22449
  } catch (error) {
22355
22450
  if (error.code === "ENOENT")
@@ -22410,8 +22505,8 @@ var cursorWriter = {
22410
22505
  if (marker !== null && (differentSource || !matchesOwnership(marker.pluginId, id, ownershipId))) {
22411
22506
  throw new Error(`Cursor local plugin ${id} belongs to another source; refusing to replace it`);
22412
22507
  }
22413
- const identicalUnowned = existsSync25(target) && marker === null && sameTree4(stage, target);
22414
- if (existsSync25(target) && marker === null && !identicalUnowned) {
22508
+ const identicalUnowned = existsSync24(target) && marker === null && sameTree4(stage, target);
22509
+ if (existsSync24(target) && marker === null && !identicalUnowned) {
22415
22510
  if (!opts?.adoptExisting)
22416
22511
  throw new Error(`Cursor local plugin ${id} is unowned and differs from the staged representation; pass --adopt-existing to take ownership explicitly`);
22417
22512
  validateExistingIdentity(target, id, sourceVersion(plugin.dir));
@@ -22430,7 +22525,7 @@ var cursorWriter = {
22430
22525
  }
22431
22526
  },
22432
22527
  async pin(plugin, opts) {
22433
- if (plugin.path === undefined || !existsSync25(plugin.path))
22528
+ if (plugin.path === undefined || !existsSync24(plugin.path))
22434
22529
  return { changes: [], refusals: [] };
22435
22530
  return pinPluginMcpFiles(plugin.path, mcpCandidates4(), opts);
22436
22531
  },
@@ -22464,7 +22559,7 @@ function projectCommandsToSkills(stage) {
22464
22559
  throw new Error(`Cursor command projection collision: ${command.name}`);
22465
22560
  seen.add(command.name);
22466
22561
  const target = join32(stage, "skills", command.name, "SKILL.md");
22467
- if (existsSync25(target))
22562
+ if (existsSync24(target))
22468
22563
  throw new Error(`Cursor command collides with an existing skill: ${command.name}`);
22469
22564
  mkdirSync9(join32(stage, "skills", command.name), { recursive: true });
22470
22565
  const body = command.body.endsWith(`
@@ -22482,13 +22577,13 @@ ${body}`);
22482
22577
  }
22483
22578
  }
22484
22579
  function hasCommands(root) {
22485
- return existsSync25(join32(root, "commands")) || existsSync25(join32(root, ".claude", "commands"));
22580
+ return existsSync24(join32(root, "commands")) || existsSync24(join32(root, ".claude", "commands"));
22486
22581
  }
22487
22582
  function ensureCursorManifest(stage, expectedName) {
22488
22583
  const cursorManifest = join32(stage, ".cursor-plugin", "plugin.json");
22489
- if (existsSync25(cursorManifest))
22584
+ if (existsSync24(cursorManifest))
22490
22585
  return;
22491
- const source = manifestCandidates(stage).find(existsSync25);
22586
+ const source = manifestCandidates(stage).find(existsSync24);
22492
22587
  if (source === undefined)
22493
22588
  throw new Error("Cursor stage has no Agent Plugins manifest");
22494
22589
  mkdirSync9(join32(stage, ".cursor-plugin"), { recursive: true });
@@ -22501,7 +22596,7 @@ function validateStage2(stage, expectedName) {
22501
22596
  const native = parseManifest3(join32(stage, ".cursor-plugin", "plugin.json"));
22502
22597
  if (native.name !== expectedName)
22503
22598
  throw new Error(`Cursor manifest identity does not match ${expectedName}`);
22504
- const canonicalPath = manifestCandidates(stage).find(existsSync25);
22599
+ const canonicalPath = manifestCandidates(stage).find(existsSync24);
22505
22600
  if (canonicalPath !== undefined) {
22506
22601
  const canonical = parseManifest3(canonicalPath);
22507
22602
  if (native.name !== canonical.name || canonical.version !== undefined && native.version !== canonical.version) {
@@ -22509,14 +22604,14 @@ function validateStage2(stage, expectedName) {
22509
22604
  }
22510
22605
  }
22511
22606
  const skills = join32(stage, "skills");
22512
- if (existsSync25(skills) && !statSync12(skills).isDirectory())
22607
+ if (existsSync24(skills) && !statSync12(skills).isDirectory())
22513
22608
  throw new Error("Cursor stage skills path is not a directory");
22514
22609
  }
22515
22610
  function manifestCandidates(root) {
22516
22611
  return [join32(root, ".claude-plugin", "plugin.json"), join32(root, "plugin.json"), join32(root, ".plugin", "plugin.json")];
22517
22612
  }
22518
22613
  function sourceVersion(root) {
22519
- const manifest = [join32(root, ".cursor-plugin", "plugin.json"), ...manifestCandidates(root)].find(existsSync25);
22614
+ const manifest = [join32(root, ".cursor-plugin", "plugin.json"), ...manifestCandidates(root)].find(existsSync24);
22520
22615
  return manifest === undefined ? undefined : parseManifest3(manifest).version;
22521
22616
  }
22522
22617
  function parseManifest3(path) {
@@ -22537,7 +22632,7 @@ function parseManifest3(path) {
22537
22632
  }
22538
22633
  function validateExistingIdentity(target, expectedName, expectedVersion) {
22539
22634
  const manifest = join32(target, ".cursor-plugin", "plugin.json");
22540
- if (!existsSync25(manifest))
22635
+ if (!existsSync24(manifest))
22541
22636
  throw new Error(`unowned Cursor local plugin has no native manifest: ${target}`);
22542
22637
  const parsed = parseManifest3(manifest);
22543
22638
  if (parsed.name !== expectedName || parsed.version !== expectedVersion)
@@ -22545,7 +22640,7 @@ function validateExistingIdentity(target, expectedName, expectedVersion) {
22545
22640
  }
22546
22641
  function readOwnership4(target) {
22547
22642
  const marker = join32(target, OWNERSHIP3);
22548
- if (!existsSync25(marker))
22643
+ if (!existsSync24(marker))
22549
22644
  return null;
22550
22645
  try {
22551
22646
  const value = JSON.parse(readFileSync26(marker, "utf8"));
@@ -22589,7 +22684,7 @@ function ownsNativeDirectory(markerId, nativeId) {
22589
22684
  return markerId.startsWith(prefix) && validIdentity2(markerId.slice(prefix.length));
22590
22685
  }
22591
22686
  function activate3(stage, target, root) {
22592
- if (!existsSync25(target)) {
22687
+ if (!existsSync24(target)) {
22593
22688
  renameSync6(stage, target);
22594
22689
  return { commit: () => {} };
22595
22690
  }
@@ -22606,7 +22701,7 @@ function activate3(stage, target, root) {
22606
22701
  return { commit: () => rmSync9(backupRoot, { recursive: true, force: true }) };
22607
22702
  }
22608
22703
  function sameTree4(left, right) {
22609
- if (!existsSync25(right))
22704
+ if (!existsSync24(right))
22610
22705
  return false;
22611
22706
  const entries = (root) => {
22612
22707
  const out = [];
@@ -22616,7 +22711,7 @@ function sameTree4(left, right) {
22616
22711
  continue;
22617
22712
  const path = join32(dir, name);
22618
22713
  const relative = prefix === "" ? name : `${prefix}/${name}`;
22619
- const stat = lstatSync17(path);
22714
+ const stat = lstatSync18(path);
22620
22715
  if (stat.isSymbolicLink())
22621
22716
  throw new Error(`Cursor managed plugin contains symlink: ${path}`);
22622
22717
  if (stat.isDirectory())
@@ -22643,15 +22738,15 @@ function assertManagedDirectory(root, target) {
22643
22738
  throw new Error(`Cursor managed path escapes its store: ${target}`);
22644
22739
  let current = resolvedRoot;
22645
22740
  for (const part of resolvedTarget.slice(resolvedRoot.length).split("/").filter(Boolean)) {
22646
- if (existsSync25(current))
22741
+ if (existsSync24(current))
22647
22742
  assertDirectoryNotLink(current);
22648
22743
  current = join32(current, part);
22649
22744
  }
22650
- if (existsSync25(current))
22745
+ if (existsSync24(current))
22651
22746
  assertDirectoryNotLink(current);
22652
22747
  }
22653
22748
  function assertDirectoryNotLink(path) {
22654
- const stat = lstatSync17(path);
22749
+ const stat = lstatSync18(path);
22655
22750
  if (stat.isSymbolicLink())
22656
22751
  throw new Error(`Cursor managed path component is a symlink: ${path}`);
22657
22752
  if (!stat.isDirectory())
@@ -22659,14 +22754,14 @@ function assertDirectoryNotLink(path) {
22659
22754
  }
22660
22755
  function assertNoSymlinks5(root) {
22661
22756
  const walk = (dir) => {
22662
- const stat = lstatSync17(dir);
22757
+ const stat = lstatSync18(dir);
22663
22758
  if (stat.isSymbolicLink())
22664
22759
  throw new Error(`Cursor plugin source contains symlink: ${dir}`);
22665
22760
  if (!stat.isDirectory())
22666
22761
  throw new Error(`Cursor plugin source is not a directory: ${dir}`);
22667
22762
  for (const name of readdirSync17(dir)) {
22668
22763
  const path = join32(dir, name);
22669
- const entry = lstatSync17(path);
22764
+ const entry = lstatSync18(path);
22670
22765
  if (entry.isSymbolicLink())
22671
22766
  throw new Error(`Cursor plugin source contains symlink: ${path}`);
22672
22767
  if (entry.isDirectory())
@@ -22866,7 +22961,7 @@ var cursorLifecycleDefinition = {
22866
22961
  const handle = prepared.handle;
22867
22962
  const target = managedPluginDir(handle.target.instance, handle.nativeId);
22868
22963
  refuseForeignScope(target, handle.scopeId, handle.nativeId);
22869
- if (existsSync25(target) && fingerprintTree(target) === fingerprintTree(prepared.stagingRoot)) {
22964
+ if (existsSync24(target) && fingerprintTree(target) === fingerprintTree(prepared.stagingRoot)) {
22870
22965
  return { receiptId: receipt("apply", handle), changed: false };
22871
22966
  }
22872
22967
  const root = localDir(handle.target.instance);
@@ -22887,7 +22982,7 @@ var cursorLifecycleDefinition = {
22887
22982
  async retire(prepared) {
22888
22983
  const handle = prepared.handle;
22889
22984
  const target = managedPluginDir(handle.target.instance, handle.nativeId);
22890
- if (!existsSync25(target))
22985
+ if (!existsSync24(target))
22891
22986
  return { receiptId: receipt("retire", handle), changed: false };
22892
22987
  refuseForeignScope(target, handle.scopeId, handle.nativeId);
22893
22988
  rmSync9(target, { recursive: true, force: true });
@@ -22909,15 +23004,15 @@ var cursorLifecycleDefinition = {
22909
23004
  const root = localDir(handle.target.instance);
22910
23005
  const target = managedPluginDir(handle.target.instance, handle.nativeId);
22911
23006
  const backup = join32(handle.rollbackReference, "active");
22912
- const restore = prior.presence === "present" && existsSync25(backup);
23007
+ const restore = prior.presence === "present" && existsSync24(backup);
22913
23008
  if (!restore) {
22914
- if (prior.presence === "present" || !existsSync25(target))
23009
+ if (prior.presence === "present" || !existsSync24(target))
22915
23010
  return { receiptId: receipt("rollback", handle), changed: false };
22916
23011
  refuseForeignScope(target, handle.scopeId, handle.nativeId);
22917
23012
  rmSync9(target, { recursive: true, force: true });
22918
23013
  return { receiptId: receipt("rollback", handle), changed: true };
22919
23014
  }
22920
- if (existsSync25(target)) {
23015
+ if (existsSync24(target)) {
22921
23016
  refuseForeignScope(target, handle.scopeId, handle.nativeId);
22922
23017
  if (fingerprintTree(target) === fingerprintTree(backup))
22923
23018
  return { receiptId: receipt("rollback", handle), changed: false };
@@ -22969,7 +23064,7 @@ function probeCursorVersion() {
22969
23064
  function locateCursorProbeBinary() {
22970
23065
  const override = process.env["OPEN_PLUGIN_CURSOR_BIN"];
22971
23066
  if (override !== undefined) {
22972
- if (override.length === 0 || !existsSync25(override))
23067
+ if (override.length === 0 || !existsSync24(override))
22973
23068
  return { kind: "refused" };
22974
23069
  return { kind: "path", path: override };
22975
23070
  }
@@ -23012,7 +23107,7 @@ function decodeStdout(bytes) {
23012
23107
  }
23013
23108
  function inventoryLocalStore(target) {
23014
23109
  const root = localDir(target.instance);
23015
- if (!existsSync25(root))
23110
+ if (!existsSync24(root))
23016
23111
  return { target, installations: [] };
23017
23112
  const installations = [];
23018
23113
  for (const entry of readdirSync17(root)) {
@@ -23033,7 +23128,7 @@ function inventoryLocalStore(target) {
23033
23128
  }
23034
23129
  function readLocalInstallation(entry, dir) {
23035
23130
  const manifestPath = join32(dir, ".cursor-plugin", "plugin.json");
23036
- if (!existsSync25(manifestPath))
23131
+ if (!existsSync24(manifestPath))
23037
23132
  return;
23038
23133
  let manifest;
23039
23134
  let marker = null;
@@ -23135,7 +23230,7 @@ function applyRecordedPins(stage, pins) {
23135
23230
  for (const pin of pins) {
23136
23231
  let found = false;
23137
23232
  for (const file of [join32(stage, ".mcp.json"), join32(stage, "mcp.json")]) {
23138
- if (!existsSync25(file))
23233
+ if (!existsSync24(file))
23139
23234
  continue;
23140
23235
  const parsed = JSON.parse(readFileSync26(file, "utf8"));
23141
23236
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
@@ -23164,7 +23259,7 @@ function projectReadback(identity) {
23164
23259
  inactiveMetadata: retainedResource(instance, identity.nativeId, "metadata")
23165
23260
  };
23166
23261
  const dir = join32(localDir(instance), identity.nativeId);
23167
- if (!existsSync25(dir)) {
23262
+ if (!existsSync24(dir)) {
23168
23263
  return {
23169
23264
  adapterId: identity.adapterId,
23170
23265
  target: identity.target,
@@ -23200,9 +23295,9 @@ function projectReadback(identity) {
23200
23295
  }
23201
23296
  function retainedResource(instance, nativeId, kind) {
23202
23297
  const dir = retentionDir(instance, nativeId, kind);
23203
- if (!existsSync25(dir))
23298
+ if (!existsSync24(dir))
23204
23299
  return { state: "absent", fingerprint: null };
23205
- const stat = lstatSync17(dir);
23300
+ const stat = lstatSync18(dir);
23206
23301
  if (stat.isSymbolicLink() || !stat.isDirectory())
23207
23302
  throw new Error(`Cursor retained ${kind} is not a directory: ${dir}`);
23208
23303
  return { state: "present", fingerprint: fingerprintTree(dir) };
@@ -23220,7 +23315,7 @@ function captureRollback2(instance, attemptId, operationId, nativeId, prior) {
23220
23315
  rmSync9(reference, { recursive: true, force: true });
23221
23316
  mkdirSync9(reference, { recursive: true });
23222
23317
  const active = join32(localDir(instance), nativeId);
23223
- if (existsSync25(active))
23318
+ if (existsSync24(active))
23224
23319
  cpSync8(active, join32(reference, "active"), { recursive: true });
23225
23320
  writeFileSync9(join32(reference, "prior.json"), `${JSON.stringify(prior)}
23226
23321
  `);
@@ -23253,7 +23348,7 @@ function absentRoute(action, route) {
23253
23348
  }
23254
23349
  }
23255
23350
  function refuseForeignScope(target, scopeId, nativeId) {
23256
- if (!existsSync25(target))
23351
+ if (!existsSync24(target))
23257
23352
  return;
23258
23353
  const marker = readOwnership4(target);
23259
23354
  if (marker === null || !ownsNativeDirectory(marker.pluginId, nativeId)) {
@@ -23282,7 +23377,7 @@ function receipt(kind, handle) {
23282
23377
 
23283
23378
  // src/hosts/omp-writer.ts
23284
23379
  init_omp_hooks();
23285
- import { cpSync as cpSync9, existsSync as existsSync26, lstatSync as lstatSync18, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync9, readFileSync as readFileSync27, readdirSync as readdirSync18, readlinkSync as readlinkSync2, renameSync as renameSync7, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync10 } from "node:fs";
23380
+ import { cpSync as cpSync9, existsSync as existsSync25, lstatSync as lstatSync19, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync9, readFileSync as readFileSync27, readdirSync as readdirSync18, readlinkSync as readlinkSync2, renameSync as renameSync7, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync10 } from "node:fs";
23286
23381
  import { dirname as dirname12, join as join33, resolve as resolve20 } from "node:path";
23287
23382
  import { tmpdir as tmpdir6 } from "node:os";
23288
23383
  var MARKER6 = ".plgnz-install.json";
@@ -23378,7 +23473,7 @@ var ompWriter = {
23378
23473
  }
23379
23474
  },
23380
23475
  async pin(plugin, opts) {
23381
- if (plugin.path === undefined || !existsSync26(plugin.path))
23476
+ if (plugin.path === undefined || !existsSync25(plugin.path))
23382
23477
  return { changes: [], refusals: [] };
23383
23478
  return pinPluginMcpFiles(plugin.path, mcpCandidates5(), opts);
23384
23479
  },
@@ -23472,7 +23567,7 @@ function registryInstallPaths(registry) {
23472
23567
  }
23473
23568
  function findOwned(id) {
23474
23569
  const root = join33(pluginsDir3(), MANAGED);
23475
- if (!existsSync26(root))
23570
+ if (!existsSync25(root))
23476
23571
  return null;
23477
23572
  for (const name of readdirSync18(root)) {
23478
23573
  const path = join33(root, name);
@@ -23490,7 +23585,7 @@ function assertOwnedLink(path, target, owned) {
23490
23585
  }
23491
23586
  function lstatExists(path) {
23492
23587
  try {
23493
- lstatSync18(path);
23588
+ lstatSync19(path);
23494
23589
  return true;
23495
23590
  } catch {
23496
23591
  return false;
@@ -23498,7 +23593,7 @@ function lstatExists(path) {
23498
23593
  }
23499
23594
  function linkPointsTo(path, target) {
23500
23595
  try {
23501
- return lstatSync18(path).isSymbolicLink() && resolve20(dirname12(path), readlinkSync2(path)) === resolve20(target);
23596
+ return lstatSync19(path).isSymbolicLink() && resolve20(dirname12(path), readlinkSync2(path)) === resolve20(target);
23502
23597
  } catch {
23503
23598
  return false;
23504
23599
  }
@@ -23538,7 +23633,7 @@ function mkdirSafe(path) {
23538
23633
  const parentBoundary = dirname12(boundary);
23539
23634
  for (let current = target;; current = dirname12(current)) {
23540
23635
  if (lstatExists(current)) {
23541
- const stat = lstatSync18(current);
23636
+ const stat = lstatSync19(current);
23542
23637
  if (stat.isSymbolicLink() || !stat.isDirectory())
23543
23638
  throw new Error(`OMP managed path is unsafe: ${current}`);
23544
23639
  }
@@ -23548,7 +23643,7 @@ function mkdirSafe(path) {
23548
23643
  mkdirSync10(path, { recursive: true });
23549
23644
  let current = target;
23550
23645
  while (true) {
23551
- const stat = lstatSync18(current);
23646
+ const stat = lstatSync19(current);
23552
23647
  if (stat.isSymbolicLink() || !stat.isDirectory())
23553
23648
  throw new Error(`OMP managed path is unsafe: ${current}`);
23554
23649
  if (current === boundary)
@@ -23564,7 +23659,7 @@ function assertExistingDirectoryTree(boundaryPath, targetPath, label) {
23564
23659
  for (let current = target;; current = dirname12(current)) {
23565
23660
  if (!lstatExists(current))
23566
23661
  throw new Error(`${label} has no safe native copy`);
23567
- const stat = lstatSync18(current);
23662
+ const stat = lstatSync19(current);
23568
23663
  if (stat.isSymbolicLink() || !stat.isDirectory())
23569
23664
  throw new Error(`${label} contains a symlink or non-directory component: ${current}`);
23570
23665
  if (current === boundary)
@@ -23572,7 +23667,7 @@ function assertExistingDirectoryTree(boundaryPath, targetPath, label) {
23572
23667
  }
23573
23668
  }
23574
23669
  function sameTree5(left, right) {
23575
- if (!existsSync26(right))
23670
+ if (!existsSync25(right))
23576
23671
  return false;
23577
23672
  const bytes = readFileSync27;
23578
23673
  const list = (root) => {
@@ -23583,7 +23678,7 @@ function sameTree5(left, right) {
23583
23678
  continue;
23584
23679
  const path = join33(dir, name);
23585
23680
  const rel = prefix ? `${prefix}/${name}` : name;
23586
- const stat = lstatSync18(path);
23681
+ const stat = lstatSync19(path);
23587
23682
  if (stat.isSymbolicLink())
23588
23683
  throw new Error(`OMP managed plugin contains symlink: ${path}`);
23589
23684
  if (stat.isDirectory())
@@ -23601,7 +23696,7 @@ function sameTree5(left, right) {
23601
23696
  }
23602
23697
  function ownership2(path) {
23603
23698
  const marker = join33(path, MARKER6);
23604
- if (!existsSync26(marker))
23699
+ if (!existsSync25(marker))
23605
23700
  return null;
23606
23701
  const value = readDoc(marker, {}, "ownership marker");
23607
23702
  if (typeof value.source !== "string" || typeof value.pluginId !== "string" || typeof value.fingerprint !== "string" || typeof value.packageName !== "string")
@@ -23620,7 +23715,7 @@ function ownership2(path) {
23620
23715
  };
23621
23716
  }
23622
23717
  function readDoc(path, fallback, label) {
23623
- if (!existsSync26(path))
23718
+ if (!existsSync25(path))
23624
23719
  return fallback;
23625
23720
  try {
23626
23721
  const value = JSON.parse(readFileSync27(path, "utf8"));
@@ -23650,7 +23745,7 @@ function writeDoc(path, value) {
23650
23745
  writeFileSync10(path, JSON.stringify(value, null, 2));
23651
23746
  }
23652
23747
  function snapshot(path) {
23653
- return existsSync26(path) ? readFileSync27(path, "utf8") : undefined;
23748
+ return existsSync25(path) ? readFileSync27(path, "utf8") : undefined;
23654
23749
  }
23655
23750
  function restore2(path, value) {
23656
23751
  if (value === undefined)
@@ -23872,7 +23967,7 @@ async function observeInventory(target) {
23872
23967
  return { target, installations: omp.listInstalled().map((plugin) => installationOf(plugin)) };
23873
23968
  }
23874
23969
  function installationOf(plugin) {
23875
- const path = plugin.path !== undefined && existsSync26(plugin.path) ? resolve20(plugin.path) : undefined;
23970
+ const path = plugin.path !== undefined && existsSync25(plugin.path) ? resolve20(plugin.path) : undefined;
23876
23971
  if (path === undefined) {
23877
23972
  return {
23878
23973
  nativeId: plugin.id,
@@ -23913,7 +24008,7 @@ function sourceOf2(owner) {
23913
24008
  }
23914
24009
  function observeReadback(identity) {
23915
24010
  const target = managedPackageDir(identity.nativeId);
23916
- const present = existsSync26(target) && linkPointsTo(managedLink(identity.nativeId), target);
24011
+ const present = existsSync25(target) && linkPointsTo(managedLink(identity.nativeId), target);
23917
24012
  const retention = retentionOf(identity.nativeId);
23918
24013
  if (!present) {
23919
24014
  return {
@@ -23957,17 +24052,17 @@ function retentionOf(nativeId) {
23957
24052
  };
23958
24053
  }
23959
24054
  function resourceObservation(path) {
23960
- if (!existsSync26(path))
24055
+ if (!existsSync25(path))
23961
24056
  return { state: "absent", fingerprint: null };
23962
24057
  return { state: "present", fingerprint: fingerprintTree(path) };
23963
24058
  }
23964
24059
  function lockMetadataObservation(nativeId) {
23965
- if (!existsSync26(lockPath()))
24060
+ if (!existsSync25(lockPath()))
23966
24061
  return { state: "absent", fingerprint: null };
23967
24062
  return { state: "present", fingerprint: sha256(canonical3(metadataView(readDoc(lockPath(), {}, "lockfile"), npmName(nativeId)))) };
23968
24063
  }
23969
24064
  function plannedLockMetadata(nativeId, version) {
23970
- const lock = existsSync26(lockPath()) ? readDoc(lockPath(), {}, "lockfile") : { plugins: {}, settings: {} };
24065
+ const lock = existsSync25(lockPath()) ? readDoc(lockPath(), {}, "lockfile") : { plugins: {}, settings: {} };
23971
24066
  const plugins = isDoc(lock.plugins) ? lock.plugins : {};
23972
24067
  const npm = npmName(nativeId);
23973
24068
  const next = { ...lock, plugins: { ...plugins, [npm]: activatedEntry(entry(plugins[npm]), version) } };
@@ -24005,7 +24100,7 @@ function captureRollback3(nativeId, attemptId, operationId) {
24005
24100
  mkdirSafe(preparationDir2(attemptId, operationId));
24006
24101
  mkdirSync10(reference, { recursive: true });
24007
24102
  const target = managedPackageDir(nativeId);
24008
- if (existsSync26(target))
24103
+ if (existsSync25(target))
24009
24104
  cpSync9(target, join33(reference, "package"), { recursive: true });
24010
24105
  writeFileSync10(join33(reference, "state.json"), JSON.stringify({ lock: captureLockRow(nativeId), link: currentLinkTarget(managedLink(nativeId)) }));
24011
24106
  return resolve20(reference);
@@ -24015,7 +24110,7 @@ function restoreRollback2(nativeId, reference) {
24015
24110
  const target = managedPackageDir(nativeId);
24016
24111
  rmSync10(target, { recursive: true, force: true });
24017
24112
  const backup = join33(reference, "package");
24018
- if (existsSync26(backup)) {
24113
+ if (existsSync25(backup)) {
24019
24114
  mkdirSafe(dirname12(target));
24020
24115
  cpSync9(backup, target, { recursive: true });
24021
24116
  }
@@ -24029,7 +24124,7 @@ function restoreRollback2(nativeId, reference) {
24029
24124
  }
24030
24125
  function captureLockRow(nativeId) {
24031
24126
  const packageName = npmName(nativeId);
24032
- if (!existsSync26(lockPath()))
24127
+ if (!existsSync25(lockPath()))
24033
24128
  return { packageName, present: false, row: null };
24034
24129
  const lock = readDoc(lockPath(), {}, "lockfile");
24035
24130
  const plugins = isDoc(lock.plugins) ? lock.plugins : {};
@@ -24039,7 +24134,7 @@ function captureLockRow(nativeId) {
24039
24134
  }
24040
24135
  function restoreLockRow(saved) {
24041
24136
  const file = lockPath();
24042
- if (!existsSync26(file)) {
24137
+ if (!existsSync25(file)) {
24043
24138
  if (!saved.present)
24044
24139
  return;
24045
24140
  writeDoc(file, { plugins: { [saved.packageName]: saved.row } });
@@ -24055,7 +24150,7 @@ function restoreLockRow(saved) {
24055
24150
  }
24056
24151
  function currentLinkTarget(path) {
24057
24152
  try {
24058
- return lstatSync18(path).isSymbolicLink() ? resolve20(dirname12(path), readlinkSync2(path)) : null;
24153
+ return lstatSync19(path).isSymbolicLink() ? resolve20(dirname12(path), readlinkSync2(path)) : null;
24059
24154
  } catch {
24060
24155
  return null;
24061
24156
  }
@@ -24097,7 +24192,7 @@ async function applyManaged(handle, stagingRoot) {
24097
24192
  }
24098
24193
  function activationAlreadyCurrent(nativeId, stage, version) {
24099
24194
  const target = managedPackageDir(nativeId);
24100
- if (!existsSync26(target) || !existsSync26(stage) || fingerprintTree(stage) !== fingerprintTree(target) || !linkPointsTo(managedLink(nativeId), target))
24195
+ if (!existsSync25(target) || !existsSync25(stage) || fingerprintTree(stage) !== fingerprintTree(target) || !linkPointsTo(managedLink(nativeId), target))
24101
24196
  return false;
24102
24197
  const lock = readDoc(lockPath(), { plugins: {}, settings: {} }, "lockfile");
24103
24198
  const plugins = object8(lock.plugins, "lockfile plugins");
@@ -24158,9 +24253,10 @@ function captureRecorded(activation, route, attemptId, operationId, affectedOper
24158
24253
  // src/native-hook-writer.ts
24159
24254
  init_hooks();
24160
24255
  init_hook_build();
24161
- import { chmodSync as chmodSync2, cpSync as cpSync10, existsSync as existsSync27, lstatSync as lstatSync19, mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync10, renameSync as renameSync8, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
24256
+ import { chmodSync as chmodSync2, cpSync as cpSync10, existsSync as existsSync26, lstatSync as lstatSync20, mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync10, renameSync as renameSync8, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
24162
24257
  import { dirname as dirname13, join as join34 } from "node:path";
24163
24258
  import { tmpdir as tmpdir7 } from "node:os";
24259
+ init_compatibility();
24164
24260
  function probeHookHostVersion(command, override) {
24165
24261
  const binary = process.env[override] ?? which(command);
24166
24262
  if (!binary)
@@ -24182,8 +24278,8 @@ function createNativeHookWriter(options) {
24182
24278
  if (reader.listInstalled().some((item) => item.id === id && item.path !== target)) {
24183
24279
  throw new Error("Native hook identity already belongs to a historical standalone install; remove that owned install before retrying: " + id);
24184
24280
  }
24185
- const owner = existsSync27(target) ? readHookOwner(target) : null;
24186
- if (existsSync27(target) && (owner === null || owner.pluginId !== id || owner.source !== source)) {
24281
+ const owner = existsSync26(target) ? readHookOwner(target) : null;
24282
+ if (existsSync26(target) && (owner === null || owner.pluginId !== id || owner.source !== source)) {
24187
24283
  throw new Error("Native hook package is not owned for this source: " + target);
24188
24284
  }
24189
24285
  const raw = registrationText(registration);
@@ -24207,7 +24303,7 @@ function createNativeHookWriter(options) {
24207
24303
  }, [profile]);
24208
24304
  if (admission.status === "refused")
24209
24305
  throw new PackageCapabilityError(store.id, admission);
24210
- if (existsSync27(join34(plugin.dir, NATIVE_HOOK_MARKER)))
24306
+ if (existsSync26(join34(plugin.dir, NATIVE_HOOK_MARKER)))
24211
24307
  throw new Error("Source contains reserved native hook ownership metadata");
24212
24308
  preflightPortableHooks(adapter, plugin.dir);
24213
24309
  checkTarget(idFor(plugin), resolved.sourceUri);
@@ -24232,7 +24328,7 @@ function createNativeHookWriter(options) {
24232
24328
  fingerprint: plugin.contentFingerprint ?? fingerprintTree(plugin.dir)
24233
24329
  }) + `
24234
24330
  `);
24235
- const unchanged = existsSync27(target) && fingerprintTree(target) === fingerprintTree(compiled) && registrationEnabled(registration);
24331
+ const unchanged = existsSync26(target) && fingerprintTree(target) === fingerprintTree(compiled) && registrationEnabled(registration);
24236
24332
  if (opts?.dryRun) {
24237
24333
  console.log("[" + store.id + "] would register native hooks: " + target);
24238
24334
  return unchanged ? "unchanged" : undefined;
@@ -24249,7 +24345,7 @@ function createNativeHookWriter(options) {
24249
24345
  const expectedFingerprint = fingerprintTree(stage);
24250
24346
  let activated = false, moved = false, committed = false;
24251
24347
  try {
24252
- if (existsSync27(target)) {
24348
+ if (existsSync26(target)) {
24253
24349
  renameSync8(target, backup);
24254
24350
  moved = true;
24255
24351
  }
@@ -24268,7 +24364,7 @@ function createNativeHookWriter(options) {
24268
24364
  renameSync8(backup, target);
24269
24365
  throw error;
24270
24366
  } finally {
24271
- if (committed || !existsSync27(backup))
24367
+ if (committed || !existsSync26(backup))
24272
24368
  rmSync11(transaction, { recursive: true, force: true });
24273
24369
  }
24274
24370
  } finally {
@@ -24278,7 +24374,7 @@ function createNativeHookWriter(options) {
24278
24374
  async remove(id, removeOptions) {
24279
24375
  const target = hookPackagePath(store, id);
24280
24376
  assertHookPath(store, target);
24281
- if (!existsSync27(target))
24377
+ if (!existsSync26(target))
24282
24378
  return options.legacyRemove(id, removeOptions);
24283
24379
  const owner = readHookOwner(target);
24284
24380
  if (owner === null || owner.pluginId !== id || removeOptions?.source !== undefined && owner.source !== removeOptions.source) {
@@ -24301,12 +24397,12 @@ function createNativeHookWriter(options) {
24301
24397
  committed = true;
24302
24398
  } catch (error) {
24303
24399
  restoreRegistration(registration, before, after);
24304
- if (!existsSync27(target))
24400
+ if (!existsSync26(target))
24305
24401
  renameSync8(backup, target);
24306
24402
  throw error;
24307
24403
  }
24308
24404
  } finally {
24309
- if (committed || !existsSync27(backup))
24405
+ if (committed || !existsSync26(backup))
24310
24406
  rmSync11(transaction, { recursive: true, force: true });
24311
24407
  }
24312
24408
  },
@@ -24320,11 +24416,10 @@ function nextRegistration(registration, raw, enabled) {
24320
24416
  return enabled ? registration.content : undefined;
24321
24417
  const value = registrationDocument(registration, raw);
24322
24418
  const previous = value[registration.field] ?? [];
24323
- const entries = previous.filter((entry) => entry !== registration.entry);
24324
- if (enabled)
24325
- entries.push(registration.entry);
24326
- if (entries.length === 0 && !Object.hasOwn(value, registration.field) && !enabled)
24419
+ const present = previous.includes(registration.entry);
24420
+ if (enabled === present)
24327
24421
  return raw;
24422
+ const entries = enabled ? [...previous, registration.entry] : previous.filter((entry) => entry !== registration.entry);
24328
24423
  value[registration.field] = entries;
24329
24424
  return JSON.stringify(value, null, 2) + `
24330
24425
  `;
@@ -24349,7 +24444,7 @@ function writeExactFile(path, text) {
24349
24444
  rmSync11(path, { force: true });
24350
24445
  return;
24351
24446
  }
24352
- const mode = existsSync27(path) ? lstatSync19(path).mode & 511 : 420;
24447
+ const mode = existsSync26(path) ? lstatSync20(path).mode & 511 : 420;
24353
24448
  mkdirSync11(dirname13(path), { recursive: true });
24354
24449
  const temporary = mkdtempSync10(join34(dirname13(path), ".plugnz-hook-write-"));
24355
24450
  try {
@@ -24363,7 +24458,7 @@ function writeExactFile(path, text) {
24363
24458
  }
24364
24459
 
24365
24460
  // src/hosts/pi-writer.ts
24366
- import { existsSync as existsSync28, lstatSync as lstatSync20, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync11, readFileSync as readFileSync29, readdirSync as readdirSync19, renameSync as renameSync9, rmSync as rmSync12, writeFileSync as writeFileSync12 } from "node:fs";
24461
+ import { existsSync as existsSync27, lstatSync as lstatSync21, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync11, readFileSync as readFileSync29, readdirSync as readdirSync19, renameSync as renameSync9, rmSync as rmSync12, writeFileSync as writeFileSync12 } from "node:fs";
24367
24462
  import { basename as basename4, dirname as dirname14, join as join35, resolve as resolve21 } from "node:path";
24368
24463
  import { tmpdir as tmpdir8 } from "node:os";
24369
24464
  var MARKER7 = ".plgnz-install.json";
@@ -24397,7 +24492,7 @@ var piWriter = {
24397
24492
  const backups = [];
24398
24493
  try {
24399
24494
  for (const candidate of [...new Set([target, ...prior])]) {
24400
- if (!existsSync28(candidate)) {
24495
+ if (!existsSync27(candidate)) {
24401
24496
  backups.push({ target: candidate });
24402
24497
  continue;
24403
24498
  }
@@ -24454,7 +24549,7 @@ var piWriter = {
24454
24549
  function stagePlugin4(source, stage, plugin, market) {
24455
24550
  assertTree(source);
24456
24551
  const root = join35(source, "skills");
24457
- if (!existsSync28(root) || !lstatSync20(root).isDirectory())
24552
+ if (!existsSync27(root) || !lstatSync21(root).isDirectory())
24458
24553
  throw new Error("Pi standalone delivery requires plugin skills/ directories");
24459
24554
  const destination = join35(stage, packageName(plugin, market));
24460
24555
  projectPluginForPi(source, destination, plugin);
@@ -24462,7 +24557,7 @@ function stagePlugin4(source, stage, plugin, market) {
24462
24557
  const walk = (dir) => {
24463
24558
  for (const entry of readdirSync19(dir)) {
24464
24559
  const path = join35(dir, entry);
24465
- const stat = lstatSync20(path);
24560
+ const stat = lstatSync21(path);
24466
24561
  if (stat.isDirectory())
24467
24562
  walk(path);
24468
24563
  else if (entry === "SKILL.md")
@@ -24506,7 +24601,7 @@ function packageName(plugin, market) {
24506
24601
  }
24507
24602
  function owner2(dir) {
24508
24603
  const file = join35(dir, MARKER7);
24509
- if (!existsSync28(file))
24604
+ if (!existsSync27(file))
24510
24605
  return null;
24511
24606
  try {
24512
24607
  const x = JSON.parse(readFileSync29(file, "utf8"));
@@ -24522,12 +24617,12 @@ function owner2(dir) {
24522
24617
  }
24523
24618
  function ownedFor(id, source) {
24524
24619
  assertPiStore();
24525
- if (!existsSync28(skillsDir()))
24620
+ if (!existsSync27(skillsDir()))
24526
24621
  return [];
24527
24622
  const out = [];
24528
24623
  for (const name of readdirSync19(skillsDir())) {
24529
24624
  const path = join35(skillsDir(), name);
24530
- if (!lstatSync20(path).isDirectory())
24625
+ if (!lstatSync21(path).isDirectory())
24531
24626
  continue;
24532
24627
  const mark = owner2(path);
24533
24628
  if (mark?.pluginId === id && (source === undefined || mark.source === source))
@@ -24537,7 +24632,7 @@ function ownedFor(id, source) {
24537
24632
  }
24538
24633
  function checkTarget(target, id, source) {
24539
24634
  assertUnder(skillsDir(), target);
24540
- if (!existsSync28(target))
24635
+ if (!existsSync27(target))
24541
24636
  return;
24542
24637
  const mark = owner2(target);
24543
24638
  if (mark === null)
@@ -24546,7 +24641,7 @@ function checkTarget(target, id, source) {
24546
24641
  throw new Error(`Pi standalone skill belongs to another source; refusing to replace it: ${target}`);
24547
24642
  }
24548
24643
  function sameTree6(stage, target) {
24549
- if (!existsSync28(target))
24644
+ if (!existsSync27(target))
24550
24645
  return false;
24551
24646
  const bytes = readFileSync29;
24552
24647
  const list = (root) => {
@@ -24555,7 +24650,7 @@ function sameTree6(stage, target) {
24555
24650
  for (const name of readdirSync19(dir).sort()) {
24556
24651
  if (name === MARKER7)
24557
24652
  continue;
24558
- const path = join35(dir, name), relative = prefix ? `${prefix}/${name}` : name, stat = lstatSync20(path);
24653
+ const path = join35(dir, name), relative = prefix ? `${prefix}/${name}` : name, stat = lstatSync21(path);
24559
24654
  if (stat.isDirectory())
24560
24655
  walk(path, relative);
24561
24656
  else if (stat.isFile())
@@ -24570,11 +24665,11 @@ function sameTree6(stage, target) {
24570
24665
  return JSON.stringify(list(stage)) === JSON.stringify(list(target));
24571
24666
  }
24572
24667
  function assertTree(root) {
24573
- const stat = lstatSync20(root);
24668
+ const stat = lstatSync21(root);
24574
24669
  if (stat.isSymbolicLink() || !stat.isDirectory())
24575
24670
  throw new Error(`Pi plugin root is not a real directory: ${root}`);
24576
24671
  for (const name of readdirSync19(root)) {
24577
- const path = join35(root, name), child = lstatSync20(path);
24672
+ const path = join35(root, name), child = lstatSync21(path);
24578
24673
  if (child.isSymbolicLink())
24579
24674
  throw new Error(`Pi plugin contains symlink: ${path}`);
24580
24675
  if (child.isDirectory())
@@ -24604,18 +24699,18 @@ function assertPiStore() {
24604
24699
  let current = home;
24605
24700
  for (const part of [basename4(dirname14(root)), basename4(root)]) {
24606
24701
  current = join35(current, part);
24607
- if (existsSync28(current) && lstatSync20(current).isSymbolicLink())
24702
+ if (existsSync27(current) && lstatSync21(current).isSymbolicLink())
24608
24703
  throw new Error(`Pi managed path component is a symlink: ${current}`);
24609
24704
  }
24610
- if (existsSync28(root))
24705
+ if (existsSync27(root))
24611
24706
  assertRealDirectory(root);
24612
- if (existsSync28(skillsDir())) {
24707
+ if (existsSync27(skillsDir())) {
24613
24708
  assertUnder(root, skillsDir());
24614
24709
  assertRealDirectory(skillsDir());
24615
24710
  }
24616
24711
  }
24617
24712
  function assertRealDirectory(path) {
24618
- const stat = lstatSync20(path);
24713
+ const stat = lstatSync21(path);
24619
24714
  if (stat.isSymbolicLink())
24620
24715
  throw new Error(`Pi managed path component is a symlink: ${path}`);
24621
24716
  if (!stat.isDirectory())
@@ -24628,7 +24723,7 @@ function assertUnder(root, path) {
24628
24723
  let current = base;
24629
24724
  for (const part of candidate.slice(base.length).split("/").filter(Boolean)) {
24630
24725
  current = join35(current, part);
24631
- if (existsSync28(current) && lstatSync20(current).isSymbolicLink())
24726
+ if (existsSync27(current) && lstatSync21(current).isSymbolicLink())
24632
24727
  throw new Error(`Pi managed path component is a symlink: ${current}`);
24633
24728
  }
24634
24729
  }
@@ -24644,7 +24739,7 @@ var piHookWriter = createNativeHookWriter({
24644
24739
  });
24645
24740
 
24646
24741
  // src/hosts/dcode-writer.ts
24647
- import { cpSync as cpSync11, existsSync as existsSync29, lstatSync as lstatSync21, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync12, readFileSync as readFileSync30, readdirSync as readdirSync20, realpathSync as realpathSync5, renameSync as renameSync10, rmSync as rmSync13, writeFileSync as writeFileSync13 } from "node:fs";
24742
+ import { cpSync as cpSync11, existsSync as existsSync28, lstatSync as lstatSync22, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync12, readFileSync as readFileSync30, readdirSync as readdirSync20, realpathSync as realpathSync5, renameSync as renameSync10, rmSync as rmSync13, writeFileSync as writeFileSync13 } from "node:fs";
24648
24743
  import { basename as basename5, dirname as dirname15, join as join36, resolve as resolve22 } from "node:path";
24649
24744
  import { tmpdir as tmpdir9 } from "node:os";
24650
24745
  import { spawn as spawnChild } from "node:child_process";
@@ -24673,7 +24768,7 @@ function nativePython() {
24673
24768
  throw new Error("dcode native lock runtime is unavailable");
24674
24769
  const shebang = readFileSync30(binary, "utf8").split(/\r?\n/, 1)[0] ?? "";
24675
24770
  const match = /^#!(\/[^\s]+python(?:\d+(?:\.\d+)?)?)$/u.exec(shebang);
24676
- if (match?.[1] === undefined || !existsSync29(match[1]))
24771
+ if (match?.[1] === undefined || !existsSync28(match[1]))
24677
24772
  throw new Error("dcode native Python interpreter is unverified; set OPEN_PLUGIN_DCODE_PYTHON_BIN to its verified interpreter");
24678
24773
  return match[1];
24679
24774
  }
@@ -24774,7 +24869,7 @@ function observeDcodeTarget(target) {
24774
24869
  throw new Error(`dcode install record ${nativeId} has duplicate rows`);
24775
24870
  const path = rowInstall(rows[0], nativeId);
24776
24871
  assertCachePath(path);
24777
- const present = existsSync29(path);
24872
+ const present = existsSync28(path);
24778
24873
  const marker = present ? ownership3(path) : null;
24779
24874
  const body = present ? readDoc2(join36(path, MARKER8), {}, "ownership marker") : {};
24780
24875
  const owned = marker?.pluginId === nativeId;
@@ -24795,7 +24890,7 @@ function observeDcodeTarget(target) {
24795
24890
  });
24796
24891
  }
24797
24892
  function dcodeLifecycleReadback(binding) {
24798
- if (existsSync29(join36(dcodeStateDir(), READBACK_FAULT)))
24893
+ if (existsSync28(join36(dcodeStateDir(), READBACK_FAULT)))
24799
24894
  throw new Error(`dcode readback failed for ${binding.nativeId}`);
24800
24895
  const installations = observeDcodeTarget(binding.target);
24801
24896
  const row = installations.find((item) => item.nativeId === binding.nativeId);
@@ -24816,7 +24911,7 @@ function dcodeLifecycleReadback(binding) {
24816
24911
  transition: { requirement: present ? "restart" : "none", status: "effective" },
24817
24912
  installedFingerprint: present ? row.installedFingerprint : null,
24818
24913
  contentRoots: present ? row.contentRoots : [],
24819
- retention: { pluginData: existsSync29(dataRoot) ? { state: "present", fingerprint: fingerprintTree(dataRoot) } : { state: "absent", fingerprint: null }, inactiveMetadata: { state: "absent", fingerprint: null } }
24914
+ retention: { pluginData: existsSync28(dataRoot) ? { state: "present", fingerprint: fingerprintTree(dataRoot) } : { state: "absent", fingerprint: null }, inactiveMetadata: { state: "absent", fingerprint: null } }
24820
24915
  };
24821
24916
  }
24822
24917
  function captureDcodeRollback(binding, attemptId, operationId) {
@@ -24825,13 +24920,13 @@ function captureDcodeRollback(binding, attemptId, operationId) {
24825
24920
  const registry = readRegistry3(dcodeRegistryFile());
24826
24921
  const enabled = boolObject(readEnablement(dcodeEnablementFile()).enabledPlugins, "enabledPlugins");
24827
24922
  const row = object9(registry.plugins, "registry plugins")[binding.nativeId];
24828
- const state = { row: row ?? null, enabled: enabled[binding.nativeId] ?? null, registryExisted: existsSync29(dcodeRegistryFile()), enablementExisted: existsSync29(dcodeEnablementFile()) };
24923
+ const state = { row: row ?? null, enabled: enabled[binding.nativeId] ?? null, registryExisted: existsSync28(dcodeRegistryFile()), enablementExisted: existsSync28(dcodeEnablementFile()) };
24829
24924
  writeFileSync13(join36(dir, "state.json"), JSON.stringify(state));
24830
24925
  for (const [index, item] of rowsFor(row).entries()) {
24831
24926
  const path = rowInstall(item, binding.nativeId);
24832
24927
  assertCachePath(path);
24833
24928
  assertNoSymlinks6(path);
24834
- if (existsSync29(path))
24929
+ if (existsSync28(path))
24835
24930
  cpSync11(path, join36(dir, `content-${index}`), { recursive: true });
24836
24931
  }
24837
24932
  return dir;
@@ -24917,7 +25012,7 @@ var dcodeDefinition = {
24917
25012
  stageActivation: async (request) => {
24918
25013
  const dir = lifecycleDirectory(request.snapshot.attemptId, request.snapshot.operationId);
24919
25014
  const stagingRoot = join36(dir, "stage");
24920
- if (existsSync29(stagingRoot))
25015
+ if (existsSync28(stagingRoot))
24921
25016
  throw new Error("dcode preparation stage already exists");
24922
25017
  mkdirSync13(stagingRoot, { recursive: true });
24923
25018
  const manifest = declaredManifest(request.snapshot.packageRoot, request.snapshot.packageName);
@@ -24939,7 +25034,7 @@ var dcodeDefinition = {
24939
25034
  const found = new Set;
24940
25035
  for (const candidate of dcodeMcpCandidates()) {
24941
25036
  const file = join36(projection.stagingRoot, candidate.kind === "spec" ? candidate.file : candidate.manifest);
24942
- if (!existsSync29(file))
25037
+ if (!existsSync28(file))
24943
25038
  continue;
24944
25039
  const body = readDoc2(file, {}, "MCP document");
24945
25040
  if (typeof body.mcpServers !== "object" || body.mcpServers === null || Array.isArray(body.mcpServers))
@@ -24979,7 +25074,7 @@ var dcodeDefinition = {
24979
25074
  if (manifest.version !== projection.packageVersion)
24980
25075
  throw new Error("dcode legacy version differs; refusing adoption");
24981
25076
  }
24982
- if (existsSync29(target) && ownership3(target)?.pluginId !== projection.nativeId)
25077
+ if (existsSync28(target) && ownership3(target)?.pluginId !== projection.nativeId)
24983
25078
  throw new Error("dcode lifecycle target is not owned");
24984
25079
  const rollbackReference = captureDcodeRollback(projection, projection.attemptId, projection.operationId);
24985
25080
  writeFileSync13(join36(rollbackReference, "next-path.json"), JSON.stringify({ target }));
@@ -24998,7 +25093,7 @@ var dcodeDefinition = {
24998
25093
  const target = lifecycleSlot(prepared.handle.nativeId, prepared.handle.projectedFingerprint);
24999
25094
  assertCachePath(target);
25000
25095
  mkdirSync13(dirname15(target), { recursive: true });
25001
- if (existsSync29(target)) {
25096
+ if (existsSync28(target)) {
25002
25097
  const marker = ownership3(target);
25003
25098
  if (marker?.pluginId !== prepared.handle.nativeId)
25004
25099
  throw new Error("dcode lifecycle activation would overwrite foreign content");
@@ -25038,22 +25133,22 @@ var dcodeDefinition = {
25038
25133
  },
25039
25134
  rollback: async (handle) => {
25040
25135
  await acquireNativeLock(handle.attemptId, handle.operationId);
25041
- if (!existsSync29(join36(handle.rollbackReference, "state.json")))
25136
+ if (!existsSync28(join36(handle.rollbackReference, "state.json")))
25042
25137
  throw new Error("dcode rollback snapshot is missing; recovery refused");
25043
25138
  const state = readDoc2(join36(handle.rollbackReference, "state.json"), {}, "rollback state");
25044
25139
  if (recoveringNativeLocks.has(`${handle.attemptId}:${handle.operationId}`))
25045
25140
  assertRecoveryRollbackMetadata(handle, state);
25046
25141
  for (const [index, root] of handle.prior.contentRoots.entries()) {
25047
25142
  const backup = join36(handle.rollbackReference, `content-${index}`);
25048
- if (!existsSync29(backup) || fingerprintTree(backup) !== root.fingerprint)
25143
+ if (!existsSync28(backup) || fingerprintTree(backup) !== root.fingerprint)
25049
25144
  throw new Error("dcode rollback snapshot bytes do not match the sealed prior");
25050
- if (recoveringNativeLocks.has(`${handle.attemptId}:${handle.operationId}`) && existsSync29(root.path) && fingerprintTree(root.path) !== root.fingerprint)
25145
+ if (recoveringNativeLocks.has(`${handle.attemptId}:${handle.operationId}`) && existsSync28(root.path) && fingerprintTree(root.path) !== root.fingerprint)
25051
25146
  throw new Error("dcode prior root changed outside the sealed operation; refusing stale overwrite");
25052
25147
  }
25053
25148
  const target = handle.projectedFingerprint === null ? undefined : lifecycleSlot(handle.nativeId, handle.projectedFingerprint);
25054
25149
  if (target !== undefined)
25055
25150
  assertCachePath(target);
25056
- if (target !== undefined && existsSync29(target) && !handle.prior.contentRoots.some((root) => resolve22(root.path) === resolve22(target))) {
25151
+ if (target !== undefined && existsSync28(target) && !handle.prior.contentRoots.some((root) => resolve22(root.path) === resolve22(target))) {
25057
25152
  if (ownership3(target)?.pluginId !== handle.nativeId || recoveringNativeLocks.has(`${handle.attemptId}:${handle.operationId}`) && fingerprintTree(target) !== handle.projectedFingerprint)
25058
25153
  throw new Error("dcode rollback candidate differs from the sealed operation; refusing stale overwrite");
25059
25154
  rmSync13(target, { recursive: true });
@@ -25062,7 +25157,7 @@ var dcodeDefinition = {
25062
25157
  const path = rowInstall(row, handle.nativeId);
25063
25158
  assertCachePath(path);
25064
25159
  const backup = join36(handle.rollbackReference, `content-${index}`);
25065
- if (existsSync29(backup)) {
25160
+ if (existsSync28(backup)) {
25066
25161
  mkdirSync13(dirname15(path), { recursive: true });
25067
25162
  cpSync11(backup, path, { recursive: true });
25068
25163
  }
@@ -25096,14 +25191,14 @@ var dcodeDefinition = {
25096
25191
  const next = readDoc2(nextFile, {}, "cleanup target");
25097
25192
  if (disposition === "verified-commit" && recovering !== undefined) {
25098
25193
  const retiredRoots = recovering.prior.contentRoots.filter((root) => !recovering.expected.contentRoots.some((next) => resolve22(next.path) === resolve22(root.path)));
25099
- if (existsSync29(priorFile))
25194
+ if (existsSync28(priorFile))
25100
25195
  assertRecoveryRollbackMetadata(recovering, readDoc2(priorFile, {}, "rollback state"));
25101
- else if (retiredRoots.some((root) => existsSync29(root.path)))
25196
+ else if (retiredRoots.some((root) => existsSync28(root.path)))
25102
25197
  throw new Error("dcode cleanup prior metadata is missing; recovery refused");
25103
- if (existsSync29(nextFile) && (typeof next.target !== "string" || !recovering.expected.contentRoots.some((root) => resolve22(root.path) === resolve22(next.target))))
25198
+ if (existsSync28(nextFile) && (typeof next.target !== "string" || !recovering.expected.contentRoots.some((root) => resolve22(root.path) === resolve22(next.target))))
25104
25199
  throw new Error("dcode cleanup target differs from the sealed expected root; recovery refused");
25105
25200
  for (const root of retiredRoots) {
25106
- if (existsSync29(root.path) && fingerprintTree(root.path) !== root.fingerprint)
25201
+ if (existsSync28(root.path) && fingerprintTree(root.path) !== root.fingerprint)
25107
25202
  throw new Error("dcode cleanup prior root changed; refusing stale deletion");
25108
25203
  }
25109
25204
  for (const root of retiredRoots)
@@ -25185,7 +25280,7 @@ var dcodeWriter = {
25185
25280
  const slot = ownership3(target);
25186
25281
  if (slot !== null && (slot.source !== resolved.sourceUri || slot.pluginId !== id))
25187
25282
  throw new Error(`dcode plugin ${id} belongs to another source; refusing to replace it`);
25188
- if (existsSync29(target) && slot === null)
25283
+ if (existsSync28(target) && slot === null)
25189
25284
  throw new Error(`dcode cache target is unowned; refusing to replace it: ${target}`);
25190
25285
  const former = prior.kind === "none" ? undefined : prior.path;
25191
25286
  const unchanged = (former === undefined || resolve22(former) === resolve22(target)) && slot?.kind === "current" && slot.fingerprint === sourceFingerprint && slot.projectedFingerprint === projected && slot.sourceRevision === resolved.sha && sameTree7(stage, target);
@@ -25229,13 +25324,13 @@ var dcodeWriter = {
25229
25324
  }
25230
25325
  } finally {
25231
25326
  rmSync13(stage, { recursive: true, force: true });
25232
- if (opts?.dryRun !== true && existsSync29(managedRoot) && readdirSync20(managedRoot).every((name) => name.startsWith(".plgnz-dcode-"))) {
25327
+ if (opts?.dryRun !== true && existsSync28(managedRoot) && readdirSync20(managedRoot).every((name) => name.startsWith(".plgnz-dcode-"))) {
25233
25328
  rmSync13(managedRoot, { recursive: true, force: true });
25234
25329
  }
25235
25330
  }
25236
25331
  },
25237
25332
  async pin(plugin, opts) {
25238
- if (plugin.path === undefined || !existsSync29(plugin.path))
25333
+ if (plugin.path === undefined || !existsSync28(plugin.path))
25239
25334
  return { changes: [], refusals: [] };
25240
25335
  assertCachePath(plugin.path);
25241
25336
  if (ownership3(plugin.path)?.pluginId !== plugin.id)
@@ -25319,7 +25414,7 @@ function assessPrior(value, id, source, adopt, name, version, sourceDir) {
25319
25414
  throw new Error(`dcode plugin ${id} has a conflicting ownership marker`);
25320
25415
  if (!adopt)
25321
25416
  throw new Error(`dcode install record ${id} is not plgnz-owned; refusing to replace it`);
25322
- if (!existsSync29(install) || lstatSync21(install).isSymbolicLink() || !lstatSync21(install).isDirectory()) {
25417
+ if (!existsSync28(install) || lstatSync22(install).isSymbolicLink() || !lstatSync22(install).isDirectory()) {
25323
25418
  throw new Error(`dcode install record ${id} is not plgnz-owned; refusing to replace it`);
25324
25419
  }
25325
25420
  assertNoSymlinks6(install);
@@ -25342,7 +25437,7 @@ function assessPrior(value, id, source, adopt, name, version, sourceDir) {
25342
25437
  return { kind: "adoptable", path: install };
25343
25438
  }
25344
25439
  function declaredManifest(dir, expectedName) {
25345
- const manifest = MANIFESTS.map((relative) => join36(dir, relative)).find((file) => existsSync29(file));
25440
+ const manifest = MANIFESTS.map((relative) => join36(dir, relative)).find((file) => existsSync28(file));
25346
25441
  if (manifest === undefined)
25347
25442
  throw new Error("dcode stage has no supported plugin manifest");
25348
25443
  let parsed;
@@ -25367,7 +25462,7 @@ function stagePlugin5(source, stage, name, version) {
25367
25462
  throw new Error(`dcode manifest identity does not match ${name}`);
25368
25463
  }
25369
25464
  function forceAutoUpdateOff(dir) {
25370
- const manifest = MANIFESTS.map((relative) => join36(dir, relative)).find((file) => existsSync29(file));
25465
+ const manifest = MANIFESTS.map((relative) => join36(dir, relative)).find((file) => existsSync28(file));
25371
25466
  if (manifest === undefined)
25372
25467
  throw new Error("dcode stage has no supported plugin manifest");
25373
25468
  const parsed = object9(JSON.parse(readFileSync30(manifest, "utf8")), "manifest");
@@ -25381,7 +25476,7 @@ function forceAutoUpdateOff(dir) {
25381
25476
  `);
25382
25477
  }
25383
25478
  function assertReadback(id, registryFile, enablementFile, target, version, projected, sourceRevision) {
25384
- if (existsSync29(join36(dcodeStateDir(), READBACK_FAULT)))
25479
+ if (existsSync28(join36(dcodeStateDir(), READBACK_FAULT)))
25385
25480
  throw new Error(`dcode readback failed for ${id}`);
25386
25481
  const registry = readRegistry3(registryFile);
25387
25482
  const enablement = readEnablement(enablementFile);
@@ -25407,18 +25502,18 @@ function assertReadback(id, registryFile, enablementFile, target, version, proje
25407
25502
  function retireFormer(path) {
25408
25503
  try {
25409
25504
  assertCachePath(path);
25410
- const stat = lstatSync21(path);
25505
+ const stat = lstatSync22(path);
25411
25506
  if (stat.isSymbolicLink() || !stat.isDirectory())
25412
25507
  throw new Error("former cache is not a directory");
25413
25508
  const backup = join36(dirname15(path), `.plgnz-dcode-retire-${basename5(path)}`);
25414
- if (existsSync29(backup)) {
25415
- if (!lstatSync21(backup).isDirectory())
25509
+ if (existsSync28(backup)) {
25510
+ if (!lstatSync22(backup).isDirectory())
25416
25511
  throw new Error("retire destination is not a directory");
25417
25512
  rmSync13(backup, { recursive: true, force: true });
25418
25513
  }
25419
25514
  renameSync10(path, backup);
25420
25515
  rmSync13(backup, { recursive: true, force: true });
25421
- if (existsSync29(path))
25516
+ if (existsSync28(path))
25422
25517
  throw new Error("former cache remains");
25423
25518
  return;
25424
25519
  } catch {
@@ -25440,7 +25535,7 @@ function listTree(root) {
25440
25535
  continue;
25441
25536
  const file = join36(dir, entry);
25442
25537
  const relative = prefix ? `${prefix}/${entry}` : entry;
25443
- const stat = lstatSync21(file);
25538
+ const stat = lstatSync22(file);
25444
25539
  if (stat.isSymbolicLink())
25445
25540
  throw new Error(`dcode plugin contains symlink: ${file}`);
25446
25541
  if (stat.isDirectory())
@@ -25455,12 +25550,12 @@ function listTree(root) {
25455
25550
  return out;
25456
25551
  }
25457
25552
  function sameTree7(left, right) {
25458
- if (!existsSync29(right))
25553
+ if (!existsSync28(right))
25459
25554
  return false;
25460
25555
  return JSON.stringify(listTree(left)) === JSON.stringify(listTree(right));
25461
25556
  }
25462
25557
  function readDoc2(file, fallback, label) {
25463
- if (!existsSync29(file))
25558
+ if (!existsSync28(file))
25464
25559
  return fallback;
25465
25560
  try {
25466
25561
  const value = JSON.parse(readFileSync30(file, "utf8"));
@@ -25520,7 +25615,7 @@ function ownership3(dir) {
25520
25615
  assertManagedPath4(dir);
25521
25616
  const file = join36(dir, MARKER8);
25522
25617
  assertManagedPath4(file);
25523
- if (!existsSync29(file))
25618
+ if (!existsSync28(file))
25524
25619
  return null;
25525
25620
  try {
25526
25621
  const value = object9(JSON.parse(readFileSync30(file, "utf8")), "ownership marker");
@@ -25550,7 +25645,7 @@ function writeDoc2(file, value) {
25550
25645
  }
25551
25646
  function snapshot2(file) {
25552
25647
  const read = readFileSync30;
25553
- return existsSync29(file) ? read(file) : undefined;
25648
+ return existsSync28(file) ? read(file) : undefined;
25554
25649
  }
25555
25650
  function restore3(file, before) {
25556
25651
  try {
@@ -25563,7 +25658,7 @@ function restore3(file, before) {
25563
25658
  } catch {}
25564
25659
  }
25565
25660
  function activate5(stage, target, parent) {
25566
- if (!existsSync29(target)) {
25661
+ if (!existsSync28(target)) {
25567
25662
  renameSync10(stage, target);
25568
25663
  return { commit: () => {}, rollback: () => rmSync13(target, { recursive: true, force: true }) };
25569
25664
  }
@@ -25589,7 +25684,7 @@ function moveAside3(path, parent = dirname15(path)) {
25589
25684
  return {
25590
25685
  commit: () => rmSync13(backupRoot, { recursive: true, force: true }),
25591
25686
  rollback: () => {
25592
- if (existsSync29(backup))
25687
+ if (existsSync28(backup))
25593
25688
  renameSync10(backup, path);
25594
25689
  rmSync13(backupRoot, { recursive: true, force: true });
25595
25690
  }
@@ -25598,7 +25693,7 @@ function moveAside3(path, parent = dirname15(path)) {
25598
25693
  function assertNoSymlinks6(dir) {
25599
25694
  for (const entry of readdirSync20(dir)) {
25600
25695
  const file = join36(dir, entry);
25601
- const stat = lstatSync21(file);
25696
+ const stat = lstatSync22(file);
25602
25697
  if (stat.isSymbolicLink())
25603
25698
  throw new Error(`dcode plugin contains symlink: ${file}`);
25604
25699
  if (stat.isDirectory())
@@ -25615,19 +25710,19 @@ function assertCachePath(path) {
25615
25710
  if (target === root || !target.startsWith(`${root}/`))
25616
25711
  throw new Error(`dcode path escapes managed cache: ${path}`);
25617
25712
  let current = root;
25618
- if (existsSync29(current) && lstatSync21(current).isSymbolicLink())
25713
+ if (existsSync28(current) && lstatSync22(current).isSymbolicLink())
25619
25714
  throw new Error(`dcode native path contains symlink: ${current}`);
25620
25715
  const relative = target.slice(root.length).replace(/^\//, "");
25621
25716
  for (const part of relative.length === 0 ? [] : relative.split("/")) {
25622
25717
  if (part === "" || part === "." || part === "..")
25623
25718
  throw new Error(`dcode path escapes managed cache: ${path}`);
25624
25719
  current = join36(current, part);
25625
- if (!existsSync29(current))
25720
+ if (!existsSync28(current))
25626
25721
  return;
25627
- if (lstatSync21(current).isSymbolicLink())
25722
+ if (lstatSync22(current).isSymbolicLink())
25628
25723
  throw new Error(`dcode native path contains symlink: ${current}`);
25629
25724
  }
25630
- if (!existsSync29(target) || !existsSync29(root))
25725
+ if (!existsSync28(target) || !existsSync28(root))
25631
25726
  return;
25632
25727
  const realRoot = realpathSync5(root);
25633
25728
  const realTarget = realpathSync5(target);
@@ -25640,18 +25735,18 @@ function assertManagedPath4(path) {
25640
25735
  if (target !== root && !target.startsWith(`${root}/`))
25641
25736
  throw new Error(`dcode path escapes native root: ${path}`);
25642
25737
  let current = root;
25643
- if (existsSync29(current) && lstatSync21(current).isSymbolicLink())
25738
+ if (existsSync28(current) && lstatSync22(current).isSymbolicLink())
25644
25739
  throw new Error(`dcode native path contains symlink: ${current}`);
25645
25740
  const relative = target.slice(root.length).replace(/^\//, "");
25646
25741
  for (const part of relative ? relative.split("/") : []) {
25647
25742
  current = join36(current, part);
25648
- if (existsSync29(current) && lstatSync21(current).isSymbolicLink())
25743
+ if (existsSync28(current) && lstatSync22(current).isSymbolicLink())
25649
25744
  throw new Error(`dcode native path contains symlink: ${current}`);
25650
25745
  }
25651
25746
  }
25652
25747
 
25653
25748
  // src/hosts/opencode-writer.ts
25654
- import { cpSync as cpSync12, existsSync as existsSync30, lstatSync as lstatSync22, mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync13, readFileSync as readFileSync31, readdirSync as readdirSync21, renameSync as renameSync11, rmSync as rmSync14, writeFileSync as writeFileSync14 } from "node:fs";
25749
+ import { cpSync as cpSync12, existsSync as existsSync29, lstatSync as lstatSync23, mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync13, readFileSync as readFileSync31, readdirSync as readdirSync21, renameSync as renameSync11, rmSync as rmSync14, writeFileSync as writeFileSync14 } from "node:fs";
25655
25750
  import { dirname as dirname16, join as join37 } from "node:path";
25656
25751
  import { tmpdir as tmpdir10 } from "node:os";
25657
25752
  var MARKER9 = ".plgnz-install.json";
@@ -25683,7 +25778,7 @@ var opencodeWriter = {
25683
25778
  try {
25684
25779
  for (const key of keys2()) {
25685
25780
  const target = targets[key];
25686
- if (!existsSync30(target)) {
25781
+ if (!existsSync29(target)) {
25687
25782
  moves.push({ target });
25688
25783
  continue;
25689
25784
  }
@@ -25722,7 +25817,7 @@ var opencodeWriter = {
25722
25817
  const targets = targetsFor(name, plugin);
25723
25818
  assertStore();
25724
25819
  for (const key of keys2())
25725
- if (existsSync30(targets[key])) {
25820
+ if (existsSync29(targets[key])) {
25726
25821
  assertManagedTree(targets[key]);
25727
25822
  if (!owned(targets[key], id))
25728
25823
  throw new Error(`OpenCode target is not owned by ${id}: ${targets[key]}`);
@@ -25731,7 +25826,7 @@ var opencodeWriter = {
25731
25826
  try {
25732
25827
  for (const key of keys2()) {
25733
25828
  const target = targets[key];
25734
- if (!existsSync30(target))
25829
+ if (!existsSync29(target))
25735
25830
  continue;
25736
25831
  const root = mkdtempSync13(join37(dirname16(target), ".plgnz-opencode-remove-"));
25737
25832
  const backup = join37(root, "previous");
@@ -25777,13 +25872,13 @@ function stagePackage(source, stage, name, activePrivateRoot, ownerValue) {
25777
25872
  return { private: privateRoot, skills, commands };
25778
25873
  }
25779
25874
  function sourceCommands(source) {
25780
- const root = existsSync30(join37(source, ".claude", "commands")) ? join37(source, ".claude", "commands") : join37(source, "commands");
25781
- if (!existsSync30(root))
25875
+ const root = existsSync29(join37(source, ".claude", "commands")) ? join37(source, ".claude", "commands") : join37(source, "commands");
25876
+ if (!existsSync29(root))
25782
25877
  return [];
25783
25878
  const out = [];
25784
25879
  const walk = (dir) => {
25785
25880
  for (const entry of readdirSync21(dir).sort()) {
25786
- const path = join37(dir, entry), stat = lstatSync22(path);
25881
+ const path = join37(dir, entry), stat = lstatSync23(path);
25787
25882
  if (stat.isDirectory()) {
25788
25883
  walk(path);
25789
25884
  continue;
@@ -25804,12 +25899,12 @@ function sourceCommands(source) {
25804
25899
  }
25805
25900
  function manualSkills(source) {
25806
25901
  const root = join37(source, "skills");
25807
- if (!existsSync30(root))
25902
+ if (!existsSync29(root))
25808
25903
  return [];
25809
25904
  const out = [];
25810
25905
  const walk = (dir) => {
25811
25906
  for (const entry of readdirSync21(dir).sort()) {
25812
- const path = join37(dir, entry), stat = lstatSync22(path);
25907
+ const path = join37(dir, entry), stat = lstatSync23(path);
25813
25908
  if (stat.isDirectory())
25814
25909
  walk(path);
25815
25910
  else if (stat.isFile() && entry === "SKILL.md") {
@@ -25915,7 +26010,7 @@ function targetsFor(name, commandNamespace) {
25915
26010
  }
25916
26011
  function owner3(path) {
25917
26012
  const file = join37(path, MARKER9);
25918
- if (!existsSync30(file))
26013
+ if (!existsSync29(file))
25919
26014
  return null;
25920
26015
  try {
25921
26016
  const value = JSON.parse(readFileSync31(file, "utf8"));
@@ -25935,7 +26030,7 @@ function owned(privateTarget, id, source) {
25935
26030
  }
25936
26031
  function checkTargets(targets, id, source) {
25937
26032
  for (const key of keys2())
25938
- if (existsSync30(targets[key])) {
26033
+ if (existsSync29(targets[key])) {
25939
26034
  assertManagedTree(targets[key]);
25940
26035
  if (!owned(targets[key], id, source))
25941
26036
  throw new Error(`OpenCode target is unowned or belongs to another source: ${targets[key]}`);
@@ -25945,7 +26040,7 @@ function allSame(staged, targets) {
25945
26040
  return keys2().every((key) => sameTree8(staged[key], targets[key]));
25946
26041
  }
25947
26042
  function sameTree8(a, b) {
25948
- if (!existsSync30(a) || !existsSync30(b))
26043
+ if (!existsSync29(a) || !existsSync29(b))
25949
26044
  return false;
25950
26045
  const bytes = readFileSync31;
25951
26046
  const list = (root) => {
@@ -25954,7 +26049,7 @@ function sameTree8(a, b) {
25954
26049
  for (const name of readdirSync21(dir).sort()) {
25955
26050
  if (name === MARKER9)
25956
26051
  continue;
25957
- const path = join37(dir, name), rel = prefix ? `${prefix}/${name}` : name, stat = lstatSync22(path);
26052
+ const path = join37(dir, name), rel = prefix ? `${prefix}/${name}` : name, stat = lstatSync23(path);
25958
26053
  if (stat.isDirectory())
25959
26054
  walk(path, rel);
25960
26055
  else if (stat.isFile())
@@ -25969,11 +26064,11 @@ function sameTree8(a, b) {
25969
26064
  return JSON.stringify(list(a)) === JSON.stringify(list(b));
25970
26065
  }
25971
26066
  function assertTree2(root) {
25972
- const stat = lstatSync22(root);
26067
+ const stat = lstatSync23(root);
25973
26068
  if (stat.isSymbolicLink() || !stat.isDirectory())
25974
26069
  throw new Error(`OpenCode plugin root is not a real directory: ${root}`);
25975
26070
  for (const name of readdirSync21(root)) {
25976
- const path = join37(root, name), child = lstatSync22(path);
26071
+ const path = join37(root, name), child = lstatSync23(path);
25977
26072
  if (name === MARKER9)
25978
26073
  throw new Error(`OpenCode plugin reserves ${MARKER9}: ${path}`);
25979
26074
  if (child.isSymbolicLink())
@@ -25985,11 +26080,11 @@ function assertTree2(root) {
25985
26080
  }
25986
26081
  }
25987
26082
  function assertManagedTree(root) {
25988
- const stat = lstatSync22(root);
26083
+ const stat = lstatSync23(root);
25989
26084
  if (stat.isSymbolicLink() || !stat.isDirectory())
25990
26085
  throw new Error(`OpenCode managed tree is unsafe: ${root}`);
25991
26086
  for (const name of readdirSync21(root)) {
25992
- const path = join37(root, name), child = lstatSync22(path);
26087
+ const path = join37(root, name), child = lstatSync23(path);
25993
26088
  if (child.isSymbolicLink())
25994
26089
  throw new Error(`OpenCode managed tree contains symlink: ${path}`);
25995
26090
  if (child.isDirectory())
@@ -26000,11 +26095,11 @@ function assertManagedTree(root) {
26000
26095
  }
26001
26096
  function assertSupportedRoot(source) {
26002
26097
  for (const entry of ["agents", "hooks", ".claude/agents", ".claude/hooks", "mcp.json", ".mcp.json"])
26003
- if (existsSync30(join37(source, entry)))
26098
+ if (existsSync29(join37(source, entry)))
26004
26099
  throw new Error(`OpenCode cannot preserve root ${entry} semantics: ${join37(source, entry)}`);
26005
26100
  for (const file of ["plugin.json", ".plugin/plugin.json", ".claude-plugin/plugin.json"]) {
26006
26101
  const path = join37(source, file);
26007
- if (!existsSync30(path))
26102
+ if (!existsSync29(path))
26008
26103
  continue;
26009
26104
  let manifest;
26010
26105
  try {
@@ -26021,7 +26116,7 @@ function assertSupportedRoot(source) {
26021
26116
  }
26022
26117
  function assertStore() {
26023
26118
  for (const path of [opencodeRoot(), join37(opencodeRoot(), ".plgnz"), opencodePackagesDir(), opencodeSkillsDir(), opencodeCommandsDir()])
26024
- if (existsSync30(path) && (!lstatSync22(path).isDirectory() || lstatSync22(path).isSymbolicLink()))
26119
+ if (existsSync29(path) && (!lstatSync23(path).isDirectory() || lstatSync23(path).isSymbolicLink()))
26025
26120
  throw new Error(`OpenCode managed path is unsafe: ${path}`);
26026
26121
  }
26027
26122
  function ensureStore2() {
@@ -26043,7 +26138,7 @@ var opencodeHookWriter = createNativeHookWriter({
26043
26138
 
26044
26139
  // src/hosts/grok-writer.ts
26045
26140
  import { spawnSync as spawnSync6 } from "node:child_process";
26046
- import { cpSync as cpSync13, existsSync as existsSync31, lstatSync as lstatSync23, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync14, readFileSync as readFileSync32, readdirSync as readdirSync22, readlinkSync as readlinkSync3, renameSync as renameSync12, rmSync as rmSync15, symlinkSync as symlinkSync2, writeFileSync as writeFileSync15 } from "node:fs";
26141
+ import { cpSync as cpSync13, existsSync as existsSync30, lstatSync as lstatSync24, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync14, readFileSync as readFileSync32, readdirSync as readdirSync22, readlinkSync as readlinkSync3, renameSync as renameSync12, rmSync as rmSync15, symlinkSync as symlinkSync2, writeFileSync as writeFileSync15 } from "node:fs";
26047
26142
  import { dirname as dirname17, join as join38, resolve as resolve24 } from "node:path";
26048
26143
  import { tmpdir as tmpdir11 } from "node:os";
26049
26144
  var stableId = (plugin) => plugin.marketplace === undefined ? plugin.name : `${plugin.name}@${plugin.marketplace}`;
@@ -26082,7 +26177,7 @@ var grokWriter = {
26082
26177
  const activation = join38(grokRoot(), "plugins", plugin.name);
26083
26178
  const existingNative = grok.listInstalled().find((candidate) => candidate.name === plugin.name)?.path;
26084
26179
  assertActivationLink(activation, existingNative);
26085
- const unchanged = lstatExists2(activation) && prior !== undefined && priorMarker?.fingerprint === plugin.contentFingerprint && priorMarker?.nativeFingerprint === nativeFingerprint && existsSync31(join38(prior, "plugins", plugin.name)) && fingerprintTree(join38(prior, "plugins", plugin.name)) === nativeFingerprint && current(id, prior, plugin.name, nativeFingerprint);
26180
+ const unchanged = lstatExists2(activation) && prior !== undefined && priorMarker?.fingerprint === plugin.contentFingerprint && priorMarker?.nativeFingerprint === nativeFingerprint && existsSync30(join38(prior, "plugins", plugin.name)) && fingerprintTree(join38(prior, "plugins", plugin.name)) === nativeFingerprint && current(id, prior, plugin.name, nativeFingerprint);
26086
26181
  if (opts?.dryRun)
26087
26182
  return unchanged ? "unchanged" : undefined;
26088
26183
  if (unchanged)
@@ -26228,7 +26323,7 @@ function basename6(path) {
26228
26323
  function assertActivationLink(link, nativePath) {
26229
26324
  if (!lstatExists2(link))
26230
26325
  return;
26231
- if (nativePath === undefined || !lstatSync23(link).isSymbolicLink() || canonical(nativePath) === undefined || canonical(link) !== canonical(nativePath)) {
26326
+ if (nativePath === undefined || !lstatSync24(link).isSymbolicLink() || canonical(nativePath) === undefined || canonical(link) !== canonical(nativePath)) {
26232
26327
  throw new Error(`Grok activation path is not the registered native plugin: ${link}`);
26233
26328
  }
26234
26329
  }
@@ -26294,7 +26389,7 @@ function validateGrokSource(dir) {
26294
26389
  }
26295
26390
  function projectGrokSource(dir) {
26296
26391
  const manifest = join38(dir, "plugin.json");
26297
- if (existsSync31(manifest)) {
26392
+ if (existsSync30(manifest)) {
26298
26393
  const doc = JSON.parse(readFileSync32(manifest, "utf8"));
26299
26394
  if (doc["permissions"] !== undefined)
26300
26395
  throw new Error(`Grok permission semantics are unverified: ${manifest}`);
@@ -26302,13 +26397,13 @@ function projectGrokSource(dir) {
26302
26397
  throw new Error(`Grok custom command path is unverified: ${manifest}`);
26303
26398
  }
26304
26399
  const skills = join38(dir, "skills");
26305
- if (existsSync31(skills))
26400
+ if (existsSync30(skills))
26306
26401
  for (const name of readdirSync22(skills)) {
26307
26402
  const skill = join38(skills, name);
26308
- if (!lstatSync23(skill).isDirectory())
26403
+ if (!lstatSync24(skill).isDirectory())
26309
26404
  continue;
26310
26405
  const file = join38(skill, "SKILL.md");
26311
- if (!existsSync31(file))
26406
+ if (!existsSync30(file))
26312
26407
  continue;
26313
26408
  const raw = readFileSync32(file, "utf8");
26314
26409
  const fm = openingFrontmatter3(raw, file);
@@ -26318,7 +26413,7 @@ function projectGrokSource(dir) {
26318
26413
  normalizeBooleanPolicy(fm, "user-invocable", "user_invocable", file);
26319
26414
  const sidecar = join38(skill, "agents", "openai.yaml");
26320
26415
  let sidecarManual;
26321
- if (existsSync31(sidecar)) {
26416
+ if (existsSync30(sidecar)) {
26322
26417
  const parsed = yamlParse(readFileSync32(sidecar, "utf8"));
26323
26418
  const policy = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed["policy"] : undefined;
26324
26419
  if (policy !== undefined) {
@@ -26340,19 +26435,19 @@ function projectGrokSource(dir) {
26340
26435
  const commands = join38(dir, "commands");
26341
26436
  const claudeCommands = join38(dir, ".claude", "commands");
26342
26437
  const seen = new Set;
26343
- for (const source of [existsSync31(commands) ? commands : claudeCommands]) {
26344
- if (!existsSync31(source))
26438
+ for (const source of [existsSync30(commands) ? commands : claudeCommands]) {
26439
+ if (!existsSync30(source))
26345
26440
  continue;
26346
26441
  for (const entry of readdirSync22(source)) {
26347
26442
  const path = join38(source, entry);
26348
- const stat = lstatSync23(path);
26443
+ const stat = lstatSync24(path);
26349
26444
  if (!stat.isFile() || !/\.(md|toml)$/u.test(entry))
26350
26445
  continue;
26351
26446
  const name = entry.replace(/\.(md|toml)$/u, "");
26352
26447
  if (seen.has(name))
26353
26448
  throw new Error(`duplicate Grok command ${name}`);
26354
26449
  seen.add(name);
26355
- if (existsSync31(join38(skills, name, "SKILL.md")))
26450
+ if (existsSync30(join38(skills, name, "SKILL.md")))
26356
26451
  throw new Error(`Grok command ${name} collides with a native skill`);
26357
26452
  const output = join38(commands, `${name}.md`);
26358
26453
  if (entry.endsWith(".md")) {
@@ -26403,11 +26498,11 @@ ${doc.prompt}`);
26403
26498
  }
26404
26499
  const legacyMcp = join38(dir, "mcp.json");
26405
26500
  const nativeMcp = join38(dir, ".mcp.json");
26406
- if (existsSync31(legacyMcp) && existsSync31(nativeMcp) && canonicalJson2(JSON.parse(readFileSync32(legacyMcp, "utf8")).mcpServers) !== canonicalJson2(JSON.parse(readFileSync32(nativeMcp, "utf8")).mcpServers))
26501
+ if (existsSync30(legacyMcp) && existsSync30(nativeMcp) && canonicalJson2(JSON.parse(readFileSync32(legacyMcp, "utf8")).mcpServers) !== canonicalJson2(JSON.parse(readFileSync32(nativeMcp, "utf8")).mcpServers))
26407
26502
  throw new Error(`conflicting Grok MCP declarations: ${legacyMcp} and ${nativeMcp}`);
26408
- if (existsSync31(legacyMcp) && !existsSync31(nativeMcp))
26503
+ if (existsSync30(legacyMcp) && !existsSync30(nativeMcp))
26409
26504
  cpSync13(legacyMcp, nativeMcp);
26410
- if (existsSync31(nativeMcp)) {
26505
+ if (existsSync30(nativeMcp)) {
26411
26506
  const value = JSON.parse(readFileSync32(nativeMcp, "utf8"));
26412
26507
  const servers = value?.["mcpServers"];
26413
26508
  if (!value || typeof value !== "object" || !servers || typeof servers !== "object" || Array.isArray(servers))
@@ -26457,28 +26552,28 @@ function legacyCandidate(plugin, adopt, prior) {
26457
26552
  throw new Error(`Grok ${plugin.name}: an existing native install is not plgnz-owned; refusing to replace it`);
26458
26553
  const installed = canonical(matches[0].path);
26459
26554
  const base = canonical(join38(grokRoot(), "installed-plugins"));
26460
- if (installed === undefined || base === undefined || !installed.startsWith(`${base}/`) || lstatSync23(matches[0].path).isSymbolicLink())
26555
+ if (installed === undefined || base === undefined || !installed.startsWith(`${base}/`) || lstatSync24(matches[0].path).isSymbolicLink())
26461
26556
  throw new Error(`Grok ${plugin.name}: legacy native path is unsafe`);
26462
26557
  const rows = repos().filter(([, repo]) => canonical(typeof repo.path === "string" ? repo.path : "") === installed);
26463
26558
  if (rows.length !== 1 || provenanceOf(rows[0][1]) !== null || namesOf(rows[0][1]).length !== 1 || namesOf(rows[0][1])[0] !== plugin.name)
26464
26559
  throw new Error(`Grok ${plugin.name}: legacy native identity is ambiguous`);
26465
26560
  const source = localSourceOf(rows[0][1]);
26466
- if (source === undefined || !existsSync31(source) || lstatSync23(source).isSymbolicLink())
26561
+ if (source === undefined || !existsSync30(source) || lstatSync24(source).isSymbolicLink())
26467
26562
  throw new Error(`Grok ${plugin.name}: legacy source is missing or unsafe`);
26468
26563
  const oldManifest = JSON.parse(readFileSync32(join38(installed, "plugin.json"), "utf8"));
26469
26564
  const newManifest = JSON.parse(readFileSync32(join38(plugin.dir, "plugin.json"), "utf8"));
26470
26565
  if (oldManifest.name !== plugin.name || newManifest.name !== plugin.name || oldManifest.version !== newManifest.version || fingerprintTree(source) !== fingerprintTree(installed))
26471
26566
  throw new Error(`Grok ${plugin.name}: legacy source, version, and native bytes must match before adoption`);
26472
26567
  const link = join38(grokRoot(), "plugins", plugin.name);
26473
- if (existsSync31(link) || lstatExists2(link)) {
26474
- if (!lstatSync23(link).isSymbolicLink() || canonical(resolve24(dirname17(link), readlinkSync3(link))) !== installed)
26568
+ if (existsSync30(link) || lstatExists2(link)) {
26569
+ if (!lstatSync24(link).isSymbolicLink() || canonical(resolve24(dirname17(link), readlinkSync3(link))) !== installed)
26475
26570
  throw new Error(`Grok ${plugin.name}: unmanaged same-name plugin link blocks adoption`);
26476
26571
  }
26477
26572
  return { source, fingerprint: fingerprintTree(installed), ...lstatExists2(link) ? { link } : {} };
26478
26573
  }
26479
26574
  function lstatExists2(path) {
26480
26575
  try {
26481
- lstatSync23(path);
26576
+ lstatSync24(path);
26482
26577
  return true;
26483
26578
  } catch {
26484
26579
  return false;
@@ -26505,7 +26600,7 @@ function assertOwnedRoot(root) {
26505
26600
  let current = base;
26506
26601
  for (const part of relative) {
26507
26602
  current = join38(current, part);
26508
- const stat = lstatSync23(current);
26603
+ const stat = lstatSync24(current);
26509
26604
  if (stat.isSymbolicLink() || !stat.isDirectory())
26510
26605
  throw new Error(`Grok marketplace root is not a safe owned directory: ${current}`);
26511
26606
  }
@@ -26697,7 +26792,7 @@ function configPriorRecord(attemptId, operationId) {
26697
26792
  }
26698
26793
  function discardStage(attemptId, operationId) {
26699
26794
  const record = stageRecord(attemptId, operationId);
26700
- if (existsSync31(record)) {
26795
+ if (existsSync30(record)) {
26701
26796
  const stage = readFileSync32(record, "utf8").trim();
26702
26797
  if (stage !== "")
26703
26798
  rmSync15(stage, { recursive: true, force: true });
@@ -26763,7 +26858,7 @@ function marketplacePathOf(repo) {
26763
26858
  }
26764
26859
  function savedRegistryRepo(directory) {
26765
26860
  const file = join38(directory, "registry-repo.json");
26766
- if (!existsSync31(file))
26861
+ if (!existsSync30(file))
26767
26862
  return { key: null, repo: null };
26768
26863
  const value = JSON.parse(readFileSync32(file, "utf8"));
26769
26864
  const key = typeof value.key === "string" ? value.key : null;
@@ -26833,7 +26928,7 @@ function captureHostSnapshot(directory, nativeId, packageName, attemptId, operat
26833
26928
  rmSync15(directory, { recursive: true, force: true });
26834
26929
  mkdirSync15(directory, { recursive: true });
26835
26930
  const priorConfig = configPriorRecord(attemptId, operationId);
26836
- if (existsSync31(priorConfig))
26931
+ if (existsSync30(priorConfig))
26837
26932
  cpSync13(priorConfig, join38(directory, "config-prior.json"));
26838
26933
  const plugin = grok.listInstalled().find((candidate) => candidate.id === nativeId);
26839
26934
  if (plugin?.path !== undefined) {
@@ -26851,7 +26946,7 @@ function captureHostSnapshot(directory, nativeId, packageName, attemptId, operat
26851
26946
  const matched = matchingRegistryRepo(nativeId, packageName);
26852
26947
  writeFileSync15(join38(directory, "registry-repo.json"), JSON.stringify(matched === undefined ? { key: null } : { key: matched[0], repo: matched[1] }));
26853
26948
  const link = join38(grokRoot(), "plugins", packageName);
26854
- if (lstatExists2(link) && lstatSync23(link).isSymbolicLink())
26949
+ if (lstatExists2(link) && lstatSync24(link).isSymbolicLink())
26855
26950
  writeFileSync15(join38(directory, "link.txt"), readlinkSync3(link));
26856
26951
  }
26857
26952
  function freshNativePaths(directory, marketplacePath) {
@@ -26870,17 +26965,17 @@ function freshNativePaths(directory, marketplacePath) {
26870
26965
  }
26871
26966
  function restoreActivationLink(directory, packageName) {
26872
26967
  const link = join38(grokRoot(), "plugins", packageName);
26873
- if (existsSync31(join38(directory, "link.txt"))) {
26968
+ if (existsSync30(join38(directory, "link.txt"))) {
26874
26969
  if (lstatExists2(link))
26875
26970
  rmSync15(link);
26876
26971
  symlinkSync2(readFileSync32(join38(directory, "link.txt"), "utf8"), link);
26877
26972
  return;
26878
26973
  }
26879
- if (lstatExists2(link) && lstatSync23(link).isSymbolicLink())
26974
+ if (lstatExists2(link) && lstatSync24(link).isSymbolicLink())
26880
26975
  rmSync15(link);
26881
26976
  }
26882
26977
  function restoreConfigFile(record) {
26883
- if (!existsSync31(record))
26978
+ if (!existsSync30(record))
26884
26979
  return;
26885
26980
  const value = JSON.parse(readFileSync32(record, "utf8"));
26886
26981
  const file = configFile3();
@@ -26898,8 +26993,8 @@ function restoreHostSnapshot(directory, scopeId, nativeId, packageName) {
26898
26993
  const finalPath = lifecycleMarketplace(scopeId, nativeId);
26899
26994
  const backupPath = join38(directory, "backup-path.txt");
26900
26995
  const nativePathFile = join38(directory, "native-path.txt");
26901
- const hadNative = existsSync31(nativePathFile);
26902
- const hadMarketplace = existsSync31(join38(directory, "marketplace"));
26996
+ const hadNative = existsSync30(nativePathFile);
26997
+ const hadMarketplace = existsSync30(join38(directory, "marketplace"));
26903
26998
  if (!hadNative)
26904
26999
  for (const native of freshNativePaths(directory, finalPath))
26905
27000
  rmSync15(native, { recursive: true, force: true });
@@ -26919,7 +27014,7 @@ function restoreHostSnapshot(directory, scopeId, nativeId, packageName) {
26919
27014
  restoreRegistryKey(directory, finalPath, packageName);
26920
27015
  restoreActivationLink(directory, packageName);
26921
27016
  restoreRecordedConfig(directory);
26922
- if (existsSync31(backupPath))
27017
+ if (existsSync30(backupPath))
26923
27018
  rmSync15(readFileSync32(backupPath, "utf8"), { recursive: true, force: true });
26924
27019
  if (hadNative) {
26925
27020
  run(["plugin", "update", packageName]);
@@ -26946,7 +27041,7 @@ ${tail}`;
26946
27041
  }
26947
27042
  function pinPluginAutoUpdate(attemptId, operationId) {
26948
27043
  const file = configFile3();
26949
- const present = existsSync31(file);
27044
+ const present = existsSync30(file);
26950
27045
  const current = present ? readFileSync32(file, "utf8") : "";
26951
27046
  const record = configPriorRecord(attemptId, operationId);
26952
27047
  mkdirSync15(dirname17(record), { recursive: true });
@@ -27048,7 +27143,7 @@ var grokLifecycleDefinition = {
27048
27143
  refreshStagedFingerprint(prepared.stagingRoot, nativeFingerprint);
27049
27144
  const finalPath = lifecycleMarketplace(prepared.handle.scopeId, prepared.handle.nativeId);
27050
27145
  const stagedRoot = dirname17(dirname17(prepared.stagingRoot));
27051
- const backup = existsSync31(finalPath) ? `${finalPath}.plgnz-backup-${prepared.handle.attemptId}` : undefined;
27146
+ const backup = existsSync30(finalPath) ? `${finalPath}.plgnz-backup-${prepared.handle.attemptId}` : undefined;
27052
27147
  if (backup !== undefined)
27053
27148
  renameSync12(finalPath, backup);
27054
27149
  renameSync12(stagedRoot, finalPath);
@@ -27136,25 +27231,25 @@ function createGrokLifecycleAdapter() {
27136
27231
 
27137
27232
  // src/hosts/zcode-cli-writer.ts
27138
27233
  init_zcode_cli_hooks();
27139
- import { chmodSync as chmodSync3, cpSync as cpSync14, existsSync as existsSync32, lstatSync as lstatSync25, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync15, readFileSync as readFileSync34, readdirSync as readdirSync24, realpathSync as realpathSync6, renameSync as renameSync13, rmSync as rmSync16, statSync as statSync13, writeFileSync as writeFileSync16 } from "node:fs";
27234
+ import { chmodSync as chmodSync3, cpSync as cpSync14, existsSync as existsSync31, lstatSync as lstatSync26, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync15, readFileSync as readFileSync34, readdirSync as readdirSync24, realpathSync as realpathSync6, renameSync as renameSync13, rmSync as rmSync16, statSync as statSync13, writeFileSync as writeFileSync16 } from "node:fs";
27140
27235
  import { basename as basename7, dirname as dirname19, join as join40, resolve as resolve26 } from "node:path";
27141
27236
  import { tmpdir as tmpdir12 } from "node:os";
27142
27237
 
27143
27238
  // src/hosts/zcode-cli-projection.ts
27144
- import { lstatSync as lstatSync24, readFileSync as readFileSync33, readdirSync as readdirSync23 } from "node:fs";
27239
+ import { lstatSync as lstatSync25, readFileSync as readFileSync33, readdirSync as readdirSync23 } from "node:fs";
27145
27240
  import { dirname as dirname18, join as join39, relative as relative8, resolve as resolve25 } from "node:path";
27146
27241
  var encode2 = (value) => new TextEncoder().encode(value);
27147
27242
  var decode = (value) => new TextDecoder().decode(value);
27148
27243
  function readZcodeProjectionTree(root) {
27149
27244
  const tree = new Map;
27150
27245
  const walk = (path, prefix) => {
27151
- const stat = lstatSync24(path);
27246
+ const stat = lstatSync25(path);
27152
27247
  if (stat.isSymbolicLink())
27153
27248
  throw new Error(`ZCode projection contains symlink: ${path}`);
27154
27249
  if (!stat.isDirectory())
27155
27250
  throw new Error(`ZCode projection root is not a directory: ${path}`);
27156
27251
  for (const name of readdirSync23(path).sort()) {
27157
- const file = join39(path, name), key = prefix === "" ? name : `${prefix}/${name}`, child = lstatSync24(file);
27252
+ const file = join39(path, name), key = prefix === "" ? name : `${prefix}/${name}`, child = lstatSync25(file);
27158
27253
  if (child.isSymbolicLink())
27159
27254
  throw new Error(`ZCode projection contains symlink: ${file}`);
27160
27255
  if (child.isDirectory()) {
@@ -27426,7 +27521,7 @@ function projectZcodePlugin(source, destination, resourceCopy, resourceLinkRoot,
27426
27521
  const target = resolve26(destination);
27427
27522
  const ownedResources = resolve26(resourceCopy);
27428
27523
  const links = resolve26(resourceLinkRoot);
27429
- if (!existsSync32(input) || !statSync13(input).isDirectory())
27524
+ if (!existsSync31(input) || !statSync13(input).isDirectory())
27430
27525
  throw new Error(`ZCode plugin source is not a directory: ${input}`);
27431
27526
  if (target === input || ownedResources === input || target.startsWith(`${input}/`) || ownedResources.startsWith(`${input}/`))
27432
27527
  throw new Error("ZCode projected outputs must not be inside the source");
@@ -27438,7 +27533,7 @@ function projectZcodePlugin(source, destination, resourceCopy, resourceLinkRoot,
27438
27533
  }
27439
27534
  for (const output of [target, ownedResources]) {
27440
27535
  try {
27441
- lstatSync25(output);
27536
+ lstatSync26(output);
27442
27537
  assertNoSymlinks7(output);
27443
27538
  } catch (error) {
27444
27539
  if (error.code !== "ENOENT")
@@ -27487,7 +27582,7 @@ function readJson3(file) {
27487
27582
  }
27488
27583
  }
27489
27584
  function commandNames(dir, prefix = "") {
27490
- if (!existsSync32(dir))
27585
+ if (!existsSync31(dir))
27491
27586
  return [];
27492
27587
  const out = [];
27493
27588
  for (const name of readdirSync24(dir)) {
@@ -27532,7 +27627,7 @@ function nativeForLogical(logicalId) {
27532
27627
  }
27533
27628
  function sameCandidate(prior, market, resources, resourceRoot, logical, native, source, fingerprint) {
27534
27629
  const marker = readZcodeOwnership(prior.installPath);
27535
- if (marker?.logicalId !== logical || marker.nativeId !== native || marker.source !== source || marker.fingerprint !== fingerprint || marker.resourcePath !== resourceRoot || !existsSync32(resourceRoot))
27630
+ if (marker?.logicalId !== logical || marker.nativeId !== native || marker.source !== source || marker.fingerprint !== fingerprint || marker.resourcePath !== resourceRoot || !existsSync31(resourceRoot))
27536
27631
  return false;
27537
27632
  try {
27538
27633
  return fingerprintTree(join40(market, "plugins", prior.name)) === fingerprintTree(prior.installPath) && fingerprintTree(resources) === fingerprintTree(resourceRoot);
@@ -27541,21 +27636,21 @@ function sameCandidate(prior, market, resources, resourceRoot, logical, native,
27541
27636
  }
27542
27637
  }
27543
27638
  function assertReplaceableOwnedRoots(market, resources, name, prior, logical, native, source) {
27544
- if (!existsSync32(market) && !existsSync32(resources))
27639
+ if (!existsSync31(market) && !existsSync31(resources))
27545
27640
  return;
27546
27641
  if (prior === undefined)
27547
- throw new Error(`Official ZCode owned path already exists without a proven native install: ${existsSync32(market) ? market : resources}`);
27642
+ throw new Error(`Official ZCode owned path already exists without a proven native install: ${existsSync31(market) ? market : resources}`);
27548
27643
  const priorRoot = zcodeSafeInstallRoot(prior.installPath);
27549
27644
  const marker = priorRoot === undefined ? null : readZcodeOwnership(priorRoot);
27550
27645
  if (marker?.logicalId !== logical || marker.nativeId !== native || marker.source !== source)
27551
27646
  throw new Error(`Official ZCode existing paths are not proven owned: ${native}`);
27552
- if (existsSync32(market)) {
27647
+ if (existsSync31(market)) {
27553
27648
  assertNoSymlinks7(market);
27554
27649
  const staged = readZcodeOwnership(join40(market, "plugins", name));
27555
27650
  if (staged?.logicalId !== logical || staged.nativeId !== native || staged.source !== source)
27556
27651
  throw new Error(`Official ZCode marketplace root is not proven owned: ${market}`);
27557
27652
  }
27558
- if (existsSync32(resources) && marker.resourcePath !== resources)
27653
+ if (existsSync31(resources) && marker.resourcePath !== resources)
27559
27654
  throw new Error(`Official ZCode resource root is not proven owned: ${resources}`);
27560
27655
  }
27561
27656
  function provePrior(prior, logical, native, source) {
@@ -27613,12 +27708,12 @@ function requireFingerprint(plugin) {
27613
27708
  return fp.toLowerCase();
27614
27709
  }
27615
27710
  function moveAside4(path) {
27616
- if (!existsSync32(path))
27711
+ if (!existsSync31(path))
27617
27712
  return { rollback: () => {}, commit: () => {} };
27618
27713
  const backup = `${path}.plgnz-backup-${Date.now()}`;
27619
27714
  renameSync13(path, backup);
27620
27715
  return { rollback: () => {
27621
- if (!existsSync32(path))
27716
+ if (!existsSync31(path))
27622
27717
  renameSync13(backup, path);
27623
27718
  }, commit: () => rmSync16(backup, { recursive: true, force: true }) };
27624
27719
  }
@@ -27628,7 +27723,7 @@ function assertName(value, label) {
27628
27723
  }
27629
27724
  function assertNoSymlinks7(root) {
27630
27725
  const visit = (path) => {
27631
- const stat = lstatSync25(path);
27726
+ const stat = lstatSync26(path);
27632
27727
  if (stat.isSymbolicLink())
27633
27728
  throw new Error(`ZCode source contains symlink: ${path}`);
27634
27729
  if (stat.isDirectory())
@@ -27745,7 +27840,7 @@ function capturedNativeRoot(reference, attemptId, operationId) {
27745
27840
  const root = dirname19(dirname19(dirname19(reference)));
27746
27841
  for (const ancestor of [join40(root, "plgnz-lifecycle"), join40(root, "plgnz-lifecycle", attemptId), reference]) {
27747
27842
  try {
27748
- if (lstatSync25(ancestor).isSymbolicLink())
27843
+ if (lstatSync26(ancestor).isSymbolicLink())
27749
27844
  throw new Error("ZCode captured snapshot ancestor was redirected");
27750
27845
  } catch (error) {
27751
27846
  if (!isObject4(error) || error["code"] !== "ENOENT")
@@ -27757,7 +27852,7 @@ function capturedNativeRoot(reference, attemptId, operationId) {
27757
27852
  return root;
27758
27853
  }
27759
27854
  function assertStageCleanupAuthority(stage, reference) {
27760
- if (lstatSync25(dirname19(stage)).isSymbolicLink() || lstatSync25(stage).isSymbolicLink())
27855
+ if (lstatSync26(dirname19(stage)).isSymbolicLink() || lstatSync26(stage).isSymbolicLink())
27761
27856
  throw new Error("ZCode cleanup stage is redirected");
27762
27857
  assertNoSymlinks7(stage);
27763
27858
  const artifact = reference.artifactId;
@@ -27796,7 +27891,7 @@ function assertStageCleanupAuthority(stage, reference) {
27796
27891
  }
27797
27892
  function readConfigObject() {
27798
27893
  const file = join40(zcodeCliConfigRoot(), "config.json");
27799
- if (!existsSync32(file))
27894
+ if (!existsSync31(file))
27800
27895
  return null;
27801
27896
  const value = JSON.parse(readFileSync34(file, "utf8"));
27802
27897
  if (!isObject4(value))
@@ -27814,7 +27909,7 @@ function optionValue(nativeId) {
27814
27909
  }
27815
27910
  function retainedState(nativeId) {
27816
27911
  const dataDir = zcodePluginDataDir(nativeId);
27817
- const pluginData = existsSync32(dataDir) && statSync13(dataDir).isDirectory() ? { state: "present", fingerprint: fingerprintTree(dataDir) } : { state: "absent", fingerprint: null };
27912
+ const pluginData = existsSync31(dataDir) && statSync13(dataDir).isDirectory() ? { state: "present", fingerprint: fingerprintTree(dataDir) } : { state: "absent", fingerprint: null };
27818
27913
  const options = optionValue(nativeId);
27819
27914
  const inactiveMetadata = options === undefined ? { state: "absent", fingerprint: null } : { state: "present", fingerprint: sha2562(canonicalJson3(options)) };
27820
27915
  return { pluginData, inactiveMetadata };
@@ -27906,9 +28001,9 @@ function resourceObservation2(root, digest) {
27906
28001
  const expected = join40(zcodeResourceRoot(), marketplaceName2(marker.nativeId), marker.fingerprint);
27907
28002
  if (canonicalExistingPath(resourcePath) !== canonicalExistingPath(expected))
27908
28003
  throw new Error("ZCode resource receipt names a foreign root");
27909
- if (!existsSync32(resourcePath))
28004
+ if (!existsSync31(resourcePath))
27910
28005
  return { roots, conforming: false };
27911
- if (lstatSync25(resourcePath).isSymbolicLink())
28006
+ if (lstatSync26(resourcePath).isSymbolicLink())
27912
28007
  throw new Error("ZCode resource receipt root is redirected");
27913
28008
  const resource = realpathSync6(resourcePath);
27914
28009
  const owned = realpathSync6(zcodeResourceRoot());
@@ -27922,7 +28017,7 @@ function retirementSnapshot(attemptId, operationId, nativeId) {
27922
28017
  const dir = join40(realpathSync6(zcodeCliRoot()), "plgnz-lifecycle", attemptId, operationId);
27923
28018
  if (canonicalExistingPath(dir) !== dir)
27924
28019
  throw new Error("ZCode rollback snapshot path is redirected");
27925
- if (existsSync32(dir)) {
28020
+ if (existsSync31(dir)) {
27926
28021
  if (!statSync13(dir).isDirectory())
27927
28022
  throw new Error(`ZCode rollback snapshot already exists and is not a directory: ${dir}`);
27928
28023
  return dir;
@@ -27934,17 +28029,17 @@ function retirementSnapshot(attemptId, operationId, nativeId) {
27934
28029
  cpSync14(root, join40(dir, "cache"), { recursive: true });
27935
28030
  writeFileSync16(join40(dir, "install-path.txt"), root ?? "");
27936
28031
  const registry = zcodeRegistryFile();
27937
- if (existsSync32(registry))
28032
+ if (existsSync31(registry))
27938
28033
  cpSync14(registry, join40(dir, "installed_plugins.json"));
27939
28034
  const config = join40(zcodeCliConfigRoot(), "config.json");
27940
- if (existsSync32(config))
28035
+ if (existsSync31(config))
27941
28036
  cpSync14(config, join40(dir, "config.json"));
27942
28037
  return dir;
27943
28038
  }
27944
28039
  function canonicalExistingPath(path) {
27945
28040
  const missing = [];
27946
28041
  let current = path;
27947
- while (!existsSync32(current)) {
28042
+ while (!existsSync31(current)) {
27948
28043
  const parent = dirname19(current);
27949
28044
  if (parent === current)
27950
28045
  throw new Error(`ZCode path does not exist: ${path}`);
@@ -27960,7 +28055,7 @@ function isCacheInstallPath(path) {
27960
28055
  }
27961
28056
  function removeRegistryPlugin(nativeId) {
27962
28057
  const file = zcodeRegistryFile();
27963
- if (!existsSync32(file))
28058
+ if (!existsSync31(file))
27964
28059
  return false;
27965
28060
  const value = JSON.parse(readFileSync34(file, "utf8"));
27966
28061
  if (!isObject4(value) || !Array.isArray(value["plugins"]))
@@ -27976,7 +28071,7 @@ function removeRegistryPlugin(nativeId) {
27976
28071
  }
27977
28072
  function removeEnabledFlag(nativeId) {
27978
28073
  const file = join40(zcodeCliConfigRoot(), "config.json");
27979
- if (!existsSync32(file))
28074
+ if (!existsSync31(file))
27980
28075
  return;
27981
28076
  const value = readConfigObject();
27982
28077
  if (value === null || !isObject4(value["plugins"]) || !isObject4(value["plugins"]["enabledPlugins"]))
@@ -27988,7 +28083,7 @@ function removeEnabledFlag(nativeId) {
27988
28083
  `);
27989
28084
  }
27990
28085
  function snapshotRegistryRow(file, nativeId) {
27991
- if (!existsSync32(file))
28086
+ if (!existsSync31(file))
27992
28087
  return;
27993
28088
  const value = JSON.parse(readFileSync34(file, "utf8"));
27994
28089
  if (!isObject4(value) || !Array.isArray(value["plugins"]))
@@ -28001,9 +28096,9 @@ function snapshotRegistryRow(file, nativeId) {
28001
28096
  function restoreRegistryPlugin(nativeId, snapshotFile) {
28002
28097
  const saved = snapshotRegistryRow(snapshotFile, nativeId);
28003
28098
  const file = zcodeRegistryFile();
28004
- if (!existsSync32(file) && saved === undefined)
28099
+ if (!existsSync31(file) && saved === undefined)
28005
28100
  return;
28006
- const live = existsSync32(file) ? JSON.parse(readFileSync34(file, "utf8")) : { version: 1, plugins: [] };
28101
+ const live = existsSync31(file) ? JSON.parse(readFileSync34(file, "utf8")) : { version: 1, plugins: [] };
28007
28102
  if (!isObject4(live) || !Array.isArray(live["plugins"]))
28008
28103
  throw new Error(`Official ZCode registry is unsupported: ${file}`);
28009
28104
  const plugins = live["plugins"].filter((row) => !isObject4(row) || row["id"] !== nativeId);
@@ -28023,8 +28118,8 @@ function configSection(config, key) {
28023
28118
  }
28024
28119
  function restorePluginConfig(nativeId, snapshotFile) {
28025
28120
  const file = join40(zcodeCliConfigRoot(), "config.json");
28026
- const snapshot = existsSync32(snapshotFile) ? readConfigObjectFrom(snapshotFile) : null;
28027
- const live = existsSync32(file) ? readConfigObject() : {};
28121
+ const snapshot = existsSync31(snapshotFile) ? readConfigObjectFrom(snapshotFile) : null;
28122
+ const live = existsSync31(file) ? readConfigObject() : {};
28028
28123
  if (live === null)
28029
28124
  throw new Error(`Official ZCode config is unsupported: ${file}`);
28030
28125
  const savedPlugins = snapshot !== null && isObject4(snapshot["plugins"]) ? snapshot["plugins"] : undefined;
@@ -28067,7 +28162,7 @@ function stageLayout(stagingRoot) {
28067
28162
  return { marketStage, resourcesStage: join40(dirname19(marketStage), "resources") };
28068
28163
  }
28069
28164
  function recordTree(dir, name, path) {
28070
- const existed = existsSync32(path);
28165
+ const existed = existsSync31(path);
28071
28166
  writeFileSync16(join40(dir, `${name}-path.txt`), path);
28072
28167
  writeFileSync16(join40(dir, `${name}-existed.txt`), existed ? "1" : "0");
28073
28168
  if (existed)
@@ -28078,7 +28173,7 @@ function knownMarketplacesFile() {
28078
28173
  }
28079
28174
  function readKnownMarketplaces() {
28080
28175
  const file = knownMarketplacesFile();
28081
- if (!existsSync32(file))
28176
+ if (!existsSync31(file))
28082
28177
  return {};
28083
28178
  const value = JSON.parse(readFileSync34(file, "utf8"));
28084
28179
  if (!isObject4(value))
@@ -28097,7 +28192,7 @@ function writeKnownMarketplaces(markets) {
28097
28192
  }
28098
28193
  function recordMarketplaceEntry(dir, market) {
28099
28194
  const flag = join40(dir, "marketplace-entry.txt");
28100
- if (existsSync32(flag))
28195
+ if (existsSync31(flag))
28101
28196
  return;
28102
28197
  const markets = readKnownMarketplaces();
28103
28198
  const present = Object.hasOwn(markets, market);
@@ -28107,7 +28202,7 @@ function recordMarketplaceEntry(dir, market) {
28107
28202
  }
28108
28203
  function restoreMarketplaceEntry(dir, market) {
28109
28204
  const flag = join40(dir, "marketplace-entry.txt");
28110
- if (!existsSync32(flag))
28205
+ if (!existsSync31(flag))
28111
28206
  return;
28112
28207
  const markets = readKnownMarketplaces();
28113
28208
  if (readFileSync34(flag, "utf8") !== "1") {
@@ -28118,7 +28213,7 @@ function restoreMarketplaceEntry(dir, market) {
28118
28213
  return;
28119
28214
  }
28120
28215
  const savedFile = join40(dir, "marketplace-entry.json");
28121
- if (!existsSync32(savedFile))
28216
+ if (!existsSync31(savedFile))
28122
28217
  throw new Error("ZCode rollback marketplace entry is missing");
28123
28218
  const saved = JSON.parse(readFileSync34(savedFile, "utf8"));
28124
28219
  markets[market] = saved;
@@ -28126,9 +28221,9 @@ function restoreMarketplaceEntry(dir, market) {
28126
28221
  }
28127
28222
  function activationSnapshot(attemptId, operationId, nativeId, marketplace, resources) {
28128
28223
  const dir = retirementSnapshot(attemptId, operationId, nativeId);
28129
- if (!existsSync32(join40(dir, "marketplace-path.txt")))
28224
+ if (!existsSync31(join40(dir, "marketplace-path.txt")))
28130
28225
  recordTree(dir, "marketplace", marketplace);
28131
- if (!existsSync32(join40(dir, "resources-path.txt")))
28226
+ if (!existsSync31(join40(dir, "resources-path.txt")))
28132
28227
  recordTree(dir, "resources", resources);
28133
28228
  recordMarketplaceEntry(dir, marketplaceName2(nativeId));
28134
28229
  return dir;
@@ -28136,7 +28231,7 @@ function activationSnapshot(attemptId, operationId, nativeId, marketplace, resou
28136
28231
  function restoreRecordedTree(dir, name, ownedRoot) {
28137
28232
  const pathFile = join40(dir, `${name}-path.txt`);
28138
28233
  const existedFile = join40(dir, `${name}-existed.txt`);
28139
- if (!existsSync32(pathFile) || !existsSync32(existedFile))
28234
+ if (!existsSync31(pathFile) || !existsSync31(existedFile))
28140
28235
  return;
28141
28236
  const path = readFileSync34(pathFile, "utf8");
28142
28237
  const existed = readFileSync34(existedFile, "utf8") === "1";
@@ -28147,9 +28242,9 @@ function restoreRecordedTree(dir, name, ownedRoot) {
28147
28242
  if (!target.startsWith(`${owned}/`))
28148
28243
  throw new Error(`ZCode rollback ${name} path is outside its root`);
28149
28244
  const copy = join40(dir, name);
28150
- if (existed && !existsSync32(copy))
28245
+ if (existed && !existsSync31(copy))
28151
28246
  throw new Error(`ZCode rollback ${name} copy is missing`);
28152
- if (!existed && existsSync32(copy))
28247
+ if (!existed && existsSync31(copy))
28153
28248
  throw new Error(`ZCode rollback ${name} copy has no path`);
28154
28249
  rmSync16(target, { recursive: true, force: true });
28155
28250
  if (!existed)
@@ -28219,7 +28314,7 @@ var zcodeCliLifecycleDefinition = {
28219
28314
  const resourceRoot = join40(realpathSync6(zcodeCliRoot()), "plgnz-resources", market, snapshot.packageFingerprint);
28220
28315
  const stageParent = join40(zcodeCliRoot(), ".plgnz-zcode-stage");
28221
28316
  mkdirSync16(stageParent, { recursive: true });
28222
- if (lstatSync25(stageParent).isSymbolicLink())
28317
+ if (lstatSync26(stageParent).isSymbolicLink())
28223
28318
  throw new Error("ZCode staging parent is redirected");
28224
28319
  const stage = activationStage(request.selection.attemptId, request.selection.operationId);
28225
28320
  mkdirSync16(stage);
@@ -28311,7 +28406,7 @@ var zcodeCliLifecycleDefinition = {
28311
28406
  const resourceRoot = marker.resourcePath;
28312
28407
  const prior = nativeById(nativeId);
28313
28408
  const priorRoot = prior === undefined ? undefined : zcodeSafeInstallRoot(prior.installPath);
28314
- const unchanged = prior !== undefined && priorRoot !== undefined && prior.version === nativeVersion && readZcodeEnabledPluginIds().get(nativeId) === true && fingerprintTree(priorRoot) === fingerprintTree(prepared.stagingRoot) && existsSync32(resourceRoot) && fingerprintTree(resourceRoot) === fingerprintTree(resourcesStage);
28409
+ const unchanged = prior !== undefined && priorRoot !== undefined && prior.version === nativeVersion && readZcodeEnabledPluginIds().get(nativeId) === true && fingerprintTree(priorRoot) === fingerprintTree(prepared.stagingRoot) && existsSync31(resourceRoot) && fingerprintTree(resourceRoot) === fingerprintTree(resourcesStage);
28315
28410
  if (unchanged)
28316
28411
  return { receiptId: `apply:${prepared.handle.attemptId}:${prepared.handle.operationId}`, changed: false };
28317
28412
  const marketBackup = moveAside4(marketRoot);
@@ -28364,11 +28459,11 @@ var zcodeCliLifecycleDefinition = {
28364
28459
  rollback: async (handle) => {
28365
28460
  capturedNativeRoot(handle.rollbackReference, handle.attemptId, handle.operationId);
28366
28461
  const dir = handle.rollbackReference;
28367
- if (!existsSync32(dir) || !statSync13(dir).isDirectory())
28462
+ if (!existsSync31(dir) || !statSync13(dir).isDirectory())
28368
28463
  throw new Error("ZCode rollback snapshot is missing");
28369
- const installPath = existsSync32(join40(dir, "install-path.txt")) ? readFileSync34(join40(dir, "install-path.txt"), "utf8") : "";
28464
+ const installPath = existsSync31(join40(dir, "install-path.txt")) ? readFileSync34(join40(dir, "install-path.txt"), "utf8") : "";
28370
28465
  const cache = join40(dir, "cache");
28371
- const cachePresent = existsSync32(cache);
28466
+ const cachePresent = existsSync31(cache);
28372
28467
  if (installPath.length > 0 && !cachePresent)
28373
28468
  throw new Error("ZCode rollback cache copy is missing");
28374
28469
  if (installPath.length === 0 && cachePresent)
@@ -28406,7 +28501,7 @@ var zcodeCliLifecycleDefinition = {
28406
28501
  const parent = join40(realpathSync6(zcodeCliRoot()), "plgnz-lifecycle");
28407
28502
  for (const candidate of [parent, join40(parent, reference.attemptId), join40(parent, reference.attemptId, reference.operationId)]) {
28408
28503
  try {
28409
- const stat = lstatSync25(candidate);
28504
+ const stat = lstatSync26(candidate);
28410
28505
  if (stat.isSymbolicLink() || candidate === join40(parent, reference.attemptId, reference.operationId))
28411
28506
  throw new Error("ZCode pre-seal cleanup has no captured snapshot authority");
28412
28507
  } catch (error) {
@@ -28416,7 +28511,7 @@ var zcodeCliLifecycleDefinition = {
28416
28511
  }
28417
28512
  }
28418
28513
  try {
28419
- if (lstatSync25(dirname19(stage)).isSymbolicLink())
28514
+ if (lstatSync26(dirname19(stage)).isSymbolicLink())
28420
28515
  throw new Error("ZCode cleanup staging parent is redirected");
28421
28516
  } catch (error) {
28422
28517
  if (!isObject4(error) || error["code"] !== "ENOENT")
@@ -28424,7 +28519,7 @@ var zcodeCliLifecycleDefinition = {
28424
28519
  }
28425
28520
  let stagePresent = true;
28426
28521
  try {
28427
- lstatSync25(stage);
28522
+ lstatSync26(stage);
28428
28523
  } catch (error) {
28429
28524
  if (!isObject4(error) || error["code"] !== "ENOENT")
28430
28525
  throw error;
@@ -28442,7 +28537,7 @@ var zcodeCliLifecycleDefinition = {
28442
28537
  var zcodeCliLifecycle = createLifecycleHostAdapter(zcodeCliLifecycleDefinition);
28443
28538
 
28444
28539
  // src/hosts/hermes-writer.ts
28445
- import { chmodSync as chmodSync4, cpSync as cpSync15, existsSync as existsSync33, lstatSync as lstatSync26, mkdirSync as mkdirSync17, mkdtempSync as mkdtempSync16, readFileSync as readFileSync35, readdirSync as readdirSync25, realpathSync as realpathSync7, renameSync as renameSync14, rmSync as rmSync17, statSync as statSync14, writeFileSync as writeFileSync17 } from "node:fs";
28540
+ import { chmodSync as chmodSync4, cpSync as cpSync15, existsSync as existsSync32, lstatSync as lstatSync27, mkdirSync as mkdirSync17, mkdtempSync as mkdtempSync16, readFileSync as readFileSync35, readdirSync as readdirSync25, realpathSync as realpathSync7, renameSync as renameSync14, rmSync as rmSync17, statSync as statSync14, writeFileSync as writeFileSync17 } from "node:fs";
28446
28541
  import { basename as basename8, dirname as dirname20, isAbsolute as isAbsolute12, join as join41, resolve as resolve27 } from "node:path";
28447
28542
  import { tmpdir as tmpdir13 } from "node:os";
28448
28543
 
@@ -28714,12 +28809,12 @@ var hermesWriter = {
28714
28809
  assertReplaceable(target, packageStage, id, ownershipId, resolved.sourceUri, opts?.adoptExisting === true, validatePackage);
28715
28810
  if (hasCompanion)
28716
28811
  assertReplaceable(companion, companionStage, companionId, ownershipId, resolved.sourceUri, opts?.adoptExisting === true, validateCompanion);
28717
- else if (existsSync33(companion))
28812
+ else if (existsSync32(companion))
28718
28813
  assertReplaceable(companion, undefined, companionId, ownershipId, resolved.sourceUri, opts?.adoptExisting === true, validateCompanion);
28719
28814
  const primaryMarker = readOwnership5(target);
28720
28815
  const companionMarker = readOwnership5(companion);
28721
28816
  const unchangedPrimary = primaryMarker?.pluginId === ownershipId && primaryMarker.fingerprint === ownership.fingerprint && sameTree9(packageStage, target);
28722
- const unchangedCompanion = hasCompanion ? companionMarker?.pluginId === ownershipId && companionMarker.fingerprint === ownership.fingerprint && sameTree9(companionStage, companion) : !existsSync33(companion);
28817
+ const unchangedCompanion = hasCompanion ? companionMarker?.pluginId === ownershipId && companionMarker.fingerprint === ownership.fingerprint && sameTree9(companionStage, companion) : !existsSync32(companion);
28723
28818
  if (opts?.dryRun)
28724
28819
  return unchangedPrimary && unchangedCompanion ? "unchanged" : undefined;
28725
28820
  if (unchangedPrimary && unchangedCompanion) {
@@ -28731,7 +28826,7 @@ var hermesWriter = {
28731
28826
  changes.push(replaceTarget(packageStage, target, root));
28732
28827
  if (hasCompanion)
28733
28828
  changes.push(replaceTarget(companionStage, companion, root));
28734
- else if (existsSync33(companion))
28829
+ else if (existsSync32(companion))
28735
28830
  changes.push(removeTarget(companion, root));
28736
28831
  updatePluginConfig(effectiveConfigPath(), [id, ...hasCompanion ? [companionId] : []], hasCompanion ? [] : [companionId]);
28737
28832
  for (const change of changes)
@@ -28763,14 +28858,14 @@ var hermesWriter = {
28763
28858
  return;
28764
28859
  const changes = [];
28765
28860
  try {
28766
- if (existsSync33(target))
28861
+ if (existsSync32(target))
28767
28862
  changes.push(removeTarget(target, root));
28768
28863
  const companionMarker = readOwnership5(companion);
28769
28864
  const disable = [nativeId];
28770
28865
  if (companionMarker !== null && companionMarker.pluginId === marker.pluginId && companionMarker.source === marker.source && companionMarker.fingerprint === marker.fingerprint) {
28771
28866
  changes.push(removeTarget(companion, root));
28772
28867
  disable.push(companionId);
28773
- } else if (!existsSync33(companion))
28868
+ } else if (!existsSync32(companion))
28774
28869
  disable.push(companionId);
28775
28870
  updatePluginConfig(effectiveConfigPath(), [], disable);
28776
28871
  for (const change of changes)
@@ -28783,7 +28878,7 @@ var hermesWriter = {
28783
28878
  }
28784
28879
  };
28785
28880
  function assertReplaceable(target, stage, expected, ownershipId, source, adopt, validate) {
28786
- if (!existsSync33(target))
28881
+ if (!existsSync32(target))
28787
28882
  return;
28788
28883
  const marker = readOwnership5(target);
28789
28884
  if (marker !== null) {
@@ -28801,7 +28896,7 @@ function assertReplaceable(target, stage, expected, ownershipId, source, adopt,
28801
28896
  function validatePackage(root, expected) {
28802
28897
  assertTree3(root);
28803
28898
  const manifest = join41(root, "plugin.json");
28804
- if (!existsSync33(manifest))
28899
+ if (!existsSync32(manifest))
28805
28900
  throw new Error("Hermes stage has no Agent Plugins manifest");
28806
28901
  let value;
28807
28902
  try {
@@ -28817,7 +28912,7 @@ function validatePackage(root, expected) {
28817
28912
  function validateCompanion(root, expected) {
28818
28913
  assertTree3(root);
28819
28914
  const manifest = join41(root, "plugin.yaml");
28820
- if (!existsSync33(manifest) || !existsSync33(join41(root, "__init__.py")))
28915
+ if (!existsSync32(manifest) || !existsSync32(join41(root, "__init__.py")))
28821
28916
  throw new Error(`Hermes native companion is incomplete: ${root}`);
28822
28917
  const value = yamlParse(readFileSync35(manifest, "utf8"));
28823
28918
  if (!value || typeof value !== "object" || Array.isArray(value) || value.name !== expected)
@@ -28825,7 +28920,7 @@ function validateCompanion(root, expected) {
28825
28920
  }
28826
28921
  function readOwnership5(target) {
28827
28922
  const file = join41(target, MARKER11);
28828
- if (!existsSync33(file))
28923
+ if (!existsSync32(file))
28829
28924
  return null;
28830
28925
  try {
28831
28926
  const value = JSON.parse(readFileSync35(file, "utf8"));
@@ -28840,7 +28935,7 @@ function readOwnership5(target) {
28840
28935
  }
28841
28936
  }
28842
28937
  function replaceTarget(stage, target, root) {
28843
- if (!existsSync33(target)) {
28938
+ if (!existsSync32(target)) {
28844
28939
  renameSync14(stage, target);
28845
28940
  return { commit: () => {}, rollback: () => rmSync17(target, { recursive: true, force: true }) };
28846
28941
  }
@@ -28865,14 +28960,14 @@ function removeTarget(target, root) {
28865
28960
  const backup = join41(backupRoot, "previous");
28866
28961
  renameSync14(target, backup);
28867
28962
  return { commit: () => rmSync17(backupRoot, { recursive: true, force: true }), rollback: () => {
28868
- if (!existsSync33(target))
28963
+ if (!existsSync32(target))
28869
28964
  renameSync14(backup, target);
28870
28965
  rmSync17(backupRoot, { recursive: true, force: true });
28871
28966
  } };
28872
28967
  }
28873
28968
  function updatePluginConfig(configured, enable, disable) {
28874
- const actual = existsSync33(configured) && lstatSync26(configured).isSymbolicLink() ? realpathSync7(configured) : configured;
28875
- const exists = existsSync33(actual);
28969
+ const actual = existsSync32(configured) && lstatSync27(configured).isSymbolicLink() ? realpathSync7(configured) : configured;
28970
+ const exists = existsSync32(actual);
28876
28971
  const original = exists ? readFileSync35(actual, "utf8") : "";
28877
28972
  let parsed = {};
28878
28973
  if (original.trim() !== "") {
@@ -28930,7 +29025,7 @@ function effectiveConfigPath() {
28930
29025
  const configured = resolve27(hermesConfigPath());
28931
29026
  if (native === configured)
28932
29027
  return configured;
28933
- if (!existsSync33(native) || !existsSync33(configured))
29028
+ if (!existsSync32(native) || !existsSync32(configured))
28934
29029
  throw new Error(`Hermes only reads ${native}; configured path ${configured} must already resolve to the same file`);
28935
29030
  const nativeReal = realpathSync7(native);
28936
29031
  const configuredReal = realpathSync7(configured);
@@ -28939,7 +29034,7 @@ function effectiveConfigPath() {
28939
29034
  throw new Error(`Hermes only reads ${native}; configured path ${configured} is a different file`);
28940
29035
  }
28941
29036
  function sameTree9(left, right) {
28942
- if (!existsSync33(right))
29037
+ if (!existsSync32(right))
28943
29038
  return false;
28944
29039
  const list = (root) => {
28945
29040
  const out = [];
@@ -28947,7 +29042,7 @@ function sameTree9(left, right) {
28947
29042
  for (const name of readdirSync25(dir).sort()) {
28948
29043
  if (name === MARKER11)
28949
29044
  continue;
28950
- const path = join41(dir, name), relative = prefix ? `${prefix}/${name}` : name, stat = lstatSync26(path);
29045
+ const path = join41(dir, name), relative = prefix ? `${prefix}/${name}` : name, stat = lstatSync27(path);
28951
29046
  if (stat.isSymbolicLink())
28952
29047
  throw new Error(`Hermes plugin contains symlink: ${path}`);
28953
29048
  if (stat.isDirectory())
@@ -28967,13 +29062,13 @@ function readBytes2(path) {
28967
29062
  return readFileSync35(path);
28968
29063
  }
28969
29064
  function assertTree3(root) {
28970
- const stat = lstatSync26(root);
29065
+ const stat = lstatSync27(root);
28971
29066
  if (stat.isSymbolicLink() || !stat.isDirectory())
28972
29067
  throw new Error(`Hermes plugin source is not a real directory: ${root}`);
28973
29068
  for (const name of readdirSync25(root)) {
28974
29069
  if (name === MARKER11)
28975
29070
  continue;
28976
- const path = join41(root, name), entry = lstatSync26(path);
29071
+ const path = join41(root, name), entry = lstatSync27(path);
28977
29072
  if (entry.isSymbolicLink())
28978
29073
  throw new Error(`Hermes plugin contains symlink: ${path}`);
28979
29074
  if (entry.isDirectory())
@@ -28988,15 +29083,15 @@ function assertManagedPath5(root, target) {
28988
29083
  throw new Error(`Hermes managed path escapes its store: ${target}`);
28989
29084
  let current = base;
28990
29085
  for (const part of selected.slice(base.length).split("/").filter(Boolean)) {
28991
- if (existsSync33(current)) {
28992
- const stat = lstatSync26(current);
29086
+ if (existsSync32(current)) {
29087
+ const stat = lstatSync27(current);
28993
29088
  if (stat.isSymbolicLink() || !stat.isDirectory())
28994
29089
  throw new Error(`Hermes managed path component is unsafe: ${current}`);
28995
29090
  }
28996
29091
  current = join41(current, part);
28997
29092
  }
28998
- if (existsSync33(current)) {
28999
- const stat = lstatSync26(current);
29093
+ if (existsSync32(current)) {
29094
+ const stat = lstatSync27(current);
29000
29095
  if (stat.isSymbolicLink() || !stat.isDirectory())
29001
29096
  throw new Error(`Hermes managed path component is unsafe: ${current}`);
29002
29097
  }
@@ -29144,7 +29239,7 @@ function verifiedSourceImportClosure(root) {
29144
29239
  if (entry.startsWith(".") || entry === "__pycache__" || entry === "node_modules")
29145
29240
  continue;
29146
29241
  const path = join41(directory, entry);
29147
- const stat = lstatSync26(path);
29242
+ const stat = lstatSync27(path);
29148
29243
  if (stat.isSymbolicLink()) {
29149
29244
  if (entry.endsWith(".py") || statSync14(path).isDirectory())
29150
29245
  return false;
@@ -29156,7 +29251,7 @@ function verifiedSourceImportClosure(root) {
29156
29251
  return visit(root, true);
29157
29252
  }
29158
29253
  function hermesExecutableSource(binary, depth = 0) {
29159
- if (depth > 4 || !isAbsolute12(binary) || !existsSync33(binary))
29254
+ if (depth > 4 || !isAbsolute12(binary) || !existsSync32(binary))
29160
29255
  return;
29161
29256
  const executable = realpathSync7(binary);
29162
29257
  if (!statSync14(executable).isFile())
@@ -29168,7 +29263,7 @@ exec `)) {
29168
29263
  exec `.length));
29169
29264
  if (args?.length === 2 && args[1] === "$@")
29170
29265
  return hermesExecutableSource(args[0], depth + 1);
29171
- if (args?.length !== 5 || args[1] !== "-I" || args[2] !== "-c" || args[4] !== "$@" || !isAbsolute12(args[0]) || !/^python(?:\d+(?:\.\d+)*)?$/u.test(basename8(args[0])) || !existsSync33(args[0]))
29266
+ if (args?.length !== 5 || args[1] !== "-I" || args[2] !== "-c" || args[4] !== "$@" || !isAbsolute12(args[0]) || !/^python(?:\d+(?:\.\d+)*)?$/u.test(basename8(args[0])) || !existsSync32(args[0]))
29172
29267
  return;
29173
29268
  const code = args[3];
29174
29269
  if (!code.startsWith(`import os, re, sys
@@ -29180,26 +29275,26 @@ exec `.length));
29180
29275
  const root = literalPythonPath(bindings[0][1]);
29181
29276
  if (root === undefined || code.replaceAll(bindings[0][1], "'/__PLUGNZ_HERMES_ROOT__'") !== hermesNativeBootstrap)
29182
29277
  return;
29183
- return root !== undefined && isAbsolute12(root) && existsSync33(join41(root, "hermes_cli", "main.py")) && realpathSync7(join41(root, "hermes_cli", "main.py")).startsWith(`${realpathSync7(root)}/`) && verifiedSourceImportClosure(realpathSync7(root)) ? realpathSync7(root) : undefined;
29278
+ return root !== undefined && isAbsolute12(root) && existsSync32(join41(root, "hermes_cli", "main.py")) && realpathSync7(join41(root, "hermes_cli", "main.py")).startsWith(`${realpathSync7(root)}/`) && verifiedSourceImportClosure(realpathSync7(root)) ? realpathSync7(root) : undefined;
29184
29279
  }
29185
29280
  const interpreter = /^#!([^\n]+)\n/u.exec(text)?.[1];
29186
- if (interpreter === undefined || !isAbsolute12(interpreter) || !existsSync33(interpreter) || !/^python(?:\d+(?:\.\d+)*)?$/u.test(basename8(interpreter)) || text.slice(text.indexOf(`
29281
+ if (interpreter === undefined || !isAbsolute12(interpreter) || !existsSync32(interpreter) || !/^python(?:\d+(?:\.\d+)*)?$/u.test(basename8(interpreter)) || text.slice(text.indexOf(`
29187
29282
  `) + 1) !== hermesUvConsoleBody)
29188
29283
  return;
29189
29284
  const venv = dirname20(dirname20(executable));
29190
- if (dirname20(interpreter) !== join41(venv, "bin") || !existsSync33(join41(venv, "pyvenv.cfg")))
29285
+ if (dirname20(interpreter) !== join41(venv, "bin") || !existsSync32(join41(venv, "pyvenv.cfg")))
29191
29286
  return;
29192
- if (existsSync33(join41(venv, "bin", "pyvenv.cfg")) || !isolatedVenvConfig(readFileSync35(join41(venv, "pyvenv.cfg"), "utf8")) || process.env["PYTHONHOME"] || process.env["PYTHONPATH"])
29287
+ if (existsSync32(join41(venv, "bin", "pyvenv.cfg")) || !isolatedVenvConfig(readFileSync35(join41(venv, "pyvenv.cfg"), "utf8")) || process.env["PYTHONHOME"] || process.env["PYTHONPATH"])
29193
29288
  return;
29194
29289
  if (hasImportShadow(join41(venv, "bin"), ["hermes_cli", "sitecustomize", "usercustomize", "_virtualenv"]))
29195
29290
  return;
29196
29291
  const lib = join41(venv, "lib");
29197
- if (!existsSync33(lib))
29292
+ if (!existsSync32(lib))
29198
29293
  return;
29199
29294
  const roots = [];
29200
29295
  for (const python of readdirSync25(lib).filter((name) => /^python\d+\.\d+$/u.test(name))) {
29201
29296
  const packages = join41(lib, python, "site-packages");
29202
- if (!existsSync33(packages))
29297
+ if (!existsSync32(packages))
29203
29298
  continue;
29204
29299
  if (hasImportShadow(packages, ["hermes_cli", "sitecustomize", "usercustomize", "_virtualenv"], ["_virtualenv.py"]))
29205
29300
  return;
@@ -29207,13 +29302,13 @@ exec `.length));
29207
29302
  const distribution = join41(packages, name);
29208
29303
  const metadata = join41(distribution, "direct_url.json");
29209
29304
  const entry = join41(distribution, "entry_points.txt");
29210
- if (!existsSync33(metadata) || !existsSync33(entry) || !/^hermes\s*=\s*hermes_cli\.main:main$/mu.test(readFileSync35(entry, "utf8")))
29305
+ if (!existsSync32(metadata) || !existsSync32(entry) || !/^hermes\s*=\s*hermes_cli\.main:main$/mu.test(readFileSync35(entry, "utf8")))
29211
29306
  continue;
29212
29307
  const direct = JSON.parse(readFileSync35(metadata, "utf8"));
29213
29308
  if (typeof direct !== "object" || direct === null || !("url" in direct) || typeof direct.url !== "string" || !("dir_info" in direct) || typeof direct.dir_info !== "object" || direct.dir_info === null || !("editable" in direct.dir_info) || direct.dir_info.editable !== true || !direct.url.startsWith("file:///"))
29214
29309
  continue;
29215
29310
  const root = decodeURIComponent(direct.url.slice("file://".length));
29216
- if (!isAbsolute12(root) || !existsSync33(join41(root, "hermes_cli", "main.py")))
29311
+ if (!isAbsolute12(root) || !existsSync32(join41(root, "hermes_cli", "main.py")))
29217
29312
  continue;
29218
29313
  const sourceModules = [
29219
29314
  "hermes_cli",
@@ -29221,7 +29316,7 @@ exec `.length));
29221
29316
  "hermes_constants",
29222
29317
  "pm",
29223
29318
  ...readdirSync25(root).filter((name) => name.endsWith(".py")).map((name) => name.slice(0, -3)),
29224
- ...readdirSync25(root).filter((name) => existsSync33(join41(root, name, "__init__.py")))
29319
+ ...readdirSync25(root).filter((name) => existsSync32(join41(root, name, "__init__.py")))
29225
29320
  ];
29226
29321
  if (hasImportShadow(packages, sourceModules) || hasImportShadow(join41(venv, "bin"), sourceModules))
29227
29322
  return;
@@ -29236,11 +29331,11 @@ exec `.length));
29236
29331
  const pth = readFileSync35(join41(packages, pthName), "utf8").trim();
29237
29332
  if (pthName === `_virtualenv.pth` && pth === "import _virtualenv") {
29238
29333
  const helper = join41(packages, "_virtualenv.py");
29239
- if (!existsSync33(helper) || new CryptoHasher("sha256").update(readFileSync35(helper, "utf8")).digest("hex") !== "cfb3db86aaa53bb62b5ff764970bec2d71c9228590a0ebec57f6ec926cc0bf1a")
29334
+ if (!existsSync32(helper) || new CryptoHasher("sha256").update(readFileSync35(helper, "utf8")).digest("hex") !== "cfb3db86aaa53bb62b5ff764970bec2d71c9228590a0ebec57f6ec926cc0bf1a")
29240
29335
  return;
29241
29336
  } else if (pthName === `__editable__.hermes_agent-${version}.pth` && pth === root)
29242
29337
  binding = true;
29243
- else if (pthName === `__editable__.hermes_agent-${version}.pth` && pth === `import ${finder}; ${finder}.install()` && existsSync33(join41(packages, `${finder}.py`)) && verifiedEditableFinder(readFileSync35(join41(packages, `${finder}.py`), "utf8"), root, version))
29338
+ else if (pthName === `__editable__.hermes_agent-${version}.pth` && pth === `import ${finder}; ${finder}.install()` && existsSync32(join41(packages, `${finder}.py`)) && verifiedEditableFinder(readFileSync35(join41(packages, `${finder}.py`), "utf8"), root, version))
29244
29339
  binding = true;
29245
29340
  else
29246
29341
  return;
@@ -29253,7 +29348,7 @@ exec `.length));
29253
29348
  }
29254
29349
  function observeHermesRevision() {
29255
29350
  const binary = process.env["OPEN_PLUGIN_HERMES_BIN"] ?? which("hermes");
29256
- if (!binary || !existsSync33(binary))
29351
+ if (!binary || !existsSync32(binary))
29257
29352
  return { kind: "unknown", diagnostic: "Select an existing Hermes launcher with OPEN_PLUGIN_HERMES_BIN; a profile config does not identify its runtime" };
29258
29353
  try {
29259
29354
  const root = hermesExecutableSource(binary);
@@ -29327,14 +29422,14 @@ function resolveInstanceConfig(root, configPath) {
29327
29422
  const configured = resolve27(configPath);
29328
29423
  if (native === configured)
29329
29424
  return configured;
29330
- if (!existsSync33(native) || !existsSync33(configured))
29425
+ if (!existsSync32(native) || !existsSync32(configured))
29331
29426
  throw new Error(`Hermes only reads ${native}; configured path ${configured} must already resolve to the same file`);
29332
29427
  if (realpathSync7(native) === realpathSync7(configured))
29333
29428
  return configured;
29334
29429
  throw new Error(`Hermes only reads ${native}; configured path ${configured} is a different file`);
29335
29430
  }
29336
29431
  function actualConfig(configPath) {
29337
- return existsSync33(configPath) && lstatSync26(configPath).isSymbolicLink() ? realpathSync7(configPath) : configPath;
29432
+ return existsSync32(configPath) && lstatSync27(configPath).isSymbolicLink() ? realpathSync7(configPath) : configPath;
29338
29433
  }
29339
29434
  function workDir(store, attemptId, operationId) {
29340
29435
  return join41(store.root, ".plgnz-lifecycle", encodeURIComponent(attemptId), encodeURIComponent(operationId));
@@ -29403,7 +29498,7 @@ function sameLifecycleOwner(marker, claim) {
29403
29498
  return installed !== null && installed.pluginId === claim.pluginId && installed.scopeId === claim.scopeId && installed.sourceType === claim.sourceType && installed.locator === claim.locator;
29404
29499
  }
29405
29500
  function assertLifecycleOwned(target, claim, handle) {
29406
- if (!existsSync33(target))
29501
+ if (!existsSync32(target))
29407
29502
  return;
29408
29503
  const marker = readMarker(target);
29409
29504
  if (marker === null)
@@ -29433,7 +29528,7 @@ function copyReplace(stage, target, root) {
29433
29528
  }
29434
29529
  function flagSet(configPath, key) {
29435
29530
  const actual = actualConfig(configPath);
29436
- if (!existsSync33(actual))
29531
+ if (!existsSync32(actual))
29437
29532
  return new Set;
29438
29533
  const parsed = yamlParse(readFileSync35(actual, "utf8"));
29439
29534
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
@@ -29459,7 +29554,7 @@ function activationMatches(configPath, packageName, companionId, hasCompanion) {
29459
29554
  }
29460
29555
  function entryValue(configPath, packageName) {
29461
29556
  const actual = actualConfig(configPath);
29462
- if (!existsSync33(actual))
29557
+ if (!existsSync32(actual))
29463
29558
  return;
29464
29559
  const parsed = yamlParse(readFileSync35(actual, "utf8"));
29465
29560
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
@@ -29492,7 +29587,7 @@ function sha2563(value) {
29492
29587
  }
29493
29588
  function retentionFor(store, packageName) {
29494
29589
  const dataDir = join41(store.root, "plugin-data", hermesPluginDataNamespace(packageName));
29495
- const pluginData = existsSync33(dataDir) && lstatSync26(dataDir).isDirectory() ? { state: "present", fingerprint: fingerprintTree(dataDir) } : { state: "absent", fingerprint: null };
29590
+ const pluginData = existsSync32(dataDir) && lstatSync27(dataDir).isDirectory() ? { state: "present", fingerprint: fingerprintTree(dataDir) } : { state: "absent", fingerprint: null };
29496
29591
  const entry = entryValue(store.configPath, packageName);
29497
29592
  const inactiveMetadata = entry === undefined ? { state: "absent", fingerprint: null } : { state: "present", fingerprint: sha2563(JSON.stringify(canonicalValue(entry))) };
29498
29593
  return { pluginData, inactiveMetadata };
@@ -29501,7 +29596,7 @@ function atomicFingerprint(packageDir, companionDir) {
29501
29596
  const temp = mkdtempSync16(join41(tmpdir13(), "plgnz-hermes-atomic-"));
29502
29597
  try {
29503
29598
  cpSync15(packageDir, join41(temp, "package"), { recursive: true });
29504
- if (companionDir !== undefined && existsSync33(companionDir))
29599
+ if (companionDir !== undefined && existsSync32(companionDir))
29505
29600
  cpSync15(companionDir, join41(temp, "commands"), { recursive: true });
29506
29601
  return fingerprintTree(temp);
29507
29602
  } finally {
@@ -29510,7 +29605,7 @@ function atomicFingerprint(packageDir, companionDir) {
29510
29605
  }
29511
29606
  function readConfigDocument2(configPath) {
29512
29607
  const actual = actualConfig(configPath);
29513
- if (!existsSync33(actual))
29608
+ if (!existsSync32(actual))
29514
29609
  return null;
29515
29610
  const text = readFileSync35(actual, "utf8");
29516
29611
  if (text.trim() === "")
@@ -29568,7 +29663,7 @@ function membership(list, id, present) {
29568
29663
  }
29569
29664
  function writeConfigDocument(configPath, doc) {
29570
29665
  const actual = actualConfig(configPath);
29571
- const exists = existsSync33(actual);
29666
+ const exists = existsSync32(actual);
29572
29667
  const mode = exists ? statSync14(actual).mode & 511 : null;
29573
29668
  mkdirSync17(dirname20(actual), { recursive: true });
29574
29669
  const temp = join41(dirname20(actual), `.plgnz-hermes-rollback-${Date.now()}-${Math.random().toString(16).slice(2)}.yaml`);
@@ -29616,18 +29711,18 @@ function saveRollback(store, reference, packageName, packageDir, companionDir) {
29616
29711
  mkdirSync17(reference, { recursive: true });
29617
29712
  const companionId = hermesCommandCompanionId(packageName);
29618
29713
  writeFileSync17(join41(reference, "config-slice.json"), JSON.stringify(captureConfigSlice(store.configPath, packageName, companionId)));
29619
- if (existsSync33(packageDir))
29714
+ if (existsSync32(packageDir))
29620
29715
  cpSync15(packageDir, join41(reference, "package"), { recursive: true });
29621
- if (existsSync33(companionDir))
29716
+ if (existsSync32(companionDir))
29622
29717
  cpSync15(companionDir, join41(reference, "commands"), { recursive: true });
29623
29718
  }
29624
29719
  function restoreRollback3(store, reference, packageDir, companionDir) {
29625
29720
  const slice = JSON.parse(readFileSync35(join41(reference, "config-slice.json"), "utf8"));
29626
29721
  rmSync17(packageDir, { recursive: true, force: true });
29627
29722
  rmSync17(companionDir, { recursive: true, force: true });
29628
- if (existsSync33(join41(reference, "package")))
29723
+ if (existsSync32(join41(reference, "package")))
29629
29724
  cpSync15(join41(reference, "package"), packageDir, { recursive: true });
29630
- if (existsSync33(join41(reference, "commands")))
29725
+ if (existsSync32(join41(reference, "commands")))
29631
29726
  cpSync15(join41(reference, "commands"), companionDir, { recursive: true });
29632
29727
  restoreConfigSlice(store.configPath, slice);
29633
29728
  }
@@ -29676,7 +29771,7 @@ var hermesLifecycleDefinition = {
29676
29771
  try {
29677
29772
  const store = storeFor(target);
29678
29773
  const actual = actualConfig(store.configPath);
29679
- if (!existsSync33(actual) || !statSync14(actual).isFile())
29774
+ if (!existsSync32(actual) || !statSync14(actual).isFile())
29680
29775
  return { kind: "unknown" };
29681
29776
  const text = readFileSync35(actual, "utf8");
29682
29777
  if (text.trim() !== "") {
@@ -29759,9 +29854,9 @@ var hermesLifecycleDefinition = {
29759
29854
  const companionStage = join41(stagingRoot, "commands");
29760
29855
  mkdirSync17(packageStage, { recursive: true });
29761
29856
  projectPluginForHermes(request.snapshot.packageRoot, packageStage, companionStage);
29762
- if (existsSync33(companionStage) && readdirSync25(companionStage).length === 0)
29857
+ if (existsSync32(companionStage) && readdirSync25(companionStage).length === 0)
29763
29858
  rmSync17(companionStage, { recursive: true });
29764
- const hasCompanion = existsSync33(companionStage);
29859
+ const hasCompanion = existsSync32(companionStage);
29765
29860
  validatePackage(packageStage, request.snapshot.packageName);
29766
29861
  if (hasCompanion)
29767
29862
  validateCompanion(companionStage, hermesCommandCompanionId(request.snapshot.packageName));
@@ -29785,7 +29880,7 @@ var hermesLifecycleDefinition = {
29785
29880
  if (projection.pins.length === 0)
29786
29881
  return [];
29787
29882
  const mcp = join41(projection.stagingRoot, "package", "mcp.json");
29788
- if (!existsSync33(mcp))
29883
+ if (!existsSync32(mcp))
29789
29884
  throw new Error(`Hermes pin set has no mcp.json: ${mcp}`);
29790
29885
  const value = JSON.parse(readFileSync35(mcp, "utf8"));
29791
29886
  const servers = value.mcpServers ?? {};
@@ -29804,7 +29899,7 @@ var hermesLifecycleDefinition = {
29804
29899
  const paths = packagePaths(store, projection.packageName);
29805
29900
  const prior = withIdentity(inspect(store, projection.nativeId, projection.packageName, "none"), projection.target, projection.scopeId, projection.packageName, projection.nativeId);
29806
29901
  capturePriorSourceRepair(projection, prior.installedFingerprint);
29807
- const hasCompanion = existsSync33(join41(projection.stagingRoot, "commands"));
29902
+ const hasCompanion = existsSync32(join41(projection.stagingRoot, "commands"));
29808
29903
  const contentRoots = [{ label: "package", path: paths.packageDir, fingerprint: fingerprintTree(join41(projection.stagingRoot, "package")) }];
29809
29904
  if (hasCompanion)
29810
29905
  contentRoots.push({ label: "commands", path: paths.companionDir, fingerprint: fingerprintTree(join41(projection.stagingRoot, "commands")) });
@@ -29841,15 +29936,15 @@ var hermesLifecycleDefinition = {
29841
29936
  assertManagedPath5(store.pluginsDir, paths.companionDir);
29842
29937
  const stagedPackage = join41(prepared.stagingRoot, "package");
29843
29938
  const stagedCompanion = join41(prepared.stagingRoot, "commands");
29844
- const hasCompanion = existsSync33(stagedCompanion);
29939
+ const hasCompanion = existsSync32(stagedCompanion);
29845
29940
  const owner = ownerFromHandle(prepared.handle);
29846
29941
  assertLifecycleOwned(paths.packageDir, owner, prepared.handle);
29847
29942
  if (hasCompanion)
29848
29943
  assertLifecycleOwned(paths.companionDir, owner, prepared.handle);
29849
- else if (existsSync33(paths.companionDir))
29944
+ else if (existsSync32(paths.companionDir))
29850
29945
  assertLifecycleOwned(paths.companionDir, owner, prepared.handle);
29851
29946
  mkdirSync17(store.pluginsDir, { recursive: true });
29852
- const unchanged = existsSync33(paths.packageDir) && atomicFingerprint(paths.packageDir, hasCompanion ? paths.companionDir : undefined) === fingerprintTree(prepared.stagingRoot) && activationMatches(store.configPath, prepared.handle.packageName, paths.companionId, hasCompanion);
29947
+ const unchanged = existsSync32(paths.packageDir) && atomicFingerprint(paths.packageDir, hasCompanion ? paths.companionDir : undefined) === fingerprintTree(prepared.stagingRoot) && activationMatches(store.configPath, prepared.handle.packageName, paths.companionId, hasCompanion);
29853
29948
  if (unchanged)
29854
29949
  return { receiptId: `apply:${prepared.handle.attemptId}:${prepared.handle.operationId}`, changed: false };
29855
29950
  const changes = [];
@@ -29857,7 +29952,7 @@ var hermesLifecycleDefinition = {
29857
29952
  changes.push(copyReplace(stagedPackage, paths.packageDir, store.pluginsDir));
29858
29953
  if (hasCompanion)
29859
29954
  changes.push(copyReplace(stagedCompanion, paths.companionDir, store.pluginsDir));
29860
- else if (existsSync33(paths.companionDir))
29955
+ else if (existsSync32(paths.companionDir))
29861
29956
  changes.push(removeTarget(paths.companionDir, store.pluginsDir));
29862
29957
  updatePluginConfig(store.configPath, [prepared.handle.packageName, ...hasCompanion ? [paths.companionId] : []], hasCompanion ? [] : [paths.companionId]);
29863
29958
  for (const change of changes)
@@ -29883,11 +29978,11 @@ var hermesLifecycleDefinition = {
29883
29978
  const source = prepared.handle.sourceLocator ?? prepared.handle.sourceRevision;
29884
29979
  const changes = [];
29885
29980
  try {
29886
- if (existsSync33(paths.packageDir)) {
29981
+ if (existsSync32(paths.packageDir)) {
29887
29982
  assertLifecycleOwned(paths.packageDir, ownerFromHandle(prepared.handle));
29888
29983
  changes.push(removeTarget(paths.packageDir, store.pluginsDir));
29889
29984
  }
29890
- if (existsSync33(paths.companionDir)) {
29985
+ if (existsSync32(paths.companionDir)) {
29891
29986
  const marker = readMarker(paths.companionDir);
29892
29987
  if (marker !== null && marker.pluginId === prepared.handle.nativeId && marker.source === source)
29893
29988
  changes.push(removeTarget(paths.companionDir, store.pluginsDir));
@@ -30234,7 +30329,7 @@ function invalidSelection2(diagnostic) {
30234
30329
  }
30235
30330
 
30236
30331
  // src/recorded-pins.ts
30237
- import { existsSync as existsSync34, readFileSync as readFileSync36 } from "node:fs";
30332
+ import { existsSync as existsSync33, readFileSync as readFileSync36 } from "node:fs";
30238
30333
  import { isAbsolute as isAbsolute13, join as join42, resolve as resolve28 } from "node:path";
30239
30334
  function resolveRecordedPinExecutables(packageRoot, servers) {
30240
30335
  const pins = [];
@@ -30257,7 +30352,7 @@ function resolveRecordedPinExecutables(packageRoot, servers) {
30257
30352
  function recordedPinCommand(packageRoot, server) {
30258
30353
  for (const name of [".mcp.json", "mcp.json"]) {
30259
30354
  const file = join42(packageRoot, name);
30260
- if (!existsSync34(file))
30355
+ if (!existsSync33(file))
30261
30356
  continue;
30262
30357
  let parsed;
30263
30358
  try {
@@ -31434,6 +31529,14 @@ function writeState(records, file = stateFile()) {
31434
31529
  validateLegacyInstallRecords(records);
31435
31530
  atomicWrite(file, JSON.stringify({ version: 1, installs: records }, null, 2));
31436
31531
  }
31532
+ function writeInstallLedger(records, changed, binding) {
31533
+ const loaded = readLifecycleState();
31534
+ if (loaded.sourceVersion !== 2) {
31535
+ writeState(records);
31536
+ return;
31537
+ }
31538
+ writeLifecycleState(withLegacyWriterRecord(loaded.state, changed, binding), { globalPreflight: "succeeded" });
31539
+ }
31437
31540
  function withLegacyWriterRecord(state, record, binding) {
31438
31541
  const source = persistedSource(binding);
31439
31542
  const scope = createDeploymentScopeIdentity(source, { kind: record.host, instance: "default" });
@@ -33446,6 +33549,9 @@ function selectTargets(all, options) {
33446
33549
  return defaultPinTargets(all);
33447
33550
  }
33448
33551
 
33552
+ // src/update.ts
33553
+ init_compatibility();
33554
+
33449
33555
  // src/native-identity.ts
33450
33556
  function captureNativeIdentity(writer, plugin) {
33451
33557
  let nativeId = null;
@@ -33497,7 +33603,12 @@ function shortSha2(sha) {
33497
33603
  async function runUpdate(name, options = {}) {
33498
33604
  const hosts = options.writers ?? writers;
33499
33605
  let state = options.state ?? readState();
33500
- const save = options.writeState ?? writeState;
33606
+ const save = (records, changed, binding) => {
33607
+ if (options.writeState !== undefined)
33608
+ options.writeState(records);
33609
+ else
33610
+ writeInstallLedger(records, changed, binding);
33611
+ };
33501
33612
  const prefix = options.dryRun === true ? "[dry-run] " : "";
33502
33613
  const findings = [];
33503
33614
  let mutationStarted = false;
@@ -33626,7 +33737,7 @@ async function runUpdate(name, options = {}) {
33626
33737
  const pending = { ...record, pending: "install" };
33627
33738
  record = pending;
33628
33739
  const next = state.map((candidate) => candidate === persistedRecord ? pending : candidate);
33629
- save(next);
33740
+ save(next, pending, resolved.snapshot.binding);
33630
33741
  state = next;
33631
33742
  recordMutationStarted = true;
33632
33743
  mutationStarted = true;
@@ -33713,7 +33824,7 @@ async function runUpdate(name, options = {}) {
33713
33824
  delete finalized.pending;
33714
33825
  const next = state.map((candidate) => candidate === record ? finalized : candidate);
33715
33826
  try {
33716
- save(next);
33827
+ save(next, finalized, resolved.snapshot.binding);
33717
33828
  } catch (error) {
33718
33829
  findings.push(findingFor(record, {
33719
33830
  mark: "✗",
@@ -33847,6 +33958,9 @@ function findConsumerProfile(id) {
33847
33958
  return byId.get(id);
33848
33959
  }
33849
33960
 
33961
+ // src/cli.ts
33962
+ init_compatibility();
33963
+
33850
33964
  // src/legacy-install-outcome.ts
33851
33965
  function serializeLegacyInstallOutcomes(report) {
33852
33966
  const rows = report.outcomes.map((outcome) => ({
@@ -33903,7 +34017,7 @@ function legacyCommandAction(command) {
33903
34017
  // package.json
33904
34018
  var package_default = {
33905
34019
  name: "plugnz",
33906
- version: "0.0.22",
34020
+ version: "0.0.23",
33907
34021
  description: "Install, diagnose and update agent plugins (Agent Plugins spec) and MCP configs across Claude Code, Codex, Cursor, Kimi and more",
33908
34022
  license: "MIT",
33909
34023
  type: "module",
@@ -34361,6 +34475,10 @@ function printReport(report, mode) {
34361
34475
  const legacy = serializeLegacyInstallOutcomes(report);
34362
34476
  for (const item of legacy)
34363
34477
  console.log(`${item.target} ${item.status} ${item.plugin}${item.diagnostic ? ` ${item.diagnostic}` : ""}`);
34478
+ for (const facts of report.verification?.operations ?? []) {
34479
+ const outcome = report.outcomes.find((row) => row.operationId === facts.operationId);
34480
+ console.log(`${outcome.scope.target.kind} ${outcome.package} compatibility=${facts.compatibility} registration=${facts.registration} executionApproval=${facts.executionApproval} delivery=${facts.delivery}`);
34481
+ }
34364
34482
  }
34365
34483
  }
34366
34484
  function select(available, targets) {
@@ -34663,14 +34781,6 @@ async function runPlannerAdd(source, binding, targets, flags) {
34663
34781
  command: { ...executed.report.command, name: "add" }
34664
34782
  });
34665
34783
  }
34666
- function writeInstallLedger(records, changed, binding) {
34667
- const loaded = readLifecycleState();
34668
- if (loaded.sourceVersion !== 2) {
34669
- writeState(records);
34670
- return;
34671
- }
34672
- writeLifecycleState(withLegacyWriterRecord(loaded.state, changed, binding), { globalPreflight: "succeeded" });
34673
- }
34674
34784
  async function runWriterAdd(source, selectedWriters, flags, mode) {
34675
34785
  let resolved;
34676
34786
  try {
@@ -35002,7 +35112,8 @@ async function runRecordedLifecycleUpdate(flags, state) {
35002
35112
  const scope = scopes.get(activation.scopeId);
35003
35113
  if (scope === undefined || scope.target.instance !== "default" || !kinds.has(scope.target.kind))
35004
35114
  return [];
35005
- if (requested !== undefined && requested !== activation.packageId && requested !== activation.nativeId)
35115
+ const writer = present.selected.find((candidate) => candidate.id === scope.target.kind);
35116
+ if (!requestedPersistedIdentityMatches(writer, activation.packageId, activation.nativeId, requested))
35006
35117
  return [];
35007
35118
  return [{ scope, packageId: activation.packageId }];
35008
35119
  });
@@ -35080,6 +35191,7 @@ async function runRecordedLifecycleUpdate(flags, state) {
35080
35191
  });
35081
35192
  }
35082
35193
  function emitAddReport(report, mode) {
35194
+ report = parseLifecycleReport({ ...report, verification: installationVerification(report) });
35083
35195
  if (mode === "json")
35084
35196
  return emitValidatedReport(report, true);
35085
35197
  printReport(report, mode);