skilld 0.4.0 → 0.4.1
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/detect-imports.mjs +3 -4
- package/dist/_chunks/detect-imports.mjs.map +1 -1
- package/dist/_chunks/{pool.mjs → pool2.mjs} +7 -2
- package/dist/_chunks/pool2.mjs.map +1 -0
- package/dist/_chunks/releases.mjs +309 -5
- package/dist/_chunks/releases.mjs.map +1 -1
- package/dist/_chunks/storage.mjs +241 -2
- package/dist/_chunks/storage.mjs.map +1 -1
- package/dist/_chunks/utils.d.mts.map +1 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/cli.mjs +364 -39
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/retriv/index.mjs +1 -1
- package/dist/retriv/index.mjs.map +1 -1
- package/dist/sources/index.mjs +1 -2
- package/package.json +1 -1
- package/dist/_chunks/git-skills.mjs +0 -319
- package/dist/_chunks/git-skills.mjs.map +0 -1
- package/dist/_chunks/pool.mjs.map +0 -1
- package/dist/_chunks/sanitize2.mjs +0 -249
- package/dist/_chunks/sanitize2.mjs.map +0 -1
- package/dist/_chunks/sync-git.mjs +0 -69
- package/dist/_chunks/sync-git.mjs.map +0 -1
- package/dist/_chunks/sync-parallel.mjs +0 -302
- package/dist/_chunks/sync-parallel.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { _ as detectInstalledAgents, a as optimizeDocs, b as targets, c as computeSkillDirName, f as unlinkSkillFromAgents, i as getModelName, n as getAvailableModels, o as generateSkillMd, r as getModelLabel, t as detectImportedPackages, u as linkSkillToAgents, v as detectTargetAgent, y as getAgentVersion } from "./_chunks/detect-imports.mjs";
|
|
3
3
|
import { i as getCacheDir, o as getVersionKey, r as getPackageDbPath, t as CACHE_DIR } from "./_chunks/config.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { a as getShippedSkills, c as linkCachedDir, d as linkShippedSkill, g as resolvePkgDir, i as getPkgKeyFiles, l as linkPkg, m as readCachedDocs, n as clearCache, o as hasShippedDocs, p as listReferenceFiles, r as ensureCacheDir, s as isCached, u as linkPkgNamed, v as writeToCache } from "./_chunks/storage.mjs";
|
|
4
|
+
import { a as getShippedSkills, b as sanitizeMarkdown, c as linkCachedDir, d as linkShippedSkill, g as resolvePkgDir, i as getPkgKeyFiles, l as linkPkg, m as readCachedDocs, n as clearCache, o as hasShippedDocs, p as listReferenceFiles, r as ensureCacheDir, s as isCached, u as linkPkgNamed, v as writeToCache } from "./_chunks/storage.mjs";
|
|
6
5
|
import "./cache/index.mjs";
|
|
7
6
|
import { closePool, createIndex, openPool, searchPooled, searchSnippets } from "./retriv/index.mjs";
|
|
8
|
-
import { C as fetchGitDocs, D as isShallowGitDocs, E as fetchReadmeContent,
|
|
7
|
+
import { C as fetchGitDocs, D as isShallowGitDocs, E as fetchReadmeContent, G as fetchGitHubIssues, H as fetchGitHubDiscussions, J as isGhAvailable, K as formatIssueAsMarkdown, M as parseGitSkillInput, P as $fetch, U as formatDiscussionAsMarkdown, V as resolveEntryFiles, W as generateDiscussionIndex, a as fetchNpmRegistryMeta, b as normalizeLlmsLinks, f as resolveLocalPackageDocs, g as downloadLlmsDocs, h as searchNpmPackages, i as fetchNpmPackage, j as fetchGitSkills, l as readLocalDependencies, m as resolvePackageDocsWithAttempts, o as fetchPkgDist, p as resolvePackageDocs, q as generateIssueIndex, r as fetchLatestVersion, t as fetchReleaseNotes, v as fetchLlmsTxt, z as parseGitHubUrl } from "./_chunks/releases.mjs";
|
|
9
8
|
import { n as yamlParseKV, r as yamlUnescape, t as yamlEscape } from "./_chunks/yaml.mjs";
|
|
10
|
-
import { a as $fetch, d as parseGitHubUrl } from "./_chunks/git-skills.mjs";
|
|
11
9
|
import "./sources/index.mjs";
|
|
12
10
|
import "./agent/index.mjs";
|
|
11
|
+
import { n as shutdownWorker } from "./_chunks/pool2.mjs";
|
|
13
12
|
import { createRequire } from "node:module";
|
|
14
13
|
import { homedir } from "node:os";
|
|
15
|
-
import { join, relative, resolve } from "pathe";
|
|
14
|
+
import { dirname, join, relative, resolve } from "pathe";
|
|
16
15
|
import { appendFileSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
17
|
-
import { execSync } from "node:child_process";
|
|
16
|
+
import { execSync, spawn } from "node:child_process";
|
|
18
17
|
import pLimit from "p-limit";
|
|
19
18
|
import * as p from "@clack/prompts";
|
|
20
19
|
import { defineCommand, runMain } from "citty";
|
|
20
|
+
import logUpdate from "log-update";
|
|
21
21
|
import { detectCurrentAgent } from "unagent/env";
|
|
22
22
|
const LLM_CACHE_DIR = join(CACHE_DIR, "llm-cache");
|
|
23
23
|
const LLM_CACHE_MAX_AGE = 10080 * 60 * 1e3;
|
|
@@ -871,6 +871,290 @@ async function indexResources(opts) {
|
|
|
871
871
|
}
|
|
872
872
|
});
|
|
873
873
|
}
|
|
874
|
+
const STATUS_ICONS = {
|
|
875
|
+
pending: "○",
|
|
876
|
+
resolving: "◐",
|
|
877
|
+
downloading: "◒",
|
|
878
|
+
embedding: "◓",
|
|
879
|
+
exploring: "◔",
|
|
880
|
+
thinking: "◔",
|
|
881
|
+
generating: "◑",
|
|
882
|
+
done: "✓",
|
|
883
|
+
error: "✗"
|
|
884
|
+
};
|
|
885
|
+
const STATUS_COLORS = {
|
|
886
|
+
pending: "\x1B[90m",
|
|
887
|
+
resolving: "\x1B[36m",
|
|
888
|
+
downloading: "\x1B[36m",
|
|
889
|
+
embedding: "\x1B[36m",
|
|
890
|
+
exploring: "\x1B[34m",
|
|
891
|
+
thinking: "\x1B[35m",
|
|
892
|
+
generating: "\x1B[33m",
|
|
893
|
+
done: "\x1B[32m",
|
|
894
|
+
error: "\x1B[31m"
|
|
895
|
+
};
|
|
896
|
+
async function syncPackagesParallel(config) {
|
|
897
|
+
const { packages, concurrency = 5 } = config;
|
|
898
|
+
const agent = targets[config.agent];
|
|
899
|
+
const states = /* @__PURE__ */ new Map();
|
|
900
|
+
const cwd = process.cwd();
|
|
901
|
+
for (const pkg of packages) states.set(pkg, {
|
|
902
|
+
name: pkg,
|
|
903
|
+
status: "pending",
|
|
904
|
+
message: "Waiting..."
|
|
905
|
+
});
|
|
906
|
+
function render() {
|
|
907
|
+
const maxNameLen = Math.max(...packages.map((p) => p.length), 20);
|
|
908
|
+
const lines = [...states.values()].map((s) => {
|
|
909
|
+
const icon = STATUS_ICONS[s.status];
|
|
910
|
+
const color = STATUS_COLORS[s.status];
|
|
911
|
+
const reset = "\x1B[0m";
|
|
912
|
+
const dim = "\x1B[90m";
|
|
913
|
+
const name = s.name.padEnd(maxNameLen);
|
|
914
|
+
const version = s.version ? `${dim}${s.version}${reset} ` : "";
|
|
915
|
+
const elapsed = (s.status === "done" || s.status === "error") && s.startedAt && s.completedAt ? ` ${dim}(${formatDuration(s.completedAt - s.startedAt)})${reset}` : "";
|
|
916
|
+
const preview = s.streamPreview ? ` ${dim}${s.streamPreview}${reset}` : "";
|
|
917
|
+
return ` ${color}${icon}${reset} ${name} ${version}${s.message}${elapsed}${preview}`;
|
|
918
|
+
});
|
|
919
|
+
const doneCount = [...states.values()].filter((s) => s.status === "done").length;
|
|
920
|
+
const errorCount = [...states.values()].filter((s) => s.status === "error").length;
|
|
921
|
+
logUpdate(`\x1B[1mSyncing ${packages.length} packages\x1B[0m (${doneCount} done${errorCount > 0 ? `, ${errorCount} failed` : ""})\n` + lines.join("\n"));
|
|
922
|
+
}
|
|
923
|
+
function update(pkg, status, message, version) {
|
|
924
|
+
const state = states.get(pkg);
|
|
925
|
+
if (!state.startedAt && status !== "pending") state.startedAt = performance.now();
|
|
926
|
+
if ((status === "done" || status === "error") && !state.completedAt) state.completedAt = performance.now();
|
|
927
|
+
state.status = status;
|
|
928
|
+
state.message = message;
|
|
929
|
+
state.streamPreview = void 0;
|
|
930
|
+
if (version) state.version = version;
|
|
931
|
+
render();
|
|
932
|
+
}
|
|
933
|
+
ensureCacheDir();
|
|
934
|
+
render();
|
|
935
|
+
const limit = pLimit(concurrency);
|
|
936
|
+
const skillData = /* @__PURE__ */ new Map();
|
|
937
|
+
const baseResults = await Promise.allSettled(packages.map((pkg) => limit(() => syncBaseSkill(pkg, config, cwd, update))));
|
|
938
|
+
logUpdate.done();
|
|
939
|
+
const successfulPkgs = [];
|
|
940
|
+
const shippedPkgs = [];
|
|
941
|
+
const errors = [];
|
|
942
|
+
for (let i = 0; i < baseResults.length; i++) {
|
|
943
|
+
const r = baseResults[i];
|
|
944
|
+
if (r.status === "fulfilled" && r.value !== "shipped") {
|
|
945
|
+
successfulPkgs.push(packages[i]);
|
|
946
|
+
skillData.set(packages[i], r.value);
|
|
947
|
+
} else if (r.status === "fulfilled" && r.value === "shipped") shippedPkgs.push(packages[i]);
|
|
948
|
+
else if (r.status === "rejected") {
|
|
949
|
+
const err = r.reason;
|
|
950
|
+
const reason = err instanceof Error ? `${err.message}\n${err.stack}` : String(err);
|
|
951
|
+
errors.push({
|
|
952
|
+
pkg: packages[i],
|
|
953
|
+
reason
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
const skillMsg = `Created ${successfulPkgs.length} base skills${shippedPkgs.length > 1 ? ` (Skipping ${shippedPkgs.length})` : ""}`;
|
|
958
|
+
p.log.success(skillMsg);
|
|
959
|
+
if (errors.length > 0) for (const { pkg, reason } of errors) p.log.error(` ${pkg}: ${reason}`);
|
|
960
|
+
const globalConfig = readConfig();
|
|
961
|
+
if (successfulPkgs.length > 0 && !globalConfig.skipLlm && !(config.yes && !config.model)) {
|
|
962
|
+
const llmConfig = await selectLlmConfig(config.model);
|
|
963
|
+
if (llmConfig) {
|
|
964
|
+
p.log.step(getModelLabel(llmConfig.model));
|
|
965
|
+
for (const pkg of successfulPkgs) states.set(pkg, {
|
|
966
|
+
name: pkg,
|
|
967
|
+
status: "pending",
|
|
968
|
+
message: "Waiting..."
|
|
969
|
+
});
|
|
970
|
+
render();
|
|
971
|
+
const llmResults = await Promise.allSettled(successfulPkgs.map((pkg) => limit(() => enhanceWithLLM(pkg, skillData.get(pkg), {
|
|
972
|
+
...config,
|
|
973
|
+
model: llmConfig.model
|
|
974
|
+
}, cwd, update, llmConfig.sections, llmConfig.customPrompt))));
|
|
975
|
+
logUpdate.done();
|
|
976
|
+
const llmSucceeded = llmResults.filter((r) => r.status === "fulfilled").length;
|
|
977
|
+
p.log.success(`Enhanced ${llmSucceeded}/${successfulPkgs.length} skills with LLM`);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
await ensureGitignore(getSharedSkillsDir(cwd) ? SHARED_SKILLS_DIR : agent.skillsDir, cwd, config.global);
|
|
981
|
+
await shutdownWorker();
|
|
982
|
+
p.outro(`Synced ${successfulPkgs.length}/${packages.length} packages`);
|
|
983
|
+
}
|
|
984
|
+
async function syncBaseSkill(packageName, config, cwd, update) {
|
|
985
|
+
const localVersion = (await readLocalDependencies(cwd).catch(() => [])).find((d) => d.name === packageName)?.version;
|
|
986
|
+
const { package: resolvedPkg, attempts } = await resolvePackageDocsWithAttempts(packageName, {
|
|
987
|
+
version: localVersion,
|
|
988
|
+
cwd,
|
|
989
|
+
onProgress: (step) => update(packageName, "resolving", RESOLVE_STEP_LABELS[step])
|
|
990
|
+
});
|
|
991
|
+
let resolved = resolvedPkg;
|
|
992
|
+
if (!resolved) {
|
|
993
|
+
update(packageName, "resolving", "Local package...");
|
|
994
|
+
resolved = await resolveLocalDep(packageName, cwd);
|
|
995
|
+
}
|
|
996
|
+
if (!resolved) {
|
|
997
|
+
const npmAttempt = attempts.find((a) => a.source === "npm");
|
|
998
|
+
let reason;
|
|
999
|
+
if (npmAttempt?.status === "not-found") {
|
|
1000
|
+
const suggestions = await searchNpmPackages(packageName, 3);
|
|
1001
|
+
const hint = suggestions.length > 0 ? ` (try: ${suggestions.map((s) => s.name).join(", ")})` : "";
|
|
1002
|
+
reason = (npmAttempt.message || "Not on npm") + hint;
|
|
1003
|
+
} else reason = attempts.filter((a) => a.status !== "success").map((a) => a.message || a.source).join("; ") || "No docs found";
|
|
1004
|
+
update(packageName, "error", reason);
|
|
1005
|
+
throw new Error(`Could not find docs for: ${packageName}`);
|
|
1006
|
+
}
|
|
1007
|
+
const version = localVersion || resolved.version || "latest";
|
|
1008
|
+
const versionKey = getVersionKey(version);
|
|
1009
|
+
if (!existsSync(join(cwd, "node_modules", packageName))) {
|
|
1010
|
+
update(packageName, "downloading", "Downloading dist...", versionKey);
|
|
1011
|
+
await fetchPkgDist(packageName, version);
|
|
1012
|
+
}
|
|
1013
|
+
const shippedResult = handleShippedSkills(packageName, version, cwd, config.agent, config.global);
|
|
1014
|
+
if (shippedResult) {
|
|
1015
|
+
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1016
|
+
if (shared) for (const shipped of shippedResult.shipped) linkSkillToAgents(shipped.skillName, shared, cwd);
|
|
1017
|
+
update(packageName, "done", "Published SKILL.md", versionKey);
|
|
1018
|
+
return "shipped";
|
|
1019
|
+
}
|
|
1020
|
+
if (config.force) forceClearCache(packageName, version);
|
|
1021
|
+
const useCache = isCached(packageName, version);
|
|
1022
|
+
if (useCache) update(packageName, "downloading", "Using cache", versionKey);
|
|
1023
|
+
else update(packageName, "downloading", config.force ? "Re-fetching docs..." : "Fetching docs...", versionKey);
|
|
1024
|
+
const baseDir = resolveBaseDir(cwd, config.agent, config.global);
|
|
1025
|
+
const skillDirName = computeSkillDirName(packageName, resolved.repoUrl);
|
|
1026
|
+
const skillDir = join(baseDir, skillDirName);
|
|
1027
|
+
mkdirSync(skillDir, { recursive: true });
|
|
1028
|
+
const features = readConfig().features ?? defaultFeatures;
|
|
1029
|
+
const resources = await fetchAndCacheResources({
|
|
1030
|
+
packageName,
|
|
1031
|
+
resolved,
|
|
1032
|
+
version,
|
|
1033
|
+
useCache,
|
|
1034
|
+
features,
|
|
1035
|
+
onProgress: (msg) => update(packageName, "downloading", msg, versionKey)
|
|
1036
|
+
});
|
|
1037
|
+
update(packageName, "downloading", "Linking references...", versionKey);
|
|
1038
|
+
linkAllReferences(skillDir, packageName, cwd, version, resources.docsType);
|
|
1039
|
+
update(packageName, "embedding", "Indexing docs", versionKey);
|
|
1040
|
+
await indexResources({
|
|
1041
|
+
packageName,
|
|
1042
|
+
version,
|
|
1043
|
+
cwd,
|
|
1044
|
+
docsToIndex: resources.docsToIndex,
|
|
1045
|
+
features,
|
|
1046
|
+
onProgress: (msg) => update(packageName, "embedding", msg, versionKey)
|
|
1047
|
+
});
|
|
1048
|
+
const hasChangelog = detectChangelog(resolvePkgDir(packageName, cwd, version));
|
|
1049
|
+
const relatedSkills = await findRelatedSkills(packageName, baseDir);
|
|
1050
|
+
const shippedDocs = hasShippedDocs(packageName, cwd, version);
|
|
1051
|
+
const pkgFiles = getPkgKeyFiles(packageName, cwd, version);
|
|
1052
|
+
const repoSlug = resolved.repoUrl?.match(/github\.com\/([^/]+\/[^/]+?)(?:\.git)?(?:[/#]|$)/)?.[1];
|
|
1053
|
+
linkPkgNamed(skillDir, packageName, cwd, version);
|
|
1054
|
+
writeLock(baseDir, skillDirName, {
|
|
1055
|
+
packageName,
|
|
1056
|
+
version,
|
|
1057
|
+
repo: repoSlug,
|
|
1058
|
+
source: resources.docSource,
|
|
1059
|
+
syncedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
1060
|
+
generator: "skilld"
|
|
1061
|
+
});
|
|
1062
|
+
const updatedLock = readLock(baseDir)?.skills[skillDirName];
|
|
1063
|
+
const allPackages = parsePackages(updatedLock?.packages).map((p) => ({ name: p.name }));
|
|
1064
|
+
const skillMd = generateSkillMd({
|
|
1065
|
+
name: packageName,
|
|
1066
|
+
version,
|
|
1067
|
+
releasedAt: resolved.releasedAt,
|
|
1068
|
+
description: resolved.description,
|
|
1069
|
+
dependencies: resolved.dependencies,
|
|
1070
|
+
distTags: resolved.distTags,
|
|
1071
|
+
relatedSkills,
|
|
1072
|
+
hasIssues: resources.hasIssues,
|
|
1073
|
+
hasDiscussions: resources.hasDiscussions,
|
|
1074
|
+
hasReleases: resources.hasReleases,
|
|
1075
|
+
hasChangelog,
|
|
1076
|
+
docsType: resources.docsType,
|
|
1077
|
+
hasShippedDocs: shippedDocs,
|
|
1078
|
+
pkgFiles,
|
|
1079
|
+
dirName: skillDirName,
|
|
1080
|
+
packages: allPackages.length > 1 ? allPackages : void 0,
|
|
1081
|
+
repoUrl: resolved.repoUrl
|
|
1082
|
+
});
|
|
1083
|
+
writeFileSync(join(skillDir, "SKILL.md"), skillMd);
|
|
1084
|
+
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1085
|
+
if (shared) linkSkillToAgents(skillDirName, shared, cwd);
|
|
1086
|
+
if (!config.global) registerProject(cwd);
|
|
1087
|
+
update(packageName, "done", "Base skill created", versionKey);
|
|
1088
|
+
return {
|
|
1089
|
+
resolved,
|
|
1090
|
+
version,
|
|
1091
|
+
skillDirName,
|
|
1092
|
+
docsType: resources.docsType,
|
|
1093
|
+
hasIssues: resources.hasIssues,
|
|
1094
|
+
hasDiscussions: resources.hasDiscussions,
|
|
1095
|
+
hasReleases: resources.hasReleases,
|
|
1096
|
+
hasChangelog,
|
|
1097
|
+
shippedDocs,
|
|
1098
|
+
pkgFiles,
|
|
1099
|
+
relatedSkills,
|
|
1100
|
+
packages: allPackages.length > 1 ? allPackages : void 0
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
async function enhanceWithLLM(packageName, data, config, cwd, update, sections, customPrompt) {
|
|
1104
|
+
const versionKey = getVersionKey(data.version);
|
|
1105
|
+
const skillDir = join(resolveBaseDir(cwd, config.agent, config.global), data.skillDirName);
|
|
1106
|
+
const hasGithub = data.hasIssues || data.hasDiscussions;
|
|
1107
|
+
const docFiles = listReferenceFiles(skillDir);
|
|
1108
|
+
update(packageName, "generating", config.model, versionKey);
|
|
1109
|
+
const { optimized, wasOptimized, error } = await optimizeDocs({
|
|
1110
|
+
packageName,
|
|
1111
|
+
skillDir,
|
|
1112
|
+
model: config.model,
|
|
1113
|
+
version: data.version,
|
|
1114
|
+
hasGithub,
|
|
1115
|
+
hasReleases: data.hasReleases,
|
|
1116
|
+
hasChangelog: data.hasChangelog,
|
|
1117
|
+
docFiles,
|
|
1118
|
+
docsType: data.docsType,
|
|
1119
|
+
hasShippedDocs: data.shippedDocs,
|
|
1120
|
+
noCache: config.force,
|
|
1121
|
+
debug: config.debug,
|
|
1122
|
+
sections,
|
|
1123
|
+
customPrompt,
|
|
1124
|
+
onProgress: (progress) => {
|
|
1125
|
+
const status = progress.type === "reasoning" ? "exploring" : "generating";
|
|
1126
|
+
const sectionPrefix = progress.section ? `[${progress.section}] ` : "";
|
|
1127
|
+
update(packageName, status, progress.chunk.startsWith("[") ? `${sectionPrefix}${progress.chunk}` : `${sectionPrefix}${config.model}`, versionKey);
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
if (error) {
|
|
1131
|
+
update(packageName, "error", error, versionKey);
|
|
1132
|
+
throw new Error(error);
|
|
1133
|
+
}
|
|
1134
|
+
if (wasOptimized) {
|
|
1135
|
+
const skillMd = generateSkillMd({
|
|
1136
|
+
name: packageName,
|
|
1137
|
+
version: data.version,
|
|
1138
|
+
releasedAt: data.resolved.releasedAt,
|
|
1139
|
+
dependencies: data.resolved.dependencies,
|
|
1140
|
+
distTags: data.resolved.distTags,
|
|
1141
|
+
body: optimized,
|
|
1142
|
+
relatedSkills: data.relatedSkills,
|
|
1143
|
+
hasIssues: data.hasIssues,
|
|
1144
|
+
hasDiscussions: data.hasDiscussions,
|
|
1145
|
+
hasReleases: data.hasReleases,
|
|
1146
|
+
hasChangelog: data.hasChangelog,
|
|
1147
|
+
docsType: data.docsType,
|
|
1148
|
+
hasShippedDocs: data.shippedDocs,
|
|
1149
|
+
pkgFiles: data.pkgFiles,
|
|
1150
|
+
dirName: data.skillDirName,
|
|
1151
|
+
packages: data.packages,
|
|
1152
|
+
repoUrl: data.resolved.repoUrl
|
|
1153
|
+
});
|
|
1154
|
+
writeFileSync(join(skillDir, "SKILL.md"), skillMd);
|
|
1155
|
+
}
|
|
1156
|
+
update(packageName, "done", "Skill optimized", versionKey);
|
|
1157
|
+
}
|
|
874
1158
|
function showResolveAttempts(attempts) {
|
|
875
1159
|
if (attempts.length === 0) return;
|
|
876
1160
|
p.log.message("\x1B[90mResolution attempts:\x1B[0m");
|
|
@@ -901,30 +1185,8 @@ async function ensureGitignore(skillsDir, cwd, isGlobal) {
|
|
|
901
1185
|
}
|
|
902
1186
|
async function syncCommand(state, opts) {
|
|
903
1187
|
if (opts.packages && opts.packages.length > 0) {
|
|
904
|
-
if (opts.packages.length > 1) {
|
|
905
|
-
|
|
906
|
-
return syncPackagesParallel({
|
|
907
|
-
packages: opts.packages,
|
|
908
|
-
global: opts.global,
|
|
909
|
-
agent: opts.agent,
|
|
910
|
-
model: opts.model,
|
|
911
|
-
yes: opts.yes,
|
|
912
|
-
force: opts.force,
|
|
913
|
-
debug: opts.debug
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
await syncSinglePackage(opts.packages[0], opts);
|
|
917
|
-
return;
|
|
918
|
-
}
|
|
919
|
-
const packages = await interactivePicker(state);
|
|
920
|
-
if (!packages || packages.length === 0) {
|
|
921
|
-
p.outro("No packages selected");
|
|
922
|
-
return;
|
|
923
|
-
}
|
|
924
|
-
if (packages.length > 1) {
|
|
925
|
-
const { syncPackagesParallel } = await import("./_chunks/sync-parallel.mjs");
|
|
926
|
-
return syncPackagesParallel({
|
|
927
|
-
packages,
|
|
1188
|
+
if (opts.packages.length > 1) return syncPackagesParallel({
|
|
1189
|
+
packages: opts.packages,
|
|
928
1190
|
global: opts.global,
|
|
929
1191
|
agent: opts.agent,
|
|
930
1192
|
model: opts.model,
|
|
@@ -932,7 +1194,23 @@ async function syncCommand(state, opts) {
|
|
|
932
1194
|
force: opts.force,
|
|
933
1195
|
debug: opts.debug
|
|
934
1196
|
});
|
|
1197
|
+
await syncSinglePackage(opts.packages[0], opts);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const packages = await interactivePicker(state);
|
|
1201
|
+
if (!packages || packages.length === 0) {
|
|
1202
|
+
p.outro("No packages selected");
|
|
1203
|
+
return;
|
|
935
1204
|
}
|
|
1205
|
+
if (packages.length > 1) return syncPackagesParallel({
|
|
1206
|
+
packages,
|
|
1207
|
+
global: opts.global,
|
|
1208
|
+
agent: opts.agent,
|
|
1209
|
+
model: opts.model,
|
|
1210
|
+
yes: opts.yes,
|
|
1211
|
+
force: opts.force,
|
|
1212
|
+
debug: opts.debug
|
|
1213
|
+
});
|
|
936
1214
|
await syncSinglePackage(packages[0], opts);
|
|
937
1215
|
}
|
|
938
1216
|
async function interactivePicker(state) {
|
|
@@ -1299,7 +1577,6 @@ async function syncSinglePackage(packageName, config) {
|
|
|
1299
1577
|
if (shared) linkSkillToAgents(skillDirName, shared, cwd);
|
|
1300
1578
|
if (!config.global) registerProject(cwd);
|
|
1301
1579
|
await ensureGitignore(shared ? SHARED_SKILLS_DIR : targets[config.agent].skillsDir, cwd, config.global);
|
|
1302
|
-
const { shutdownWorker } = await import("./_chunks/pool.mjs");
|
|
1303
1580
|
await shutdownWorker();
|
|
1304
1581
|
p.outro(`Synced ${packageName} to ${relative(cwd, skillDir)}`);
|
|
1305
1582
|
}
|
|
@@ -1414,7 +1691,6 @@ async function installCommand(opts) {
|
|
|
1414
1691
|
continue;
|
|
1415
1692
|
}
|
|
1416
1693
|
if (info.source === "github" || info.source === "gitlab" || info.source === "local") {
|
|
1417
|
-
const { fetchGitSkills } = await import("./_chunks/git-skills.mjs").then((n) => n.n);
|
|
1418
1694
|
const match = (await fetchGitSkills({
|
|
1419
1695
|
type: info.source,
|
|
1420
1696
|
...info.repo?.includes("/") ? {
|
|
@@ -1426,8 +1702,6 @@ async function installCommand(opts) {
|
|
|
1426
1702
|
...info.source === "local" ? { localPath: info.repo } : {}
|
|
1427
1703
|
})).skills.find((s) => s.name === name);
|
|
1428
1704
|
if (match) {
|
|
1429
|
-
const { sanitizeMarkdown } = await import("./_chunks/sanitize2.mjs").then((n) => n.r);
|
|
1430
|
-
const { dirname } = await import("pathe");
|
|
1431
1705
|
const skillDir = join(skillsDir, name);
|
|
1432
1706
|
mkdirSync(skillDir, { recursive: true });
|
|
1433
1707
|
writeFileSync(join(skillDir, "SKILL.md"), sanitizeMarkdown(match.content));
|
|
@@ -1642,7 +1916,6 @@ async function installCommand(opts) {
|
|
|
1642
1916
|
for (const [name, info] of Object.entries(lock.skills)) writeLock(skillsDir, name, info);
|
|
1643
1917
|
if (shared) for (const [name] of skills) linkSkillToAgents(name, shared, cwd);
|
|
1644
1918
|
else syncLockfilesToDirs(lock, allSkillsDirs.filter((d) => d !== skillsDir));
|
|
1645
|
-
const { shutdownWorker } = await import("./_chunks/pool.mjs");
|
|
1646
1919
|
await shutdownWorker();
|
|
1647
1920
|
p.outro("Install complete");
|
|
1648
1921
|
}
|
|
@@ -2716,6 +2989,61 @@ async function runWizard() {
|
|
|
2716
2989
|
});
|
|
2717
2990
|
p.outro("Thanks, you're all set! Change config anytime with `skilld config`.");
|
|
2718
2991
|
}
|
|
2992
|
+
async function syncGitSkills(opts) {
|
|
2993
|
+
const { source, agent, global: isGlobal, yes } = opts;
|
|
2994
|
+
const cwd = process.cwd();
|
|
2995
|
+
const agentConfig = targets[agent];
|
|
2996
|
+
const baseDir = isGlobal ? join(CACHE_DIR, "skills") : join(cwd, agentConfig.skillsDir);
|
|
2997
|
+
const label = source.type === "local" ? source.localPath : `${source.owner}/${source.repo}`;
|
|
2998
|
+
const spin = timedSpinner();
|
|
2999
|
+
spin.start(`Fetching skills from ${label}`);
|
|
3000
|
+
const { skills, commitSha } = await fetchGitSkills(source, (msg) => spin.message(msg));
|
|
3001
|
+
if (skills.length === 0) {
|
|
3002
|
+
spin.stop(`No skills found in ${label}`);
|
|
3003
|
+
return;
|
|
3004
|
+
}
|
|
3005
|
+
spin.stop(`Found ${skills.length} skill(s) in ${label}`);
|
|
3006
|
+
let selected = skills;
|
|
3007
|
+
if (source.skillPath) selected = skills;
|
|
3008
|
+
else if (skills.length > 1 && !yes) {
|
|
3009
|
+
const choices = await p.multiselect({
|
|
3010
|
+
message: `Select skills to install from ${label}`,
|
|
3011
|
+
options: skills.map((s) => ({
|
|
3012
|
+
label: s.name,
|
|
3013
|
+
value: s.name,
|
|
3014
|
+
hint: s.description || s.path
|
|
3015
|
+
})),
|
|
3016
|
+
initialValues: skills.map((s) => s.name)
|
|
3017
|
+
});
|
|
3018
|
+
if (p.isCancel(choices)) return;
|
|
3019
|
+
const selectedNames = new Set(choices);
|
|
3020
|
+
selected = skills.filter((s) => selectedNames.has(s.name));
|
|
3021
|
+
}
|
|
3022
|
+
mkdirSync(baseDir, { recursive: true });
|
|
3023
|
+
for (const skill of selected) {
|
|
3024
|
+
const skillDir = join(baseDir, skill.name);
|
|
3025
|
+
mkdirSync(skillDir, { recursive: true });
|
|
3026
|
+
writeFileSync(join(skillDir, "SKILL.md"), sanitizeMarkdown(skill.content));
|
|
3027
|
+
if (skill.files.length > 0) for (const f of skill.files) {
|
|
3028
|
+
const filePath = join(skillDir, ".skilld", f.path);
|
|
3029
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
3030
|
+
writeFileSync(filePath, f.content);
|
|
3031
|
+
}
|
|
3032
|
+
const sourceType = source.type === "local" ? "local" : source.type;
|
|
3033
|
+
writeLock(baseDir, skill.name, {
|
|
3034
|
+
source: sourceType,
|
|
3035
|
+
repo: source.type === "local" ? source.localPath : `${source.owner}/${source.repo}`,
|
|
3036
|
+
path: skill.path || void 0,
|
|
3037
|
+
ref: source.ref || "main",
|
|
3038
|
+
commit: commitSha,
|
|
3039
|
+
syncedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
3040
|
+
generator: "external"
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3043
|
+
if (!isGlobal) registerProject(cwd);
|
|
3044
|
+
const names = selected.map((s) => `\x1B[36m${s.name}\x1B[0m`).join(", ");
|
|
3045
|
+
p.log.success(`Installed ${names}`);
|
|
3046
|
+
}
|
|
2719
3047
|
const _emit = process.emit;
|
|
2720
3048
|
process.emit = (event, ...args) => event === "warning" && args[0]?.name === "ExperimentalWarning" && args[0]?.message?.includes("SQLite") ? false : _emit.apply(process, [event, ...args]);
|
|
2721
3049
|
function getRepoHint(name, cwd) {
|
|
@@ -2959,8 +3287,6 @@ const addCommand = defineCommand({
|
|
|
2959
3287
|
if (!agent) return;
|
|
2960
3288
|
}
|
|
2961
3289
|
const rawInputs = [...new Set([args.package, ...args._ || []].map((s) => s.trim()).filter(Boolean))];
|
|
2962
|
-
const { parseGitSkillInput } = await import("./_chunks/git-skills.mjs").then((n) => n.n);
|
|
2963
|
-
const { syncGitSkills } = await import("./_chunks/sync-git.mjs");
|
|
2964
3290
|
const gitSources = [];
|
|
2965
3291
|
const npmTokens = [];
|
|
2966
3292
|
for (const input of rawInputs) {
|
|
@@ -3232,7 +3558,6 @@ runMain(defineCommand({
|
|
|
3232
3558
|
const cwd = process.cwd();
|
|
3233
3559
|
if (args.prepare) {
|
|
3234
3560
|
if (args.background) {
|
|
3235
|
-
const { spawn } = await import("node:child_process");
|
|
3236
3561
|
spawn(process.execPath, [
|
|
3237
3562
|
process.argv[1],
|
|
3238
3563
|
"--prepare",
|
|
@@ -3579,6 +3904,6 @@ runMain(defineCommand({
|
|
|
3579
3904
|
}
|
|
3580
3905
|
}
|
|
3581
3906
|
}));
|
|
3582
|
-
export {
|
|
3907
|
+
export {};
|
|
3583
3908
|
|
|
3584
3909
|
//# sourceMappingURL=cli.mjs.map
|