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,9 +1,279 @@
1
- import { a as REFERENCES_DIR, c as getRepoCacheDir, o as REPOS_DIR, t as getCacheDir } from "./version.mjs";
1
+ import { l as getPackageDbPath, n as CONFIG_PATH, o as REFERENCES_DIR, p as skillInternalDir, s as REPOS_DIR, t as CACHE_DIR, u as getRepoCacheDir } from "./paths.mjs";
2
+ import { n as yamlParseKV, r as yamlUnescape, t as yamlEscape } from "./yaml.mjs";
2
3
  import { i as readPackageJsonSafe } from "./package-json.mjs";
4
+ import { r as getVersionKey, t as getCacheDir } from "./version.mjs";
3
5
  import { r as resolvePkgDir } from "./prepare.mjs";
4
6
  import { n as sanitizeMarkdown } from "./sanitize.mjs";
5
- import { basename, join, resolve } from "pathe";
6
- import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
7
+ import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
8
+ import { basename, dirname, join, resolve } from "pathe";
9
+ const defaultFeatures = {
10
+ search: true,
11
+ issues: true,
12
+ discussions: true,
13
+ releases: true
14
+ };
15
+ function getActiveFeatures(overrides) {
16
+ const fromConfig = readConfig().features;
17
+ const merged = {
18
+ ...defaultFeatures,
19
+ ...fromConfig ?? {}
20
+ };
21
+ return overrides ? {
22
+ ...merged,
23
+ ...overrides
24
+ } : merged;
25
+ }
26
+ let configCache;
27
+ function hasConfig() {
28
+ return existsSync(CONFIG_PATH);
29
+ }
30
+ function hasCompletedWizard() {
31
+ if (!existsSync(CONFIG_PATH)) return false;
32
+ const config = readConfig();
33
+ return config.features !== void 0 || config.model !== void 0 || config.skipLlm !== void 0;
34
+ }
35
+ function readConfig() {
36
+ if (configCache) return {
37
+ ...configCache,
38
+ features: configCache.features ? { ...configCache.features } : void 0,
39
+ projects: configCache.projects ? [...configCache.projects] : void 0
40
+ };
41
+ if (!existsSync(CONFIG_PATH)) return {};
42
+ const content = readFileSync(CONFIG_PATH, "utf-8");
43
+ const config = {};
44
+ let inBlock = null;
45
+ const projects = [];
46
+ const features = {};
47
+ for (const line of content.split("\n")) {
48
+ if (line.startsWith("projects:")) {
49
+ inBlock = "projects";
50
+ continue;
51
+ }
52
+ if (line.startsWith("features:")) {
53
+ inBlock = "features";
54
+ continue;
55
+ }
56
+ if (inBlock === "projects") {
57
+ if (line.startsWith(" - ")) {
58
+ projects.push(yamlUnescape(line.slice(4)));
59
+ continue;
60
+ }
61
+ inBlock = null;
62
+ }
63
+ if (inBlock === "features") {
64
+ const m = line.match(/^ {2}(\w+):\s*(.+)/);
65
+ if (m) {
66
+ const key = m[1];
67
+ if (key in defaultFeatures) features[key] = m[2] === "true";
68
+ continue;
69
+ }
70
+ inBlock = null;
71
+ }
72
+ const kv = yamlParseKV(line);
73
+ if (!kv) continue;
74
+ const [key, value] = kv;
75
+ if (key === "model" && value) config.model = value;
76
+ if (key === "agent" && value) config.agent = value;
77
+ if (key === "skipLlm") config.skipLlm = value === "true";
78
+ }
79
+ if (projects.length > 0) config.projects = projects;
80
+ if (Object.keys(features).length > 0) config.features = {
81
+ ...defaultFeatures,
82
+ ...features
83
+ };
84
+ configCache = config;
85
+ return config;
86
+ }
87
+ function writeConfig(config) {
88
+ mkdirSync(CACHE_DIR, {
89
+ recursive: true,
90
+ mode: 448
91
+ });
92
+ let yaml = "";
93
+ if (config.model) yaml += `model: ${config.model}\n`;
94
+ if (config.agent) yaml += `agent: ${config.agent}\n`;
95
+ if (config.skipLlm) yaml += `skipLlm: true\n`;
96
+ if (config.features) {
97
+ yaml += "features:\n";
98
+ for (const [k, v] of Object.entries(config.features)) yaml += ` ${k}: ${v}\n`;
99
+ }
100
+ if (config.projects?.length) {
101
+ yaml += "projects:\n";
102
+ for (const p of config.projects) yaml += ` - ${yamlEscape(p)}\n`;
103
+ }
104
+ writeFileSync(CONFIG_PATH, yaml, { mode: 384 });
105
+ configCache = void 0;
106
+ }
107
+ function updateConfig(updates) {
108
+ writeConfig({
109
+ ...readConfig(),
110
+ ...updates
111
+ });
112
+ }
113
+ function registerProject(projectPath) {
114
+ const config = readConfig();
115
+ const projects = new Set(config.projects || []);
116
+ projects.add(projectPath);
117
+ writeConfig({
118
+ ...config,
119
+ projects: [...projects]
120
+ });
121
+ }
122
+ function unregisterProject(projectPath) {
123
+ const config = readConfig();
124
+ const projects = (config.projects || []).filter((p) => p !== projectPath);
125
+ writeConfig({
126
+ ...config,
127
+ projects
128
+ });
129
+ }
130
+ function getRegisteredProjects() {
131
+ return readConfig().projects || [];
132
+ }
133
+ function getSkillReferenceDirs(skillDir) {
134
+ const refsDir = skillInternalDir(skillDir);
135
+ if (!existsSync(refsDir)) return [];
136
+ const resolved = readdirSync(refsDir).map((entry) => join(refsDir, entry)).filter((p) => lstatSync(p).isSymbolicLink() && existsSync(p)).map((p) => realpathSync(p));
137
+ const parents = /* @__PURE__ */ new Set();
138
+ for (const p of resolved) {
139
+ const parent = dirname(p);
140
+ if (!resolved.includes(parent)) parents.add(parent);
141
+ }
142
+ return [...resolved, ...parents];
143
+ }
144
+ function clearSkillInternalDir(skillDir) {
145
+ const refsDir = skillInternalDir(skillDir);
146
+ if (existsSync(refsDir)) rmSync(refsDir, {
147
+ recursive: true,
148
+ force: true
149
+ });
150
+ }
151
+ function classifyCachedDoc(path) {
152
+ const issueMatch = path.match(/^issues\/issue-(\d+)\.md$/);
153
+ if (issueMatch) return {
154
+ type: "issue",
155
+ number: Number(issueMatch[1])
156
+ };
157
+ const discussionMatch = path.match(/^discussions\/discussion-(\d+)\.md$/);
158
+ if (discussionMatch) return {
159
+ type: "discussion",
160
+ number: Number(discussionMatch[1])
161
+ };
162
+ if (path.startsWith("releases/")) return { type: "release" };
163
+ return { type: "doc" };
164
+ }
165
+ function forceClearCache(packageName, version, repoInfo) {
166
+ clearCache(packageName, version);
167
+ const forcedDbPath = getPackageDbPath(packageName, version);
168
+ if (existsSync(forcedDbPath)) rmSync(forcedDbPath, {
169
+ recursive: true,
170
+ force: true
171
+ });
172
+ if (repoInfo) {
173
+ const repoDir = getRepoCacheDir(repoInfo.owner, repoInfo.repo);
174
+ if (existsSync(repoDir)) rmSync(repoDir, {
175
+ recursive: true,
176
+ force: true
177
+ });
178
+ }
179
+ }
180
+ function linkAllReferences(skillDir, packageName, cwd, version, docsType, extraPackages, features, repoInfo) {
181
+ const f = features ?? readConfig().features ?? defaultFeatures;
182
+ try {
183
+ linkPkg(skillDir, packageName, cwd, version);
184
+ linkPkgNamed(skillDir, packageName, cwd, version);
185
+ if (!hasShippedDocs(packageName, cwd, version) && docsType !== "readme") linkCachedDir(skillDir, packageName, version, "docs");
186
+ if (f.issues) if (repoInfo) linkRepoCachedDir(skillDir, repoInfo.owner, repoInfo.repo, "issues");
187
+ else linkCachedDir(skillDir, packageName, version, "issues");
188
+ if (f.discussions) if (repoInfo) linkRepoCachedDir(skillDir, repoInfo.owner, repoInfo.repo, "discussions");
189
+ else linkCachedDir(skillDir, packageName, version, "discussions");
190
+ if (f.releases) if (repoInfo) linkRepoCachedDir(skillDir, repoInfo.owner, repoInfo.repo, "releases");
191
+ else linkCachedDir(skillDir, packageName, version, "releases");
192
+ linkCachedDir(skillDir, packageName, version, "sections");
193
+ if (extraPackages) {
194
+ for (const pkg of extraPackages) if (pkg.name !== packageName) linkPkgNamed(skillDir, pkg.name, cwd, pkg.version);
195
+ }
196
+ } catch {}
197
+ }
198
+ function detectDocsType(packageName, version, repoUrl, llmsUrl) {
199
+ const cacheDir = getCacheDir(packageName, version);
200
+ if (existsSync(join(cacheDir, "docs", "index.md")) || existsSync(join(cacheDir, "docs", "guide"))) return {
201
+ docsType: "docs",
202
+ docSource: repoUrl ? `${repoUrl}/tree/v${version}/docs` : "git"
203
+ };
204
+ if (existsSync(join(cacheDir, "llms.txt"))) return {
205
+ docsType: "llms.txt",
206
+ docSource: llmsUrl || "llms.txt"
207
+ };
208
+ if (existsSync(join(cacheDir, "docs", "README.md"))) return { docsType: "readme" };
209
+ return { docsType: "readme" };
210
+ }
211
+ function ejectReferences(skillDir, packageName, cwd, version, docsType, features, repoInfo) {
212
+ const f = features ?? readConfig().features ?? defaultFeatures;
213
+ const cacheDir = getCacheDir(packageName, version);
214
+ const refsDir = join(skillDir, "references");
215
+ const repoDir = repoInfo ? getRepoCacheDir(repoInfo.owner, repoInfo.repo) : cacheDir;
216
+ if (!hasShippedDocs(packageName, cwd, version) && docsType !== "readme") copyCachedSubdir(cacheDir, refsDir, "docs");
217
+ if (f.issues) copyCachedSubdir(repoDir, refsDir, "issues");
218
+ if (f.discussions) copyCachedSubdir(repoDir, refsDir, "discussions");
219
+ if (f.releases) copyCachedSubdir(repoDir, refsDir, "releases");
220
+ }
221
+ function copyCachedSubdir(cacheDir, refsDir, subdir) {
222
+ const srcDir = join(cacheDir, subdir);
223
+ if (!existsSync(srcDir)) return;
224
+ const destDir = join(refsDir, subdir);
225
+ mkdirSync(destDir, { recursive: true });
226
+ function walk(dir, rel) {
227
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
228
+ const srcPath = join(dir, entry.name);
229
+ const destPath = join(destDir, rel ? `${rel}/${entry.name}` : entry.name);
230
+ if (entry.isDirectory()) {
231
+ mkdirSync(destPath, { recursive: true });
232
+ walk(srcPath, rel ? `${rel}/${entry.name}` : entry.name);
233
+ } else copyFileSync(srcPath, destPath);
234
+ }
235
+ }
236
+ walk(srcDir, "");
237
+ }
238
+ function loadCachedReferences(opts) {
239
+ const { packageName, version, repoUrl, llmsUrl, readmeUrl, onProgress, generateDocsIndex } = opts;
240
+ onProgress("Loading cached docs");
241
+ const detected = detectDocsType(packageName, version, repoUrl, llmsUrl);
242
+ const docsType = detected.docsType;
243
+ const docSource = detected.docSource ?? readmeUrl ?? "readme";
244
+ const docsToIndex = [];
245
+ if (!existsSync(getPackageDbPath(packageName, version))) {
246
+ onProgress("Reading cached docs for indexing");
247
+ const cached = readCachedDocs(packageName, version);
248
+ for (const doc of cached) docsToIndex.push({
249
+ id: doc.path,
250
+ content: doc.content,
251
+ metadata: {
252
+ package: packageName,
253
+ source: doc.path,
254
+ ...classifyCachedDoc(doc.path)
255
+ }
256
+ });
257
+ }
258
+ let backfillIndex;
259
+ if (docsType !== "readme" && !existsSync(join(getCacheDir(packageName, version), "docs", "_INDEX.md"))) {
260
+ onProgress("Generating docs index");
261
+ const cached = readCachedDocs(packageName, version);
262
+ if (cached.filter((d) => d.path.startsWith("docs/") && d.path.endsWith(".md")).length > 1) {
263
+ const docsIndex = generateDocsIndex(cached);
264
+ if (docsIndex) backfillIndex = {
265
+ path: "docs/_INDEX.md",
266
+ content: docsIndex
267
+ };
268
+ }
269
+ }
270
+ return {
271
+ docsToIndex,
272
+ docSource,
273
+ docsType,
274
+ backfillIndex
275
+ };
276
+ }
7
277
  function safeSymlink(target, linkPath) {
8
278
  const resolved = resolve(target);
9
279
  if (!resolved.startsWith(REFERENCES_DIR) && !resolved.startsWith(REPOS_DIR)) throw new Error(`Symlink target outside allowed dirs: ${resolved}`);
@@ -70,7 +340,7 @@ function writeToRepoCache(owner, repo, docs) {
70
340
  }
71
341
  function linkRepoCachedDir(skillDir, owner, repo, subdir) {
72
342
  const repoDir = getRepoCacheDir(owner, repo);
73
- const referencesDir = join(skillDir, ".skilld");
343
+ const referencesDir = skillInternalDir(skillDir);
74
344
  const linkPath = join(referencesDir, subdir);
75
345
  const cachedPath = join(repoDir, subdir);
76
346
  mkdirSync(referencesDir, { recursive: true });
@@ -78,7 +348,7 @@ function linkRepoCachedDir(skillDir, owner, repo, subdir) {
78
348
  }
79
349
  function linkCachedDir(skillDir, name, version, subdir) {
80
350
  const cacheDir = getCacheDir(name, version);
81
- const referencesDir = join(skillDir, ".skilld");
351
+ const referencesDir = skillInternalDir(skillDir);
82
352
  const linkPath = join(referencesDir, subdir);
83
353
  const cachedPath = join(cacheDir, subdir);
84
354
  mkdirSync(referencesDir, { recursive: true });
@@ -87,7 +357,7 @@ function linkCachedDir(skillDir, name, version, subdir) {
87
357
  function linkPkg(skillDir, name, cwd, version) {
88
358
  const pkgPath = resolvePkgDir(name, cwd, version);
89
359
  if (!pkgPath) return;
90
- const referencesDir = join(skillDir, ".skilld");
360
+ const referencesDir = skillInternalDir(skillDir);
91
361
  mkdirSync(referencesDir, { recursive: true });
92
362
  const pkgLinkPath = join(referencesDir, "pkg");
93
363
  try {
@@ -100,7 +370,7 @@ function linkPkgNamed(skillDir, name, cwd, version) {
100
370
  const pkgPath = resolvePkgDir(name, cwd, version);
101
371
  if (!pkgPath) return;
102
372
  const shortName = name.split("/").pop().toLowerCase();
103
- const referencesDir = join(skillDir, ".skilld");
373
+ const referencesDir = skillInternalDir(skillDir);
104
374
  mkdirSync(referencesDir, { recursive: true });
105
375
  const linkPath = join(referencesDir, `pkg-${shortName}`);
106
376
  try {
@@ -190,7 +460,7 @@ function clearAllCache() {
190
460
  return packages.length;
191
461
  }
192
462
  function listReferenceFiles(skillDir, maxDepth = 3) {
193
- const referencesDir = join(skillDir, ".skilld");
463
+ const referencesDir = skillInternalDir(skillDir);
194
464
  if (!existsSync(referencesDir)) return [];
195
465
  const files = [];
196
466
  function walk(dir, depth) {
@@ -213,6 +483,42 @@ function listReferenceFiles(skillDir, maxDepth = 3) {
213
483
  walk(referencesDir, 0);
214
484
  return files;
215
485
  }
216
- export { writeSections as _, hasShippedDocs as a, isReadmeOnlyCache as c, linkPkgNamed as d, linkRepoCachedDir as f, readCachedSection as g, readCachedDocs as h, getPkgKeyFiles as i, linkCachedDir as l, listReferenceFiles as m, clearCache as n, inferDocsTypeFromCache as o, listCached as p, ensureCacheDir as r, isCached as s, clearAllCache as t, linkPkg as u, writeToCache as v, writeToRepoCache as y };
486
+ function createReferenceCache(packageName, version) {
487
+ const requireVersion = (op) => {
488
+ if (!version) throw new Error(`ReferenceCache.${op} requires a version (package: ${packageName})`);
489
+ return version;
490
+ };
491
+ return {
492
+ packageName,
493
+ version,
494
+ get versionKey() {
495
+ return getVersionKey(requireVersion("versionKey"));
496
+ },
497
+ get dir() {
498
+ return getCacheDir(packageName, requireVersion("dir"));
499
+ },
500
+ ensure: () => ensureCacheDir(),
501
+ has: () => !!version && isCached(packageName, version),
502
+ write: (docs) => void writeToCache(packageName, requireVersion("write"), docs),
503
+ writeSections: (sections) => writeSections(packageName, requireVersion("writeSections"), sections),
504
+ readSection: (file) => readCachedSection(packageName, requireVersion("readSection"), file),
505
+ readDocs: () => readCachedDocs(packageName, requireVersion("readDocs")),
506
+ detectDocs: (repoUrl, llmsUrl) => detectDocsType(packageName, requireVersion("detectDocs"), repoUrl, llmsUrl),
507
+ load: (opts) => loadCachedReferences({
508
+ ...opts,
509
+ packageName,
510
+ version: requireVersion("load")
511
+ }),
512
+ linkInto: (skillDir, cwd, docsType, opts) => linkAllReferences(skillDir, packageName, cwd, requireVersion("linkInto"), docsType, opts?.extraPackages, opts?.features, opts?.repoInfo),
513
+ linkPkgNamed: (skillDir, cwd) => linkPkgNamed(skillDir, packageName, cwd, version),
514
+ eject: (skillDir, cwd, docsType, opts) => ejectReferences(skillDir, packageName, cwd, requireVersion("eject"), docsType, opts?.features, opts?.repoInfo),
515
+ clearForce: (repoInfo) => forceClearCache(packageName, requireVersion("clearForce"), repoInfo),
516
+ clearSkillInternal: (skillDir) => clearSkillInternalDir(skillDir),
517
+ pkgDir: (cwd) => resolvePkgDir(packageName, cwd, version),
518
+ hasShipped: (cwd) => hasShippedDocs(packageName, cwd, version),
519
+ keyFiles: (cwd) => getPkgKeyFiles(packageName, cwd, version)
520
+ };
521
+ }
522
+ export { getActiveFeatures as A, detectDocsType as C, linkAllReferences as D, getSkillReferenceDirs as E, registerProject as F, unregisterProject as I, updateConfig as L, hasCompletedWizard as M, hasConfig as N, loadCachedReferences as O, readConfig as P, clearSkillInternalDir as S, forceClearCache as T, readCachedSection as _, getPkgKeyFiles as a, writeToRepoCache as b, isCached as c, linkPkg as d, linkPkgNamed as f, readCachedDocs as g, listReferenceFiles as h, ensureCacheDir as i, getRegisteredProjects as j, defaultFeatures as k, isReadmeOnlyCache as l, listCached as m, clearAllCache as n, hasShippedDocs as o, linkRepoCachedDir as p, clearCache as r, inferDocsTypeFromCache as s, createReferenceCache as t, linkCachedDir as u, writeSections as v, ejectReferences as w, classifyCachedDoc as x, writeToCache as y };
217
523
 
218
524
  //# sourceMappingURL=cache.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache.mjs","names":[],"sources":["../../src/cache/storage.ts"],"sourcesContent":["/**\n * Cache storage operations\n */\n\nimport type { CachedDoc, CachedPackage } from './types.ts'\nimport { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { basename, join, resolve } from 'pathe'\nimport { readPackageJsonSafe } from '../core/package-json.ts'\nimport { resolvePkgDir } from '../core/prepare.ts'\nimport { sanitizeMarkdown } from '../core/sanitize.ts'\nimport { getRepoCacheDir, REFERENCES_DIR, REPOS_DIR } from './config.ts'\nimport { getCacheDir } from './version.ts'\n\n/** Safely create a symlink, validating target is under REFERENCES_DIR or REPOS_DIR */\nfunction safeSymlink(target: string, linkPath: string): void {\n const resolved = resolve(target)\n if (!resolved.startsWith(REFERENCES_DIR) && !resolved.startsWith(REPOS_DIR))\n throw new Error(`Symlink target outside allowed dirs: ${resolved}`)\n // Remove pre-existing symlink (check with lstat to detect symlinks)\n try {\n const stat = lstatSync(linkPath)\n if (stat.isSymbolicLink() || stat.isFile())\n unlinkSync(linkPath)\n }\n catch {}\n symlinkSync(target, linkPath, 'junction')\n}\n\n/**\n * Check if package is cached at given version\n */\nexport function isCached(name: string, version: string): boolean {\n return existsSync(getCacheDir(name, version))\n}\n\n/** Check if cache only has docs/README.md (pkg/ already has this) */\nexport function isReadmeOnlyCache(cacheDir: string): boolean {\n const docsDir = join(cacheDir, 'docs')\n if (!existsSync(docsDir))\n return false\n const files = readdirSync(docsDir)\n return files.length === 1 && files[0] === 'README.md'\n}\n\nexport function inferDocsTypeFromCache(cacheDir: string, source?: string): 'llms.txt' | 'readme' | 'docs' {\n if (source?.includes('llms.txt') || existsSync(join(cacheDir, 'docs', 'llms.txt')))\n return 'llms.txt'\n return isReadmeOnlyCache(cacheDir) ? 'readme' : 'docs'\n}\n\n/**\n * Ensure cache directories exist\n */\nexport function ensureCacheDir(): void {\n mkdirSync(REFERENCES_DIR, { recursive: true, mode: 0o700 })\n mkdirSync(REPOS_DIR, { recursive: true, mode: 0o700 })\n}\n\n/**\n * Write docs to cache\n */\nexport function writeToCache(\n name: string,\n version: string,\n docs: CachedDoc[],\n): string {\n const cacheDir = getCacheDir(name, version)\n mkdirSync(cacheDir, { recursive: true, mode: 0o700 })\n\n for (const doc of docs) {\n const filePath = join(cacheDir, doc.path)\n mkdirSync(join(filePath, '..'), { recursive: true, mode: 0o700 })\n writeFileSync(filePath, sanitizeMarkdown(doc.content), { mode: 0o600 })\n }\n\n return cacheDir\n}\n\n/**\n * Write docs to repo-level cache (~/.skilld/repos/<owner>/<repo>/)\n */\nexport function writeToRepoCache(\n owner: string,\n repo: string,\n docs: CachedDoc[],\n): string {\n const repoDir = getRepoCacheDir(owner, repo)\n mkdirSync(repoDir, { recursive: true, mode: 0o700 })\n\n for (const doc of docs) {\n const filePath = join(repoDir, doc.path)\n mkdirSync(join(filePath, '..'), { recursive: true, mode: 0o700 })\n writeFileSync(filePath, sanitizeMarkdown(doc.content), { mode: 0o600 })\n }\n\n return repoDir\n}\n\n/**\n * Create symlink from .skilld dir to a repo-level cached subdirectory.\n * .claude/skills/<skill>/.skilld/<subdir> -> ~/.skilld/repos/<owner>/<repo>/<subdir>\n */\nexport function linkRepoCachedDir(skillDir: string, owner: string, repo: string, subdir: string): void {\n const repoDir = getRepoCacheDir(owner, repo)\n const referencesDir = join(skillDir, '.skilld')\n const linkPath = join(referencesDir, subdir)\n const cachedPath = join(repoDir, subdir)\n\n mkdirSync(referencesDir, { recursive: true })\n\n if (existsSync(cachedPath)) {\n safeSymlink(cachedPath, linkPath)\n }\n}\n\n/**\n * Create symlink from .skilld dir to a cached subdirectory.\n * Unified handler for docs, issues, discussions, sections, releases.\n *\n * Structure:\n * .claude/skills/<skill>/.skilld/<subdir> -> ~/.skilld/references/<pkg>@<version>/<subdir>\n *\n * The .skilld/ dirs are gitignored. After clone, `skilld install` recreates from lockfile.\n */\nexport function linkCachedDir(skillDir: string, name: string, version: string, subdir: string): void {\n const cacheDir = getCacheDir(name, version)\n const referencesDir = join(skillDir, '.skilld')\n const linkPath = join(referencesDir, subdir)\n const cachedPath = join(cacheDir, subdir)\n\n mkdirSync(referencesDir, { recursive: true })\n\n if (existsSync(cachedPath)) {\n safeSymlink(cachedPath, linkPath)\n }\n}\n\n/**\n * Resolve the package directory: node_modules first, then cached dist fallback.\n * Returns the path if found, null otherwise.\n */\nexport { resolvePkgDir } from '../core/prepare.ts'\nexport { getShippedSkills, linkShippedSkill } from '../core/prepare.ts'\nexport type { ShippedSkill } from '../core/prepare.ts'\n\n/**\n * Create symlink from .skilld dir to package directory\n *\n * Structure:\n * .claude/skills/<skill>/.skilld/pkg -> node_modules/<pkg> OR ~/.skilld/references/<pkg>@<version>/pkg\n *\n * This gives access to package.json, README.md, dist/, and any shipped docs/\n */\nexport function linkPkg(skillDir: string, name: string, cwd: string, version?: string): void {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return\n\n const referencesDir = join(skillDir, '.skilld')\n mkdirSync(referencesDir, { recursive: true })\n\n const pkgLinkPath = join(referencesDir, 'pkg')\n try {\n lstatSync(pkgLinkPath)\n unlinkSync(pkgLinkPath)\n }\n catch {}\n symlinkSync(pkgPath, pkgLinkPath, 'junction')\n}\n\n/**\n * Create named symlink from .skilld dir to package directory.\n * Short name = last segment of package name (e.g., @vue/reactivity → pkg-reactivity)\n *\n * Structure:\n * .claude/skills/<skill>/.skilld/pkg-<short> -> node_modules/<pkg>\n */\nexport function linkPkgNamed(skillDir: string, name: string, cwd: string, version?: string): void {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return\n\n const shortName = name.split('/').pop()!.toLowerCase()\n const referencesDir = join(skillDir, '.skilld')\n mkdirSync(referencesDir, { recursive: true })\n\n const linkPath = join(referencesDir, `pkg-${shortName}`)\n try {\n lstatSync(linkPath)\n unlinkSync(linkPath)\n }\n catch {}\n symlinkSync(pkgPath, linkPath, 'junction')\n}\n\n/**\n * Get key files from a package directory for display\n * Returns entry points + docs files\n */\nexport function getPkgKeyFiles(name: string, cwd: string, version?: string): string[] {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return []\n\n const files: string[] = []\n const pkgJsonPath = join(pkgPath, 'package.json')\n\n const pkgJsonResult = readPackageJsonSafe(pkgJsonPath)\n if (pkgJsonResult) {\n const pkg = pkgJsonResult.parsed as Record<string, any>\n\n // Entry points\n if (pkg.main)\n files.push(basename(pkg.main))\n if (pkg.module && pkg.module !== pkg.main)\n files.push(basename(pkg.module))\n\n // Type definitions (relative path preserved for LLM tool hints)\n const typesPath = pkg.types || pkg.typings\n if (typesPath && existsSync(join(pkgPath, typesPath)))\n files.push(typesPath)\n }\n\n // Check for common doc files (case-insensitive readme match)\n const entries = readdirSync(pkgPath).filter(f =>\n /^readme\\.md$/i.test(f) || /^changelog\\.md$/i.test(f),\n )\n files.push(...entries)\n\n return [...new Set(files)]\n}\n\n/**\n * Write LLM-generated section outputs to global cache for cross-project reuse\n *\n * Structure:\n * ~/.skilld/references/<pkg>@<version>/sections/_BEST_PRACTICES.md\n */\nexport function writeSections(name: string, version: string, sections: Array<{ file: string, content: string }>): void {\n const cacheDir = getCacheDir(name, version)\n const sectionsDir = join(cacheDir, 'sections')\n mkdirSync(sectionsDir, { recursive: true, mode: 0o700 })\n for (const { file, content } of sections) {\n writeFileSync(join(sectionsDir, file), content, { mode: 0o600 })\n }\n}\n\n/**\n * Read a cached section from the global references dir\n */\nexport function readCachedSection(name: string, version: string, file: string): string | null {\n const path = join(getCacheDir(name, version), 'sections', file)\n if (!existsSync(path))\n return null\n return readFileSync(path, 'utf-8')\n}\n\nexport function hasShippedDocs(name: string, cwd: string, version?: string): boolean {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return false\n\n const docsCandidates = ['docs', 'documentation', 'doc']\n for (const candidate of docsCandidates) {\n const docsPath = join(pkgPath, candidate)\n if (existsSync(docsPath))\n return true\n }\n return false\n}\n\n/**\n * List all cached packages\n */\nexport function listCached(): CachedPackage[] {\n if (!existsSync(REFERENCES_DIR))\n return []\n\n return readdirSync(REFERENCES_DIR)\n .filter(name => name.includes('@'))\n .map((dir) => {\n const atIdx = dir.lastIndexOf('@')\n return { name: dir.slice(0, atIdx), version: dir.slice(atIdx + 1), dir: join(REFERENCES_DIR, dir) }\n })\n}\n\n/**\n * Read cached docs for a package\n */\nexport function readCachedDocs(name: string, version: string): CachedDoc[] {\n const cacheDir = getCacheDir(name, version)\n if (!existsSync(cacheDir))\n return []\n\n const docs: CachedDoc[] = []\n\n function walk(dir: string, prefix = '') {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const entryPath = join(dir, entry.name)\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name\n\n if (entry.isDirectory()) {\n walk(entryPath, relativePath)\n }\n else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx')) {\n docs.push({\n path: relativePath,\n content: readFileSync(entryPath, 'utf-8'),\n })\n }\n }\n }\n\n walk(cacheDir)\n return docs\n}\n\n/**\n * Clear cache for a specific package\n */\nexport function clearCache(name: string, version: string): boolean {\n const cacheDir = getCacheDir(name, version)\n if (!existsSync(cacheDir))\n return false\n\n rmSync(cacheDir, { recursive: true })\n return true\n}\n\n/**\n * Clear all cache\n */\nexport function clearAllCache(): number {\n const packages = listCached()\n for (const pkg of packages) {\n clearCache(pkg.name, pkg.version)\n }\n // Also clear repo-level cache\n if (existsSync(REPOS_DIR))\n rmSync(REPOS_DIR, { recursive: true })\n return packages.length\n}\n\n/**\n * List files in .skilld directory (pkg + docs) as relative paths for prompt context\n * Returns paths like ./.skilld/pkg/README.md, ./.skilld/docs/api.md\n */\nexport function listReferenceFiles(skillDir: string, maxDepth = 3): string[] {\n const referencesDir = join(skillDir, '.skilld')\n if (!existsSync(referencesDir))\n return []\n\n const files: string[] = []\n\n function walk(dir: string, depth: number) {\n if (depth > maxDepth)\n return\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory() || entry.isSymbolicLink()) {\n try {\n const stat = statSync(full)\n if (stat.isDirectory()) {\n walk(full, depth + 1)\n continue\n }\n }\n catch { continue }\n }\n if (entry.name.endsWith('.md')) {\n files.push(full)\n }\n }\n }\n catch {\n // Broken symlink or permission error\n }\n }\n\n walk(referencesDir, 0)\n return files\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cache.mjs","names":[],"sources":["../../src/core/config.ts","../../src/cache/references.ts","../../src/cache/storage.ts","../../src/cache/reference-cache.ts"],"sourcesContent":["import type { OptimizeModel } from '../agent/index.ts'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { CACHE_DIR, CONFIG_PATH } from './paths.ts'\nimport { yamlEscape, yamlParseKV, yamlUnescape } from './yaml.ts'\n\nexport interface FeaturesConfig {\n search: boolean\n issues: boolean\n discussions: boolean\n releases: boolean\n}\n\nexport const defaultFeatures: FeaturesConfig = {\n search: true,\n issues: true,\n discussions: true,\n releases: true,\n}\n\n/**\n * Resolve the active feature set: defaults overlaid with user config, then\n * caller-supplied overrides. Single seam so feature gating doesn't drift.\n */\nexport function getActiveFeatures(overrides?: Partial<FeaturesConfig>): FeaturesConfig {\n const fromConfig = readConfig().features\n const merged: FeaturesConfig = { ...defaultFeatures, ...(fromConfig ?? {}) }\n return overrides ? { ...merged, ...overrides } : merged\n}\n\nexport interface SkilldConfig {\n model?: OptimizeModel\n agent?: string\n features?: FeaturesConfig\n projects?: string[]\n skipLlm?: boolean\n}\n\nlet configCache: SkilldConfig | undefined\n\nexport function hasConfig(): boolean {\n return existsSync(CONFIG_PATH)\n}\n\n/** Whether the first-run wizard has been completed (not just agent selection) */\nexport function hasCompletedWizard(): boolean {\n if (!existsSync(CONFIG_PATH))\n return false\n const config = readConfig()\n return config.features !== undefined || config.model !== undefined || config.skipLlm !== undefined\n}\n\nexport function readConfig(): SkilldConfig {\n if (configCache) {\n return {\n ...configCache,\n features: configCache.features ? { ...configCache.features } : undefined,\n projects: configCache.projects ? [...configCache.projects] : undefined,\n }\n }\n if (!existsSync(CONFIG_PATH))\n return {}\n\n const content = readFileSync(CONFIG_PATH, 'utf-8')\n const config: SkilldConfig = {}\n let inBlock: 'projects' | 'features' | null = null\n const projects: string[] = []\n const features: Partial<FeaturesConfig> = {}\n\n for (const line of content.split('\\n')) {\n if (line.startsWith('projects:')) {\n inBlock = 'projects'\n continue\n }\n if (line.startsWith('features:')) {\n inBlock = 'features'\n continue\n }\n if (inBlock === 'projects') {\n if (line.startsWith(' - ')) {\n projects.push(yamlUnescape(line.slice(4)))\n continue\n }\n inBlock = null\n }\n if (inBlock === 'features') {\n const m = line.match(/^ {2}(\\w+):\\s*(.+)/)\n if (m) {\n const key = m[1] as keyof FeaturesConfig\n if (key in defaultFeatures)\n features[key] = m[2] === 'true'\n continue\n }\n inBlock = null\n }\n const kv = yamlParseKV(line)\n if (!kv)\n continue\n const [key, value] = kv\n if (key === 'model' && value)\n config.model = value as OptimizeModel\n if (key === 'agent' && value)\n config.agent = value\n if (key === 'skipLlm')\n config.skipLlm = value === 'true'\n }\n\n if (projects.length > 0)\n config.projects = projects\n if (Object.keys(features).length > 0)\n config.features = { ...defaultFeatures, ...features }\n configCache = config\n return config\n}\n\nexport function writeConfig(config: SkilldConfig): void {\n mkdirSync(CACHE_DIR, { recursive: true, mode: 0o700 })\n\n let yaml = ''\n if (config.model)\n yaml += `model: ${config.model}\\n`\n if (config.agent)\n yaml += `agent: ${config.agent}\\n`\n if (config.skipLlm)\n yaml += `skipLlm: true\\n`\n if (config.features) {\n yaml += 'features:\\n'\n for (const [k, v] of Object.entries(config.features)) {\n yaml += ` ${k}: ${v}\\n`\n }\n }\n if (config.projects?.length) {\n yaml += 'projects:\\n'\n for (const p of config.projects) {\n yaml += ` - ${yamlEscape(p)}\\n`\n }\n }\n\n writeFileSync(CONFIG_PATH, yaml, { mode: 0o600 })\n configCache = undefined\n}\n\nexport function updateConfig(updates: Partial<SkilldConfig>): void {\n const config = readConfig()\n writeConfig({ ...config, ...updates })\n}\n\nexport function registerProject(projectPath: string): void {\n const config = readConfig()\n const projects = new Set(config.projects || [])\n projects.add(projectPath)\n writeConfig({ ...config, projects: [...projects] })\n}\n\nexport function unregisterProject(projectPath: string): void {\n const config = readConfig()\n const projects = (config.projects || []).filter(p => p !== projectPath)\n writeConfig({ ...config, projects })\n}\n\nexport function getRegisteredProjects(): string[] {\n return readConfig().projects || []\n}\n","/**\n * Higher-level reference-cache operations: composition over the cache\n * primitives in `src/cache/index.ts`.\n *\n * Owns:\n * - The on-disk shape of `~/.skilld/references/<pkg>@<version>/`\n * - `.skilld/` symlinks inside agent skill dirs (linkAllReferences)\n * - Loading cached docs back as a `ResolvedContent`-shaped result\n * - Force-clearing and ejecting (portable copy) caches\n *\n * Callers (sync, sync-parallel, sync-git, install, author) should use these\n * helpers instead of touching cache primitives directly.\n */\n\nimport type { FeaturesConfig } from '../core/config.ts'\nimport type { IndexDoc } from '../sources/content-resolver.ts'\nimport { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, realpathSync, rmSync } from 'node:fs'\nimport { dirname, join } from 'pathe'\nimport { defaultFeatures, readConfig } from '../core/config.ts'\nimport { skillInternalDir } from '../core/paths.ts'\nimport {\n clearCache,\n getCacheDir,\n getPackageDbPath,\n getRepoCacheDir,\n hasShippedDocs,\n linkCachedDir,\n linkPkg,\n linkPkgNamed,\n linkRepoCachedDir,\n readCachedDocs,\n} from './index.ts'\n\n/**\n * Resolve every symlink under `<skillDir>/.skilld/` to its real path, plus\n * the parent dirs CLI sandboxes need (e.g. Gemini). What an LLM CLI passes to\n * `--add-dir` to make references readable.\n */\nexport function getSkillReferenceDirs(skillDir: string): string[] {\n const refsDir = skillInternalDir(skillDir)\n if (!existsSync(refsDir))\n return []\n const resolved = readdirSync(refsDir)\n .map(entry => join(refsDir, entry))\n .filter(p => lstatSync(p).isSymbolicLink() && existsSync(p))\n .map(p => realpathSync(p))\n\n const parents = new Set<string>()\n for (const p of resolved) {\n const parent = dirname(p)\n if (!resolved.includes(parent))\n parents.add(parent)\n }\n\n return [...resolved, ...parents]\n}\n\n/**\n * Remove the transient `<skillDir>/.skilld/` symlink dir. Used after eject to\n * clean up references that have been copied as real files.\n */\nexport function clearSkillInternalDir(skillDir: string): void {\n const refsDir = skillInternalDir(skillDir)\n if (existsSync(refsDir))\n rmSync(refsDir, { recursive: true, force: true })\n}\n\n/** Classify a cached doc path into the right metadata type */\nexport function classifyCachedDoc(path: string): { type: string, number?: number } {\n const issueMatch = path.match(/^issues\\/issue-(\\d+)\\.md$/)\n if (issueMatch)\n return { type: 'issue', number: Number(issueMatch[1]) }\n const discussionMatch = path.match(/^discussions\\/discussion-(\\d+)\\.md$/)\n if (discussionMatch)\n return { type: 'discussion', number: Number(discussionMatch[1]) }\n if (path.startsWith('releases/'))\n return { type: 'release' }\n return { type: 'doc' }\n}\n\n/** Clear cache + db for --force flag */\nexport function forceClearCache(packageName: string, version: string, repoInfo?: { owner: string, repo: string }): void {\n clearCache(packageName, version)\n const forcedDbPath = getPackageDbPath(packageName, version)\n if (existsSync(forcedDbPath))\n rmSync(forcedDbPath, { recursive: true, force: true })\n // Also clear repo-level cache when force is used\n if (repoInfo) {\n const repoDir = getRepoCacheDir(repoInfo.owner, repoInfo.repo)\n if (existsSync(repoDir))\n rmSync(repoDir, { recursive: true, force: true })\n }\n}\n\n/** Link all reference symlinks (pkg, docs, issues, discussions, releases) */\nexport function linkAllReferences(skillDir: string, packageName: string, cwd: string, version: string, docsType: string, extraPackages?: Array<{ name: string, version?: string }>, features?: FeaturesConfig, repoInfo?: { owner: string, repo: string }): void {\n const f = features ?? readConfig().features ?? defaultFeatures\n try {\n linkPkg(skillDir, packageName, cwd, version)\n linkPkgNamed(skillDir, packageName, cwd, version)\n if (!hasShippedDocs(packageName, cwd, version) && docsType !== 'readme') {\n linkCachedDir(skillDir, packageName, version, 'docs')\n }\n // Issues/discussions/releases: use repo cache when available, else package cache\n if (f.issues) {\n if (repoInfo)\n linkRepoCachedDir(skillDir, repoInfo.owner, repoInfo.repo, 'issues')\n else\n linkCachedDir(skillDir, packageName, version, 'issues')\n }\n if (f.discussions) {\n if (repoInfo)\n linkRepoCachedDir(skillDir, repoInfo.owner, repoInfo.repo, 'discussions')\n else\n linkCachedDir(skillDir, packageName, version, 'discussions')\n }\n if (f.releases) {\n if (repoInfo)\n linkRepoCachedDir(skillDir, repoInfo.owner, repoInfo.repo, 'releases')\n else\n linkCachedDir(skillDir, packageName, version, 'releases')\n }\n linkCachedDir(skillDir, packageName, version, 'sections')\n // Create named symlinks for additional packages in multi-package skills\n if (extraPackages) {\n for (const pkg of extraPackages) {\n if (pkg.name !== packageName)\n linkPkgNamed(skillDir, pkg.name, cwd, pkg.version)\n }\n }\n }\n catch {\n // Symlink may fail on some systems\n }\n}\n\n/** Detect docs type from cached directory contents */\nexport function detectDocsType(packageName: string, version: string, repoUrl?: string, llmsUrl?: string): { docsType: 'docs' | 'llms.txt' | 'readme', docSource?: string } {\n const cacheDir = getCacheDir(packageName, version)\n if (existsSync(join(cacheDir, 'docs', 'index.md')) || existsSync(join(cacheDir, 'docs', 'guide'))) {\n return {\n docsType: 'docs',\n docSource: repoUrl ? `${repoUrl}/tree/v${version}/docs` : 'git',\n }\n }\n if (existsSync(join(cacheDir, 'llms.txt'))) {\n return {\n docsType: 'llms.txt',\n docSource: llmsUrl || 'llms.txt',\n }\n }\n if (existsSync(join(cacheDir, 'docs', 'README.md'))) {\n return { docsType: 'readme' }\n }\n return { docsType: 'readme' }\n}\n\n/** Eject (portable copy) of cached references into a skill dir */\nexport function ejectReferences(skillDir: string, packageName: string, cwd: string, version: string, docsType: string, features?: FeaturesConfig, repoInfo?: { owner: string, repo: string }): void {\n const f = features ?? readConfig().features ?? defaultFeatures\n const cacheDir = getCacheDir(packageName, version)\n const refsDir = join(skillDir, 'references')\n // Repo-level data source (falls back to package cache)\n const repoDir = repoInfo ? getRepoCacheDir(repoInfo.owner, repoInfo.repo) : cacheDir\n\n // Copy cached docs (skip pkg — eject is for portable sharing, pkg references node_modules)\n if (!hasShippedDocs(packageName, cwd, version) && docsType !== 'readme')\n copyCachedSubdir(cacheDir, refsDir, 'docs')\n\n if (f.issues)\n copyCachedSubdir(repoDir, refsDir, 'issues')\n if (f.discussions)\n copyCachedSubdir(repoDir, refsDir, 'discussions')\n if (f.releases)\n copyCachedSubdir(repoDir, refsDir, 'releases')\n}\n\n/** Recursively copy a cached subdirectory into the references dir */\nfunction copyCachedSubdir(cacheDir: string, refsDir: string, subdir: string): void {\n const srcDir = join(cacheDir, subdir)\n if (!existsSync(srcDir))\n return\n\n const destDir = join(refsDir, subdir)\n mkdirSync(destDir, { recursive: true })\n\n function walk(dir: string, rel: string) {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const srcPath = join(dir, entry.name)\n const destPath = join(destDir, rel ? `${rel}/${entry.name}` : entry.name)\n if (entry.isDirectory()) {\n mkdirSync(destPath, { recursive: true })\n walk(srcPath, rel ? `${rel}/${entry.name}` : entry.name)\n }\n else {\n copyFileSync(srcPath, destPath)\n }\n }\n }\n\n walk(srcDir, '')\n}\n\nexport interface CachedReferencesResult {\n /** Docs to feed the embedding index (empty if db already exists) */\n docsToIndex: IndexDoc[]\n /** Resolved doc-source label (URL or git path) */\n docSource: string\n /** Detected docs type from cache layout */\n docsType: 'docs' | 'llms.txt' | 'readme'\n /** _INDEX.md to write if missing (backfill for older caches) */\n backfillIndex?: { path: string, content: string }\n}\n\nexport interface LoadCachedReferencesOptions {\n packageName: string\n version: string\n repoUrl?: string\n llmsUrl?: string\n readmeUrl?: string\n onProgress: (message: string) => void\n /** Caller supplies index generator to avoid the cache module pulling sources */\n generateDocsIndex: (docs: Array<{ path: string, content: string }>) => string | null\n}\n\n/**\n * Load cached references for a package and produce the index/backfill data\n * needed to continue the sync pipeline without re-fetching.\n */\nexport function loadCachedReferences(opts: LoadCachedReferencesOptions): CachedReferencesResult {\n const { packageName, version, repoUrl, llmsUrl, readmeUrl, onProgress, generateDocsIndex } = opts\n onProgress('Loading cached docs')\n const detected = detectDocsType(packageName, version, repoUrl, llmsUrl)\n const docsType = detected.docsType\n const docSource = detected.docSource ?? readmeUrl ?? 'readme'\n const docsToIndex: IndexDoc[] = []\n\n // Load cached docs for indexing if db doesn't exist yet\n const dbPath = getPackageDbPath(packageName, version)\n if (!existsSync(dbPath)) {\n onProgress('Reading cached docs for indexing')\n const cached = readCachedDocs(packageName, version)\n for (const doc of cached) {\n docsToIndex.push({\n id: doc.path,\n content: doc.content,\n metadata: { package: packageName, source: doc.path, ...classifyCachedDoc(doc.path) },\n })\n }\n }\n\n // Backfill docs index for caches created before this feature\n let backfillIndex: { path: string, content: string } | undefined\n if (docsType !== 'readme' && !existsSync(join(getCacheDir(packageName, version), 'docs', '_INDEX.md'))) {\n onProgress('Generating docs index')\n const cached = readCachedDocs(packageName, version)\n const docFiles = cached.filter(d => d.path.startsWith('docs/') && d.path.endsWith('.md'))\n if (docFiles.length > 1) {\n const docsIndex = generateDocsIndex(cached)\n if (docsIndex)\n backfillIndex = { path: 'docs/_INDEX.md', content: docsIndex }\n }\n }\n\n return { docsToIndex, docSource, docsType, backfillIndex }\n}\n","/**\n * Cache storage operations\n */\n\nimport type { CachedDoc, CachedPackage } from './types.ts'\nimport { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { basename, join, resolve } from 'pathe'\nimport { readPackageJsonSafe } from '../core/package-json.ts'\nimport { getRepoCacheDir, REFERENCES_DIR, REPOS_DIR, skillInternalDir } from '../core/paths.ts'\nimport { resolvePkgDir } from '../core/prepare.ts'\nimport { sanitizeMarkdown } from '../core/sanitize.ts'\nimport { getCacheDir } from './version.ts'\n\n/** Safely create a symlink, validating target is under REFERENCES_DIR or REPOS_DIR */\nfunction safeSymlink(target: string, linkPath: string): void {\n const resolved = resolve(target)\n if (!resolved.startsWith(REFERENCES_DIR) && !resolved.startsWith(REPOS_DIR))\n throw new Error(`Symlink target outside allowed dirs: ${resolved}`)\n // Remove pre-existing symlink (check with lstat to detect symlinks)\n try {\n const stat = lstatSync(linkPath)\n if (stat.isSymbolicLink() || stat.isFile())\n unlinkSync(linkPath)\n }\n catch {}\n symlinkSync(target, linkPath, 'junction')\n}\n\n/**\n * Check if package is cached at given version\n * @internal\n */\nexport function isCached(name: string, version: string): boolean {\n return existsSync(getCacheDir(name, version))\n}\n\n/** Check if cache only has docs/README.md (pkg/ already has this) */\nexport function isReadmeOnlyCache(cacheDir: string): boolean {\n const docsDir = join(cacheDir, 'docs')\n if (!existsSync(docsDir))\n return false\n const files = readdirSync(docsDir)\n return files.length === 1 && files[0] === 'README.md'\n}\n\nexport function inferDocsTypeFromCache(cacheDir: string, source?: string): 'llms.txt' | 'readme' | 'docs' {\n if (source?.includes('llms.txt') || existsSync(join(cacheDir, 'docs', 'llms.txt')))\n return 'llms.txt'\n return isReadmeOnlyCache(cacheDir) ? 'readme' : 'docs'\n}\n\n/**\n * Ensure cache directories exist\n */\nexport function ensureCacheDir(): void {\n mkdirSync(REFERENCES_DIR, { recursive: true, mode: 0o700 })\n mkdirSync(REPOS_DIR, { recursive: true, mode: 0o700 })\n}\n\n/**\n * Write docs to cache\n * @internal\n */\nexport function writeToCache(\n name: string,\n version: string,\n docs: CachedDoc[],\n): string {\n const cacheDir = getCacheDir(name, version)\n mkdirSync(cacheDir, { recursive: true, mode: 0o700 })\n\n for (const doc of docs) {\n const filePath = join(cacheDir, doc.path)\n mkdirSync(join(filePath, '..'), { recursive: true, mode: 0o700 })\n writeFileSync(filePath, sanitizeMarkdown(doc.content), { mode: 0o600 })\n }\n\n return cacheDir\n}\n\n/**\n * Write docs to repo-level cache (~/.skilld/repos/<owner>/<repo>/)\n */\nexport function writeToRepoCache(\n owner: string,\n repo: string,\n docs: CachedDoc[],\n): string {\n const repoDir = getRepoCacheDir(owner, repo)\n mkdirSync(repoDir, { recursive: true, mode: 0o700 })\n\n for (const doc of docs) {\n const filePath = join(repoDir, doc.path)\n mkdirSync(join(filePath, '..'), { recursive: true, mode: 0o700 })\n writeFileSync(filePath, sanitizeMarkdown(doc.content), { mode: 0o600 })\n }\n\n return repoDir\n}\n\n/**\n * Create symlink from .skilld dir to a repo-level cached subdirectory.\n * .claude/skills/<skill>/.skilld/<subdir> -> ~/.skilld/repos/<owner>/<repo>/<subdir>\n */\nexport function linkRepoCachedDir(skillDir: string, owner: string, repo: string, subdir: string): void {\n const repoDir = getRepoCacheDir(owner, repo)\n const referencesDir = skillInternalDir(skillDir)\n const linkPath = join(referencesDir, subdir)\n const cachedPath = join(repoDir, subdir)\n\n mkdirSync(referencesDir, { recursive: true })\n\n if (existsSync(cachedPath)) {\n safeSymlink(cachedPath, linkPath)\n }\n}\n\n/**\n * Create symlink from .skilld dir to a cached subdirectory.\n * Unified handler for docs, issues, discussions, sections, releases.\n *\n * Structure:\n * .claude/skills/<skill>/.skilld/<subdir> -> ~/.skilld/references/<pkg>@<version>/<subdir>\n *\n * The .skilld/ dirs are gitignored. After clone, `skilld install` recreates from lockfile.\n */\nexport function linkCachedDir(skillDir: string, name: string, version: string, subdir: string): void {\n const cacheDir = getCacheDir(name, version)\n const referencesDir = skillInternalDir(skillDir)\n const linkPath = join(referencesDir, subdir)\n const cachedPath = join(cacheDir, subdir)\n\n mkdirSync(referencesDir, { recursive: true })\n\n if (existsSync(cachedPath)) {\n safeSymlink(cachedPath, linkPath)\n }\n}\n\n/**\n * Resolve the package directory: node_modules first, then cached dist fallback.\n * Returns the path if found, null otherwise.\n */\nexport { resolvePkgDir } from '../core/prepare.ts'\nexport { getShippedSkills, linkShippedSkill } from '../core/prepare.ts'\nexport type { ShippedSkill } from '../core/prepare.ts'\n\n/**\n * Create symlink from .skilld dir to package directory\n *\n * Structure:\n * .claude/skills/<skill>/.skilld/pkg -> node_modules/<pkg> OR ~/.skilld/references/<pkg>@<version>/pkg\n *\n * This gives access to package.json, README.md, dist/, and any shipped docs/\n */\nexport function linkPkg(skillDir: string, name: string, cwd: string, version?: string): void {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return\n\n const referencesDir = skillInternalDir(skillDir)\n mkdirSync(referencesDir, { recursive: true })\n\n const pkgLinkPath = join(referencesDir, 'pkg')\n try {\n lstatSync(pkgLinkPath)\n unlinkSync(pkgLinkPath)\n }\n catch {}\n symlinkSync(pkgPath, pkgLinkPath, 'junction')\n}\n\n/**\n * Create named symlink from .skilld dir to package directory.\n * Short name = last segment of package name (e.g., @vue/reactivity → pkg-reactivity)\n *\n * Structure:\n * .claude/skills/<skill>/.skilld/pkg-<short> -> node_modules/<pkg>\n */\nexport function linkPkgNamed(skillDir: string, name: string, cwd: string, version?: string): void {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return\n\n const shortName = name.split('/').pop()!.toLowerCase()\n const referencesDir = skillInternalDir(skillDir)\n mkdirSync(referencesDir, { recursive: true })\n\n const linkPath = join(referencesDir, `pkg-${shortName}`)\n try {\n lstatSync(linkPath)\n unlinkSync(linkPath)\n }\n catch {}\n symlinkSync(pkgPath, linkPath, 'junction')\n}\n\n/**\n * Get key files from a package directory for display\n * Returns entry points + docs files\n */\nexport function getPkgKeyFiles(name: string, cwd: string, version?: string): string[] {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return []\n\n const files: string[] = []\n const pkgJsonPath = join(pkgPath, 'package.json')\n\n const pkgJsonResult = readPackageJsonSafe(pkgJsonPath)\n if (pkgJsonResult) {\n const pkg = pkgJsonResult.parsed as Record<string, any>\n\n // Entry points\n if (pkg.main)\n files.push(basename(pkg.main))\n if (pkg.module && pkg.module !== pkg.main)\n files.push(basename(pkg.module))\n\n // Type definitions (relative path preserved for LLM tool hints)\n const typesPath = pkg.types || pkg.typings\n if (typesPath && existsSync(join(pkgPath, typesPath)))\n files.push(typesPath)\n }\n\n // Check for common doc files (case-insensitive readme match)\n const entries = readdirSync(pkgPath).filter(f =>\n /^readme\\.md$/i.test(f) || /^changelog\\.md$/i.test(f),\n )\n files.push(...entries)\n\n return [...new Set(files)]\n}\n\n/**\n * Write LLM-generated section outputs to global cache for cross-project reuse\n *\n * Structure:\n * ~/.skilld/references/<pkg>@<version>/sections/_BEST_PRACTICES.md\n */\nexport function writeSections(name: string, version: string, sections: Array<{ file: string, content: string }>): void {\n const cacheDir = getCacheDir(name, version)\n const sectionsDir = join(cacheDir, 'sections')\n mkdirSync(sectionsDir, { recursive: true, mode: 0o700 })\n for (const { file, content } of sections) {\n writeFileSync(join(sectionsDir, file), content, { mode: 0o600 })\n }\n}\n\n/**\n * Read a cached section from the global references dir\n */\nexport function readCachedSection(name: string, version: string, file: string): string | null {\n const path = join(getCacheDir(name, version), 'sections', file)\n if (!existsSync(path))\n return null\n return readFileSync(path, 'utf-8')\n}\n\nexport function hasShippedDocs(name: string, cwd: string, version?: string): boolean {\n const pkgPath = resolvePkgDir(name, cwd, version)\n if (!pkgPath)\n return false\n\n const docsCandidates = ['docs', 'documentation', 'doc']\n for (const candidate of docsCandidates) {\n const docsPath = join(pkgPath, candidate)\n if (existsSync(docsPath))\n return true\n }\n return false\n}\n\n/**\n * List all cached packages\n */\nexport function listCached(): CachedPackage[] {\n if (!existsSync(REFERENCES_DIR))\n return []\n\n return readdirSync(REFERENCES_DIR)\n .filter(name => name.includes('@'))\n .map((dir) => {\n const atIdx = dir.lastIndexOf('@')\n return { name: dir.slice(0, atIdx), version: dir.slice(atIdx + 1), dir: join(REFERENCES_DIR, dir) }\n })\n}\n\n/**\n * Read cached docs for a package\n */\nexport function readCachedDocs(name: string, version: string): CachedDoc[] {\n const cacheDir = getCacheDir(name, version)\n if (!existsSync(cacheDir))\n return []\n\n const docs: CachedDoc[] = []\n\n function walk(dir: string, prefix = '') {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const entryPath = join(dir, entry.name)\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name\n\n if (entry.isDirectory()) {\n walk(entryPath, relativePath)\n }\n else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx')) {\n docs.push({\n path: relativePath,\n content: readFileSync(entryPath, 'utf-8'),\n })\n }\n }\n }\n\n walk(cacheDir)\n return docs\n}\n\n/**\n * Clear cache for a specific package\n */\nexport function clearCache(name: string, version: string): boolean {\n const cacheDir = getCacheDir(name, version)\n if (!existsSync(cacheDir))\n return false\n\n rmSync(cacheDir, { recursive: true })\n return true\n}\n\n/**\n * Clear all cache\n */\nexport function clearAllCache(): number {\n const packages = listCached()\n for (const pkg of packages) {\n clearCache(pkg.name, pkg.version)\n }\n // Also clear repo-level cache\n if (existsSync(REPOS_DIR))\n rmSync(REPOS_DIR, { recursive: true })\n return packages.length\n}\n\n/**\n * List files in .skilld directory (pkg + docs) as relative paths for prompt context\n * Returns paths like ./.skilld/pkg/README.md, ./.skilld/docs/api.md\n */\nexport function listReferenceFiles(skillDir: string, maxDepth = 3): string[] {\n const referencesDir = skillInternalDir(skillDir)\n if (!existsSync(referencesDir))\n return []\n\n const files: string[] = []\n\n function walk(dir: string, depth: number) {\n if (depth > maxDepth)\n return\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory() || entry.isSymbolicLink()) {\n try {\n const stat = statSync(full)\n if (stat.isDirectory()) {\n walk(full, depth + 1)\n continue\n }\n }\n catch { continue }\n }\n if (entry.name.endsWith('.md')) {\n files.push(full)\n }\n }\n }\n catch {\n // Broken symlink or permission error\n }\n }\n\n walk(referencesDir, 0)\n return files\n}\n","/**\n * Per-package reference cache facade. Closes over `(packageName, version)` so\n * call sites stop threading those tuples through chained primitives.\n */\n\nimport type { FeaturesConfig } from '../core/config.ts'\nimport type {\n CachedReferencesResult,\n LoadCachedReferencesOptions,\n} from './references.ts'\nimport type { CachedDoc } from './types.ts'\nimport {\n clearSkillInternalDir,\n detectDocsType,\n ejectReferences,\n forceClearCache,\n linkAllReferences,\n loadCachedReferences,\n} from './references.ts'\nimport {\n ensureCacheDir,\n getPkgKeyFiles,\n hasShippedDocs,\n isCached,\n linkPkgNamed,\n readCachedDocs,\n readCachedSection,\n resolvePkgDir,\n writeSections,\n writeToCache,\n} from './storage.ts'\nimport { getCacheDir, getVersionKey } from './version.ts'\n\nexport interface ReferenceCacheLinkOpts {\n extraPackages?: Array<{ name: string, version?: string }>\n features?: FeaturesConfig\n repoInfo?: { owner: string, repo: string }\n}\n\nexport interface ReferenceCacheEjectOpts {\n features?: FeaturesConfig\n repoInfo?: { owner: string, repo: string }\n}\n\nexport interface ReferenceCache {\n readonly packageName: string\n /** May be undefined when caller only knows the package name (e.g. merge against a lock without a recorded version). Cache-keyed methods/getters throw in that case; pkg/has/keyFiles fall back to node_modules. */\n readonly version: string | undefined\n /** Throws if accessed when version is undefined. */\n readonly versionKey: string\n /** Throws if accessed when version is undefined. */\n readonly dir: string\n ensure: () => void\n has: () => boolean\n write: (docs: CachedDoc[]) => void\n writeSections: (sections: Array<{ file: string, content: string }>) => void\n readSection: (file: string) => string | null\n readDocs: () => CachedDoc[]\n detectDocs: (\n repoUrl?: string,\n llmsUrl?: string,\n ) => { docsType: 'docs' | 'llms.txt' | 'readme', docSource?: string }\n load: (\n opts: Omit<LoadCachedReferencesOptions, 'packageName' | 'version'>,\n ) => CachedReferencesResult\n linkInto: (\n skillDir: string,\n cwd: string,\n docsType: string,\n opts?: ReferenceCacheLinkOpts,\n ) => void\n linkPkgNamed: (skillDir: string, cwd: string) => void\n eject: (\n skillDir: string,\n cwd: string,\n docsType: string,\n opts?: ReferenceCacheEjectOpts,\n ) => void\n clearForce: (repoInfo?: { owner: string, repo: string }) => void\n clearSkillInternal: (skillDir: string) => void\n pkgDir: (cwd: string) => string | null\n hasShipped: (cwd: string) => boolean\n keyFiles: (cwd: string) => string[]\n}\n\nexport function createReferenceCache(packageName: string, version?: string): ReferenceCache {\n const requireVersion = (op: string): string => {\n if (!version)\n throw new Error(`ReferenceCache.${op} requires a version (package: ${packageName})`)\n return version\n }\n return {\n packageName,\n version,\n get versionKey() { return getVersionKey(requireVersion('versionKey')) },\n get dir() { return getCacheDir(packageName, requireVersion('dir')) },\n ensure: () => ensureCacheDir(),\n has: () => !!version && isCached(packageName, version),\n write: docs => void writeToCache(packageName, requireVersion('write'), docs),\n writeSections: sections => writeSections(packageName, requireVersion('writeSections'), sections),\n readSection: file => readCachedSection(packageName, requireVersion('readSection'), file),\n readDocs: () => readCachedDocs(packageName, requireVersion('readDocs')),\n detectDocs: (repoUrl, llmsUrl) =>\n detectDocsType(packageName, requireVersion('detectDocs'), repoUrl, llmsUrl),\n load: opts =>\n loadCachedReferences({ ...opts, packageName, version: requireVersion('load') }),\n linkInto: (skillDir, cwd, docsType, opts) =>\n linkAllReferences(\n skillDir,\n packageName,\n cwd,\n requireVersion('linkInto'),\n docsType,\n opts?.extraPackages,\n opts?.features,\n opts?.repoInfo,\n ),\n linkPkgNamed: (skillDir, cwd) =>\n linkPkgNamed(skillDir, packageName, cwd, version),\n eject: (skillDir, cwd, docsType, opts) =>\n ejectReferences(\n skillDir,\n packageName,\n cwd,\n requireVersion('eject'),\n docsType,\n opts?.features,\n opts?.repoInfo,\n ),\n clearForce: repoInfo => forceClearCache(packageName, requireVersion('clearForce'), repoInfo),\n clearSkillInternal: skillDir => clearSkillInternalDir(skillDir),\n pkgDir: cwd => resolvePkgDir(packageName, cwd, version),\n hasShipped: cwd => hasShippedDocs(packageName, cwd, version),\n keyFiles: cwd => getPkgKeyFiles(packageName, cwd, version),\n }\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { a as REFERENCES_DIR, i as CACHE_DIR, o as REPOS_DIR } from "./version.mjs";
1
+ import { o as REFERENCES_DIR, s as REPOS_DIR, t as CACHE_DIR } from "./paths.mjs";
2
2
  import "./cache.mjs";
3
3
  import { n as clearEmbeddingCache } from "./embedding-cache2.mjs";
4
- import { join } from "pathe";
5
4
  import { existsSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
5
+ import { join } from "pathe";
6
6
  import * as p from "@clack/prompts";
7
7
  import { defineCommand } from "citty";
8
8
  const LLM_CACHE_DIR = join(CACHE_DIR, "llm-cache");
@@ -1,9 +1,9 @@
1
- import { o as getModelName } from "./agent.mjs";
1
+ import { L as updateConfig, P as readConfig } from "./cache.mjs";
2
2
  import { i as readPackageJsonSafe, n as editJsonProperty, r as patchPackageJson } from "./package-json.mjs";
3
3
  import { a as targets, i as getAgentVersion, n as detectProjectAgents, r as detectTargetAgent, t as detectInstalledAgents } from "./detect.mjs";
4
- import { a as readConfig, c as updateConfig } from "./config.mjs";
5
- import { join } from "pathe";
4
+ import { a as getModelName } from "./agent.mjs";
6
5
  import { readFileSync } from "node:fs";
6
+ import { join } from "pathe";
7
7
  import { parseTree } from "jsonc-parser";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import * as p from "@clack/prompts";
@@ -1,10 +1,13 @@
1
+ import "./paths.mjs";
2
+ import "./yaml.mjs";
3
+ import "./cache.mjs";
1
4
  import "./package-json.mjs";
2
5
  import "./sanitize.mjs";
3
- import "./yaml.mjs";
4
6
  import "./markdown.mjs";
5
- import "./shared.mjs";
6
- import "./skill.mjs";
7
- import "./config.mjs";
7
+ import "./sources.mjs";
8
+ import "./prompts.mjs";
8
9
  import "./lockfile.mjs";
10
+ import "./semver.mjs";
9
11
  import "./skills.mjs";
12
+ import "./monorepo.mjs";
10
13
  export {};
@@ -1,6 +1,6 @@
1
+ import { existsSync, readdirSync } from "node:fs";
1
2
  import { homedir } from "node:os";
2
3
  import { join } from "pathe";
3
- import { existsSync, readdirSync } from "node:fs";
4
4
  import { spawnSync } from "node:child_process";
5
5
  import { isWindows } from "std-env";
6
6
  const SPEC_FRONTMATTER = {
@@ -1,7 +1,7 @@
1
- import { i as CACHE_DIR } from "./version.mjs";
1
+ import { t as CACHE_DIR } from "./paths.mjs";
2
2
  import "./cache.mjs";
3
- import { join } from "pathe";
4
3
  import { rmSync } from "node:fs";
4
+ import { join } from "pathe";
5
5
  const EMBEDDINGS_DB_PATH = join(CACHE_DIR, "embeddings.db");
6
6
  let _db = null;
7
7
  async function openDb() {