skilld 0.3.1 → 0.4.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 +9 -8
- package/dist/_chunks/detect-imports.mjs +51 -37
- package/dist/_chunks/detect-imports.mjs.map +1 -1
- package/dist/_chunks/git-skills.mjs +319 -0
- package/dist/_chunks/git-skills.mjs.map +1 -0
- package/dist/_chunks/releases.mjs +2 -61
- package/dist/_chunks/releases.mjs.map +1 -1
- package/dist/_chunks/sanitize2.mjs +249 -0
- package/dist/_chunks/sanitize2.mjs.map +1 -0
- package/dist/_chunks/storage.mjs +2 -241
- package/dist/_chunks/storage.mjs.map +1 -1
- package/dist/_chunks/sync-git.mjs +69 -0
- package/dist/_chunks/sync-git.mjs.map +1 -0
- package/dist/_chunks/sync-parallel.mjs +10 -4
- package/dist/_chunks/sync-parallel.mjs.map +1 -1
- package/dist/_chunks/utils.d.mts +54 -1
- package/dist/_chunks/utils.d.mts.map +1 -1
- package/dist/_chunks/yaml.mjs +24 -0
- package/dist/_chunks/yaml.mjs.map +1 -0
- package/dist/agent/index.d.mts +11 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +2 -2
- package/dist/cli.mjs +150 -29
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/sources/index.d.mts +2 -2
- package/dist/sources/index.mjs +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,22 +34,23 @@ Skilld leverages maintainers existing effort. Maintainers write great docs for u
|
|
|
34
34
|
|
|
35
35
|
## Features
|
|
36
36
|
|
|
37
|
-
- 🌍 **
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
37
|
+
- 🌍 **Any Source: Opt-in** - Any NPM dependency or GitHub source, docs auto-resolved
|
|
38
|
+
- 📦 **Bleeding Edge Context** - Latest issues, discussions, and releases synced on
|
|
39
|
+
every update. Always use the latest best practices and avoid deprecated patterns.
|
|
40
|
+
- 📚 **Opt-in LLM Sections** - Enhance skills with LLM-generated `Best practices`, `LLM Gaps`, `Doc Map`, or your own prompts
|
|
41
|
+
- 🔍 **Semantic Search** - Query indexed docs across all skills via [retriv](https://github.com/harlan-zw/retriv) embeddings
|
|
42
|
+
- 🎯 **Safe & Versioned** - Prompt injection sanitization, version-aware caching, auto-updates on new releases
|
|
43
|
+
- 🤝 **Ecosystem** - Compatible with [`npx skills`](https://skills.sh/) and [skills-npm](https://github.com/antfu/skills-npm)
|
|
43
44
|
|
|
44
45
|
## Quick Start
|
|
45
46
|
|
|
46
47
|
Run skilld in a project to generate skills for your dependencies through a simple interactive wizard:
|
|
47
48
|
|
|
48
49
|
```bash
|
|
49
|
-
npx skilld
|
|
50
|
+
npx -y skilld
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
If you need to re-configure skilld, just run `npx skilld config` to update your agent, model, or preferences.
|
|
53
|
+
If you need to re-configure skilld, just run `npx -y skilld config` to update your agent, model, or preferences.
|
|
53
54
|
|
|
54
55
|
### Tips
|
|
55
56
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as sanitizeMarkdown, t as repairMarkdown } from "./sanitize2.mjs";
|
|
2
|
+
import { _ as writeSections, h as readCachedSection } from "./storage.mjs";
|
|
3
|
+
import { t as yamlEscape } from "./yaml.mjs";
|
|
2
4
|
import { createRequire } from "node:module";
|
|
3
5
|
import { homedir } from "node:os";
|
|
4
|
-
import { dirname, join } from "pathe";
|
|
5
|
-
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, join, relative } from "pathe";
|
|
7
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
8
|
import { exec, spawn, spawnSync } from "node:child_process";
|
|
7
9
|
import { globby } from "globby";
|
|
8
10
|
import { findDynamicImports, findStaticImports } from "mlly";
|
|
@@ -18,7 +20,6 @@ var __exportAll = (all, no_symbols) => {
|
|
|
18
20
|
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
19
21
|
return target;
|
|
20
22
|
};
|
|
21
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
22
23
|
const SPEC_FRONTMATTER = {
|
|
23
24
|
"name": {
|
|
24
25
|
name: "name",
|
|
@@ -696,16 +697,24 @@ function generateImportantBlock({ packageName, hasIssues, hasDiscussions, hasRel
|
|
|
696
697
|
if (hasDiscussions) rows.push(["Discussions", `\`${skillDir}/.skilld/discussions/\``]);
|
|
697
698
|
if (hasChangelog) rows.push(["Changelog", `\`${skillDir}/.skilld/pkg/${hasChangelog}\``]);
|
|
698
699
|
if (hasReleases) rows.push(["Releases", `\`${skillDir}/.skilld/releases/\``]);
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
| Resource | Command |
|
|
702
|
-
|----------|---------|
|
|
703
|
-
| Search all | \`Bash 'npx skilld search "<query>" -p ${packageName}'\` |
|
|
704
|
-
${[
|
|
700
|
+
const table = [
|
|
705
701
|
"| Resource | Path |",
|
|
706
702
|
"|----------|------|",
|
|
707
703
|
...rows.map(([desc, cmd]) => `| ${desc} | ${cmd} |`)
|
|
708
|
-
].join("\n")
|
|
704
|
+
].join("\n");
|
|
705
|
+
return `**IMPORTANT:** Use these references
|
|
706
|
+
|
|
707
|
+
## Search
|
|
708
|
+
|
|
709
|
+
Use \`npx -y skilld search\` as your primary research tool — search before manually reading files. Hybrid semantic + keyword search across all indexed docs, issues, and releases.
|
|
710
|
+
|
|
711
|
+
\`\`\`bash
|
|
712
|
+
npx -y skilld search "<query>" -p ${packageName}
|
|
713
|
+
${hasIssues ? `npx -y skilld search "issues:<query>" -p ${packageName}\n` : ""}${hasReleases ? `npx -y skilld search "releases:<query>" -p ${packageName}\n` : ""}\`\`\`
|
|
714
|
+
|
|
715
|
+
Filters: \`docs:\`, \`issues:\`, \`releases:\` prefix narrows by source type.
|
|
716
|
+
|
|
717
|
+
${table}`;
|
|
709
718
|
}
|
|
710
719
|
function buildPreamble(opts) {
|
|
711
720
|
const { packageName, skillDir, hasIssues, hasDiscussions, hasReleases, hasChangelog, docFiles, docsType = "docs", hasShippedDocs = false, versionContext } = opts;
|
|
@@ -804,27 +813,6 @@ function buildAllSectionPrompts(opts) {
|
|
|
804
813
|
}
|
|
805
814
|
return result;
|
|
806
815
|
}
|
|
807
|
-
const NEEDS_QUOTING = /[:"'\\\n\r\t#{}[\],&*!|>%@`]/;
|
|
808
|
-
function yamlEscape(value) {
|
|
809
|
-
if (!NEEDS_QUOTING.test(value)) return value;
|
|
810
|
-
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")}"`;
|
|
811
|
-
}
|
|
812
|
-
function yamlUnescape(raw) {
|
|
813
|
-
const trimmed = raw.trim();
|
|
814
|
-
if (!trimmed) return "";
|
|
815
|
-
if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) return trimmed.slice(1, -1).replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, "\"").replace(/\\\\/g, "\\");
|
|
816
|
-
if (trimmed.startsWith("'") && trimmed.endsWith("'")) return trimmed.slice(1, -1);
|
|
817
|
-
return trimmed;
|
|
818
|
-
}
|
|
819
|
-
function yamlParseKV(line) {
|
|
820
|
-
const trimmed = line.trim();
|
|
821
|
-
const colonIdx = trimmed.indexOf(":");
|
|
822
|
-
if (colonIdx === -1) return null;
|
|
823
|
-
const key = trimmed.slice(0, colonIdx).trim();
|
|
824
|
-
const rawValue = trimmed.slice(colonIdx + 1);
|
|
825
|
-
if (!key) return null;
|
|
826
|
-
return [key, yamlUnescape(rawValue)];
|
|
827
|
-
}
|
|
828
816
|
function sanitizeName(name) {
|
|
829
817
|
return name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").slice(0, 255) || "unnamed-skill";
|
|
830
818
|
}
|
|
@@ -858,6 +846,32 @@ function installSkillForAgents(skillName, skillContent, options = {}) {
|
|
|
858
846
|
paths
|
|
859
847
|
};
|
|
860
848
|
}
|
|
849
|
+
function linkSkillToAgents(skillName, sharedDir, cwd) {
|
|
850
|
+
for (const [, agent] of Object.entries(targets)) {
|
|
851
|
+
const agentSkillsDir = join(cwd, agent.skillsDir);
|
|
852
|
+
if (!existsSync(join(cwd, agent.skillsDir.split("/")[0]))) continue;
|
|
853
|
+
const target = join(agentSkillsDir, skillName);
|
|
854
|
+
let isSymlink = false;
|
|
855
|
+
let targetExists = false;
|
|
856
|
+
try {
|
|
857
|
+
const stat = lstatSync(target);
|
|
858
|
+
targetExists = true;
|
|
859
|
+
isSymlink = stat.isSymbolicLink();
|
|
860
|
+
} catch {}
|
|
861
|
+
if (targetExists && !isSymlink) continue;
|
|
862
|
+
if (isSymlink) unlinkSync(target);
|
|
863
|
+
mkdirSync(agentSkillsDir, { recursive: true });
|
|
864
|
+
symlinkSync(relative(agentSkillsDir, join(sharedDir, skillName)), target);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
function unlinkSkillFromAgents(skillName, cwd) {
|
|
868
|
+
for (const [, agent] of Object.entries(targets)) {
|
|
869
|
+
const target = join(cwd, agent.skillsDir, skillName);
|
|
870
|
+
try {
|
|
871
|
+
if (lstatSync(target).isSymbolicLink()) unlinkSync(target);
|
|
872
|
+
} catch {}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
861
875
|
const FILE_PATTERN_MAP = {
|
|
862
876
|
"vue": ["*.vue"],
|
|
863
877
|
"svelte": ["*.svelte"],
|
|
@@ -1019,12 +1033,12 @@ function generateFrontmatter({ name, version, description: pkgDescription, globs
|
|
|
1019
1033
|
return lines.join("\n");
|
|
1020
1034
|
}
|
|
1021
1035
|
function generateSearchBlock(name, hasIssues, hasReleases) {
|
|
1022
|
-
const examples = [`npx skilld search "query" -p ${name}`];
|
|
1023
|
-
if (hasIssues) examples.push(`npx skilld search "issues:error handling" -p ${name}`);
|
|
1024
|
-
if (hasReleases) examples.push(`npx skilld search "releases:deprecated" -p ${name}`);
|
|
1036
|
+
const examples = [`npx -y skilld search "query" -p ${name}`];
|
|
1037
|
+
if (hasIssues) examples.push(`npx -y skilld search "issues:error handling" -p ${name}`);
|
|
1038
|
+
if (hasReleases) examples.push(`npx -y skilld search "releases:deprecated" -p ${name}`);
|
|
1025
1039
|
return `## Search
|
|
1026
1040
|
|
|
1027
|
-
Use \`npx skilld search\` instead of grepping \`.skilld/\` directories — hybrid semantic + keyword search across all indexed docs, issues, and releases.
|
|
1041
|
+
Use \`npx -y skilld search\` instead of grepping \`.skilld/\` directories — hybrid semantic + keyword search across all indexed docs, issues, and releases.
|
|
1028
1042
|
|
|
1029
1043
|
\`\`\`bash
|
|
1030
1044
|
${examples.join("\n")}
|
|
@@ -1833,6 +1847,6 @@ function isNodeBuiltin(pkg) {
|
|
|
1833
1847
|
const base = pkg.startsWith("node:") ? pkg.slice(5) : pkg;
|
|
1834
1848
|
return NODE_BUILTINS.has(base.split("/")[0]);
|
|
1835
1849
|
}
|
|
1836
|
-
export {
|
|
1850
|
+
export { detectInstalledAgents as _, optimizeDocs as a, targets as b, computeSkillDirName as c, sanitizeName as d, unlinkSkillFromAgents as f, buildSectionPrompt as g, buildAllSectionPrompts as h, getModelName as i, installSkillForAgents as l, SECTION_OUTPUT_FILES as m, getAvailableModels as n, generateSkillMd as o, SECTION_MERGE_ORDER as p, getModelLabel as r, FILE_PATTERN_MAP as s, detectImportedPackages as t, linkSkillToAgents as u, detectTargetAgent as v, __exportAll as x, getAgentVersion as y };
|
|
1837
1851
|
|
|
1838
1852
|
//# sourceMappingURL=detect-imports.mjs.map
|