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.
- package/dist/_chunks/add.mjs +66 -0
- package/dist/_chunks/add.mjs.map +1 -0
- package/dist/_chunks/agent-prompt.mjs +88 -0
- package/dist/_chunks/agent-prompt.mjs.map +1 -0
- package/dist/_chunks/agent.mjs +81 -57
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/args.mjs +42 -0
- package/dist/_chunks/args.mjs.map +1 -0
- package/dist/_chunks/assemble.mjs +10 -7
- package/dist/_chunks/assemble.mjs.map +1 -1
- package/dist/_chunks/author.mjs +33 -17
- package/dist/_chunks/author.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +143 -183
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cache2.mjs +7 -6
- package/dist/_chunks/cache2.mjs.map +1 -1
- package/dist/_chunks/client.mjs +117 -0
- package/dist/_chunks/client.mjs.map +1 -0
- package/dist/_chunks/core.mjs +5 -5
- package/dist/_chunks/detect.mjs +53 -43
- package/dist/_chunks/detect.mjs.map +1 -1
- package/dist/_chunks/eject.mjs +69 -0
- package/dist/_chunks/eject.mjs.map +1 -0
- package/dist/_chunks/embedding-cache2.mjs +1 -1
- package/dist/_chunks/env.mjs +19 -0
- package/dist/_chunks/env.mjs.map +1 -0
- package/dist/_chunks/install-many.mjs +376 -0
- package/dist/_chunks/install-many.mjs.map +1 -0
- package/dist/_chunks/install.mjs +81 -326
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/intro.mjs +63 -0
- package/dist/_chunks/intro.mjs.map +1 -0
- package/dist/_chunks/list.mjs +2 -2
- package/dist/_chunks/list.mjs.map +1 -1
- package/dist/_chunks/lockfile.mjs +3 -2
- package/dist/_chunks/lockfile.mjs.map +1 -1
- package/dist/_chunks/login.mjs +233 -0
- package/dist/_chunks/login.mjs.map +1 -0
- package/dist/_chunks/logout.mjs +27 -0
- package/dist/_chunks/logout.mjs.map +1 -0
- package/dist/_chunks/map.mjs +11 -0
- package/dist/_chunks/map.mjs.map +1 -0
- package/dist/_chunks/markdown.mjs +79 -54
- package/dist/_chunks/markdown.mjs.map +1 -1
- package/dist/_chunks/menu.mjs +33 -0
- package/dist/_chunks/menu.mjs.map +1 -0
- package/dist/_chunks/model-picker.mjs +61 -0
- package/dist/_chunks/model-picker.mjs.map +1 -0
- package/dist/_chunks/monorepo.mjs +4 -2
- package/dist/_chunks/monorepo.mjs.map +1 -1
- package/dist/_chunks/package-json.mjs.map +1 -1
- package/dist/_chunks/paths.mjs +3 -5
- package/dist/_chunks/paths.mjs.map +1 -1
- package/dist/_chunks/{sync-pipeline.mjs → pipeline.mjs} +346 -313
- package/dist/_chunks/pipeline.mjs.map +1 -0
- package/dist/_chunks/pool2.mjs +1 -1
- package/dist/_chunks/portable.mjs +151 -0
- package/dist/_chunks/portable.mjs.map +1 -0
- package/dist/_chunks/prepare-hook.mjs +2 -0
- package/dist/_chunks/prepare-hook2.mjs +61 -0
- package/dist/_chunks/prepare-hook2.mjs.map +1 -0
- package/dist/_chunks/prepare.mjs +47 -3
- package/dist/_chunks/prepare.mjs.map +1 -1
- package/dist/_chunks/prepare2.mjs +7 -6
- package/dist/_chunks/prepare2.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +484 -74
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/pull.mjs +219 -0
- package/dist/_chunks/pull.mjs.map +1 -0
- package/dist/_chunks/regex.mjs +19 -0
- package/dist/_chunks/regex.mjs.map +1 -0
- package/dist/_chunks/retriv.mjs +2 -171
- package/dist/_chunks/retriv2.mjs +159 -0
- package/dist/_chunks/retriv2.mjs.map +1 -0
- package/dist/_chunks/sanitize.mjs +12 -9
- package/dist/_chunks/sanitize.mjs.map +1 -1
- package/dist/_chunks/search-helpers.mjs +8 -6
- package/dist/_chunks/search-helpers.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +23 -20
- package/dist/_chunks/search-interactive.mjs.map +1 -1
- package/dist/_chunks/search.mjs +3 -3
- package/dist/_chunks/search.mjs.map +1 -1
- package/dist/_chunks/semver.mjs +2755 -1
- package/dist/_chunks/semver.mjs.map +1 -1
- package/dist/_chunks/skill-installer2.mjs +10 -11
- package/dist/_chunks/skill-installer2.mjs.map +1 -1
- package/dist/_chunks/skills.mjs +6 -7
- package/dist/_chunks/skills.mjs.map +1 -1
- package/dist/_chunks/store.mjs +107 -0
- package/dist/_chunks/store.mjs.map +1 -0
- package/dist/_chunks/sync.mjs +411 -910
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/sync2.mjs +2 -5
- package/dist/_chunks/telemetry.mjs +26 -0
- package/dist/_chunks/telemetry.mjs.map +1 -0
- package/dist/_chunks/uninstall.mjs +12 -9
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/_chunks/update.mjs +171 -0
- package/dist/_chunks/update.mjs.map +1 -0
- package/dist/_chunks/upload.mjs +3 -3
- package/dist/_chunks/validate.mjs +1 -1
- package/dist/_chunks/version.mjs +16 -17
- package/dist/_chunks/version.mjs.map +1 -1
- package/dist/_chunks/whoami.mjs +21 -0
- package/dist/_chunks/whoami.mjs.map +1 -0
- package/dist/_chunks/wizard.mjs +2 -190
- package/dist/_chunks/wizard2.mjs +200 -0
- package/dist/_chunks/wizard2.mjs.map +1 -0
- package/dist/cli.mjs +72 -53
- package/dist/cli.mjs.map +1 -1
- package/dist/prepare.mjs +4 -3
- package/dist/prepare.mjs.map +1 -1
- package/dist/retriv/worker.d.mts +5 -1
- package/dist/retriv/worker.d.mts.map +1 -1
- package/dist/retriv/worker.mjs +1 -1
- package/package.json +19 -28
- package/dist/_chunks/author-group.mjs +0 -17
- package/dist/_chunks/author-group.mjs.map +0 -1
- package/dist/_chunks/cli-helpers.mjs +0 -335
- package/dist/_chunks/cli-helpers.mjs.map +0 -1
- package/dist/_chunks/cli-helpers2.mjs +0 -2
- package/dist/_chunks/index.d.mts +0 -344
- package/dist/_chunks/index.d.mts.map +0 -1
- package/dist/_chunks/index2.d.mts +0 -279
- package/dist/_chunks/index2.d.mts.map +0 -1
- package/dist/_chunks/index3.d.mts +0 -44
- package/dist/_chunks/index3.d.mts.map +0 -1
- package/dist/_chunks/index4.d.mts +0 -553
- package/dist/_chunks/index4.d.mts.map +0 -1
- package/dist/_chunks/package-registry.mjs +0 -465
- package/dist/_chunks/package-registry.mjs.map +0 -1
- package/dist/_chunks/retriv.mjs.map +0 -1
- package/dist/_chunks/setup.mjs +0 -17
- package/dist/_chunks/setup.mjs.map +0 -1
- package/dist/_chunks/sources.mjs +0 -2654
- package/dist/_chunks/sources.mjs.map +0 -1
- package/dist/_chunks/sync-pipeline.mjs.map +0 -1
- package/dist/_chunks/sync-registry.mjs +0 -65
- package/dist/_chunks/sync-registry.mjs.map +0 -1
- package/dist/_chunks/types.d.mts +0 -76
- package/dist/_chunks/types.d.mts.map +0 -1
- package/dist/_chunks/types2.d.mts +0 -88
- package/dist/_chunks/types2.d.mts.map +0 -1
- package/dist/_chunks/wizard.mjs.map +0 -1
- package/dist/agent/index.d.mts +0 -2
- package/dist/agent/index.mjs +0 -4
- package/dist/cache/index.d.mts +0 -2
- package/dist/cache/index.mjs +0 -5
- package/dist/index.d.mts +0 -6
- package/dist/index.mjs +0 -6
- package/dist/retriv/index.d.mts +0 -3
- package/dist/retriv/index.mjs +0 -2
- package/dist/sources/index.d.mts +0 -3
- package/dist/sources/index.mjs +0 -3
- package/dist/types.d.mts +0 -4
- package/dist/types.mjs +0 -1
package/dist/_chunks/install.mjs
CHANGED
|
@@ -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
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
293
|
-
version,
|
|
294
|
-
skillDir,
|
|
295
|
-
packages: info.packages
|
|
148
|
+
ctx
|
|
296
149
|
});
|
|
297
150
|
}
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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 {
|
|
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(
|
|
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
|
-
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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(
|
|
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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"}
|