@hasna/skills 0.10.28 → 0.10.31

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/bin/mcp.js CHANGED
@@ -20019,7 +20019,7 @@ var package_default;
20019
20019
  var init_package = __esm(() => {
20020
20020
  package_default = {
20021
20021
  name: "@hasna/skills",
20022
- version: "0.10.28",
20022
+ version: "0.10.31",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
@@ -38184,6 +38184,8 @@ var init_native_discovery_roots = __esm(() => {
38184
38184
  ["codex", ".codex/skills"],
38185
38185
  ["codex", ".agents/skills"],
38186
38186
  ["gemini", ".gemini/skills"],
38187
+ ["sumi", ".sumi/skills"],
38188
+ ["sumi", ".sumi/skill"],
38187
38189
  ["codewith", ".codewith/skills"],
38188
38190
  ["opencode", ".config/opencode/skills"],
38189
38191
  ["opencode", ".opencode/skills"],
@@ -38201,7 +38203,7 @@ var init_native_discovery_roots = __esm(() => {
38201
38203
  // src/lib/agent-adapters.ts
38202
38204
  var INTEGRATION_AGENTS;
38203
38205
  var init_agent_adapters = __esm(() => {
38204
- INTEGRATION_AGENTS = ["claude", "codex", "gemini", "opencode", "cursor", "hermes"];
38206
+ INTEGRATION_AGENTS = ["claude", "codex", "gemini", "opencode", "cursor", "hermes", "sumi"];
38205
38207
  });
38206
38208
 
38207
38209
  // src/lib/agent-policy-limits.ts
@@ -48092,6 +48094,38 @@ var init_agent_bridge = __esm(() => {
48092
48094
  // src/lib/agent-codex.ts
48093
48095
  var init_agent_codex = () => {};
48094
48096
 
48097
+ // src/lib/agent-sumi.ts
48098
+ import { existsSync as existsSync8, lstatSync as lstatSync13, realpathSync as realpathSync4 } from "fs";
48099
+ import { join as join18, resolve as resolve10 } from "path";
48100
+ function sumiConfigDirectory(home, env = process.env) {
48101
+ for (const key of ["SUMI_CONFIG", "SUMI_CONFIG_CONTENT"])
48102
+ if (env[key] !== undefined)
48103
+ throw new Error(`Sumi ${key} requires a dedicated discovery adapter; unset it before Skills integration`);
48104
+ const selected = (key) => env[key]?.trim() ? env[key] : undefined;
48105
+ const expand = (value) => resolve10(value === "~" ? home : value.startsWith("~/") ? join18(home, value.slice(2)) : value);
48106
+ const explicit = selected("SUMI_CONFIG_DIR");
48107
+ const xdg = selected("XDG_CONFIG_HOME");
48108
+ const custom2 = selected("SUMI_HOME");
48109
+ const canonical5 = explicit ? expand(explicit) : xdg ? join18(expand(xdg), "sumi") : join18(custom2 ? expand(custom2) : join18(home, ".hasna-internal/sumi"), "config");
48110
+ if (explicit || xdg || custom2)
48111
+ return canonical5;
48112
+ const legacy = join18(home, ".config/sumi");
48113
+ const a = lstatSync13(canonical5, { throwIfNoEntry: false }), b = lstatSync13(legacy, { throwIfNoEntry: false });
48114
+ if (a && b && realpathSync4(canonical5) !== realpathSync4(legacy))
48115
+ throw new Error("Sumi config roots conflict; complete native home adoption before Skills integration");
48116
+ const path = a ? canonical5 : b ? legacy : canonical5;
48117
+ if (!existsSync8(path))
48118
+ return path;
48119
+ const physical = realpathSync4(path);
48120
+ if ((a?.isSymbolicLink() || b?.isSymbolicLink()) && ![canonical5, legacy].includes(physical))
48121
+ throw new Error("Sumi config alias must resolve to its canonical or legacy root");
48122
+ return physical;
48123
+ }
48124
+ function sumiConfigPath(home) {
48125
+ return join18(sumiConfigDirectory(home), "sumi.json");
48126
+ }
48127
+ var init_agent_sumi = () => {};
48128
+
48095
48129
  // src/lib/agent-integration.ts
48096
48130
  var init_agent_integration = __esm(() => {
48097
48131
  init_codex_plugin_skill_controls();
@@ -48105,6 +48139,7 @@ var init_agent_integration = __esm(() => {
48105
48139
  init_agent_discovery();
48106
48140
  init_agent_adapters();
48107
48141
  init_agent_codex();
48142
+ init_agent_sumi();
48108
48143
  init_agent_hermes();
48109
48144
  init_claude_settings_witness();
48110
48145
  });
@@ -48142,17 +48177,17 @@ var init_skill_aliases = __esm(() => {
48142
48177
  });
48143
48178
 
48144
48179
  // src/lib/project-state.ts
48145
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
48146
- import { join as join18 } from "path";
48180
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
48181
+ import { join as join19 } from "path";
48147
48182
  function getProjectStateDir(targetDir = process.cwd()) {
48148
- return join18(targetDir, SKILLS_PROJECT_DIR);
48183
+ return join19(targetDir, SKILLS_PROJECT_DIR);
48149
48184
  }
48150
48185
  function getProjectConfigPath(targetDir = process.cwd()) {
48151
- return join18(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
48186
+ return join19(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
48152
48187
  }
48153
48188
  function loadProjectConfig(targetDir = process.cwd()) {
48154
48189
  const path = getProjectConfigPath(targetDir);
48155
- if (!existsSync8(path))
48190
+ if (!existsSync9(path))
48156
48191
  return null;
48157
48192
  try {
48158
48193
  return normalizeProjectConfig(JSON.parse(readFileSync12(path, "utf-8")));
@@ -48263,8 +48298,8 @@ var init_project_state = __esm(() => {
48263
48298
  });
48264
48299
 
48265
48300
  // src/lib/installer.ts
48266
- import { existsSync as existsSync9, readFileSync as readFileSync13, rmSync } from "fs";
48267
- import { join as join19 } from "path";
48301
+ import { existsSync as existsSync10, readFileSync as readFileSync13, rmSync } from "fs";
48302
+ import { join as join20 } from "path";
48268
48303
  import { homedir as homedir2 } from "os";
48269
48304
  function getSkillPath(name) {
48270
48305
  const skillName = normalizeSkillName(getCanonicalSkillName(name));
@@ -48274,7 +48309,7 @@ function getSkillPath(name) {
48274
48309
  const extensionPath = findExtensionSkillPath(skillName);
48275
48310
  if (extensionPath)
48276
48311
  return extensionPath;
48277
- return join19(getPortableSkillsRoot(), skillName);
48312
+ return join20(getPortableSkillsRoot(), skillName);
48278
48313
  }
48279
48314
  function getCanonicalSkillName(name) {
48280
48315
  return getSkill(name)?.name ?? resolveSkillAlias(normalizeSkillSlug(name));
@@ -48283,7 +48318,7 @@ function installSkill(name, options = {}) {
48283
48318
  const { targetDir = process.cwd(), overwrite = false } = options;
48284
48319
  const canonicalName = getCanonicalSkillName(name);
48285
48320
  const skillName = normalizeSkillName(canonicalName);
48286
- if (!existsSync9(getSkillPath(name))) {
48321
+ if (!existsSync10(getSkillPath(name))) {
48287
48322
  const knownOfficial = Boolean(getSkill(name));
48288
48323
  return {
48289
48324
  skill: canonicalName,
@@ -48328,11 +48363,11 @@ function getAgentSkillsDir(agent, scope = "global", projectDir) {
48328
48363
  const base = projectDir || process.cwd();
48329
48364
  switch (agent) {
48330
48365
  case "pi":
48331
- return scope === "project" ? join19(base, ".pi", "skills") : join19(homedir2(), ".pi", "agent", "skills");
48366
+ return scope === "project" ? join20(base, ".pi", "skills") : join20(homedir2(), ".pi", "agent", "skills");
48332
48367
  case "opencode":
48333
- return scope === "project" ? join19(base, ".opencode", "skills") : join19(homedir2(), ".config", "opencode", "skills");
48368
+ return scope === "project" ? join20(base, ".opencode", "skills") : join20(homedir2(), ".config", "opencode", "skills");
48334
48369
  default:
48335
- return scope === "project" ? join19(base, `.${agent}`, "skills") : join19(homedir2(), `.${agent}`, "skills");
48370
+ return scope === "project" ? join20(base, `.${agent}`, "skills") : join20(homedir2(), `.${agent}`, "skills");
48336
48371
  }
48337
48372
  }
48338
48373
  function warnMissingDependencies(name, targetDir) {
@@ -48347,8 +48382,8 @@ function warnMissingDependencies(name, targetDir) {
48347
48382
  }
48348
48383
  }
48349
48384
  function readBundledSkillVersion(name) {
48350
- const pkgPath = join19(getSkillPath(name), "package.json");
48351
- if (!existsSync9(pkgPath))
48385
+ const pkgPath = join20(getSkillPath(name), "package.json");
48386
+ if (!existsSync10(pkgPath))
48352
48387
  return "unknown";
48353
48388
  try {
48354
48389
  const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
@@ -48415,13 +48450,13 @@ var init_skill_doc_file = __esm(() => {
48415
48450
  });
48416
48451
 
48417
48452
  // src/lib/skillinfo.ts
48418
- import { existsSync as existsSync10, readFileSync as readFileSync14 } from "fs";
48419
- import { join as join20 } from "path";
48453
+ import { existsSync as existsSync11, readFileSync as readFileSync14 } from "fs";
48454
+ import { join as join21 } from "path";
48420
48455
  function isInstructionSkillDir(skillPath, meta3) {
48421
48456
  if (meta3?.kind === "instruction")
48422
48457
  return true;
48423
- const skillMdPath = join20(skillPath, "SKILL.md");
48424
- if (!existsSync10(skillMdPath))
48458
+ const skillMdPath = join21(skillPath, "SKILL.md");
48459
+ if (!existsSync11(skillMdPath))
48425
48460
  return false;
48426
48461
  try {
48427
48462
  return parseSkillFrontmatter(readFileSync14(skillMdPath, "utf-8"))?.kind === "instruction";
@@ -48431,12 +48466,12 @@ function isInstructionSkillDir(skillPath, meta3) {
48431
48466
  }
48432
48467
  function getSkillDocs(name) {
48433
48468
  const skillPath = getSkillPath(name);
48434
- if (!existsSync10(skillPath))
48469
+ if (!existsSync11(skillPath))
48435
48470
  return null;
48436
48471
  return {
48437
- skillMd: readIfExists(join20(skillPath, "SKILL.md")),
48438
- readme: readIfExists(join20(skillPath, "README.md")),
48439
- claudeMd: readIfExists(join20(skillPath, "CLAUDE.md"))
48472
+ skillMd: readIfExists(join21(skillPath, "SKILL.md")),
48473
+ readme: readIfExists(join21(skillPath, "README.md")),
48474
+ claudeMd: readIfExists(join21(skillPath, "CLAUDE.md"))
48440
48475
  };
48441
48476
  }
48442
48477
  function getSkillBestDoc(name, file2) {
@@ -48448,18 +48483,18 @@ function getSkillBestDoc(name, file2) {
48448
48483
  }
48449
48484
  function getSkillRequirements(name) {
48450
48485
  const skillPath = getSkillPath(name);
48451
- if (!existsSync10(skillPath))
48486
+ if (!existsSync11(skillPath))
48452
48487
  return null;
48453
48488
  const texts = [];
48454
48489
  for (const file2 of ["SKILL.md", "README.md", "CLAUDE.md", ".env.example", ".env.local.example"]) {
48455
- const content = readIfExists(join20(skillPath, file2));
48490
+ const content = readIfExists(join21(skillPath, file2));
48456
48491
  if (content)
48457
48492
  texts.push(content);
48458
48493
  }
48459
48494
  const meta3 = getSkill(name);
48460
48495
  let dependencies = {};
48461
48496
  try {
48462
- dependencies = JSON.parse(readFileSync14(join20(skillPath, "package.json"), "utf8")).dependencies || {};
48497
+ dependencies = JSON.parse(readFileSync14(join21(skillPath, "package.json"), "utf8")).dependencies || {};
48463
48498
  } catch {}
48464
48499
  return getSkillRequirementsFromContent(name, texts, dependencies, meta3);
48465
48500
  }
@@ -48512,7 +48547,7 @@ async function runSkill(name, args, options = {}) {
48512
48547
  const meta3 = getSkill(name);
48513
48548
  const canonicalName = meta3?.name ?? name;
48514
48549
  const skillPath = getSkillPath(canonicalName);
48515
- if (!existsSync10(skillPath)) {
48550
+ if (!existsSync11(skillPath)) {
48516
48551
  return { exitCode: 1, error: `Skill '${name}' not found` };
48517
48552
  }
48518
48553
  if (isInstructionSkillDir(skillPath, meta3)) {
@@ -48521,8 +48556,8 @@ async function runSkill(name, args, options = {}) {
48521
48556
  error: `Skill '${name}' is an instruction skill (kind: instruction) and is not runnable. Instruction skills are consumed by coding agents via SKILL.md, not executed with 'skills run'.`
48522
48557
  };
48523
48558
  }
48524
- const pkgPath = join20(skillPath, "package.json");
48525
- if (!existsSync10(pkgPath)) {
48559
+ const pkgPath = join21(skillPath, "package.json");
48560
+ if (!existsSync11(pkgPath)) {
48526
48561
  return { exitCode: 1, error: `No package.json in skill '${name}'` };
48527
48562
  }
48528
48563
  let entryPoint2;
@@ -48541,12 +48576,12 @@ async function runSkill(name, args, options = {}) {
48541
48576
  } catch {
48542
48577
  return { exitCode: 1, error: `Failed to parse package.json for skill '${name}'` };
48543
48578
  }
48544
- const entryPath = join20(skillPath, entryPoint2);
48545
- if (!existsSync10(entryPath)) {
48579
+ const entryPath = join21(skillPath, entryPoint2);
48580
+ if (!existsSync11(entryPath)) {
48546
48581
  return { exitCode: 1, error: `Entry point '${entryPoint2}' not found in skill '${name}'` };
48547
48582
  }
48548
48583
  const env = { ...process.env, ...options.env };
48549
- if (!existsSync10(join20(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
48584
+ if (!existsSync11(join21(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
48550
48585
  const failure = await prepareSkillDependencies(skillPath, env, options.preparationTimeoutMs);
48551
48586
  if (failure)
48552
48587
  return failure;
@@ -48572,7 +48607,7 @@ async function runSkill(name, args, options = {}) {
48572
48607
  function detectProjectSkills(cwd = process.cwd()) {
48573
48608
  let pkg;
48574
48609
  try {
48575
- pkg = JSON.parse(readFileSync14(join20(cwd, "package.json"), "utf8"));
48610
+ pkg = JSON.parse(readFileSync14(join21(cwd, "package.json"), "utf8"));
48576
48611
  } catch {
48577
48612
  return { detected: [], recommended: [] };
48578
48613
  }
@@ -48610,7 +48645,7 @@ function extractEnvVars(text2) {
48610
48645
  }
48611
48646
  function readIfExists(path) {
48612
48647
  try {
48613
- if (existsSync10(path)) {
48648
+ if (existsSync11(path)) {
48614
48649
  return readFileSync14(path, "utf-8");
48615
48650
  }
48616
48651
  } catch {}
@@ -48667,6 +48702,8 @@ var init_selected_document = __esm(() => {
48667
48702
  async function resolveSelectionContext(profileId, options = {}) {
48668
48703
  const sessionState = options.sessionId ? readSkillSessionSnapshotIfExists(options.sessionId, options) : null;
48669
48704
  const session = sessionState?.receipt ?? null;
48705
+ if (options.nativeParentSessionId !== undefined && session && (session.parent?.sessionId ?? null) !== options.nativeParentSessionId)
48706
+ throw new SkillSelectionError("SESSION_PARENT_MISMATCH", "The native session id is already bound to different parent custody.");
48670
48707
  const parentState = !session && options.parentSessionId ? readSkillSessionSnapshotIfExists(options.parentSessionId, options) : null;
48671
48708
  if (!session && options.parentSessionId && !parentState) {
48672
48709
  throw new SkillSelectionError("SESSION_PARENT_NOT_FOUND", "A child Skills session requires an existing parent receipt so its inherited pin can be bound exactly.");
@@ -48860,11 +48897,11 @@ var init_plugin_projection = __esm(() => {
48860
48897
  });
48861
48898
 
48862
48899
  // src/lib/plugin-projection-store.ts
48863
- import { constants as constants7, closeSync as closeSync10, fchmodSync, fstatSync as fstatSync10, fsyncSync as fsyncSync2, linkSync, lstatSync as lstatSync13, mkdirSync as mkdirSync6, openSync as openSync10, opendirSync as opendirSync2, readSync as readSync6, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
48864
- import { dirname as dirname11, isAbsolute as isAbsolute9, join as join21, parse as parse9, resolve as resolve10 } from "path";
48900
+ import { constants as constants7, closeSync as closeSync10, fchmodSync, fstatSync as fstatSync10, fsyncSync as fsyncSync2, linkSync, lstatSync as lstatSync14, mkdirSync as mkdirSync6, openSync as openSync10, opendirSync as opendirSync2, readSync as readSync6, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
48901
+ import { dirname as dirname11, isAbsolute as isAbsolute9, join as join22, parse as parse9, resolve as resolve11 } from "path";
48865
48902
  function stat(path) {
48866
48903
  try {
48867
- return lstatSync13(path, { bigint: true });
48904
+ return lstatSync14(path, { bigint: true });
48868
48905
  } catch (error61) {
48869
48906
  if (missing(error61))
48870
48907
  return null;
@@ -48872,7 +48909,7 @@ function stat(path) {
48872
48909
  }
48873
48910
  }
48874
48911
  function canonical5(path) {
48875
- pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute9(path) && resolve10(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
48912
+ pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute9(path) && resolve11(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
48876
48913
  }
48877
48914
  function owner(stats, system = false) {
48878
48915
  const current = uid();
@@ -48887,7 +48924,7 @@ function ancestors(path, create = false) {
48887
48924
  let current = filesystemRoot;
48888
48925
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
48889
48926
  if (segment)
48890
- current = join21(current, segment);
48927
+ current = join22(current, segment);
48891
48928
  let currentStat = stat(current);
48892
48929
  if (!currentStat && create) {
48893
48930
  try {
@@ -48995,7 +49032,7 @@ function snapshotPluginTree(root, options = {}) {
48995
49032
  pluginNeed(++visited <= PLUGIN_PROJECTION_LIMITS.files * 50, "Plugin tree membership exceeds its limit");
48996
49033
  const path = relative5 ? `${relative5}/${name}` : name;
48997
49034
  pluginNeed(new TextEncoder().encode(path).byteLength <= 100 && !/[\\:\x00-\x1f\x7f]/u.test(path), "Plugin entry path exceeds its limit or is unsafe");
48998
- const absolute = join21(directory, name), entryStat = stat(absolute);
49035
+ const absolute = join22(directory, name), entryStat = stat(absolute);
48999
49036
  pluginNeed(entryStat, "Plugin tree member disappeared");
49000
49037
  if (relative5 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
49001
49038
  const bytes2 = readBytes(absolute, 32, "native-pin");
@@ -49012,7 +49049,7 @@ function snapshotPluginTree(root, options = {}) {
49012
49049
  directories.push({ path: absolute, stat: entryStat, names: pins });
49013
49050
  for (const pin of pins) {
49014
49051
  pluginNeed(/^[1-9][0-9]{0,9}$/.test(pin) && Number(pin) <= 2147483647, "Unrecognized native plugin pin name");
49015
- const pinPath = join21(absolute, pin), pinStat = stat(pinPath);
49052
+ const pinPath = join22(absolute, pin), pinStat = stat(pinPath);
49016
49053
  pluginNeed(pinStat, "Native plugin pin disappeared");
49017
49054
  const bytes2 = readBytes(pinPath, 4096, "native-pin");
49018
49055
  let value;
@@ -49109,7 +49146,7 @@ var init_selected_manifest = __esm(() => {
49109
49146
  });
49110
49147
 
49111
49148
  // src/lib/plugin-admission.ts
49112
- import { isAbsolute as isAbsolute10, join as join22, resolve as resolve11 } from "path";
49149
+ import { isAbsolute as isAbsolute10, join as join23, resolve as resolve12 } from "path";
49113
49150
  function validatePluginTarget(value) {
49114
49151
  pluginKeys(value, ["schemaVersion", "pluginId", "registrations", "native", "resolver"]);
49115
49152
  pluginNeed(value.schemaVersion === 1, "Invalid plugin admission target");
@@ -49119,7 +49156,7 @@ function validatePluginTarget(value) {
49119
49156
  for (const registration of value.registrations) {
49120
49157
  pluginKeys(registration, ["scope", "projectPath"]);
49121
49158
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
49122
- pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute10(registration.projectPath) && resolve11(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
49159
+ pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute10(registration.projectPath) && resolve12(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
49123
49160
  const key = JSON.stringify([registration.scope, registration.projectPath]);
49124
49161
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
49125
49162
  scopes.add(key);
@@ -49127,7 +49164,7 @@ function validatePluginTarget(value) {
49127
49164
  for (const key of ["native", "resolver"]) {
49128
49165
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
49129
49166
  pluginText(value[key].executable);
49130
- pluginNeed(isAbsolute10(value[key].executable) && resolve11(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
49167
+ pluginNeed(isAbsolute10(value[key].executable) && resolve12(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
49131
49168
  pluginDigest(value[key].digest);
49132
49169
  }
49133
49170
  pluginNeed(["2.1.274", "2.1.276"].includes(value.native.version), "Plugin admission requires a certified Claude command-source runtime (2.1.274 or 2.1.276)");
@@ -49270,12 +49307,12 @@ function pluginResolverCommand(binding) {
49270
49307
  }
49271
49308
  function pluginBindingPath(storeRoot, id) {
49272
49309
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
49273
- return join22(storeRoot, "bindings", `${id}.json`);
49310
+ return join23(storeRoot, "bindings", `${id}.json`);
49274
49311
  }
49275
49312
  function pluginReceiptPath(storeRoot, id, digest) {
49276
49313
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
49277
49314
  pluginDigest(digest);
49278
- return join22(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
49315
+ return join23(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
49279
49316
  }
49280
49317
  function readPluginBinding(storeRoot, id) {
49281
49318
  const value = readPluginJson(pluginBindingPath(storeRoot, id));
@@ -49295,7 +49332,7 @@ function readPluginAdmissionReceipt(storeRoot, id, digest) {
49295
49332
  pluginNeed(receipt.plan.bindingId === id && receipt.plan.planDigest === digest, "Plugin receipt identity differs from its filename");
49296
49333
  const binding = readPluginBinding(storeRoot, id);
49297
49334
  pluginNeed(canonicalJson(binding) === canonicalJson(receipt.plan.binding) && receipt.plan.sourceCommand === pluginResolverCommand(binding), "Plugin receipt binding changed");
49298
- pluginNeed(receipt.materializedPath === join22(storeRoot, "objects", id, digest.slice(7)), "Plugin receipt points outside its immutable materialization");
49335
+ pluginNeed(receipt.materializedPath === join23(storeRoot, "objects", id, digest.slice(7)), "Plugin receipt points outside its immutable materialization");
49299
49336
  pluginText(receipt.admittedAt, 64);
49300
49337
  pluginNeed(Number.isFinite(Date.parse(receipt.admittedAt)), "Invalid plugin admission time");
49301
49338
  return receipt;
@@ -49312,8 +49349,8 @@ var init_plugin_admission = __esm(() => {
49312
49349
  });
49313
49350
 
49314
49351
  // src/lib/plugin-discovery.ts
49315
- import { closeSync as closeSync11, constants as constants8, fstatSync as fstatSync11, lstatSync as lstatSync14, openSync as openSync11, opendirSync as opendirSync3, readSync as readSync7 } from "fs";
49316
- import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute11, join as join23, resolve as resolve12 } from "path";
49352
+ import { closeSync as closeSync11, constants as constants8, fstatSync as fstatSync11, lstatSync as lstatSync15, openSync as openSync11, opendirSync as opendirSync3, readSync as readSync7 } from "fs";
49353
+ import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute11, join as join24, resolve as resolve13 } from "path";
49317
49354
  function validateManagedPluginWitnesses(value) {
49318
49355
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
49319
49356
  const seen = new Set;
@@ -49322,21 +49359,21 @@ function validateManagedPluginWitnesses(value) {
49322
49359
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
49323
49360
  seen.add(item.bindingId);
49324
49361
  pluginText(item.storeRoot);
49325
- pluginNeed(isAbsolute11(item.storeRoot) && resolve12(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
49362
+ pluginNeed(isAbsolute11(item.storeRoot) && resolve13(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
49326
49363
  }
49327
49364
  }
49328
49365
  function safe3(path) {
49329
49366
  pluginText(path);
49330
- pluginNeed(isAbsolute11(path) && resolve12(path) === path, "Invalid plugin registry path");
49367
+ pluginNeed(isAbsolute11(path) && resolve13(path) === path, "Invalid plugin registry path");
49331
49368
  for (let at = path;; at = dirname12(at)) {
49332
- pluginNeed(!lstatSync14(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
49369
+ pluginNeed(!lstatSync15(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
49333
49370
  if (at === dirname12(at))
49334
49371
  break;
49335
49372
  }
49336
49373
  }
49337
49374
  function readRegistry(path) {
49338
49375
  safe3(path);
49339
- const initial = lstatSync14(path);
49376
+ const initial = lstatSync15(path);
49340
49377
  pluginNeed(initial.isFile() && initial.size <= 1024 * 1024, "Plugin registry is not a bounded regular file");
49341
49378
  const fd = openSync11(path, constants8.O_RDONLY | constants8.O_NOFOLLOW | constants8.O_NONBLOCK);
49342
49379
  try {
@@ -49350,7 +49387,7 @@ function readRegistry(path) {
49350
49387
  break;
49351
49388
  length += count;
49352
49389
  }
49353
- const after = fstatSync11(fd), current = lstatSync14(path);
49390
+ const after = fstatSync11(fd), current = lstatSync15(path);
49354
49391
  safe3(path);
49355
49392
  pluginNeed(length <= 1024 * 1024 && length === opened.size && after.size === opened.size && after.mtimeMs === opened.mtimeMs && after.ctimeMs === opened.ctimeMs && current.dev === opened.dev && current.ino === opened.ino && current.mtimeMs === opened.mtimeMs && current.ctimeMs === opened.ctimeMs, "Plugin registry changed during read");
49356
49393
  let value;
@@ -49380,7 +49417,7 @@ function hashManagedPluginRegistry(path, managed) {
49380
49417
  seen.add(target.pluginId);
49381
49418
  const rows = plugins[target.pluginId];
49382
49419
  pluginNeed(Array.isArray(rows) && rows.length === target.registrations.length, "Managed plugin registration membership changed");
49383
- const [name, market] = target.pluginId.split("@"), cacheRoot = join23(dirname12(path), "cache", market, name);
49420
+ const [name, market] = target.pluginId.split("@"), cacheRoot = join24(dirname12(path), "cache", market, name);
49384
49421
  const scopes = new Set, approvals = new Map, currentFiles = new Map;
49385
49422
  plugins[target.pluginId] = rows.map((row) => {
49386
49423
  pluginNeed(pluginObject(row), "Invalid managed plugin registration");
@@ -49393,7 +49430,7 @@ function hashManagedPluginRegistry(path, managed) {
49393
49430
  pluginText(row.sourceProducerPath);
49394
49431
  pluginText(row.lastUpdated, 64);
49395
49432
  pluginNeed(Number.isFinite(Date.parse(row.lastUpdated)), "Invalid managed plugin update timestamp");
49396
- pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join23(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
49433
+ pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join24(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
49397
49434
  const approval = (producer) => {
49398
49435
  pluginText(producer);
49399
49436
  const digest = `sha256:${basename6(producer)}`;
@@ -49423,7 +49460,7 @@ function hashManagedPluginRegistry(path, managed) {
49423
49460
  return Object.fromEntries(Object.entries(row).filter(([key]) => !["version", "installPath", "sourceProducerPath", "previousProducerPaths", "lastUpdated"].includes(key)));
49424
49461
  });
49425
49462
  safe3(cacheRoot);
49426
- const before = lstatSync14(cacheRoot);
49463
+ const before = lstatSync15(cacheRoot);
49427
49464
  pluginNeed(before.isDirectory(), "Invalid managed plugin cache root");
49428
49465
  const directory = opendirSync3(cacheRoot), names = [];
49429
49466
  try {
@@ -49436,17 +49473,17 @@ function hashManagedPluginRegistry(path, managed) {
49436
49473
  directory.closeSync();
49437
49474
  }
49438
49475
  for (const version2 of names.sort()) {
49439
- const files = pluginFileWitnesses(snapshotPluginTree(join23(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
49476
+ const files = pluginFileWitnesses(snapshotPluginTree(join24(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
49440
49477
  verifiedBytes += files.reduce((total, file2) => total + file2.size, 0);
49441
49478
  pluginNeed(verifiedBytes <= 256 * 1024 * 1024, "Managed plugin verification exceeds its aggregate byte budget");
49442
49479
  const serialized = JSON.stringify(files);
49443
- const expected = currentFiles.get(join23(cacheRoot, version2));
49480
+ const expected = currentFiles.get(join24(cacheRoot, version2));
49444
49481
  pluginNeed(expected === undefined || serialized === expected, "Current native cache differs from its exact registered producer receipt");
49445
49482
  pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(version2, receipt) && JSON.stringify(receipt.plan.files) === serialized), "A retained native plugin cache version differs from every approved projection");
49446
49483
  }
49447
49484
  for (const row of rows)
49448
49485
  pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
49449
- const after = lstatSync14(cacheRoot);
49486
+ const after = lstatSync15(cacheRoot);
49450
49487
  safe3(cacheRoot);
49451
49488
  pluginNeed(before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs, "Managed cache version membership changed during verification");
49452
49489
  }
@@ -49461,19 +49498,19 @@ var init_plugin_discovery = __esm(() => {
49461
49498
 
49462
49499
  // src/lib/claude-marketplace-registry.ts
49463
49500
  import { createHash as createHash13 } from "crypto";
49464
- import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync15, openSync as openSync12, readSync as readSync8 } from "fs";
49465
- import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute12, resolve as resolve13 } from "path";
49501
+ import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync16, openSync as openSync12, readSync as readSync8 } from "fs";
49502
+ import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute12, resolve as resolve14 } from "path";
49466
49503
  function need5(value, reason) {
49467
49504
  if (!value)
49468
49505
  throw new Error(`Claude marketplace registry ${reason}`);
49469
49506
  }
49470
49507
  function absolutePath2(value) {
49471
- need5(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve13(value) === value, "requires a normalized absolute path");
49508
+ need5(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve14(value) === value, "requires a normalized absolute path");
49472
49509
  }
49473
49510
  function parents2(path) {
49474
49511
  const result = [];
49475
49512
  for (let at = dirname13(path);; at = dirname13(at)) {
49476
- const stat2 = lstatSync15(at, { bigint: true });
49513
+ const stat2 = lstatSync16(at, { bigint: true });
49477
49514
  need5(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
49478
49515
  result.push([at, stat2]);
49479
49516
  if (at === dirname13(at))
@@ -49484,7 +49521,7 @@ function readRegistry2(path, budget) {
49484
49521
  absolutePath2(path);
49485
49522
  need5(basename7(path) === "known_marketplaces.json", "requires known_marketplaces.json");
49486
49523
  need5(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
49487
- const ancestors2 = parents2(path), initial = lstatSync15(path, { bigint: true });
49524
+ const ancestors2 = parents2(path), initial = lstatSync16(path, { bigint: true });
49488
49525
  need5(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
49489
49526
  need5(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
49490
49527
  const fd = openSync12(path, constants9.O_RDONLY | constants9.O_NOFOLLOW | constants9.O_NONBLOCK);
@@ -49499,10 +49536,10 @@ function readRegistry2(path, budget) {
49499
49536
  break;
49500
49537
  length += count;
49501
49538
  }
49502
- const after = fstatSync12(fd, { bigint: true }), current = lstatSync15(path, { bigint: true });
49539
+ const after = fstatSync12(fd, { bigint: true }), current = lstatSync16(path, { bigint: true });
49503
49540
  need5(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
49504
49541
  for (const [ancestor, before] of ancestors2) {
49505
- const now = lstatSync15(ancestor, { bigint: true });
49542
+ const now = lstatSync16(ancestor, { bigint: true });
49506
49543
  need5(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
49507
49544
  }
49508
49545
  budget.remaining -= length;
@@ -49642,7 +49679,7 @@ var init_claude_marketplace_registry = __esm(() => {
49642
49679
  });
49643
49680
 
49644
49681
  // src/lib/codex-hook-trust-files.ts
49645
- import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, fsyncSync as fsyncSync3, lstatSync as lstatSync16, openSync as openSync13, readSync as readSync9, writeFileSync as writeFileSync5 } from "fs";
49682
+ import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, fsyncSync as fsyncSync3, lstatSync as lstatSync17, openSync as openSync13, readSync as readSync9, writeFileSync as writeFileSync5 } from "fs";
49646
49683
  import { createHash as createHash14 } from "crypto";
49647
49684
  import { dirname as dirname14 } from "path";
49648
49685
  function need6(value, code) {
@@ -49651,7 +49688,7 @@ function need6(value, code) {
49651
49688
  }
49652
49689
  function safeParents(file2) {
49653
49690
  for (let p = dirname14(file2);; p = dirname14(p)) {
49654
- const s = lstatSync16(p);
49691
+ const s = lstatSync17(p);
49655
49692
  need6(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
49656
49693
  need6((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
49657
49694
  if (dirname14(p) === p)
@@ -49661,7 +49698,7 @@ function safeParents(file2) {
49661
49698
  function snapshot(file2, privateFile = false, options = {}) {
49662
49699
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
49663
49700
  safeParents(file2);
49664
- const initial = lstatSync16(file2, { bigint: true });
49701
+ const initial = lstatSync17(file2, { bigint: true });
49665
49702
  need6(initial.isFile() && initial.uid === BigInt(process.getuid()) && (initial.nlink === 1n || readOnlyPackage && initial.nlink > 1n) && (initial.mode & 0o022n) === 0n && (!privateFile || (initial.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
49666
49703
  need6(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
49667
49704
  const fd = openSync13(file2, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
@@ -49676,7 +49713,7 @@ function snapshot(file2, privateFile = false, options = {}) {
49676
49713
  break;
49677
49714
  length += n2;
49678
49715
  }
49679
- need6(length === Number(before.size) && sameStat(before, fstatSync13(fd, { bigint: true })) && sameStat(before, lstatSync16(file2, { bigint: true })), "INPUT_CHANGED");
49716
+ need6(length === Number(before.size) && sameStat(before, fstatSync13(fd, { bigint: true })) && sameStat(before, lstatSync17(file2, { bigint: true })), "INPUT_CHANGED");
49680
49717
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
49681
49718
  return { file: file2, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash14("sha256").update(content).digest("hex") };
49682
49719
  } finally {
@@ -49731,8 +49768,8 @@ var init_codex_hook_discovery_recovery = __esm(() => {
49731
49768
 
49732
49769
  // src/lib/agent-discovery.ts
49733
49770
  import { createHash as createHash16 } from "crypto";
49734
- import { lstatSync as lstatSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync4 } from "fs";
49735
- import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute13, join as join24, resolve as resolve14, sep as sep5 } from "path";
49771
+ import { lstatSync as lstatSync18, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync5 } from "fs";
49772
+ import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute13, join as join25, resolve as resolve15, sep as sep5 } from "path";
49736
49773
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
49737
49774
  function parseConfig(text2, path, toml = false) {
49738
49775
  try {
@@ -49748,7 +49785,7 @@ function safe4(path) {
49748
49785
  if (!isAbsolute13(path) || path.includes("\x00"))
49749
49786
  throw new Error("Expected an absolute native discovery path");
49750
49787
  for (let cursor = path;; cursor = dirname15(cursor)) {
49751
- if (lstatSync17(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
49788
+ if (lstatSync18(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
49752
49789
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
49753
49790
  if (dirname15(cursor) === cursor)
49754
49791
  break;
@@ -49758,7 +49795,7 @@ function read(path, changes) {
49758
49795
  safe4(path);
49759
49796
  if (changes?.has(path))
49760
49797
  return changes.get(path);
49761
- const stat2 = lstatSync17(path, { throwIfNoEntry: false });
49798
+ const stat2 = lstatSync18(path, { throwIfNoEntry: false });
49762
49799
  if (!stat2)
49763
49800
  return null;
49764
49801
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
@@ -49869,12 +49906,12 @@ function codexInstallationRoots(binding) {
49869
49906
  if (binding.agent !== "codex" || binding.method !== "reviewed" || proof.version !== "codex-cli 0.160.0" || !/^[a-f0-9]{64}$/.test(proof.catalogSha256) || !Array.isArray(proof.plugins) || !proof.plugins.length)
49870
49907
  throw new Error("Invalid native installation input proof");
49871
49908
  const cache = dirname15(dirname15(proof.plugins[0].pluginParent));
49872
- const config2 = join24(dirname15(dirname15(cache)), "config.toml"), home = dirname15(dirname15(dirname15(cache)));
49909
+ const config2 = join25(dirname15(dirname15(cache)), "config.toml"), home = dirname15(dirname15(dirname15(cache)));
49873
49910
  const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
49874
- const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join24(home, path));
49911
+ const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join25(home, path));
49875
49912
  if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep5) || input2.sourceRoot.startsWith(root + sep5)) || binding.sources.some((source) => basename8(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep5)))))
49876
49913
  throw new Error("Native installation input overlaps configuration or loading roots");
49877
- if (proof.plugins.some((input2) => dirname15(dirname15(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join24(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
49914
+ if (proof.plugins.some((input2) => dirname15(dirname15(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join25(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
49878
49915
  throw new Error("Missing native installation input source witness");
49879
49916
  return reviewedCodexPluginSourceRoots(cache, proof.plugins, (path) => {
49880
49917
  const text2 = read(path);
@@ -49892,10 +49929,12 @@ function assertMarketplaceBinding(binding, source) {
49892
49929
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
49893
49930
  }
49894
49931
  function agentDiscoveryConfigPath(home, agent) {
49895
- return join24(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
49932
+ if (agent === "sumi")
49933
+ return sumiConfigPath(home);
49934
+ return join25(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
49896
49935
  }
49897
49936
  function resolveAgentDiscovery(options) {
49898
- const canonical6 = options.canonical ?? resolve14, home = resolve14(options.home), agent = options.agent;
49937
+ const canonical6 = options.canonical ?? resolve15, home = resolve15(options.home), agent = options.agent;
49899
49938
  const sources = [], roots = new Set, builtinNames = [];
49900
49939
  const witness = (path, format, fields2) => {
49901
49940
  const source = { path: canonical6(path), sha256: null, ...format ? { format, fields: fields2 } : {} };
@@ -49906,13 +49945,49 @@ function resolveAgentDiscovery(options) {
49906
49945
  if (agent === "hermes")
49907
49946
  assertHermesEnvironment(home);
49908
49947
  const configPath = agentDiscoveryConfigPath(home, agent);
49909
- const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : ["version"]);
49948
+ const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : agent === "sumi" ? ["skills", "plugin", "plugins", "permissions"] : ["version"]);
49910
49949
  const config2 = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
49911
49950
  const unresolved = (detail) => {
49912
49951
  throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
49913
49952
  };
49953
+ if (agent === "sumi") {
49954
+ const directory = sumiConfigDirectory(home);
49955
+ if (witness(join25(directory, "sumi.jsonc")) !== null)
49956
+ unresolved("JSONC configuration requires a supported format adapter");
49957
+ for (const root of [directory, join25(home, ".claude"), join25(home, ".agents")])
49958
+ for (const name of ["skill", "skills"])
49959
+ roots.add(join25(root, name));
49960
+ if (config2.skills !== undefined && (!Array.isArray(config2.skills) || config2.skills.some((path) => typeof path !== "string")))
49961
+ unresolved("skills must be a string array");
49962
+ for (const value of config2.skills ?? []) {
49963
+ if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute13(value) || value.startsWith("~/")))
49964
+ unresolved("remote or relative skill sources need a dedicated discovery adapter");
49965
+ roots.add(value.startsWith("~/") ? join25(home, value.slice(2)) : value);
49966
+ }
49967
+ for (const key of ["plugin", "plugins"])
49968
+ if (config2[key] !== undefined && !Array.isArray(config2[key]))
49969
+ unresolved(`${key} must be an array`);
49970
+ const plugins = [join25(directory, "plugin"), join25(directory, "plugins")];
49971
+ for (const path of plugins) {
49972
+ safe4(path);
49973
+ if (lstatSync18(path, { throwIfNoEntry: false })?.isDirectory())
49974
+ for (const name of readdirSync7(path).sort()) {
49975
+ if (name === "skills-cli.js" && path === plugins[1])
49976
+ continue;
49977
+ const target = join25(path, name);
49978
+ if (!lstatSync18(target).isFile())
49979
+ unresolved("local plugin packages need a dedicated discovery adapter");
49980
+ witness(target);
49981
+ }
49982
+ }
49983
+ for (const root of roots) {
49984
+ safe4(root);
49985
+ if (lstatSync18(root, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(root).some((name) => name.endsWith(".md")))
49986
+ unresolved("flat markdown skills require a dedicated native migration adapter");
49987
+ }
49988
+ }
49914
49989
  if (agent === "hermes") {
49915
- const profile = witness(join24(home, ".hermes/active_profile"));
49990
+ const profile = witness(join25(home, ".hermes/active_profile"));
49916
49991
  if (profile?.trim() && profile.trim() !== "default")
49917
49992
  unresolved("a non-default profile is active");
49918
49993
  const declared = config2.skills?.external_dirs ?? [], paths = typeof declared === "string" ? [declared] : declared;
@@ -49926,7 +50001,7 @@ function resolveAgentDiscovery(options) {
49926
50001
  continue;
49927
50002
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
49928
50003
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
49929
- const path = normalized === "~" ? home : normalized.startsWith("~/") ? join24(home, normalized.slice(2)) : resolve14(home, ".hermes", normalized);
50004
+ const path = normalized === "~" ? home : normalized.startsWith("~/") ? join25(home, normalized.slice(2)) : resolve15(home, ".hermes", normalized);
49930
50005
  safe4(path);
49931
50006
  roots.add(path);
49932
50007
  }
@@ -49935,8 +50010,8 @@ function resolveAgentDiscovery(options) {
49935
50010
  const executable = Bun.which("gemini");
49936
50011
  if (executable) {
49937
50012
  let packageRoot;
49938
- for (let directory = dirname15(realpathSync4(executable)), depth = 0;depth < 8; directory = dirname15(directory), depth++) {
49939
- const path = join24(directory, "package.json"), raw = read(path);
50013
+ for (let directory = dirname15(realpathSync5(executable)), depth = 0;depth < 8; directory = dirname15(directory), depth++) {
50014
+ const path = join25(directory, "package.json"), raw = read(path);
49940
50015
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
49941
50016
  packageRoot = directory;
49942
50017
  witness(path);
@@ -49947,12 +50022,12 @@ function resolveAgentDiscovery(options) {
49947
50022
  }
49948
50023
  if (!packageRoot)
49949
50024
  unresolved("installed Gemini package layout is not recognized");
49950
- const builtinRoot = join24(packageRoot, "bundle/builtin");
50025
+ const builtinRoot = join25(packageRoot, "bundle/builtin");
49951
50026
  safe4(builtinRoot);
49952
- if (!lstatSync17(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
50027
+ if (!lstatSync18(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
49953
50028
  unresolved("installed Gemini builtin root is missing");
49954
50029
  for (const name of readdirSync7(builtinRoot).sort()) {
49955
- const text2 = witness(join24(builtinRoot, name, "SKILL.md"));
50030
+ const text2 = witness(join25(builtinRoot, name, "SKILL.md"));
49956
50031
  const match = text2?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
49957
50032
  if (!match?.[1] || builtinNames.includes(match[1]))
49958
50033
  unresolved("installed Gemini builtin name is missing or ambiguous");
@@ -49994,39 +50069,39 @@ function resolveAgentDiscovery(options) {
49994
50069
  function plugin(root) {
49995
50070
  root = canonical6(root);
49996
50071
  safe4(root);
49997
- const manifestPath = join24(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
50072
+ const manifestPath = join25(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
49998
50073
  const raw = witness(manifestPath);
49999
50074
  if (raw === null)
50000
50075
  unresolved("plugin manifest missing");
50001
50076
  const manifest = parseConfig(raw, manifestPath);
50002
- const hooks = witness(join24(root, "hooks/hooks.json"));
50077
+ const hooks = witness(join25(root, "hooks/hooks.json"));
50003
50078
  if (manifest.hooks !== undefined || hooks !== null)
50004
50079
  unresolved("plugin hooks require a separate no-skill-injection review");
50005
- const commands = join24(root, "commands");
50080
+ const commands = join25(root, "commands");
50006
50081
  safe4(commands);
50007
- if (agent === "claude" && (manifest.commands !== undefined || lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length))
50082
+ if (agent === "claude" && (manifest.commands !== undefined || lstatSync18(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length))
50008
50083
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
50009
- const rootSkill = witness(join24(root, "SKILL.md"));
50084
+ const rootSkill = witness(join25(root, "SKILL.md"));
50010
50085
  if (rootSkill !== null)
50011
50086
  roots.add(root);
50012
50087
  const declared = manifest.skills === undefined ? ["./skills"] : typeof manifest.skills === "string" ? [manifest.skills] : manifest.skills;
50013
50088
  if (!Array.isArray(declared) || declared.some((path) => typeof path !== "string"))
50014
50089
  unresolved("unsupported plugin skill paths");
50015
50090
  if (agent === "claude")
50016
- roots.add(join24(root, "skills"));
50091
+ roots.add(join25(root, "skills"));
50017
50092
  for (const value of declared) {
50018
- const path = resolve14(root, value);
50093
+ const path = resolve15(root, value);
50019
50094
  if (path !== root && !path.startsWith(root + sep5))
50020
50095
  unresolved("plugin skill path escapes its root");
50021
50096
  roots.add(path.endsWith(`${sep5}SKILL.md`) ? dirname15(path) : path);
50022
50097
  }
50023
50098
  }
50024
50099
  if (agent === "claude") {
50025
- const registrations = witness(join24(home, ".claude/plugins/installed_plugins.json"));
50026
- const installed = registrations === null ? {} : parseConfig(registrations, join24(home, ".claude/plugins/installed_plugins.json")).plugins;
50027
- const commands = canonical6(join24(home, ".claude/commands"));
50100
+ const registrations = witness(join25(home, ".claude/plugins/installed_plugins.json"));
50101
+ const installed = registrations === null ? {} : parseConfig(registrations, join25(home, ".claude/plugins/installed_plugins.json")).plugins;
50102
+ const commands = canonical6(join25(home, ".claude/commands"));
50028
50103
  safe4(commands);
50029
- if (lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
50104
+ if (lstatSync18(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
50030
50105
  unresolved("legacy home command discovery requires a dedicated format adapter");
50031
50106
  for (const [id, enabled] of Object.entries(config2.enabledPlugins ?? {})) {
50032
50107
  if (enabled === false)
@@ -50048,16 +50123,16 @@ function resolveAgentDiscovery(options) {
50048
50123
  const market = config2.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
50049
50124
  if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute13(market.source))
50050
50125
  unresolved("enabled plugin marketplace is not an explicit local source");
50051
- const catalogText = witness(join24(market.source, ".agents/plugins/marketplace.json"));
50126
+ const catalogText = witness(join25(market.source, ".agents/plugins/marketplace.json"));
50052
50127
  if (catalogText === null)
50053
50128
  unresolved("marketplace catalog missing");
50054
- const catalog = parseConfig(catalogText, join24(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
50129
+ const catalog = parseConfig(catalogText, join25(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
50055
50130
  if (matches.length !== 1 || matches[0]?.source?.source !== "local" || typeof matches[0]?.source?.path !== "string")
50056
50131
  unresolved("plugin catalog source is missing or ambiguous");
50057
- plugin(resolve14(market.source, matches[0].source.path));
50132
+ plugin(resolve15(market.source, matches[0].source.path));
50058
50133
  }
50059
50134
  } else if (agent === "opencode") {
50060
- if (witness(join24(home, ".config/opencode/opencode.jsonc")) !== null || witness(join24(home, ".config/opencode/config.json")) !== null)
50135
+ if (witness(join25(home, ".config/opencode/opencode.jsonc")) !== null || witness(join25(home, ".config/opencode/config.json")) !== null)
50061
50136
  unresolved("additional config layers require review");
50062
50137
  if ((config2.plugin?.length ?? 0) > 0 || config2.skills?.urls?.length)
50063
50138
  unresolved("external plugin or remote skill source");
@@ -50066,14 +50141,17 @@ function resolveAgentDiscovery(options) {
50066
50141
  unresolved("relative or malformed added skill root");
50067
50142
  roots.add(path);
50068
50143
  }
50069
- const localPlugins = join24(home, ".config/opencode/plugins");
50144
+ const localPlugins = join25(home, ".config/opencode/plugins");
50070
50145
  safe4(localPlugins);
50071
- if (lstatSync17(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
50146
+ if (lstatSync18(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
50072
50147
  unresolved("additional local plugin hooks require review");
50148
+ } else if (agent === "sumi") {
50149
+ if ((config2.plugin?.length ?? 0) > 0 || (config2.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical6(configPath) && source.path !== canonical6(join25(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
50150
+ unresolved("external or foreign local plugins require review");
50073
50151
  } else if (agent === "hermes") {
50074
- for (const directory of [join24(home, ".hermes/plugins"), join24(home, ".hermes/hermes-agent")]) {
50152
+ for (const directory of [join25(home, ".hermes/plugins"), join25(home, ".hermes/hermes-agent")]) {
50075
50153
  safe4(directory);
50076
- if (lstatSync17(directory, { throwIfNoEntry: false }))
50154
+ if (lstatSync18(directory, { throwIfNoEntry: false }))
50077
50155
  unresolved("installed runtime/plugin discovery requires reviewed source bindings");
50078
50156
  }
50079
50157
  if (Bun.which("hermes") || Object.keys(config2.plugins ?? {}).length)
@@ -50081,24 +50159,24 @@ function resolveAgentDiscovery(options) {
50081
50159
  } else if (agent === "gemini") {
50082
50160
  if (Object.keys(config2.extensions ?? {}).length || config2.skills?.paths?.length)
50083
50161
  unresolved("custom extension or skill paths");
50084
- const directory = join24(home, ".gemini/extensions");
50162
+ const directory = join25(home, ".gemini/extensions");
50085
50163
  safe4(directory);
50086
- if (lstatSync17(directory, { throwIfNoEntry: false }))
50164
+ if (lstatSync18(directory, { throwIfNoEntry: false }))
50087
50165
  for (const name of readdirSync7(directory)) {
50088
- const root = join24(directory, name);
50166
+ const root = join25(directory, name);
50089
50167
  safe4(root);
50090
- if (!lstatSync17(root)?.isDirectory())
50168
+ if (!lstatSync18(root)?.isDirectory())
50091
50169
  continue;
50092
- const raw = witness(join24(root, "gemini-extension.json"));
50170
+ const raw = witness(join25(root, "gemini-extension.json"));
50093
50171
  if (raw === null)
50094
50172
  unresolved("extension registration missing");
50095
- const manifest = parseConfig(raw, join24(root, "gemini-extension.json"));
50096
- if (manifest.hooks !== undefined || witness(join24(root, "hooks/hooks.json")) !== null || witness(join24(root, ".gemini-extension-install.json")) !== null)
50173
+ const manifest = parseConfig(raw, join25(root, "gemini-extension.json"));
50174
+ if (manifest.hooks !== undefined || witness(join25(root, "hooks/hooks.json")) !== null || witness(join25(root, ".gemini-extension-install.json")) !== null)
50097
50175
  unresolved("extension hooks or linked registration require review");
50098
- roots.add(join24(root, "skills"));
50176
+ roots.add(join25(root, "skills"));
50099
50177
  }
50100
50178
  }
50101
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join24(home, ".hermes/plugins"), join24(home, ".hermes/hermes-agent")].map((path) => canonical6(path))) } : {} };
50179
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join25(home, ".hermes/plugins"), join25(home, ".hermes/hermes-agent")].map((path) => canonical6(path))) } : {} };
50102
50180
  }
50103
50181
  var digest = (text2) => createHash16("sha256").update(text2).digest("hex");
50104
50182
  var init_agent_discovery = __esm(() => {
@@ -50114,16 +50192,17 @@ var init_agent_discovery = __esm(() => {
50114
50192
  init_codex_hook_discovery_recovery();
50115
50193
  init_codex_settings_witness();
50116
50194
  init_codex_plugin_skill_controls();
50195
+ init_agent_sumi();
50117
50196
  init_native_discovery_roots();
50118
50197
  init_agent_discovery_directories();
50119
50198
  });
50120
50199
 
50121
50200
  // src/lib/authoring-path.ts
50122
- import { lstatSync as lstatSync18, realpathSync as realpathSync5 } from "fs";
50201
+ import { lstatSync as lstatSync19, realpathSync as realpathSync6 } from "fs";
50123
50202
  import { homedir as homedir3 } from "os";
50124
- import { basename as basename9, dirname as dirname16, join as join25, resolve as resolve15, sep as sep6 } from "path";
50203
+ import { basename as basename9, dirname as dirname16, join as join26, resolve as resolve16, sep as sep6 } from "path";
50125
50204
  function pathParts(path) {
50126
- return resolve15(path).split(sep6).filter(Boolean);
50205
+ return resolve16(path).split(sep6).filter(Boolean);
50127
50206
  }
50128
50207
  function nativeRootMatch(path) {
50129
50208
  const parts = pathParts(path);
@@ -50137,24 +50216,24 @@ function nativeRootMatch(path) {
50137
50216
  return;
50138
50217
  }
50139
50218
  function physicalPath(path) {
50140
- let cursor = resolve15(path);
50219
+ let cursor = resolve16(path);
50141
50220
  const suffix = [];
50142
- while (!lstatSync18(cursor, { throwIfNoEntry: false })) {
50221
+ while (!lstatSync19(cursor, { throwIfNoEntry: false })) {
50143
50222
  suffix.unshift(basename9(cursor));
50144
50223
  const parent = dirname16(cursor);
50145
50224
  if (parent === cursor)
50146
- return resolve15(path);
50225
+ return resolve16(path);
50147
50226
  cursor = parent;
50148
50227
  }
50149
- return resolve15(realpathSync5(cursor), ...suffix);
50228
+ return resolve16(realpathSync6(cursor), ...suffix);
50150
50229
  }
50151
50230
  function contains(root, path) {
50152
50231
  return path === root || path.startsWith(root + sep6);
50153
50232
  }
50154
50233
  function configuredRoots(home, explicitHome) {
50155
- const homeData = join25(home, ".hasna", "skills");
50234
+ const homeData = join26(home, ".hasna", "skills");
50156
50235
  const homePolicy = readManagedSkillPolicySnapshot(homeData);
50157
- const configuredPolicy = !explicitHome && resolve15(getDataDirReadOnly()) !== resolve15(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
50236
+ const configuredPolicy = !explicitHome && resolve16(getDataDirReadOnly()) !== resolve16(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
50158
50237
  const policy = homePolicy ?? configuredPolicy;
50159
50238
  const bridge = policy?.value.bridge;
50160
50239
  if (bridge && (typeof bridge.home !== "string" || physicalPath(bridge.home) !== physicalPath(home))) {
@@ -50183,8 +50262,8 @@ function configuredRoots(home, explicitHome) {
50183
50262
  admitBinding(binding);
50184
50263
  continue;
50185
50264
  }
50186
- const nativeHome = join25(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
50187
- if (!lstatSync18(nativeHome, { throwIfNoEntry: false }))
50265
+ const nativeHome = join26(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
50266
+ if (!lstatSync19(nativeHome, { throwIfNoEntry: false }))
50188
50267
  continue;
50189
50268
  roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
50190
50269
  }
@@ -50193,22 +50272,22 @@ function configuredRoots(home, explicitHome) {
50193
50272
  function assertPortableAuthoringPath(path, options = {}) {
50194
50273
  if (typeof path !== "string" || !path || path.includes("\x00"))
50195
50274
  throw new Error("Invalid portable authoring path");
50196
- const lexical = resolve15(path);
50275
+ const lexical = resolve16(path);
50197
50276
  const physical = physicalPath(lexical);
50198
50277
  const candidates = [lexical, physical];
50199
50278
  let native = candidates.map(nativeRootMatch).find(Boolean);
50200
- const home = resolve15(options.homeDir ?? homedir3());
50201
- const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join25(home, ...parts));
50202
- defaults.push(join25(home, ".codex/plugins/cache"), join25(home, ".claude/plugins/cache"), join25(home, ".claude/plugins/synced"), join25(home, ".gemini/extensions"));
50279
+ const home = resolve16(options.homeDir ?? homedir3());
50280
+ const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join26(home, ...parts));
50281
+ defaults.push(join26(home, ".codex/plugins/cache"), join26(home, ".claude/plugins/cache"), join26(home, ".claude/plugins/synced"), join26(home, ".gemini/extensions"));
50203
50282
  for (const root of defaults) {
50204
- if (candidates.some((candidate) => contains(resolve15(root), candidate) || contains(physicalPath(root), candidate)))
50283
+ if (candidates.some((candidate) => contains(resolve16(root), candidate) || contains(physicalPath(root), candidate)))
50205
50284
  native ??= root;
50206
50285
  }
50207
50286
  if (native) {
50208
50287
  throw new Error(`Refusing portable Skills authoring below native discovery root '${native}': ${lexical}. Set HASNA_SKILLS_DIR to a private authoring corpus outside native roots.`);
50209
50288
  }
50210
50289
  for (const root of configuredRoots(home, options.homeDir !== undefined)) {
50211
- if (candidates.some((candidate) => contains(resolve15(root), candidate) || contains(physicalPath(root), candidate))) {
50290
+ if (candidates.some((candidate) => contains(resolve16(root), candidate) || contains(physicalPath(root), candidate))) {
50212
50291
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
50213
50292
  }
50214
50293
  }
@@ -50225,32 +50304,32 @@ var init_authoring_path = __esm(() => {
50225
50304
 
50226
50305
  // src/lib/portable-skills.ts
50227
50306
  import {
50228
- existsSync as existsSync11,
50307
+ existsSync as existsSync12,
50229
50308
  mkdirSync as mkdirSync7,
50230
50309
  mkdtempSync,
50231
50310
  readdirSync as readdirSync8,
50232
- realpathSync as realpathSync6,
50311
+ realpathSync as realpathSync7,
50233
50312
  renameSync as renameSync3,
50234
50313
  rmSync as rmSync3,
50235
50314
  statSync as statSync7,
50236
50315
  writeFileSync as writeFileSync6
50237
50316
  } from "fs";
50238
- import { basename as basename10, dirname as dirname17, isAbsolute as isAbsolute14, join as join26, normalize as normalize3, relative as relative5, resolve as resolve16, sep as sep7 } from "path";
50317
+ import { basename as basename10, dirname as dirname17, isAbsolute as isAbsolute14, join as join27, normalize as normalize3, relative as relative5, resolve as resolve17, sep as sep7 } from "path";
50239
50318
  function getPortableSkillsRoot(options = {}) {
50240
50319
  return resolvePortableSkillsRoot(options, true);
50241
50320
  }
50242
50321
  function resolvePortableSkillsRoot(options, migrate) {
50243
50322
  if (options.rootDir)
50244
50323
  return options.rootDir;
50245
- const appDir = options.homeDir ? join26(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
50246
- const cache = join26(appDir, SKILLS_CACHE_DIRNAME);
50324
+ const appDir = options.homeDir ? join27(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
50325
+ const cache = join27(appDir, SKILLS_CACHE_DIRNAME);
50247
50326
  if (isOwnerLayoutMigrated(appDir) && safeIsDirectory(cache))
50248
50327
  return cache;
50249
- const installed = join26(appDir, INSTALLED_SKILLS_DIRNAME);
50328
+ const installed = join27(appDir, INSTALLED_SKILLS_DIRNAME);
50250
50329
  return installed;
50251
50330
  }
50252
50331
  function getPortableSkillPath(name, options = {}) {
50253
- return join26(getPortableSkillsRoot(options), normalizePortableSkillName(name));
50332
+ return join27(getPortableSkillsRoot(options), normalizePortableSkillName(name));
50254
50333
  }
50255
50334
  function findPortableSkill(name, options = {}) {
50256
50335
  let normalized;
@@ -50260,7 +50339,7 @@ function findPortableSkill(name, options = {}) {
50260
50339
  return null;
50261
50340
  }
50262
50341
  const path = getPortableSkillPath(normalized, options);
50263
- if (!existsSync11(path) || !statSync7(path).isDirectory())
50342
+ if (!existsSync12(path) || !statSync7(path).isDirectory())
50264
50343
  return null;
50265
50344
  try {
50266
50345
  return summarizePortableSkill(path, normalized);
@@ -50276,7 +50355,7 @@ function listPortableSkills(options = {}) {
50276
50355
  for (const entry of readdirSync8(root).sort()) {
50277
50356
  if (entry.startsWith("."))
50278
50357
  continue;
50279
- const path = join26(root, entry);
50358
+ const path = join27(root, entry);
50280
50359
  if (!safeIsDirectory(path))
50281
50360
  continue;
50282
50361
  try {
@@ -50309,11 +50388,11 @@ function isOfficialSkillName(name) {
50309
50388
  function scaffoldPortableSkill(name, options = {}) {
50310
50389
  const skillName = normalizeNewPortableSkillName(name);
50311
50390
  const readOnlyRoot = resolvePortableSkillsRoot(options, false);
50312
- assertPortableAuthoringPath(join26(readOnlyRoot, skillName), options);
50391
+ assertPortableAuthoringPath(join27(readOnlyRoot, skillName), options);
50313
50392
  const root = getPortableSkillsRoot(options);
50314
- const skillPath = join26(root, skillName);
50393
+ const skillPath = join27(root, skillName);
50315
50394
  assertPortableAuthoringPath(skillPath, options);
50316
- if (existsSync11(skillPath)) {
50395
+ if (existsSync12(skillPath)) {
50317
50396
  if (!options.overwrite)
50318
50397
  throw new Error(`Skill '${skillName}' already exists at ${skillPath}`);
50319
50398
  rmSync3(skillPath, { recursive: true, force: true });
@@ -50330,16 +50409,16 @@ function scaffoldPortableSkill(name, options = {}) {
50330
50409
  return { name: skillName, path: skillPath, manifest, created: true };
50331
50410
  }
50332
50411
  function physicalImportPath(path) {
50333
- let ancestor = resolve16(path);
50412
+ let ancestor = resolve17(path);
50334
50413
  const suffix = [];
50335
- while (!existsSync11(ancestor)) {
50414
+ while (!existsSync12(ancestor)) {
50336
50415
  suffix.unshift(basename10(ancestor));
50337
50416
  ancestor = dirname17(ancestor);
50338
50417
  }
50339
- return join26(realpathSync6(ancestor), ...suffix);
50418
+ return join27(realpathSync7(ancestor), ...suffix);
50340
50419
  }
50341
50420
  function assertDisjointImportPaths(source, destination) {
50342
- const sourcePath = realpathSync6(source);
50421
+ const sourcePath = realpathSync7(source);
50343
50422
  const destinationPath = physicalImportPath(destination);
50344
50423
  const contains2 = (parent, child) => {
50345
50424
  const path = relative5(parent, child);
@@ -50351,7 +50430,7 @@ function assertDisjointImportPaths(source, destination) {
50351
50430
  }
50352
50431
  function portPortableSkill(sourcePath, options = {}) {
50353
50432
  const absoluteSource = normalize3(sourcePath);
50354
- if (!existsSync11(absoluteSource) || !statSync7(absoluteSource).isDirectory()) {
50433
+ if (!existsSync12(absoluteSource) || !statSync7(absoluteSource).isDirectory()) {
50355
50434
  throw new Error(`Skill source directory not found: ${sourcePath}`);
50356
50435
  }
50357
50436
  const inferred = readPortableSkillManifestForImport(absoluteSource);
@@ -50362,14 +50441,14 @@ function portPortableSkill(sourcePath, options = {}) {
50362
50441
  const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename10(absoluteSource)}')` : ""} matches a bundled official skill.`;
50363
50442
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
50364
50443
  }
50365
- const readOnlyDestination = join26(resolvePortableSkillsRoot(options, false), skillName);
50444
+ const readOnlyDestination = join27(resolvePortableSkillsRoot(options, false), skillName);
50366
50445
  assertPortableAuthoringPath(readOnlyDestination, options);
50367
50446
  assertDisjointImportPaths(absoluteSource, readOnlyDestination);
50368
50447
  const root = getPortableSkillsRoot(options);
50369
- const destination = join26(root, skillName);
50448
+ const destination = join27(root, skillName);
50370
50449
  assertPortableAuthoringPath(destination, options);
50371
50450
  assertDisjointImportPaths(absoluteSource, destination);
50372
- if (existsSync11(destination)) {
50451
+ if (existsSync12(destination)) {
50373
50452
  if (!options.overwrite)
50374
50453
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
50375
50454
  rmSync3(destination, { recursive: true, force: true });
@@ -50397,10 +50476,10 @@ function validatePortableSkillDirectory(name, skillPath) {
50397
50476
  const issues = [...base.issues];
50398
50477
  const warnings = [...base.warnings];
50399
50478
  let manifest;
50400
- if (existsSync11(skillPath)) {
50401
- const skillJsonPath = join26(skillPath, "skill.json");
50402
- const skillMdPath = join26(skillPath, "SKILL.md");
50403
- if (!existsSync11(skillJsonPath) && !existsSync11(skillMdPath)) {
50479
+ if (existsSync12(skillPath)) {
50480
+ const skillJsonPath = join27(skillPath, "skill.json");
50481
+ const skillMdPath = join27(skillPath, "SKILL.md");
50482
+ if (!existsSync12(skillJsonPath) && !existsSync12(skillMdPath)) {
50404
50483
  add3(issues, "portable.manifest_missing", "Missing portable manifest: expected SKILL.md frontmatter and/or skill.json");
50405
50484
  }
50406
50485
  try {
@@ -50419,7 +50498,7 @@ function validatePortableSkillDirectory(name, skillPath) {
50419
50498
  add3(issues, "portable.version_missing", "Portable manifest missing version");
50420
50499
  }
50421
50500
  const contractIssues = validatePortableManifestContract(manifest, {
50422
- strict: existsSync11(join26(skillPath, "skill.json")),
50501
+ strict: existsSync12(join27(skillPath, "skill.json")),
50423
50502
  skillPath
50424
50503
  });
50425
50504
  for (const issue2 of contractIssues)
@@ -50459,8 +50538,8 @@ function validatePortableSkillDirectory(name, skillPath) {
50459
50538
  add3(issues, "portable.command_entry_unsafe", `Command '${command.name}' entry '${command.entry}' must stay inside the skill directory`);
50460
50539
  continue;
50461
50540
  }
50462
- const entryPath = join26(skillPath, command.entry);
50463
- if (!existsSync11(entryPath))
50541
+ const entryPath = join27(skillPath, command.entry);
50542
+ if (!existsSync12(entryPath))
50464
50543
  add3(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
50465
50544
  else if (statSync7(entryPath).isDirectory())
50466
50545
  add3(issues, "portable.command_entry_directory", `Command '${command.name}' entry '${command.entry}' must be a file`);
@@ -50470,7 +50549,7 @@ function validatePortableSkillDirectory(name, skillPath) {
50470
50549
  } catch (error61) {
50471
50550
  add3(issues, "portable.manifest_invalid", error61.message);
50472
50551
  }
50473
- if (manifest?.kind !== "instruction" && !existsSync11(join26(skillPath, "AGENTS.md"))) {
50552
+ if (manifest?.kind !== "instruction" && !existsSync12(join27(skillPath, "AGENTS.md"))) {
50474
50553
  add3(issues, "portable.agents_missing", "Missing AGENTS.md with build-out instructions for coding agents");
50475
50554
  }
50476
50555
  }
@@ -50697,8 +50776,8 @@ var init_search = __esm(() => {
50697
50776
  });
50698
50777
 
50699
50778
  // src/lib/registry.ts
50700
- import { existsSync as existsSync12, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "fs";
50701
- import { join as join27 } from "path";
50779
+ import { existsSync as existsSync13, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "fs";
50780
+ import { join as join28 } from "path";
50702
50781
  function parseSkillMdFrontmatter(content) {
50703
50782
  const match = content.match(/^---\n([\s\S]*?)\n---/);
50704
50783
  if (!match)
@@ -50731,7 +50810,7 @@ function parseSkillMdFrontmatter(content) {
50731
50810
  return Object.keys(result).length > 0 ? result : null;
50732
50811
  }
50733
50812
  function discoverSkillsInDir(dir, source = "custom") {
50734
- if (!existsSync12(dir))
50813
+ if (!existsSync13(dir))
50735
50814
  return [];
50736
50815
  const result = [];
50737
50816
  try {
@@ -50739,8 +50818,8 @@ function discoverSkillsInDir(dir, source = "custom") {
50739
50818
  for (const entry of entries) {
50740
50819
  if (!entry.isDirectory())
50741
50820
  continue;
50742
- const skillMdPath = join27(dir, entry.name, "SKILL.md");
50743
- if (!existsSync12(skillMdPath))
50821
+ const skillMdPath = join28(dir, entry.name, "SKILL.md");
50822
+ if (!existsSync13(skillMdPath))
50744
50823
  continue;
50745
50824
  let content;
50746
50825
  try {
@@ -50759,7 +50838,7 @@ function discoverSkillsInDir(dir, source = "custom") {
50759
50838
  category: fm.category || "Development Tools",
50760
50839
  tags: fm.tags || [],
50761
50840
  ...fm.kind ? { kind: fm.kind } : {},
50762
- ...isHostedMetadataSkillDir(join27(dir, entry.name)) ? { serverOwned: true } : {},
50841
+ ...isHostedMetadataSkillDir(join28(dir, entry.name)) ? { serverOwned: true } : {},
50763
50842
  source
50764
50843
  });
50765
50844
  }
@@ -50768,16 +50847,16 @@ function discoverSkillsInDir(dir, source = "custom") {
50768
50847
  }
50769
50848
  function findExtensionSkillPath(name) {
50770
50849
  const config2 = loadConfig();
50771
- if (!config2.extensionsDir || !existsSync12(config2.extensionsDir))
50850
+ if (!config2.extensionsDir || !existsSync13(config2.extensionsDir))
50772
50851
  return null;
50773
50852
  try {
50774
50853
  const entries = readdirSync9(config2.extensionsDir, { withFileTypes: true });
50775
50854
  for (const entry of entries) {
50776
50855
  if (!entry.isDirectory())
50777
50856
  continue;
50778
- const skillDir = join27(config2.extensionsDir, entry.name);
50779
- const skillMdPath = join27(skillDir, "SKILL.md");
50780
- if (!existsSync12(skillMdPath))
50857
+ const skillDir = join28(config2.extensionsDir, entry.name);
50858
+ const skillMdPath = join28(skillDir, "SKILL.md");
50859
+ if (!existsSync13(skillMdPath))
50781
50860
  continue;
50782
50861
  let content;
50783
50862
  try {
@@ -50820,8 +50899,8 @@ function clearRegistryCache() {
50820
50899
  registryCacheTime = 0;
50821
50900
  registryCacheKey = null;
50822
50901
  }
50823
- function getSkillsByCategory(category) {
50824
- return loadRegistry().filter((s) => s.category === category);
50902
+ function getSkillsByCategory(category, catalog) {
50903
+ return (catalog ?? loadRegistry()).filter((s) => s.category === category);
50825
50904
  }
50826
50905
  function getSkill(name) {
50827
50906
  const registry2 = loadRegistry();
@@ -51973,14 +52052,14 @@ var init_remote_workspace_leave = __esm(() => {
51973
52052
  });
51974
52053
 
51975
52054
  // src/lib/auth-store.ts
51976
- import { chmodSync, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync17, renameSync as renameSync4, statSync as statSync8, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
51977
- import { basename as basename11, dirname as dirname18, join as join28 } from "path";
52055
+ import { chmodSync, existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync17, renameSync as renameSync4, statSync as statSync8, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
52056
+ import { basename as basename11, dirname as dirname18, join as join29 } from "path";
51978
52057
  function getAuthFilePath(env = process.env) {
51979
52058
  return skillsCredentialFilePath(env);
51980
52059
  }
51981
52060
  function getIdentityFilePath(env = process.env) {
51982
52061
  const file2 = skillsCredentialFilePath(env);
51983
- return join28(dirname18(file2), basename11(file2).replace(/^credentials/, "identity") + ".json");
52062
+ return join29(dirname18(file2), basename11(file2).replace(/^credentials/, "identity") + ".json");
51984
52063
  }
51985
52064
  function getApiUrl(action, env = process.env, options = {}) {
51986
52065
  return requireSkillsApiOrigin(action, env, options);
@@ -52208,10 +52287,10 @@ async function readQuoteUnavailableCode(response) {
52208
52287
  let timer;
52209
52288
  let deadlineExceeded = false;
52210
52289
  const expired = Symbol("quote body deadline");
52211
- const deadline = new Promise((resolve17) => {
52290
+ const deadline = new Promise((resolve18) => {
52212
52291
  timer = setTimeout(() => {
52213
52292
  deadlineExceeded = true;
52214
- resolve17(expired);
52293
+ resolve18(expired);
52215
52294
  reader.cancel().catch(() => {});
52216
52295
  }, 1500);
52217
52296
  });
@@ -53694,12 +53773,12 @@ class RemotePrivatePublicationsClient {
53694
53773
  previous = view;
53695
53774
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
53696
53775
  return view;
53697
- await new Promise((resolve17) => {
53776
+ await new Promise((resolve18) => {
53698
53777
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
53699
53778
  function done() {
53700
53779
  clearTimeout(timer);
53701
53780
  options.signal?.removeEventListener("abort", done);
53702
- resolve17();
53781
+ resolve18();
53703
53782
  }
53704
53783
  options.signal?.addEventListener("abort", done, { once: true });
53705
53784
  });
@@ -53987,10 +54066,10 @@ var init_remote_auth = __esm(() => {
53987
54066
  });
53988
54067
 
53989
54068
  // src/lib/workspace-profile.ts
53990
- import { constants as constants11, closeSync as closeSync14, fstatSync as fstatSync14, lstatSync as lstatSync19, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync2, openSync as openSync14, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
54069
+ import { constants as constants11, closeSync as closeSync14, fstatSync as fstatSync14, lstatSync as lstatSync20, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync2, openSync as openSync14, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
53991
54070
  function stat2(path) {
53992
54071
  try {
53993
- return lstatSync19(path);
54072
+ return lstatSync20(path);
53994
54073
  } catch (error61) {
53995
54074
  if (error61.code === "ENOENT")
53996
54075
  return null;
@@ -54219,8 +54298,8 @@ var init_recurring_customer = __esm(() => {
54219
54298
  });
54220
54299
 
54221
54300
  // src/lib/recurring-recovery.ts
54222
- import { constants as constants12, closeSync as closeSync15, fsyncSync as fsyncSync4, fstatSync as fstatSync15, lstatSync as lstatSync20, mkdirSync as mkdirSync10, openSync as openSync15, readSync as readSync10, realpathSync as realpathSync7, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
54223
- import { dirname as dirname19, isAbsolute as isAbsolute15, join as join29, resolve as resolve17 } from "path";
54301
+ import { constants as constants12, closeSync as closeSync15, fsyncSync as fsyncSync4, fstatSync as fstatSync15, lstatSync as lstatSync21, mkdirSync as mkdirSync10, openSync as openSync15, readSync as readSync10, realpathSync as realpathSync8, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
54302
+ import { dirname as dirname19, isAbsolute as isAbsolute15, join as join30, resolve as resolve18 } from "path";
54224
54303
  import { randomUUID as randomUUID2 } from "crypto";
54225
54304
 
54226
54305
  class RecoveryOwner {
@@ -54228,10 +54307,10 @@ class RecoveryOwner {
54228
54307
  parents = [];
54229
54308
  constructor(directory) {
54230
54309
  this.directory = directory;
54231
- if (!isAbsolute15(directory) || resolve17(directory) !== directory || realpathSync7(directory) !== directory)
54310
+ if (!isAbsolute15(directory) || resolve18(directory) !== directory || realpathSync8(directory) !== directory)
54232
54311
  invalid5();
54233
54312
  for (let path = directory;; path = dirname19(path)) {
54234
- const stat3 = lstatSync20(path);
54313
+ const stat3 = lstatSync21(path);
54235
54314
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
54236
54315
  invalid5();
54237
54316
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
@@ -54241,20 +54320,20 @@ class RecoveryOwner {
54241
54320
  this.assert();
54242
54321
  }
54243
54322
  assert() {
54244
- if (realpathSync7(this.directory) !== this.directory)
54323
+ if (realpathSync8(this.directory) !== this.directory)
54245
54324
  invalid5();
54246
54325
  for (const prior of this.parents) {
54247
- const now = lstatSync20(prior.path);
54326
+ const now = lstatSync21(prior.path);
54248
54327
  if (!now.isDirectory() || now.isSymbolicLink() || now.dev !== prior.dev || now.ino !== prior.ino)
54249
54328
  invalid5();
54250
54329
  }
54251
- const own2 = lstatSync20(this.directory);
54330
+ const own2 = lstatSync21(this.directory);
54252
54331
  if ((own2.mode & 511) !== 448 || (own2.mode & 3584) !== 0 || process.getuid && own2.uid !== process.getuid())
54253
54332
  invalid5();
54254
54333
  }
54255
54334
  read(name) {
54256
54335
  this.assert();
54257
- const fd = openSync15(join29(this.directory, name), constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
54336
+ const fd = openSync15(join30(this.directory, name), constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
54258
54337
  try {
54259
54338
  const before = fstatSync15(fd);
54260
54339
  if (!before.isFile() || before.nlink !== 1 || (before.mode & 4095) !== 384 || before.size < 1 || before.size > 8192 || process.getuid && before.uid !== process.getuid())
@@ -54267,7 +54346,7 @@ class RecoveryOwner {
54267
54346
  break;
54268
54347
  size += n2;
54269
54348
  }
54270
- const after = fstatSync15(fd), path = lstatSync20(join29(this.directory, name));
54349
+ const after = fstatSync15(fd), path = lstatSync21(join30(this.directory, name));
54271
54350
  if (size !== before.size || after.size !== before.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs || path.dev !== before.dev || path.ino !== before.ino || !path.isFile() || path.isSymbolicLink())
54272
54351
  invalid5();
54273
54352
  this.assert();
@@ -54280,7 +54359,7 @@ class RecoveryOwner {
54280
54359
  this.assert();
54281
54360
  const bytes = canonicalJson2(value, 8192) + `
54282
54361
  `;
54283
- const fd = openSync15(join29(this.directory, name), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54362
+ const fd = openSync15(join30(this.directory, name), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54284
54363
  try {
54285
54364
  writeFileSync9(fd, bytes);
54286
54365
  fsyncSync4(fd);
@@ -54307,14 +54386,14 @@ class RecoveryOwner {
54307
54386
  if (this.read("state.json") !== expected)
54308
54387
  invalid5();
54309
54388
  this.assert();
54310
- renameSync6(join29(this.directory, name), join29(this.directory, "state.json"));
54389
+ renameSync6(join30(this.directory, name), join30(this.directory, "state.json"));
54311
54390
  this.sync();
54312
54391
  }
54313
54392
  async locked(action) {
54314
54393
  this.assert();
54315
54394
  let fd;
54316
54395
  try {
54317
- fd = openSync15(join29(this.directory, "operation.lock"), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54396
+ fd = openSync15(join30(this.directory, "operation.lock"), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54318
54397
  } catch {
54319
54398
  throw new RecurringCustomerError("RECURRING_RECOVERY_BUSY", "Recovery is locked. Confirm the original process has stopped before explicitly reconciling the retained lock; no request was retried.");
54320
54399
  }
@@ -54327,10 +54406,10 @@ class RecoveryOwner {
54327
54406
  } finally {
54328
54407
  closeSync15(fd);
54329
54408
  this.assert();
54330
- const now = lstatSync20(join29(this.directory, "operation.lock"));
54409
+ const now = lstatSync21(join30(this.directory, "operation.lock"));
54331
54410
  if (owner2.dev !== now.dev || owner2.ino !== now.ino || !now.isFile() || now.isSymbolicLink())
54332
54411
  invalid5();
54333
- unlinkSync5(join29(this.directory, "operation.lock"));
54412
+ unlinkSync5(join30(this.directory, "operation.lock"));
54334
54413
  this.sync();
54335
54414
  }
54336
54415
  }
@@ -54363,7 +54442,7 @@ function base(customer, organizationId) {
54363
54442
  };
54364
54443
  }
54365
54444
  function create(directory, intent) {
54366
- if (!isAbsolute15(directory) || resolve17(directory) !== directory || realpathSync7(dirname19(directory)) !== dirname19(directory))
54445
+ if (!isAbsolute15(directory) || resolve18(directory) !== directory || realpathSync8(dirname19(directory)) !== dirname19(directory))
54367
54446
  invalid5();
54368
54447
  mkdirSync10(directory, { mode: 448 });
54369
54448
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
@@ -56461,20 +56540,20 @@ var init_credential_state = __esm(() => {
56461
56540
 
56462
56541
  // src/lib/run-state.ts
56463
56542
  import { createHash as createHash19, randomBytes } from "crypto";
56464
- import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync10, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
56465
- import { extname, join as join30, relative as relative6 } from "path";
56543
+ import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync10, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
56544
+ import { extname, join as join31, relative as relative6 } from "path";
56466
56545
  function createSkillRun(params, targetDir = process.cwd()) {
56467
56546
  const now = new Date;
56468
56547
  const id = createRunId(now);
56469
56548
  const day = now.toISOString().slice(0, 10);
56470
56549
  const skillName = normalizeSkillName(params.skill);
56471
56550
  const root = getProjectStateDir(targetDir);
56472
- const runDir = join30(root, "runs", day, id);
56473
- const logsDir = join30(runDir, "logs");
56474
- const exportDir = join30(root, "exports", skillName, id);
56551
+ const runDir = join31(root, "runs", day, id);
56552
+ const logsDir = join31(runDir, "logs");
56553
+ const exportDir = join31(root, "exports", skillName, id);
56475
56554
  mkdirSync11(logsDir, { recursive: true });
56476
56555
  mkdirSync11(exportDir, { recursive: true });
56477
- mkdirSync11(join30(root, "tmp"), { recursive: true });
56556
+ mkdirSync11(join31(root, "tmp"), { recursive: true });
56478
56557
  const record11 = {
56479
56558
  id,
56480
56559
  skill: skillName,
@@ -56526,22 +56605,22 @@ function updateSkillRun(context2, patch) {
56526
56605
  return context2.record;
56527
56606
  }
56528
56607
  function writeRunLogs(context2, stdout = "", stderr = "") {
56529
- writeFileSync10(join30(context2.logsDir, "stdout.log"), stdout);
56530
- writeFileSync10(join30(context2.logsDir, "stderr.log"), stderr);
56608
+ writeFileSync10(join31(context2.logsDir, "stdout.log"), stdout);
56609
+ writeFileSync10(join31(context2.logsDir, "stderr.log"), stderr);
56531
56610
  }
56532
56611
  function appendRunEvent(context2, event, data = {}) {
56533
56612
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
56534
56613
  `;
56535
- const path = join30(context2.runDir, "events.ndjson");
56536
- const previous = existsSync14(path) ? readFileSync19(path, "utf-8") : "";
56614
+ const path = join31(context2.runDir, "events.ndjson");
56615
+ const previous = existsSync15(path) ? readFileSync19(path, "utf-8") : "";
56537
56616
  writeFileSync10(path, previous + line);
56538
56617
  }
56539
56618
  function findSkillRun(runId, targetDir = process.cwd()) {
56540
- const runsRoot = join30(getProjectStateDir(targetDir), "runs");
56541
- if (!existsSync14(runsRoot))
56619
+ const runsRoot = join31(getProjectStateDir(targetDir), "runs");
56620
+ if (!existsSync15(runsRoot))
56542
56621
  return null;
56543
56622
  for (const day of readdirSync10(runsRoot)) {
56544
- const record11 = readRunRecord(join30(runsRoot, day, runId));
56623
+ const record11 = readRunRecord(join31(runsRoot, day, runId));
56545
56624
  if (record11)
56546
56625
  return record11;
56547
56626
  }
@@ -56558,15 +56637,15 @@ function skillRunEnv(context2) {
56558
56637
  };
56559
56638
  }
56560
56639
  function writeRunRecord(context2) {
56561
- writeFileSync10(join30(context2.runDir, "run.json"), JSON.stringify(context2.record, null, 2) + `
56640
+ writeFileSync10(join31(context2.runDir, "run.json"), JSON.stringify(context2.record, null, 2) + `
56562
56641
  `);
56563
56642
  }
56564
56643
  function writeArtifactsManifest(context2, artifacts) {
56565
- writeFileSync10(join30(context2.runDir, "artifacts.json"), JSON.stringify({ runId: context2.record.id, artifacts }, null, 2) + `
56644
+ writeFileSync10(join31(context2.runDir, "artifacts.json"), JSON.stringify({ runId: context2.record.id, artifacts }, null, 2) + `
56566
56645
  `);
56567
56646
  }
56568
56647
  function collectRunArtifacts(context2) {
56569
- if (!existsSync14(context2.exportDir))
56648
+ if (!existsSync15(context2.exportDir))
56570
56649
  return [];
56571
56650
  const artifacts = [];
56572
56651
  for (const path of walkFiles(context2.exportDir)) {
@@ -56582,8 +56661,8 @@ function collectRunArtifacts(context2) {
56582
56661
  return artifacts.sort((a, b) => a.path.localeCompare(b.path));
56583
56662
  }
56584
56663
  function readRunRecord(runDir) {
56585
- const path = join30(runDir, "run.json");
56586
- if (!existsSync14(path))
56664
+ const path = join31(runDir, "run.json");
56665
+ if (!existsSync15(path))
56587
56666
  return null;
56588
56667
  try {
56589
56668
  return JSON.parse(readFileSync19(path, "utf-8"));
@@ -56594,7 +56673,7 @@ function readRunRecord(runDir) {
56594
56673
  function walkFiles(dir) {
56595
56674
  const files = [];
56596
56675
  for (const entry of readdirSync10(dir)) {
56597
- const full = join30(dir, entry);
56676
+ const full = join31(dir, entry);
56598
56677
  if (statSync9(full).isDirectory())
56599
56678
  files.push(...walkFiles(full));
56600
56679
  else
@@ -56851,7 +56930,7 @@ import { closeSync as closeSync16, fstatSync as fstatSync16, openSync as openSyn
56851
56930
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
56852
56931
  import { createRequire as createRequire2 } from "module";
56853
56932
  import { hostname as osHostname2 } from "os";
56854
- import { isAbsolute as isAbsolute17, join as join31 } from "path";
56933
+ import { isAbsolute as isAbsolute17, join as join32 } from "path";
56855
56934
  import { createRequire as createRequire22 } from "module";
56856
56935
  function envToken2(name) {
56857
56936
  return name.toUpperCase().replace(/-/g, "_");
@@ -56882,14 +56961,14 @@ function hasnaHomeDir2(env) {
56882
56961
  if (override)
56883
56962
  return override;
56884
56963
  const home = homeDir2(env);
56885
- return home ? join31(home, HASNA_HOME_DIR2) : null;
56964
+ return home ? join32(home, HASNA_HOME_DIR2) : null;
56886
56965
  }
56887
56966
  function appConfigDir2(name, env) {
56888
56967
  const configRoot = absoluteOverride2(env, HASNA_CONFIG_HOME_ENV_KEY2);
56889
56968
  if (configRoot)
56890
- return join31(configRoot, name);
56969
+ return join32(configRoot, name);
56891
56970
  const root = hasnaHomeDir2(env);
56892
- return root ? join31(root, name, CONFIG_SUBDIR2) : null;
56971
+ return root ? join32(root, name, CONFIG_SUBDIR2) : null;
56893
56972
  }
56894
56973
  function credentialDiskSourceList2(name, env, profile = null) {
56895
56974
  if (!SAFE_APP_SLUG2.test(name))
@@ -56898,7 +56977,7 @@ function credentialDiskSourceList2(name, env, profile = null) {
56898
56977
  if (!directory2)
56899
56978
  return [];
56900
56979
  const file2 = profile ? `${CREDENTIALS_FILE2}-${profile}` : CREDENTIALS_FILE2;
56901
- return [{ path: join31(directory2, file2), tier: "disk" }];
56980
+ return [{ path: join32(directory2, file2), tier: "disk" }];
56902
56981
  }
56903
56982
  function credentialDiskSources2(name, env) {
56904
56983
  return credentialDiskSourceList2(name, env, null).map((s) => s.path);
@@ -58012,7 +58091,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
58012
58091
  });
58013
58092
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
58014
58093
  }
58015
- var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve18) => setTimeout(resolve18, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
58094
+ var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve19) => setTimeout(resolve19, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
58016
58095
  var init_sdk = __esm(() => {
58017
58096
  init_transport2 = __esm2(() => {
58018
58097
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -58147,7 +58226,7 @@ var init_sdk = __esm(() => {
58147
58226
  });
58148
58227
 
58149
58228
  // src/lib/execution-secrets.ts
58150
- import { constants as constants13, closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readSync as readSync11, realpathSync as realpathSync8 } from "fs";
58229
+ import { constants as constants13, closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readSync as readSync11, realpathSync as realpathSync9 } from "fs";
58151
58230
  import { hostname as stationHostname } from "os";
58152
58231
  function selectedSecretBindingsTemplate(scope, names, createClient = createSecretsClientFromEnv) {
58153
58232
  let secretsAuthority;
@@ -58160,7 +58239,7 @@ function selectedSecretBindingsTemplate(scope, names, createClient = createSecre
58160
58239
  return {
58161
58240
  schema: "hasna.skills-secret-bindings.v1",
58162
58241
  selection: { authority, workspaceId, profileId: scope.profileId, profileRevision, slug: slug2, version: version2, bundleDigest },
58163
- consumer: { stationId: process.env.HASNA_STATION || stationHostname(), workspaceDirectory: realpathSync8(scope.cwd) },
58242
+ consumer: { stationId: process.env.HASNA_STATION || stationHostname(), workspaceDirectory: realpathSync9(scope.cwd) },
58164
58243
  secretsAuthority,
58165
58244
  bindings: Object.fromEntries(names.map((name) => [name, ""]))
58166
58245
  };
@@ -58198,7 +58277,7 @@ function validateSelectedSecretBindings(value, scope, names) {
58198
58277
  }
58199
58278
  let workspaceDirectory;
58200
58279
  try {
58201
- workspaceDirectory = realpathSync8(scope.cwd);
58280
+ workspaceDirectory = realpathSync9(scope.cwd);
58202
58281
  } catch {
58203
58282
  return refuse2("SECRET_BINDING_CONSUMER_MISMATCH", "The execution workspace cannot be resolved.");
58204
58283
  }
@@ -58391,8 +58470,8 @@ __export(exports_selected_run, {
58391
58470
  });
58392
58471
  import { createHash as createHash20 } from "crypto";
58393
58472
  import { spawn } from "child_process";
58394
- import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync9 } from "fs";
58395
- import { dirname as dirname20, join as join32, resolve as resolve18 } from "path";
58473
+ import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync10 } from "fs";
58474
+ import { dirname as dirname20, join as join33, resolve as resolve19 } from "path";
58396
58475
  import { tmpdir, hostname as stationHostname2 } from "os";
58397
58476
  async function resolveSelectedRun(spec, profileId, options = {}) {
58398
58477
  const context2 = await resolveSelectionContext(profileId, options);
@@ -58472,7 +58551,7 @@ async function executeSelectedLocal(selected, options = {}) {
58472
58551
  throw new SkillSelectionError("INVALID_SECRET_BINDINGS", "Explicit environment values must be bounded strings without NUL bytes.");
58473
58552
  secretEnv[name] = value;
58474
58553
  }
58475
- const runDirectory = mkdtempSync3(join32(tmpdir(), "skills-execution-"));
58554
+ const runDirectory = mkdtempSync3(join33(tmpdir(), "skills-execution-"));
58476
58555
  const paths = new SkillEntryPaths;
58477
58556
  for (const entry of entries) {
58478
58557
  paths.add(entry.path, 100, () => {
@@ -58480,12 +58559,12 @@ async function executeSelectedLocal(selected, options = {}) {
58480
58559
  }, () => {
58481
58560
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
58482
58561
  });
58483
- const destination = join32(runDirectory, entry.path);
58562
+ const destination = join33(runDirectory, entry.path);
58484
58563
  mkdirSync12(dirname20(destination), { recursive: true, mode: 448 });
58485
58564
  writeFileSync11(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
58486
58565
  }
58487
58566
  env.SKILLS_INPUT_JSON = input2;
58488
- env.SKILLS_WORKSPACE_DIR = resolve18(options.cwd ?? process.cwd());
58567
+ env.SKILLS_WORKSPACE_DIR = resolve19(options.cwd ?? process.cwd());
58489
58568
  env.SKILLS_RUN_DIR = runDirectory;
58490
58569
  if (runtime.version) {
58491
58570
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
@@ -58498,7 +58577,7 @@ async function executeSelectedLocal(selected, options = {}) {
58498
58577
  const { authority: authority2, workspaceId, profileRevision, slug: slug2, version: version2, bundleDigest } = selection2;
58499
58578
  const request2 = {
58500
58579
  selection: { authority: authority2, workspaceId, profileId, profileRevision, slug: slug2, version: version2, bundleDigest },
58501
- consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync9(options.cwd ?? process.cwd()) }
58580
+ consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync10(options.cwd ?? process.cwd()) }
58502
58581
  };
58503
58582
  const grant = await (options.resolveExecutionGrant ?? resolveExecutionGrant)(request2);
58504
58583
  if (!grant || !grantIdentifier(grant.policyRevision) || !grantIdentifier(grant.grantId))
@@ -58508,7 +58587,7 @@ async function executeSelectedLocal(selected, options = {}) {
58508
58587
  }
58509
58588
  if (bindings)
58510
58589
  secretEnv = await resolveSelectedSecrets(bindings, options.createSecretsClient);
58511
- const result = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], join32(runDirectory, declaredEntry), ...args], runDirectory, { ...env, ...secretEnv }, input2, timeoutMs);
58590
+ const result = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], join33(runDirectory, declaredEntry), ...args], runDirectory, { ...env, ...secretEnv }, input2, timeoutMs);
58512
58591
  result.stdout = redactExecutionSecrets(result.stdout, secretEnv);
58513
58592
  result.stderr = redactExecutionSecrets(result.stderr, secretEnv);
58514
58593
  const receipt = {
@@ -58521,7 +58600,7 @@ async function executeSelectedLocal(selected, options = {}) {
58521
58600
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
58522
58601
  ...result
58523
58602
  };
58524
- writeFileSync11(join32(runDirectory, ".execution-receipt.json"), JSON.stringify({ ...receipt, stdout: undefined, stderr: undefined }), { mode: 384 });
58603
+ writeFileSync11(join33(runDirectory, ".execution-receipt.json"), JSON.stringify({ ...receipt, stdout: undefined, stderr: undefined }), { mode: 384 });
58525
58604
  return receipt;
58526
58605
  }
58527
58606
  async function subprocess(command, cwd, env, input2, timeoutMs) {
@@ -58710,8 +58789,8 @@ var init_blog_article = __esm(() => {
58710
58789
  });
58711
58790
 
58712
58791
  // src/mcp/operation-tools.ts
58713
- import { existsSync as existsSync15, readdirSync as readdirSync11, statSync as statSync10 } from "fs";
58714
- import { join as join33 } from "path";
58792
+ import { existsSync as existsSync16, readdirSync as readdirSync11, statSync as statSync10 } from "fs";
58793
+ import { join as join34 } from "path";
58715
58794
  function registerOperationTools(server) {
58716
58795
  server.registerTool("cloud_skill_eligibility", {
58717
58796
  title: "Cloud Skill Eligibility",
@@ -59183,12 +59262,12 @@ function registerOperationTools(server) {
59183
59262
  const agents = [];
59184
59263
  for (const agent of AGENT_TARGETS) {
59185
59264
  const agentSkillsPath = getAgentSkillsDir(agent, "global");
59186
- const exists = existsSync15(agentSkillsPath);
59265
+ const exists = existsSync16(agentSkillsPath);
59187
59266
  let skillCount = 0;
59188
59267
  if (exists) {
59189
59268
  try {
59190
59269
  skillCount = readdirSync11(agentSkillsPath).filter((f) => {
59191
- const full = join33(agentSkillsPath, f);
59270
+ const full = join34(agentSkillsPath, f);
59192
59271
  return !f.startsWith(".") && statSync10(full).isDirectory();
59193
59272
  }).length;
59194
59273
  } catch {}
@@ -59255,16 +59334,16 @@ var init_operation_tools = __esm(() => {
59255
59334
  });
59256
59335
 
59257
59336
  // src/lib/feedback.ts
59258
- import { appendFileSync, existsSync as existsSync16, mkdirSync as mkdirSync13 } from "fs";
59259
- import { dirname as dirname21, join as join34 } from "path";
59337
+ import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync13 } from "fs";
59338
+ import { dirname as dirname21, join as join35 } from "path";
59260
59339
  import { Database } from "bun:sqlite";
59261
59340
  function getFeedbackDbPath() {
59262
- return join34(getDataDir(), "skills.db");
59341
+ return join35(getDataDir(), "skills.db");
59263
59342
  }
59264
59343
  function getFeedbackDb() {
59265
59344
  const dbPath = getFeedbackDbPath();
59266
59345
  const dir = dirname21(dbPath);
59267
- if (!existsSync16(dir))
59346
+ if (!existsSync17(dir))
59268
59347
  mkdirSync13(dir, { recursive: true });
59269
59348
  const db = new Database(dbPath);
59270
59349
  db.exec("PRAGMA journal_mode = WAL");
@@ -59291,9 +59370,9 @@ function saveFeedback(input2) {
59291
59370
  throw new Error("Feedback message is required");
59292
59371
  const category = input2.category ?? "general";
59293
59372
  if (isApiMode()) {
59294
- const path = join34(getDataDir(), "feedback.jsonl");
59373
+ const path = join35(getDataDir(), "feedback.jsonl");
59295
59374
  const dir = dirname21(path);
59296
- if (!existsSync16(dir))
59375
+ if (!existsSync17(dir))
59297
59376
  mkdirSync13(dir, { recursive: true });
59298
59377
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
59299
59378
  `);
@@ -59455,14 +59534,14 @@ var init_resource_meta_tools = __esm(() => {
59455
59534
  });
59456
59535
 
59457
59536
  // src/lib/scheduler.ts
59458
- import { existsSync as existsSync17, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
59459
- import { join as join35 } from "path";
59537
+ import { existsSync as existsSync18, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
59538
+ import { join as join36 } from "path";
59460
59539
  function getSchedulesPath(targetDir = process.cwd()) {
59461
- return join35(targetDir, ".skills", "schedules.json");
59540
+ return join36(targetDir, ".skills", "schedules.json");
59462
59541
  }
59463
59542
  function loadSchedules(targetDir = process.cwd()) {
59464
59543
  const path = getSchedulesPath(targetDir);
59465
- if (existsSync17(path)) {
59544
+ if (existsSync18(path)) {
59466
59545
  try {
59467
59546
  return JSON.parse(readFileSync21(path, "utf-8"));
59468
59547
  } catch {}
@@ -59471,8 +59550,8 @@ function loadSchedules(targetDir = process.cwd()) {
59471
59550
  }
59472
59551
  function saveSchedules(data, targetDir = process.cwd()) {
59473
59552
  const path = getSchedulesPath(targetDir);
59474
- const dir = join35(targetDir, ".skills");
59475
- if (!existsSync17(dir))
59553
+ const dir = join36(targetDir, ".skills");
59554
+ if (!existsSync18(dir))
59476
59555
  mkdirSync14(dir, { recursive: true });
59477
59556
  writeFileSync12(path, JSON.stringify(data, null, 2));
59478
59557
  }
@@ -59745,14 +59824,14 @@ var init_schedule_tools = __esm(() => {
59745
59824
  // src/lib/native-storage.ts
59746
59825
  import { createHash as createHash21, createHmac } from "crypto";
59747
59826
  import {
59748
- existsSync as existsSync18,
59827
+ existsSync as existsSync19,
59749
59828
  mkdirSync as mkdirSync15,
59750
59829
  readFileSync as readFileSync22,
59751
59830
  readdirSync as readdirSync12,
59752
59831
  statSync as statSync11,
59753
59832
  writeFileSync as writeFileSync13
59754
59833
  } from "fs";
59755
- import { dirname as dirname22, join as join36, normalize as normalize4, relative as relative7, sep as sep8 } from "path";
59834
+ import { dirname as dirname22, join as join37, normalize as normalize4, relative as relative7, sep as sep8 } from "path";
59756
59835
  function resolveSkillsNativeStorageConfig(env = process.env) {
59757
59836
  assertNoRetiredModeEnvVars(env, {
59758
59837
  app: SKILLS_ENV_NAMESPACE,
@@ -59793,7 +59872,7 @@ function getSkillsNativeStorageStatus(options = {}) {
59793
59872
  local: {
59794
59873
  dataDir: getDataDir(),
59795
59874
  projectStateDir: getProjectStateDir(targetDir),
59796
- feedbackDbPath: join36(getDataDir(), "skills.db")
59875
+ feedbackDbPath: join37(getDataDir(), "skills.db")
59797
59876
  },
59798
59877
  remote: {
59799
59878
  databaseConfigured: Boolean(config2.databaseUrl),
@@ -59813,7 +59892,7 @@ function getStorageStatus(options = {}) {
59813
59892
  function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
59814
59893
  const projectStateDir = getProjectStateDir(targetDir);
59815
59894
  const files = [];
59816
- if (existsSync18(projectStateDir)) {
59895
+ if (existsSync19(projectStateDir)) {
59817
59896
  for (const filePath of walkFiles2(projectStateDir)) {
59818
59897
  const bytes = readFileSync22(filePath);
59819
59898
  const relativePath = toPosix(relative7(targetDir, filePath));
@@ -59874,7 +59953,7 @@ function parsePositiveInteger(value) {
59874
59953
  function walkFiles2(dir) {
59875
59954
  const files = [];
59876
59955
  for (const entry of readdirSync12(dir)) {
59877
- const full = join36(dir, entry);
59956
+ const full = join37(dir, entry);
59878
59957
  const stats = statSync11(full);
59879
59958
  if (stats.isDirectory())
59880
59959
  files.push(...walkFiles2(full));
@@ -60112,20 +60191,20 @@ var init_private_publication_customer = __esm(() => {
60112
60191
  });
60113
60192
 
60114
60193
  // src/lib/private-publication-recovery.ts
60115
- import { constants as constants14, closeSync as closeSync18, fsyncSync as fsyncSync5, fstatSync as fstatSync18, lstatSync as lstatSync21, mkdirSync as mkdirSync16, openSync as openSync18, readSync as readSync12, realpathSync as realpathSync10, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
60116
- import { dirname as dirname23, isAbsolute as isAbsolute18, join as join37, resolve as resolve19 } from "path";
60194
+ import { constants as constants14, closeSync as closeSync18, fsyncSync as fsyncSync5, fstatSync as fstatSync18, lstatSync as lstatSync22, mkdirSync as mkdirSync16, openSync as openSync18, readSync as readSync12, realpathSync as realpathSync11, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
60195
+ import { dirname as dirname23, isAbsolute as isAbsolute18, join as join38, resolve as resolve20 } from "path";
60117
60196
  import { randomUUID as randomUUID3 } from "crypto";
60118
60197
  function safeDirectory(directory2) {
60119
- if (!isAbsolute18(directory2) || directory2 !== resolve19(directory2) || realpathSync10(directory2) !== directory2)
60198
+ if (!isAbsolute18(directory2) || directory2 !== resolve20(directory2) || realpathSync11(directory2) !== directory2)
60120
60199
  return fail2();
60121
60200
  for (let path = directory2;; path = dirname23(path)) {
60122
- const stat3 = lstatSync21(path);
60201
+ const stat3 = lstatSync22(path);
60123
60202
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
60124
60203
  return fail2();
60125
60204
  if (path === dirname23(path))
60126
60205
  break;
60127
60206
  }
60128
- const own2 = lstatSync21(directory2);
60207
+ const own2 = lstatSync22(directory2);
60129
60208
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
60130
60209
  return fail2();
60131
60210
  return { dev: own2.dev, ino: own2.ino };
@@ -60136,7 +60215,7 @@ function unchangedDirectory(directory2, identity3) {
60136
60215
  return fail2();
60137
60216
  }
60138
60217
  function readOwned(directory2, name, max) {
60139
- const identity3 = safeDirectory(directory2), file2 = join37(directory2, name);
60218
+ const identity3 = safeDirectory(directory2), file2 = join38(directory2, name);
60140
60219
  const fd = openSync18(file2, constants14.O_RDONLY | constants14.O_NOFOLLOW);
60141
60220
  try {
60142
60221
  const stat3 = fstatSync18(fd);
@@ -60160,7 +60239,7 @@ function readOwned(directory2, name, max) {
60160
60239
  }
60161
60240
  }
60162
60241
  function writeOwned(directory2, name, bytes) {
60163
- const fd = openSync18(join37(directory2, name), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
60242
+ const fd = openSync18(join38(directory2, name), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
60164
60243
  try {
60165
60244
  writeFileSync14(fd, bytes);
60166
60245
  fsyncSync5(fd);
@@ -60173,7 +60252,7 @@ function save(directory2, value) {
60173
60252
  writeOwned(directory2, temporary, JSON.stringify(value) + `
60174
60253
  `);
60175
60254
  unchangedDirectory(directory2, identity3);
60176
- renameSync7(join37(directory2, temporary), join37(directory2, "receipt.json"));
60255
+ renameSync7(join38(directory2, temporary), join38(directory2, "receipt.json"));
60177
60256
  const fd = openSync18(directory2, constants14.O_RDONLY | constants14.O_NOFOLLOW);
60178
60257
  try {
60179
60258
  fsyncSync5(fd);
@@ -60186,7 +60265,7 @@ function bind(client, receipt) {
60186
60265
  throw new PrivatePublicationError("PUBLICATION_IDENTITY_CHANGED", "The fresh session does not match the recovery directory's server, account and membership.");
60187
60266
  }
60188
60267
  async function locked(directory2, action) {
60189
- const identity3 = safeDirectory(directory2), file2 = join37(directory2, "operation.lock");
60268
+ const identity3 = safeDirectory(directory2), file2 = join38(directory2, "operation.lock");
60190
60269
  let fd;
60191
60270
  try {
60192
60271
  fd = openSync18(file2, constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
@@ -60202,7 +60281,7 @@ async function locked(directory2, action) {
60202
60281
  } finally {
60203
60282
  closeSync18(fd);
60204
60283
  unchangedDirectory(directory2, identity3);
60205
- const now = lstatSync21(file2);
60284
+ const now = lstatSync22(file2);
60206
60285
  if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
60207
60286
  fail2();
60208
60287
  unlinkSync6(file2);
@@ -60254,7 +60333,7 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
60254
60333
  phase: "prepared",
60255
60334
  intent: null
60256
60335
  };
60257
- if (!isAbsolute18(recoveryDirectory) || resolve19(recoveryDirectory) !== recoveryDirectory || realpathSync10(dirname23(recoveryDirectory)) !== dirname23(recoveryDirectory))
60336
+ if (!isAbsolute18(recoveryDirectory) || resolve20(recoveryDirectory) !== recoveryDirectory || realpathSync11(dirname23(recoveryDirectory)) !== dirname23(recoveryDirectory))
60258
60337
  return fail2();
60259
60338
  mkdirSync16(recoveryDirectory, { mode: 448 });
60260
60339
  safeDirectory(recoveryDirectory);
@@ -61070,7 +61149,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
61070
61149
  request2[bodyBufferKey] = buffered;
61071
61150
  return Promise.resolve(buffered);
61072
61151
  }
61073
- const promise3 = new Promise((resolve20, reject) => {
61152
+ const promise3 = new Promise((resolve21, reject) => {
61074
61153
  const chunks = [];
61075
61154
  let settled = false;
61076
61155
  const finish = (callback) => {
@@ -61092,7 +61171,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
61092
61171
  reject(error61 ?? normalizeAbortError(request2, incoming));
61093
61172
  else {
61094
61173
  request2[bodyBufferKey] = recovered;
61095
- resolve20(recovered);
61174
+ resolve21(recovered);
61096
61175
  }
61097
61176
  });
61098
61177
  return true;
@@ -61104,7 +61183,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
61104
61183
  finish(() => {
61105
61184
  const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
61106
61185
  request2[bodyBufferKey] = buffer;
61107
- resolve20(buffer);
61186
+ resolve21(buffer);
61108
61187
  });
61109
61188
  };
61110
61189
  const onError = (error61) => {
@@ -61378,7 +61457,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
61378
61457
  });
61379
61458
  if (!chunk) {
61380
61459
  if (i === 1) {
61381
- await new Promise((resolve20) => setTimeout(resolve20));
61460
+ await new Promise((resolve21) => setTimeout(resolve21));
61382
61461
  maxReadCount = 3;
61383
61462
  continue;
61384
61463
  }
@@ -62608,9 +62687,9 @@ data:
62608
62687
  const initRequest = messages.find((m) => isInitializeRequest(m));
62609
62688
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
62610
62689
  if (this._enableJsonResponse) {
62611
- return new Promise((resolve20) => {
62690
+ return new Promise((resolve21) => {
62612
62691
  this._streamMapping.set(streamId, {
62613
- resolveJson: resolve20,
62692
+ resolveJson: resolve21,
62614
62693
  cleanup: () => {
62615
62694
  this._streamMapping.delete(streamId);
62616
62695
  }
@@ -62979,19 +63058,19 @@ async function connectMcpForNode() {
62979
63058
  return { server: server2, transport };
62980
63059
  }
62981
63060
  function readBody(req) {
62982
- return new Promise((resolve20, reject) => {
63061
+ return new Promise((resolve21, reject) => {
62983
63062
  const chunks = [];
62984
63063
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
62985
63064
  req.on("end", () => {
62986
63065
  const raw = Buffer.concat(chunks).toString("utf-8");
62987
63066
  if (!raw.trim()) {
62988
- resolve20(undefined);
63067
+ resolve21(undefined);
62989
63068
  return;
62990
63069
  }
62991
63070
  try {
62992
- resolve20(JSON.parse(raw));
63071
+ resolve21(JSON.parse(raw));
62993
63072
  } catch {
62994
- resolve20(undefined);
63073
+ resolve21(undefined);
62995
63074
  }
62996
63075
  });
62997
63076
  req.on("error", reject);
@@ -63033,9 +63112,9 @@ async function startSkillsMcpHttpServer(options = {}) {
63033
63112
  }
63034
63113
  }
63035
63114
  });
63036
- await new Promise((resolve20, reject) => {
63115
+ await new Promise((resolve21, reject) => {
63037
63116
  httpServer.once("error", reject);
63038
- httpServer.listen(port, hostname4, () => resolve20());
63117
+ httpServer.listen(port, hostname4, () => resolve21());
63039
63118
  });
63040
63119
  const address = httpServer.address();
63041
63120
  const listenPort = typeof address === "object" && address ? address.port : port;