@hasna/skills 0.1.64 → 0.1.67

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
@@ -6905,24 +6905,24 @@ __export(exports_auth_store, {
6905
6905
  getApiKey: () => getApiKey,
6906
6906
  clearAuthConfig: () => clearAuthConfig
6907
6907
  });
6908
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync6, unlinkSync } from "fs";
6909
- import { dirname as dirname5, join as join11 } from "path";
6908
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync6, unlinkSync } from "fs";
6909
+ import { dirname as dirname5, join as join12 } from "path";
6910
6910
  import { homedir as homedir3 } from "os";
6911
6911
  function getAuthFilePath() {
6912
- return join11(getDataDir(), "auth.json");
6912
+ return join12(getDataDir(), "auth.json");
6913
6913
  }
6914
6914
  function getAuthFilePathReadOnly() {
6915
- return join11(getDataDirReadOnly(), "auth.json");
6915
+ return join12(getDataDirReadOnly(), "auth.json");
6916
6916
  }
6917
6917
  function legacyAuthFilePath() {
6918
- return join11(process.env["HOME"] || process.env["USERPROFILE"] || homedir3(), ".skills", "auth.json");
6918
+ return join12(process.env["HOME"] || process.env["USERPROFILE"] || homedir3(), ".skills", "auth.json");
6919
6919
  }
