@stacksjs/skills 0.70.87 → 0.70.90

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 CHANGED
@@ -1,2 +1 @@
1
- // @bun
2
- export{e as validateSkill,k as loadSkillMetadata,a as listSkills,i as getSkill};
1
+ export { listSkills, getSkill, validateSkill, loadSkillMetadata } from "./skills";
package/dist/skills.js ADDED
@@ -0,0 +1,74 @@
1
+ import { join, resolve } from "@stacksjs/path";
2
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
+ const SKILLS_DIR = resolve(join(import.meta.dir, "..", "..", "..", "..", "..", ".claude", "skills"));
4
+ function parseFrontmatter(content) {
5
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
6
+ if (!match)
7
+ return {
8
+ metadata: { name: "", description: "" },
9
+ body: content
10
+ };
11
+ const [, frontmatterStr, body] = match, metadata = {};
12
+ for (const line of (frontmatterStr ?? "").split(`
13
+ `)) {
14
+ const colonIndex = line.indexOf(":");
15
+ if (colonIndex === -1)
16
+ continue;
17
+ const key = line.slice(0, colonIndex).trim(), value = line.slice(colonIndex + 1).trim();
18
+ metadata[key] = value;
19
+ }
20
+ return { metadata, body: body ?? "" };
21
+ }
22
+ export function listSkills() {
23
+ if (!existsSync(SKILLS_DIR))
24
+ return [];
25
+ return readdirSync(SKILLS_DIR).filter((entry) => {
26
+ const entryPath = join(SKILLS_DIR, entry);
27
+ return statSync(entryPath).isDirectory() && existsSync(join(entryPath, "SKILL.md"));
28
+ });
29
+ }
30
+ export function getSkill(name) {
31
+ const skillPath = join(SKILLS_DIR, name, "SKILL.md");
32
+ if (!existsSync(skillPath))
33
+ return null;
34
+ const content = readFileSync(skillPath, "utf-8"), { metadata, body } = parseFrontmatter(content), skillDir = join(SKILLS_DIR, name), scripts = existsSync(join(skillDir, "scripts")) ? readdirSync(join(skillDir, "scripts")) : [], references = existsSync(join(skillDir, "references")) ? readdirSync(join(skillDir, "references")) : [], assets = existsSync(join(skillDir, "assets")) ? readdirSync(join(skillDir, "assets")) : [];
35
+ return {
36
+ metadata,
37
+ instructions: body,
38
+ path: skillPath,
39
+ scripts,
40
+ references,
41
+ assets
42
+ };
43
+ }
44
+ export function loadSkillMetadata(name) {
45
+ return getSkill(name)?.metadata ?? null;
46
+ }
47
+ export function validateSkill(name) {
48
+ const errors = [], skillDir = join(SKILLS_DIR, name);
49
+ if (!existsSync(skillDir)) {
50
+ errors.push(`Skill directory not found: ${skillDir}`);
51
+ return { valid: !1, errors };
52
+ }
53
+ const skillPath = join(skillDir, "SKILL.md");
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);
59
+ if (!metadata.name)
60
+ errors.push("Missing required field: name");
61
+ else {
62
+ if (metadata.name.length > 64)
63
+ errors.push("Name must be 1-64 characters");
64
+ if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(metadata.name))
65
+ errors.push("Name must be lowercase letters, numbers, and hyphens only");
66
+ if (metadata.name !== name)
67
+ errors.push(`Name "${metadata.name}" must match directory name "${name}"`);
68
+ }
69
+ if (!metadata.description)
70
+ errors.push("Missing required field: description");
71
+ else if (metadata.description.length > 1024)
72
+ errors.push("Description must be 1-1024 characters");
73
+ return { valid: errors.length === 0, errors };
74
+ }
package/dist/types.js ADDED
File without changes
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.87",
5
+ "version": "0.70.90",
6
6
  "description": "Agent skills for the Stacks framework, following the agentskills.io standard.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -54,11 +54,11 @@
54
54
  "prepublishOnly": "bun run build"
55
55
  },
56
56
  "dependencies": {
57
- "@stacksjs/path": "0.70.87",
58
- "@stacksjs/storage": "0.70.87"
57
+ "@stacksjs/path": "0.70.90",
58
+ "@stacksjs/storage": "0.70.90"
59
59
  },
60
60
  "devDependencies": {
61
61
  "better-dx": "^0.2.16",
62
- "@stacksjs/types": "0.70.87"
62
+ "@stacksjs/types": "0.70.90"
63
63
  }
64
64
  }