@stacksjs/skills 0.70.162 → 0.70.164
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 +2 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +9 -1
- package/dist/skills.d.ts +23 -0
- package/dist/skills.js +46 -24
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -310,6 +310,7 @@ _Focus on coding, not publishing._
|
|
|
310
310
|
|
|
311
311
|
Convention over configuration, while staying wholly configurable. _No more boilerplate._
|
|
312
312
|
|
|
313
|
+
- 🧠 **LLM-Friendly Authoring** _models generate compact application intent instead of repeating framework glue or reading `node_modules`_
|
|
313
314
|
- 💎 **Automated Upgrades** _no need to worry about upgrading to the latest versions, Stacks upgrades you_
|
|
314
315
|
- 🦋 **Pretty Dev URLs** _your-project.localhost instead of localhost:3000_
|
|
315
316
|
- 💡 **IDE Integration** _auto-completions, inline docs & a powerful IDE setup_
|
|
@@ -352,7 +353,7 @@ For help, discussion about best practices, or any other conversation that would
|
|
|
352
353
|
|
|
353
354
|
For casual chit-chat with others using this package:
|
|
354
355
|
|
|
355
|
-
[Join the Stacks Discord Server](https://
|
|
356
|
+
[Join the Stacks Discord Server](https://stacksjs.com/discord)
|
|
356
357
|
|
|
357
358
|
## Postcardware
|
|
358
359
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
export type { Skill,
|
|
2
|
-
export {
|
|
1
|
+
export type { Skill, SkillManifest, SkillMetadata } from './types';
|
|
2
|
+
export {
|
|
3
|
+
bundledSkillsPath,
|
|
4
|
+
getSkill,
|
|
5
|
+
listSkills,
|
|
6
|
+
loadSkillMetadata,
|
|
7
|
+
projectSkillsPath,
|
|
8
|
+
resolveSkillPath,
|
|
9
|
+
validateSkill,
|
|
10
|
+
} from './skills';
|
package/dist/index.js
CHANGED
package/dist/skills.d.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
import type { Skill, SkillMetadata } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Every available skill name, sorted, with project skills shadowing bundled
|
|
4
|
+
* ones of the same name rather than appearing twice.
|
|
5
|
+
*/
|
|
2
6
|
export declare function listSkills(): string[];
|
|
3
7
|
export declare function getSkill(name: string): Skill | null;
|
|
4
8
|
export declare function loadSkillMetadata(name: string): SkillMetadata | null;
|
|
9
|
+
/**
|
|
10
|
+
* Checks a skill against the agentskills.io frontmatter rules.
|
|
11
|
+
*/
|
|
5
12
|
export declare function validateSkill(name: string): { valid: boolean, errors: string[] };
|
|
13
|
+
/**
|
|
14
|
+
* The directory the framework's own skills ship from. `buddy setup:ai` reads it;
|
|
15
|
+
* nothing should write into it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function bundledSkillsPath(): string;
|
|
18
|
+
/**
|
|
19
|
+
* The directory a project puts its own skills in. Searched before
|
|
20
|
+
* {@link bundledSkillsPath}, so a skill here shadows a bundled one of the same
|
|
21
|
+
* name.
|
|
22
|
+
*/
|
|
23
|
+
export declare function projectSkillsPath(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Resolves a skill to its directory on disk, or `null` if no source has it.
|
|
26
|
+
* Exposed so `buddy setup:ai` can link/copy the winning directory per skill.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveSkillPath(name: string): string | null;
|
package/dist/skills.js
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { appPath, frameworkPath, join } from "@stacksjs/path";
|
|
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
|
+
}
|
|
4
17
|
function parseFrontmatter(content) {
|
|
5
18
|
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
6
19
|
if (!match)
|
|
@@ -20,42 +33,42 @@ function parseFrontmatter(content) {
|
|
|
20
33
|
return { metadata, body: body ?? "" };
|
|
21
34
|
}
|
|
22
35
|
export function listSkills() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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();
|
|
29
47
|
}
|
|
30
48
|
export function getSkill(name) {
|
|
31
|
-
const
|
|
32
|
-
if (!
|
|
49
|
+
const skillDir = resolveSkillDir(name);
|
|
50
|
+
if (!skillDir)
|
|
33
51
|
return null;
|
|
34
|
-
const content = readFileSync(skillPath, "utf-8"), { metadata, body } = parseFrontmatter(content),
|
|
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)) : [];
|
|
35
53
|
return {
|
|
36
54
|
metadata,
|
|
37
55
|
instructions: body,
|
|
38
56
|
path: skillPath,
|
|
39
|
-
scripts,
|
|
40
|
-
references,
|
|
41
|
-
assets
|
|
57
|
+
scripts: listDir("scripts"),
|
|
58
|
+
references: listDir("references"),
|
|
59
|
+
assets: listDir("assets")
|
|
42
60
|
};
|
|
43
61
|
}
|
|
44
62
|
export function loadSkillMetadata(name) {
|
|
45
63
|
return getSkill(name)?.metadata ?? null;
|
|
46
64
|
}
|
|
47
65
|
export function validateSkill(name) {
|
|
48
|
-
const errors = [], skillDir =
|
|
49
|
-
if (!
|
|
50
|
-
errors.push(`Skill
|
|
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(", ")}`);
|
|
51
69
|
return { valid: !1, errors };
|
|
52
70
|
}
|
|
53
|
-
const
|
|
54
|
-
if (!existsSync(skillPath)) {
|
|
55
|
-
errors.push(`SKILL.md not found in ${skillDir}`);
|
|
56
|
-
return { valid: !1, errors };
|
|
57
|
-
}
|
|
58
|
-
const content = readFileSync(skillPath, "utf-8"), { metadata } = parseFrontmatter(content);
|
|
71
|
+
const content = readFileSync(join(skillDir, "SKILL.md"), "utf-8"), { metadata } = parseFrontmatter(content);
|
|
59
72
|
if (!metadata.name)
|
|
60
73
|
errors.push("Missing required field: name");
|
|
61
74
|
else {
|
|
@@ -72,3 +85,12 @@ export function validateSkill(name) {
|
|
|
72
85
|
errors.push("Description must be 1-1024 characters");
|
|
73
86
|
return { valid: errors.length === 0, errors };
|
|
74
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
|
+
}
|
package/package.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"name": "@stacksjs/skills",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.70.
|
|
6
|
-
"description": "
|
|
5
|
+
"version": "0.70.164",
|
|
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": [
|
|
9
9
|
"Chris Breuer <chris@stacksjs.com>"
|
|
@@ -45,8 +45,7 @@
|
|
|
45
45
|
"types": "dist/index.d.ts",
|
|
46
46
|
"files": [
|
|
47
47
|
"README.md",
|
|
48
|
-
"dist"
|
|
49
|
-
"skills"
|
|
48
|
+
"dist"
|
|
50
49
|
],
|
|
51
50
|
"scripts": {
|
|
52
51
|
"build": "bun build.ts",
|
|
@@ -54,11 +53,11 @@
|
|
|
54
53
|
"prepublishOnly": "bun run build"
|
|
55
54
|
},
|
|
56
55
|
"dependencies": {
|
|
57
|
-
"@stacksjs/path": "0.70.
|
|
58
|
-
"@stacksjs/storage": "0.70.
|
|
56
|
+
"@stacksjs/path": "0.70.164",
|
|
57
|
+
"@stacksjs/storage": "0.70.164"
|
|
59
58
|
},
|
|
60
59
|
"devDependencies": {
|
|
61
60
|
"better-dx": "^0.2.17",
|
|
62
|
-
"@stacksjs/types": "0.70.
|
|
61
|
+
"@stacksjs/types": "0.70.164"
|
|
63
62
|
}
|
|
64
63
|
}
|