skilld 1.7.4 → 2.0.0

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 (156) hide show
  1. package/dist/_chunks/add.mjs +66 -0
  2. package/dist/_chunks/add.mjs.map +1 -0
  3. package/dist/_chunks/agent-prompt.mjs +88 -0
  4. package/dist/_chunks/agent-prompt.mjs.map +1 -0
  5. package/dist/_chunks/agent.mjs +81 -57
  6. package/dist/_chunks/agent.mjs.map +1 -1
  7. package/dist/_chunks/args.mjs +42 -0
  8. package/dist/_chunks/args.mjs.map +1 -0
  9. package/dist/_chunks/assemble.mjs +10 -7
  10. package/dist/_chunks/assemble.mjs.map +1 -1
  11. package/dist/_chunks/author.mjs +33 -17
  12. package/dist/_chunks/author.mjs.map +1 -1
  13. package/dist/_chunks/cache.mjs +143 -183
  14. package/dist/_chunks/cache.mjs.map +1 -1
  15. package/dist/_chunks/cache2.mjs +7 -6
  16. package/dist/_chunks/cache2.mjs.map +1 -1
  17. package/dist/_chunks/client.mjs +117 -0
  18. package/dist/_chunks/client.mjs.map +1 -0
  19. package/dist/_chunks/core.mjs +5 -5
  20. package/dist/_chunks/detect.mjs +53 -43
  21. package/dist/_chunks/detect.mjs.map +1 -1
  22. package/dist/_chunks/eject.mjs +69 -0
  23. package/dist/_chunks/eject.mjs.map +1 -0
  24. package/dist/_chunks/embedding-cache2.mjs +1 -1
  25. package/dist/_chunks/env.mjs +19 -0
  26. package/dist/_chunks/env.mjs.map +1 -0
  27. package/dist/_chunks/install-many.mjs +376 -0
  28. package/dist/_chunks/install-many.mjs.map +1 -0
  29. package/dist/_chunks/install.mjs +81 -326
  30. package/dist/_chunks/install.mjs.map +1 -1
  31. package/dist/_chunks/intro.mjs +63 -0
  32. package/dist/_chunks/intro.mjs.map +1 -0
  33. package/dist/_chunks/list.mjs +2 -2
  34. package/dist/_chunks/list.mjs.map +1 -1
  35. package/dist/_chunks/lockfile.mjs +3 -2
  36. package/dist/_chunks/lockfile.mjs.map +1 -1
  37. package/dist/_chunks/login.mjs +233 -0
  38. package/dist/_chunks/login.mjs.map +1 -0
  39. package/dist/_chunks/logout.mjs +27 -0
  40. package/dist/_chunks/logout.mjs.map +1 -0
  41. package/dist/_chunks/map.mjs +11 -0
  42. package/dist/_chunks/map.mjs.map +1 -0
  43. package/dist/_chunks/markdown.mjs +79 -54
  44. package/dist/_chunks/markdown.mjs.map +1 -1
  45. package/dist/_chunks/menu.mjs +33 -0
  46. package/dist/_chunks/menu.mjs.map +1 -0
  47. package/dist/_chunks/model-picker.mjs +61 -0
  48. package/dist/_chunks/model-picker.mjs.map +1 -0
  49. package/dist/_chunks/monorepo.mjs +4 -2
  50. package/dist/_chunks/monorepo.mjs.map +1 -1
  51. package/dist/_chunks/package-json.mjs.map +1 -1
  52. package/dist/_chunks/paths.mjs +3 -5
  53. package/dist/_chunks/paths.mjs.map +1 -1
  54. package/dist/_chunks/{sync-pipeline.mjs → pipeline.mjs} +346 -313
  55. package/dist/_chunks/pipeline.mjs.map +1 -0
  56. package/dist/_chunks/pool2.mjs +1 -1
  57. package/dist/_chunks/portable.mjs +151 -0
  58. package/dist/_chunks/portable.mjs.map +1 -0
  59. package/dist/_chunks/prepare-hook.mjs +2 -0
  60. package/dist/_chunks/prepare-hook2.mjs +61 -0
  61. package/dist/_chunks/prepare-hook2.mjs.map +1 -0
  62. package/dist/_chunks/prepare.mjs +47 -3
  63. package/dist/_chunks/prepare.mjs.map +1 -1
  64. package/dist/_chunks/prepare2.mjs +7 -6
  65. package/dist/_chunks/prepare2.mjs.map +1 -1
  66. package/dist/_chunks/prompts.mjs +484 -74
  67. package/dist/_chunks/prompts.mjs.map +1 -1
  68. package/dist/_chunks/pull.mjs +219 -0
  69. package/dist/_chunks/pull.mjs.map +1 -0
  70. package/dist/_chunks/regex.mjs +19 -0
  71. package/dist/_chunks/regex.mjs.map +1 -0
  72. package/dist/_chunks/retriv.mjs +2 -171
  73. package/dist/_chunks/retriv2.mjs +159 -0
  74. package/dist/_chunks/retriv2.mjs.map +1 -0
  75. package/dist/_chunks/sanitize.mjs +12 -9
  76. package/dist/_chunks/sanitize.mjs.map +1 -1
  77. package/dist/_chunks/search-helpers.mjs +8 -6
  78. package/dist/_chunks/search-helpers.mjs.map +1 -1
  79. package/dist/_chunks/search-interactive.mjs +23 -20
  80. package/dist/_chunks/search-interactive.mjs.map +1 -1
  81. package/dist/_chunks/search.mjs +3 -3
  82. package/dist/_chunks/search.mjs.map +1 -1
  83. package/dist/_chunks/semver.mjs +2755 -1
  84. package/dist/_chunks/semver.mjs.map +1 -1
  85. package/dist/_chunks/skill-installer2.mjs +10 -11
  86. package/dist/_chunks/skill-installer2.mjs.map +1 -1
  87. package/dist/_chunks/skills.mjs +6 -7
  88. package/dist/_chunks/skills.mjs.map +1 -1
  89. package/dist/_chunks/store.mjs +107 -0
  90. package/dist/_chunks/store.mjs.map +1 -0
  91. package/dist/_chunks/sync.mjs +411 -910
  92. package/dist/_chunks/sync.mjs.map +1 -1
  93. package/dist/_chunks/sync2.mjs +2 -5
  94. package/dist/_chunks/telemetry.mjs +26 -0
  95. package/dist/_chunks/telemetry.mjs.map +1 -0
  96. package/dist/_chunks/uninstall.mjs +12 -9
  97. package/dist/_chunks/uninstall.mjs.map +1 -1
  98. package/dist/_chunks/update.mjs +171 -0
  99. package/dist/_chunks/update.mjs.map +1 -0
  100. package/dist/_chunks/upload.mjs +3 -3
  101. package/dist/_chunks/validate.mjs +1 -1
  102. package/dist/_chunks/version.mjs +16 -17
  103. package/dist/_chunks/version.mjs.map +1 -1
  104. package/dist/_chunks/whoami.mjs +21 -0
  105. package/dist/_chunks/whoami.mjs.map +1 -0
  106. package/dist/_chunks/wizard.mjs +2 -190
  107. package/dist/_chunks/wizard2.mjs +200 -0
  108. package/dist/_chunks/wizard2.mjs.map +1 -0
  109. package/dist/cli.mjs +72 -53
  110. package/dist/cli.mjs.map +1 -1
  111. package/dist/prepare.mjs +4 -3
  112. package/dist/prepare.mjs.map +1 -1
  113. package/dist/retriv/worker.d.mts +5 -1
  114. package/dist/retriv/worker.d.mts.map +1 -1
  115. package/dist/retriv/worker.mjs +1 -1
  116. package/package.json +19 -28
  117. package/dist/_chunks/author-group.mjs +0 -17
  118. package/dist/_chunks/author-group.mjs.map +0 -1
  119. package/dist/_chunks/cli-helpers.mjs +0 -335
  120. package/dist/_chunks/cli-helpers.mjs.map +0 -1
  121. package/dist/_chunks/cli-helpers2.mjs +0 -2
  122. package/dist/_chunks/index.d.mts +0 -344
  123. package/dist/_chunks/index.d.mts.map +0 -1
  124. package/dist/_chunks/index2.d.mts +0 -279
  125. package/dist/_chunks/index2.d.mts.map +0 -1
  126. package/dist/_chunks/index3.d.mts +0 -44
  127. package/dist/_chunks/index3.d.mts.map +0 -1
  128. package/dist/_chunks/index4.d.mts +0 -553
  129. package/dist/_chunks/index4.d.mts.map +0 -1
  130. package/dist/_chunks/package-registry.mjs +0 -465
  131. package/dist/_chunks/package-registry.mjs.map +0 -1
  132. package/dist/_chunks/retriv.mjs.map +0 -1
  133. package/dist/_chunks/setup.mjs +0 -17
  134. package/dist/_chunks/setup.mjs.map +0 -1
  135. package/dist/_chunks/sources.mjs +0 -2654
  136. package/dist/_chunks/sources.mjs.map +0 -1
  137. package/dist/_chunks/sync-pipeline.mjs.map +0 -1
  138. package/dist/_chunks/sync-registry.mjs +0 -65
  139. package/dist/_chunks/sync-registry.mjs.map +0 -1
  140. package/dist/_chunks/types.d.mts +0 -76
  141. package/dist/_chunks/types.d.mts.map +0 -1
  142. package/dist/_chunks/types2.d.mts +0 -88
  143. package/dist/_chunks/types2.d.mts.map +0 -1
  144. package/dist/_chunks/wizard.mjs.map +0 -1
  145. package/dist/agent/index.d.mts +0 -2
  146. package/dist/agent/index.mjs +0 -4
  147. package/dist/cache/index.d.mts +0 -2
  148. package/dist/cache/index.mjs +0 -5
  149. package/dist/index.d.mts +0 -6
  150. package/dist/index.mjs +0 -6
  151. package/dist/retriv/index.d.mts +0 -3
  152. package/dist/retriv/index.mjs +0 -2
  153. package/dist/sources/index.d.mts +0 -3
  154. package/dist/sources/index.mjs +0 -3
  155. package/dist/types.d.mts +0 -4
  156. package/dist/types.mjs +0 -1
