skilld 1.7.3 → 1.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/_chunks/agent.mjs +693 -599
  2. package/dist/_chunks/agent.mjs.map +1 -1
  3. package/dist/_chunks/assemble.mjs +3 -3
  4. package/dist/_chunks/author.mjs +51 -121
  5. package/dist/_chunks/author.mjs.map +1 -1
  6. package/dist/_chunks/cache.mjs +315 -9
  7. package/dist/_chunks/cache.mjs.map +1 -1
  8. package/dist/_chunks/cache2.mjs +2 -2
  9. package/dist/_chunks/cli-helpers.mjs +3 -3
  10. package/dist/_chunks/core.mjs +7 -4
  11. package/dist/_chunks/detect.mjs +1 -1
  12. package/dist/_chunks/embedding-cache2.mjs +2 -2
  13. package/dist/_chunks/index.d.mts +305 -112
  14. package/dist/_chunks/index.d.mts.map +1 -1
  15. package/dist/_chunks/index2.d.mts +267 -32
  16. package/dist/_chunks/index2.d.mts.map +1 -1
  17. package/dist/_chunks/index3.d.mts +32 -577
  18. package/dist/_chunks/index3.d.mts.map +1 -1
  19. package/dist/_chunks/index4.d.mts +553 -0
  20. package/dist/_chunks/index4.d.mts.map +1 -0
  21. package/dist/_chunks/install.mjs +48 -88
  22. package/dist/_chunks/install.mjs.map +1 -1
  23. package/dist/_chunks/list.mjs +1 -1
  24. package/dist/_chunks/lockfile.mjs +29 -6
  25. package/dist/_chunks/lockfile.mjs.map +1 -1
  26. package/dist/_chunks/monorepo.mjs +71 -0
  27. package/dist/_chunks/monorepo.mjs.map +1 -0
  28. package/dist/_chunks/{shared.mjs → package-registry.mjs} +2 -40
  29. package/dist/_chunks/package-registry.mjs.map +1 -0
  30. package/dist/_chunks/paths.mjs +49 -0
  31. package/dist/_chunks/paths.mjs.map +1 -0
  32. package/dist/_chunks/pool2.mjs +1 -1
  33. package/dist/_chunks/prepare.mjs +1 -1
  34. package/dist/_chunks/prepare2.mjs +5 -5
  35. package/dist/_chunks/prepare2.mjs.map +1 -1
  36. package/dist/_chunks/prompts.mjs +366 -18
  37. package/dist/_chunks/prompts.mjs.map +1 -1
  38. package/dist/_chunks/search-helpers.mjs +5 -6
  39. package/dist/_chunks/search-helpers.mjs.map +1 -1
  40. package/dist/_chunks/search-interactive.mjs +1 -1
  41. package/dist/_chunks/search.mjs +1 -2
  42. package/dist/_chunks/search.mjs.map +1 -1
  43. package/dist/_chunks/semver.mjs +13 -0
  44. package/dist/_chunks/semver.mjs.map +1 -0
  45. package/dist/_chunks/skill-installer.mjs +2 -0
  46. package/dist/_chunks/skill-installer2.mjs +155 -0
  47. package/dist/_chunks/skill-installer2.mjs.map +1 -0
  48. package/dist/_chunks/skills.mjs +10 -9
  49. package/dist/_chunks/skills.mjs.map +1 -1
  50. package/dist/_chunks/sources.mjs +549 -372
  51. package/dist/_chunks/sources.mjs.map +1 -1
  52. package/dist/_chunks/sync-pipeline.mjs +952 -0
  53. package/dist/_chunks/sync-pipeline.mjs.map +1 -0
  54. package/dist/_chunks/sync-registry.mjs +19 -13
  55. package/dist/_chunks/sync-registry.mjs.map +1 -1
  56. package/dist/_chunks/sync.mjs +797 -886
  57. package/dist/_chunks/sync.mjs.map +1 -1
  58. package/dist/_chunks/sync2.mjs +4 -2
  59. package/dist/_chunks/types.d.mts +65 -77
  60. package/dist/_chunks/types.d.mts.map +1 -1
  61. package/dist/_chunks/types2.d.mts +88 -0
  62. package/dist/_chunks/types2.d.mts.map +1 -0
  63. package/dist/_chunks/uninstall.mjs +7 -8
  64. package/dist/_chunks/uninstall.mjs.map +1 -1
  65. package/dist/_chunks/upload.mjs +2 -2
  66. package/dist/_chunks/validate.mjs +1 -1
  67. package/dist/_chunks/version.mjs +3 -13
  68. package/dist/_chunks/version.mjs.map +1 -1
  69. package/dist/_chunks/wizard.mjs +2 -2
  70. package/dist/agent/index.d.mts +2 -346
  71. package/dist/agent/index.mjs +2 -3
  72. package/dist/cache/index.d.mts +2 -2
  73. package/dist/cache/index.mjs +4 -3
  74. package/dist/cli.mjs +12 -13
  75. package/dist/cli.mjs.map +1 -1
  76. package/dist/index.d.mts +5 -4
  77. package/dist/index.mjs +4 -3
  78. package/dist/prepare.mjs +2 -2
  79. package/dist/prepare.mjs.map +1 -1
  80. package/dist/retriv/index.d.mts +2 -2
  81. package/dist/retriv/worker.d.mts +1 -1
  82. package/dist/sources/index.d.mts +3 -2
  83. package/dist/sources/index.mjs +3 -3
  84. package/dist/types.d.mts +3 -3
  85. package/package.json +2 -2
  86. package/dist/_chunks/config.mjs +0 -122
  87. package/dist/_chunks/config.mjs.map +0 -1
  88. package/dist/_chunks/prefix.mjs +0 -108
  89. package/dist/_chunks/prefix.mjs.map +0 -1
  90. package/dist/_chunks/shared.mjs.map +0 -1
  91. package/dist/_chunks/skill.mjs +0 -329
  92. package/dist/_chunks/skill.mjs.map +0 -1
  93. package/dist/_chunks/sync-shared.mjs +0 -2
  94. package/dist/_chunks/sync-shared2.mjs +0 -1020
  95. package/dist/_chunks/sync-shared2.mjs.map +0 -1
  96. package/dist/agent/index.d.mts.map +0 -1