6920
6920
  function getAuthConfig() {
6921
6921
  if (cachedConfig !== undefined)
6922
6922
  return cachedConfig;
6923
6923
  try {
6924
- const file = existsSync11(getAuthFilePath()) ? getAuthFilePath() : legacyAuthFilePath();
6925
- const raw = readFileSync10(file, "utf-8");
6924
+ const file = existsSync12(getAuthFilePath()) ? getAuthFilePath() : legacyAuthFilePath();
6925
+ const raw = readFileSync11(file, "utf-8");
6926
6926
  const config2 = JSON.parse(raw);
6927
6927
  if (!config2.apiKey) {
6928
6928
  cachedConfig = null;
@@ -6960,8 +6960,8 @@ function getApiKey() {
6960
6960
  }
6961
6961
  function getAuthConfigReadOnly() {
6962
6962
  try {
6963
- const file = existsSync11(getAuthFilePathReadOnly()) ? getAuthFilePathReadOnly() : legacyAuthFilePath();
6964
- const raw = readFileSync10(file, "utf-8");
6963
+ const file = existsSync12(getAuthFilePathReadOnly()) ? getAuthFilePathReadOnly() : legacyAuthFilePath();
6964
+ const raw = readFileSync11(file, "utf-8");
6965
6965
  const config2 = JSON.parse(raw);
6966
6966
  if (!config2.apiKey)
6967
6967
  return null;
@@ -12943,7 +12943,7 @@ class StdioServerTransport {
12943
12943
  // package.json
12944
12944
  var package_default = {
12945
12945
  name: "@hasna/skills",
12946
- version: "0.1.64",
12946
+ version: "0.1.67",
12947
12947
  description: "Skills library for AI coding agents",
12948
12948
  type: "module",
12949
12949
  bin: {
@@ -12984,6 +12984,7 @@ var package_default = {
12984
12984
  scripts: {
12985
12985
  clean: "rm -rf bin/ dist/",
12986
12986
  build: "bun run clean && bun build ./src/cli/index.tsx --outdir ./bin --target bun && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
12987
+ "build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
12987
12988
  test: "bun test --timeout 30000",
12988
12989
  dev: "bun run ./src/cli/index.tsx",
12989
12990
  "dev:watch": "bun --watch run ./src/cli/index.tsx",
@@ -12993,6 +12994,7 @@ var package_default = {
12993
12994
  migrate: "bun run ./src/server/migrate.ts",
12994
12995
  typecheck: "tsc --noEmit",
12995
12996
  "verify:release": "bun run scripts/release-guard.ts",
12997
+ prepare: "bun run build:js",
12996
12998
  prepack: "bun run build && bun run verify:release",
12997
12999
  prepublishOnly: "bun run typecheck && bun run test",
12998
13000
  postinstall: "mkdir -p $HOME/.hasna/skills/custom 2>/dev/null || true"
@@ -20879,22 +20881,23 @@ var EMPTY_COMPLETION_RESULT = {
20879
20881
 
20880
20882
  // src/lib/registry.ts
20881
20883
  init_config();
20882
- import { existsSync as existsSync6, readFileSync as readFileSync5, readdirSync as readdirSync5 } from "fs";
20883
- import { join as join6 } from "path";
20884
+ import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync6 } from "fs";
20885
+ import { join as join7 } from "path";
20884
20886
 
20885
20887
  // src/lib/portable-skills.ts
20886
20888
  init_config();
20887
20889
  import {
20888
20890
  cpSync as cpSync2,
20889
- existsSync as existsSync5,
20891
+ existsSync as existsSync6,
20890
20892
  mkdirSync as mkdirSync3,
20891
- readdirSync as readdirSync4,
20893
+ mkdtempSync,
20894
+ readdirSync as readdirSync5,
20892
20895
  renameSync,
20893
20896
  rmSync,
20894
- statSync as statSync5,
20897
+ statSync as statSync6,
20895
20898
  writeFileSync as writeFileSync3
20896
20899
  } from "fs";
20897
- import { basename as basename2, dirname as dirname3, isAbsolute as isAbsolute2, join as join5, normalize as normalize2 } from "path";
20900
+ import { basename as basename2, dirname as dirname3, isAbsolute as isAbsolute2, join as join6, normalize as normalize2 } from "path";
20898
20901
 
20899
20902
  // src/lib/registry-data/development-tools.ts
20900
20903
  var DEVELOPMENT_TOOLS_SKILLS = [
@@ -21605,11 +21608,9 @@ var SKILLS = [
21605
21608
  ...EVENT_MANAGEMENT_SKILLS
21606
21609
  ];
21607
21610
 
21608
- // src/lib/skill-validation.ts
21609
- import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
21610
- import { isAbsolute, join as join2, normalize } from "path";
21611
-
21612
21611
  // src/lib/hosted-skill-set.ts
21612
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
21613
+ import { join as join2 } from "path";
21613
21614
  var HOSTED_RUNTIMES = new Set(["hosted"]);
21614
21615
  var HOSTED_SOURCES = new Set(["remote", "private-hosted"]);
21615
21616
  function normalizeMarker(value) {
@@ -21621,6 +21622,16 @@ function isHostedMetadataPackage(pkg) {
21621
21622
  return false;
21622
21623
  return HOSTED_RUNTIMES.has(normalizeMarker(skills.runtime)) || HOSTED_SOURCES.has(normalizeMarker(skills.source));
21623
21624
  }
21625
+ function isHostedMetadataSkillDir(skillDir) {
21626
+ const pkgPath = join2(skillDir, "package.json");
21627
+ if (!existsSync2(pkgPath))
21628
+ return false;
21629
+ try {
21630
+ return isHostedMetadataPackage(JSON.parse(readFileSync2(pkgPath, "utf8")));
21631
+ } catch {
21632
+ return false;
21633
+ }
21634
+ }
21624
21635
  var HOSTED_METADATA_SET_EMPTY_ERROR = [
21625
21636
  "The hosted metadata skill set is empty, but the packaging guards that depend on it",
21626
21637
  "only mean anything while it is non-empty: an empty set makes every one of them pass",
@@ -21637,6 +21648,8 @@ var BRACE_SOURCE_EXCLUSION = new RegExp(`^!skills/\\{(${SLUG}(?:,${SLUG})+)\\}/s
21637
21648
  var SINGLE_SOURCE_EXCLUSION = new RegExp(`^!skills/(${SLUG})/src$`);
21638
21649
 
21639
21650
  // src/lib/skill-validation.ts
21651
+ import { existsSync as existsSync3, lstatSync, readFileSync as readFileSync3, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
21652
+ import { isAbsolute, join as join3, normalize } from "path";
21640
21653
  var VALID_SKILL_KINDS = ["executable", "instruction"];
21641
21654
  var DOC_FILES = ["SKILL.md", "README.md", "CLAUDE.md"];
21642
21655
  var RESERVED_SKILL_ENTRIES = new Set([
@@ -21690,7 +21703,7 @@ function add(target, code, message) {
21690
21703
  target.push({ code, message });
21691
21704
  }
21692
21705
  function readJsonFile(path) {
21693
- return JSON.parse(readFileSync2(path, "utf-8"));
21706
+ return JSON.parse(readFileSync3(path, "utf-8"));
21694
21707
  }
21695
21708
  function asRecord(value) {
21696
21709
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
@@ -21774,7 +21787,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21774
21787
  binCommands: [],
21775
21788
  docFiles: []
21776
21789
  };
21777
- if (!existsSync2(skillPath)) {
21790
+ if (!existsSync3(skillPath)) {
21778
21791
  add(issues, "skill.dir_missing", `Skill directory not found: ${skillPath}`);
21779
21792
  return {
21780
21793
  name: bareName,
@@ -21788,8 +21801,8 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21788
21801
  if (!VALID_BIN_COMMAND.test(bareName)) {
21789
21802
  add(issues, "skill.name_invalid", `Skill name '${bareName}' must use lowercase letters, numbers, dots, underscores, or hyphens`);
21790
21803
  }
21791
- for (const entry of readdirSync2(skillPath).sort()) {
21792
- const entryPath = join2(skillPath, entry);
21804
+ for (const entry of readdirSync3(skillPath).sort()) {
21805
+ const entryPath = join3(skillPath, entry);
21793
21806
  if (RESERVED_SKILL_ENTRIES.has(entry)) {
21794
21807
  add(issues, "skill.reserved_file", `Reserved file '${entry}' is not allowed in skill packages`);
21795
21808
  }
@@ -21801,15 +21814,15 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21801
21814
  }
21802
21815
  }
21803
21816
  for (const docFile of DOC_FILES) {
21804
- if (existsSync2(join2(skillPath, docFile)))
21817
+ if (existsSync3(join3(skillPath, docFile)))
21805
21818
  metadata.docFiles.push(docFile);
21806
21819
  }
21807
21820
  if (metadata.docFiles.length === 0) {
21808
21821
  add(issues, "skill.docs_missing", "Missing documentation file: expected SKILL.md, README.md, or CLAUDE.md");
21809
21822
  }
21810
- const skillMdPath = join2(skillPath, "SKILL.md");
21811
- if (existsSync2(skillMdPath)) {
21812
- const frontmatter = parseSkillFrontmatter(readFileSync2(skillMdPath, "utf-8"));
21823
+ const skillMdPath = join3(skillPath, "SKILL.md");
21824
+ if (existsSync3(skillMdPath)) {
21825
+ const frontmatter = parseSkillFrontmatter(readFileSync3(skillMdPath, "utf-8"));
21813
21826
  if (!frontmatter) {
21814
21827
  add(warnings, "skill.frontmatter_missing", "SKILL.md has no YAML frontmatter");
21815
21828
  } else {
@@ -21851,8 +21864,8 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21851
21864
  }
21852
21865
  metadata.kind = resolvedKind;
21853
21866
  const isInstruction = resolvedKind === "instruction";
21854
- const pkgPath = join2(skillPath, "package.json");
21855
- if (!existsSync2(pkgPath)) {
21867
+ const pkgPath = join3(skillPath, "package.json");
21868
+ if (!existsSync3(pkgPath)) {
21856
21869
  if (!isInstruction)
21857
21870
  add(issues, "package.missing", "Missing package.json");
21858
21871
  } else {
@@ -21910,10 +21923,10 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21910
21923
  add(issues, "package.bin_target_unsafe", `package.json bin '${command}' target '${target}' must stay inside the skill directory`);
21911
21924
  continue;
21912
21925
  }
21913
- const targetPath = join2(skillPath, target);
21914
- if (!existsSync2(targetPath)) {
21926
+ const targetPath = join3(skillPath, target);
21927
+ if (!existsSync3(targetPath)) {
21915
21928
  add(warnings, "package.bin_target_missing", `package.json bin '${command}' target '${target}' is not present before build`);
21916
- } else if (statSync2(targetPath).isDirectory()) {
21929
+ } else if (statSync3(targetPath).isDirectory()) {
21917
21930
  add(issues, "package.bin_target_directory", `package.json bin '${command}' target '${target}' must point to a file, not a directory`);
21918
21931
  }
21919
21932
  }
@@ -21928,18 +21941,18 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21928
21941
  metadata.runtime = "none";
21929
21942
  } else {
21930
21943
  metadata.runtime = hostedMetadata ? "hosted" : "local";
21931
- const srcDir = join2(skillPath, "src");
21944
+ const srcDir = join3(skillPath, "src");
21932
21945
  if (hostedMetadata) {
21933
- if (existsSync2(srcDir)) {
21946
+ if (existsSync3(srcDir)) {
21934
21947
  add(issues, "skill.hosted_source_forbidden", "Hosted metadata skills must not include local implementation source");
21935
21948
  }
21936
- } else if (!existsSync2(srcDir)) {
21949
+ } else if (!existsSync3(srcDir)) {
21937
21950
  add(issues, "skill.src_missing", "Missing src/ directory");
21938
- } else if (!existsSync2(join2(srcDir, "index.ts")) && !existsSync2(join2(srcDir, "index.js"))) {
21951
+ } else if (!existsSync3(join3(srcDir, "index.ts")) && !existsSync3(join3(srcDir, "index.js"))) {
21939
21952
  add(issues, "skill.src_index_missing", "Missing src/index.ts or src/index.js");
21940
21953
  } else {
21941
- const indexPath = existsSync2(join2(srcDir, "index.ts")) ? join2(srcDir, "index.ts") : join2(srcDir, "index.js");
21942
- const size = statSync2(indexPath).size;
21954
+ const indexPath = existsSync3(join3(srcDir, "index.ts")) ? join3(srcDir, "index.ts") : join3(srcDir, "index.js");
21955
+ const size = statSync3(indexPath).size;
21943
21956
  if (size < 50)
21944
21957
  add(warnings, "skill.src_index_minimal", `Source entry point is very small (${size}B)`);
21945
21958
  }
@@ -21956,8 +21969,8 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
21956
21969
 
21957
21970
  // src/lib/skill-hash.ts
21958
21971
  import { createHash } from "crypto";
21959
- import { existsSync as existsSync3, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync3 } from "fs";
21960
- import { join as join3, sep } from "path";
21972
+ import { existsSync as existsSync4, readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
21973
+ import { join as join4, sep } from "path";
21961
21974
  var CONTENT_HASH_ALGORITHM = "sha256";
21962
21975
  var HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
21963
21976
  var HASH_COVERAGE = [
@@ -22016,10 +22029,10 @@ function collectBundleFiles(skillPath) {
22016
22029
  if (seen.has(entry))
22017
22030
  continue;
22018
22031
  seen.add(entry);
22019
- const absolute = join3(skillPath, entry);
22020
- if (!existsSync3(absolute))
22032
+ const absolute = join4(skillPath, entry);
22033
+ if (!existsSync4(absolute))
22021
22034
  continue;
22022
- if (statSync3(absolute).isDirectory())
22035
+ if (statSync4(absolute).isDirectory())
22023
22036
  collectDirectory(files, absolute, entry);
22024
22037
  else
22025
22038
  collectFile(files, absolute, entry);
@@ -22027,14 +22040,14 @@ function collectBundleFiles(skillPath) {
22027
22040
  return files.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
22028
22041
  }
22029
22042
  function collectDirectory(files, dir, rel) {
22030
- for (const entry of readdirSync3(dir).sort()) {
22043
+ for (const entry of readdirSync4(dir).sort()) {
22031
22044
  if (entry.startsWith("."))
22032
22045
  continue;
22033
- const absolute = join3(dir, entry);
22046
+ const absolute = join4(dir, entry);
22034
22047
  const childRel = `${rel}/${entry}`;
22035
22048
  let stats;
22036
22049
  try {
22037
- stats = statSync3(absolute);
22050
+ stats = statSync4(absolute);
22038
22051
  } catch {
22039
22052
  continue;
22040
22053
  }
@@ -22050,7 +22063,7 @@ function collectDirectory(files, dir, rel) {
22050
22063
  }
22051
22064
  }
22052
22065
  function collectFile(files, absolute, rel) {
22053
- const buffer = readFileSync3(absolute);
22066
+ const buffer = readFileSync4(absolute);
22054
22067
  if (rel === "skill.json") {
22055
22068
  files.push({ rel: rel.split(sep).join("/"), content: new TextEncoder().encode(canonicalizeManifest(new TextDecoder().decode(buffer))) });
22056
22069
  return;
@@ -22250,14 +22263,14 @@ function validateRuntimeContract(manifest, issues, strict) {
22250
22263
  // src/lib/portable-skills-files.ts
22251
22264
  import {
22252
22265
  cpSync,
22253
- existsSync as existsSync4,
22266
+ existsSync as existsSync5,
22254
22267
  lstatSync as lstatSync2,
22255
22268
  mkdirSync as mkdirSync2,
22256
- readFileSync as readFileSync4,
22269
+ readFileSync as readFileSync5,
22257
22270
  realpathSync,
22258
22271
  writeFileSync as writeFileSync2
22259
22272
  } from "fs";
22260
- import { basename, dirname as dirname2, join as join4, relative } from "path";
22273
+ import { basename, dirname as dirname2, join as join5, relative } from "path";
22261
22274
  var ANY_SEGMENT_COPY_EXCLUDES = new Set([
22262
22275
  ".git",
22263
22276
  ".DS_Store",
@@ -22300,12 +22313,12 @@ function normalizePortableSkillName(name) {
22300
22313
  return normalized;
22301
22314
  }
22302
22315
  function readPortableSkillManifest(skillPath, fallbackName = basename(skillPath)) {
22303
- const skillJsonPath = join4(skillPath, "skill.json");
22304
- const skillMdPath = join4(skillPath, "SKILL.md");
22305
- const pkgPath = join4(skillPath, "package.json");
22306
- const jsonManifest = existsSync4(skillJsonPath) ? readJsonObject(skillJsonPath) : undefined;
22307
- const frontmatter = existsSync4(skillMdPath) ? parseSkillFrontmatter(readFileSync4(skillMdPath, "utf-8")) ?? undefined : undefined;
22308
- const pkg = existsSync4(pkgPath) ? readJsonObject(pkgPath) : undefined;
22316
+ const skillJsonPath = join5(skillPath, "skill.json");
22317
+ const skillMdPath = join5(skillPath, "SKILL.md");
22318
+ const pkgPath = join5(skillPath, "package.json");
22319
+ const jsonManifest = existsSync5(skillJsonPath) ? readJsonObject(skillJsonPath) : undefined;
22320
+ const frontmatter = existsSync5(skillMdPath) ? parseSkillFrontmatter(readFileSync5(skillMdPath, "utf-8")) ?? undefined : undefined;
22321
+ const pkg = existsSync5(pkgPath) ? readJsonObject(pkgPath) : undefined;
22309
22322
  const name = normalizePortableSkillName(stringField(jsonManifest, "name") ?? frontmatter?.name ?? stringValue(pkg?.name) ?? fallbackName);
22310
22323
  const description = stringField(jsonManifest, "description") ?? frontmatter?.description ?? stringValue(pkg?.description) ?? `${name} skill`;
22311
22324
  const version2 = stringField(jsonManifest, "version") ?? frontmatter?.version ?? stringValue(pkg?.version) ?? PORTABLE_SKILL_DEFAULT_VERSION;
@@ -22351,7 +22364,7 @@ function createInstructionManifest(name, options) {
22351
22364
  }
22352
22365
  function writeInstructionSkillTemplate(skillPath, manifest) {
22353
22366
  mkdirSync2(skillPath, { recursive: true });
22354
- writeFileSync2(join4(skillPath, "SKILL.md"), renderInstructionSkillMd(manifest));
22367
+ writeFileSync2(join5(skillPath, "SKILL.md"), renderInstructionSkillMd(manifest));
22355
22368
  writeSkillJsonWithHash(skillPath, manifest);
22356
22369
  }
22357
22370
  function renderInstructionSkillMd(manifest) {
@@ -22400,12 +22413,12 @@ function createPortableManifest(name, options) {
22400
22413
  };
22401
22414
  }
22402
22415
  function writePortableSkillTemplate(skillPath, manifest) {
22403
- mkdirSync2(join4(skillPath, "src"), { recursive: true });
22404
- writeFileSync2(join4(skillPath, "SKILL.md"), renderSkillMd(manifest));
22405
- writeFileSync2(join4(skillPath, "AGENTS.md"), renderAgentsMd(manifest));
22406
- writeFileSync2(join4(skillPath, "package.json"), renderPackageJson(manifest));
22407
- writeFileSync2(join4(skillPath, "tsconfig.json"), renderTsconfig());
22408
- writeFileSync2(join4(skillPath, "src", "index.ts"), renderEntrypoint(manifest));
22416
+ mkdirSync2(join5(skillPath, "src"), { recursive: true });
22417
+ writeFileSync2(join5(skillPath, "SKILL.md"), renderSkillMd(manifest));
22418
+ writeFileSync2(join5(skillPath, "AGENTS.md"), renderAgentsMd(manifest));
22419
+ writeFileSync2(join5(skillPath, "package.json"), renderPackageJson(manifest));
22420
+ writeFileSync2(join5(skillPath, "tsconfig.json"), renderTsconfig());
22421
+ writeFileSync2(join5(skillPath, "src", "index.ts"), renderEntrypoint(manifest));
22409
22422
  writeSkillJsonWithHash(skillPath, manifest);
22410
22423
  }
22411
22424
  function fillContractDefaults(manifest, entrypoint) {
@@ -22430,7 +22443,7 @@ function writeSkillJsonWithHash(skillPath, manifest) {
22430
22443
  content_hash: undefined
22431
22444
  }
22432
22445
  };
22433
- writeFileSync2(join4(skillPath, "skill.json"), `${JSON.stringify({ ...existing, ...renderSkillJsonObject(withoutHash) }, null, 2)}
22446
+ writeFileSync2(join5(skillPath, "skill.json"), `${JSON.stringify({ ...existing, ...renderSkillJsonObject(withoutHash) }, null, 2)}
22434
22447
  `);
22435
22448
  const hash = computeContentHash(skillPath);
22436
22449
  const withHash = {
@@ -22440,16 +22453,16 @@ function writeSkillJsonWithHash(skillPath, manifest) {
22440
22453
  content_hash: hash
22441
22454
  }
22442
22455
  };
22443
- writeFileSync2(join4(skillPath, "skill.json"), `${JSON.stringify({ ...existing, ...renderSkillJsonObject(withHash) }, null, 2)}
22456
+ writeFileSync2(join5(skillPath, "skill.json"), `${JSON.stringify({ ...existing, ...renderSkillJsonObject(withHash) }, null, 2)}
22444
22457
  `);
22445
22458
  return withHash;
22446
22459
  }
22447
22460
  function readExistingSkillJson(skillPath) {
22448
- const path = join4(skillPath, "skill.json");
22449
- if (!existsSync4(path))
22461
+ const path = join5(skillPath, "skill.json");
22462
+ if (!existsSync5(path))
22450
22463
  return {};
22451
22464
  try {
22452
- const parsed = JSON.parse(readFileSync4(path, "utf-8"));
22465
+ const parsed = JSON.parse(readFileSync5(path, "utf-8"));
22453
22466
  return isRecord2(parsed) ? parsed : {};
22454
22467
  } catch {
22455
22468
  return {};
@@ -22479,28 +22492,28 @@ function ensurePortableSkillFiles(skillPath, manifest) {
22479
22492
  tags: next.tags?.length ? next.tags : ["custom", next.name]
22480
22493
  };
22481
22494
  const entry = next.commands[0]?.entry ?? "src/index.ts";
22482
- if (entry && !existsSync4(join4(skillPath, entry))) {
22483
- mkdirSync2(dirname2(join4(skillPath, entry)), { recursive: true });
22484
- writeFileSync2(join4(skillPath, entry), renderEntrypoint(next));
22495
+ if (entry && !existsSync5(join5(skillPath, entry))) {
22496
+ mkdirSync2(dirname2(join5(skillPath, entry)), { recursive: true });
22497
+ writeFileSync2(join5(skillPath, entry), renderEntrypoint(next));
22485
22498
  }
22486
- if (!existsSync4(join4(skillPath, "SKILL.md")))
22487
- writeFileSync2(join4(skillPath, "SKILL.md"), renderSkillMd(next));
22499
+ if (!existsSync5(join5(skillPath, "SKILL.md")))
22500
+ writeFileSync2(join5(skillPath, "SKILL.md"), renderSkillMd(next));
22488
22501
  else
22489
- writeFileSync2(join4(skillPath, "SKILL.md"), ensureSkillMdFrontmatter(readFileSync4(join4(skillPath, "SKILL.md"), "utf-8"), next));
22490
- if (!existsSync4(join4(skillPath, "AGENTS.md")))
22491
- writeFileSync2(join4(skillPath, "AGENTS.md"), renderAgentsMd(next));
22502
+ writeFileSync2(join5(skillPath, "SKILL.md"), ensureSkillMdFrontmatter(readFileSync5(join5(skillPath, "SKILL.md"), "utf-8"), next));
22503
+ if (!existsSync5(join5(skillPath, "AGENTS.md")))
22504
+ writeFileSync2(join5(skillPath, "AGENTS.md"), renderAgentsMd(next));
22492
22505
  ensurePackageJson(skillPath, next);
22493
- if (!existsSync4(join4(skillPath, "tsconfig.json")))
22494
- writeFileSync2(join4(skillPath, "tsconfig.json"), renderTsconfig());
22506
+ if (!existsSync5(join5(skillPath, "tsconfig.json")))
22507
+ writeFileSync2(join5(skillPath, "tsconfig.json"), renderTsconfig());
22495
22508
  writeSkillJsonWithHash(skillPath, next);
22496
22509
  return readPortableSkillManifest(skillPath, next.name);
22497
22510
  }
22498
22511
  function ensurePackageJson(skillPath, manifest) {
22499
- const pkgPath = join4(skillPath, "package.json");
22512
+ const pkgPath = join5(skillPath, "package.json");
22500
22513
  const first = manifest.commands[0] ?? { name: manifest.name, entry: "src/index.ts" };
22501
22514
  const commandName = normalizePortableSkillName(first.name || manifest.name);
22502
22515
  const entry = (first.entry ?? "src/index.ts").replace(/^\.\//, "");
22503
- if (!existsSync4(pkgPath)) {
22516
+ if (!existsSync5(pkgPath)) {
22504
22517
  writeFileSync2(pkgPath, renderPackageJson(manifest));
22505
22518
  return;
22506
22519
  }
@@ -22543,8 +22556,8 @@ function ensureInstructionSkillFiles(skillPath, manifest) {
22543
22556
  inputs: [],
22544
22557
  commands: []
22545
22558
  };
22546
- if (!existsSync4(join4(skillPath, "SKILL.md"))) {
22547
- writeFileSync2(join4(skillPath, "SKILL.md"), renderSkillMd(next));
22559
+ if (!existsSync5(join5(skillPath, "SKILL.md"))) {
22560
+ writeFileSync2(join5(skillPath, "SKILL.md"), renderSkillMd(next));
22548
22561
  }
22549
22562
  writeSkillJsonWithHash(skillPath, next);
22550
22563
  return readPortableSkillManifest(skillPath, next.name);
@@ -22795,7 +22808,7 @@ function inferPackageCommands(pkg, fallbackName) {
22795
22808
  return;
22796
22809
  }
22797
22810
  function readJsonObject(path) {
22798
- const parsed = JSON.parse(readFileSync4(path, "utf-8"));
22811
+ const parsed = JSON.parse(readFileSync5(path, "utf-8"));
22799
22812
  if (!isRecord2(parsed))
22800
22813
  throw new Error(`${basename(path)} must contain a JSON object`);
22801
22814
  return parsed;
@@ -22827,36 +22840,36 @@ var LEGACY_CUSTOM_DIRNAME = "custom";
22827
22840
  function getPortableSkillsRoot(options = {}) {
22828
22841
  if (options.rootDir)
22829
22842
  return options.rootDir;
22830
- const appDir = options.homeDir ? join5(options.homeDir, ".hasna", "skills") : getDataDir();
22831
- const cache = join5(appDir, SKILLS_CACHE_DIRNAME);
22843
+ const appDir = options.homeDir ? join6(options.homeDir, ".hasna", "skills") : getDataDir();
22844
+ const cache = join6(appDir, SKILLS_CACHE_DIRNAME);
22832
22845
  if (isOwnerLayoutMigrated(appDir) && safeIsDirectory(cache))
22833
22846
  return cache;
22834
- const installed = join5(appDir, INSTALLED_SKILLS_DIRNAME);
22847
+ const installed = join6(appDir, INSTALLED_SKILLS_DIRNAME);
22835
22848
  migrateLegacySkillLayout(appDir, installed);
22836
22849
  return installed;
22837
22850
  }
22838
22851
  function looksLikeSkillDirectory(path) {
22839
22852
  if (!safeIsDirectory(path))
22840
22853
  return false;
22841
- return existsSync5(join5(path, "SKILL.md")) || existsSync5(join5(path, "skill.json")) || existsSync5(join5(path, "package.json"));
22854
+ return existsSync6(join6(path, "SKILL.md")) || existsSync6(join6(path, "skill.json")) || existsSync6(join6(path, "package.json"));
22842
22855
  }
22843
22856
  function migrateLegacySkillLayout(appDir, installed) {
22844
22857
  if (!safeIsDirectory(appDir))
22845
22858
  return;
22846
22859
  const candidates = [];
22847
22860
  try {
22848
- for (const entry of readdirSync4(appDir)) {
22861
+ for (const entry of readdirSync5(appDir)) {
22849
22862
  if (entry.startsWith(".") || entry === INSTALLED_SKILLS_DIRNAME)
22850
22863
  continue;
22851
- const path = join5(appDir, entry);
22864
+ const path = join6(appDir, entry);
22852
22865
  if (entry === LEGACY_CUSTOM_DIRNAME) {
22853
22866
  if (!safeIsDirectory(path))
22854
22867
  continue;
22855
22868
  try {
22856
- for (const nested of readdirSync4(path)) {
22869
+ for (const nested of readdirSync5(path)) {
22857
22870
  if (nested.startsWith("."))
22858
22871
  continue;
22859
- const nestedPath = join5(path, nested);
22872
+ const nestedPath = join6(path, nested);
22860
22873
  if (looksLikeSkillDirectory(nestedPath))
22861
22874
  candidates.push({ from: nestedPath, name: nested });
22862
22875
  }
@@ -22870,10 +22883,10 @@ function migrateLegacySkillLayout(appDir, installed) {
22870
22883
  return;
22871
22884
  }
22872
22885
  for (const { from, name } of candidates) {
22873
- const target = join5(installed, name);
22874
- if (existsSync5(target))
22886
+ const target = join6(installed, name);
22887
+ if (existsSync6(target))
22875
22888
  continue;
22876
- const staging = join5(installed, `.migrating-${name}-${process.pid}`);
22889
+ const staging = join6(installed, `.migrating-${name}-${process.pid}`);
22877
22890
  try {
22878
22891
  rmSync(staging, { recursive: true, force: true });
22879
22892
  cpSync2(from, staging, { recursive: true, errorOnExist: false });
@@ -22886,7 +22899,7 @@ function migrateLegacySkillLayout(appDir, installed) {
22886
22899
  }
22887
22900
  }
22888
22901
  function getPortableSkillPath(name, options = {}) {
22889
- return join5(getPortableSkillsRoot(options), normalizePortableSkillName(name));
22902
+ return join6(getPortableSkillsRoot(options), normalizePortableSkillName(name));
22890
22903
  }
22891
22904
  function findPortableSkill(name, options = {}) {
22892
22905
  let normalized;
@@ -22896,7 +22909,7 @@ function findPortableSkill(name, options = {}) {
22896
22909
  return null;
22897
22910
  }
22898
22911
  const path = getPortableSkillPath(normalized, options);
22899
- if (!existsSync5(path) || !statSync5(path).isDirectory())
22912
+ if (!existsSync6(path) || !statSync6(path).isDirectory())
22900
22913
  return null;
22901
22914
  try {
22902
22915
  return summarizePortableSkill(path, normalized);
@@ -22909,10 +22922,10 @@ function listPortableSkills(options = {}) {
22909
22922
  if (!safeIsDirectory(root))
22910
22923
  return [];
22911
22924
  const skills = [];
22912
- for (const entry of readdirSync4(root).sort()) {
22925
+ for (const entry of readdirSync5(root).sort()) {
22913
22926
  if (entry.startsWith("."))
22914
22927
  continue;
22915
- const path = join5(root, entry);
22928
+ const path = join6(root, entry);
22916
22929
  if (!safeIsDirectory(path))
22917
22930
  continue;
22918
22931
  try {
@@ -22934,7 +22947,8 @@ function listPortableSkillMetas(options = {}) {
22934
22947
  tags: manifest.tags || ["custom"],
22935
22948
  version: skill.version,
22936
22949
  ...manifest.kind ? { kind: manifest.kind } : {},
22937
- source: "custom"
22950
+ source: "custom",
22951
+ ...isHostedMetadataSkillDir(skill.path) ? { serverOwned: true } : {}
22938
22952
  };
22939
22953
  });
22940
22954
  }
@@ -22945,8 +22959,8 @@ function isOfficialSkillName(name) {
22945
22959
  function scaffoldPortableSkill(name, options = {}) {
22946
22960
  const skillName = normalizePortableSkillName(name);
22947
22961
  const root = getPortableSkillsRoot(options);
22948
- const skillPath = join5(root, skillName);
22949
- if (existsSync5(skillPath)) {
22962
+ const skillPath = join6(root, skillName);
22963
+ if (existsSync6(skillPath)) {
22950
22964
  if (!options.overwrite)
22951
22965
  throw new Error(`Skill '${skillName}' already exists at ${skillPath}`);
22952
22966
  rmSync(skillPath, { recursive: true, force: true });
@@ -22964,7 +22978,7 @@ function scaffoldPortableSkill(name, options = {}) {
22964
22978
  }
22965
22979
  function portPortableSkill(sourcePath, options = {}) {
22966
22980
  const absoluteSource = normalize2(sourcePath);
22967
- if (!existsSync5(absoluteSource) || !statSync5(absoluteSource).isDirectory()) {
22981
+ if (!existsSync6(absoluteSource) || !statSync6(absoluteSource).isDirectory()) {
22968
22982
  throw new Error(`Skill source directory not found: ${sourcePath}`);
22969
22983
  }
22970
22984
  const inferred = readPortableSkillManifest(absoluteSource, basename2(absoluteSource));
@@ -22976,8 +22990,8 @@ function portPortableSkill(sourcePath, options = {}) {
22976
22990
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
22977
22991
  }
22978
22992
  const root = getPortableSkillsRoot(options);
22979
- const destination = join5(root, skillName);
22980
- if (existsSync5(destination)) {
22993
+ const destination = join6(root, skillName);
22994
+ if (existsSync6(destination)) {
22981
22995
  if (!options.overwrite)
22982
22996
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
22983
22997
  rmSync(destination, { recursive: true, force: true });
@@ -23005,10 +23019,10 @@ function validatePortableSkillDirectory(name, skillPath) {
23005
23019
  const issues = [...base.issues];
23006
23020
  const warnings = [...base.warnings];
23007
23021
  let manifest;
23008
- if (existsSync5(skillPath)) {
23009
- const skillJsonPath = join5(skillPath, "skill.json");
23010
- const skillMdPath = join5(skillPath, "SKILL.md");
23011
- if (!existsSync5(skillJsonPath) && !existsSync5(skillMdPath)) {
23022
+ if (existsSync6(skillPath)) {
23023
+ const skillJsonPath = join6(skillPath, "skill.json");
23024
+ const skillMdPath = join6(skillPath, "SKILL.md");
23025
+ if (!existsSync6(skillJsonPath) && !existsSync6(skillMdPath)) {
23012
23026
  add3(issues, "portable.manifest_missing", "Missing portable manifest: expected SKILL.md frontmatter and/or skill.json");
23013
23027
  }
23014
23028
  try {
@@ -23027,7 +23041,7 @@ function validatePortableSkillDirectory(name, skillPath) {
23027
23041
  add3(issues, "portable.version_missing", "Portable manifest missing version");
23028
23042
  }
23029
23043
  const contractIssues = validatePortableManifestContract(manifest, {
23030
- strict: existsSync5(join5(skillPath, "skill.json")),
23044
+ strict: existsSync6(join6(skillPath, "skill.json")),
23031
23045
  skillPath
23032
23046
  });
23033
23047
  for (const issue2 of contractIssues)
@@ -23063,10 +23077,10 @@ function validatePortableSkillDirectory(name, skillPath) {
23063
23077
  add3(issues, "portable.command_entry_unsafe", `Command '${command.name}' entry '${command.entry}' must stay inside the skill directory`);
23064
23078
  continue;
23065
23079
  }
23066
- const entryPath = join5(skillPath, command.entry);
23067
- if (!existsSync5(entryPath))
23080
+ const entryPath = join6(skillPath, command.entry);
23081
+ if (!existsSync6(entryPath))
23068
23082
  add3(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
23069
- else if (statSync5(entryPath).isDirectory())
23083
+ else if (statSync6(entryPath).isDirectory())
23070
23084
  add3(issues, "portable.command_entry_directory", `Command '${command.name}' entry '${command.entry}' must be a file`);
23071
23085
  }
23072
23086
  }
@@ -23074,7 +23088,7 @@ function validatePortableSkillDirectory(name, skillPath) {
23074
23088
  } catch (error2) {
23075
23089
  add3(issues, "portable.manifest_invalid", error2.message);
23076
23090
  }
23077
- if (manifest?.kind !== "instruction" && !existsSync5(join5(skillPath, "AGENTS.md"))) {
23091
+ if (manifest?.kind !== "instruction" && !existsSync6(join6(skillPath, "AGENTS.md"))) {
23078
23092
  add3(issues, "portable.agents_missing", "Missing AGENTS.md with build-out instructions for coding agents");
23079
23093
  }
23080
23094
  }
@@ -23106,7 +23120,7 @@ function summarizePortableSkill(skillPath, fallbackName) {
23106
23120
  }
23107
23121
  function safeIsDirectory(path) {
23108
23122
  try {
23109
- return statSync5(path).isDirectory();
23123
+ return statSync6(path).isDirectory();
23110
23124
  } catch {
23111
23125
  return false;
23112
23126
  }
@@ -23332,20 +23346,20 @@ function parseSkillMdFrontmatter(content) {
23332
23346
  return Object.keys(result).length > 0 ? result : null;
23333
23347
  }
23334
23348
  function discoverSkillsInDir(dir, source = "custom") {
23335
- if (!existsSync6(dir))
23349
+ if (!existsSync7(dir))
23336
23350
  return [];
23337
23351
  const result = [];
23338
23352
  try {
23339
- const entries = readdirSync5(dir, { withFileTypes: true });
23353
+ const entries = readdirSync6(dir, { withFileTypes: true });
23340
23354
  for (const entry of entries) {
23341
23355
  if (!entry.isDirectory())
23342
23356
  continue;
23343
- const skillMdPath = join6(dir, entry.name, "SKILL.md");
23344
- if (!existsSync6(skillMdPath))
23357
+ const skillMdPath = join7(dir, entry.name, "SKILL.md");
23358
+ if (!existsSync7(skillMdPath))
23345
23359
  continue;
23346
23360
  let content;
23347
23361
  try {
23348
- content = readFileSync5(skillMdPath, "utf-8");
23362
+ content = readFileSync6(skillMdPath, "utf-8");
23349
23363
  } catch {
23350
23364
  continue;
23351
23365
  }
@@ -23360,6 +23374,7 @@ function discoverSkillsInDir(dir, source = "custom") {
23360
23374
  category: fm.category || "Development Tools",
23361
23375
  tags: fm.tags || [],
23362
23376
  ...fm.kind ? { kind: fm.kind } : {},
23377
+ ...isHostedMetadataSkillDir(join7(dir, entry.name)) ? { serverOwned: true } : {},
23363
23378
  source
23364
23379
  });
23365
23380
  }
@@ -23368,20 +23383,20 @@ function discoverSkillsInDir(dir, source = "custom") {
23368
23383
  }
23369
23384
  function findExtensionSkillPath(name) {
23370
23385
  const config2 = loadConfig();
23371
- if (!config2.extensionsDir || !existsSync6(config2.extensionsDir))
23386
+ if (!config2.extensionsDir || !existsSync7(config2.extensionsDir))
23372
23387
  return null;
23373
23388
  try {
23374
- const entries = readdirSync5(config2.extensionsDir, { withFileTypes: true });
23389
+ const entries = readdirSync6(config2.extensionsDir, { withFileTypes: true });
23375
23390
  for (const entry of entries) {
23376
23391
  if (!entry.isDirectory())
23377
23392
  continue;
23378
- const skillDir = join6(config2.extensionsDir, entry.name);
23379
- const skillMdPath = join6(skillDir, "SKILL.md");
23380
- if (!existsSync6(skillMdPath))
23393
+ const skillDir = join7(config2.extensionsDir, entry.name);
23394
+ const skillMdPath = join7(skillDir, "SKILL.md");
23395
+ if (!existsSync7(skillMdPath))
23381
23396
  continue;
23382
23397
  let content;
23383
23398
  try {
23384
- content = readFileSync5(skillMdPath, "utf-8");
23399
+ content = readFileSync6(skillMdPath, "utf-8");
23385
23400
  } catch {
23386
23401
  continue;
23387
23402
  }
@@ -23414,7 +23429,7 @@ function loadRegistry(cwd) {
23414
23429
  const official = SKILLS.map((s) => ({ ...s, source: "official" }));
23415
23430
  const extensions = config2.extensionsDir ? discoverSkillsInDir(config2.extensionsDir, "extension") : [];
23416
23431
  const portableCustom = listPortableSkillMetas();
23417
- const legacyCustom = discoverSkillsInDir(join6(dataDir, "custom"));
23432
+ const legacyCustom = discoverSkillsInDir(join7(dataDir, "custom"));
23418
23433
  const globalCustom = mergeCustomSkills([...legacyCustom, ...portableCustom]);
23419
23434
  registryCache = mergeSkillRegistryLists(official, extensions, globalCustom);
23420
23435
  registryCacheTime = now;
@@ -23450,8 +23465,8 @@ function mergeCustomSkills(skills) {
23450
23465
  }
23451
23466
 
23452
23467
  // src/lib/installer.ts
23453
- import { existsSync as existsSync8, readFileSync as readFileSync7, rmSync as rmSync2 } from "fs";
23454
- import { dirname as dirname4, join as join8 } from "path";
23468
+ import { existsSync as existsSync9, readFileSync as readFileSync8, rmSync as rmSync2 } from "fs";
23469
+ import { dirname as dirname4, join as join9 } from "path";
23455
23470
  import { homedir as homedir2 } from "os";
23456
23471
  import { fileURLToPath } from "url";
23457
23472
 
@@ -23468,8 +23483,8 @@ function normalizeSkillName(name) {
23468
23483
  init_config();
23469
23484
 
23470
23485
  // src/lib/project-state.ts
23471
- import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
23472
- import { join as join7 } from "path";
23486
+ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
23487
+ import { join as join8 } from "path";
23473
23488
  var VALID_PIN_SOURCES = [
23474
23489
  "official",
23475
23490
  "custom",
@@ -23484,17 +23499,17 @@ var SKILLS_PROJECT_DIR = ".skills";
23484
23499
  var PROJECT_CONFIG_FILE = "project.json";
23485
23500
  var DEFAULT_EXPORT_DIR = ".skills/exports";
23486
23501
  function getProjectStateDir(targetDir = process.cwd()) {
23487
- return join7(targetDir, SKILLS_PROJECT_DIR);
23502
+ return join8(targetDir, SKILLS_PROJECT_DIR);
23488
23503
  }
23489
23504
  function getProjectConfigPath(targetDir = process.cwd()) {
23490
- return join7(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
23505
+ return join8(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
23491
23506
  }
23492
23507
  function loadProjectConfig(targetDir = process.cwd()) {
23493
23508
  const path = getProjectConfigPath(targetDir);
23494
- if (!existsSync7(path))
23509
+ if (!existsSync8(path))
23495
23510
  return null;
23496
23511
  try {
23497
- return normalizeProjectConfig(JSON.parse(readFileSync6(path, "utf-8")));
23512
+ return normalizeProjectConfig(JSON.parse(readFileSync7(path, "utf-8")));
23498
23513
  } catch {
23499
23514
  return null;
23500
23515
  }
@@ -23593,12 +23608,12 @@ var __dirname2 = dirname4(fileURLToPath(import.meta.url));
23593
23608
  function findSkillsDir() {
23594
23609
  let dir = __dirname2;
23595
23610
  for (let i = 0;i < 5; i++) {
23596
- const candidate = join8(dir, "skills");
23597
- if (existsSync8(candidate) && !dir.includes(".skills"))
23611
+ const candidate = join9(dir, "skills");
23612
+ if (existsSync9(candidate) && !dir.includes(".skills"))
23598
23613
  return candidate;
23599
23614
  dir = dirname4(dir);
23600
23615
  }
23601
- return join8(__dirname2, "..", "skills");
23616
+ return join9(__dirname2, "..", "skills");
23602
23617
  }
23603
23618
  var SKILLS_DIR = findSkillsDir();
23604
23619
  function getSkillPath(name) {
@@ -23606,13 +23621,13 @@ function getSkillPath(name) {
23606
23621
  const portable = findPortableSkill(skillName);
23607
23622
  if (portable)
23608
23623
  return portable.path;
23609
- const legacyCustomPath = join8(getDataDir(), "custom", skillName);
23610
- if (existsSync8(legacyCustomPath))
23624
+ const legacyCustomPath = join9(getDataDir(), "custom", skillName);
23625
+ if (existsSync9(legacyCustomPath))
23611
23626
  return legacyCustomPath;
23612
23627
  const extensionPath = findExtensionSkillPath(skillName);
23613
23628
  if (extensionPath)
23614
23629
  return extensionPath;
23615
- return join8(SKILLS_DIR, skillName);
23630
+ return join9(SKILLS_DIR, skillName);
23616
23631
  }
23617
23632
  function getCanonicalSkillName(name) {
23618
23633
  return getSkill(name)?.name ?? resolveSkillAlias(normalizeSkillSlug(name));
@@ -23621,7 +23636,7 @@ function installSkill(name, options = {}) {
23621
23636
  const { targetDir = process.cwd(), overwrite = false } = options;
23622
23637
  const canonicalName = getCanonicalSkillName(name);
23623
23638
  const skillName = normalizeSkillName(canonicalName);
23624
- if (!existsSync8(getSkillPath(name))) {
23639
+ if (!existsSync9(getSkillPath(name))) {
23625
23640
  const knownOfficial = Boolean(getSkill(name));
23626
23641
  return {
23627
23642
  skill: canonicalName,
@@ -23676,11 +23691,11 @@ function getAgentSkillsDir(agent, scope = "global", projectDir) {
23676
23691
  const base = projectDir || process.cwd();
23677
23692
  switch (agent) {
23678
23693
  case "pi":
23679
- return scope === "project" ? join8(base, ".pi", "skills") : join8(homedir2(), ".pi", "agent", "skills");
23694
+ return scope === "project" ? join9(base, ".pi", "skills") : join9(homedir2(), ".pi", "agent", "skills");
23680
23695
  case "opencode":
23681
- return scope === "project" ? join8(base, ".opencode", "skills") : join8(homedir2(), ".config", "opencode", "skills");
23696
+ return scope === "project" ? join9(base, ".opencode", "skills") : join9(homedir2(), ".config", "opencode", "skills");
23682
23697
  default:
23683
- return scope === "project" ? join8(base, `.${agent}`, "skills") : join8(homedir2(), `.${agent}`, "skills");
23698
+ return scope === "project" ? join9(base, `.${agent}`, "skills") : join9(homedir2(), `.${agent}`, "skills");
23684
23699
  }
23685
23700
  }
23686
23701
  function warnMissingDependencies(name, targetDir) {
@@ -23695,11 +23710,11 @@ function warnMissingDependencies(name, targetDir) {
23695
23710
  }
23696
23711
  }
23697
23712
  function readBundledSkillVersion(name) {
23698
- const pkgPath = join8(getSkillPath(name), "package.json");
23699
- if (!existsSync8(pkgPath))
23713
+ const pkgPath = join9(getSkillPath(name), "package.json");
23714
+ if (!existsSync9(pkgPath))
23700
23715
  return "unknown";
23701
23716
  try {
23702
- const pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
23717
+ const pkg = JSON.parse(readFileSync8(pkgPath, "utf-8"));
23703
23718
  return pkg.version || "unknown";
23704
23719
  } catch {
23705
23720
  return "unknown";
@@ -23707,16 +23722,16 @@ function readBundledSkillVersion(name) {
23707
23722
  }
23708
23723
 
23709
23724
  // src/lib/skillinfo.ts
23710
- import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
23711
- import { join as join9 } from "path";
23725
+ import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
23726
+ import { join as join10 } from "path";
23712
23727
  function isInstructionSkillDir(skillPath, meta) {
23713
23728
  if (meta?.kind === "instruction")
23714
23729
  return true;
23715
- const skillMdPath = join9(skillPath, "SKILL.md");
23716
- if (!existsSync9(skillMdPath))
23730
+ const skillMdPath = join10(skillPath, "SKILL.md");
23731
+ if (!existsSync10(skillMdPath))
23717
23732
  return false;
23718
23733
  try {
23719
- return parseSkillFrontmatter(readFileSync8(skillMdPath, "utf-8"))?.kind === "instruction";
23734
+ return parseSkillFrontmatter(readFileSync9(skillMdPath, "utf-8"))?.kind === "instruction";
23720
23735
  } catch {
23721
23736
  return false;
23722
23737
  }
@@ -23739,12 +23754,12 @@ var HOSTED_PROVIDER_ENV_PREFIXES = [
23739
23754
  ];
23740
23755
  function getSkillDocs(name) {
23741
23756
  const skillPath = getSkillPath(name);
23742
- if (!existsSync9(skillPath))
23757
+ if (!existsSync10(skillPath))
23743
23758
  return null;
23744
23759
  return {
23745
- skillMd: readIfExists(join9(skillPath, "SKILL.md")),
23746
- readme: readIfExists(join9(skillPath, "README.md")),
23747
- claudeMd: readIfExists(join9(skillPath, "CLAUDE.md"))
23760
+ skillMd: readIfExists(join10(skillPath, "SKILL.md")),
23761
+ readme: readIfExists(join10(skillPath, "README.md")),
23762
+ claudeMd: readIfExists(join10(skillPath, "CLAUDE.md"))
23748
23763
  };
23749
23764
  }
23750
23765
  function getSkillBestDoc(name) {
@@ -23755,11 +23770,11 @@ function getSkillBestDoc(name) {
23755
23770
  }
23756
23771
  function getSkillRequirements(name) {
23757
23772
  const skillPath = getSkillPath(name);
23758
- if (!existsSync9(skillPath))
23773
+ if (!existsSync10(skillPath))
23759
23774
  return null;
23760
23775
  const texts = [];
23761
23776
  for (const file of ["SKILL.md", "README.md", "CLAUDE.md", ".env.example", ".env.local.example"]) {
23762
- const content = readIfExists(join9(skillPath, file));
23777
+ const content = readIfExists(join10(skillPath, file));
23763
23778
  if (content)
23764
23779
  texts.push(content);
23765
23780
  }
@@ -23798,10 +23813,10 @@ function getSkillRequirements(name) {
23798
23813
  const skillName = normalizeSkillName(name);
23799
23814
  let cliCommand = `skills run ${skillName}`;
23800
23815
  let dependencies = {};
23801
- const pkgPath = join9(skillPath, "package.json");
23802
- if (existsSync9(pkgPath)) {
23816
+ const pkgPath = join10(skillPath, "package.json");
23817
+ if (existsSync10(pkgPath)) {
23803
23818
  try {
23804
- const pkg = JSON.parse(readFileSync8(pkgPath, "utf-8"));
23819
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
23805
23820
  dependencies = pkg.dependencies || {};
23806
23821
  } catch {}
23807
23822
  }
@@ -23819,7 +23834,7 @@ async function runSkill(name, args, options = {}) {
23819
23834
  const meta = getSkill(name);
23820
23835
  const canonicalName = meta?.name ?? name;
23821
23836
  const skillPath = getSkillPath(canonicalName);
23822
- if (!existsSync9(skillPath)) {
23837
+ if (!existsSync10(skillPath)) {
23823
23838
  return { exitCode: 1, error: `Skill '${name}' not found` };
23824
23839
  }
23825
23840
  if (isInstructionSkillDir(skillPath, meta)) {
@@ -23828,13 +23843,13 @@ async function runSkill(name, args, options = {}) {
23828
23843
  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'.`
23829
23844
  };
23830
23845
  }
23831
- const pkgPath = join9(skillPath, "package.json");
23832
- if (!existsSync9(pkgPath)) {
23846
+ const pkgPath = join10(skillPath, "package.json");
23847
+ if (!existsSync10(pkgPath)) {
23833
23848
  return { exitCode: 1, error: `No package.json in skill '${name}'` };
23834
23849
  }
23835
23850
  let entryPoint;
23836
23851
  try {
23837
- const pkg = JSON.parse(readFileSync8(pkgPath, "utf-8"));
23852
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
23838
23853
  if (pkg.bin) {
23839
23854
  const binValues = Object.values(pkg.bin);
23840
23855
  entryPoint = binValues[0];
@@ -23848,12 +23863,12 @@ async function runSkill(name, args, options = {}) {
23848
23863
  } catch {
23849
23864
  return { exitCode: 1, error: `Failed to parse package.json for skill '${name}'` };
23850
23865
  }
23851
- const entryPath = join9(skillPath, entryPoint);
23852
- if (!existsSync9(entryPath)) {
23866
+ const entryPath = join10(skillPath, entryPoint);
23867
+ if (!existsSync10(entryPath)) {
23853
23868
  return { exitCode: 1, error: `Entry point '${entryPoint}' not found in skill '${name}'` };
23854
23869
  }
23855
- const nodeModules = join9(skillPath, "node_modules");
23856
- if (!existsSync9(nodeModules)) {
23870
+ const nodeModules = join10(skillPath, "node_modules");
23871
+ if (!existsSync10(nodeModules)) {
23857
23872
  const install = Bun.spawn(["bun", "install", "--no-save"], {
23858
23873
  cwd: skillPath,
23859
23874
  stdout: "pipe",
@@ -23880,15 +23895,15 @@ async function runSkill(name, args, options = {}) {
23880
23895
  return { exitCode };
23881
23896
  }
23882
23897
  function detectProjectSkills(cwd = process.cwd()) {
23883
- const pkgPath = join9(cwd, "package.json");
23884
- if (!existsSync9(pkgPath)) {
23898
+ const pkgPath = join10(cwd, "package.json");
23899
+ if (!existsSync10(pkgPath)) {
23885
23900
  const alwaysRecommend = ["market-research-report", "repo-onboarding-report", "blog-article"];
23886
23901
  const recommended2 = alwaysRecommend.map((name) => loadRegistry().find((s) => s.name === name)).filter((s) => s !== undefined);
23887
23902
  return { detected: [], recommended: recommended2 };
23888
23903
  }
23889
23904
  let pkg;
23890
23905
  try {
23891
- pkg = JSON.parse(readFileSync8(pkgPath, "utf-8"));
23906
+ pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
23892
23907
  } catch {
23893
23908
  const alwaysRecommend = ["market-research-report", "repo-onboarding-report", "blog-article"];
23894
23909
  const recommended2 = alwaysRecommend.map((name) => loadRegistry().find((s) => s.name === name)).filter((s) => s !== undefined);
@@ -23977,8 +23992,8 @@ function extractEnvVars(text) {
23977
23992
  }
23978
23993
  function readIfExists(path) {
23979
23994
  try {
23980
- if (existsSync9(path)) {
23981
- return readFileSync8(path, "utf-8");
23995
+ if (existsSync10(path)) {
23996
+ return readFileSync9(path, "utf-8");
23982
23997
  }
23983
23998
  } catch {}
23984
23999
  return null;
@@ -25560,25 +25575,25 @@ function registerDiscoveryTools(server) {
25560
25575
  }
25561
25576
 
25562
25577
  // src/mcp/operation-tools.ts
25563
- import { existsSync as existsSync12, readdirSync as readdirSync7, statSync as statSync7 } from "fs";
25564
- import { join as join12 } from "path";
25578
+ import { existsSync as existsSync13, readdirSync as readdirSync8, statSync as statSync8 } from "fs";
25579
+ import { join as join13 } from "path";
25565
25580
 
25566
25581
  // src/lib/run-state.ts
25567
25582
  import { createHash as createHash2, randomBytes } from "crypto";
25568
- import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as readFileSync9, readdirSync as readdirSync6, statSync as statSync6, writeFileSync as writeFileSync5 } from "fs";
25569
- import { extname, join as join10, relative as relative2 } from "path";
25583
+ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync10, readdirSync as readdirSync7, statSync as statSync7, writeFileSync as writeFileSync5 } from "fs";
25584
+ import { extname, join as join11, relative as relative2 } from "path";
25570
25585
  function createSkillRun(params, targetDir = process.cwd()) {
25571
25586
  const now = new Date;
25572
25587
  const id = createRunId(now);
25573
25588
  const day = now.toISOString().slice(0, 10);
25574
25589
  const skillName = normalizeSkillName(params.skill);
25575
25590
  const root = getProjectStateDir(targetDir);
25576
- const runDir = join10(root, "runs", day, id);
25577
- const logsDir = join10(runDir, "logs");
25578
- const exportDir = join10(root, "exports", skillName, id);
25591
+ const runDir = join11(root, "runs", day, id);
25592
+ const logsDir = join11(runDir, "logs");
25593
+ const exportDir = join11(root, "exports", skillName, id);
25579
25594
  mkdirSync5(logsDir, { recursive: true });
25580
25595
  mkdirSync5(exportDir, { recursive: true });
25581
- mkdirSync5(join10(root, "tmp"), { recursive: true });
25596
+ mkdirSync5(join11(root, "tmp"), { recursive: true });
25582
25597
  const record3 = {
25583
25598
  id,
25584
25599
  skill: skillName,
@@ -25629,22 +25644,22 @@ function updateSkillRun(context, patch) {
25629
25644
  return context.record;
25630
25645
  }
25631
25646
  function writeRunLogs(context, stdout = "", stderr = "") {
25632
- writeFileSync5(join10(context.logsDir, "stdout.log"), stdout);
25633
- writeFileSync5(join10(context.logsDir, "stderr.log"), stderr);
25647
+ writeFileSync5(join11(context.logsDir, "stdout.log"), stdout);
25648
+ writeFileSync5(join11(context.logsDir, "stderr.log"), stderr);
25634
25649
  }
25635
25650
  function appendRunEvent(context, event, data = {}) {
25636
25651
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
25637
25652
  `;
25638
- const path = join10(context.runDir, "events.ndjson");
25639
- const previous = existsSync10(path) ? readFileSync9(path, "utf-8") : "";
25653
+ const path = join11(context.runDir, "events.ndjson");
25654
+ const previous = existsSync11(path) ? readFileSync10(path, "utf-8") : "";
25640
25655
  writeFileSync5(path, previous + line);
25641
25656
  }
25642
25657
  function findSkillRun(runId, targetDir = process.cwd()) {
25643
- const runsRoot = join10(getProjectStateDir(targetDir), "runs");
25644
- if (!existsSync10(runsRoot))
25658
+ const runsRoot = join11(getProjectStateDir(targetDir), "runs");
25659
+ if (!existsSync11(runsRoot))
25645
25660
  return null;
25646
- for (const day of readdirSync6(runsRoot)) {
25647
- const record3 = readRunRecord(join10(runsRoot, day, runId));
25661
+ for (const day of readdirSync7(runsRoot)) {
25662
+ const record3 = readRunRecord(join11(runsRoot, day, runId));
25648
25663
  if (record3)
25649
25664
  return record3;
25650
25665
  }
@@ -25661,20 +25676,20 @@ function skillRunEnv(context) {
25661
25676
  };
25662
25677
  }
25663
25678
  function writeRunRecord(context) {
25664
- writeFileSync5(join10(context.runDir, "run.json"), JSON.stringify(context.record, null, 2) + `
25679
+ writeFileSync5(join11(context.runDir, "run.json"), JSON.stringify(context.record, null, 2) + `
25665
25680
  `);
25666
25681
  }
25667
25682
  function writeArtifactsManifest(context, artifacts) {
25668
- writeFileSync5(join10(context.runDir, "artifacts.json"), JSON.stringify({ runId: context.record.id, artifacts }, null, 2) + `
25683
+ writeFileSync5(join11(context.runDir, "artifacts.json"), JSON.stringify({ runId: context.record.id, artifacts }, null, 2) + `
25669
25684
  `);
25670
25685
  }
25671
25686
  function collectRunArtifacts(context) {
25672
- if (!existsSync10(context.exportDir))
25687
+ if (!existsSync11(context.exportDir))
25673
25688
  return [];
25674
25689
  const artifacts = [];
25675
25690
  for (const path of walkFiles(context.exportDir)) {
25676
- const stat = statSync6(path);
25677
- const bytes = readFileSync9(path);
25691
+ const stat = statSync7(path);
25692
+ const bytes = readFileSync10(path);
25678
25693
  artifacts.push({
25679
25694
  path: toProjectRelative(context.targetDir, path),
25680
25695
  mime: mimeForPath(path),
@@ -25685,20 +25700,20 @@ function collectRunArtifacts(context) {
25685
25700
  return artifacts.sort((a, b) => a.path.localeCompare(b.path));
25686
25701
  }
25687
25702
  function readRunRecord(runDir) {
25688
- const path = join10(runDir, "run.json");
25689
- if (!existsSync10(path))
25703
+ const path = join11(runDir, "run.json");
25704
+ if (!existsSync11(path))
25690
25705
  return null;
25691
25706
  try {
25692
- return JSON.parse(readFileSync9(path, "utf-8"));
25707
+ return JSON.parse(readFileSync10(path, "utf-8"));
25693
25708
  } catch {
25694
25709
  return null;
25695
25710
  }
25696
25711
  }
25697
25712
  function walkFiles(dir) {
25698
25713
  const files = [];
25699
- for (const entry of readdirSync6(dir)) {
25700
- const full = join10(dir, entry);
25701
- if (statSync6(full).isDirectory())
25714
+ for (const entry of readdirSync7(dir)) {
25715
+ const full = join11(dir, entry);
25716
+ if (statSync7(full).isDirectory())
25702
25717
  files.push(...walkFiles(full));
25703
25718
  else
25704
25719
  files.push(full);
@@ -25742,6 +25757,34 @@ function mimeForPath(path) {
25742
25757
  return "application/octet-stream";
25743
25758
  }
25744
25759
  }
25760
+ // src/lib/run-routing.ts
25761
+ init_api_url();
25762
+ init_auth_store();
25763
+ function isServerOwnedSkill(skill) {
25764
+ return skill.serverOwned === true;
25765
+ }
25766
+ function resolveRunRouting(skill, apiKey, apiUrl) {
25767
+ if (!isServerOwnedSkill(skill))
25768
+ return { route: "local" };
25769
+ if (!apiUrl) {
25770
+ return {
25771
+ route: "error",
25772
+ code: "REMOTE_REQUIRES_ORIGIN",
25773
+ error: `${skill.name} is a server-owned skill. Point the CLI at a Skills API: ` + `skills setup --api-url <url> (or export SKILLS_API_URL)`
25774
+ };
25775
+ }
25776
+ if (!apiKey) {
25777
+ return {
25778
+ route: "error",
25779
+ code: "REMOTE_REQUIRES_CREDENTIAL",
25780
+ error: `${skill.name} is a server-owned skill. Run: skills auth login`
25781
+ };
25782
+ }
25783
+ return { route: "remote", apiKey };
25784
+ }
25785
+ function resolveConfiguredRunRouting(skill) {
25786
+ return resolveRunRouting(skill, getApiKey(), resolveApiUrl());
25787
+ }
25745
25788
 
25746
25789
  // src/mcp/operation-tools.ts
25747
25790
  function registerOperationTools(server) {
@@ -25951,7 +25994,6 @@ function registerOperationTools(server) {
25951
25994
  if (!skill) {
25952
25995
  return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
25953
25996
  }
25954
- const { getApiKey: getApiKey2 } = await Promise.resolve().then(() => (init_auth_store(), exports_auth_store));
25955
25997
  const {
25956
25998
  ARTICLE_GENERATION_SLUG: ARTICLE_GENERATION_SLUG2,
25957
25999
  validateBlogArticleRunOptions: validateBlogArticleRunOptions2
@@ -25965,24 +26007,24 @@ function registerOperationTools(server) {
25965
26007
  return mcpError("INVALID_BLOG_ARTICLE_OPTIONS", validation.errors.join(" "));
25966
26008
  }
25967
26009
  }
25968
- const apiKey = getApiKey2();
25969
- const hostedRuntime = false;
26010
+ const routing = resolveConfiguredRunRouting(skill);
25970
26011
  const runContext = createSkillRun({
25971
26012
  skill: skillName,
25972
26013
  args: runArgs,
25973
- remote: hostedRuntime
26014
+ remote: routing.route === "remote"
25974
26015
  });
25975
- if (hostedRuntime && !apiKey) {
25976
- const error2 = `${skillName} is a hosted skill. Run: skills auth login`;
26016
+ if (routing.route === "error") {
26017
+ const error2 = routing.error;
25977
26018
  writeRunLogs(runContext, "", error2 + `
25978
26019
  `);
25979
26020
  const run = completeSkillRun(runContext, { status: "failed", error: error2 });
25980
- return mcpError("AUTH_REQUIRED", `${error2}. Local run metadata: ${run.paths.runDir}/run.json`, ["skills auth login"]);
26021
+ const suggestions = routing.code === "REMOTE_REQUIRES_ORIGIN" ? ["skills setup --api-url <url>", "skills auth login"] : ["skills auth login"];
26022
+ return mcpError(routing.code, `${error2}. Local run metadata: ${run.paths.runDir}/run.json`, suggestions);
25981
26023
  }
25982
- if (hostedRuntime && apiKey) {
26024
+ if (routing.route === "remote") {
25983
26025
  try {
25984
26026
  const { RemoteSkillsClient: RemoteSkillsClient2 } = await Promise.resolve().then(() => (init_remote_client(), exports_remote_client));
25985
- const client = new RemoteSkillsClient2(apiKey);
26027
+ const client = new RemoteSkillsClient2(routing.apiKey);
25986
26028
  const run = await client.submitRun(skillName, runInput, runArgs);
25987
26029
  if (run.error) {
25988
26030
  writeRunLogs(runContext, "", String(run.error) + `
@@ -26141,13 +26183,13 @@ function registerOperationTools(server) {
26141
26183
  const agents = [];
26142
26184
  for (const agent of AGENT_TARGETS) {
26143
26185
  const agentSkillsPath = getAgentSkillsDir(agent, "global");
26144
- const exists = existsSync12(agentSkillsPath);
26186
+ const exists = existsSync13(agentSkillsPath);
26145
26187
  let skillCount = 0;
26146
26188
  if (exists) {
26147
26189
  try {
26148
- skillCount = readdirSync7(agentSkillsPath).filter((f) => {
26149
- const full = join12(agentSkillsPath, f);
26150
- return !f.startsWith(".") && statSync7(full).isDirectory();
26190
+ skillCount = readdirSync8(agentSkillsPath).filter((f) => {
26191
+ const full = join13(agentSkillsPath, f);
26192
+ return !f.startsWith(".") && statSync8(full).isDirectory();
26151
26193
  }).length;
26152
26194
  } catch {}
26153
26195
  }
@@ -26193,16 +26235,16 @@ function compactRunToolPayload(payload, detailHint) {
26193
26235
 
26194
26236
  // src/lib/feedback.ts
26195
26237
  init_config();
26196
- import { existsSync as existsSync13, mkdirSync as mkdirSync7 } from "fs";
26197
- import { dirname as dirname6, join as join13 } from "path";
26238
+ import { existsSync as existsSync14, mkdirSync as mkdirSync7 } from "fs";
26239
+ import { dirname as dirname6, join as join14 } from "path";
26198
26240
  import { Database } from "bun:sqlite";
26199
26241
  function getFeedbackDbPath() {
26200
- return join13(getDataDir(), "skills.db");
26242
+ return join14(getDataDir(), "skills.db");
26201
26243
  }
26202
26244
  function getFeedbackDb() {
26203
26245
  const dbPath = getFeedbackDbPath();
26204
26246
  const dir = dirname6(dbPath);
26205
- if (!existsSync13(dir))
26247
+ if (!existsSync14(dir))
26206
26248
  mkdirSync7(dir, { recursive: true });
26207
26249
  const db = new Database(dbPath);
26208
26250
  db.exec("PRAGMA journal_mode = WAL");
@@ -26361,24 +26403,24 @@ function registerResourceMetaTools(server) {
26361
26403
  }
26362
26404
 
26363
26405
  // src/lib/scheduler.ts
26364
- import { existsSync as existsSync14, readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8 } from "fs";
26365
- import { join as join14 } from "path";
26406
+ import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8 } from "fs";
26407
+ import { join as join15 } from "path";
26366
26408
  function getSchedulesPath(targetDir = process.cwd()) {
26367
- return join14(targetDir, ".skills", "schedules.json");
26409
+ return join15(targetDir, ".skills", "schedules.json");
26368
26410
  }
26369
26411
  function loadSchedules(targetDir = process.cwd()) {
26370
26412
  const path = getSchedulesPath(targetDir);
26371
- if (existsSync14(path)) {
26413
+ if (existsSync15(path)) {
26372
26414
  try {
26373
- return JSON.parse(readFileSync11(path, "utf-8"));
26415
+ return JSON.parse(readFileSync12(path, "utf-8"));
26374
26416
  } catch {}
26375
26417
  }
26376
26418
  return { version: 1, schedules: [] };
26377
26419
  }
26378
26420
  function saveSchedules(data, targetDir = process.cwd()) {
26379
26421
  const path = getSchedulesPath(targetDir);
26380
- const dir = join14(targetDir, ".skills");
26381
- if (!existsSync14(dir))
26422
+ const dir = join15(targetDir, ".skills");
26423
+ if (!existsSync15(dir))
26382
26424
  mkdirSync8(dir, { recursive: true });
26383
26425
  writeFileSync7(path, JSON.stringify(data, null, 2));
26384
26426
  }
@@ -26641,14 +26683,14 @@ function registerScheduleTools(server) {
26641
26683
  init_config();
26642
26684
  import { createHash as createHash3, createHmac } from "crypto";
26643
26685
  import {
26644
- existsSync as existsSync15,
26686
+ existsSync as existsSync16,
26645
26687
  mkdirSync as mkdirSync9,
26646
- readFileSync as readFileSync12,
26647
- readdirSync as readdirSync8,
26648
- statSync as statSync8,
26688
+ readFileSync as readFileSync13,
26689
+ readdirSync as readdirSync9,
26690
+ statSync as statSync9,
26649
26691
  writeFileSync as writeFileSync8
26650
26692
  } from "fs";
26651
- import { dirname as dirname7, join as join15, normalize as normalize3, relative as relative3, sep as sep2 } from "path";
26693
+ import { dirname as dirname7, join as join16, normalize as normalize3, relative as relative3, sep as sep2 } from "path";
26652
26694
  init_retired_settings();
26653
26695
  var SKILLS_STORAGE_TABLES = [
26654
26696
  "skills_sync_records",
@@ -26725,7 +26767,7 @@ function getSkillsNativeStorageStatus(options = {}) {
26725
26767
  local: {
26726
26768
  dataDir: getDataDir(),
26727
26769
  projectStateDir: getProjectStateDir(targetDir),
26728
- feedbackDbPath: join15(getDataDir(), "skills.db")
26770
+ feedbackDbPath: join16(getDataDir(), "skills.db")
26729
26771
  },
26730
26772
  remote: {
26731
26773
  databaseConfigured: Boolean(config2.databaseUrl),
@@ -26745,9 +26787,9 @@ function getStorageStatus(options = {}) {
26745
26787
  function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
26746
26788
  const projectStateDir = getProjectStateDir(targetDir);
26747
26789
  const files = [];
26748
- if (existsSync15(projectStateDir)) {
26790
+ if (existsSync16(projectStateDir)) {
26749
26791
  for (const filePath of walkFiles2(projectStateDir)) {
26750
- const bytes = readFileSync12(filePath);
26792
+ const bytes = readFileSync13(filePath);
26751
26793
  const relativePath = toPosix(relative3(targetDir, filePath));
26752
26794
  files.push({
26753
26795
  path: relativePath,
@@ -26828,9 +26870,9 @@ function parsePositiveInteger(value) {
26828
26870
  }
26829
26871
  function walkFiles2(dir) {
26830
26872
  const files = [];
26831
- for (const entry of readdirSync8(dir)) {
26832
- const full = join15(dir, entry);
26833
- const stats = statSync8(full);
26873
+ for (const entry of readdirSync9(dir)) {
26874
+ const full = join16(dir, entry);
26875
+ const stats = statSync9(full);
26834
26876
  if (stats.isDirectory())
26835
26877
  files.push(...walkFiles2(full));
26836
26878
  else
@@ -28369,10 +28411,13 @@ if (args.includes("--version") || args.includes("-V")) {
28369
28411
  console.log(package_default.version);
28370
28412
  process.exit(0);
28371
28413
  }
28414
+ async function startMcpStdio() {
28415
+ const server2 = buildServer();
28416
+ await server2.connect(new StdioServerTransport);
28417
+ }
28372
28418
  async function main() {
28373
28419
  if (isMcpStdioMode(args)) {
28374
- const server2 = buildServer();
28375
- await server2.connect(new StdioServerTransport);
28420
+ await startMcpStdio();
28376
28421
  return;
28377
28422
  }
28378
28423
  const port = parseMcpHttpPort(args);
@@ -28385,5 +28430,6 @@ if (import.meta.main) {
28385
28430
  });
28386
28431
  }
28387
28432
  export {
28433
+ startMcpStdio,
28388
28434
  buildServer
28389
28435
  };