@stacksjs/skills 0.70.258 → 0.70.259
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/index.js +1 -9
- package/dist/skills.js +2 -96
- package/package.json +14 -7
package/dist/index.js
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
bundledSkillsPath,
|
|
3
|
-
getSkill,
|
|
4
|
-
listSkills,
|
|
5
|
-
loadSkillMetadata,
|
|
6
|
-
projectSkillsPath,
|
|
7
|
-
resolveSkillPath,
|
|
8
|
-
validateSkill
|
|
9
|
-
} from "./skills";
|
|
1
|
+
export{bundledSkillsPath,getSkill,listSkills,loadSkillMetadata,projectSkillsPath,resolveSkillPath,validateSkill}from"./skills";
|
package/dist/skills.js
CHANGED
|
@@ -1,96 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
function skillSources() {
|
|
4
|
-
return [
|
|
5
|
-
appPath("Skills"),
|
|
6
|
-
frameworkPath("defaults/ai/skills")
|
|
7
|
-
];
|
|
8
|
-
}
|
|
9
|
-
function resolveSkillDir(name) {
|
|
10
|
-
for (const source of skillSources()) {
|
|
11
|
-
const dir = join(source, name);
|
|
12
|
-
if (existsSync(join(dir, "SKILL.md")))
|
|
13
|
-
return dir;
|
|
14
|
-
}
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
function parseFrontmatter(content) {
|
|
18
|
-
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
19
|
-
if (!match)
|
|
20
|
-
return {
|
|
21
|
-
metadata: { name: "", description: "" },
|
|
22
|
-
body: content
|
|
23
|
-
};
|
|
24
|
-
const [, frontmatterStr, body] = match, metadata = {};
|
|
25
|
-
for (const line of (frontmatterStr ?? "").split(`
|
|
26
|
-
`)) {
|
|
27
|
-
const colonIndex = line.indexOf(":");
|
|
28
|
-
if (colonIndex === -1)
|
|
29
|
-
continue;
|
|
30
|
-
const key = line.slice(0, colonIndex).trim(), value = line.slice(colonIndex + 1).trim();
|
|
31
|
-
metadata[key] = value;
|
|
32
|
-
}
|
|
33
|
-
return { metadata, body: body ?? "" };
|
|
34
|
-
}
|
|
35
|
-
export function listSkills() {
|
|
36
|
-
const names = new Set;
|
|
37
|
-
for (const source of skillSources()) {
|
|
38
|
-
if (!existsSync(source))
|
|
39
|
-
continue;
|
|
40
|
-
for (const entry of readdirSync(source)) {
|
|
41
|
-
const entryPath = join(source, entry);
|
|
42
|
-
if (statSync(entryPath).isDirectory() && existsSync(join(entryPath, "SKILL.md")))
|
|
43
|
-
names.add(entry);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return [...names].sort();
|
|
47
|
-
}
|
|
48
|
-
export function getSkill(name) {
|
|
49
|
-
const skillDir = resolveSkillDir(name);
|
|
50
|
-
if (!skillDir)
|
|
51
|
-
return null;
|
|
52
|
-
const skillPath = join(skillDir, "SKILL.md"), content = readFileSync(skillPath, "utf-8"), { metadata, body } = parseFrontmatter(content), listDir = (dir) => existsSync(join(skillDir, dir)) ? readdirSync(join(skillDir, dir)) : [];
|
|
53
|
-
return {
|
|
54
|
-
metadata,
|
|
55
|
-
instructions: body,
|
|
56
|
-
path: skillPath,
|
|
57
|
-
scripts: listDir("scripts"),
|
|
58
|
-
references: listDir("references"),
|
|
59
|
-
assets: listDir("assets")
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
export function loadSkillMetadata(name) {
|
|
63
|
-
return getSkill(name)?.metadata ?? null;
|
|
64
|
-
}
|
|
65
|
-
export function validateSkill(name) {
|
|
66
|
-
const errors = [], skillDir = resolveSkillDir(name);
|
|
67
|
-
if (!skillDir) {
|
|
68
|
-
errors.push(`Skill not found in any source: ${skillSources().map((source) => join(source, name)).join(", ")}`);
|
|
69
|
-
return { valid: !1, errors };
|
|
70
|
-
}
|
|
71
|
-
const content = readFileSync(join(skillDir, "SKILL.md"), "utf-8"), { metadata } = parseFrontmatter(content);
|
|
72
|
-
if (!metadata.name)
|
|
73
|
-
errors.push("Missing required field: name");
|
|
74
|
-
else {
|
|
75
|
-
if (metadata.name.length > 64)
|
|
76
|
-
errors.push("Name must be 1-64 characters");
|
|
77
|
-
if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(metadata.name))
|
|
78
|
-
errors.push("Name must be lowercase letters, numbers, and hyphens only");
|
|
79
|
-
if (metadata.name !== name)
|
|
80
|
-
errors.push(`Name "${metadata.name}" must match directory name "${name}"`);
|
|
81
|
-
}
|
|
82
|
-
if (!metadata.description)
|
|
83
|
-
errors.push("Missing required field: description");
|
|
84
|
-
else if (metadata.description.length > 1024)
|
|
85
|
-
errors.push("Description must be 1-1024 characters");
|
|
86
|
-
return { valid: errors.length === 0, errors };
|
|
87
|
-
}
|
|
88
|
-
export function bundledSkillsPath() {
|
|
89
|
-
return frameworkPath("defaults/ai/skills");
|
|
90
|
-
}
|
|
91
|
-
export function projectSkillsPath() {
|
|
92
|
-
return appPath("Skills");
|
|
93
|
-
}
|
|
94
|
-
export function resolveSkillPath(name) {
|
|
95
|
-
return resolveSkillDir(name);
|
|
96
|
-
}
|
|
1
|
+
import{existsSync,readdirSync,readFileSync,statSync}from"node:fs";import{appPath,frameworkPath,join}from"@stacksjs/path";function skillSources(){return[appPath("Skills"),frameworkPath("defaults/ai/skills")]}function resolveSkillDir(name){for(const source of skillSources()){const dir=join(source,name);if(existsSync(join(dir,"SKILL.md")))return dir}return null}function parseFrontmatter(content){const match=content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!match)return{metadata:{name:"",description:""},body:content};const[,frontmatterStr,body]=match,metadata={};for(const line of(frontmatterStr??"").split(`
|
|
2
|
+
`)){const colonIndex=line.indexOf(":");if(colonIndex===-1)continue;const key=line.slice(0,colonIndex).trim(),value=line.slice(colonIndex+1).trim();metadata[key]=value}return{metadata,body:body??""}}export function listSkills(){const names=new Set;for(const source of skillSources()){if(!existsSync(source))continue;for(const entry of readdirSync(source)){const entryPath=join(source,entry);if(statSync(entryPath).isDirectory()&&existsSync(join(entryPath,"SKILL.md")))names.add(entry)}}return[...names].sort()}export function getSkill(name){const skillDir=resolveSkillDir(name);if(!skillDir)return null;const skillPath=join(skillDir,"SKILL.md"),content=readFileSync(skillPath,"utf-8"),{metadata,body}=parseFrontmatter(content),listDir=(dir)=>existsSync(join(skillDir,dir))?readdirSync(join(skillDir,dir)):[];return{metadata,instructions:body,path:skillPath,scripts:listDir("scripts"),references:listDir("references"),assets:listDir("assets")}}export function loadSkillMetadata(name){return getSkill(name)?.metadata??null}export function validateSkill(name){const errors=[],skillDir=resolveSkillDir(name);if(!skillDir){errors.push(`Skill not found in any source: ${skillSources().map((source)=>join(source,name)).join(", ")}`);return{valid:!1,errors}}const content=readFileSync(join(skillDir,"SKILL.md"),"utf-8"),{metadata}=parseFrontmatter(content);if(!metadata.name)errors.push("Missing required field: name");else{if(metadata.name.length>64)errors.push("Name must be 1-64 characters");if(!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(metadata.name))errors.push("Name must be lowercase letters, numbers, and hyphens only");if(metadata.name!==name)errors.push(`Name "${metadata.name}" must match directory name "${name}"`)}if(!metadata.description)errors.push("Missing required field: description");else if(metadata.description.length>1024)errors.push("Description must be 1-1024 characters");return{valid:errors.length===0,errors}}export function bundledSkillsPath(){return frameworkPath("defaults/ai/skills")}export function projectSkillsPath(){return appPath("Skills")}export function resolveSkillPath(name){return resolveSkillDir(name)}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/skills",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.70.
|
|
5
|
+
"version": "0.70.259",
|
|
6
6
|
"description": "Reads the Stacks framework's agent skills, following the agentskills.io standard. The skills themselves ship in storage/framework/defaults/ai/skills.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -34,9 +34,16 @@
|
|
|
34
34
|
"default": "./dist/index.js"
|
|
35
35
|
},
|
|
36
36
|
"./*": {
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
37
|
+
"types": "./dist/*.d.ts",
|
|
38
|
+
"bun": "./dist/*.js",
|
|
39
|
+
"import": "./dist/*.js",
|
|
40
|
+
"default": "./dist/*.js"
|
|
41
|
+
},
|
|
42
|
+
"./*.js": {
|
|
43
|
+
"types": "./dist/*.d.ts",
|
|
44
|
+
"bun": "./dist/*.js",
|
|
45
|
+
"import": "./dist/*.js",
|
|
46
|
+
"default": "./dist/*.js"
|
|
40
47
|
}
|
|
41
48
|
},
|
|
42
49
|
"module": "dist/index.js",
|
|
@@ -51,11 +58,11 @@
|
|
|
51
58
|
"prepublishOnly": "bun run build"
|
|
52
59
|
},
|
|
53
60
|
"dependencies": {
|
|
54
|
-
"@stacksjs/path": "0.70.
|
|
55
|
-
"@stacksjs/storage": "0.70.
|
|
61
|
+
"@stacksjs/path": "0.70.259",
|
|
62
|
+
"@stacksjs/storage": "0.70.259"
|
|
56
63
|
},
|
|
57
64
|
"devDependencies": {
|
|
58
65
|
"better-dx": "^0.2.17",
|
|
59
|
-
"@stacksjs/types": "0.70.
|
|
66
|
+
"@stacksjs/types": "0.70.259"
|
|
60
67
|
}
|
|
61
68
|
}
|