@@ -1,8 +1,3 @@
1
- import { join } from "pathe";
2
- import { existsSync } from "node:fs";
3
- import { execSync } from "node:child_process";
4
- import { diff, gt, valid } from "semver";
5
- import { isWindows } from "std-env";
6
1
  const REPO_REGISTRY = {
7
2
  "vuejs/core": {
8
3
  owner: "vuejs",
@@ -465,39 +460,6 @@ function getRelatedPackages(packageName) {
465
460
  if (!entry) return [];
466
461
  return Object.keys(entry.packages);
467
462
  }
468
- function mapInsert(map, key, create) {
469
- let val = map.get(key);
470
- if (val === void 0) {
471
- val = create();
472
- map.set(key, val);
473
- }
474
- return val;
475
- }
476
- function semverValid(v) {
477
- return valid(v, true);
478
- }
479
- function semverGt(a, b) {
480
- return gt(a, b, true);
481
- }
482
- function semverDiff(a, b) {
483
- return diff(a, b);
484
- }
485
- let _skilldCommand;
486
- function resolveSkilldCommand() {
487
- if (_skilldCommand !== void 0) return _skilldCommand;
488
- try {
489
- execSync(`${isWindows ? "where" : "which"} skilld`, { stdio: "ignore" });
490
- _skilldCommand = "skilld";
491
- } catch {
492
- _skilldCommand = "npx -y skilld";
493
- }
494
- return _skilldCommand;
495
- }
496
- const SHARED_SKILLS_DIR = ".skills";
497
- function getSharedSkillsDir(cwd = process.cwd()) {
498
- const dir = join(cwd, SHARED_SKILLS_DIR);
499
- return existsSync(dir) ? dir : null;
500
- }
501
- export { semverDiff as a, getBlogPreset as c, getFilePatterns as d, getPackageRules as f, getRepoKeyForPackage as g, getRepoEntry as h, resolveSkilldCommand as i, getCrawlUrl as l, getRelatedPackages as m, getSharedSkillsDir as n, semverGt as o, getPrereleaseChangelogRef as p, mapInsert as r, semverValid as s, SHARED_SKILLS_DIR as t, getDocOverride as u };
463
+ export { getPackageRules as a, getRepoEntry as c, getFilePatterns as i, getRepoKeyForPackage as l, getCrawlUrl as n, getPrereleaseChangelogRef as o, getDocOverride as r, getRelatedPackages as s, getBlogPreset as t };
502
464
 
503
- //# sourceMappingURL=shared.mjs.map
465
+ //# sourceMappingURL=package-registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-registry.mjs","names":[],"sources":["../../src/sources/package-registry.data.ts","../../src/sources/package-registry.ts"],"sourcesContent":["/**\n * Curated repo registry data — keyed by GitHub 'owner/repo'.\n * Maintained as a TypeScript const so RepoEntry types validate it.\n * Lookup helpers and reverse index live in package-registry.ts.\n */\n\nimport type { RepoEntry } from './package-registry.ts'\n\nexport const REPO_REGISTRY: Record<string, RepoEntry> = {\n // ── Frameworks with doc overrides ──\n\n 'vuejs/core': {\n owner: 'vuejs',\n repo: 'core',\n docsRepo: 'docs',\n docsPath: 'src',\n homepage: 'https://vuejs.org',\n prereleaseChangelogRef: 'minor',\n packages: {\n 'vue': { primary: true, filePatterns: ['*.vue'], rules: ['ALWAYS use `<script setup lang=\"ts\">`', 'Use ```vue code fences for SFC examples containing `<script>` or `<template>` tags, ```ts for plain TypeScript'] },\n '@vue/compiler-core': {},\n '@vue/compiler-dom': {},\n '@vue/reactivity': {},\n '@vue/runtime-core': {},\n '@vue/runtime-dom': {},\n '@vue/shared': {},\n },\n blogReleases: [\n { version: '3.5', url: 'https://blog.vuejs.org/posts/vue-3-5', date: '2024-09-01' },\n { version: '3.4', url: 'https://blog.vuejs.org/posts/vue-3-4', date: '2023-12-28' },\n { version: '3.3', url: 'https://blog.vuejs.org/posts/vue-3-3', date: '2023-05-11' },\n { version: '3.2', url: 'https://blog.vuejs.org/posts/vue-3-2', date: '2021-08-05' },\n { version: '3.1', url: 'https://blog.vuejs.org/posts/vue-3-1', date: '2021-06-07' },\n { version: '3.0', url: 'https://blog.vuejs.org/posts/vue-3-0', date: '2020-09-18' },\n ],\n },\n\n 'tailwindlabs/tailwindcss': {\n owner: 'tailwindlabs',\n repo: 'tailwindcss',\n docsRepo: 'tailwindcss.com',\n docsPath: 'src/docs',\n homepage: 'https://tailwindcss.com',\n packages: {\n tailwindcss: { primary: true },\n },\n },\n\n 'withastro/astro': {\n owner: 'withastro',\n repo: 'astro',\n docsRepo: 'docs',\n docsPath: 'src/content/docs/en',\n homepage: 'https://docs.astro.build',\n packages: {\n astro: { primary: true, filePatterns: ['*.astro'] },\n },\n },\n\n 'vueuse/vueuse': {\n owner: 'vueuse',\n repo: 'vueuse',\n docsPath: 'packages',\n packages: {\n '@vueuse/core': { primary: true },\n },\n },\n\n // ── Frameworks (file patterns only) ──\n\n 'sveltejs/svelte': {\n owner: 'sveltejs',\n repo: 'svelte',\n packages: {\n svelte: { primary: true, filePatterns: ['*.svelte'], rules: ['ALWAYS use runes syntax ($state, $derived, $effect, $props)'] },\n },\n },\n\n 'solidjs/solid': {\n owner: 'solidjs',\n repo: 'solid',\n packages: {\n 'solid-js': { primary: true, filePatterns: ['*.jsx', '*.tsx'] },\n },\n },\n\n 'QwikDev/qwik': {\n owner: 'QwikDev',\n repo: 'qwik',\n packages: {\n qwik: { primary: true, filePatterns: ['*.tsx'] },\n },\n },\n\n 'marko-js/marko': {\n owner: 'marko-js',\n repo: 'marko',\n packages: {\n marko: { primary: true, filePatterns: ['*.marko'] },\n },\n },\n\n 'riot/riot': {\n owner: 'riot',\n repo: 'riot',\n packages: {\n riot: { primary: true, filePatterns: ['*.riot'] },\n },\n },\n\n // ── Languages/transpilers ──\n\n 'microsoft/TypeScript': {\n owner: 'microsoft',\n repo: 'TypeScript',\n packages: {\n typescript: { primary: true, filePatterns: ['*.ts', '*.tsx', '*.mts', '*.cts'] },\n },\n blogReleases: [\n { version: '6.0', url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-6-0-beta/', date: '2026-02-11', title: 'Announcing TypeScript 6.0 Beta' },\n { version: '5.9', url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-5-9/', date: '2025-08-01', title: 'Announcing TypeScript 5.9' },\n { version: '5.8', url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-5-8/', date: '2025-02-28', title: 'Announcing TypeScript 5.8' },\n { version: '5.7', url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-5-7/', date: '2024-11-22', title: 'Announcing TypeScript 5.7' },\n { version: '5.6', url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-5-6/', date: '2024-09-09', title: 'Announcing TypeScript 5.6' },\n { version: '5.5', url: 'https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/', date: '2024-06-20', title: 'Announcing TypeScript 5.5' },\n ],\n },\n\n 'jashkenas/coffeescript': {\n owner: 'jashkenas',\n repo: 'coffeescript',\n packages: {\n coffeescript: { primary: true, filePatterns: ['*.coffee'] },\n },\n },\n\n 'gkz/LiveScript': {\n owner: 'gkz',\n repo: 'LiveScript',\n packages: {\n livescript: { primary: true, filePatterns: ['*.ls'] },\n },\n },\n\n 'elm/compiler': {\n owner: 'elm',\n repo: 'compiler',\n packages: {\n elm: { primary: true, filePatterns: ['*.elm'] },\n },\n },\n\n // ── CSS preprocessors ──\n\n 'sass/dart-sass': {\n owner: 'sass',\n repo: 'dart-sass',\n packages: {\n sass: { primary: true, filePatterns: ['*.scss', '*.sass'] },\n },\n },\n\n 'less/less.js': {\n owner: 'less',\n repo: 'less.js',\n packages: {\n less: { primary: true, filePatterns: ['*.less'] },\n },\n },\n\n 'stylus/stylus': {\n owner: 'stylus',\n repo: 'stylus',\n packages: {\n stylus: { primary: true, filePatterns: ['*.styl'] },\n },\n },\n\n 'postcss/postcss': {\n owner: 'postcss',\n repo: 'postcss',\n packages: {\n postcss: { primary: true, filePatterns: ['*.css', '*.pcss'] },\n },\n },\n\n // ── Template engines ──\n\n 'pugjs/pug': {\n owner: 'pugjs',\n repo: 'pug',\n packages: {\n pug: { primary: true, filePatterns: ['*.pug'] },\n },\n },\n\n 'mde/ejs': {\n owner: 'mde',\n repo: 'ejs',\n packages: {\n ejs: { primary: true, filePatterns: ['*.ejs'] },\n },\n },\n\n 'handlebars-lang/handlebars.js': {\n owner: 'handlebars-lang',\n repo: 'handlebars.js',\n packages: {\n handlebars: { primary: true, filePatterns: ['*.hbs', '*.handlebars'] },\n },\n },\n\n 'janl/mustache.js': {\n owner: 'janl',\n repo: 'mustache.js',\n packages: {\n mustache: { primary: true, filePatterns: ['*.mustache'] },\n },\n },\n\n 'mozilla/nunjucks': {\n owner: 'mozilla',\n repo: 'nunjucks',\n packages: {\n nunjucks: { primary: true, filePatterns: ['*.njk'] },\n },\n },\n\n 'Shopify/liquid': {\n owner: 'Shopify',\n repo: 'liquid',\n packages: {\n liquid: { primary: true, filePatterns: ['*.liquid'] },\n },\n },\n\n // ── Data formats ──\n\n 'eemeli/yaml': {\n owner: 'eemeli',\n repo: 'yaml',\n packages: {\n yaml: { primary: true, filePatterns: ['*.yaml', '*.yml'] },\n },\n },\n\n 'nodeca/js-yaml': {\n owner: 'nodeca',\n repo: 'js-yaml',\n packages: {\n 'js-yaml': { primary: true, filePatterns: ['*.yaml', '*.yml'] },\n },\n },\n\n 'BinaryMuse/toml-node': {\n owner: 'BinaryMuse',\n repo: 'toml-node',\n packages: {\n 'toml': { primary: true, filePatterns: ['*.toml'] },\n '@iarna/toml': { filePatterns: ['*.toml'] },\n },\n },\n\n 'json5/json5': {\n owner: 'json5',\n repo: 'json5',\n packages: {\n json5: { primary: true, filePatterns: ['*.json5'] },\n },\n },\n\n 'microsoft/node-jsonc-parser': {\n owner: 'microsoft',\n repo: 'node-jsonc-parser',\n packages: {\n 'jsonc-parser': { primary: true, filePatterns: ['*.jsonc'] },\n },\n },\n\n // ── Markdown ──\n\n 'markdown-it/markdown-it': {\n owner: 'markdown-it',\n repo: 'markdown-it',\n packages: {\n 'markdown-it': { primary: true, filePatterns: ['*.md'] },\n },\n },\n\n 'markedjs/marked': {\n owner: 'markedjs',\n repo: 'marked',\n packages: {\n marked: { primary: true, filePatterns: ['*.md'] },\n },\n },\n\n 'remarkjs/remark': {\n owner: 'remarkjs',\n repo: 'remark',\n packages: {\n remark: { primary: true, filePatterns: ['*.md', '*.mdx'] },\n },\n },\n\n 'mdx-js/mdx': {\n owner: 'mdx-js',\n repo: 'mdx',\n packages: {\n '@mdx-js/mdx': { primary: true, filePatterns: ['*.mdx'] },\n },\n },\n\n // ── GraphQL ──\n\n 'graphql/graphql-js': {\n owner: 'graphql',\n repo: 'graphql-js',\n packages: {\n 'graphql': { primary: true, filePatterns: ['*.graphql', '*.gql'] },\n 'graphql-tag': { filePatterns: ['*.graphql', '*.gql'] },\n },\n },\n\n 'dotansimha/graphql-code-generator': {\n owner: 'dotansimha',\n repo: 'graphql-code-generator',\n packages: {\n '@graphql-codegen/cli': { primary: true, filePatterns: ['*.graphql', '*.gql'] },\n },\n },\n\n // ── UI Frameworks ──\n\n 'quasarframework/quasar': {\n owner: 'quasarframework',\n repo: 'quasar',\n docsPath: 'docs/src/pages',\n docsRef: 'dev',\n homepage: 'https://quasar.dev',\n packages: {\n quasar: { primary: true },\n },\n },\n\n // ── Animation ──\n\n 'motiondivision/motion-vue': {\n owner: 'motiondivision',\n repo: 'motion-vue',\n homepage: 'https://motion.dev',\n crawlUrl: 'https://motion.dev/docs/vue**',\n packages: {\n 'motion-v': { primary: true },\n },\n },\n\n // ── Other ──\n\n 'prisma/prisma': {\n owner: 'prisma',\n repo: 'prisma',\n packages: {\n 'prisma': { primary: true, filePatterns: ['*.prisma'] },\n '@prisma/client': { filePatterns: ['*.prisma'] },\n },\n },\n\n 'nicolo-ribaudo/tc39-proposal-wasm-esm-integration': {\n owner: 'nicolo-ribaudo',\n repo: 'tc39-proposal-wasm-esm-integration',\n packages: {\n 'wasm-pack': { primary: true, filePatterns: ['*.wasm'] },\n },\n },\n}\n","/**\n * Package registry — types, lookup helpers, and reverse index.\n * Curated registry data lives in package-registry.data.ts.\n * Keyed by GitHub 'owner/repo' (source code repo).\n */\n\nimport { REPO_REGISTRY } from './package-registry.data.ts'\n\nexport interface BlogRelease {\n version: string\n url: string\n date: string\n title?: string\n}\n\nexport interface PackageEntry {\n filePatterns?: string[]\n primary?: boolean\n /** Extra rules injected into skill generation prompts */\n rules?: string[]\n}\n\nexport interface RepoEntry {\n owner: string\n repo: string\n /** Separate docs repo name (e.g. 'docs' → owner/docs) */\n docsRepo?: string\n /** Path prefix to filter markdown files */\n docsPath?: string\n /** Branch/ref override */\n docsRef?: string\n /** Homepage URL */\n homepage?: string\n /** URL pattern to crawl for docs (glob, e.g. 'https://example.com/docs/**') */\n crawlUrl?: string\n /** Branch to fetch CHANGELOG.md from when installed version is a prerelease (e.g. 'minor' for Vue) */\n prereleaseChangelogRef?: string\n /** Packages in this repo */\n packages: Record<string, PackageEntry>\n /** Curated blog release posts */\n blogReleases?: BlogRelease[]\n}\n\n// Backwards-compatible types\nexport interface DocOverride {\n owner: string\n repo: string\n path: string\n ref?: string\n homepage?: string\n}\n\nexport interface BlogPreset {\n packageName: string\n releases: BlogRelease[]\n}\n\n// ── Reverse index (auto-generated) ──\n\nconst PACKAGE_TO_REPO_MAP: Record<string, string> = {}\n\nfor (const [repoKey, entry] of Object.entries(REPO_REGISTRY)) {\n for (const packageName of Object.keys(entry.packages)) {\n PACKAGE_TO_REPO_MAP[packageName] = repoKey\n }\n}\n\n// ── Backwards-compatible helpers ──\n\nexport function getDocOverride(packageName: string): DocOverride | undefined {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return undefined\n const entry = REPO_REGISTRY[repoKey]\n if (!entry?.docsRepo && !entry?.docsPath)\n return undefined\n\n return {\n owner: entry.owner,\n repo: entry.docsRepo || entry.repo,\n path: entry.docsPath || '',\n ref: entry.docsRef,\n homepage: entry.homepage,\n }\n}\n\nexport function getBlogPreset(packageName: string): BlogPreset | undefined {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return undefined\n const entry = REPO_REGISTRY[repoKey]\n if (!entry?.blogReleases)\n return undefined\n\n return {\n packageName,\n releases: entry.blogReleases,\n }\n}\n\nexport function getFilePatterns(packageName: string): string[] | undefined {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return undefined\n return REPO_REGISTRY[repoKey]?.packages[packageName]?.filePatterns\n}\n\n// ── New APIs ──\n\nexport function getRepoEntry(repoKey: string): RepoEntry | undefined {\n return REPO_REGISTRY[repoKey]\n}\n\nexport function getRepoKeyForPackage(packageName: string): string | undefined {\n return PACKAGE_TO_REPO_MAP[packageName]\n}\n\nexport function getPackageRules(packageName: string): string[] {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return []\n return REPO_REGISTRY[repoKey]?.packages[packageName]?.rules ?? []\n}\n\nexport function getPrereleaseChangelogRef(packageName: string): string | undefined {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return undefined\n return REPO_REGISTRY[repoKey]?.prereleaseChangelogRef\n}\n\nexport function getCrawlUrl(packageName: string): string | undefined {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return undefined\n return REPO_REGISTRY[repoKey]?.crawlUrl\n}\n\nexport function getRelatedPackages(packageName: string): string[] {\n const repoKey = PACKAGE_TO_REPO_MAP[packageName]\n if (!repoKey)\n return []\n const entry = REPO_REGISTRY[repoKey]\n if (!entry)\n return []\n return Object.keys(entry.packages)\n}\n"],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { existsSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "pathe";
4
+ const SHARED_SKILLS_DIR = ".skills";
5
+ const SKILL_INTERNAL_DIRNAME = ".skilld";
6
+ const SKILL_INTERNAL_FILENAME = "_SKILL.md";
7
+ const LOCK_FILENAME = "skilld-lock.yaml";
8
+ const CONFIG_FILENAME = "config.yaml";
9
+ const CACHE_DIR = join(homedir(), ".skilld");
10
+ const REFERENCES_DIR = join(CACHE_DIR, "references");
11
+ const REPOS_DIR = join(CACHE_DIR, "repos");
12
+ const LLM_CACHE_DIR = join(CACHE_DIR, "llm-cache");
13
+ join(CACHE_DIR, "skills");
14
+ join(CACHE_DIR, "git-skills");
15
+ join(CACHE_DIR, "embeddings.db");
16
+ const CONFIG_PATH = join(CACHE_DIR, CONFIG_FILENAME);
17
+ const PI_AI_AUTH_PATH = join(CACHE_DIR, "pi-ai-auth.json");
18
+ function getSharedSkillsDir(cwd = process.cwd()) {
19
+ const dir = join(cwd, SHARED_SKILLS_DIR);
20
+ return existsSync(dir) ? dir : null;
21
+ }
22
+ function lockfilePath(skillsDir) {
23
+ return join(skillsDir, LOCK_FILENAME);
24
+ }
25
+ function skillInternalDir(skillDir) {
26
+ return join(skillDir, SKILL_INTERNAL_DIRNAME);
27
+ }
28
+ function skillInternalFile(skillDir) {
29
+ return join(skillDir, SKILL_INTERNAL_DIRNAME, SKILL_INTERNAL_FILENAME);
30
+ }
31
+ function skillLogDir(skillDir) {
32
+ return join(skillDir, SKILL_INTERNAL_DIRNAME, "logs");
33
+ }
34
+ function skillRefsSection(skillDir, section) {
35
+ return join(skillDir, SKILL_INTERNAL_DIRNAME, section);
36
+ }
37
+ function getReferencesDir(name, version) {
38
+ return join(REFERENCES_DIR, `${name}@${version}`);
39
+ }
40
+ function getRepoCacheDir(owner, repo) {
41
+ if (owner.includes("..") || repo.includes("..") || owner.includes("/") || repo.includes("/")) throw new Error(`Invalid repo path: ${owner}/${repo}`);
42
+ return join(REPOS_DIR, owner, repo);
43
+ }
44
+ function getPackageDbPath(name, version) {
45
+ return join(getReferencesDir(name, version), "search.db");
46
+ }
47
+ export { PI_AI_AUTH_PATH as a, SHARED_SKILLS_DIR as c, getSharedSkillsDir as d, lockfilePath as f, skillRefsSection as g, skillLogDir as h, LOCK_FILENAME as i, getPackageDbPath as l, skillInternalFile as m, CONFIG_PATH as n, REFERENCES_DIR as o, skillInternalDir as p, LLM_CACHE_DIR as r, REPOS_DIR as s, CACHE_DIR as t, getRepoCacheDir as u };
48
+
49
+ //# sourceMappingURL=paths.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.mjs","names":[],"sources":["../../src/core/paths.ts"],"sourcesContent":["/**\n * Project layout: every `~/.skilld/...` and `.claude/skills/...` path lives here.\n *\n * Two layers:\n * 1. Global cache under `~/.skilld/` (references, repos, llm-cache, etc.)\n * 2. Per-skill internals: `<skillDir>/.skilld/` holds reference symlinks,\n * logs, and the canonical `_SKILL.md`. The lockfile sits as a sibling\n * of skill dirs as `skilld-lock.yaml`.\n *\n * Per-agent target dirs (`.claude/skills/`, `.cursor/skills/`, ...) are owned\n * by the agent registry (`src/agent/registry.ts`); this module exposes the\n * agent-agnostic `.skills/` shared dir and helpers that compose with target dirs.\n */\n\nimport { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\n\n// ── Project-relative names ──\n\n/** Shared, agent-agnostic skills directory at project root */\nexport const SHARED_SKILLS_DIR = '.skills'\n\n/** Per-skill internals directory (cache symlinks, logs, prompts, _SKILL.md) */\nexport const SKILL_INTERNAL_DIRNAME = '.skilld'\n\n/** Canonical SKILL.md copy inside the per-skill internals dir (frontmatter source of truth) */\nexport const SKILL_INTERNAL_FILENAME = '_SKILL.md'\n\n/** Lockfile sibling of skill directories */\nexport const LOCK_FILENAME = 'skilld-lock.yaml'\n\n/** Config filename inside the global cache */\nexport const CONFIG_FILENAME = 'config.yaml'\n\n// ── Global cache layout (~/.skilld/) ──\n\n/** Root of the global cache */\nexport const CACHE_DIR: string = join(homedir(), '.skilld')\n\n/** References subdirectory: `~/.skilld/references/<pkg>@<version>/` */\nexport const REFERENCES_DIR: string = join(CACHE_DIR, 'references')\n\n/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */\nexport const REPOS_DIR: string = join(CACHE_DIR, 'repos')\n\n/** LLM output cache: `~/.skilld/llm-cache/<sha256>.json` */\nexport const LLM_CACHE_DIR: string = join(CACHE_DIR, 'llm-cache')\n\n/** Global skill installs (skilld install --global) */\nexport const GLOBAL_SKILLS_DIR: string = join(CACHE_DIR, 'skills')\n\n/** Cloned git skills repos */\nexport const GIT_SKILLS_DIR: string = join(CACHE_DIR, 'git-skills')\n\n/** sqlite-vec embedding cache */\nexport const EMBEDDINGS_DB_PATH: string = join(CACHE_DIR, 'embeddings.db')\n\n/** Global config file */\nexport const CONFIG_PATH: string = join(CACHE_DIR, CONFIG_FILENAME)\n\n/** pi-ai auth credentials */\nexport const PI_AI_AUTH_PATH: string = join(CACHE_DIR, 'pi-ai-auth.json')\n\n// ── Helpers ──\n\n/** Returns the shared skills directory path if `.skills/` exists at project root, else null */\nexport function getSharedSkillsDir(cwd: string = process.cwd()): string | null {\n const dir = join(cwd, SHARED_SKILLS_DIR)\n return existsSync(dir) ? dir : null\n}\n\n/** Path to the lockfile inside a skills directory */\nexport function lockfilePath(skillsDir: string): string {\n return join(skillsDir, LOCK_FILENAME)\n}\n\n/** Per-skill internals dir (`<skillDir>/.skilld`) */\nexport function skillInternalDir(skillDir: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME)\n}\n\n/** Per-skill canonical SKILL.md (`<skillDir>/.skilld/_SKILL.md`) */\nexport function skillInternalFile(skillDir: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME, SKILL_INTERNAL_FILENAME)\n}\n\n/** Per-skill log dir (`<skillDir>/.skilld/logs`) */\nexport function skillLogDir(skillDir: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME, 'logs')\n}\n\n/** Per-skill section dir (`<skillDir>/.skilld/<section>`), e.g. issues/discussions/releases/docs */\nexport function skillRefsSection(skillDir: string, section: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME, section)\n}\n\n/** References cache dir for a `name@version` */\nexport function getReferencesDir(name: string, version: string): string {\n return join(REFERENCES_DIR, `${name}@${version}`)\n}\n\n/** Repo cache dir with path-traversal validation */\nexport function getRepoCacheDir(owner: string, repo: string): string {\n if (owner.includes('..') || repo.includes('..') || owner.includes('/') || repo.includes('/'))\n throw new Error(`Invalid repo path: ${owner}/${repo}`)\n return join(REPOS_DIR, owner, repo)\n}\n\n/** search.db path for a `name@version` */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(getReferencesDir(name, version), 'search.db')\n}\n"],"mappings":";;;;;;;;;AAqBA,MAAa,iBAAA,KAAoB,WAAA,aAAA;AAGjC,MAAa,YAAA,KAAA,WAAyB,QAAA;AAGtC,MAAa,gBAAA,KAAA,WAA0B,YAAA;AAGV,KAAA,WAAA,SAAA;AAGhB,KAAkB,WAAA,aAAA;AAKO,KAAS,WAAE,gBAAU;AAG3D,MAAa,cAAA,KAAyB,WAAK,gBAAwB;AAGnE,MAAa,kBAAyB,KAAA,WAAW,kBAAQ;AAGzD,SAAa,mBAA6B,MAAA,QAAW,KAAA,EAAA;;CAGrD,OAAa,WAAA,IAAA,GAA4B,MAAK;;;CAM9C,OAAa,KAAA,WAAA,cAAkC;;;CAM/C,OAAa,KAAA,UAAA,uBAA0C;;SAM/C,kBAAgB,UAAA;CACtB,OAAO,KAAA,UAAe,wBAAS,wBAAA;;AAIjC,SAAgB,YAAA,UAAa;CAC3B,OAAO,KAAK,UAAA,wBAAyB,OAAA;;AAIvC,SAAgB,iBAAiB,UAA0B,SAAA;CACzD,OAAO,KAAK,UAAU,wBAAuB,QAAA;;AAI/C,SAAgB,iBAAA,MAAkB,SAA0B;CAC1D,OAAO,KAAK,gBAAU,GAAA,KAAA,GAAA,UAAwB;;AAIhD,SAAgB,gBAAY,OAA0B,MAAA;CACpD,IAAA,MAAO,SAAK,KAAU,IAAA,KAAA,SAAA,KAAwB,IAAA,MAAO,SAAA,IAAA,IAAA,KAAA,SAAA,IAAA,EAAA,MAAA,IAAA,MAAA,sBAAA,MAAA,GAAA,OAAA;;;SAK9C,iBAAe,MAAA,SAAA;;;SAKf,mBAAK,GAAgB,qBAAqB,GAAA,sBAAA,GAAA,gBAAA,GAAA,oBAAA,GAAA,eAAA,GAAA,iBAAA,GAAA,oBAAA,GAAA,qBAAA,GAAA,eAAA,GAAA,kBAAA,GAAA,oBAAA,GAAA,iBAAA,GAAA,aAAA,GAAA,aAAA,GAAA,mBAAA"}
@@ -1,6 +1,6 @@
1
1
  import { t as SearchDepsUnavailableError } from "./retriv.mjs";
2
- import { dirname, join } from "pathe";
3
2
  import { existsSync } from "node:fs";
3
+ import { dirname, join } from "pathe";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { Worker } from "node:worker_threads";
6
6
  function reconstructError(message, name) {
@@ -1,6 +1,6 @@
1
1
  import { t as getCacheDir } from "./version.mjs";
2
- import { join } from "pathe";
3
2
  import { existsSync, lstatSync, mkdirSync, readdirSync, rmSync, symlinkSync, unlinkSync } from "node:fs";
3
+ import { join } from "pathe";
4
4
  function toStorageName(name) {
5
5
  if (name.startsWith("crate:")) return `@skilld-crate/${name.slice(6)}`;
6
6
  return name;
@@ -1,13 +1,13 @@
1
- import "./agent.mjs";
1
+ import { d as getSharedSkillsDir } from "./paths.mjs";
2
2
  import { i as restorePkgSymlink, n as linkShippedSkill, t as getShippedSkills } from "./prepare.mjs";
3
- import { n as getSharedSkillsDir } from "./shared.mjs";
4
3
  import { a as targets } from "./detect.mjs";
5
- import { o as linkSkillToAgents, v as todayIsoDate } from "./skill.mjs";
4
+ import "./agent.mjs";
5
+ import { o as linkSkillToAgents, v as todayIsoDate } from "./prompts.mjs";
6
6
  import { b as resolveAgent } from "./cli-helpers.mjs";
7
- import { a as readLock, c as writeLock } from "./lockfile.mjs";
7
+ import { c as readLock, d as writeLock } from "./lockfile.mjs";
8
8
  import { t as getProjectState } from "./skills.mjs";
9
- import { join } from "pathe";
10
9
  import { existsSync, mkdirSync } from "node:fs";
10
+ import { join } from "pathe";
11
11
  import * as p from "@clack/prompts";
12
12
  import { defineCommand } from "citty";
13
13
  const prepareCommandDef = defineCommand({
@@ -1 +1 @@
1
- {"version":3,"file":"prepare2.mjs","names":["agents"],"sources":["../../src/commands/prepare.ts"],"sourcesContent":["/**\n * Prepare command — lightweight hook for package.json \"prepare\" script.\n *\n * Designed to run on every `pnpm install` / `npm install`. Blocking, fast, no LLM calls.\n * 1. Restore broken symlinks from lockfile (like `install` but skips doc fetching)\n * 2. Auto-install shipped skills from deps (just symlinks + lockfile writes)\n * 3. Report outdated skills count and suggest `skilld update`\n */\n\nimport { existsSync, mkdirSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents, linkSkillToAgents } from '../agent/index.ts'\nimport { resolveAgent } from '../cli-helpers.ts'\nimport { todayIsoDate } from '../core/formatting.ts'\nimport { readLock, writeLock } from '../core/lockfile.ts'\nimport { getShippedSkills, linkShippedSkill, restorePkgSymlink } from '../core/prepare.ts'\nimport { getSharedSkillsDir } from '../core/shared.ts'\nimport { getProjectState } from '../core/skills.ts'\n\nexport const prepareCommandDef = defineCommand({\n meta: { name: 'prepare', description: 'Restore references and sync shipped skills (for package.json hooks)' },\n args: {\n agent: {\n type: 'enum' as const,\n options: Object.keys(agents),\n alias: 'a',\n description: 'Target agent',\n },\n },\n async run({ args }) {\n const cwd = process.cwd()\n\n const agent = resolveAgent(args.agent)\n if (!agent || agent === 'none')\n return\n\n const agentConfig = agents[agent]\n const shared = getSharedSkillsDir(cwd)\n const skillsDir = shared || join(cwd, agentConfig.skillsDir)\n\n // ── Fast path: read primary lockfile, check all skills intact ──\n\n const lock = readLock(skillsDir)\n if (lock && Object.keys(lock.skills).length > 0) {\n let allIntact = true\n\n for (const [name, info] of Object.entries(lock.skills)) {\n if (!info.version)\n continue\n\n const skillDir = join(skillsDir, name)\n if (existsSync(skillDir)) {\n // Skill dir exists; for non-shipped, also check .skilld/pkg symlink\n if (info.source !== 'shipped')\n restorePkgSymlink(skillsDir, name, info, cwd)\n continue\n }\n\n // Skill dir missing, needs restore\n allIntact = false\n\n if (info.source === 'shipped') {\n const pkgName = info.packageName || name\n const shipped = getShippedSkills(pkgName, cwd, info.version)\n const match = shipped.find(s => s.skillName === name)\n if (match)\n linkShippedSkill(skillsDir, name, match.skillDir)\n }\n }\n\n // If all skills intact, skip expensive getProjectState entirely\n if (allIntact)\n return\n }\n\n // ── Slow path: discover new shipped skills + report outdated ──\n\n const state = await getProjectState(cwd)\n let shippedCount = 0\n\n if (state.shipped.length > 0) {\n mkdirSync(skillsDir, { recursive: true })\n\n for (const entry of state.shipped) {\n const version = state.deps.get(entry.packageName)?.replace(/^[\\^~>=<]+/, '') || '0.0.0'\n\n for (const skill of entry.skills) {\n linkShippedSkill(skillsDir, skill.skillName, skill.skillDir)\n writeLock(skillsDir, skill.skillName, {\n packageName: entry.packageName,\n version,\n source: 'shipped',\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n })\n\n if (shared)\n linkSkillToAgents(skill.skillName, shared, cwd, agent)\n\n shippedCount++\n }\n }\n\n if (shippedCount > 0)\n p.log.success(`Installed ${shippedCount} shipped skill${shippedCount > 1 ? 's' : ''}`)\n }\n\n if (state.outdated.length > 0) {\n const n = state.outdated.length\n p.log.info(`${n} package${n > 1 ? 's' : ''} ha${n > 1 ? 've' : 's'} new features and/or breaking changes. Run \\`skilld update\\` to sync.`)\n }\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAqBA,SAAa,OAAA,KAAA,QAAoB;EAC/B,OAAM;EAAE,aAAM;EAAW,EAAA;OAAoF,IAAA,EAAA,QAAA;EAC7G,MAAM,MACJ,QAAO,KAAA;EACL,MAAM,QAAA,aAAA,KAAA,MAAA;EACN,IAAA,CAAA,SAAS,UAAYA,QAAO;EAC5B,MAAA,cAAO,QAAA;EACP,MAAA,SAAa,mBAAA,IAAA;EACd,MACF,YAAA,UAAA,KAAA,KAAA,YAAA,UAAA;EACD,MAAM,OAAM,SAAQ,UAAA;EAClB,IAAA,QAAY,OAAA,KAAQ,KAAK,OAAA,CAAA,SAAA,GAAA;GAEzB,IAAA,YAAc;GACd,KAAK,MAAA,CAAA,MAAS,SAAU,OACtB,QAAA,KAAA,OAAA,EAAA;IAEF,IAAM,CAAA,KAAA,SAAcA;IACpB,IAAM,WAAS,KAAA,WAAA,KAAuB,CAAA,EAAA;KACtC,IAAM,KAAA,WAAY,WAAe,kBAAiB,WAAU,MAAA,MAAA,IAAA;KAI5D;;IAEE,YAAI;IAEJ,IAAK,KAAA,WAAa,WAAS;KACzB,MAAK,QAAK,iBACR,KAAA,eAAA,MAAA,KAAA,KAAA,QAAA,CAAA,MAAA,MAAA,EAAA,cAAA,KAAA;KAGF,IAAI,OAAA,iBADkB,WACI,MAAA,MAAA,SAAA;;;;;QAUtB,QAAK,MAAA,gBAAsB,IAAA;MAG7B,eADgB;MAEhB,MAAI,QACF,SAAA,GAAA;;;IAKN,MAAI,UACF,MAAA,KAAA,IAAA,MAAA,YAAA,EAAA,QAAA,cAAA,GAAA,IAAA;;KAKJ,iBAAoB,WAAA,MAAgB,WAAI,MAAA,SAAA;KACxC,UAAI,WAAe,MAAA,WAAA;MAEf,aAAM,MAAQ;MAChB;MAEA,QAAW;MACT,UAAM,cAAgB;MAEtB,WAAW;MACT,CAAA;KACA,IAAA,QAAU,kBAAiB,MAAA,WAAW,QAAA,KAAA,MAAA;;;;OAIpC,eAAU,GAAA,EAAA,IAAc,QAAA,aAAA,aAAA,gBAAA,eAAA,IAAA,MAAA,KAAA;;MAEzB,MAAC,SAAA,SAAA,GAAA;SAEE,IAAA,MACF,SAAA;KAEF,IAAA,KAAA,GAAA,EAAA,UAAA,IAAA,IAAA,MAAA,GAAA,KAAA,IAAA,IAAA,OAAA,IAAA,uEAAA;;;;SAQF"}
1
+ {"version":3,"file":"prepare2.mjs","names":["agents"],"sources":["../../src/commands/prepare.ts"],"sourcesContent":["/**\n * Prepare command — lightweight hook for package.json \"prepare\" script.\n *\n * Designed to run on every `pnpm install` / `npm install`. Blocking, fast, no LLM calls.\n * 1. Restore broken symlinks from lockfile (like `install` but skips doc fetching)\n * 2. Auto-install shipped skills from deps (just symlinks + lockfile writes)\n * 3. Report outdated skills count and suggest `skilld update`\n */\n\nimport { existsSync, mkdirSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents, linkSkillToAgents } from '../agent/index.ts'\nimport { resolveAgent } from '../cli-helpers.ts'\nimport { todayIsoDate } from '../core/formatting.ts'\nimport { readLock, writeLock } from '../core/lockfile.ts'\nimport { getSharedSkillsDir } from '../core/paths.ts'\nimport { getShippedSkills, linkShippedSkill, restorePkgSymlink } from '../core/prepare.ts'\nimport { getProjectState } from '../core/skills.ts'\n\nexport const prepareCommandDef = defineCommand({\n meta: { name: 'prepare', description: 'Restore references and sync shipped skills (for package.json hooks)' },\n args: {\n agent: {\n type: 'enum' as const,\n options: Object.keys(agents),\n alias: 'a',\n description: 'Target agent',\n },\n },\n async run({ args }) {\n const cwd = process.cwd()\n\n const agent = resolveAgent(args.agent)\n if (!agent || agent === 'none')\n return\n\n const agentConfig = agents[agent]\n const shared = getSharedSkillsDir(cwd)\n const skillsDir = shared || join(cwd, agentConfig.skillsDir)\n\n // ── Fast path: read primary lockfile, check all skills intact ──\n\n const lock = readLock(skillsDir)\n if (lock && Object.keys(lock.skills).length > 0) {\n let allIntact = true\n\n for (const [name, info] of Object.entries(lock.skills)) {\n if (!info.version)\n continue\n\n const skillDir = join(skillsDir, name)\n if (existsSync(skillDir)) {\n // Skill dir exists; for non-shipped, also check .skilld/pkg symlink\n if (info.source !== 'shipped')\n restorePkgSymlink(skillsDir, name, info, cwd)\n continue\n }\n\n // Skill dir missing, needs restore\n allIntact = false\n\n if (info.source === 'shipped') {\n const pkgName = info.packageName || name\n const shipped = getShippedSkills(pkgName, cwd, info.version)\n const match = shipped.find(s => s.skillName === name)\n if (match)\n linkShippedSkill(skillsDir, name, match.skillDir)\n }\n }\n\n // If all skills intact, skip expensive getProjectState entirely\n if (allIntact)\n return\n }\n\n // ── Slow path: discover new shipped skills + report outdated ──\n\n const state = await getProjectState(cwd)\n let shippedCount = 0\n\n if (state.shipped.length > 0) {\n mkdirSync(skillsDir, { recursive: true })\n\n for (const entry of state.shipped) {\n const version = state.deps.get(entry.packageName)?.replace(/^[\\^~>=<]+/, '') || '0.0.0'\n\n for (const skill of entry.skills) {\n linkShippedSkill(skillsDir, skill.skillName, skill.skillDir)\n writeLock(skillsDir, skill.skillName, {\n packageName: entry.packageName,\n version,\n source: 'shipped',\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n })\n\n if (shared)\n linkSkillToAgents(skill.skillName, shared, cwd, agent)\n\n shippedCount++\n }\n }\n\n if (shippedCount > 0)\n p.log.success(`Installed ${shippedCount} shipped skill${shippedCount > 1 ? 's' : ''}`)\n }\n\n if (state.outdated.length > 0) {\n const n = state.outdated.length\n p.log.info(`${n} package${n > 1 ? 's' : ''} ha${n > 1 ? 've' : 's'} new features and/or breaking changes. Run \\`skilld update\\` to sync.`)\n }\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAqBA,SAAa,OAAA,KAAA,QAAoB;EAC/B,OAAM;EAAE,aAAM;EAAW,EAAA;OAAoF,IAAA,EAAA,QAAA;EAC7G,MAAM,MACJ,QAAO,KAAA;EACL,MAAM,QAAA,aAAA,KAAA,MAAA;EACN,IAAA,CAAA,SAAS,UAAYA,QAAO;EAC5B,MAAA,cAAO,QAAA;EACP,MAAA,SAAa,mBAAA,IAAA;EACd,MACF,YAAA,UAAA,KAAA,KAAA,YAAA,UAAA;EACD,MAAM,OAAM,SAAQ,UAAA;EAClB,IAAA,QAAY,OAAA,KAAQ,KAAK,OAAA,CAAA,SAAA,GAAA;GAEzB,IAAA,YAAc;GACd,KAAK,MAAA,CAAA,MAAS,SAAU,OACtB,QAAA,KAAA,OAAA,EAAA;IAEF,IAAM,CAAA,KAAA,SAAcA;IACpB,IAAM,WAAS,KAAA,WAAA,KAAuB,CAAA,EAAA;KACtC,IAAM,KAAA,WAAY,WAAe,kBAAiB,WAAU,MAAA,MAAA,IAAA;KAI5D;;IAEE,YAAI;IAEJ,IAAK,KAAA,WAAa,WAAS;KACzB,MAAK,QAAK,iBACR,KAAA,eAAA,MAAA,KAAA,KAAA,QAAA,CAAA,MAAA,MAAA,EAAA,cAAA,KAAA;KAGF,IAAI,OAAA,iBADkB,WACI,MAAA,MAAA,SAAA;;;;;QAUtB,QAAK,MAAA,gBAAsB,IAAA;MAG7B,eADgB;MAEhB,MAAI,QACF,SAAA,GAAA;;;IAKN,MAAI,UACF,MAAA,KAAA,IAAA,MAAA,YAAA,EAAA,QAAA,cAAA,GAAA,IAAA;;KAKJ,iBAAoB,WAAA,MAAgB,WAAI,MAAA,SAAA;KACxC,UAAI,WAAe,MAAA,WAAA;MAEf,aAAM,MAAQ;MAChB;MAEA,QAAW;MACT,UAAM,cAAgB;MAEtB,WAAW;MACT,CAAA;KACA,IAAA,QAAU,kBAAiB,MAAA,WAAW,QAAA,KAAA,MAAA;;;;OAIpC,eAAU,GAAA,EAAA,IAAc,QAAA,aAAA,aAAA,gBAAA,eAAA,IAAA,MAAA,KAAA;;MAEzB,MAAC,SAAA,SAAA,GAAA;SAEE,IAAA,MACF,SAAA;KAEF,IAAA,KAAA,GAAA,EAAA,UAAA,IAAA,IAAA,MAAA,GAAA,KAAA,IAAA,IAAA,OAAA,IAAA,uEAAA;;;;SAQF"}
@@ -1,6 +1,24 @@
1
- import { f as getPackageRules, i as resolveSkilldCommand } from "./shared.mjs";
2
- import "./skill.mjs";
3
- import { dirname } from "pathe";
1
+ import { p as skillInternalDir } from "./paths.mjs";
2
+ import { t as yamlEscape } from "./yaml.mjs";
3
+ import { n as sanitizeMarkdown, t as repairMarkdown } from "./sanitize.mjs";
4
+ import { a as getPackageRules, i as getFilePatterns } from "./package-registry.mjs";
5
+ import { a as targets, t as detectInstalledAgents } from "./detect.mjs";
6
+ import { existsSync, lstatSync, mkdirSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
7
+ import { dirname, join, relative } from "pathe";
8
+ import { execSync } from "node:child_process";
9
+ import * as p from "@clack/prompts";
10
+ import { isWindows } from "std-env";
11
+ let cached;
12
+ function resolveSkilldCommand() {
13
+ if (cached !== void 0) return cached;
14
+ try {
15
+ execSync(`${isWindows ? "where" : "which"} skilld`, { stdio: "ignore" });
16
+ cached = "skilld";
17
+ } catch {
18
+ cached = "npx -y skilld";
19
+ }
20
+ return cached;
21
+ }
4
22
  const TOTAL_TARGET = 500;
5
23
  const DEFAULT_OVERHEAD = 30;
6
24
  function remainingLines(overheadLines) {
@@ -289,16 +307,28 @@ Content addressing the user's instructions above, using concise examples and sou
289
307
  rules: [`- **Custom section "${heading}":** MAX ${customMaxLines} lines, use \`## ${heading}\` heading`]
290
308
  };
291
309
  }
292
- const SECTION_OUTPUT_FILES = {
293
- "best-practices": "_BEST_PRACTICES.md",
294
- "api-changes": "_API_CHANGES.md",
295
- "custom": "_CUSTOM.md"
296
- };
297
- const SECTION_MERGE_ORDER = [
298
- "api-changes",
299
- "best-practices",
300
- "custom"
310
+ const SECTIONS = [
311
+ {
312
+ id: "api-changes",
313
+ outputFile: "_API_CHANGES.md",
314
+ build: (ctx) => apiChangesSection(ctx)
315
+ },
316
+ {
317
+ id: "best-practices",
318
+ outputFile: "_BEST_PRACTICES.md",
319
+ build: (ctx) => bestPracticesSection(ctx)
320
+ },
321
+ {
322
+ id: "custom",
323
+ outputFile: "_CUSTOM.md",
324
+ build: (ctx, customPrompt) => customPrompt ? customSection(customPrompt, ctx.enabledSectionCount, ctx.overheadLines) : null
325
+ }
301
326
  ];
327
+ const SECTION_OUTPUT_FILES = Object.fromEntries(SECTIONS.map((s) => [s.id, s.outputFile]));
328
+ const SECTION_MERGE_ORDER = SECTIONS.map((s) => s.id);
329
+ function getSectionModule(id) {
330
+ return SECTIONS.find((s) => s.id === id);
331
+ }
302
332
  function wrapSection(section, content) {
303
333
  return `<!-- skilld:${section} -->\n${content}\n<!-- /skilld:${section} -->`;
304
334
  }
@@ -372,11 +402,7 @@ ${generateImportantBlock({
372
402
  ${docsSection ? `${docsSection}\n` : ""}`;
373
403
  }
374
404
  function getSectionDef(section, ctx, customPrompt) {
375
- switch (section) {
376
- case "api-changes": return apiChangesSection(ctx);
377
- case "best-practices": return bestPracticesSection(ctx);
378
- case "custom": return customPrompt ? customSection(customPrompt, ctx.enabledSectionCount, ctx.overheadLines) : null;
379
- }
405
+ return getSectionModule(section)?.build(ctx, customPrompt) ?? null;
380
406
  }
381
407
  function getSectionValidator(section) {
382
408
  return getSectionDef(section, { packageName: "" }, section === "custom" ? {
@@ -487,6 +513,328 @@ function portabilizePrompt(prompt, section) {
487
513
  out = out.replace(/\n{3,}/g, "\n\n");
488
514
  return out;
489
515
  }
490
- export { extractMarkedSections as a, wrapSection as c, buildSectionPrompt as i, maxItems as l, SECTION_OUTPUT_FILES as n, getSectionValidator as o, buildAllSectionPrompts as r, portabilizePrompt as s, SECTION_MERGE_ORDER as t, maxLines as u };
516
+ function todayIsoDate() {
517
+ return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
518
+ }
519
+ function timeAgo(iso) {
520
+ if (!iso) return "";
521
+ const diff = Date.now() - new Date(iso).getTime();
522
+ const days = Math.floor(diff / 864e5);
523
+ if (days <= 0) return "today";
524
+ if (days === 1) return "1d ago";
525
+ if (days < 7) return `${days}d ago`;
526
+ if (days < 30) return `${Math.floor(days / 7)}w ago`;
527
+ return `${Math.floor(days / 30)}mo ago`;
528
+ }
529
+ function formatSource(source) {
530
+ if (!source) return "";
531
+ if (source === "shipped") return "shipped";
532
+ if (source.includes("llms.txt")) return "llms.txt";
533
+ if (source.includes("github.com")) return source.replace(/https?:\/\/github\.com\//, "");
534
+ return source;
535
+ }
536
+ function formatDuration(ms) {
537
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
538
+ return `${(ms / 1e3).toFixed(1)}s`;
539
+ }
540
+ function timedSpinner() {
541
+ const spin = p.spinner();
542
+ let startedAt = 0;
543
+ return {
544
+ start(msg) {
545
+ startedAt = Date.now();
546
+ spin.start(msg);
547
+ },
548
+ message(msg) {
549
+ spin.message(msg);
550
+ },
551
+ stop(msg) {
552
+ const elapsed = startedAt ? formatDuration(Date.now() - startedAt) : "";
553
+ spin.stop(elapsed ? `${msg} \x1B[90m[${elapsed}]\x1B[0m` : msg);
554
+ }
555
+ };
556
+ }
557
+ function highlightTerms(content, terms) {
558
+ if (terms.length === 0) return content;
559
+ const sorted = terms.toSorted((a, b) => b.length - a.length);
560
+ const pattern = new RegExp(`(${sorted.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, "gi");
561
+ return content.replace(pattern, "\x1B[33m$1\x1B[0m");
562
+ }
563
+ function scoreLabel(pct) {
564
+ return `${pct >= 70 ? "\x1B[32m" : pct >= 40 ? "\x1B[33m" : "\x1B[90m"}${pct}%\x1B[0m`;
565
+ }
566
+ function normalizeScores(results) {
567
+ const map = /* @__PURE__ */ new Map();
568
+ const max = results.reduce((m, r) => Math.max(m, r.score), 0);
569
+ for (const r of results) map.set(r, max > 0 ? Math.round(r.score / max * 100) : 0);
570
+ return map;
571
+ }
572
+ function formatSnippet(r, versions, pct) {
573
+ const refPath = `.claude/skills/${r.package}/.skilld/${r.source}`;
574
+ const lineRange = r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`;
575
+ const score = pct != null ? scoreLabel(pct) : `\x1B[90m${r.score.toFixed(2)}\x1B[0m`;
576
+ const version = versions?.get(r.package);
577
+ const pkgLabel = version ? `${r.package}@${version}` : r.package;
578
+ const scopeStr = r.scope?.length ? `${r.scope.map((e) => e.name).join(".")} → ` : "";
579
+ const entityStr = r.entities?.map((e) => e.signature || `${e.type} ${e.name}`).join(", ");
580
+ const highlighted = highlightTerms(r.content, r.highlights);
581
+ return [
582
+ `${pkgLabel} ${score}${entityStr ? ` \x1B[36m${scopeStr}${entityStr}\x1B[0m` : ""}`,
583
+ `\x1B[90m${refPath}:${lineRange}\x1B[0m`,
584
+ ` ${highlighted.replace(/\n/g, "\n ")}`
585
+ ].join("\n");
586
+ }
587
+ function formatCompactSnippet(r, cols) {
588
+ const entityStr = r.entities?.length ? r.entities.map((e) => e.signature || e.name).join(", ") : "";
589
+ const scopeStr = r.scope?.length ? `${r.scope.map((e) => e.name).join(".")} → ` : "";
590
+ const title = entityStr ? `${scopeStr}${entityStr}` : r.source.split("/").pop() || r.source;
591
+ const path = `${`.claude/skills/${r.package}/.skilld/${r.source}`}:${r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`}`;
592
+ const maxPreview = cols - 6;
593
+ const firstLine = r.content.split("\n").find((l) => l.trim() && l.trim() !== "---" && !/^#+\s*$/.test(l.trim())) || "";
594
+ return {
595
+ title,
596
+ path,
597
+ preview: firstLine.length > maxPreview ? `${firstLine.slice(0, maxPreview - 1)}…` : firstLine
598
+ };
599
+ }
600
+ function sanitizeName(name) {
601
+ return name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").slice(0, 255) || "unnamed-skill";
602
+ }
603
+ function computeSkillDirName(packageName) {
604
+ return `${sanitizeName(packageName)}-skilld`;
605
+ }
606
+ function installSkillForAgents(skillName, skillContent, options = {}) {
607
+ const isGlobal = options.global ?? false;
608
+ const cwd = options.cwd || process.cwd();
609
+ const sanitized = sanitizeName(skillName);
610
+ const explicit = !!options.agents;
611
+ const targetAgents = options.agents || detectInstalledAgents();
612
+ const installed = [];
613
+ const skipped = [];
614
+ const paths = [];
615
+ const writtenDirs = /* @__PURE__ */ new Set();
616
+ for (const agentType of targetAgents) {
617
+ const agent = targets[agentType];
618
+ if (isGlobal && !agent.globalSkillsDir) {
619
+ skipped.push({
620
+ agent: agentType,
621
+ reason: "no global support"
622
+ });
623
+ continue;
624
+ }
625
+ const baseDir = isGlobal ? agent.globalSkillsDir : join(cwd, agent.skillsDir);
626
+ if (!explicit && !existsSync(baseDir)) {
627
+ skipped.push({
628
+ agent: agentType,
629
+ reason: "skills dir not found"
630
+ });
631
+ continue;
632
+ }
633
+ if (isGlobal && (writtenDirs.has(baseDir) || agent.additionalSkillsDirs.some((d) => writtenDirs.has(d)))) {
634
+ skipped.push({
635
+ agent: agentType,
636
+ reason: "already covered by another agent dir"
637
+ });
638
+ continue;
639
+ }
640
+ const skillDir = join(baseDir, sanitized);
641
+ const skilldDir = skillInternalDir(skillDir);
642
+ mkdirSync(skilldDir, { recursive: true });
643
+ writeFileSync(join(skilldDir, "_SKILL.md"), sanitizeMarkdown(repairMarkdown(skillContent)));
644
+ if (options.files) for (const [filename, content] of Object.entries(options.files)) writeFileSync(join(skillDir, filename), filename.endsWith(".md") ? sanitizeMarkdown(repairMarkdown(content)) : content);
645
+ installed.push(agentType);
646
+ paths.push(skillDir);
647
+ writtenDirs.add(baseDir);
648
+ }
649
+ return {
650
+ installed,
651
+ skipped,
652
+ paths
653
+ };
654
+ }
655
+ function linkSkillToAgents(skillName, sharedDir, cwd, agentType) {
656
+ const targetAgents = agentType ? [[agentType, targets[agentType]]] : Object.entries(targets);
657
+ const linkedDirs = /* @__PURE__ */ new Set();
658
+ for (const [type, agent] of targetAgents) {
659
+ const agentSkillsDir = join(cwd, agent.skillsDir);
660
+ if (agentType === type) mkdirSync(agentSkillsDir, { recursive: true });
661
+ else {
662
+ if (!existsSync(agentSkillsDir)) continue;
663
+ if (agent.additionalSkillsDirs.map((d) => join(cwd, d)).some((d) => linkedDirs.has(d))) {
664
+ const staleTarget = join(agentSkillsDir, skillName);
665
+ try {
666
+ if (lstatSync(staleTarget).isSymbolicLink() && !existsSync(staleTarget)) unlinkSync(staleTarget);
667
+ } catch {}
668
+ continue;
669
+ }
670
+ }
671
+ const target = join(agentSkillsDir, skillName);
672
+ let isSymlink = false;
673
+ let targetExists = false;
674
+ try {
675
+ const stat = lstatSync(target);
676
+ targetExists = true;
677
+ isSymlink = stat.isSymbolicLink();
678
+ } catch {}
679
+ if (targetExists && !isSymlink) continue;
680
+ if (isSymlink) unlinkSync(target);
681
+ symlinkSync(relative(agentSkillsDir, join(sharedDir, skillName)), target);
682
+ linkedDirs.add(agentSkillsDir);
683
+ }
684
+ }
685
+ function unlinkSkillFromAgents(skillName, cwd, agentType) {
686
+ const targetAgents = agentType ? [[agentType, targets[agentType]]] : Object.entries(targets);
687
+ for (const [, agent] of targetAgents) {
688
+ const target = join(cwd, agent.skillsDir, skillName);
689
+ try {
690
+ if (lstatSync(target).isSymbolicLink()) unlinkSync(target);
691
+ } catch {}
692
+ }
693
+ }
694
+ function writeSkillMd(skillDir, content) {
695
+ writeFileSync(join(skillDir, "SKILL.md"), content);
696
+ }
697
+ function writeGeneratedSkillMd(skillDir, opts) {
698
+ const content = generateSkillMd(opts);
699
+ writeSkillMd(skillDir, content);
700
+ return content;
701
+ }
702
+ function generateSkillMd(opts) {
703
+ const header = generatePackageHeader(opts);
704
+ const search = !opts.eject && opts.features?.search !== false ? generateSearchBlock(opts.name) : "";
705
+ let body = opts.body;
706
+ if (body && opts.eject) {
707
+ body = body.replace(/\.\/\.skilld\//g, "./references/");
708
+ body = body.replace(/\s*\[source\]\(\.\/references\/pkg\/[^)]*\)/gi, "");
709
+ }
710
+ const content = body ? search ? `${header}\n\n${search}\n\n${body}` : `${header}\n\n${body}` : search ? `${header}\n\n${search}` : header;
711
+ const footer = generateFooter(opts.relatedSkills);
712
+ return sanitizeMarkdown(repairMarkdown(`${generateFrontmatter(opts)}${content}\n${footer}`));
713
+ }
714
+ function formatShortDate(isoDate) {
715
+ const date = new Date(isoDate);
716
+ if (Number.isNaN(date.getTime())) return "";
717
+ return `${[
718
+ "Jan",
719
+ "Feb",
720
+ "Mar",
721
+ "Apr",
722
+ "May",
723
+ "Jun",
724
+ "Jul",
725
+ "Aug",
726
+ "Sep",
727
+ "Oct",
728
+ "Nov",
729
+ "Dec"
730
+ ][date.getUTCMonth()]} ${date.getUTCFullYear()}`;
731
+ }
732
+ function generatePackageHeader({ name, version, distTags, repoUrl, hasIssues, hasDiscussions, hasReleases, docsType, pkgFiles, packages, eject }) {
733
+ const versionSuffix = version ? `@${version}` : "";
734
+ let title = `# ${name}${versionSuffix}`;
735
+ if (repoUrl) {
736
+ const url = repoUrl.startsWith("http") ? repoUrl : `https://github.com/${repoUrl}`;
737
+ title = `# [${repoUrl.startsWith("http") ? repoUrl.split("/").slice(-2).join("/") : repoUrl}](${url}) \`${name}${versionSuffix}\``;
738
+ }
739
+ const lines = [title];
740
+ if (distTags && Object.keys(distTags).length > 0) {
741
+ const tags = Object.entries(distTags).sort(([, a], [, b]) => (b.releasedAt ?? "").localeCompare(a.releasedAt ?? "")).slice(0, 3).map(([tag, info]) => {
742
+ const relDate = info.releasedAt ? ` (${formatShortDate(info.releasedAt)})` : "";
743
+ return `${tag}: ${info.version}${relDate}`;
744
+ }).join(", ");
745
+ lines.push(`**Tags:** ${tags}`);
746
+ }
747
+ lines.push("");
748
+ const refBase = eject ? "./references" : "./.skilld";
749
+ const refs = [];
750
+ if (!eject) {
751
+ refs.push(`[package.json](${refBase}/pkg/package.json)`);
752
+ if (packages && packages.length > 1) for (const pkg of packages) {
753
+ const shortName = pkg.name.split("/").pop().toLowerCase();
754
+ refs.push(`[pkg-${shortName}](${refBase}/pkg-${shortName}/package.json)`);
755
+ }
756
+ if (pkgFiles?.includes("README.md")) refs.push(`[README](${refBase}/pkg/README.md)`);
757
+ }
758
+ if (docsType && docsType !== "readme") refs.push(`[Docs](${refBase}/docs/_INDEX.md)`);
759
+ if (hasIssues) refs.push(`[Issues](${refBase}/issues/_INDEX.md)`);
760
+ if (hasDiscussions) refs.push(`[Discussions](${refBase}/discussions/_INDEX.md)`);
761
+ if (hasReleases) refs.push(`[Releases](${refBase}/releases/_INDEX.md)`);
762
+ if (refs.length > 0) lines.push(`**References:** ${refs.join(" • ")}`);
763
+ return lines.join("\n");
764
+ }
765
+ function expandPackageName(name) {
766
+ const variants = /* @__PURE__ */ new Set();
767
+ const unscoped = name.replace(/^@/, "");
768
+ if (unscoped !== name) {
769
+ variants.add(unscoped);
770
+ variants.add(unscoped.replace(/\//g, " "));
771
+ }
772
+ if (name.includes("-")) {
773
+ const spaced = name.replace(/^@/, "").replace(/\//g, " ").replace(/-/g, " ");
774
+ variants.add(spaced);
775
+ }
776
+ variants.delete(name);
777
+ return [...variants];
778
+ }
779
+ function expandRepoName(repoUrl) {
780
+ const variants = /* @__PURE__ */ new Set();
781
+ const repoName = repoUrl.startsWith("http") ? repoUrl.split("/").pop() : repoUrl.split("/").pop();
782
+ if (!repoName) return [];
783
+ variants.add(repoName);
784
+ if (repoName.includes("-")) variants.add(repoName.replace(/-/g, " "));
785
+ return [...variants];
786
+ }
787
+ function generateFrontmatter({ name, version, description: pkgDescription, globs, body, generatedBy, dirName, packages, repoUrl }) {
788
+ const patterns = globs ?? getFilePatterns(name);
789
+ const globHint = patterns?.length ? ` or working with ${patterns.join(", ")} files` : "";
790
+ const rawDesc = pkgDescription?.replace(/[<>]/g, "").replace(/\.?\s*$/, "");
791
+ const cleanDesc = rawDesc && rawDesc.length > 200 ? `${rawDesc.slice(0, 197)}...` : rawDesc;
792
+ const editHint = globHint ? `editing${globHint} or code importing` : "writing code importing";
793
+ let desc;
794
+ if (packages && packages.length > 1) {
795
+ const importList = packages.map((p) => `"${p.name}"`).join(", ");
796
+ const allKeywords = /* @__PURE__ */ new Set();
797
+ for (const pkg of packages) {
798
+ allKeywords.add(pkg.name);
799
+ for (const kw of expandPackageName(pkg.name)) allKeywords.add(kw);
800
+ }
801
+ const keywordList = [...allKeywords].join(", ");
802
+ desc = `${cleanDesc ? `${cleanDesc}. ` : ""}ALWAYS use when ${editHint} ${importList}. Consult for debugging, best practices, or modifying ${keywordList}.`;
803
+ } else {
804
+ const allKeywords = /* @__PURE__ */ new Set();
805
+ allKeywords.add(name);
806
+ for (const kw of expandPackageName(name)) allKeywords.add(kw);
807
+ if (repoUrl) for (const kw of expandRepoName(repoUrl)) allKeywords.add(kw);
808
+ const nameList = [...allKeywords].join(", ");
809
+ desc = `${cleanDesc ? `${cleanDesc}. ` : ""}ALWAYS use when ${editHint} "${name}". Consult for debugging, best practices, or modifying ${nameList}.`;
810
+ }
811
+ if (desc.length > 1024) desc = `${desc.slice(0, 1021)}...`;
812
+ const lines = [
813
+ "---",
814
+ `name: ${dirName ?? computeSkillDirName(name)}`,
815
+ `description: ${yamlEscape(desc)}`
816
+ ];
817
+ const metaEntries = [];
818
+ if (version) metaEntries.push(` version: ${yamlEscape(version)}`);
819
+ if (body && generatedBy) metaEntries.push(` generated_by: ${yamlEscape(generatedBy)}`);
820
+ metaEntries.push(` generated_at: ${todayIsoDate()}`);
821
+ if (metaEntries.length) {
822
+ lines.push("metadata:");
823
+ lines.push(...metaEntries);
824
+ }
825
+ lines.push("---", "", "");
826
+ return lines.join("\n");
827
+ }
828
+ function generateSearchBlock(name) {
829
+ const cmd = resolveSkilldCommand();
830
+ return `## Search
831
+
832
+ Use \`${cmd} search "query" -p ${name}\` instead of grepping \`.skilld/\` directories. Run \`${cmd} search --guide -p ${name}\` for full syntax, filters, and operators.`;
833
+ }
834
+ function generateFooter(relatedSkills) {
835
+ if (relatedSkills.length === 0) return "";
836
+ return `\nRelated: ${relatedSkills.join(", ")}\n`;
837
+ }
838
+ export { portabilizePrompt as C, maxItems as D, SECTION_OUTPUT_FILES as E, maxLines as O, getSectionValidator as S, SECTION_MERGE_ORDER as T, timedSpinner as _, installSkillForAgents as a, buildSectionPrompt as b, unlinkSkillFromAgents as c, formatSnippet as d, formatSource as f, timeAgo as g, scoreLabel as h, computeSkillDirName as i, resolveSkilldCommand as k, formatCompactSnippet as l, normalizeScores as m, writeGeneratedSkillMd as n, linkSkillToAgents as o, highlightTerms as p, writeSkillMd as r, sanitizeName as s, generateSkillMd as t, formatDuration as u, todayIsoDate as v, wrapSection as w, extractMarkedSections as x, buildAllSectionPrompts as y };
491
839
 
492
840
  //# sourceMappingURL=prompts.mjs.map