@@ -1,24 +1,24 @@
1
- import { d as getSharedSkillsDir, l as getPackageDbPath, p as skillInternalDir } from "./paths.mjs";
2
- import { P as readConfig, a as getPkgKeyFiles, h as listReferenceFiles, i as ensureCacheDir, k as defaultFeatures, o as hasShippedDocs, s as inferDocsTypeFromCache, t as createReferenceCache, x as classifyCachedDoc } from "./cache.mjs";
3
- import { i as readPackageJsonSafe } from "./package-json.mjs";
4
- import { t as getCacheDir } from "./version.mjs";
5
- import { n as linkShippedSkill, r as resolvePkgDir, t as getShippedSkills } from "./prepare.mjs";
6
- import { n as sanitizeMarkdown } from "./sanitize.mjs";
7
- import { r as createIndex, t as SearchDepsUnavailableError } from "./retriv.mjs";
8
- import { C as resolveEntryFiles, F as downloadLlmsDocs, J as isShallowGitDocs, K as fetchGitDocs, L as fetchLlmsTxt, N as fetchReadmeContent, a as toStoragePackageName, at as fetchGitHubRaw, b as fetchGitSkills, g as resolvePackageDocs, q as filterFrameworkDocs, ut as parseGitHubUrl, z as normalizeLlmsLinks } from "./sources.mjs";
9
1
  import { a as targets } from "./detect.mjs";
10
- import { i as getModelLabel, o as createToolProgress, t as optimizeDocs } from "./agent.mjs";
11
- import { _ as timedSpinner, n as writeGeneratedSkillMd, o as linkSkillToAgents, r as writeSkillMd } from "./prompts.mjs";
12
- import { _ as promptForAgent, b as resolveAgent, x as sharedArgs } from "./cli-helpers.mjs";
2
+ import { i as getModelLabel } from "./agent.mjs";
3
+ import { h as timedSpinner, i as linkSkillToAgents, n as writeSkillMd } from "./prompts.mjs";
4
+ import { f as getSharedSkillsDir, m as skillInternalDir } from "./paths.mjs";
5
+ import { n as sanitizeMarkdown } from "./sanitize.mjs";
6
+ import { a as resolvePkgDir, i as linkShippedSkill, n as getShippedSkills, s as getCacheDir } from "./prepare.mjs";
7
+ import { i as readPackageJsonSafe } from "./package-json.mjs";
8
+ import { d as readConfig, o as defaultFeatures, r as ensureCacheDir, t as createReferenceCache } from "./cache.mjs";
9
+ import { n as promptForAgent, r as resolveAgent } from "./agent-prompt.mjs";
10
+ import { t as sharedArgs } from "./args.mjs";
11
+ import { _ as fetchGitSkills, a as resolvePackageDocs, l as toStoragePackageName } from "./semver.mjs";
13
12
  import { a as parsePackageNames, c as readLock, d as writeLock, i as mergeLocks, o as parsePackages, u as syncLockfilesToDirs } from "./lockfile.mjs";
14
- import { h as writePromptFiles, l as selectLlmConfig, o as indexResources } from "./sync-pipeline.mjs";
13
+ import { a as prepareSkillReferences, c as selectLlmConfig, f as writeBaseSkill, p as writePromptFiles, r as fetchAndCacheResources, t as buildSkillContext, u as enhanceSkillWithLLM } from "./pipeline.mjs";
15
14
  import { n as shutdownWorker } from "./pool2.mjs";
