skilld 1.0.1 → 1.1.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/README.md +45 -21
- package/dist/_chunks/agent.mjs +8 -7
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/assemble.mjs +134 -0
- package/dist/_chunks/assemble.mjs.map +1 -0
- package/dist/_chunks/detect.mjs +737 -0
- package/dist/_chunks/detect.mjs.map +1 -0
- package/dist/_chunks/formatting.mjs +25 -294
- package/dist/_chunks/formatting.mjs.map +1 -1
- package/dist/_chunks/install.mjs +34 -10
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/list.mjs +3 -1
- package/dist/_chunks/list.mjs.map +1 -1
- package/dist/_chunks/pool.mjs +113 -176
- package/dist/_chunks/pool.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +64 -735
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/sanitize.mjs +2 -2
- package/dist/_chunks/sanitize.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +3 -1
- package/dist/_chunks/search-interactive.mjs.map +1 -1
- package/dist/_chunks/search.mjs +3 -1
- package/dist/_chunks/search2.mjs +180 -0
- package/dist/_chunks/search2.mjs.map +1 -0
- package/dist/_chunks/skills.mjs +292 -0
- package/dist/_chunks/skills.mjs.map +1 -0
- package/dist/_chunks/sync.mjs +298 -25
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/sync2.mjs +4 -2
- package/dist/_chunks/uninstall.mjs +6 -4
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/_chunks/validate.mjs +2 -1
- package/dist/_chunks/validate.mjs.map +1 -1
- package/dist/agent/index.d.mts +29 -6
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +4 -3
- package/dist/cli.mjs +24 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/retriv/index.mjs +1 -1
- package/dist/retriv/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/_chunks/pool2.mjs +0 -115
- package/dist/_chunks/pool2.mjs.map +0 -1
package/dist/_chunks/sync.mjs
CHANGED
|
@@ -5,11 +5,13 @@ import { i as parseFrontmatter } from "./markdown.mjs";
|
|
|
5
5
|
import { SearchDepsUnavailableError, createIndex } from "../retriv/index.mjs";
|
|
6
6
|
import { d as getPrereleaseChangelogRef, n as getSharedSkillsDir, o as getBlogPreset, t as SHARED_SKILLS_DIR } from "./shared.mjs";
|
|
7
7
|
import { $ as fetchGitHubIssues, A as parseGitSkillInput, C as downloadLlmsDocs, D as normalizeLlmsLinks, F as formatDiscussionAsMarkdown, G as $fetch, H as generateReleaseIndex, I as generateDiscussionIndex, L as fetchCrawledDocs, M as resolveEntryFiles, N as generateDocsIndex, P as fetchGitHubDiscussions, R as toCrawlPattern, T as fetchLlmsTxt, U as isPrerelease, V as fetchReleaseNotes, X as parseGitHubUrl, Z as parsePackageSpec, b as isShallowGitDocs, et as formatIssueAsMarkdown, f as resolvePackageDocsWithAttempts, h as fetchGitDocs, i as fetchPkgDist, k as fetchGitSkills, n as fetchNpmPackage, nt as isGhAvailable, p as searchNpmPackages, s as readLocalDependencies, tt as generateIssueIndex, u as resolveLocalPackageDocs, v as fetchReadmeContent, x as resolveGitHubRepo, y as filterFrameworkDocs, z as fetchBlogReleases } from "./sources.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import { a as
|
|
10
|
-
import {
|
|
8
|
+
import { a as targets } from "./detect.mjs";
|
|
9
|
+
import { a as sanitizeName, c as SECTION_OUTPUT_FILES, g as maxLines, h as maxItems, i as linkSkillToAgents, l as buildAllSectionPrompts, n as computeSkillDirName, p as portabilizePrompt, t as generateSkillMd } from "./prompts.mjs";
|
|
10
|
+
import { a as getModelLabel, i as getAvailableModels, o as getModelName, r as createToolProgress, s as optimizeDocs, t as detectImportedPackages } from "./agent.mjs";
|
|
11
|
+
import { C as hasCompletedWizard, E as registerProject, O as updateConfig, T as readConfig, d as getInstalledGenerators, h as promptForAgent, l as timedSpinner, m as isInteractive, n as formatDuration, p as introLine, v as resolveAgent, x as defaultFeatures, y as sharedArgs } from "./formatting.mjs";
|
|
12
|
+
import { o as parsePackages, s as readLock, t as getProjectState, u as writeLock } from "./skills.mjs";
|
|
11
13
|
import { t as runWizard } from "../cli.mjs";
|
|
12
|
-
import { n as shutdownWorker } from "./
|
|
14
|
+
import { n as shutdownWorker } from "./pool.mjs";
|
|
13
15
|
import { dirname, join, relative, resolve } from "pathe";
|
|
14
16
|
import { appendFileSync, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
15
17
|
import { isCI } from "std-env";
|
|
@@ -17,6 +19,8 @@ import pLimit from "p-limit";
|
|
|
17
19
|
import * as p from "@clack/prompts";
|
|
18
20
|
import { defineCommand } from "citty";
|
|
19
21
|
import logUpdate from "log-update";
|
|
22
|
+
/** Max docs sent to the embedding pipeline to prevent oversized indexes */
|
|
23
|
+
const MAX_INDEX_DOCS = 250;
|
|
20
24
|
const RESOLVE_STEP_LABELS = {
|
|
21
25
|
"npm": "npm registry",
|
|
22
26
|
"github-docs": "GitHub docs",
|
|
@@ -322,7 +326,7 @@ async function fetchAndCacheResources(opts) {
|
|
|
322
326
|
if (resolved.docsUrl && !cachedDocs.some((d) => d.path.startsWith("docs/"))) {
|
|
323
327
|
const crawlPattern = resolved.crawlUrl || toCrawlPattern(resolved.docsUrl);
|
|
324
328
|
onProgress("Crawling docs site");
|
|
325
|
-
const crawledDocs = await fetchCrawledDocs(crawlPattern, onProgress).catch((err) => {
|
|
329
|
+
const crawledDocs = await fetchCrawledDocs(crawlPattern, onProgress, resolved.crawlUrl ? 200 : 400).catch((err) => {
|
|
326
330
|
warnings.push(`Crawl failed for ${crawlPattern}: ${err?.message || err}`);
|
|
327
331
|
return [];
|
|
328
332
|
});
|
|
@@ -558,6 +562,24 @@ async function indexResources(opts) {
|
|
|
558
562
|
});
|
|
559
563
|
}
|
|
560
564
|
if (allDocs.length === 0) return;
|
|
565
|
+
if (allDocs.length > MAX_INDEX_DOCS) {
|
|
566
|
+
const TYPE_PRIORITY = {
|
|
567
|
+
doc: 0,
|
|
568
|
+
issue: 1,
|
|
569
|
+
discussion: 2,
|
|
570
|
+
release: 3,
|
|
571
|
+
source: 4,
|
|
572
|
+
types: 5
|
|
573
|
+
};
|
|
574
|
+
allDocs.sort((a, b) => {
|
|
575
|
+
const ta = TYPE_PRIORITY[a.metadata?.type || "doc"] ?? 3;
|
|
576
|
+
const tb = TYPE_PRIORITY[b.metadata?.type || "doc"] ?? 3;
|
|
577
|
+
if (ta !== tb) return ta - tb;
|
|
578
|
+
return a.id.localeCompare(b.id);
|
|
579
|
+
});
|
|
580
|
+
onProgress(`Indexing capped at ${MAX_INDEX_DOCS}/${allDocs.length} docs (prioritized by type)`);
|
|
581
|
+
allDocs.length = MAX_INDEX_DOCS;
|
|
582
|
+
}
|
|
561
583
|
onProgress(`Building search index (${allDocs.length} docs)`);
|
|
562
584
|
try {
|
|
563
585
|
await createIndex(allDocs, {
|
|
@@ -804,6 +826,11 @@ async function selectLlmConfig(presetModel, message) {
|
|
|
804
826
|
value: "pick",
|
|
805
827
|
hint: "choose another model"
|
|
806
828
|
},
|
|
829
|
+
{
|
|
830
|
+
label: "Prompt only",
|
|
831
|
+
value: "prompt",
|
|
832
|
+
hint: "write prompts for manual use"
|
|
833
|
+
},
|
|
807
834
|
{
|
|
808
835
|
label: "Skip",
|
|
809
836
|
value: "skip",
|
|
@@ -813,6 +840,16 @@ async function selectLlmConfig(presetModel, message) {
|
|
|
813
840
|
});
|
|
814
841
|
if (p.isCancel(choice)) return null;
|
|
815
842
|
if (choice === "skip") return null;
|
|
843
|
+
if (choice === "prompt") {
|
|
844
|
+
const { sections, customPrompt, cancelled } = await selectSkillSections(message ? `${message} (prompt only)` : "Select sections for prompt generation");
|
|
845
|
+
if (cancelled || sections.length === 0) return null;
|
|
846
|
+
return {
|
|
847
|
+
model: defaultModel,
|
|
848
|
+
sections,
|
|
849
|
+
customPrompt,
|
|
850
|
+
promptOnly: true
|
|
851
|
+
};
|
|
852
|
+
}
|
|
816
853
|
const model = choice === "pick" ? await selectModel(false) : defaultModel;
|
|
817
854
|
if (!model) return null;
|
|
818
855
|
const modelName = getModelName(model);
|
|
@@ -886,6 +923,41 @@ async function enhanceSkillWithLLM(opts) {
|
|
|
886
923
|
} else llmLog.error(`LLM optimization failed${error ? `: ${error}` : ""}`);
|
|
887
924
|
}
|
|
888
925
|
/**
|
|
926
|
+
* Build and write PROMPT_*.md files for manual LLM use.
|
|
927
|
+
* Returns the list of sections that had prompts written.
|
|
928
|
+
*/
|
|
929
|
+
function writePromptFiles(opts) {
|
|
930
|
+
const { skillDir, sections, customPrompt, features } = opts;
|
|
931
|
+
const docFiles = listReferenceFiles(skillDir);
|
|
932
|
+
const prompts = buildAllSectionPrompts({
|
|
933
|
+
packageName: opts.packageName,
|
|
934
|
+
skillDir,
|
|
935
|
+
version: opts.version,
|
|
936
|
+
hasIssues: opts.hasIssues,
|
|
937
|
+
hasDiscussions: opts.hasDiscussions,
|
|
938
|
+
hasReleases: opts.hasReleases,
|
|
939
|
+
hasChangelog: opts.hasChangelog,
|
|
940
|
+
docFiles,
|
|
941
|
+
docsType: opts.docsType,
|
|
942
|
+
hasShippedDocs: opts.hasShippedDocs,
|
|
943
|
+
pkgFiles: opts.pkgFiles,
|
|
944
|
+
customPrompt,
|
|
945
|
+
features,
|
|
946
|
+
sections
|
|
947
|
+
});
|
|
948
|
+
const skilldDir = join(skillDir, ".skilld");
|
|
949
|
+
mkdirSync(skilldDir, { recursive: true });
|
|
950
|
+
for (const [section, prompt] of prompts) writeFileSync(join(skilldDir, `PROMPT_${section}.md`), prompt);
|
|
951
|
+
const written = [...prompts.keys()];
|
|
952
|
+
if (written.length > 0) {
|
|
953
|
+
const relDir = relative(process.cwd(), skillDir);
|
|
954
|
+
const promptFiles = written.map((s) => `PROMPT_${s}.md`).join(", ");
|
|
955
|
+
const outputFileList = written.map((s) => SECTION_OUTPUT_FILES[s]).join(", ");
|
|
956
|
+
p.log.info(`Prompt files written to ${relDir}/.skilld/\n\x1B[2m\x1B[3m Read each prompt file (${promptFiles}) in ${relDir}/.skilld/, read the\n referenced files, then write your output to the matching file (${outputFileList}).\n When done, run: skilld assemble\x1B[0m`);
|
|
957
|
+
}
|
|
958
|
+
return written;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
889
961
|
* Anonymous telemetry — fire-and-forget GET to add-skill.vercel.sh/t
|
|
890
962
|
*
|
|
891
963
|
* Opt-out: set DISABLE_TELEMETRY=1 or DO_NOT_TRACK=1
|
|
@@ -1076,7 +1148,22 @@ async function syncGitHubRepo(opts) {
|
|
|
1076
1148
|
p.log.success(`Created base skill: ${relative(cwd, skillDir)}`);
|
|
1077
1149
|
if (!readConfig().skipLlm && (!yes || opts.model)) {
|
|
1078
1150
|
const llmConfig = await selectLlmConfig(opts.model);
|
|
1079
|
-
if (llmConfig) {
|
|
1151
|
+
if (llmConfig?.promptOnly) writePromptFiles({
|
|
1152
|
+
packageName,
|
|
1153
|
+
skillDir,
|
|
1154
|
+
version,
|
|
1155
|
+
hasIssues: resources.hasIssues,
|
|
1156
|
+
hasDiscussions: resources.hasDiscussions,
|
|
1157
|
+
hasReleases: resources.hasReleases,
|
|
1158
|
+
hasChangelog,
|
|
1159
|
+
docsType: resources.docsType,
|
|
1160
|
+
hasShippedDocs: shippedDocs,
|
|
1161
|
+
pkgFiles,
|
|
1162
|
+
sections: llmConfig.sections,
|
|
1163
|
+
customPrompt: llmConfig.customPrompt,
|
|
1164
|
+
features
|
|
1165
|
+
});
|
|
1166
|
+
else if (llmConfig) {
|
|
1080
1167
|
p.log.step(getModelLabel(llmConfig.model));
|
|
1081
1168
|
await enhanceSkillWithLLM({
|
|
1082
1169
|
packageName,
|
|
@@ -1102,7 +1189,7 @@ async function syncGitHubRepo(opts) {
|
|
|
1102
1189
|
}
|
|
1103
1190
|
}
|
|
1104
1191
|
const shared = !isGlobal && getSharedSkillsDir(cwd);
|
|
1105
|
-
if (shared) linkSkillToAgents(skillDirName, shared, cwd);
|
|
1192
|
+
if (shared) linkSkillToAgents(skillDirName, shared, cwd, agent);
|
|
1106
1193
|
if (!isGlobal) {
|
|
1107
1194
|
registerProject(cwd);
|
|
1108
1195
|
await ensureGitignore(shared || targets[agent].skillsDir, cwd, isGlobal);
|
|
@@ -1210,7 +1297,25 @@ async function syncPackagesParallel(config) {
|
|
|
1210
1297
|
const globalConfig = readConfig();
|
|
1211
1298
|
if (successfulPkgs.length > 0 && !globalConfig.skipLlm && !(config.yes && !config.model)) {
|
|
1212
1299
|
const llmConfig = await selectLlmConfig(config.model);
|
|
1213
|
-
if (llmConfig) {
|
|
1300
|
+
if (llmConfig?.promptOnly) for (const pkg of successfulPkgs) {
|
|
1301
|
+
const data = skillData.get(pkg);
|
|
1302
|
+
writePromptFiles({
|
|
1303
|
+
packageName: pkg,
|
|
1304
|
+
skillDir: join(resolveBaseDir(cwd, config.agent, config.global), data.skillDirName),
|
|
1305
|
+
version: data.version,
|
|
1306
|
+
hasIssues: data.hasIssues,
|
|
1307
|
+
hasDiscussions: data.hasDiscussions,
|
|
1308
|
+
hasReleases: data.hasReleases,
|
|
1309
|
+
hasChangelog: data.hasChangelog,
|
|
1310
|
+
docsType: data.docsType,
|
|
1311
|
+
hasShippedDocs: data.shippedDocs,
|
|
1312
|
+
pkgFiles: data.pkgFiles,
|
|
1313
|
+
sections: llmConfig.sections,
|
|
1314
|
+
customPrompt: llmConfig.customPrompt,
|
|
1315
|
+
features: data.features
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
else if (llmConfig) {
|
|
1214
1319
|
p.log.step(getModelLabel(llmConfig.model));
|
|
1215
1320
|
for (const pkg of successfulPkgs) states.set(pkg, {
|
|
1216
1321
|
name: pkg,
|
|
@@ -1266,7 +1371,7 @@ async function syncBaseSkill(packageSpec, config, cwd, update) {
|
|
|
1266
1371
|
const shippedResult = handleShippedSkills(packageName, version, cwd, config.agent, config.global);
|
|
1267
1372
|
if (shippedResult) {
|
|
1268
1373
|
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1269
|
-
if (shared) for (const shipped of shippedResult.shipped) linkSkillToAgents(shipped.skillName, shared, cwd);
|
|
1374
|
+
if (shared) for (const shipped of shippedResult.shipped) linkSkillToAgents(shipped.skillName, shared, cwd, config.agent);
|
|
1270
1375
|
update(packageName, "done", "Published SKILL.md", versionKey);
|
|
1271
1376
|
return "shipped";
|
|
1272
1377
|
}
|
|
@@ -1338,7 +1443,7 @@ async function syncBaseSkill(packageSpec, config, cwd, update) {
|
|
|
1338
1443
|
});
|
|
1339
1444
|
writeFileSync(join(skillDir, "SKILL.md"), skillMd);
|
|
1340
1445
|
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1341
|
-
if (shared) linkSkillToAgents(skillDirName, shared, cwd);
|
|
1446
|
+
if (shared) linkSkillToAgents(skillDirName, shared, cwd, config.agent);
|
|
1342
1447
|
if (!config.global) registerProject(cwd);
|
|
1343
1448
|
update(packageName, "done", config.mode === "update" ? "Skill updated" : "Base skill created", versionKey);
|
|
1344
1449
|
return {
|
|
@@ -1568,7 +1673,7 @@ async function syncSinglePackage(packageSpec, config) {
|
|
|
1568
1673
|
if (shippedResult) {
|
|
1569
1674
|
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1570
1675
|
for (const shipped of shippedResult.shipped) {
|
|
1571
|
-
if (shared) linkSkillToAgents(shipped.skillName, shared, cwd);
|
|
1676
|
+
if (shared) linkSkillToAgents(shipped.skillName, shared, cwd, config.agent);
|
|
1572
1677
|
p.log.success(`Using published SKILL.md: ${shipped.skillName} → ${relative(cwd, shipped.skillDir)}`);
|
|
1573
1678
|
}
|
|
1574
1679
|
spin.stop(`Using published SKILL.md(s) from ${packageName}`);
|
|
@@ -1577,7 +1682,7 @@ async function syncSinglePackage(packageSpec, config) {
|
|
|
1577
1682
|
spin.stop(`Resolved ${packageName}@${useCache ? versionKey : version}${config.force ? " (force)" : useCache ? " (cached)" : ""}`);
|
|
1578
1683
|
if (!localVersion && !requestedTag && !isPrerelease(version)) {
|
|
1579
1684
|
const nextTag = resolved.distTags?.next ?? resolved.distTags?.beta ?? resolved.distTags?.alpha;
|
|
1580
|
-
if (nextTag) p.log.warn(`\x1B[33mNo local dependency found — using latest stable (${version}). Prerelease ${nextTag.version} available: skilld add ${packageName}@beta\x1B[0m`);
|
|
1685
|
+
if (nextTag && (!resolved.releasedAt || !nextTag.releasedAt || nextTag.releasedAt > resolved.releasedAt)) p.log.warn(`\x1B[33mNo local dependency found — using latest stable (${version}). Prerelease ${nextTag.version} available: skilld add ${packageName}@beta\x1B[0m`);
|
|
1581
1686
|
}
|
|
1582
1687
|
ensureCacheDir();
|
|
1583
1688
|
const baseDir = resolveBaseDir(cwd, config.agent, config.global);
|
|
@@ -1619,12 +1724,13 @@ async function syncSinglePackage(packageSpec, config) {
|
|
|
1619
1724
|
});
|
|
1620
1725
|
writeFileSync(join(skillDir, "SKILL.md"), skillMd);
|
|
1621
1726
|
const mergeShared = !config.global && getSharedSkillsDir(cwd);
|
|
1622
|
-
if (mergeShared) linkSkillToAgents(skillDirName, mergeShared, cwd);
|
|
1727
|
+
if (mergeShared) linkSkillToAgents(skillDirName, mergeShared, cwd, config.agent);
|
|
1623
1728
|
if (!config.global) registerProject(cwd);
|
|
1624
1729
|
p.outro(`Merged ${packageName} into ${skillDirName}`);
|
|
1625
1730
|
return;
|
|
1626
1731
|
}
|
|
1627
|
-
const features = readConfig().features ?? defaultFeatures;
|
|
1732
|
+
const features = { ...readConfig().features ?? defaultFeatures };
|
|
1733
|
+
if (config.noSearch) features.search = false;
|
|
1628
1734
|
const resSpin = timedSpinner();
|
|
1629
1735
|
resSpin.start("Finding resources");
|
|
1630
1736
|
const resources = await fetchAndCacheResources({
|
|
@@ -1701,7 +1807,22 @@ async function syncSinglePackage(packageSpec, config) {
|
|
|
1701
1807
|
p.log.success(config.mode === "update" ? `Updated skill: ${relative(cwd, skillDir)}` : `Created base skill: ${relative(cwd, skillDir)}`);
|
|
1702
1808
|
if (!readConfig().skipLlm && (!config.yes || config.model)) {
|
|
1703
1809
|
const llmConfig = await selectLlmConfig(config.model);
|
|
1704
|
-
if (llmConfig) {
|
|
1810
|
+
if (llmConfig?.promptOnly) writePromptFiles({
|
|
1811
|
+
packageName,
|
|
1812
|
+
skillDir,
|
|
1813
|
+
version,
|
|
1814
|
+
hasIssues: resources.hasIssues,
|
|
1815
|
+
hasDiscussions: resources.hasDiscussions,
|
|
1816
|
+
hasReleases: resources.hasReleases,
|
|
1817
|
+
hasChangelog,
|
|
1818
|
+
docsType: resources.docsType,
|
|
1819
|
+
hasShippedDocs: shippedDocs,
|
|
1820
|
+
pkgFiles,
|
|
1821
|
+
sections: llmConfig.sections,
|
|
1822
|
+
customPrompt: llmConfig.customPrompt,
|
|
1823
|
+
features
|
|
1824
|
+
});
|
|
1825
|
+
else if (llmConfig) {
|
|
1705
1826
|
p.log.step(getModelLabel(llmConfig.model));
|
|
1706
1827
|
await enhanceSkillWithLLM({
|
|
1707
1828
|
packageName,
|
|
@@ -1738,7 +1859,7 @@ async function syncSinglePackage(packageSpec, config) {
|
|
|
1738
1859
|
}
|
|
1739
1860
|
if (!isEject) {
|
|
1740
1861
|
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1741
|
-
if (shared) linkSkillToAgents(skillDirName, shared, cwd);
|
|
1862
|
+
if (shared) linkSkillToAgents(skillDirName, shared, cwd, config.agent);
|
|
1742
1863
|
if (!config.global) registerProject(cwd);
|
|
1743
1864
|
await ensureGitignore(shared ? SHARED_SKILLS_DIR : targets[config.agent].skillsDir, cwd, config.global);
|
|
1744
1865
|
await ensureAgentInstructions(config.agent, cwd, config.global);
|
|
@@ -1773,8 +1894,16 @@ const addCommandDef = defineCommand({
|
|
|
1773
1894
|
agent = await promptForAgent();
|
|
1774
1895
|
if (!agent) return;
|
|
1775
1896
|
}
|
|
1776
|
-
if (!hasCompletedWizard()) await runWizard();
|
|
1777
1897
|
const rawInputs = [...new Set([args.package, ...args._ || []].map((s) => s.trim()).filter(Boolean))];
|
|
1898
|
+
if (agent === "none") {
|
|
1899
|
+
const packages = [...new Set(rawInputs.flatMap((s) => s.split(/[,\s]+/)).map((s) => s.trim()).filter(Boolean))];
|
|
1900
|
+
for (const pkg of packages) await exportPortablePrompts(pkg, {
|
|
1901
|
+
force: args.force,
|
|
1902
|
+
agent: "none"
|
|
1903
|
+
});
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (!hasCompletedWizard()) await runWizard();
|
|
1778
1907
|
const gitSources = [];
|
|
1779
1908
|
const npmTokens = [];
|
|
1780
1909
|
for (const input of rawInputs) {
|
|
@@ -1817,30 +1946,36 @@ const ejectCommandDef = defineCommand({
|
|
|
1817
1946
|
description: "Eject skill with references as real files (portable, no symlinks)"
|
|
1818
1947
|
},
|
|
1819
1948
|
args: {
|
|
1820
|
-
package: {
|
|
1949
|
+
"package": {
|
|
1821
1950
|
type: "positional",
|
|
1822
1951
|
description: "Package to eject",
|
|
1823
1952
|
required: true
|
|
1824
1953
|
},
|
|
1825
|
-
name: {
|
|
1954
|
+
"name": {
|
|
1826
1955
|
type: "string",
|
|
1827
1956
|
alias: "n",
|
|
1828
1957
|
description: "Custom skill directory name (default: derived from package)"
|
|
1829
1958
|
},
|
|
1830
|
-
out: {
|
|
1959
|
+
"out": {
|
|
1831
1960
|
type: "string",
|
|
1832
1961
|
alias: "o",
|
|
1833
1962
|
description: "Output directory path override"
|
|
1834
1963
|
},
|
|
1835
|
-
from: {
|
|
1964
|
+
"from": {
|
|
1836
1965
|
type: "string",
|
|
1837
1966
|
description: "Collect releases/issues/discussions from this date onward (YYYY-MM-DD)"
|
|
1838
1967
|
},
|
|
1968
|
+
"no-search": {
|
|
1969
|
+
type: "boolean",
|
|
1970
|
+
description: "Skip search index / embeddings generation",
|
|
1971
|
+
default: false
|
|
1972
|
+
},
|
|
1839
1973
|
...sharedArgs
|
|
1840
1974
|
},
|
|
1841
1975
|
async run({ args }) {
|
|
1842
1976
|
const cwd = process.cwd();
|
|
1843
|
-
const
|
|
1977
|
+
const resolved = resolveAgent(args.agent);
|
|
1978
|
+
const agent = resolved && resolved !== "none" ? resolved : "claude-code";
|
|
1844
1979
|
if (!hasCompletedWizard()) await runWizard();
|
|
1845
1980
|
const state = await getProjectState(cwd);
|
|
1846
1981
|
p.intro(introLine({ state }));
|
|
@@ -1854,7 +1989,8 @@ const ejectCommandDef = defineCommand({
|
|
|
1854
1989
|
debug: args.debug,
|
|
1855
1990
|
eject: args.out || true,
|
|
1856
1991
|
name: args.name,
|
|
1857
|
-
from: args.from
|
|
1992
|
+
from: args.from,
|
|
1993
|
+
noSearch: args["no-search"]
|
|
1858
1994
|
});
|
|
1859
1995
|
}
|
|
1860
1996
|
});
|
|
@@ -1897,10 +2033,22 @@ const updateCommandDef = defineCommand({
|
|
|
1897
2033
|
const silent = !isInteractive();
|
|
1898
2034
|
let agent = resolveAgent(args.agent);
|
|
1899
2035
|
if (!agent) {
|
|
1900
|
-
if (silent) return;
|
|
1901
2036
|
agent = await promptForAgent();
|
|
1902
2037
|
if (!agent) return;
|
|
1903
2038
|
}
|
|
2039
|
+
if (agent === "none") {
|
|
2040
|
+
const state = await getProjectState(cwd);
|
|
2041
|
+
const packages = args.package ? [...new Set([args.package, ...args._ || []].flatMap((s) => s.split(/[,\s]+/)).map((s) => s.trim()).filter(Boolean))] : state.outdated.map((s) => s.packageName || s.name);
|
|
2042
|
+
if (packages.length === 0) {
|
|
2043
|
+
if (!silent) p.log.success("All skills up to date");
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
for (const pkg of packages) await exportPortablePrompts(pkg, {
|
|
2047
|
+
force: args.force,
|
|
2048
|
+
agent: "none"
|
|
2049
|
+
});
|
|
2050
|
+
return;
|
|
2051
|
+
}
|
|
1904
2052
|
const config = readConfig();
|
|
1905
2053
|
const state = await getProjectState(cwd);
|
|
1906
2054
|
if (!silent) {
|
|
@@ -1937,6 +2085,131 @@ const updateCommandDef = defineCommand({
|
|
|
1937
2085
|
});
|
|
1938
2086
|
}
|
|
1939
2087
|
});
|
|
1940
|
-
|
|
2088
|
+
async function exportPortablePrompts(packageSpec, opts) {
|
|
2089
|
+
const { name: packageName } = parsePackageSpec(packageSpec);
|
|
2090
|
+
const sections = opts.sections ?? DEFAULT_SECTIONS;
|
|
2091
|
+
const spin = timedSpinner();
|
|
2092
|
+
spin.start(`Resolving ${packageSpec}`);
|
|
2093
|
+
const cwd = process.cwd();
|
|
2094
|
+
const localVersion = (await readLocalDependencies(cwd).catch(() => [])).find((d) => d.name === packageName)?.version;
|
|
2095
|
+
let resolved = (await resolvePackageDocsWithAttempts(packageName, {
|
|
2096
|
+
version: localVersion,
|
|
2097
|
+
cwd,
|
|
2098
|
+
onProgress: (step) => spin.message(`${packageName}: ${RESOLVE_STEP_LABELS[step]}`)
|
|
2099
|
+
})).package;
|
|
2100
|
+
if (!resolved) {
|
|
2101
|
+
spin.message(`Resolving local package: ${packageName}`);
|
|
2102
|
+
resolved = await resolveLocalDep(packageName, cwd);
|
|
2103
|
+
}
|
|
2104
|
+
if (!resolved) {
|
|
2105
|
+
spin.stop(`Could not find docs for: ${packageName}`);
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
const version = localVersion || resolved.version || "latest";
|
|
2109
|
+
const versionKey = getVersionKey(version);
|
|
2110
|
+
const useCache = !opts.force && isCached(packageName, version);
|
|
2111
|
+
if (!existsSync(join(cwd, "node_modules", packageName))) {
|
|
2112
|
+
spin.message(`Downloading ${packageName}@${version} dist`);
|
|
2113
|
+
await fetchPkgDist(packageName, version);
|
|
2114
|
+
}
|
|
2115
|
+
spin.stop(`Resolved ${packageName}@${useCache ? versionKey : version}`);
|
|
2116
|
+
ensureCacheDir();
|
|
2117
|
+
const skillDirName = computeSkillDirName(packageName);
|
|
2118
|
+
const features = readConfig().features ?? defaultFeatures;
|
|
2119
|
+
const agent = opts.agent === "none" ? null : opts.agent ?? await import("./detect.mjs").then((n) => n.r).then((m) => m.detectTargetAgent());
|
|
2120
|
+
const baseDir = agent ? resolveBaseDir(cwd, agent, false) : join(cwd, ".claude", "skills");
|
|
2121
|
+
const skillDir = opts.out ? resolve(cwd, opts.out) : join(baseDir, skillDirName);
|
|
2122
|
+
if (existsSync(skillDir) && !opts.force) {
|
|
2123
|
+
const existing = Object.values(SECTION_OUTPUT_FILES).filter((f) => existsSync(join(skillDir, f)));
|
|
2124
|
+
if (existing.length > 0) p.log.warn(`Overwriting existing output files in ${relative(cwd, skillDir)}: ${existing.join(", ")}`);
|
|
2125
|
+
}
|
|
2126
|
+
mkdirSync(skillDir, { recursive: true });
|
|
2127
|
+
const resSpin = timedSpinner();
|
|
2128
|
+
resSpin.start("Fetching resources");
|
|
2129
|
+
const resources = await fetchAndCacheResources({
|
|
2130
|
+
packageName,
|
|
2131
|
+
resolved,
|
|
2132
|
+
version,
|
|
2133
|
+
useCache,
|
|
2134
|
+
features,
|
|
2135
|
+
onProgress: (msg) => resSpin.message(msg)
|
|
2136
|
+
});
|
|
2137
|
+
resSpin.stop("Resources ready");
|
|
2138
|
+
for (const w of resources.warnings) p.log.warn(`\x1B[33m${w}\x1B[0m`);
|
|
2139
|
+
linkAllReferences(skillDir, packageName, cwd, version, resources.docsType, void 0, features, resources.repoInfo);
|
|
2140
|
+
const hasChangelog = detectChangelog(resolvePkgDir(packageName, cwd, version), getCacheDir(packageName, version));
|
|
2141
|
+
const shippedDocs = hasShippedDocs(packageName, cwd, version);
|
|
2142
|
+
const pkgFiles = getPkgKeyFiles(packageName, cwd, version);
|
|
2143
|
+
const docFiles = listReferenceFiles(skillDir);
|
|
2144
|
+
const prompts = buildAllSectionPrompts({
|
|
2145
|
+
packageName,
|
|
2146
|
+
skillDir,
|
|
2147
|
+
version,
|
|
2148
|
+
hasIssues: resources.hasIssues,
|
|
2149
|
+
hasDiscussions: resources.hasDiscussions,
|
|
2150
|
+
hasReleases: resources.hasReleases,
|
|
2151
|
+
hasChangelog,
|
|
2152
|
+
docFiles,
|
|
2153
|
+
docsType: resources.docsType,
|
|
2154
|
+
hasShippedDocs: shippedDocs,
|
|
2155
|
+
pkgFiles,
|
|
2156
|
+
features,
|
|
2157
|
+
sections
|
|
2158
|
+
});
|
|
2159
|
+
ejectReferences(skillDir, packageName, cwd, version, resources.docsType, features, resources.repoInfo);
|
|
2160
|
+
const skilldDir = join(skillDir, ".skilld");
|
|
2161
|
+
if (existsSync(skilldDir)) rmSync(skilldDir, {
|
|
2162
|
+
recursive: true,
|
|
2163
|
+
force: true
|
|
2164
|
+
});
|
|
2165
|
+
for (const [section, prompt] of prompts) {
|
|
2166
|
+
const portable = portabilizePrompt(prompt, section);
|
|
2167
|
+
writeFileSync(join(skillDir, `PROMPT_${section}.md`), portable);
|
|
2168
|
+
}
|
|
2169
|
+
const relatedSkills = await findRelatedSkills(packageName, join(skillDir, ".."));
|
|
2170
|
+
const skillMd = generateSkillMd({
|
|
2171
|
+
name: packageName,
|
|
2172
|
+
version,
|
|
2173
|
+
releasedAt: resolved.releasedAt,
|
|
2174
|
+
description: resolved.description,
|
|
2175
|
+
dependencies: resolved.dependencies,
|
|
2176
|
+
distTags: resolved.distTags,
|
|
2177
|
+
relatedSkills,
|
|
2178
|
+
hasIssues: resources.hasIssues,
|
|
2179
|
+
hasDiscussions: resources.hasDiscussions,
|
|
2180
|
+
hasReleases: resources.hasReleases,
|
|
2181
|
+
hasChangelog,
|
|
2182
|
+
docsType: resources.docsType,
|
|
2183
|
+
hasShippedDocs: shippedDocs,
|
|
2184
|
+
pkgFiles,
|
|
2185
|
+
repoUrl: resolved.repoUrl,
|
|
2186
|
+
features,
|
|
2187
|
+
eject: true
|
|
2188
|
+
});
|
|
2189
|
+
writeFileSync(join(skillDir, "SKILL.md"), skillMd);
|
|
2190
|
+
const repoSlug = resolved.repoUrl?.match(/github\.com\/([^/]+\/[^/]+?)(?:\.git)?(?:[/#]|$)/)?.[1];
|
|
2191
|
+
writeLock(baseDir, skillDirName, {
|
|
2192
|
+
packageName,
|
|
2193
|
+
version,
|
|
2194
|
+
repo: repoSlug,
|
|
2195
|
+
source: resources.docSource,
|
|
2196
|
+
syncedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
2197
|
+
generator: "skilld"
|
|
2198
|
+
});
|
|
2199
|
+
if (agent) {
|
|
2200
|
+
const shared = getSharedSkillsDir(cwd);
|
|
2201
|
+
if (shared) linkSkillToAgents(skillDirName, shared, cwd, agent);
|
|
2202
|
+
await ensureGitignore(shared ? SHARED_SKILLS_DIR : targets[agent].skillsDir, cwd, false);
|
|
2203
|
+
await ensureAgentInstructions(agent, cwd, false);
|
|
2204
|
+
registerProject(cwd);
|
|
2205
|
+
} else await ensureGitignore(".claude/skills", cwd, false);
|
|
2206
|
+
const relDir = relative(cwd, skillDir);
|
|
2207
|
+
const sectionList = [...prompts.keys()];
|
|
2208
|
+
p.log.success(`Skill installed to ${relDir}`);
|
|
2209
|
+
const promptFiles = sectionList.map((s) => `PROMPT_${s}.md`).join(", ");
|
|
2210
|
+
const outputFileList = sectionList.map((s) => SECTION_OUTPUT_FILES[s]).join(", ");
|
|
2211
|
+
p.log.info(`Have your agent enhance the skill. Give it this prompt:\n\x1B[2m\x1B[3m Read each prompt file (${promptFiles}) in ${relDir}/, read the\n referenced files, then write your output to the matching file (${outputFileList}).\n When done, run: skilld assemble\x1B[0m`);
|
|
2212
|
+
}
|
|
2213
|
+
export { writePromptFiles as _, updateCommandDef as a, SKILLD_MARKER_START as c, ensureAgentInstructions as d, ensureGitignore as f, selectSkillSections as g, selectModel as h, syncCommand as i, classifyCachedDoc as l, selectLlmConfig as m, ejectCommandDef as n, DEFAULT_SECTIONS as o, indexResources as p, exportPortablePrompts as r, SKILLD_MARKER_END as s, addCommandDef as t, enhanceSkillWithLLM as u };
|
|
1941
2214
|
|
|
1942
2215
|
//# sourceMappingURL=sync.mjs.map
|