skilld 1.7.0 → 1.7.2
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/agent.mjs +14 -5
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/assemble.mjs +1 -1
- package/dist/_chunks/author.mjs +6 -9
- package/dist/_chunks/author.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +11 -1
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cli-helpers.mjs +1 -1
- package/dist/_chunks/core.mjs +1 -1
- package/dist/_chunks/index.d.mts +4 -1
- package/dist/_chunks/index.d.mts.map +1 -1
- package/dist/_chunks/index3.d.mts +3 -1
- package/dist/_chunks/index3.d.mts.map +1 -1
- package/dist/_chunks/install.mjs +523 -85
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/list.mjs +1 -1
- package/dist/_chunks/lockfile.mjs +4 -1
- package/dist/_chunks/lockfile.mjs.map +1 -1
- package/dist/_chunks/prefix.mjs +5 -5
- package/dist/_chunks/prefix.mjs.map +1 -1
- package/dist/_chunks/prepare2.mjs +4 -4
- package/dist/_chunks/prepare2.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +3 -142
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/search-helpers.mjs +2 -2
- package/dist/_chunks/search-interactive.mjs +1 -1
- package/dist/_chunks/search.mjs +1 -1
- package/dist/_chunks/shared.mjs +463 -1
- package/dist/_chunks/shared.mjs.map +1 -1
- package/dist/_chunks/skill.mjs +329 -0
- package/dist/_chunks/skill.mjs.map +1 -0
- package/dist/_chunks/skills.mjs +3 -3
- package/dist/_chunks/sources.mjs +7 -3
- package/dist/_chunks/sources.mjs.map +1 -1
- package/dist/_chunks/sync-registry.mjs +4 -4
- package/dist/_chunks/sync-registry.mjs.map +1 -1
- package/dist/_chunks/sync-shared2.mjs +9 -10
- package/dist/_chunks/sync-shared2.mjs.map +1 -1
- package/dist/_chunks/sync.mjs +48 -62
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/uninstall.mjs +2 -2
- package/dist/_chunks/upload.mjs +1 -1
- package/dist/_chunks/validate.mjs +1 -1
- package/dist/_chunks/wizard.mjs +1 -1
- package/dist/agent/index.d.mts +3 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +4 -4
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +2 -2
- package/dist/cli.mjs +5 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/prepare.mjs +1 -1
- package/dist/sources/index.d.mts +2 -2
- package/dist/sources/index.mjs +3 -3
- package/dist/types.d.mts +2 -2
- package/package.json +6 -5
- package/dist/THIRD-PARTY-LICENSES.md +0 -38
- package/dist/_chunks/formatting.mjs +0 -82
- package/dist/_chunks/formatting.mjs.map +0 -1
- package/dist/_chunks/install2.mjs +0 -554
- package/dist/_chunks/install2.mjs.map +0 -1
- package/dist/_chunks/libs/@sinclair/typebox.mjs +0 -2304
- package/dist/_chunks/libs/@sinclair/typebox.mjs.map +0 -1
- package/dist/_chunks/package-registry.mjs +0 -465
- package/dist/_chunks/package-registry.mjs.map +0 -1
- package/dist/_chunks/rolldown-runtime.mjs +0 -11
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { n as sanitizeMarkdown, t as repairMarkdown } from "./sanitize.mjs";
|
|
2
|
+
import { t as yamlEscape } from "./yaml.mjs";
|
|
3
|
+
import { d as getFilePatterns, i as resolveSkilldCommand } from "./shared.mjs";
|
|
4
|
+
import { a as targets, t as detectInstalledAgents } from "./detect.mjs";
|
|
5
|
+
import { join, relative } from "pathe";
|
|
6
|
+
import { existsSync, lstatSync, mkdirSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
|
+
import * as p from "@clack/prompts";
|
|
8
|
+
function todayIsoDate() {
|
|
9
|
+
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
10
|
+
}
|
|
11
|
+
function timeAgo(iso) {
|
|
12
|
+
if (!iso) return "";
|
|
13
|
+
const diff = Date.now() - new Date(iso).getTime();
|
|
14
|
+
const days = Math.floor(diff / 864e5);
|
|
15
|
+
if (days <= 0) return "today";
|
|
16
|
+
if (days === 1) return "1d ago";
|
|
17
|
+
if (days < 7) return `${days}d ago`;
|
|
18
|
+
if (days < 30) return `${Math.floor(days / 7)}w ago`;
|
|
19
|
+
return `${Math.floor(days / 30)}mo ago`;
|
|
20
|
+
}
|
|
21
|
+
function formatSource(source) {
|
|
22
|
+
if (!source) return "";
|
|
23
|
+
if (source === "shipped") return "shipped";
|
|
24
|
+
if (source.includes("llms.txt")) return "llms.txt";
|
|
25
|
+
if (source.includes("github.com")) return source.replace(/https?:\/\/github\.com\//, "");
|
|
26
|
+
return source;
|
|
27
|
+
}
|
|
28
|
+
function formatDuration(ms) {
|
|
29
|
+
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
30
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
31
|
+
}
|
|
32
|
+
function timedSpinner() {
|
|
33
|
+
const spin = p.spinner({ indicator: "timer" });
|
|
34
|
+
return {
|
|
35
|
+
start(msg) {
|
|
36
|
+
spin.start(msg);
|
|
37
|
+
},
|
|
38
|
+
message(msg) {
|
|
39
|
+
spin.message(msg);
|
|
40
|
+
},
|
|
41
|
+
stop(msg) {
|
|
42
|
+
spin.stop(msg);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function highlightTerms(content, terms) {
|
|
47
|
+
if (terms.length === 0) return content;
|
|
48
|
+
const sorted = terms.toSorted((a, b) => b.length - a.length);
|
|
49
|
+
const pattern = new RegExp(`(${sorted.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, "gi");
|
|
50
|
+
return content.replace(pattern, "\x1B[33m$1\x1B[0m");
|
|
51
|
+
}
|
|
52
|
+
function scoreLabel(pct) {
|
|
53
|
+
return `${pct >= 70 ? "\x1B[32m" : pct >= 40 ? "\x1B[33m" : "\x1B[90m"}${pct}%\x1B[0m`;
|
|
54
|
+
}
|
|
55
|
+
function normalizeScores(results) {
|
|
56
|
+
const map = /* @__PURE__ */ new Map();
|
|
57
|
+
const max = results.reduce((m, r) => Math.max(m, r.score), 0);
|
|
58
|
+
for (const r of results) map.set(r, max > 0 ? Math.round(r.score / max * 100) : 0);
|
|
59
|
+
return map;
|
|
60
|
+
}
|
|
61
|
+
function formatSnippet(r, versions, pct) {
|
|
62
|
+
const refPath = `.claude/skills/${r.package}/.skilld/${r.source}`;
|
|
63
|
+
const lineRange = r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`;
|
|
64
|
+
const score = pct != null ? scoreLabel(pct) : `\x1B[90m${r.score.toFixed(2)}\x1B[0m`;
|
|
65
|
+
const version = versions?.get(r.package);
|
|
66
|
+
const pkgLabel = version ? `${r.package}@${version}` : r.package;
|
|
67
|
+
const scopeStr = r.scope?.length ? `${r.scope.map((e) => e.name).join(".")} → ` : "";
|
|
68
|
+
const entityStr = r.entities?.map((e) => e.signature || `${e.type} ${e.name}`).join(", ");
|
|
69
|
+
const highlighted = highlightTerms(r.content, r.highlights);
|
|
70
|
+
return [
|
|
71
|
+
`${pkgLabel} ${score}${entityStr ? ` \x1B[36m${scopeStr}${entityStr}\x1B[0m` : ""}`,
|
|
72
|
+
`\x1B[90m${refPath}:${lineRange}\x1B[0m`,
|
|
73
|
+
` ${highlighted.replace(/\n/g, "\n ")}`
|
|
74
|
+
].join("\n");
|
|
75
|
+
}
|
|
76
|
+
function formatCompactSnippet(r, cols) {
|
|
77
|
+
const entityStr = r.entities?.length ? r.entities.map((e) => e.signature || e.name).join(", ") : "";
|
|
78
|
+
const scopeStr = r.scope?.length ? `${r.scope.map((e) => e.name).join(".")} → ` : "";
|
|
79
|
+
const title = entityStr ? `${scopeStr}${entityStr}` : r.source.split("/").pop() || r.source;
|
|
80
|
+
const path = `${`.claude/skills/${r.package}/.skilld/${r.source}`}:${r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`}`;
|
|
81
|
+
const maxPreview = cols - 6;
|
|
82
|
+
const firstLine = r.content.split("\n").find((l) => l.trim() && l.trim() !== "---" && !/^#+\s*$/.test(l.trim())) || "";
|
|
83
|
+
return {
|
|
84
|
+
title,
|
|
85
|
+
path,
|
|
86
|
+
preview: firstLine.length > maxPreview ? `${firstLine.slice(0, maxPreview - 1)}…` : firstLine
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function sanitizeName(name) {
|
|
90
|
+
return name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").slice(0, 255) || "unnamed-skill";
|
|
91
|
+
}
|
|
92
|
+
function computeSkillDirName(packageName) {
|
|
93
|
+
return `${sanitizeName(packageName)}-skilld`;
|
|
94
|
+
}
|
|
95
|
+
function installSkillForAgents(skillName, skillContent, options = {}) {
|
|
96
|
+
const isGlobal = options.global ?? false;
|
|
97
|
+
const cwd = options.cwd || process.cwd();
|
|
98
|
+
const sanitized = sanitizeName(skillName);
|
|
99
|
+
const explicit = !!options.agents;
|
|
100
|
+
const targetAgents = options.agents || detectInstalledAgents();
|
|
101
|
+
const installed = [];
|
|
102
|
+
const skipped = [];
|
|
103
|
+
const paths = [];
|
|
104
|
+
const writtenDirs = /* @__PURE__ */ new Set();
|
|
105
|
+
for (const agentType of targetAgents) {
|
|
106
|
+
const agent = targets[agentType];
|
|
107
|
+
if (isGlobal && !agent.globalSkillsDir) {
|
|
108
|
+
skipped.push({
|
|
109
|
+
agent: agentType,
|
|
110
|
+
reason: "no global support"
|
|
111
|
+
});
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const baseDir = isGlobal ? agent.globalSkillsDir : join(cwd, agent.skillsDir);
|
|
115
|
+
if (!explicit && !existsSync(baseDir)) {
|
|
116
|
+
skipped.push({
|
|
117
|
+
agent: agentType,
|
|
118
|
+
reason: "skills dir not found"
|
|
119
|
+
});
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (isGlobal && (writtenDirs.has(baseDir) || agent.additionalSkillsDirs.some((d) => writtenDirs.has(d)))) {
|
|
123
|
+
skipped.push({
|
|
124
|
+
agent: agentType,
|
|
125
|
+
reason: "already covered by another agent dir"
|
|
126
|
+
});
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const skillDir = join(baseDir, sanitized);
|
|
130
|
+
const skilldDir = join(skillDir, ".skilld");
|
|
131
|
+
mkdirSync(skilldDir, { recursive: true });
|
|
132
|
+
writeFileSync(join(skilldDir, "_SKILL.md"), sanitizeMarkdown(repairMarkdown(skillContent)));
|
|
133
|
+
if (options.files) for (const [filename, content] of Object.entries(options.files)) writeFileSync(join(skillDir, filename), filename.endsWith(".md") ? sanitizeMarkdown(repairMarkdown(content)) : content);
|
|
134
|
+
installed.push(agentType);
|
|
135
|
+
paths.push(skillDir);
|
|
136
|
+
writtenDirs.add(baseDir);
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
installed,
|
|
140
|
+
skipped,
|
|
141
|
+
paths
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function linkSkillToAgents(skillName, sharedDir, cwd, agentType) {
|
|
145
|
+
const targetAgents = agentType ? [[agentType, targets[agentType]]] : Object.entries(targets);
|
|
146
|
+
const linkedDirs = /* @__PURE__ */ new Set();
|
|
147
|
+
for (const [type, agent] of targetAgents) {
|
|
148
|
+
const agentSkillsDir = join(cwd, agent.skillsDir);
|
|
149
|
+
if (agentType === type) mkdirSync(agentSkillsDir, { recursive: true });
|
|
150
|
+
else {
|
|
151
|
+
if (!existsSync(agentSkillsDir)) continue;
|
|
152
|
+
if (agent.additionalSkillsDirs.map((d) => join(cwd, d)).some((d) => linkedDirs.has(d))) {
|
|
153
|
+
const staleTarget = join(agentSkillsDir, skillName);
|
|
154
|
+
try {
|
|
155
|
+
if (lstatSync(staleTarget).isSymbolicLink() && !existsSync(staleTarget)) unlinkSync(staleTarget);
|
|
156
|
+
} catch {}
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const target = join(agentSkillsDir, skillName);
|
|
161
|
+
let isSymlink = false;
|
|
162
|
+
let targetExists = false;
|
|
163
|
+
try {
|
|
164
|
+
const stat = lstatSync(target);
|
|
165
|
+
targetExists = true;
|
|
166
|
+
isSymlink = stat.isSymbolicLink();
|
|
167
|
+
} catch {}
|
|
168
|
+
if (targetExists && !isSymlink) continue;
|
|
169
|
+
if (isSymlink) unlinkSync(target);
|
|
170
|
+
symlinkSync(relative(agentSkillsDir, join(sharedDir, skillName)), target);
|
|
171
|
+
linkedDirs.add(agentSkillsDir);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function unlinkSkillFromAgents(skillName, cwd, agentType) {
|
|
175
|
+
const targetAgents = agentType ? [[agentType, targets[agentType]]] : Object.entries(targets);
|
|
176
|
+
for (const [, agent] of targetAgents) {
|
|
177
|
+
const target = join(cwd, agent.skillsDir, skillName);
|
|
178
|
+
try {
|
|
179
|
+
if (lstatSync(target).isSymbolicLink()) unlinkSync(target);
|
|
180
|
+
} catch {}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function writeSkillMd(skillDir, content) {
|
|
184
|
+
writeFileSync(join(skillDir, "SKILL.md"), content);
|
|
185
|
+
}
|
|
186
|
+
function writeGeneratedSkillMd(skillDir, opts) {
|
|
187
|
+
const content = generateSkillMd(opts);
|
|
188
|
+
writeSkillMd(skillDir, content);
|
|
189
|
+
return content;
|
|
190
|
+
}
|
|
191
|
+
function generateSkillMd(opts) {
|
|
192
|
+
const header = generatePackageHeader(opts);
|
|
193
|
+
const search = !opts.eject && opts.features?.search !== false ? generateSearchBlock(opts.name) : "";
|
|
194
|
+
let body = opts.body;
|
|
195
|
+
if (body && opts.eject) {
|
|
196
|
+
body = body.replace(/\.\/\.skilld\//g, "./references/");
|
|
197
|
+
body = body.replace(/\s*\[source\]\(\.\/references\/pkg\/[^)]*\)/gi, "");
|
|
198
|
+
}
|
|
199
|
+
const content = body ? search ? `${header}\n\n${search}\n\n${body}` : `${header}\n\n${body}` : search ? `${header}\n\n${search}` : header;
|
|
200
|
+
const footer = generateFooter(opts.relatedSkills);
|
|
201
|
+
return sanitizeMarkdown(repairMarkdown(`${generateFrontmatter(opts)}${content}\n${footer}`));
|
|
202
|
+
}
|
|
203
|
+
function formatShortDate(isoDate) {
|
|
204
|
+
const date = new Date(isoDate);
|
|
205
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
206
|
+
return `${[
|
|
207
|
+
"Jan",
|
|
208
|
+
"Feb",
|
|
209
|
+
"Mar",
|
|
210
|
+
"Apr",
|
|
211
|
+
"May",
|
|
212
|
+
"Jun",
|
|
213
|
+
"Jul",
|
|
214
|
+
"Aug",
|
|
215
|
+
"Sep",
|
|
216
|
+
"Oct",
|
|
217
|
+
"Nov",
|
|
218
|
+
"Dec"
|
|
219
|
+
][date.getUTCMonth()]} ${date.getUTCFullYear()}`;
|
|
220
|
+
}
|
|
221
|
+
function generatePackageHeader({ name, version, distTags, repoUrl, hasIssues, hasDiscussions, hasReleases, docsType, pkgFiles, packages, eject }) {
|
|
222
|
+
const versionSuffix = version ? `@${version}` : "";
|
|
223
|
+
let title = `# ${name}${versionSuffix}`;
|
|
224
|
+
if (repoUrl) {
|
|
225
|
+
const url = repoUrl.startsWith("http") ? repoUrl : `https://github.com/${repoUrl}`;
|
|
226
|
+
title = `# [${repoUrl.startsWith("http") ? repoUrl.split("/").slice(-2).join("/") : repoUrl}](${url}) \`${name}${versionSuffix}\``;
|
|
227
|
+
}
|
|
228
|
+
const lines = [title];
|
|
229
|
+
if (distTags && Object.keys(distTags).length > 0) {
|
|
230
|
+
const tags = Object.entries(distTags).sort(([, a], [, b]) => (b.releasedAt ?? "").localeCompare(a.releasedAt ?? "")).slice(0, 3).map(([tag, info]) => {
|
|
231
|
+
const relDate = info.releasedAt ? ` (${formatShortDate(info.releasedAt)})` : "";
|
|
232
|
+
return `${tag}: ${info.version}${relDate}`;
|
|
233
|
+
}).join(", ");
|
|
234
|
+
lines.push(`**Tags:** ${tags}`);
|
|
235
|
+
}
|
|
236
|
+
lines.push("");
|
|
237
|
+
const refBase = eject ? "./references" : "./.skilld";
|
|
238
|
+
const refs = [];
|
|
239
|
+
if (!eject) {
|
|
240
|
+
refs.push(`[package.json](${refBase}/pkg/package.json)`);
|
|
241
|
+
if (packages && packages.length > 1) for (const pkg of packages) {
|
|
242
|
+
const shortName = pkg.name.split("/").pop().toLowerCase();
|
|
243
|
+
refs.push(`[pkg-${shortName}](${refBase}/pkg-${shortName}/package.json)`);
|
|
244
|
+
}
|
|
245
|
+
if (pkgFiles?.includes("README.md")) refs.push(`[README](${refBase}/pkg/README.md)`);
|
|
246
|
+
}
|
|
247
|
+
if (docsType && docsType !== "readme") refs.push(`[Docs](${refBase}/docs/_INDEX.md)`);
|
|
248
|
+
if (hasIssues) refs.push(`[Issues](${refBase}/issues/_INDEX.md)`);
|
|
249
|
+
if (hasDiscussions) refs.push(`[Discussions](${refBase}/discussions/_INDEX.md)`);
|
|
250
|
+
if (hasReleases) refs.push(`[Releases](${refBase}/releases/_INDEX.md)`);
|
|
251
|
+
if (refs.length > 0) lines.push(`**References:** ${refs.join(" • ")}`);
|
|
252
|
+
return lines.join("\n");
|
|
253
|
+
}
|
|
254
|
+
function expandPackageName(name) {
|
|
255
|
+
const variants = /* @__PURE__ */ new Set();
|
|
256
|
+
const unscoped = name.replace(/^@/, "");
|
|
257
|
+
if (unscoped !== name) {
|
|
258
|
+
variants.add(unscoped);
|
|
259
|
+
variants.add(unscoped.replace(/\//g, " "));
|
|
260
|
+
}
|
|
261
|
+
if (name.includes("-")) {
|
|
262
|
+
const spaced = name.replace(/^@/, "").replace(/\//g, " ").replace(/-/g, " ");
|
|
263
|
+
variants.add(spaced);
|
|
264
|
+
}
|
|
265
|
+
variants.delete(name);
|
|
266
|
+
return [...variants];
|
|
267
|
+
}
|
|
268
|
+
function expandRepoName(repoUrl) {
|
|
269
|
+
const variants = /* @__PURE__ */ new Set();
|
|
270
|
+
const repoName = repoUrl.startsWith("http") ? repoUrl.split("/").pop() : repoUrl.split("/").pop();
|
|
271
|
+
if (!repoName) return [];
|
|
272
|
+
variants.add(repoName);
|
|
273
|
+
if (repoName.includes("-")) variants.add(repoName.replace(/-/g, " "));
|
|
274
|
+
return [...variants];
|
|
275
|
+
}
|
|
276
|
+
function generateFrontmatter({ name, version, description: pkgDescription, globs, body, generatedBy, dirName, packages, repoUrl }) {
|
|
277
|
+
const patterns = globs ?? getFilePatterns(name);
|
|
278
|
+
const globHint = patterns?.length ? ` or working with ${patterns.join(", ")} files` : "";
|
|
279
|
+
const rawDesc = pkgDescription?.replace(/[<>]/g, "").replace(/\.?\s*$/, "");
|
|
280
|
+
const cleanDesc = rawDesc && rawDesc.length > 200 ? `${rawDesc.slice(0, 197)}...` : rawDesc;
|
|
281
|
+
const editHint = globHint ? `editing${globHint} or code importing` : "writing code importing";
|
|
282
|
+
let desc;
|
|
283
|
+
if (packages && packages.length > 1) {
|
|
284
|
+
const importList = packages.map((p) => `"${p.name}"`).join(", ");
|
|
285
|
+
const allKeywords = /* @__PURE__ */ new Set();
|
|
286
|
+
for (const pkg of packages) {
|
|
287
|
+
allKeywords.add(pkg.name);
|
|
288
|
+
for (const kw of expandPackageName(pkg.name)) allKeywords.add(kw);
|
|
289
|
+
}
|
|
290
|
+
const keywordList = [...allKeywords].join(", ");
|
|
291
|
+
desc = `${cleanDesc ? `${cleanDesc}. ` : ""}ALWAYS use when ${editHint} ${importList}. Consult for debugging, best practices, or modifying ${keywordList}.`;
|
|
292
|
+
} else {
|
|
293
|
+
const allKeywords = /* @__PURE__ */ new Set();
|
|
294
|
+
allKeywords.add(name);
|
|
295
|
+
for (const kw of expandPackageName(name)) allKeywords.add(kw);
|
|
296
|
+
if (repoUrl) for (const kw of expandRepoName(repoUrl)) allKeywords.add(kw);
|
|
297
|
+
const nameList = [...allKeywords].join(", ");
|
|
298
|
+
desc = `${cleanDesc ? `${cleanDesc}. ` : ""}ALWAYS use when ${editHint} "${name}". Consult for debugging, best practices, or modifying ${nameList}.`;
|
|
299
|
+
}
|
|
300
|
+
if (desc.length > 1024) desc = `${desc.slice(0, 1021)}...`;
|
|
301
|
+
const lines = [
|
|
302
|
+
"---",
|
|
303
|
+
`name: ${dirName ?? computeSkillDirName(name)}`,
|
|
304
|
+
`description: ${yamlEscape(desc)}`
|
|
305
|
+
];
|
|
306
|
+
const metaEntries = [];
|
|
307
|
+
if (version) metaEntries.push(` version: ${yamlEscape(version)}`);
|
|
308
|
+
if (body && generatedBy) metaEntries.push(` generated_by: ${yamlEscape(generatedBy)}`);
|
|
309
|
+
metaEntries.push(` generated_at: ${todayIsoDate()}`);
|
|
310
|
+
if (metaEntries.length) {
|
|
311
|
+
lines.push("metadata:");
|
|
312
|
+
lines.push(...metaEntries);
|
|
313
|
+
}
|
|
314
|
+
lines.push("---", "", "");
|
|
315
|
+
return lines.join("\n");
|
|
316
|
+
}
|
|
317
|
+
function generateSearchBlock(name) {
|
|
318
|
+
const cmd = resolveSkilldCommand();
|
|
319
|
+
return `## Search
|
|
320
|
+
|
|
321
|
+
Use \`${cmd} search "query" -p ${name}\` instead of grepping \`.skilld/\` directories. Run \`${cmd} search --guide -p ${name}\` for full syntax, filters, and operators.`;
|
|
322
|
+
}
|
|
323
|
+
function generateFooter(relatedSkills) {
|
|
324
|
+
if (relatedSkills.length === 0) return "";
|
|
325
|
+
return `\nRelated: ${relatedSkills.join(", ")}\n`;
|
|
326
|
+
}
|
|
327
|
+
export { timedSpinner as _, installSkillForAgents as a, unlinkSkillFromAgents as c, formatSnippet as d, formatSource as f, timeAgo as g, scoreLabel as h, computeSkillDirName as i, formatCompactSnippet as l, normalizeScores as m, writeGeneratedSkillMd as n, linkSkillToAgents as o, highlightTerms as p, writeSkillMd as r, sanitizeName as s, generateSkillMd as t, formatDuration as u, todayIsoDate as v };
|
|
328
|
+
|
|
329
|
+
//# sourceMappingURL=skill.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.mjs","names":["agents"],"sources":["../../src/core/formatting.ts","../../src/agent/install.ts","../../src/agent/prompts/skill.ts"],"sourcesContent":["import type { SearchSnippet } from '../retriv/index.ts'\nimport type { ProjectState } from './skills.ts'\nimport * as p from '@clack/prompts'\n\nexport function todayIsoDate(): string {\n return new Date().toISOString().split('T')[0]!\n}\n\nexport function timeAgo(iso?: string): string {\n if (!iso)\n return ''\n const diff = Date.now() - new Date(iso).getTime()\n const days = Math.floor(diff / 86400000)\n if (days <= 0)\n return 'today'\n if (days === 1)\n return '1d ago'\n if (days < 7)\n return `${days}d ago`\n if (days < 30)\n return `${Math.floor(days / 7)}w ago`\n return `${Math.floor(days / 30)}mo ago`\n}\n\nexport function formatSource(source?: string): string {\n if (!source)\n return ''\n if (source === 'shipped')\n return 'shipped'\n if (source.includes('llms.txt'))\n return 'llms.txt'\n if (source.includes('github.com'))\n return source.replace(/https?:\\/\\/github\\.com\\//, '')\n return source\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000)\n return `${Math.round(ms)}ms`\n return `${(ms / 1000).toFixed(1)}s`\n}\n\n/** Spinner wrapper that shows elapsed time via built-in timer indicator */\nexport function timedSpinner() {\n const spin = p.spinner({ indicator: 'timer' })\n return {\n start(msg: string) {\n spin.start(msg)\n },\n message(msg: string) {\n spin.message(msg)\n },\n stop(msg: string) {\n spin.stop(msg)\n },\n }\n}\n\nexport function formatSkillStatus(state: ProjectState): void {\n const { missing, outdated, synced } = state\n\n if (synced.length > 0)\n p.log.success(`${synced.length} synced`)\n if (outdated.length > 0)\n p.log.warn(`${outdated.length} outdated: ${outdated.map(s => s.name).join(', ')}`)\n if (missing.length > 0)\n p.log.info(`${missing.length} missing: ${missing.slice(0, 5).join(', ')}${missing.length > 5 ? '...' : ''}`)\n}\n\nexport function highlightTerms(content: string, terms: string[]): string {\n if (terms.length === 0)\n return content\n // Sort by length desc to match longer terms first\n const sorted = terms.toSorted((a, b) => b.length - a.length)\n const pattern = new RegExp(`(${sorted.map(t => t.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})`, 'gi')\n return content.replace(pattern, '\\x1B[33m$1\\x1B[0m')\n}\n\n/** Format a normalized score (0-100) with color */\nexport function scoreLabel(pct: number): string {\n const color = pct >= 70 ? '\\x1B[32m' : pct >= 40 ? '\\x1B[33m' : '\\x1B[90m'\n return `${color}${pct}%\\x1B[0m`\n}\n\n/** Normalize raw cosine similarity scores to 0-100 relative to the best match */\nexport function normalizeScores(results: SearchSnippet[]): Map<SearchSnippet, number> {\n const map = new Map<SearchSnippet, number>()\n const max = results.reduce((m, r) => Math.max(m, r.score), 0)\n for (const r of results)\n map.set(r, max > 0 ? Math.round((r.score / max) * 100) : 0)\n return map\n}\n\nexport function formatSnippet(r: SearchSnippet, versions?: Map<string, string>, pct?: number): string {\n const refPath = `.claude/skills/${r.package}/.skilld/${r.source}`\n const lineRange = r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`\n const score = pct != null ? scoreLabel(pct) : `\\x1B[90m${r.score.toFixed(2)}\\x1B[0m`\n const version = versions?.get(r.package)\n const pkgLabel = version ? `${r.package}@${version}` : r.package\n\n const scopeStr = r.scope?.length ? `${r.scope.map(e => e.name).join('.')} → ` : ''\n const entityStr = r.entities?.map(e => e.signature || `${e.type} ${e.name}`).join(', ')\n const highlighted = highlightTerms(r.content, r.highlights)\n\n return [\n `${pkgLabel} ${score}${entityStr ? ` \\x1B[36m${scopeStr}${entityStr}\\x1B[0m` : ''}`,\n `\\x1B[90m${refPath}:${lineRange}\\x1B[0m`,\n ` ${highlighted.replace(/\\n/g, '\\n ')}`,\n ].join('\\n')\n}\n\n/** Compact 2-line format for interactive search list */\nexport function formatCompactSnippet(r: SearchSnippet, cols: number): { title: string, path: string, preview: string } {\n const entityStr = r.entities?.length\n ? r.entities.map(e => e.signature || e.name).join(', ')\n : ''\n const scopeStr = r.scope?.length ? `${r.scope.map(e => e.name).join('.')} → ` : ''\n const title = entityStr ? `${scopeStr}${entityStr}` : r.source.split('/').pop() || r.source\n\n const refPath = `.claude/skills/${r.package}/.skilld/${r.source}`\n const lineRange = r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`\n const path = `${refPath}:${lineRange}`\n\n // First meaningful line as preview (skip empty, frontmatter delimiters, headings-only)\n const maxPreview = cols - 6\n const firstLine = r.content.split('\\n').find(l => l.trim() && l.trim() !== '---' && !/^#+\\s*$/.test(l.trim())) || ''\n const preview = firstLine.length > maxPreview ? `${firstLine.slice(0, maxPreview - 1)}…` : firstLine\n\n return { title, path, preview }\n}\n","/**\n * Skill installation - write skills to agent directories\n */\n\nimport type { AgentType } from './types.ts'\nimport { existsSync, lstatSync, mkdirSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { join, relative } from 'pathe'\nimport { repairMarkdown, sanitizeMarkdown } from '../core/sanitize.ts'\nimport { detectInstalledAgents } from './detect.ts'\nimport { agents } from './registry.ts'\n\n/**\n * Sanitize skill name for filesystem\n */\nexport function sanitizeName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9._]+/g, '-')\n .replace(/^[.\\-]+|[.\\-]+$/g, '')\n .slice(0, 255) || 'unnamed-skill'\n}\n\n/**\n * Compute skill directory name from package name with -skilld suffix.\n * No collisions for monorepo packages (each gets a unique name).\n *\n * Examples:\n * vue → vue-skilld\n * @unhead/vue → unhead-vue-skilld\n * @unhead/react → unhead-react-skilld\n */\nexport function computeSkillDirName(packageName: string): string {\n return `${sanitizeName(packageName)}-skilld`\n}\n\n/**\n * Install a skill directly to agent skill directories.\n * When agents are explicitly specified, creates directories as needed.\n * When falling back to auto-detection, only writes to agents whose skills dir already exists.\n */\nexport function installSkillForAgents(\n skillName: string,\n skillContent: string,\n options: {\n global?: boolean\n cwd?: string\n agents?: AgentType[]\n /** Additional files to write (filename -> content) */\n files?: Record<string, string>\n } = {},\n): { installed: AgentType[], skipped: Array<{ agent: AgentType, reason: string }>, paths: string[] } {\n const isGlobal = options.global ?? false\n const cwd = options.cwd || process.cwd()\n const sanitized = sanitizeName(skillName)\n const explicit = !!options.agents\n const targetAgents = options.agents || detectInstalledAgents()\n\n const installed: AgentType[] = []\n const skipped: Array<{ agent: AgentType, reason: string }> = []\n const paths: string[] = []\n // Track directories already written to, so agents that also scan those dirs\n // (via additionalSkillsDirs) don't get duplicate skills\n const writtenDirs = new Set<string>()\n\n for (const agentType of targetAgents) {\n const agent = agents[agentType]\n\n // Skip if agent doesn't support global installation\n if (isGlobal && !agent.globalSkillsDir) {\n skipped.push({ agent: agentType, reason: 'no global support' })\n continue\n }\n\n const baseDir = isGlobal ? agent.globalSkillsDir! : join(cwd, agent.skillsDir)\n\n // Auto-detected agents: only write if their skills dir already exists\n if (!explicit && !existsSync(baseDir)) {\n skipped.push({ agent: agentType, reason: 'skills dir not found' })\n continue\n }\n\n // Skip if this agent already reads a directory we've written to\n // (prevents duplicate skills in agents that scan multiple dirs)\n if (isGlobal && (writtenDirs.has(baseDir) || agent.additionalSkillsDirs.some(d => writtenDirs.has(d)))) {\n skipped.push({ agent: agentType, reason: 'already covered by another agent dir' })\n continue\n }\n\n const skillDir = join(baseDir, sanitized)\n const skilldDir = join(skillDir, '.skilld')\n mkdirSync(skilldDir, { recursive: true })\n writeFileSync(join(skilldDir, '_SKILL.md'), sanitizeMarkdown(repairMarkdown(skillContent)))\n\n if (options.files) {\n for (const [filename, content] of Object.entries(options.files)) {\n writeFileSync(join(skillDir, filename), filename.endsWith('.md') ? sanitizeMarkdown(repairMarkdown(content)) : content)\n }\n }\n\n installed.push(agentType)\n paths.push(skillDir)\n writtenDirs.add(baseDir)\n }\n\n return { installed, skipped, paths }\n}\n\n/**\n * Create a relative symlink from the target agent's skills dir to the shared .skills/ dir.\n * Only creates directories for the explicit target agent; other agents must already have\n * their skills dir present. This prevents skilld from polluting projects with dirs\n * for agents the user doesn't use (e.g. .gemini/, .agent/).\n */\nexport function linkSkillToAgents(skillName: string, sharedDir: string, cwd: string, agentType?: AgentType): void {\n const targetAgents = agentType ? [[agentType, agents[agentType]] as const] : Object.entries(agents)\n const linkedDirs = new Set<string>()\n\n for (const [type, agent] of targetAgents) {\n const agentSkillsDir = join(cwd, agent.skillsDir)\n const isTarget = agentType === type\n\n if (isTarget) {\n // Target agent: create skills dir if needed\n mkdirSync(agentSkillsDir, { recursive: true })\n }\n else {\n // Non-target agent: only link if skills dir already exists, never create\n if (!existsSync(agentSkillsDir))\n continue\n // Skip if this agent already reads a directory we've linked to\n const resolvedAdditional = agent.additionalSkillsDirs.map(d => join(cwd, d))\n if (resolvedAdditional.some(d => linkedDirs.has(d))) {\n // Clean stale symlinks before skipping\n const staleTarget = join(agentSkillsDir, skillName)\n try {\n if (lstatSync(staleTarget).isSymbolicLink() && !existsSync(staleTarget))\n unlinkSync(staleTarget)\n }\n catch {}\n continue\n }\n }\n\n const target = join(agentSkillsDir, skillName)\n\n // Check what's at the target path\n let isSymlink = false\n let targetExists = false\n try {\n const stat = lstatSync(target)\n targetExists = true\n isSymlink = stat.isSymbolicLink()\n }\n catch {}\n\n // Skip real directories (user's custom skills, not managed by us)\n if (targetExists && !isSymlink)\n continue\n\n // Remove existing symlink (including dangling)\n if (isSymlink)\n unlinkSync(target)\n\n const source = join(sharedDir, skillName)\n const rel = relative(agentSkillsDir, source)\n symlinkSync(rel, target)\n linkedDirs.add(agentSkillsDir)\n }\n}\n\n/**\n * Remove per-agent symlinks for a skill when removing from shared dir.\n */\nexport function unlinkSkillFromAgents(skillName: string, cwd: string, agentType?: AgentType): void {\n const targetAgents = agentType ? [[agentType, agents[agentType]] as const] : Object.entries(agents)\n\n for (const [, agent] of targetAgents) {\n const target = join(cwd, agent.skillsDir, skillName)\n try {\n if (lstatSync(target).isSymbolicLink())\n unlinkSync(target)\n }\n catch {}\n }\n}\n","/**\n * SKILL.md file generation\n */\n\nimport type { FeaturesConfig } from '../../core/config.ts'\nimport { writeFileSync } from 'node:fs'\nimport { join } from 'pathe'\nimport { todayIsoDate } from '../../core/formatting.ts'\nimport { repairMarkdown, sanitizeMarkdown } from '../../core/sanitize.ts'\nimport { resolveSkilldCommand } from '../../core/shared.ts'\nimport { yamlEscape } from '../../core/yaml.ts'\nimport { getFilePatterns } from '../../sources/package-registry.ts'\nimport { computeSkillDirName } from '../install.ts'\n\nexport interface SkillOptions {\n name: string\n version?: string\n releasedAt?: string\n /** npm dist-tags with version and release date */\n distTags?: Record<string, { version: string, releasedAt?: string }>\n globs?: string[]\n description?: string\n /** LLM-generated body — replaces default heading + description */\n body?: string\n relatedSkills: string[]\n hasIssues?: boolean\n hasDiscussions?: boolean\n hasReleases?: boolean\n hasChangelog?: string | false\n docsType?: 'llms.txt' | 'readme' | 'docs'\n hasShippedDocs?: boolean\n /** Key files in package (entry points + docs) */\n pkgFiles?: string[]\n /** Model used to generate LLM sections */\n generatedBy?: string\n /** Override directory name for frontmatter (repo-based, e.g. \"vuejs-core\") */\n dirName?: string\n /** All packages tracked by this skill (multi-package skills) */\n packages?: Array<{ name: string }>\n /** GitHub repo URL (owner/repo format or full URL) */\n repoUrl?: string\n /** Resolved feature flags */\n features?: FeaturesConfig\n /** Eject mode: use ./references/ paths instead of ./.skilld/ for portable skills */\n eject?: boolean\n}\n\nexport function writeSkillMd(skillDir: string, content: string): void {\n writeFileSync(join(skillDir, 'SKILL.md'), content)\n}\n\nexport function writeGeneratedSkillMd(skillDir: string, opts: SkillOptions): string {\n const content = generateSkillMd(opts)\n writeSkillMd(skillDir, content)\n return content\n}\n\nexport function generateSkillMd(opts: SkillOptions): string {\n const header = generatePackageHeader(opts)\n const search = !opts.eject && opts.features?.search !== false ? generateSearchBlock(opts.name) : ''\n // Eject mode: rewrite .skilld/ paths to ./references/ in LLM-generated body\n // Then strip [source](./references/pkg/...) links since pkg/ is not ejected\n let body = opts.body\n if (body && opts.eject) {\n body = body.replace(/\\.\\/\\.skilld\\//g, './references/')\n body = body.replace(/\\s*\\[source\\]\\(\\.\\/references\\/pkg\\/[^)]*\\)/gi, '')\n }\n const content = body\n ? search ? `${header}\\n\\n${search}\\n\\n${body}` : `${header}\\n\\n${body}`\n : search ? `${header}\\n\\n${search}` : header\n const footer = generateFooter(opts.relatedSkills)\n return sanitizeMarkdown(repairMarkdown(`${generateFrontmatter(opts)}${content}\\n${footer}`))\n}\n\n/** Format ISO date as short absolute date: \"Jan 2025\", \"Dec 2024\" */\nfunction formatShortDate(isoDate: string): string {\n const date = new Date(isoDate)\n if (Number.isNaN(date.getTime()))\n return ''\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n return `${months[date.getUTCMonth()]} ${date.getUTCFullYear()}`\n}\n\nfunction generatePackageHeader({ name, version, distTags, repoUrl, hasIssues, hasDiscussions, hasReleases, docsType, pkgFiles, packages, eject }: SkillOptions): string {\n const versionSuffix = version ? `@${version}` : ''\n let title = `# ${name}${versionSuffix}`\n if (repoUrl) {\n const url = repoUrl.startsWith('http') ? repoUrl : `https://github.com/${repoUrl}`\n const repoName = repoUrl.startsWith('http') ? repoUrl.split('/').slice(-2).join('/') : repoUrl\n title = `# [${repoName}](${url}) \\`${name}${versionSuffix}\\``\n }\n const lines: string[] = [title]\n\n if (distTags && Object.keys(distTags).length > 0) {\n const tags = Object.entries(distTags)\n .sort(([, a], [, b]) => (b.releasedAt ?? '').localeCompare(a.releasedAt ?? ''))\n .slice(0, 3)\n .map(([tag, info]) => {\n const relDate = info.releasedAt ? ` (${formatShortDate(info.releasedAt)})` : ''\n return `${tag}: ${info.version}${relDate}`\n })\n .join(', ')\n lines.push(`**Tags:** ${tags}`)\n }\n\n // References with context hints (progressive disclosure — describe what each contains)\n lines.push('')\n const refBase = eject ? './references' : './.skilld'\n const refs: string[] = []\n if (!eject) {\n refs.push(`[package.json](${refBase}/pkg/package.json)`)\n if (packages && packages.length > 1) {\n for (const pkg of packages) {\n const shortName = pkg.name.split('/').pop()!.toLowerCase()\n refs.push(`[pkg-${shortName}](${refBase}/pkg-${shortName}/package.json)`)\n }\n }\n if (pkgFiles?.includes('README.md'))\n refs.push(`[README](${refBase}/pkg/README.md)`)\n }\n if (docsType && docsType !== 'readme')\n refs.push(`[Docs](${refBase}/docs/_INDEX.md)`)\n if (hasIssues)\n refs.push(`[Issues](${refBase}/issues/_INDEX.md)`)\n if (hasDiscussions)\n refs.push(`[Discussions](${refBase}/discussions/_INDEX.md)`)\n if (hasReleases)\n refs.push(`[Releases](${refBase}/releases/_INDEX.md)`)\n\n if (refs.length > 0)\n lines.push(`**References:** ${refs.join(' • ')}`)\n\n return lines.join('\\n')\n}\n\n/**\n * Expand a package name into keyword variants for better trigger matching.\n * e.g. \"@nuxt/ui\" → [\"nuxt ui\", \"nuxt/ui\"], \"vue-router\" → [\"vue router\"]\n */\nfunction expandPackageName(name: string): string[] {\n const variants = new Set<string>()\n // Strip scope for matching: @nuxt/ui → nuxt/ui → nuxt ui\n const unscoped = name.replace(/^@/, '')\n if (unscoped !== name) {\n variants.add(unscoped) // nuxt/ui\n variants.add(unscoped.replace(/\\//g, ' ')) // nuxt ui\n }\n // Hyphen → space: vue-router → vue router\n if (name.includes('-')) {\n const spaced = name.replace(/^@/, '').replace(/\\//g, ' ').replace(/-/g, ' ')\n variants.add(spaced)\n }\n // Remove the original name itself from variants (it's already in the description)\n variants.delete(name)\n return [...variants]\n}\n\n/**\n * Extract and expand GitHub repo name into keyword variants.\n * e.g. \"motion-v\" → [\"motion-v\", \"motion v\"]\n */\nfunction expandRepoName(repoUrl: string): string[] {\n const variants = new Set<string>()\n // Extract repo name from URL or owner/repo format\n const repoName = repoUrl.startsWith('http')\n ? repoUrl.split('/').pop()!\n : repoUrl.split('/').pop()!\n\n if (!repoName)\n return []\n\n variants.add(repoName) // motion-v\n // Hyphen → space: motion-v → motion v\n if (repoName.includes('-')) {\n variants.add(repoName.replace(/-/g, ' '))\n }\n return [...variants]\n}\n\nfunction generateFrontmatter({ name, version, description: pkgDescription, globs, body, generatedBy, dirName, packages, repoUrl }: SkillOptions): string {\n const patterns = globs ?? getFilePatterns(name)\n const globHint = patterns?.length ? ` or working with ${patterns.join(', ')} files` : ''\n\n // Strip angle brackets from npm description (forbidden in frontmatter per Agent Skills spec)\n // Cap at 200 chars so the npm description doesn't crowd out our triggering prompt\n const rawDesc = pkgDescription?.replace(/[<>]/g, '').replace(/\\.?\\s*$/, '')\n const cleanDesc = rawDesc && rawDesc.length > 200 ? `${rawDesc.slice(0, 197)}...` : rawDesc\n\n const editHint = globHint\n ? `editing${globHint} or code importing`\n : 'writing code importing'\n\n // Structure: [What it does] + [When to use it] + [Key capabilities]\n let desc: string\n if (packages && packages.length > 1) {\n const importList = packages.map(p => `\"${p.name}\"`).join(', ')\n const allKeywords = new Set<string>()\n for (const pkg of packages) {\n allKeywords.add(pkg.name)\n for (const kw of expandPackageName(pkg.name))\n allKeywords.add(kw)\n }\n const keywordList = [...allKeywords].join(', ')\n const what = cleanDesc ? `${cleanDesc}. ` : ''\n desc = `${what}ALWAYS use when ${editHint} ${importList}. Consult for debugging, best practices, or modifying ${keywordList}.`\n }\n else {\n const allKeywords = new Set<string>()\n allKeywords.add(name)\n for (const kw of expandPackageName(name))\n allKeywords.add(kw)\n if (repoUrl) {\n for (const kw of expandRepoName(repoUrl))\n allKeywords.add(kw)\n }\n const nameList = [...allKeywords].join(', ')\n const what = cleanDesc ? `${cleanDesc}. ` : ''\n desc = `${what}ALWAYS use when ${editHint} \"${name}\". Consult for debugging, best practices, or modifying ${nameList}.`\n }\n\n // Enforce 1024 char limit (Agent Skills spec)\n if (desc.length > 1024)\n desc = `${desc.slice(0, 1021)}...`\n\n const lines = [\n '---',\n `name: ${dirName ?? computeSkillDirName(name)}`,\n `description: ${yamlEscape(desc)}`,\n ]\n // version and generated_by go under metadata per Agent Skills spec\n const metaEntries: string[] = []\n if (version)\n metaEntries.push(` version: ${yamlEscape(version)}`)\n if (body && generatedBy)\n metaEntries.push(` generated_by: ${yamlEscape(generatedBy)}`)\n metaEntries.push(` generated_at: ${todayIsoDate()}`)\n if (metaEntries.length) {\n lines.push('metadata:')\n lines.push(...metaEntries)\n }\n lines.push('---', '', '')\n return lines.join('\\n')\n}\n\nfunction generateSearchBlock(name: string): string {\n const cmd = resolveSkilldCommand()\n\n return `## Search\n\nUse \\`${cmd} search \"query\" -p ${name}\\` instead of grepping \\`.skilld/\\` directories. Run \\`${cmd} search --guide -p ${name}\\` for full syntax, filters, and operators.`\n}\n\nfunction generateFooter(relatedSkills: string[]): string {\n if (relatedSkills.length === 0)\n return ''\n return `\\nRelated: ${relatedSkills.join(', ')}\\n`\n}\n"],"mappings":"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"}
|
package/dist/_chunks/skills.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import "./agent.mjs";
|
|
1
2
|
import { t as getShippedSkills } from "./prepare.mjs";
|
|
2
3
|
import "./cache.mjs";
|
|
3
|
-
import { s as readLocalDependencies } from "./sources.mjs";
|
|
4
4
|
import { n as getSharedSkillsDir, o as semverGt, s as semverValid } from "./shared.mjs";
|
|
5
|
+
import { s as readLocalDependencies } from "./sources.mjs";
|
|
5
6
|
import { a as targets } from "./detect.mjs";
|
|
6
|
-
import "./
|
|
7
|
-
import { i as readLock, n as parsePackages, r as parseSkillFrontmatter } from "./lockfile.mjs";
|
|
7
|
+
import { a as readLock, i as parseSkillFrontmatter, r as parsePackages } from "./lockfile.mjs";
|
|
8
8
|
import { join } from "pathe";
|
|
9
9
|
import { existsSync, readdirSync } from "node:fs";
|
|
10
10
|
function* iterateSkills(opts = {}) {
|
package/dist/_chunks/sources.mjs
CHANGED
|
@@ -2,8 +2,7 @@ import { t as getCacheDir } from "./version.mjs";
|
|
|
2
2
|
import { i as readPackageJsonSafe } from "./package-json.mjs";
|
|
3
3
|
import { t as yamlEscape } from "./yaml.mjs";
|
|
4
4
|
import { i as parseFrontmatter, n as extractLinks, r as extractTitle, t as extractDescription } from "./markdown.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { r as mapInsert } from "./shared.mjs";
|
|
5
|
+
import { c as getBlogPreset, l as getCrawlUrl, r as mapInsert, u as getDocOverride } from "./shared.mjs";
|
|
7
6
|
import { tmpdir } from "node:os";
|
|
8
7
|
import { basename, dirname, join, resolve } from "pathe";
|
|
9
8
|
import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
@@ -222,6 +221,11 @@ function parseGitHubUrl(url) {
|
|
|
222
221
|
repo: match[2]
|
|
223
222
|
};
|
|
224
223
|
}
|
|
224
|
+
function parseGitHubRepoSlug(url) {
|
|
225
|
+
if (!url) return void 0;
|
|
226
|
+
const parsed = parseGitHubUrl(url);
|
|
227
|
+
return parsed ? `${parsed.owner}/${parsed.repo}` : void 0;
|
|
228
|
+
}
|
|
225
229
|
function normalizeRepoUrl(url) {
|
|
226
230
|
return url.replace(/^git\+/, "").replace(/#.*$/, "").replace(/\.git$/, "").replace(/^git:\/\//, "https://").replace(/^ssh:\/\/git@github\.com/, "https://github.com").replace(/^git@github\.com:/, "https://github.com/");
|
|
227
231
|
}
|
|
@@ -2456,6 +2460,6 @@ function getInstalledSkillVersion(skillDir) {
|
|
|
2456
2460
|
if (!existsSync(skillPath)) return null;
|
|
2457
2461
|
return readFileSync(skillPath, "utf-8").match(/^version:\s*"?([^"\n]+)"?/m)?.[1] || null;
|
|
2458
2462
|
}
|
|
2459
|
-
export { fetchText as $, filterFrameworkDocs as A, fetchGitHubIssues as B, toCrawlPattern as C, fetchGitHubRepoMeta as D, fetchGitDocs as E, extractSections as F, compareSemver as G, generateIssueIndex as H, fetchLlmsTxt as I, isPrerelease as J, fetchReleaseNotes as K, fetchLlmsUrl as L, resolveGitHubRepo as M, validateGitDocsWithLlms as N, fetchReadme as O, downloadLlmsDocs as P, fetchGitHubRaw as Q, normalizeLlmsLinks as R, fetchCrawledDocs as S, MIN_GIT_DOCS as T, isGhAvailable as U, formatIssueAsMarkdown as V, fetchBlogReleases as W, $fetch as X, parseSemver as Y, extractBranchHint as Z, resolveEntryFiles as _, getInstalledSkillVersion as a, formatDiscussionAsMarkdown as b, readLocalPackageInfo as c, resolvePackageDocs as d, isGitHubRepoUrl as et, resolvePackageDocsWithAttempts as f, parseSkillFrontmatterName as g, parseGitSkillInput as h, fetchPkgDist as i,
|
|
2463
|
+
export { fetchText as $, filterFrameworkDocs as A, fetchGitHubIssues as B, toCrawlPattern as C, fetchGitHubRepoMeta as D, fetchGitDocs as E, extractSections as F, compareSemver as G, generateIssueIndex as H, fetchLlmsTxt as I, isPrerelease as J, fetchReleaseNotes as K, fetchLlmsUrl as L, resolveGitHubRepo as M, validateGitDocsWithLlms as N, fetchReadme as O, downloadLlmsDocs as P, fetchGitHubRaw as Q, normalizeLlmsLinks as R, fetchCrawledDocs as S, MIN_GIT_DOCS as T, isGhAvailable as U, formatIssueAsMarkdown as V, fetchBlogReleases as W, $fetch as X, parseSemver as Y, extractBranchHint as Z, resolveEntryFiles as _, getInstalledSkillVersion as a, verifyUrl as at, formatDiscussionAsMarkdown as b, readLocalPackageInfo as c, resolvePackageDocs as d, isGitHubRepoUrl as et, resolvePackageDocsWithAttempts as f, parseSkillFrontmatterName as g, parseGitSkillInput as h, fetchPkgDist as i, parsePackageSpec as it, isShallowGitDocs as j, fetchReadmeContent as k, resolveInstalledVersion as l, fetchGitSkills as m, fetchNpmPackage as n, parseGitHubRepoSlug as nt, parseVersionSpecifier as o, searchNpmPackages as p, generateReleaseIndex as q, fetchNpmRegistryMeta as r, parseGitHubUrl as rt, readLocalDependencies as s, fetchLatestVersion as t, normalizeRepoUrl as tt, resolveLocalPackageDocs as u, generateDocsIndex as v, resolveCrateDocsWithAttempts as w, generateDiscussionIndex as x, fetchGitHubDiscussions as y, parseMarkdownLinks as z };
|
|
2460
2464
|
|
|
2461
2465
|
//# sourceMappingURL=sources.mjs.map
|