skilld 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/detect-imports.mjs +12 -4
- package/dist/_chunks/detect-imports.mjs.map +1 -1
- package/dist/_chunks/markdown.mjs +76 -0
- package/dist/_chunks/markdown.mjs.map +1 -0
- package/dist/_chunks/npm.mjs +87 -32
- package/dist/_chunks/npm.mjs.map +1 -1
- package/dist/_chunks/package-registry.mjs +445 -0
- package/dist/_chunks/package-registry.mjs.map +1 -0
- package/dist/_chunks/utils.d.mts +16 -1
- package/dist/_chunks/utils.d.mts.map +1 -1
- package/dist/_chunks/yaml.mjs +1 -443
- package/dist/_chunks/yaml.mjs.map +1 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/cli.mjs +43 -26
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/retriv/index.d.mts.map +1 -1
- package/dist/retriv/index.mjs +1 -4
- package/dist/retriv/index.mjs.map +1 -1
- package/dist/sources/index.d.mts +2 -2
- package/dist/sources/index.mjs +4 -3
- package/package.json +8 -3
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { n as yamlParseKV } from "./yaml.mjs";
|
|
2
|
+
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
3
|
+
import { frontmatterFromMarkdown } from "mdast-util-frontmatter";
|
|
4
|
+
import { toString } from "mdast-util-to-string";
|
|
5
|
+
import { frontmatter } from "micromark-extension-frontmatter";
|
|
6
|
+
import { visit } from "unist-util-visit";
|
|
7
|
+
function parseMd(content) {
|
|
8
|
+
const tree = fromMarkdown(content, {
|
|
9
|
+
extensions: [frontmatter(["yaml"])],
|
|
10
|
+
mdastExtensions: [frontmatterFromMarkdown(["yaml"])]
|
|
11
|
+
});
|
|
12
|
+
const fm = {};
|
|
13
|
+
visit(tree, "yaml", (node) => {
|
|
14
|
+
if (node.type === "yaml") for (const line of node.value.split("\n")) {
|
|
15
|
+
const kv = yamlParseKV(line);
|
|
16
|
+
if (kv) fm[kv[0]] = kv[1];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
tree,
|
|
21
|
+
frontmatter: fm
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function parseFrontmatter(content) {
|
|
25
|
+
return parseMd(content).frontmatter;
|
|
26
|
+
}
|
|
27
|
+
function stripHeadingAnchors(text) {
|
|
28
|
+
return text.replace(/\s*\{#[^}]+\}\s*$/, "").trim();
|
|
29
|
+
}
|
|
30
|
+
function extractTitle(content) {
|
|
31
|
+
const { tree, frontmatter: fm } = parseMd(content);
|
|
32
|
+
if (fm.title) return fm.title;
|
|
33
|
+
let title = null;
|
|
34
|
+
visit(tree, "heading", (node) => {
|
|
35
|
+
if (node.depth === 1 && !title) {
|
|
36
|
+
const text = stripHeadingAnchors(toString(node)).replace(/^\\+\s*/, "").trim();
|
|
37
|
+
if (text.length > 0) title = text;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return title;
|
|
41
|
+
}
|
|
42
|
+
function extractDescription(content) {
|
|
43
|
+
const { tree } = parseMd(content);
|
|
44
|
+
let desc = null;
|
|
45
|
+
visit(tree, "paragraph", (node, _index, parent) => {
|
|
46
|
+
if (desc || parent?.type !== "root") return;
|
|
47
|
+
const text = toString(node).trim();
|
|
48
|
+
if (text.length === 0) return;
|
|
49
|
+
let clean = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[`*_~]/g, "");
|
|
50
|
+
if (clean.length > 150) clean = `${clean.slice(0, 147)}...`;
|
|
51
|
+
desc = clean;
|
|
52
|
+
});
|
|
53
|
+
return desc;
|
|
54
|
+
}
|
|
55
|
+
function extractLinks(content) {
|
|
56
|
+
const { tree } = parseMd(content);
|
|
57
|
+
const links = [];
|
|
58
|
+
const seen = /* @__PURE__ */ new Set();
|
|
59
|
+
visit(tree, "link", (node) => {
|
|
60
|
+
if (!seen.has(node.url)) {
|
|
61
|
+
seen.add(node.url);
|
|
62
|
+
links.push({
|
|
63
|
+
title: toString(node),
|
|
64
|
+
url: node.url
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return links;
|
|
69
|
+
}
|
|
70
|
+
function stripFrontmatter(content) {
|
|
71
|
+
const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/);
|
|
72
|
+
return match ? content.slice(match[0].length).trim() : content;
|
|
73
|
+
}
|
|
74
|
+
export { stripFrontmatter as a, parseFrontmatter as i, extractLinks as n, extractTitle as r, extractDescription as t };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=markdown.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.mjs","names":[],"sources":["../../src/core/markdown.ts"],"sourcesContent":["/**\n * AST-based markdown parsing using mdast/micromark.\n * Replaces scattered regex-based frontmatter/heading/link extraction.\n */\n\nimport type { Nodes, Root } from 'mdast'\nimport { fromMarkdown } from 'mdast-util-from-markdown'\nimport { frontmatterFromMarkdown } from 'mdast-util-frontmatter'\nimport { toString } from 'mdast-util-to-string'\nimport { frontmatter } from 'micromark-extension-frontmatter'\nimport { visit } from 'unist-util-visit'\nimport { yamlParseKV } from './yaml.ts'\n\nexport interface MdHeading {\n depth: number\n text: string\n}\n\nexport interface MdLink {\n title: string\n url: string\n}\n\nexport interface ParsedMd {\n tree: Root\n frontmatter: Record<string, string>\n}\n\n/** Parse markdown string to AST + frontmatter key-values */\nexport function parseMd(content: string): ParsedMd {\n const tree = fromMarkdown(content, {\n extensions: [frontmatter(['yaml'])],\n mdastExtensions: [frontmatterFromMarkdown(['yaml'])],\n })\n\n const fm: Record<string, string> = {}\n visit(tree, 'yaml', (node: Nodes) => {\n if (node.type === 'yaml') {\n for (const line of (node as any).value.split('\\n')) {\n const kv = yamlParseKV(line)\n if (kv)\n fm[kv[0]] = kv[1]\n }\n }\n })\n\n return { tree, frontmatter: fm }\n}\n\n/** Extract frontmatter key-value pairs only */\nexport function parseFrontmatter(content: string): Record<string, string> {\n return parseMd(content).frontmatter\n}\n\n/** Strip custom heading anchors like {#some-id} */\nfunction stripHeadingAnchors(text: string): string {\n return text.replace(/\\s*\\{#[^}]+\\}\\s*$/, '').trim()\n}\n\n/** Extract title: frontmatter title > first h1 > null */\nexport function extractTitle(content: string): string | null {\n const { tree, frontmatter: fm } = parseMd(content)\n if (fm.title)\n return fm.title\n\n let title: string | null = null\n visit(tree, 'heading', (node) => {\n if (node.depth === 1 && !title) {\n // Strip {#id} anchors and leading backslash escapes (e.g. `# \\`)\n const text = stripHeadingAnchors(toString(node)).replace(/^\\\\+\\s*/, '').trim()\n if (text.length > 0)\n title = text\n }\n })\n\n return title\n}\n\n/** Extract first paragraph text, 150 char max */\nexport function extractDescription(content: string): string | null {\n const { tree } = parseMd(content)\n\n let desc: string | null = null\n visit(tree, 'paragraph', (node, _index, parent) => {\n // Only top-level paragraphs (skip blockquote children, list items, etc.)\n if (desc || parent?.type !== 'root')\n return\n\n const text = toString(node).trim()\n if (text.length === 0)\n return\n\n // Strip markdown link syntax remnants and formatting chars\n let clean = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1').replace(/[`*_~]/g, '')\n if (clean.length > 150)\n clean = `${clean.slice(0, 147)}...`\n desc = clean\n })\n\n return desc\n}\n\n/** Extract all headings with depth and text */\nexport function extractHeadings(content: string): MdHeading[] {\n const { tree } = parseMd(content)\n const headings: MdHeading[] = []\n\n visit(tree, 'heading', (node) => {\n headings.push({ depth: node.depth, text: stripHeadingAnchors(toString(node)) })\n })\n\n return headings\n}\n\n/** Extract all links (deduped by url) */\nexport function extractLinks(content: string): MdLink[] {\n const { tree } = parseMd(content)\n const links: MdLink[] = []\n const seen = new Set<string>()\n\n visit(tree, 'link', (node) => {\n if (!seen.has(node.url)) {\n seen.add(node.url)\n links.push({ title: toString(node), url: node.url })\n }\n })\n\n return links\n}\n\n/** Strip frontmatter block, return body only */\nexport function stripFrontmatter(content: string): string {\n const match = content.match(/^---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n/)\n return match ? content.slice(match[0].length).trim() : content\n}\n"],"mappings":";;;;;;AA6BA,SAAgB,QAAQ,SAA2B;CACjD,MAAM,OAAO,aAAa,SAAS;EACjC,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;EACnC,iBAAiB,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;EACpD,CAAC;CAEF,MAAM,KAA6B,EAAE;AACrC,OAAM,MAAM,SAAS,SAAgB;AACnC,MAAI,KAAK,SAAS,OAChB,MAAK,MAAM,QAAS,KAAa,MAAM,MAAM,KAAK,EAAE;GAClD,MAAM,KAAK,YAAY,KAAK;AAC5B,OAAI,GACF,IAAG,GAAG,MAAM,GAAG;;GAGrB;AAEF,QAAO;EAAE;EAAM,aAAa;EAAI;;AAIlC,SAAgB,iBAAiB,SAAyC;AACxE,QAAO,QAAQ,QAAQ,CAAC;;AAI1B,SAAS,oBAAoB,MAAsB;AACjD,QAAO,KAAK,QAAQ,qBAAqB,GAAG,CAAC,MAAM;;AAIrD,SAAgB,aAAa,SAAgC;CAC3D,MAAM,EAAE,MAAM,aAAa,OAAO,QAAQ,QAAQ;AAClD,KAAI,GAAG,MACL,QAAO,GAAG;CAEZ,IAAI,QAAuB;AAC3B,OAAM,MAAM,YAAY,SAAS;AAC/B,MAAI,KAAK,UAAU,KAAK,CAAC,OAAO;GAE9B,MAAM,OAAO,oBAAoB,SAAS,KAAK,CAAC,CAAC,QAAQ,WAAW,GAAG,CAAC,MAAM;AAC9E,OAAI,KAAK,SAAS,EAChB,SAAQ;;GAEZ;AAEF,QAAO;;AAIT,SAAgB,mBAAmB,SAAgC;CACjE,MAAM,EAAE,SAAS,QAAQ,QAAQ;CAEjC,IAAI,OAAsB;AAC1B,OAAM,MAAM,cAAc,MAAM,QAAQ,WAAW;AAEjD,MAAI,QAAQ,QAAQ,SAAS,OAC3B;EAEF,MAAM,OAAO,SAAS,KAAK,CAAC,MAAM;AAClC,MAAI,KAAK,WAAW,EAClB;EAGF,IAAI,QAAQ,KAAK,QAAQ,0BAA0B,KAAK,CAAC,QAAQ,WAAW,GAAG;AAC/E,MAAI,MAAM,SAAS,IACjB,SAAQ,GAAG,MAAM,MAAM,GAAG,IAAI,CAAC;AACjC,SAAO;GACP;AAEF,QAAO;;AAgBT,SAAgB,aAAa,SAA2B;CACtD,MAAM,EAAE,SAAS,QAAQ,QAAQ;CACjC,MAAM,QAAkB,EAAE;CAC1B,MAAM,uBAAO,IAAI,KAAa;AAE9B,OAAM,MAAM,SAAS,SAAS;AAC5B,MAAI,CAAC,KAAK,IAAI,KAAK,IAAI,EAAE;AACvB,QAAK,IAAI,KAAK,IAAI;AAClB,SAAM,KAAK;IAAE,OAAO,SAAS,KAAK;IAAE,KAAK,KAAK;IAAK,CAAC;;GAEtD;AAEF,QAAO;;AAIT,SAAgB,iBAAiB,SAAyB;CACxD,MAAM,QAAQ,QAAQ,MAAM,iCAAiC;AAC7D,QAAO,QAAQ,QAAQ,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG"}
|
package/dist/_chunks/npm.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { i as getCacheDir } from "./config.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { i as parseFrontmatter, n as extractLinks, r as extractTitle, t as extractDescription } from "./markdown.mjs";
|
|
3
|
+
import { n as getDocOverride, t as getBlogPreset } from "./package-registry.mjs";
|
|
3
4
|
import { basename, dirname, join, resolve } from "pathe";
|
|
4
5
|
import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, unlinkSync } from "node:fs";
|
|
5
6
|
import { htmlToMarkdown } from "mdream";
|
|
@@ -755,9 +756,29 @@ function truncateBody(body, limit) {
|
|
|
755
756
|
if (lastParagraph > lastSafeEnd * .6) return `${slice.slice(0, lastParagraph)}\n\n...`;
|
|
756
757
|
return `${slice}...`;
|
|
757
758
|
}
|
|
759
|
+
const TITLE_NOISE_RE = /looking .*(?:developer|engineer|freelanc)|hiring|job post|guide me to (?:complete|finish|build)|help me (?:complete|finish|build)|seeking .* tutorial|recommend.* course/i;
|
|
760
|
+
const MIN_DISCUSSION_SCORE = 3;
|
|
758
761
|
function scoreComment(c) {
|
|
759
762
|
return (c.isMaintainer ? 3 : 1) * (hasCodeBlock(c.body) ? 2 : 1) * (1 + c.reactions);
|
|
760
763
|
}
|
|
764
|
+
function scoreDiscussion(d) {
|
|
765
|
+
if (TITLE_NOISE_RE.test(d.title)) return -1;
|
|
766
|
+
let score = 0;
|
|
767
|
+
if (d.isMaintainer) score += 3;
|
|
768
|
+
if (hasCodeBlock([
|
|
769
|
+
d.body,
|
|
770
|
+
d.answer || "",
|
|
771
|
+
...d.topComments.map((c) => c.body)
|
|
772
|
+
].join("\n"))) score += 3;
|
|
773
|
+
score += Math.min(d.upvoteCount, 5);
|
|
774
|
+
if (d.answer) {
|
|
775
|
+
score += 2;
|
|
776
|
+
if (d.answer.length > 100) score += 1;
|
|
777
|
+
}
|
|
778
|
+
if (d.topComments.some((c) => c.isMaintainer)) score += 2;
|
|
779
|
+
if (d.topComments.some((c) => c.reactions > 0)) score += 1;
|
|
780
|
+
return score;
|
|
781
|
+
}
|
|
761
782
|
async function fetchGitHubDiscussions(owner, repo, limit = 20, releasedAt, fromDate) {
|
|
762
783
|
if (!isGhAvailable()) return [];
|
|
763
784
|
if (!fromDate && releasedAt) {
|
|
@@ -770,7 +791,7 @@ async function fetchGitHubDiscussions(owner, repo, limit = 20, releasedAt, fromD
|
|
|
770
791
|
"api",
|
|
771
792
|
"graphql",
|
|
772
793
|
"-f",
|
|
773
|
-
`query=${`query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { discussions(first: ${Math.min(limit * 3, 80)}, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { number title body category { name } createdAt url upvoteCount comments(first: 10) { totalCount nodes { body author { login } authorAssociation reactions { totalCount } } } answer { body author { login } authorAssociation } author { login } } } } }`}`,
|
|
794
|
+
`query=${`query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { discussions(first: ${Math.min(limit * 3, 80)}, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { number title body category { name } createdAt url upvoteCount comments(first: 10) { totalCount nodes { body author { login } authorAssociation reactions { totalCount } } } answer { body author { login } authorAssociation } author { login } authorAssociation } } } }`}`,
|
|
774
795
|
"-f",
|
|
775
796
|
`owner=${owner}`,
|
|
776
797
|
"-f",
|
|
@@ -819,15 +840,23 @@ async function fetchGitHubDiscussions(owner, repo, limit = 20, releasedAt, fromD
|
|
|
819
840
|
url: d.url,
|
|
820
841
|
upvoteCount: d.upvoteCount || 0,
|
|
821
842
|
comments: d.comments?.totalCount || 0,
|
|
843
|
+
isMaintainer: [
|
|
844
|
+
"OWNER",
|
|
845
|
+
"MEMBER",
|
|
846
|
+
"COLLABORATOR"
|
|
847
|
+
].includes(d.authorAssociation),
|
|
822
848
|
answer,
|
|
823
849
|
topComments: comments
|
|
824
850
|
};
|
|
825
|
-
}).
|
|
826
|
-
|
|
827
|
-
|
|
851
|
+
}).map((d) => ({
|
|
852
|
+
d,
|
|
853
|
+
score: scoreDiscussion(d)
|
|
854
|
+
})).filter(({ score }) => score >= MIN_DISCUSSION_SCORE).sort((a, b) => {
|
|
855
|
+
const aHigh = HIGH_VALUE_CATEGORIES.has(a.d.category.toLowerCase()) ? 1 : 0;
|
|
856
|
+
const bHigh = HIGH_VALUE_CATEGORIES.has(b.d.category.toLowerCase()) ? 1 : 0;
|
|
828
857
|
if (aHigh !== bHigh) return bHigh - aHigh;
|
|
829
|
-
return b.
|
|
830
|
-
}).slice(0, limit);
|
|
858
|
+
return b.score - a.score;
|
|
859
|
+
}).slice(0, limit).map(({ d }) => d);
|
|
831
860
|
} catch {
|
|
832
861
|
return [];
|
|
833
862
|
}
|
|
@@ -892,6 +921,50 @@ function generateDiscussionIndex(discussions) {
|
|
|
892
921
|
}
|
|
893
922
|
return sections.join("\n");
|
|
894
923
|
}
|
|
924
|
+
function generateDocsIndex(docs) {
|
|
925
|
+
const docFiles = docs.filter((d) => d.path.startsWith("docs/") && d.path.endsWith(".md") && !d.path.endsWith("_INDEX.md")).sort((a, b) => a.path.localeCompare(b.path));
|
|
926
|
+
if (docFiles.length === 0) return "";
|
|
927
|
+
const rootFiles = [];
|
|
928
|
+
const byDir = /* @__PURE__ */ new Map();
|
|
929
|
+
for (const doc of docFiles) {
|
|
930
|
+
const rel = doc.path.slice(5);
|
|
931
|
+
const dir = rel.includes("/") ? rel.slice(0, rel.lastIndexOf("/")) : "";
|
|
932
|
+
if (!dir) rootFiles.push(doc);
|
|
933
|
+
else {
|
|
934
|
+
const list = byDir.get(dir);
|
|
935
|
+
if (list) list.push(doc);
|
|
936
|
+
else byDir.set(dir, [doc]);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
const sections = [
|
|
940
|
+
"---",
|
|
941
|
+
`total: ${docFiles.length}`,
|
|
942
|
+
"---",
|
|
943
|
+
"",
|
|
944
|
+
"# Docs Index",
|
|
945
|
+
""
|
|
946
|
+
];
|
|
947
|
+
for (const file of rootFiles) {
|
|
948
|
+
const rel = file.path.slice(5);
|
|
949
|
+
const title = extractTitle(file.content) || rel.replace(/\.md$/, "");
|
|
950
|
+
const desc = extractDescription(file.content);
|
|
951
|
+
const descPart = desc ? `: ${desc}` : "";
|
|
952
|
+
sections.push(`- [${title}](./${rel})${descPart}`);
|
|
953
|
+
}
|
|
954
|
+
if (rootFiles.length > 0) sections.push("");
|
|
955
|
+
for (const [dir, files] of byDir) {
|
|
956
|
+
sections.push(`## ${dir} (${files.length})`, "");
|
|
957
|
+
for (const file of files) {
|
|
958
|
+
const rel = file.path.slice(5);
|
|
959
|
+
const title = extractTitle(file.content) || rel.replace(/\.md$/, "").split("/").pop();
|
|
960
|
+
const desc = extractDescription(file.content);
|
|
961
|
+
const descPart = desc ? `: ${desc}` : "";
|
|
962
|
+
sections.push(`- [${title}](./${rel})${descPart}`);
|
|
963
|
+
}
|
|
964
|
+
sections.push("");
|
|
965
|
+
}
|
|
966
|
+
return sections.join("\n");
|
|
967
|
+
}
|
|
895
968
|
const SKIP_DIRS = [
|
|
896
969
|
"node_modules",
|
|
897
970
|
"_vendor",
|
|
@@ -1006,16 +1079,11 @@ function parseGitUrl(url) {
|
|
|
1006
1079
|
}
|
|
1007
1080
|
}
|
|
1008
1081
|
function parseSkillFrontmatterName(content) {
|
|
1009
|
-
const
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
if (!kv) continue;
|
|
1015
|
-
if (kv[0] === "name") result.name = kv[1];
|
|
1016
|
-
if (kv[0] === "description") result.description = kv[1];
|
|
1017
|
-
}
|
|
1018
|
-
return result;
|
|
1082
|
+
const fm = parseFrontmatter(content);
|
|
1083
|
+
return {
|
|
1084
|
+
name: fm.name,
|
|
1085
|
+
description: fm.description
|
|
1086
|
+
};
|
|
1019
1087
|
}
|
|
1020
1088
|
const SUPPORTING_DIRS = [
|
|
1021
1089
|
"scripts",
|
|
@@ -1204,20 +1272,7 @@ async function fetchLlmsTxt(url) {
|
|
|
1204
1272
|
};
|
|
1205
1273
|
}
|
|
1206
1274
|
function parseMarkdownLinks(content) {
|
|
1207
|
-
|
|
1208
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1209
|
-
const linkRegex = /\[([^\]]+)\]\(([^)]+\.md)\)/g;
|
|
1210
|
-
for (let match = linkRegex.exec(content); match !== null; match = linkRegex.exec(content)) {
|
|
1211
|
-
const url = match[2];
|
|
1212
|
-
if (!seen.has(url)) {
|
|
1213
|
-
seen.add(url);
|
|
1214
|
-
links.push({
|
|
1215
|
-
title: match[1],
|
|
1216
|
-
url
|
|
1217
|
-
});
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
return links;
|
|
1275
|
+
return extractLinks(content).filter((l) => l.url.endsWith(".md"));
|
|
1221
1276
|
}
|
|
1222
1277
|
function isSafeUrl(url) {
|
|
1223
1278
|
try {
|
|
@@ -2048,6 +2103,6 @@ function getInstalledSkillVersion(skillDir) {
|
|
|
2048
2103
|
if (!existsSync(skillPath)) return null;
|
|
2049
2104
|
return readFileSync(skillPath, "utf-8").match(/^version:\s*"?([^"\n]+)"?/m)?.[1] || null;
|
|
2050
2105
|
}
|
|
2051
|
-
export {
|
|
2106
|
+
export { isGhAvailable as $, parseSkillFrontmatterName as A, isPrerelease as B, extractSections as C, parseMarkdownLinks as D, normalizeLlmsLinks as E, generateDiscussionIndex as F, isGitHubRepoUrl as G, $fetch as H, fetchBlogReleases as I, parsePackageSpec as J, normalizeRepoUrl as K, compareSemver as L, generateDocsIndex as M, fetchGitHubDiscussions as N, fetchGitSkills as O, formatDiscussionAsMarkdown as P, generateIssueIndex as Q, fetchReleaseNotes as R, downloadLlmsDocs as S, fetchLlmsUrl as T, extractBranchHint as U, parseSemver as V, fetchText as W, fetchGitHubIssues as X, verifyUrl as Y, formatIssueAsMarkdown as Z, fetchReadme as _, getInstalledSkillVersion as a, resolveGitHubRepo as b, readLocalPackageInfo as c, resolvePackageDocs as d, SHARED_SKILLS_DIR as et, resolvePackageDocsWithAttempts as f, fetchGitHubRepoMeta as g, fetchGitDocs as h, fetchPkgDist as i, resolveEntryFiles as j, parseGitSkillInput as k, resolveInstalledVersion as l, MIN_GIT_DOCS as m, fetchNpmPackage as n, mapInsert as nt, parseVersionSpecifier as o, searchNpmPackages as p, parseGitHubUrl as q, fetchNpmRegistryMeta as r, semverGt as rt, readLocalDependencies as s, fetchLatestVersion as t, getSharedSkillsDir as tt, resolveLocalPackageDocs as u, fetchReadmeContent as v, fetchLlmsTxt as w, validateGitDocsWithLlms as x, isShallowGitDocs as y, generateReleaseIndex as z };
|
|
2052
2107
|
|
|
2053
2108
|
//# sourceMappingURL=npm.mjs.map
|