16
- import "./sync.mjs";
17
15
  import { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
18
- import { homedir } from "node:os";
19
- import { dirname, join } from "pathe";
16
+ import { styleText } from "node:util";
20
17
  import * as p from "@clack/prompts";
21
18
  import { defineCommand } from "citty";
19
+ import { dirname, join } from "pathe";
20
+ import { homedir } from "node:os";
21
+ const STATIC_REGEX_1 = /ungh:\/\/([^/]+)\/(.+)/;
22
22
  async function installCommand(opts) {
23
23
  const cwd = process.cwd();
24
24
  const agent = targets[opts.agent];
@@ -57,11 +57,11 @@ async function installCommand(opts) {
57
57
  }
58
58
  p.log.info(`Restoring ${toRestore.length} references`);
59
59
  ensureCacheDir();
60
- const allSkillNames = skills.map(([, info]) => info.packageName || "").filter(Boolean);
61
60
  const regenerated = [];
62
61
  for (const { name, info } of toRestore) {
63
62
  const version = info.version;
64
- const pkgName = toStoragePackageName(info.packageName || unsanitizeName(name, info.source));
63
+ const identityName = info.packageName || unsanitizeName(name, info.source);
64
+ const pkgName = toStoragePackageName(identityName);
65
65
  if (info.source === "shipped") {
66
66
  const match = getShippedSkills(pkgName, cwd, version).find((s) => s.skillName === name);
67
67
  if (match) {
@@ -97,237 +97,73 @@ async function installCommand(opts) {
97
97
  const skillDir = join(skillsDir, name);
98
98
  const cache = createReferenceCache(pkgName, version);
99
99
  const spin = timedSpinner();
100
- if (cache.has()) {
101
- spin.start(`Linking ${name}`);
102
- mkdirSync(skillDir, { recursive: true });
103
- const repoGh = info.repo ? parseGitHubUrl(`https://github.com/${info.repo}`) : null;
104
- const docsType = inferDocsTypeFromCache(cache.dir, info.source);
105
- cache.linkInto(skillDir, cwd, docsType, {
106
- extraPackages: parsePackages(info.packages),
107
- features,
108
- repoInfo: repoGh ? {
109
- owner: repoGh.owner,
110
- repo: repoGh.repo
111
- } : void 0
112
- });
113
- if (features.search && !existsSync(getPackageDbPath(pkgName, version))) {
114
- spin.message(`Indexing ${name}`);
115
- await indexResources({
116
- packageName: pkgName,
117
- version,
118
- cwd,
119
- docsToIndex: cache.readDocs().map((d) => ({
120
- id: d.path,
121
- content: d.content,
122
- metadata: {
123
- package: pkgName,
124
- source: d.path,
125
- type: classifyCachedDoc(d.path).type
126
- }
127
- })),
128
- features,
129
- onProgress: (msg) => spin.message(msg)
130
- });
131
- }
132
- if (!copyFromExistingAgent(skillDir, name, allSkillsDirs)) {
133
- if (regenerateBaseSkillMd(skillDir, pkgName, version, cwd, allSkillNames, info.source, info.packages)) regenerated.push({
134
- name,
135
- pkgName,
136
- version,
137
- skillDir,
138
- packages: info.packages
139
- });
140
- }
141
- spin.stop(`Linked ${name}`);
142
- continue;
143
- }
144
- spin.start(`Downloading ${name}@${version}`);
145
- const resolved = await resolvePackageDocs(pkgName, { version });
100
+ const wasCacheHit = cache.has();
101
+ spin.start(wasCacheHit ? `Linking ${name}` : `Downloading ${name}@${version}`);
102
+ mkdirSync(skillDir, { recursive: true });
103
+ const resolved = wasCacheHit ? synthesizeResolved(identityName, version, info, cwd) : await resolvePackageDocs(pkgName, { version });
146
104
  if (!resolved) {
147
105
  spin.stop(`Could not resolve: ${name}`);
148
106
  continue;
149
107
  }
150
- const cachedDocs = [];
151
- const docsToIndex = [];
152
- const isFrameworkDoc = (path) => filterFrameworkDocs([path], pkgName).length > 0;
153
- if (resolved.gitDocsUrl && resolved.repoUrl) {
154
- const gh = parseGitHubUrl(resolved.repoUrl);
155
- if (gh) {
156
- const gitDocs = await fetchGitDocs(gh.owner, gh.repo, version, pkgName);
157
- if (gitDocs?.files.length) {
158
- const BATCH_SIZE = 20;
159
- for (let i = 0; i < gitDocs.files.length; i += BATCH_SIZE) {
160
- const batch = gitDocs.files.slice(i, i + BATCH_SIZE);
161
- const results = await Promise.all(batch.map(async (file) => {
162
- const content = await fetchGitHubRaw(`${gitDocs.baseUrl}/${file}`);
163
- if (!content) return null;
164
- return {
165
- file,
166
- content
167
- };
168
- }));
169
- for (const r of results) if (r) {
170
- const stripped = gitDocs.docsPrefix ? r.file.replace(gitDocs.docsPrefix, "") : r.file;
171
- const cachePath = stripped.startsWith("docs/") ? stripped : `docs/${stripped}`;
172
- cachedDocs.push({
173
- path: cachePath,
174
- content: r.content
175
- });
176
- docsToIndex.push({
177
- id: cachePath,
178
- content: r.content,
179
- metadata: {
180
- package: pkgName,
181
- source: cachePath,
182
- type: "doc"
183
- }
184
- });
185
- }
186
- }
187
- if (isShallowGitDocs(cachedDocs.length) && resolved.llmsUrl) {
188
- cachedDocs.length = 0;
189
- docsToIndex.length = 0;
190
- } else if (cachedDocs.length > 0 && resolved.llmsUrl) {
191
- const llmsContent = await fetchLlmsTxt(resolved.llmsUrl);
192
- if (llmsContent) {
193
- const baseUrl = resolved.docsUrl || new URL(resolved.llmsUrl).origin;
194
- cachedDocs.push({
195
- path: "llms.txt",
196
- content: normalizeLlmsLinks(llmsContent.raw)
197
- });
198
- if (llmsContent.links.length > 0) {
199
- const docs = await downloadLlmsDocs(llmsContent, baseUrl);
200
- for (const doc of docs) {
201
- if (!isFrameworkDoc(doc.url)) continue;
202
- const localPath = doc.url.startsWith("/") ? doc.url.slice(1) : doc.url;
203
- cachedDocs.push({
204
- path: join("llms-docs", ...localPath.split("/")),
205
- content: doc.content
206
- });
207
- }
208
- }
209
- }
210
- }
211
- }
212
- }
213
- }
214
- if (resolved.llmsUrl && cachedDocs.length === 0) {
215
- const llmsContent = await fetchLlmsTxt(resolved.llmsUrl);
216
- if (llmsContent) {
217
- cachedDocs.push({
218
- path: "llms.txt",
219
- content: normalizeLlmsLinks(llmsContent.raw)
220
- });
221
- if (llmsContent.links.length > 0) {
222
- const docs = await downloadLlmsDocs(llmsContent, resolved.docsUrl || new URL(resolved.llmsUrl).origin);
223
- for (const doc of docs) {
224
- if (!isFrameworkDoc(doc.url)) continue;
225
- const cachePath = join("docs", ...(doc.url.startsWith("/") ? doc.url.slice(1) : doc.url).split("/"));
226
- cachedDocs.push({
227
- path: cachePath,
228
- content: doc.content
229
- });
230
- docsToIndex.push({
231
- id: doc.url,
232
- content: doc.content,
233
- metadata: {
234
- package: pkgName,
235
- source: cachePath,
236
- type: "doc"
237
- }
238
- });
239
- }
240
- }
241
- }
242
- }
243
- if (resolved.readmeUrl && cachedDocs.length === 0) {
244
- const content = await fetchReadmeContent(resolved.readmeUrl);
245
- if (content) {
246
- cachedDocs.push({
247
- path: "docs/README.md",
248
- content
249
- });
250
- docsToIndex.push({
251
- id: "README.md",
252
- content,
253
- metadata: {
254
- package: pkgName,
255
- source: "docs/README.md",
256
- type: "doc"
257
- }
258
- });
259
- }
108
+ const resources = await fetchAndCacheResources({
109
+ packageName: pkgName,
110
+ resolved,
111
+ version,
112
+ useCache: wasCacheHit,
113
+ features,
114
+ onProgress: (msg) => spin.message(msg)
115
+ });
116
+ for (const w of resources.warnings) p.log.warn(`${name}: ${w}`);
117
+ if (!cache.has()) {
118
+ spin.stop(`No docs found for ${name}`);
119
+ continue;
260
120
  }
261
- if (cachedDocs.length > 0) {
262
- cache.write(cachedDocs);
263
- const repoGh = info.repo ? parseGitHubUrl(`https://github.com/${info.repo}`) : null;
264
- const docsType = inferDocsTypeFromCache(cache.dir, info.source);
265
- cache.linkInto(skillDir, cwd, docsType, {
266
- extraPackages: parsePackages(info.packages),
121
+ const ctx = buildSkillContext({
122
+ packageName: identityName,
123
+ cachePackageName: pkgName,
124
+ version,
125
+ skillDir,
126
+ skillDirName: name,
127
+ resources,
128
+ prepared: await prepareSkillReferences({
129
+ packageName: pkgName,
130
+ version,
131
+ cwd,
132
+ skillDir,
133
+ resources,
267
134
  features,
268
- repoInfo: repoGh ? {
269
- owner: repoGh.owner,
270
- repo: repoGh.repo
271
- } : void 0
272
- });
273
- if (features.search) try {
274
- if (docsToIndex.length > 0) await createIndex(docsToIndex, { dbPath: getPackageDbPath(pkgName, version) });
275
- const pkgDir = resolvePkgDir(pkgName, cwd, version);
276
- const entryFiles = pkgDir ? await resolveEntryFiles(pkgDir) : [];
277
- if (entryFiles.length > 0) await createIndex(entryFiles.map((e) => ({
278
- id: e.path,
279
- content: e.content,
280
- metadata: {
281
- package: pkgName,
282
- source: `pkg/${e.path}`,
283
- type: e.type
284
- }
285
- })), { dbPath: getPackageDbPath(pkgName, version) });
286
- } catch (err) {
287
- if (!(err instanceof SearchDepsUnavailableError)) throw err;
288
- }
289
- if (!copyFromExistingAgent(skillDir, name, allSkillsDirs)) {
290
- if (regenerateBaseSkillMd(skillDir, pkgName, version, cwd, allSkillNames, info.source, info.packages)) regenerated.push({
135
+ baseDir: skillsDir,
136
+ extraPackages: parsePackages(info.packages),
137
+ onIndexProgress: (msg) => spin.message(msg)
138
+ }),
139
+ resolved,
140
+ packages: parsePackageNames(info.packages),
141
+ features
142
+ });
143
+ if (!copyFromExistingAgent(skillDir, name, allSkillsDirs)) {
144
+ if (!existsSync(join(skillDir, "SKILL.md"))) {
145
+ writeBaseSkill(ctx);
146
+ regenerated.push({
291
147
  name,
292
- pkgName,
293
- version,
294
- skillDir,
295
- packages: info.packages
148
+ ctx
296
149
  });
297
150
  }
298
- spin.stop(`Downloaded and linked ${name}`);
299
- } else spin.stop(`No docs found for ${name}`);
151
+ }
152
+ spin.stop(wasCacheHit ? `Linked ${name}` : `Downloaded and linked ${name}`);
300
153
  }
301
154
  if (regenerated.length > 0 && !readConfig().skipLlm) {
302
155
  const llmConfig = await selectLlmConfig(void 0, `Enhance SKILL.md for ${regenerated.map((r) => r.name).join(", ")}`);
303
- if (llmConfig?.promptOnly) {
304
- const features = readConfig().features ?? defaultFeatures;
305
- for (const { pkgName, version, skillDir } of regenerated) {
306
- const globalCachePath = getCacheDir(pkgName, version);
307
- writePromptFiles({
308
- packageName: pkgName,
309
- version,
310
- skillDir,
311
- references: {
312
- docsType: "docs",
313
- hasShippedDocs: false,
314
- pkgFiles: getPkgKeyFiles(pkgName, process.cwd(), version),
315
- hasIssues: existsSync(join(globalCachePath, "issues")),
316
- hasDiscussions: existsSync(join(globalCachePath, "discussions")),
317
- hasReleases: existsSync(join(globalCachePath, "releases")),
318
- hasChangelog: false
319
- },
320
- resolved: {},
321
- relatedSkills: [],
322
- features
323
- }, {
324
- sections: llmConfig.sections,
325
- customPrompt: llmConfig.customPrompt
326
- });
327
- }
328
- } else if (llmConfig) {
156
+ if (llmConfig?.promptOnly) for (const { ctx } of regenerated) writePromptFiles(ctx, {
157
+ sections: llmConfig.sections,
158
+ customPrompt: llmConfig.customPrompt
159
+ });
160
+ else if (llmConfig) {
329
161
  p.log.step(getModelLabel(llmConfig.model));
330
- for (const { pkgName, version, skillDir, packages: pkgPackages } of regenerated) await enhanceRegenerated(pkgName, version, skillDir, llmConfig.model, llmConfig.sections, llmConfig.customPrompt, pkgPackages);
162
+ for (const { ctx } of regenerated) await enhanceSkillWithLLM(ctx, {
163
+ model: llmConfig.model,
164
+ sections: llmConfig.sections,
165
+ customPrompt: llmConfig.customPrompt
166
+ });
331
167
  }
332
168
  }
333
169
  for (const [name, info] of Object.entries(lock.skills)) writeLock(skillsDir, name, info);
@@ -352,7 +188,7 @@ function copyFromExistingAgent(skillDir, name, allSkillsDirs) {
352
188
  }
353
189
  function unsanitizeName(sanitized, source) {
354
190
  if (source?.includes("ungh://")) {
355
- const match = source.match(/ungh:\/\/([^/]+)\/(.+)/);
191
+ const match = source.match(STATIC_REGEX_1);
356
192
  if (match) return `@${match[1]}/${match[2]}`;
357
193
  }
358
194
  if (sanitized.startsWith("antfu-")) return `@antfu/${sanitized.slice(6)}`;
@@ -362,61 +198,15 @@ function unsanitizeName(sanitized, source) {
362
198
  if (sanitized.startsWith("vueuse-")) return `@vueuse/${sanitized.slice(7)}`;
363
199
  return sanitized;
364
200
  }
365
- async function enhanceRegenerated(pkgName, version, skillDir, model, sections, customPrompt, packages) {
366
- const llmLog = p.taskLog({
367
- title: `Agent exploring ${pkgName}`,
368
- limit: 3
369
- });
370
- const docFiles = listReferenceFiles(skillDir);
371
- const globalCachePath = getCacheDir(pkgName, version);
372
- const hasIssues = existsSync(join(globalCachePath, "issues"));
373
- const hasDiscussions = existsSync(join(globalCachePath, "discussions"));
374
- const hasGithub = hasIssues || hasDiscussions;
375
- const hasReleases = existsSync(join(globalCachePath, "releases"));
376
- const features = readConfig().features ?? defaultFeatures;
377
- const { optimized, wasOptimized } = await optimizeDocs({
378
- packageName: pkgName,
379
- skillDir,
380
- model,
201
+ function synthesizeResolved(identityName, version, info, cwd) {
202
+ const repoUrl = info.repo?.includes("/") ? `https://github.com/${info.repo}` : void 0;
203
+ const pkgPath = resolvePkgDir(toStoragePackageName(identityName), cwd, version);
204
+ return {
205
+ name: identityName,
381
206
  version,
382
- hasGithub,
383
- hasReleases,
384
- docFiles,
385
- sections,
386
- customPrompt,
387
- features,
388
- pkgFiles: getPkgKeyFiles(pkgName, process.cwd(), version),
389
- onProgress: createToolProgress(llmLog)
390
- });
391
- if (wasOptimized) {
392
- llmLog.success("Generated best practices");
393
- const cwd = process.cwd();
394
- const pkgPath = resolvePkgDir(pkgName, cwd, version);
395
- let description;
396
- if (pkgPath) {
397
- const pkgJsonResult = readPackageJsonSafe(join(pkgPath, "package.json"));
398
- if (pkgJsonResult) description = pkgJsonResult.parsed.description;
399
- }
400
- const docsType = inferDocsTypeFromCache(globalCachePath);
401
- const dirName = skillDir.split("/").pop();
402
- const allPackages = parsePackageNames(packages);
403
- writeGeneratedSkillMd(skillDir, {
404
- name: pkgName,
405
- version,
406
- description,
407
- body: optimized,
408
- relatedSkills: [],
409
- hasIssues,
410
- hasDiscussions,
411
- hasReleases,
412
- docsType,
413
- hasShippedDocs: hasShippedDocs(pkgName, cwd, version),
414
- pkgFiles: getPkgKeyFiles(pkgName, cwd, version),
415
- dirName,
416
- packages: allPackages.length > 1 ? allPackages : void 0,
417
- features
418
- });
419
- } else llmLog.message("Enhancement skipped");
207
+ repoUrl,
208
+ description: pkgPath ? readPackageJsonSafe(join(pkgPath, "package.json"))?.parsed.description : void 0
209
+ };
420
210
  }
421
211
  const installCommandDef = defineCommand({
422
212
  meta: {
@@ -435,48 +225,13 @@ const installCommandDef = defineCommand({
435
225
  if (!picked || picked === "none") return;
436
226
  agent = picked;
437
227
  }
438
- p.intro(`\x1B[1m\x1B[35mskilld\x1B[0m install`);
228
+ p.intro(`${styleText(["bold", "magenta"], "skilld")} install`);
439
229
  return installCommand({
440
230
  global: args.global,
441
231
  agent
442
232
  });
443
233
  }
444
234
  });
445
- function regenerateBaseSkillMd(skillDir, pkgName, version, cwd, allSkillNames, source, packages) {
446
- if (existsSync(join(skillDir, "SKILL.md"))) return false;
447
- const pkgPath = resolvePkgDir(pkgName, cwd, version);
448
- let description;
449
- if (pkgPath) {
450
- const pkgResult = readPackageJsonSafe(join(pkgPath, "package.json"));
451
- if (pkgResult) description = pkgResult.parsed.description;
452
- }
453
- const globalCachePath = getCacheDir(pkgName, version);
454
- const docsType = inferDocsTypeFromCache(globalCachePath, source);
455
- const feat = readConfig().features ?? defaultFeatures;
456
- const hasIssues = feat.issues && existsSync(join(globalCachePath, "issues"));
457
- const hasDiscussions = feat.discussions && existsSync(join(globalCachePath, "discussions"));
458
- const hasReleases = feat.releases && existsSync(join(globalCachePath, "releases"));
459
- const relatedSkills = allSkillNames.filter((n) => n !== pkgName);
460
- const dirName = skillDir.split("/").pop();
461
- const allPackages = parsePackageNames(packages);
462
- mkdirSync(skillDir, { recursive: true });
463
- writeGeneratedSkillMd(skillDir, {
464
- name: pkgName,
465
- version,
466
- description,
467
- relatedSkills,
468
- hasIssues,
469
- hasDiscussions,
470
- hasReleases,
471
- docsType,
472
- hasShippedDocs: hasShippedDocs(pkgName, cwd, version),
473
- pkgFiles: getPkgKeyFiles(pkgName, cwd, version),
474
- dirName,
475
- packages: allPackages.length > 1 ? allPackages : void 0,
476
- features: readConfig().features ?? defaultFeatures
477
- });
478
- return true;
479
- }
480
235
  function hasStaleReferences(referencesPath, pkgName, version, features) {
481
236
  for (const entry of readdirSync(referencesPath)) {
482
237
  const entryPath = join(referencesPath, entry);
@@ -1 +1 @@
1
- {"version":3,"file":"install.mjs","names":["agents","checkShippedDocs"],"sources":["../../src/commands/install.ts"],"sourcesContent":["/**\n * Install command - restore .skilld/ and SKILL.md from lockfile\n *\n * After cloning a repo, the .skilld/ symlinks are missing (gitignored).\n * If SKILL.md was deleted, a base version is regenerated from local metadata.\n * This command recreates them from the lockfile:\n * .claude/skills/<skill>/.skilld/pkg -> node_modules/<pkg> (always)\n * .claude/skills/<skill>/.skilld/docs -> ~/.skilld/references/<pkg>@<version>/docs (if external)\n * .claude/skills/<skill>/SKILL.md -> regenerated from package.json + cache state\n */\n\nimport type { AgentType, CustomPrompt, SkillSection } from '../agent/index.ts'\nimport type { FeaturesConfig } from '../core/config.ts'\nimport type { SkillInfo } from '../core/lockfile.ts'\nimport { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { dirname, join } from 'pathe'\nimport { agents, createToolProgress, getModelLabel, linkSkillToAgents, optimizeDocs } from '../agent/index.ts'\nimport { writeGeneratedSkillMd, writeSkillMd } from '../agent/prompts/skill.ts'\nimport {\n hasShippedDocs as checkShippedDocs,\n classifyCachedDoc,\n createReferenceCache,\n ensureCacheDir,\n getCacheDir,\n getPackageDbPath,\n getPkgKeyFiles,\n getShippedSkills,\n inferDocsTypeFromCache,\n linkShippedSkill,\n listReferenceFiles,\n resolvePkgDir,\n} from '../cache/index.ts'\nimport { promptForAgent, resolveAgent, sharedArgs } from '../cli-helpers.ts'\nimport { defaultFeatures, readConfig } from '../core/config.ts'\nimport { timedSpinner } from '../core/formatting.ts'\nimport { mergeLocks, parsePackageNames, parsePackages, readLock, syncLockfilesToDirs, writeLock } from '../core/lockfile.ts'\nimport { readPackageJsonSafe } from '../core/package-json.ts'\nimport { getSharedSkillsDir, skillInternalDir } from '../core/paths.ts'\nimport { toStoragePackageName } from '../core/prefix.ts'\nimport { sanitizeMarkdown } from '../core/sanitize.ts'\nimport { indexResources } from '../retriv/index-pipeline.ts'\nimport { createIndex, SearchDepsUnavailableError } from '../retriv/index.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport { fetchGitSkills } from '../sources/git-skills.ts'\nimport {\n downloadLlmsDocs,\n fetchGitDocs,\n fetchGitHubRaw,\n fetchLlmsTxt,\n fetchReadmeContent,\n filterFrameworkDocs,\n isShallowGitDocs,\n normalizeLlmsLinks,\n parseGitHubUrl,\n resolveEntryFiles,\n resolvePackageDocs,\n} from '../sources/index.ts'\nimport { selectLlmConfig, writePromptFiles } from './sync.ts'\n\nexport interface InstallOptions {\n global: boolean\n agent: AgentType\n}\n\nexport async function installCommand(opts: InstallOptions): Promise<void> {\n const cwd = process.cwd()\n const agent = agents[opts.agent]\n const shared = !opts.global && getSharedSkillsDir(cwd)\n const skillsDir = opts.global\n ? join(homedir(), '.skilld', 'skills')\n : shared || join(cwd, agent.skillsDir)\n\n // Collect lockfiles from all agent skill dirs and merge\n // In shared mode, read from .skills/ only\n const allSkillsDirs = shared\n ? [shared]\n : Object.values(agents).map(t =>\n opts.global ? t.globalSkillsDir : join(cwd, t.skillsDir),\n )\n const allLocks = allSkillsDirs\n .map(dir => readLock(dir))\n .filter((l): l is NonNullable<typeof l> => !!l && Object.keys(l.skills).length > 0)\n\n if (allLocks.length === 0) {\n p.log.warn('No skilld-lock.yaml found. Run `skilld` to sync skills first.')\n return\n }\n\n const lock = mergeLocks(allLocks)\n\n const skills = Object.entries(lock.skills)\n const toRestore: Array<{ name: string, info: SkillInfo }> = []\n const features = readConfig().features ?? defaultFeatures\n\n // Find skills with missing/broken references symlinks\n for (const [name, info] of skills) {\n if (!info.version)\n continue\n\n // Shipped skills: the skill dir IS the symlink, no references/ subdir\n if (info.source === 'shipped') {\n const skillDir = join(skillsDir, name)\n if (!existsSync(skillDir)) {\n toRestore.push({ name, info })\n }\n continue\n }\n\n const skillDir = join(skillsDir, name)\n const referencesPath = skillInternalDir(skillDir)\n const skillMdPath = join(skillDir, 'SKILL.md')\n\n // Check skill dir, SKILL.md, and all internal .skilld/ references\n const needsRestore = !existsSync(skillDir)\n || !existsSync(skillMdPath)\n || !existsSync(referencesPath)\n || hasStaleReferences(referencesPath, toStoragePackageName(info.packageName || name), info.version!, features)\n\n if (needsRestore) {\n toRestore.push({ name, info })\n }\n }\n\n if (toRestore.length === 0) {\n p.log.success('All up to date')\n return\n }\n\n p.log.info(`Restoring ${toRestore.length} references`)\n ensureCacheDir()\n\n const allSkillNames = skills.map(([, info]) => info.packageName || '').filter(Boolean)\n const regenerated: Array<{ name: string, pkgName: string, version: string, skillDir: string, packages?: string }> = []\n\n for (const { name, info } of toRestore) {\n const version = info.version!\n const identityName = info.packageName || unsanitizeName(name, info.source)\n const pkgName = toStoragePackageName(identityName)\n\n // Shipped skills: re-link from node_modules or cached dist\n if (info.source === 'shipped') {\n const shipped = getShippedSkills(pkgName, cwd, version)\n const match = shipped.find(s => s.skillName === name)\n if (match) {\n linkShippedSkill(skillsDir, name, match.skillDir)\n p.log.success(`Linked ${name}`)\n }\n else {\n p.log.warn(`${name}: package ${pkgName} no longer ships this skill`)\n }\n continue\n }\n\n // Git-sourced skills: re-fetch from remote\n if (info.source === 'github' || info.source === 'gitlab' || info.source === 'local') {\n const source = {\n type: info.source as 'github' | 'gitlab' | 'local',\n ...(info.repo?.includes('/') ? { owner: info.repo.split('/')[0], repo: info.repo.split('/')[1] } : {}),\n skillPath: info.path,\n ref: info.ref,\n ...(info.source === 'local' ? { localPath: info.repo } : {}),\n }\n const result = await fetchGitSkills(source)\n const match = result.skills.find(s => s.name === name)\n if (match) {\n const skillDir = join(skillsDir, name)\n mkdirSync(skillDir, { recursive: true })\n writeSkillMd(skillDir, sanitizeMarkdown(match.content))\n for (const f of match.files) {\n const filePath = join(skillDir, f.path)\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, f.content)\n }\n p.log.success(`Restored ${name} from ${info.repo}`)\n }\n else {\n p.log.warn(`${name}: skill not found in ${info.repo}`)\n }\n continue\n }\n\n const skillDir = join(skillsDir, name)\n const cache = createReferenceCache(pkgName, version)\n const spin = timedSpinner()\n\n // Check if already in global cache - just create symlinks\n if (cache.has()) {\n spin.start(`Linking ${name}`)\n mkdirSync(skillDir, { recursive: true })\n const repoGh = info.repo ? parseGitHubUrl(`https://github.com/${info.repo}`) : null\n const docsType = inferDocsTypeFromCache(cache.dir, info.source)\n cache.linkInto(skillDir, cwd, docsType, {\n extraPackages: parsePackages(info.packages),\n features,\n repoInfo: repoGh ? { owner: repoGh.owner, repo: repoGh.repo } : undefined,\n })\n // Create search index from cached docs if missing\n if (features.search && !existsSync(getPackageDbPath(pkgName, version))) {\n spin.message(`Indexing ${name}`)\n const cached = cache.readDocs()\n const docsToIndex = cached.map(d => ({\n id: d.path,\n content: d.content,\n metadata: { package: pkgName, source: d.path, type: classifyCachedDoc(d.path).type },\n }))\n await indexResources({ packageName: pkgName, version, cwd, docsToIndex, features, onProgress: msg => spin.message(msg) })\n }\n if (!copyFromExistingAgent(skillDir, name, allSkillsDirs)) {\n if (regenerateBaseSkillMd(skillDir, pkgName, version, cwd, allSkillNames, info.source, info.packages))\n regenerated.push({ name, pkgName, version, skillDir, packages: info.packages })\n }\n spin.stop(`Linked ${name}`)\n continue\n }\n\n // Need to download to global cache first\n spin.start(`Downloading ${name}@${version}`)\n\n const resolved = await resolvePackageDocs(pkgName, { version })\n\n if (!resolved) {\n spin.stop(`Could not resolve: ${name}`)\n continue\n }\n\n const cachedDocs: Array<{ path: string, content: string }> = []\n const docsToIndex: Array<{ id: string, content: string, metadata: Record<string, any> }> = []\n const isFrameworkDoc = (path: string) => filterFrameworkDocs([path], pkgName).length > 0\n\n // Try git docs first\n if (resolved.gitDocsUrl && resolved.repoUrl) {\n const gh = parseGitHubUrl(resolved.repoUrl)\n if (gh) {\n const gitDocs = await fetchGitDocs(gh.owner, gh.repo, version, pkgName)\n if (gitDocs?.files.length) {\n const BATCH_SIZE = 20\n for (let i = 0; i < gitDocs.files.length; i += BATCH_SIZE) {\n const batch = gitDocs.files.slice(i, i + BATCH_SIZE)\n const results = await Promise.all(\n batch.map(async (file) => {\n const url = `${gitDocs.baseUrl}/${file}`\n const content = await fetchGitHubRaw(url)\n if (!content)\n return null\n return { file, content }\n }),\n )\n for (const r of results) {\n if (r) {\n const stripped = gitDocs.docsPrefix ? r.file.replace(gitDocs.docsPrefix, '') : r.file\n const cachePath = stripped.startsWith('docs/') ? stripped : `docs/${stripped}`\n cachedDocs.push({ path: cachePath, content: r.content })\n docsToIndex.push({ id: cachePath, content: r.content, metadata: { package: pkgName, source: cachePath, type: 'doc' } })\n }\n }\n }\n\n // Shallow git-docs: if < threshold and llms.txt exists, discard and fall through\n if (isShallowGitDocs(cachedDocs.length) && resolved.llmsUrl) {\n cachedDocs.length = 0\n docsToIndex.length = 0\n }\n else if (cachedDocs.length > 0 && resolved.llmsUrl) {\n // Always cache llms.txt alongside good git-docs as supplementary reference\n const llmsContent = await fetchLlmsTxt(resolved.llmsUrl)\n if (llmsContent) {\n const baseUrl = resolved.docsUrl || new URL(resolved.llmsUrl).origin\n cachedDocs.push({ path: 'llms.txt', content: normalizeLlmsLinks(llmsContent.raw) })\n if (llmsContent.links.length > 0) {\n const docs = await downloadLlmsDocs(llmsContent, baseUrl)\n for (const doc of docs) {\n if (!isFrameworkDoc(doc.url))\n continue\n const localPath = doc.url.startsWith('/') ? doc.url.slice(1) : doc.url\n cachedDocs.push({ path: join('llms-docs', ...localPath.split('/')), content: doc.content })\n }\n }\n }\n }\n }\n }\n }\n\n // Try llms.txt\n if (resolved.llmsUrl && cachedDocs.length === 0) {\n const llmsContent = await fetchLlmsTxt(resolved.llmsUrl)\n if (llmsContent) {\n cachedDocs.push({ path: 'llms.txt', content: normalizeLlmsLinks(llmsContent.raw) })\n if (llmsContent.links.length > 0) {\n const baseUrl = resolved.docsUrl || new URL(resolved.llmsUrl).origin\n const docs = await downloadLlmsDocs(llmsContent, baseUrl)\n for (const doc of docs) {\n if (!isFrameworkDoc(doc.url))\n continue\n const localPath = doc.url.startsWith('/') ? doc.url.slice(1) : doc.url\n const cachePath = join('docs', ...localPath.split('/'))\n cachedDocs.push({ path: cachePath, content: doc.content })\n docsToIndex.push({ id: doc.url, content: doc.content, metadata: { package: pkgName, source: cachePath, type: 'doc' } })\n }\n }\n }\n }\n\n // Fallback to README\n if (resolved.readmeUrl && cachedDocs.length === 0) {\n const content = await fetchReadmeContent(resolved.readmeUrl)\n if (content) {\n cachedDocs.push({ path: 'docs/README.md', content })\n docsToIndex.push({ id: 'README.md', content, metadata: { package: pkgName, source: 'docs/README.md', type: 'doc' } })\n }\n }\n\n if (cachedDocs.length > 0) {\n cache.write(cachedDocs)\n\n const repoGh = info.repo ? parseGitHubUrl(`https://github.com/${info.repo}`) : null\n const docsType = inferDocsTypeFromCache(cache.dir, info.source)\n cache.linkInto(skillDir, cwd, docsType, {\n extraPackages: parsePackages(info.packages),\n features,\n repoInfo: repoGh ? { owner: repoGh.owner, repo: repoGh.repo } : undefined,\n })\n\n if (features.search) {\n try {\n if (docsToIndex.length > 0) {\n await createIndex(docsToIndex, { dbPath: getPackageDbPath(pkgName, version) })\n }\n\n // Index package entry files (.d.ts / .js)\n const pkgDir = resolvePkgDir(pkgName, cwd, version)\n const entryFiles = pkgDir ? await resolveEntryFiles(pkgDir) : []\n if (entryFiles.length > 0) {\n await createIndex(entryFiles.map(e => ({\n id: e.path,\n content: e.content,\n metadata: { package: pkgName, source: `pkg/${e.path}`, type: e.type },\n })), { dbPath: getPackageDbPath(pkgName, version) })\n }\n }\n catch (err) {\n if (!(err instanceof SearchDepsUnavailableError))\n throw err\n }\n }\n\n if (!copyFromExistingAgent(skillDir, name, allSkillsDirs)) {\n if (regenerateBaseSkillMd(skillDir, pkgName, version, cwd, allSkillNames, info.source, info.packages))\n regenerated.push({ name, pkgName, version, skillDir, packages: info.packages })\n }\n spin.stop(`Downloaded and linked ${name}`)\n }\n else {\n spin.stop(`No docs found for ${name}`)\n }\n }\n\n // Offer LLM enhancement for regenerated SKILL.md files\n if (regenerated.length > 0 && !readConfig().skipLlm) {\n const names = regenerated.map(r => r.name).join(', ')\n const llmConfig = await selectLlmConfig(undefined, `Enhance SKILL.md for ${names}`)\n if (llmConfig?.promptOnly) {\n const features = readConfig().features ?? defaultFeatures\n for (const { pkgName, version, skillDir } of regenerated) {\n const globalCachePath = getCacheDir(pkgName, version)\n writePromptFiles({\n packageName: pkgName,\n version,\n skillDir,\n references: {\n docsType: 'docs',\n hasShippedDocs: false,\n pkgFiles: getPkgKeyFiles(pkgName, process.cwd(), version),\n hasIssues: existsSync(join(globalCachePath, 'issues')),\n hasDiscussions: existsSync(join(globalCachePath, 'discussions')),\n hasReleases: existsSync(join(globalCachePath, 'releases')),\n hasChangelog: false,\n },\n resolved: {},\n relatedSkills: [],\n features,\n }, {\n sections: llmConfig.sections,\n customPrompt: llmConfig.customPrompt,\n })\n }\n }\n else if (llmConfig) {\n p.log.step(getModelLabel(llmConfig.model))\n for (const { pkgName, version, skillDir, packages: pkgPackages } of regenerated) {\n await enhanceRegenerated(pkgName, version, skillDir, llmConfig.model, llmConfig.sections, llmConfig.customPrompt, pkgPackages)\n }\n }\n }\n\n // Write merged lockfile to target dir and sync to all other existing lockfiles\n for (const [name, info] of Object.entries(lock.skills))\n writeLock(skillsDir, name, info)\n\n // In shared mode: recreate per-agent symlinks, skip per-agent lockfile sync\n if (shared) {\n for (const [name] of skills)\n linkSkillToAgents(name, shared, cwd, opts.agent)\n }\n else {\n syncLockfilesToDirs(lock, allSkillsDirs.filter(d => d !== skillsDir))\n }\n\n await shutdownWorker()\n\n p.outro('Install complete')\n}\n\n/** Copy SKILL.md from another agent's skill dir if one exists */\nfunction copyFromExistingAgent(skillDir: string, name: string, allSkillsDirs: string[]): boolean {\n const targetMd = join(skillDir, 'SKILL.md')\n if (existsSync(targetMd))\n return false\n for (const dir of allSkillsDirs) {\n if (dir === skillDir)\n continue\n const candidateMd = join(dir, name, 'SKILL.md')\n if (existsSync(candidateMd) && !lstatSync(candidateMd).isSymbolicLink()) {\n mkdirSync(skillDir, { recursive: true })\n copyFileSync(candidateMd, targetMd)\n return true\n }\n }\n return false\n}\n\n/** Try to recover original package name from sanitized name + source */\nfunction unsanitizeName(sanitized: string, source?: string): string {\n if (source?.includes('ungh://')) {\n const match = source.match(/ungh:\\/\\/([^/]+)\\/(.+)/)\n if (match)\n return `@${match[1]}/${match[2]}`\n }\n\n if (sanitized.startsWith('antfu-'))\n return `@antfu/${sanitized.slice(6)}`\n if (sanitized.startsWith('clack-'))\n return `@clack/${sanitized.slice(6)}`\n if (sanitized.startsWith('nuxt-'))\n return `@nuxt/${sanitized.slice(5)}`\n if (sanitized.startsWith('vue-'))\n return `@vue/${sanitized.slice(4)}`\n if (sanitized.startsWith('vueuse-'))\n return `@vueuse/${sanitized.slice(7)}`\n\n return sanitized\n}\n\n/** Run LLM enhancement on a regenerated SKILL.md */\nasync function enhanceRegenerated(\n pkgName: string,\n version: string,\n skillDir: string,\n model: Parameters<typeof optimizeDocs>[0]['model'],\n sections: SkillSection[],\n customPrompt?: CustomPrompt,\n packages?: string,\n): Promise<void> {\n const llmLog = p.taskLog({ title: `Agent exploring ${pkgName}`, limit: 3 })\n\n const docFiles = listReferenceFiles(skillDir)\n const globalCachePath = getCacheDir(pkgName, version)\n const hasIssues = existsSync(join(globalCachePath, 'issues'))\n const hasDiscussions = existsSync(join(globalCachePath, 'discussions'))\n const hasGithub = hasIssues || hasDiscussions\n const hasReleases = existsSync(join(globalCachePath, 'releases'))\n\n const features = readConfig().features ?? defaultFeatures\n const { optimized, wasOptimized } = await optimizeDocs({\n packageName: pkgName,\n skillDir,\n model,\n version,\n hasGithub,\n hasReleases,\n docFiles,\n sections,\n customPrompt,\n features,\n pkgFiles: getPkgKeyFiles(pkgName, process.cwd(), version),\n onProgress: createToolProgress(llmLog),\n })\n\n if (wasOptimized) {\n llmLog.success('Generated best practices')\n // Re-read local metadata for the enhanced version\n const cwd = process.cwd()\n const pkgPath = resolvePkgDir(pkgName, cwd, version)\n let description: string | undefined\n if (pkgPath) {\n const pkgJsonPath = join(pkgPath, 'package.json')\n const pkgJsonResult = readPackageJsonSafe(pkgJsonPath)\n if (pkgJsonResult) {\n description = pkgJsonResult.parsed.description as string | undefined\n }\n }\n\n const docsType = inferDocsTypeFromCache(globalCachePath)\n\n // Derive dirName from the skill directory name\n const dirName = skillDir.split('/').pop()\n\n const allPackages = parsePackageNames(packages)\n writeGeneratedSkillMd(skillDir, {\n name: pkgName,\n version,\n description,\n body: optimized,\n relatedSkills: [],\n hasIssues,\n hasDiscussions,\n hasReleases,\n docsType,\n hasShippedDocs: checkShippedDocs(pkgName, cwd, version),\n pkgFiles: getPkgKeyFiles(pkgName, cwd, version),\n dirName,\n packages: allPackages.length > 1 ? allPackages : undefined,\n features,\n })\n }\n else {\n llmLog.message('Enhancement skipped')\n }\n}\n\nexport const installCommandDef = defineCommand({\n meta: { name: 'install', description: 'Restore references from lockfile' },\n args: {\n global: sharedArgs.global,\n agent: sharedArgs.agent,\n },\n async run({ args }) {\n let agent = resolveAgent(args.agent)\n if (!agent || agent === 'none') {\n if (agent === 'none')\n return\n const picked = await promptForAgent()\n if (!picked || picked === 'none')\n return\n agent = picked\n }\n\n p.intro(`\\x1B[1m\\x1B[35mskilld\\x1B[0m install`)\n return installCommand({ global: args.global, agent })\n },\n})\n\n/** Regenerate base SKILL.md from local metadata if missing */\nfunction regenerateBaseSkillMd(\n skillDir: string,\n pkgName: string,\n version: string,\n cwd: string,\n allSkillNames: string[],\n source?: string,\n packages?: string,\n): boolean {\n const skillMdPath = join(skillDir, 'SKILL.md')\n if (existsSync(skillMdPath))\n return false\n\n // Read description + deps from local package.json\n const pkgPath = resolvePkgDir(pkgName, cwd, version)\n let description: string | undefined\n if (pkgPath) {\n const pkgResult = readPackageJsonSafe(join(pkgPath, 'package.json'))\n if (pkgResult) {\n description = pkgResult.parsed.description as string | undefined\n }\n }\n\n // Infer docsType from source or cache\n const globalCachePath = getCacheDir(pkgName, version)\n const docsType = inferDocsTypeFromCache(globalCachePath, source)\n\n // Check cache dirs for issues/discussions/releases (only if feature enabled)\n const feat = readConfig().features ?? defaultFeatures\n const hasIssues = feat.issues && existsSync(join(globalCachePath, 'issues'))\n const hasDiscussions = feat.discussions && existsSync(join(globalCachePath, 'discussions'))\n const hasReleases = feat.releases && existsSync(join(globalCachePath, 'releases'))\n\n // Related skills from other lockfile entries\n const relatedSkills = allSkillNames.filter(n => n !== pkgName)\n\n // Derive dirName from the skill directory name (lockfile key)\n const dirName = skillDir.split('/').pop()\n\n // Build multi-package list from lockfile packages field\n const allPackages = parsePackageNames(packages)\n\n mkdirSync(skillDir, { recursive: true })\n writeGeneratedSkillMd(skillDir, {\n name: pkgName,\n version,\n description,\n relatedSkills,\n hasIssues,\n hasDiscussions,\n hasReleases,\n docsType,\n hasShippedDocs: checkShippedDocs(pkgName, cwd, version),\n pkgFiles: getPkgKeyFiles(pkgName, cwd, version),\n dirName,\n packages: allPackages.length > 1 ? allPackages : undefined,\n features: readConfig().features ?? defaultFeatures,\n })\n\n return true\n}\n\n/** Check if .skilld/ has broken symlinks or is missing expected references from global cache */\nfunction hasStaleReferences(referencesPath: string, pkgName: string, version: string, features: FeaturesConfig): boolean {\n // Scan existing entries for broken symlinks\n for (const entry of readdirSync(referencesPath)) {\n const entryPath = join(referencesPath, entry)\n if (lstatSync(entryPath).isSymbolicLink() && !existsSync(entryPath))\n return true\n }\n\n // Check pkg link always expected\n if (!existsSync(join(referencesPath, 'pkg')))\n return true\n\n // Check expected links against global cache\n const globalCachePath = getCacheDir(pkgName, version)\n const expected: Array<[string, boolean]> = [\n ['docs', existsSync(join(globalCachePath, 'docs'))],\n ['issues', features.issues && existsSync(join(globalCachePath, 'issues'))],\n ['discussions', features.discussions && existsSync(join(globalCachePath, 'discussions'))],\n ['releases', features.releases && existsSync(join(globalCachePath, 'releases'))],\n ['sections', existsSync(join(globalCachePath, 'sections'))],\n ]\n\n for (const [name, shouldExist] of expected) {\n if (shouldExist && !existsSync(join(referencesPath, name)))\n return true\n }\n\n return false\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"install.mjs","names":["agents"],"sources":["../../src/commands/install.ts"],"sourcesContent":["/**\n * Install command - restore .skilld/ and SKILL.md from lockfile\n *\n * After cloning a repo, the .skilld/ symlinks are missing (gitignored).\n * If SKILL.md was deleted, a base version is regenerated from local metadata.\n * This command recreates them from the lockfile:\n * .claude/skills/<skill>/.skilld/pkg -> node_modules/<pkg> (always)\n * .claude/skills/<skill>/.skilld/docs -> ~/.skilld/references/<pkg>@<version>/docs (if external)\n * .claude/skills/<skill>/SKILL.md -> regenerated from package.json + cache state\n */\n\nimport type { AgentType } from '../agent/index.ts'\nimport type { SkillContext } from '../agent/skill-builder.ts'\nimport type { FeaturesConfig } from '../core/config.ts'\nimport type { SkillInfo } from '../core/lockfile.ts'\nimport type { ResolvedPackage } from '../sources/index.ts'\nimport { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { styleText } from 'node:util'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { dirname, join } from 'pathe'\nimport { agents, getModelLabel, linkSkillToAgents } from '../agent/index.ts'\nimport { writeSkillMd } from '../agent/prompts/skill.ts'\nimport { enhanceSkillWithLLM, writeBaseSkill, writePromptFiles } from '../agent/skill-builder.ts'\nimport { createReferenceCache, ensureCacheDir, getCacheDir } from '../cache/index.ts'\nimport { promptForAgent, resolveAgent } from '../cli/agent-prompt.ts'\nimport { sharedArgs } from '../cli/args.ts'\nimport { defaultFeatures, readConfig } from '../core/config.ts'\nimport { timedSpinner } from '../core/formatting.ts'\nimport { mergeLocks, parsePackageNames, parsePackages, readLock, syncLockfilesToDirs, writeLock } from '../core/lockfile.ts'\nimport { readPackageJsonSafe } from '../core/package-json.ts'\nimport { getSharedSkillsDir, skillInternalDir } from '../core/paths.ts'\nimport { toStoragePackageName } from '../core/prefix.ts'\nimport {\n getShippedSkills,\n linkShippedSkill,\n resolvePkgDir,\n} from '../core/prepare.ts'\nimport { sanitizeMarkdown } from '../core/sanitize.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport { fetchGitSkills } from '../sources/git-skills.ts'\nimport { resolvePackageDocs } from '../sources/index.ts'\nimport { selectLlmConfig } from './llm-prompts.ts'\nimport { buildSkillContext, fetchAndCacheResources, prepareSkillReferences } from './sync/pipeline.ts'\n\nconst STATIC_REGEX_1 = /ungh:\\/\\/([^/]+)\\/(.+)/\n\nexport interface InstallOptions {\n global: boolean\n agent: AgentType\n}\n\nexport async function installCommand(opts: InstallOptions): Promise<void> {\n const cwd = process.cwd()\n const agent = agents[opts.agent]\n const shared = !opts.global && getSharedSkillsDir(cwd)\n const skillsDir = opts.global\n ? join(homedir(), '.skilld', 'skills')\n : shared || join(cwd, agent.skillsDir)\n\n // Collect lockfiles from all agent skill dirs and merge\n // In shared mode, read from .skills/ only\n const allSkillsDirs = shared\n ? [shared]\n : Object.values(agents).map(t =>\n opts.global ? t.globalSkillsDir : join(cwd, t.skillsDir),\n )\n const allLocks = allSkillsDirs\n .map(dir => readLock(dir))\n .filter((l): l is NonNullable<typeof l> => !!l && Object.keys(l.skills).length > 0)\n\n if (allLocks.length === 0) {\n p.log.warn('No skilld-lock.yaml found. Run `skilld` to sync skills first.')\n return\n }\n\n const lock = mergeLocks(allLocks)\n\n const skills = Object.entries(lock.skills)\n const toRestore: Array<{ name: string, info: SkillInfo }> = []\n const features = readConfig().features ?? defaultFeatures\n\n // Find skills with missing/broken references symlinks\n for (const [name, info] of skills) {\n if (!info.version)\n continue\n\n // Shipped skills: the skill dir IS the symlink, no references/ subdir\n if (info.source === 'shipped') {\n const skillDir = join(skillsDir, name)\n if (!existsSync(skillDir)) {\n toRestore.push({ name, info })\n }\n continue\n }\n\n const skillDir = join(skillsDir, name)\n const referencesPath = skillInternalDir(skillDir)\n const skillMdPath = join(skillDir, 'SKILL.md')\n\n // Check skill dir, SKILL.md, and all internal .skilld/ references\n const needsRestore = !existsSync(skillDir)\n || !existsSync(skillMdPath)\n || !existsSync(referencesPath)\n || hasStaleReferences(referencesPath, toStoragePackageName(info.packageName || name), info.version!, features)\n\n if (needsRestore) {\n toRestore.push({ name, info })\n }\n }\n\n if (toRestore.length === 0) {\n p.log.success('All up to date')\n return\n }\n\n p.log.info(`Restoring ${toRestore.length} references`)\n ensureCacheDir()\n\n const regenerated: Array<{ name: string, ctx: SkillContext }> = []\n\n for (const { name, info } of toRestore) {\n const version = info.version!\n const identityName = info.packageName || unsanitizeName(name, info.source)\n const pkgName = toStoragePackageName(identityName)\n\n // Shipped skills: re-link from node_modules or cached dist\n if (info.source === 'shipped') {\n const shipped = getShippedSkills(pkgName, cwd, version)\n const match = shipped.find(s => s.skillName === name)\n if (match) {\n linkShippedSkill(skillsDir, name, match.skillDir)\n p.log.success(`Linked ${name}`)\n }\n else {\n p.log.warn(`${name}: package ${pkgName} no longer ships this skill`)\n }\n continue\n }\n\n // Git-sourced skills: re-fetch from remote\n if (info.source === 'github' || info.source === 'gitlab' || info.source === 'local') {\n const source = {\n type: info.source as 'github' | 'gitlab' | 'local',\n ...(info.repo?.includes('/') ? { owner: info.repo.split('/')[0], repo: info.repo.split('/')[1] } : {}),\n skillPath: info.path,\n ref: info.ref,\n ...(info.source === 'local' ? { localPath: info.repo } : {}),\n }\n const result = await fetchGitSkills(source)\n const match = result.skills.find(s => s.name === name)\n if (match) {\n const skillDir = join(skillsDir, name)\n mkdirSync(skillDir, { recursive: true })\n writeSkillMd(skillDir, sanitizeMarkdown(match.content))\n for (const f of match.files) {\n const filePath = join(skillDir, f.path)\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, f.content)\n }\n p.log.success(`Restored ${name} from ${info.repo}`)\n }\n else {\n p.log.warn(`${name}: skill not found in ${info.repo}`)\n }\n continue\n }\n\n const skillDir = join(skillsDir, name)\n const cache = createReferenceCache(pkgName, version)\n const spin = timedSpinner()\n const wasCacheHit = cache.has()\n spin.start(wasCacheHit ? `Linking ${name}` : `Downloading ${name}@${version}`)\n mkdirSync(skillDir, { recursive: true })\n\n const resolved: ResolvedPackage | null = wasCacheHit\n ? synthesizeResolved(identityName, version, info, cwd)\n : await resolvePackageDocs(pkgName, { version })\n\n if (!resolved) {\n spin.stop(`Could not resolve: ${name}`)\n continue\n }\n\n const resources = await fetchAndCacheResources({\n packageName: pkgName,\n resolved,\n version,\n useCache: wasCacheHit,\n features,\n onProgress: msg => spin.message(msg),\n })\n\n for (const w of resources.warnings)\n p.log.warn(`${name}: ${w}`)\n\n if (!cache.has()) {\n spin.stop(`No docs found for ${name}`)\n continue\n }\n\n const prepared = await prepareSkillReferences({\n packageName: pkgName,\n version,\n cwd,\n skillDir,\n resources,\n features,\n baseDir: skillsDir,\n extraPackages: parsePackages(info.packages),\n onIndexProgress: msg => spin.message(msg),\n })\n\n const ctx = buildSkillContext({\n packageName: identityName,\n cachePackageName: pkgName,\n version,\n skillDir,\n skillDirName: name,\n resources,\n prepared,\n resolved,\n packages: parsePackageNames(info.packages),\n features,\n })\n\n if (!copyFromExistingAgent(skillDir, name, allSkillsDirs)) {\n if (!existsSync(join(skillDir, 'SKILL.md'))) {\n writeBaseSkill(ctx)\n regenerated.push({ name, ctx })\n }\n }\n spin.stop(wasCacheHit ? `Linked ${name}` : `Downloaded and linked ${name}`)\n }\n\n // Offer LLM enhancement for regenerated SKILL.md files\n if (regenerated.length > 0 && !readConfig().skipLlm) {\n const names = regenerated.map(r => r.name).join(', ')\n const llmConfig = await selectLlmConfig(undefined, `Enhance SKILL.md for ${names}`)\n if (llmConfig?.promptOnly) {\n for (const { ctx } of regenerated)\n writePromptFiles(ctx, { sections: llmConfig.sections, customPrompt: llmConfig.customPrompt })\n }\n else if (llmConfig) {\n p.log.step(getModelLabel(llmConfig.model))\n for (const { ctx } of regenerated) {\n await enhanceSkillWithLLM(ctx, {\n model: llmConfig.model,\n sections: llmConfig.sections,\n customPrompt: llmConfig.customPrompt,\n })\n }\n }\n }\n\n // Write merged lockfile to target dir and sync to all other existing lockfiles\n for (const [name, info] of Object.entries(lock.skills))\n writeLock(skillsDir, name, info)\n\n // In shared mode: recreate per-agent symlinks, skip per-agent lockfile sync\n if (shared) {\n for (const [name] of skills)\n linkSkillToAgents(name, shared, cwd, opts.agent)\n }\n else {\n syncLockfilesToDirs(lock, allSkillsDirs.filter(d => d !== skillsDir))\n }\n\n await shutdownWorker()\n\n p.outro('Install complete')\n}\n\n/** Copy SKILL.md from another agent's skill dir if one exists */\nfunction copyFromExistingAgent(skillDir: string, name: string, allSkillsDirs: string[]): boolean {\n const targetMd = join(skillDir, 'SKILL.md')\n if (existsSync(targetMd))\n return false\n for (const dir of allSkillsDirs) {\n if (dir === skillDir)\n continue\n const candidateMd = join(dir, name, 'SKILL.md')\n if (existsSync(candidateMd) && !lstatSync(candidateMd).isSymbolicLink()) {\n mkdirSync(skillDir, { recursive: true })\n copyFileSync(candidateMd, targetMd)\n return true\n }\n }\n return false\n}\n\n/** Try to recover original package name from sanitized name + source */\nfunction unsanitizeName(sanitized: string, source?: string): string {\n if (source?.includes('ungh://')) {\n const match = source.match(STATIC_REGEX_1)\n if (match)\n return `@${match[1]}/${match[2]}`\n }\n\n if (sanitized.startsWith('antfu-'))\n return `@antfu/${sanitized.slice(6)}`\n if (sanitized.startsWith('clack-'))\n return `@clack/${sanitized.slice(6)}`\n if (sanitized.startsWith('nuxt-'))\n return `@nuxt/${sanitized.slice(5)}`\n if (sanitized.startsWith('vue-'))\n return `@vue/${sanitized.slice(4)}`\n if (sanitized.startsWith('vueuse-'))\n return `@vueuse/${sanitized.slice(7)}`\n\n return sanitized\n}\n\n/** Build a minimal ResolvedPackage from lockfile state for cache-hit restoration. */\nfunction synthesizeResolved(identityName: string, version: string, info: SkillInfo, cwd: string): ResolvedPackage {\n const repoUrl = info.repo?.includes('/') ? `https://github.com/${info.repo}` : undefined\n const pkgPath = resolvePkgDir(toStoragePackageName(identityName), cwd, version)\n const description = pkgPath\n ? readPackageJsonSafe(join(pkgPath, 'package.json'))?.parsed.description as string | undefined\n : undefined\n return { name: identityName, version, repoUrl, description }\n}\n\nexport const installCommandDef = defineCommand({\n meta: { name: 'install', description: 'Restore references from lockfile' },\n args: {\n global: sharedArgs.global,\n agent: sharedArgs.agent,\n },\n async run({ args }) {\n let agent = resolveAgent(args.agent)\n if (!agent || agent === 'none') {\n if (agent === 'none')\n return\n const picked = await promptForAgent()\n if (!picked || picked === 'none')\n return\n agent = picked\n }\n\n p.intro(`${styleText(['bold', 'magenta'], 'skilld')} install`)\n return installCommand({ global: args.global, agent })\n },\n})\n\n/** Check if .skilld/ has broken symlinks or is missing expected references from global cache */\nfunction hasStaleReferences(referencesPath: string, pkgName: string, version: string, features: FeaturesConfig): boolean {\n // Scan existing entries for broken symlinks\n for (const entry of readdirSync(referencesPath)) {\n const entryPath = join(referencesPath, entry)\n if (lstatSync(entryPath).isSymbolicLink() && !existsSync(entryPath))\n return true\n }\n\n // Check pkg link always expected\n if (!existsSync(join(referencesPath, 'pkg')))\n return true\n\n // Check expected links against global cache\n const globalCachePath = getCacheDir(pkgName, version)\n const expected: Array<[string, boolean]> = [\n ['docs', existsSync(join(globalCachePath, 'docs'))],\n ['issues', features.issues && existsSync(join(globalCachePath, 'issues'))],\n ['discussions', features.discussions && existsSync(join(globalCachePath, 'discussions'))],\n ['releases', features.releases && existsSync(join(globalCachePath, 'releases'))],\n ['sections', existsSync(join(globalCachePath, 'sections'))],\n ]\n\n for (const [name, shouldExist] of expected) {\n if (shouldExist && !existsSync(join(referencesPath, name)))\n return true\n }\n\n return false\n}\n"],"mappings":"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"}