@skills-hub-ai/skill-parser 0.1.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.
@@ -0,0 +1,22 @@
1
+ export interface ParsedSkill {
2
+ name: string;
3
+ description: string;
4
+ version: string;
5
+ category: string | undefined;
6
+ platforms: string[];
7
+ instructions: string;
8
+ raw: string;
9
+ }
10
+ export interface ParseError {
11
+ field: string;
12
+ message: string;
13
+ }
14
+ export interface ParseResult {
15
+ success: boolean;
16
+ skill?: ParsedSkill;
17
+ errors: ParseError[];
18
+ }
19
+ export declare function parseSkillMd(content: string): ParseResult;
20
+ export declare function validateSemver(version: string): boolean;
21
+ export declare function compareSemver(a: string, b: string): number;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAID,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAkFzD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAS1D"}
package/dist/index.js ADDED
@@ -0,0 +1,109 @@
1
+ import { parse as parseYaml } from "yaml";
2
+ import { z } from "zod";
3
+ import { CATEGORY_SLUGS, PLATFORMS } from "@skills-hub-ai/shared";
4
+ const frontmatterSchema = z.object({
5
+ name: z.string().min(1),
6
+ description: z.string().min(1),
7
+ version: z
8
+ .union([z.string(), z.number()])
9
+ .transform((v) => String(v))
10
+ .pipe(z.string().min(1)),
11
+ category: z
12
+ .string()
13
+ .optional()
14
+ .transform((v) => v?.toLowerCase()),
15
+ platforms: z
16
+ .array(z.string())
17
+ .optional()
18
+ .default([]),
19
+ });
20
+ const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
21
+ export function parseSkillMd(content) {
22
+ const errors = [];
23
+ const trimmed = content.trim();
24
+ if (!trimmed) {
25
+ return { success: false, errors: [{ field: "content", message: "File is empty" }] };
26
+ }
27
+ const match = trimmed.match(FRONTMATTER_REGEX);
28
+ if (!match) {
29
+ return {
30
+ success: false,
31
+ errors: [{ field: "frontmatter", message: "No YAML frontmatter found. Expected --- delimiters." }],
32
+ };
33
+ }
34
+ const [, yamlBlock, instructionBlock] = match;
35
+ let parsed;
36
+ try {
37
+ parsed = parseYaml(yamlBlock);
38
+ }
39
+ catch (e) {
40
+ return {
41
+ success: false,
42
+ errors: [{ field: "frontmatter", message: `Invalid YAML: ${e instanceof Error ? e.message : "unknown error"}` }],
43
+ };
44
+ }
45
+ if (!parsed || typeof parsed !== "object") {
46
+ return {
47
+ success: false,
48
+ errors: [{ field: "frontmatter", message: "Frontmatter must be a YAML object" }],
49
+ };
50
+ }
51
+ const result = frontmatterSchema.safeParse(parsed);
52
+ if (!result.success) {
53
+ for (const issue of result.error.issues) {
54
+ errors.push({ field: issue.path.join(".") || "unknown", message: issue.message });
55
+ }
56
+ return { success: false, errors };
57
+ }
58
+ const { name, description, version, category, platforms } = result.data;
59
+ const instructions = parsed.instructions || instructionBlock.trim();
60
+ if (!instructions) {
61
+ errors.push({ field: "instructions", message: "No instructions found in frontmatter or body" });
62
+ return { success: false, errors };
63
+ }
64
+ if (category && !CATEGORY_SLUGS.includes(category)) {
65
+ errors.push({
66
+ field: "category",
67
+ message: `Unknown category "${category}". Valid: ${CATEGORY_SLUGS.join(", ")}`,
68
+ });
69
+ }
70
+ const normalizedPlatforms = platforms.map((p) => p.toUpperCase().replace(/[\s-]/g, "_"));
71
+ for (const p of normalizedPlatforms) {
72
+ if (!PLATFORMS.includes(p)) {
73
+ errors.push({ field: "platforms", message: `Unknown platform "${p}". Valid: ${PLATFORMS.join(", ")}` });
74
+ }
75
+ }
76
+ if (errors.length > 0) {
77
+ return { success: false, errors };
78
+ }
79
+ return {
80
+ success: true,
81
+ skill: {
82
+ name,
83
+ description,
84
+ version,
85
+ category,
86
+ platforms: normalizedPlatforms,
87
+ instructions,
88
+ raw: content,
89
+ },
90
+ errors: [],
91
+ };
92
+ }
93
+ export function validateSemver(version) {
94
+ return /^\d+\.\d+\.\d+$/.test(version);
95
+ }
96
+ export function compareSemver(a, b) {
97
+ if (!validateSemver(a) || !validateSemver(b))
98
+ return 0;
99
+ const pa = a.split(".").map(Number);
100
+ const pb = b.split(".").map(Number);
101
+ for (let i = 0; i < 3; i++) {
102
+ if (pa[i] > pb[i])
103
+ return 1;
104
+ if (pa[i] < pb[i])
105
+ return -1;
106
+ }
107
+ return 0;
108
+ }
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;SAC/B,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SAC3B,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1B,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACrC,SAAS,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,CAAC;CACf,CAAC,CAAC;AAuBH,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AAExE,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAE/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IACtF,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,qDAAqD,EAAE,CAAC;SACnG,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,EAAE,SAAS,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC;IAC9C,IAAI,MAA+B,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,SAAS,CAA4B,CAAC;IAC3D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;SACjH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;SACjF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IACxE,MAAM,YAAY,GAAI,MAAM,CAAC,YAAuB,IAAI,gBAAgB,CAAC,IAAI,EAAE,CAAC;IAEhF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC,CAAC;QAChG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAe,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,qBAAqB,QAAQ,aAAa,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC/E,CAAC,CAAC;IACL,CAAC;IAED,MAAM,mBAAmB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IACzF,KAAK,MAAM,CAAC,IAAI,mBAAmB,EAAE,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,qBAAqB,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1G,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,KAAK,EAAE;YACL,IAAI;YACJ,WAAW;YACX,OAAO;YACP,QAAQ;YACR,SAAS,EAAE,mBAAmB;YAC9B,YAAY;YACZ,GAAG,EAAE,OAAO;SACb;QACD,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,CAAS;IAChD,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACvD,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAC5B,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,131 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { parseSkillMd, validateSemver, compareSemver } from "./index.js";
3
+ describe("parseSkillMd", () => {
4
+ it("parses a valid SKILL.md", () => {
5
+ const content = `---
6
+ name: Test Skill
7
+ description: A test skill
8
+ version: 1.0.0
9
+ category: build
10
+ platforms:
11
+ - CLAUDE_CODE
12
+ ---
13
+ These are the instructions.`;
14
+ const result = parseSkillMd(content);
15
+ expect(result.success).toBe(true);
16
+ expect(result.skill?.name).toBe("Test Skill");
17
+ expect(result.skill?.description).toBe("A test skill");
18
+ expect(result.skill?.version).toBe("1.0.0");
19
+ expect(result.skill?.category).toBe("build");
20
+ expect(result.skill?.platforms).toEqual(["CLAUDE_CODE"]);
21
+ expect(result.skill?.instructions).toBe("These are the instructions.");
22
+ });
23
+ it("fails on missing frontmatter", () => {
24
+ const result = parseSkillMd("Just some text without frontmatter");
25
+ expect(result.success).toBe(false);
26
+ expect(result.errors[0].field).toBe("frontmatter");
27
+ });
28
+ it("fails on empty content", () => {
29
+ const result = parseSkillMd("");
30
+ expect(result.success).toBe(false);
31
+ expect(result.errors[0].field).toBe("content");
32
+ });
33
+ it("fails on missing required fields", () => {
34
+ const content = `---
35
+ description: A test skill
36
+ ---
37
+ Instructions here.`;
38
+ const result = parseSkillMd(content);
39
+ expect(result.success).toBe(false);
40
+ expect(result.errors.some((e) => e.field === "name" || e.message.includes("Required"))).toBe(true);
41
+ });
42
+ it("normalizes platform names", () => {
43
+ const content = `---
44
+ name: Test
45
+ description: A test
46
+ version: 1.0.0
47
+ platforms:
48
+ - claude code
49
+ ---
50
+ Instructions.`;
51
+ const result = parseSkillMd(content);
52
+ expect(result.success).toBe(true);
53
+ expect(result.skill?.platforms).toEqual(["CLAUDE_CODE"]);
54
+ });
55
+ it("lowercases category", () => {
56
+ const content = `---
57
+ name: Test
58
+ description: A test
59
+ version: 1.0.0
60
+ category: Build
61
+ ---
62
+ Instructions.`;
63
+ const result = parseSkillMd(content);
64
+ expect(result.success).toBe(true);
65
+ expect(result.skill?.category).toBe("build");
66
+ });
67
+ it("rejects invalid category", () => {
68
+ const content = `---
69
+ name: Test
70
+ description: A test
71
+ version: 1.0.0
72
+ category: nonexistent
73
+ ---
74
+ Instructions.`;
75
+ const result = parseSkillMd(content);
76
+ expect(result.success).toBe(false);
77
+ expect(result.errors.some((e) => e.field === "category")).toBe(true);
78
+ });
79
+ it("handles numeric version", () => {
80
+ const content = `---
81
+ name: Test
82
+ description: A test
83
+ version: 1
84
+ ---
85
+ Instructions.`;
86
+ const result = parseSkillMd(content);
87
+ expect(result.success).toBe(true);
88
+ expect(result.skill?.version).toBe("1");
89
+ });
90
+ it("fails when no instructions in body or frontmatter", () => {
91
+ const content = `---
92
+ name: Test
93
+ description: A test
94
+ version: 1.0.0
95
+ ---
96
+ `;
97
+ const result = parseSkillMd(content);
98
+ expect(result.success).toBe(false);
99
+ expect(result.errors.some((e) => e.field === "instructions")).toBe(true);
100
+ });
101
+ });
102
+ describe("validateSemver", () => {
103
+ it("accepts valid semver", () => {
104
+ expect(validateSemver("1.0.0")).toBe(true);
105
+ expect(validateSemver("0.1.0")).toBe(true);
106
+ expect(validateSemver("10.20.30")).toBe(true);
107
+ });
108
+ it("rejects invalid semver", () => {
109
+ expect(validateSemver("1.0")).toBe(false);
110
+ expect(validateSemver("1")).toBe(false);
111
+ expect(validateSemver("v1.0.0")).toBe(false);
112
+ expect(validateSemver("1.0.0-beta")).toBe(false);
113
+ expect(validateSemver("")).toBe(false);
114
+ });
115
+ });
116
+ describe("compareSemver", () => {
117
+ it("returns 0 for equal versions", () => {
118
+ expect(compareSemver("1.0.0", "1.0.0")).toBe(0);
119
+ });
120
+ it("returns 1 when a > b", () => {
121
+ expect(compareSemver("2.0.0", "1.0.0")).toBe(1);
122
+ expect(compareSemver("1.1.0", "1.0.0")).toBe(1);
123
+ expect(compareSemver("1.0.1", "1.0.0")).toBe(1);
124
+ });
125
+ it("returns -1 when a < b", () => {
126
+ expect(compareSemver("1.0.0", "2.0.0")).toBe(-1);
127
+ expect(compareSemver("1.0.0", "1.1.0")).toBe(-1);
128
+ expect(compareSemver("1.0.0", "1.0.1")).toBe(-1);
129
+ });
130
+ });
131
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { ParsedSkill } from "./index.js";
2
+ /**
3
+ * OpenFang HAND.toml representation.
4
+ * A "Hand" is OpenFang's concept of a skill/tool that an agent can use.
5
+ * See: https://github.com/OpenFang (MIT licensed)
6
+ */
7
+ export interface HandConfig {
8
+ hand: {
9
+ name: string;
10
+ description: string;
11
+ version: string;
12
+ };
13
+ instructions: {
14
+ system_prompt: string;
15
+ user_template: string;
16
+ };
17
+ model: {
18
+ provider: string;
19
+ model_id: string;
20
+ max_tokens: number;
21
+ temperature: number;
22
+ };
23
+ limits: {
24
+ timeout_seconds: number;
25
+ max_retries: number;
26
+ };
27
+ metadata: {
28
+ source: string;
29
+ source_url: string;
30
+ platforms: string[];
31
+ category: string;
32
+ };
33
+ }
34
+ export interface TranslateOptions {
35
+ modelProvider?: string;
36
+ modelId?: string;
37
+ maxTokens?: number;
38
+ temperature?: number;
39
+ timeoutSeconds?: number;
40
+ sourceUrl?: string;
41
+ }
42
+ /**
43
+ * Translate a parsed SKILL.md into OpenFang HAND.toml format.
44
+ */
45
+ export declare function translateToHand(skill: ParsedSkill, options?: TranslateOptions): HandConfig;
46
+ /**
47
+ * Serialize a HandConfig to TOML format string.
48
+ */
49
+ export declare function serializeHandToml(config: HandConfig): string;
50
+ //# sourceMappingURL=openfang.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfang.d.ts","sourceRoot":"","sources":["../src/openfang.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACN,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,gBAAqB,GAC7B,UAAU,CAkCZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAiC5D"}
@@ -0,0 +1,134 @@
1
+ const DEFAULT_OPTIONS = {
2
+ modelProvider: "anthropic",
3
+ modelId: "claude-sonnet-4-5-20250514",
4
+ maxTokens: 4096,
5
+ temperature: 0.3,
6
+ timeoutSeconds: 120,
7
+ sourceUrl: "",
8
+ };
9
+ /**
10
+ * Translate a parsed SKILL.md into OpenFang HAND.toml format.
11
+ */
12
+ export function translateToHand(skill, options = {}) {
13
+ const opts = { ...DEFAULT_OPTIONS, ...options };
14
+ // Extract a user template from the instructions if one is defined,
15
+ // otherwise use a generic template
16
+ const userTemplate = extractUserTemplate(skill.instructions);
17
+ return {
18
+ hand: {
19
+ name: sanitizeName(skill.name),
20
+ description: skill.description,
21
+ version: skill.version,
22
+ },
23
+ instructions: {
24
+ system_prompt: skill.instructions,
25
+ user_template: userTemplate,
26
+ },
27
+ model: {
28
+ provider: opts.modelProvider,
29
+ model_id: opts.modelId,
30
+ max_tokens: opts.maxTokens,
31
+ temperature: opts.temperature,
32
+ },
33
+ limits: {
34
+ timeout_seconds: opts.timeoutSeconds,
35
+ max_retries: 2,
36
+ },
37
+ metadata: {
38
+ source: "skills-hub.ai",
39
+ source_url: opts.sourceUrl,
40
+ platforms: skill.platforms,
41
+ category: skill.category ?? "general",
42
+ },
43
+ };
44
+ }
45
+ /**
46
+ * Serialize a HandConfig to TOML format string.
47
+ */
48
+ export function serializeHandToml(config) {
49
+ const lines = [];
50
+ lines.push("[hand]");
51
+ lines.push(`name = ${tomlString(config.hand.name)}`);
52
+ lines.push(`description = ${tomlString(config.hand.description)}`);
53
+ lines.push(`version = ${tomlString(config.hand.version)}`);
54
+ lines.push("");
55
+ lines.push("[instructions]");
56
+ lines.push(`system_prompt = ${tomlMultilineString(config.instructions.system_prompt)}`);
57
+ lines.push(`user_template = ${tomlString(config.instructions.user_template)}`);
58
+ lines.push("");
59
+ lines.push("[model]");
60
+ lines.push(`provider = ${tomlString(config.model.provider)}`);
61
+ lines.push(`model_id = ${tomlString(config.model.model_id)}`);
62
+ lines.push(`max_tokens = ${config.model.max_tokens}`);
63
+ lines.push(`temperature = ${config.model.temperature}`);
64
+ lines.push("");
65
+ lines.push("[limits]");
66
+ lines.push(`timeout_seconds = ${config.limits.timeout_seconds}`);
67
+ lines.push(`max_retries = ${config.limits.max_retries}`);
68
+ lines.push("");
69
+ lines.push("[metadata]");
70
+ lines.push(`source = ${tomlString(config.metadata.source)}`);
71
+ lines.push(`source_url = ${tomlString(config.metadata.source_url)}`);
72
+ lines.push(`platforms = [${config.metadata.platforms.map(tomlString).join(", ")}]`);
73
+ lines.push(`category = ${tomlString(config.metadata.category)}`);
74
+ return lines.join("\n") + "\n";
75
+ }
76
+ /**
77
+ * Extract a user template from skill instructions.
78
+ * Looks for patterns like "INPUT:", "User provides:", etc.
79
+ */
80
+ function extractUserTemplate(instructions) {
81
+ // Look for explicit input specification
82
+ const inputPatterns = [
83
+ /(?:input|user provides?|expects?|takes?)\s*:\s*(.+?)(?:\n\n|\n(?=[A-Z#]))/is,
84
+ /(?:^|\n)>\s*(?:input|user)\s*:\s*(.+?)(?:\n\n|\n(?=[A-Z#]))/is,
85
+ ];
86
+ for (const pattern of inputPatterns) {
87
+ const match = instructions.match(pattern);
88
+ if (match?.[1]) {
89
+ return match[1].trim();
90
+ }
91
+ }
92
+ return "{{input}}";
93
+ }
94
+ /**
95
+ * Sanitize a skill name for OpenFang compatibility.
96
+ * OpenFang hand names must be lowercase alphanumeric with hyphens.
97
+ */
98
+ function sanitizeName(name) {
99
+ const sanitized = name
100
+ .toLowerCase()
101
+ .replace(/[^a-z0-9\s-]/g, "")
102
+ .replace(/\s+/g, "-")
103
+ .replace(/-+/g, "-")
104
+ .replace(/^-|-$/g, "")
105
+ .slice(0, 64);
106
+ // Fallback for names that are entirely special characters
107
+ return sanitized || "unnamed-hand";
108
+ }
109
+ function tomlString(value) {
110
+ return `"${value
111
+ .replace(/\\/g, "\\\\")
112
+ .replace(/"/g, '\\"')
113
+ .replace(/\n/g, "\\n")
114
+ .replace(/\r/g, "\\r")
115
+ .replace(/\t/g, "\\t")
116
+ .replace(/\x0c/g, "\\f")
117
+ .replace(/\x08/g, "\\b")
118
+ // eslint-disable-next-line no-control-regex
119
+ .replace(/[\x00-\x07\x0e-\x1f\x7f]/g, (ch) => `\\u${ch.charCodeAt(0).toString(16).padStart(4, "0")}`)}"`;
120
+ }
121
+ function tomlMultilineString(value) {
122
+ // Use TOML multiline basic strings (""") for long content
123
+ // These support escape sequences, unlike literal strings (''')
124
+ if (value.length > 200 || value.includes("\n")) {
125
+ const escaped = value
126
+ .replace(/\\/g, "\\\\")
127
+ .replace(/"""/g, '\\"\\"\\"')
128
+ // eslint-disable-next-line no-control-regex
129
+ .replace(/[\x00-\x08\x0e-\x1f\x7f]/g, (ch) => `\\u${ch.charCodeAt(0).toString(16).padStart(4, "0")}`);
130
+ return `"""\n${escaped}\n"""`;
131
+ }
132
+ return tomlString(value);
133
+ }
134
+ //# sourceMappingURL=openfang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfang.js","sourceRoot":"","sources":["../src/openfang.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openfang.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfang.test.d.ts","sourceRoot":"","sources":["../src/openfang.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { translateToHand, serializeHandToml } from "./openfang.js";
3
+ const sampleSkill = {
4
+ name: "Code Reviewer",
5
+ description: "Reviews code for bugs and style issues",
6
+ version: "1.2.0",
7
+ category: "build",
8
+ platforms: ["CLAUDE_CODE", "CURSOR"],
9
+ instructions: `You are an autonomous code reviewer.
10
+
11
+ ## Phase 1: Analysis
12
+ Input: The user provides a git diff or file path.
13
+ Output: A structured review with line-by-line comments.
14
+
15
+ ## Phase 2: Suggestions
16
+ Error handling: If the diff is empty, report "no changes found".
17
+ IMPORTANT: Never modify code directly — only suggest changes.
18
+
19
+ Example:
20
+ \`\`\`
21
+ // Line 42: Consider using const instead of let
22
+ \`\`\`
23
+
24
+ Output format: Markdown with headings per file.`,
25
+ raw: "",
26
+ };
27
+ describe("translateToHand", () => {
28
+ it("translates a parsed skill to HandConfig", () => {
29
+ const config = translateToHand(sampleSkill);
30
+ expect(config.hand.name).toBe("code-reviewer");
31
+ expect(config.hand.description).toBe("Reviews code for bugs and style issues");
32
+ expect(config.hand.version).toBe("1.2.0");
33
+ });
34
+ it("sets default model config", () => {
35
+ const config = translateToHand(sampleSkill);
36
+ expect(config.model.provider).toBe("anthropic");
37
+ expect(config.model.model_id).toBe("claude-sonnet-4-5-20250514");
38
+ expect(config.model.max_tokens).toBe(4096);
39
+ expect(config.model.temperature).toBe(0.3);
40
+ });
41
+ it("passes instructions as system_prompt", () => {
42
+ const config = translateToHand(sampleSkill);
43
+ expect(config.instructions.system_prompt).toBe(sampleSkill.instructions);
44
+ });
45
+ it("extracts user_template from instructions", () => {
46
+ const config = translateToHand(sampleSkill);
47
+ // Should extract the input specification or fall back to {{input}}
48
+ expect(config.instructions.user_template).toBeDefined();
49
+ expect(config.instructions.user_template.length).toBeGreaterThan(0);
50
+ });
51
+ it("respects custom options", () => {
52
+ const config = translateToHand(sampleSkill, {
53
+ modelProvider: "openai",
54
+ modelId: "gpt-4",
55
+ maxTokens: 8192,
56
+ temperature: 0.7,
57
+ timeoutSeconds: 60,
58
+ sourceUrl: "https://skills-hub.ai/skills/code-reviewer",
59
+ });
60
+ expect(config.model.provider).toBe("openai");
61
+ expect(config.model.model_id).toBe("gpt-4");
62
+ expect(config.model.max_tokens).toBe(8192);
63
+ expect(config.model.temperature).toBe(0.7);
64
+ expect(config.limits.timeout_seconds).toBe(60);
65
+ expect(config.metadata.source_url).toBe("https://skills-hub.ai/skills/code-reviewer");
66
+ });
67
+ it("sets metadata from skill", () => {
68
+ const config = translateToHand(sampleSkill);
69
+ expect(config.metadata.source).toBe("skills-hub.ai");
70
+ expect(config.metadata.platforms).toEqual(["CLAUDE_CODE", "CURSOR"]);
71
+ expect(config.metadata.category).toBe("build");
72
+ });
73
+ it("sanitizes name for OpenFang compatibility", () => {
74
+ const skill = {
75
+ ...sampleSkill,
76
+ name: "My Awesome Skill! (v2) @#$",
77
+ };
78
+ const config = translateToHand(skill);
79
+ expect(config.hand.name).toBe("my-awesome-skill-v2");
80
+ expect(config.hand.name).toMatch(/^[a-z0-9-]+$/);
81
+ });
82
+ it("falls back to 'unnamed-hand' for all-special-char names", () => {
83
+ const skill = { ...sampleSkill, name: "@#$%^&*()" };
84
+ const config = translateToHand(skill);
85
+ expect(config.hand.name).toBe("unnamed-hand");
86
+ });
87
+ it("handles missing category", () => {
88
+ const skill = {
89
+ ...sampleSkill,
90
+ category: undefined,
91
+ };
92
+ const config = translateToHand(skill);
93
+ expect(config.metadata.category).toBe("general");
94
+ });
95
+ it("truncates long names to 64 chars", () => {
96
+ const skill = {
97
+ ...sampleSkill,
98
+ name: "a".repeat(100),
99
+ };
100
+ const config = translateToHand(skill);
101
+ expect(config.hand.name.length).toBeLessThanOrEqual(64);
102
+ });
103
+ });
104
+ describe("serializeHandToml", () => {
105
+ it("serializes HandConfig to valid TOML", () => {
106
+ const config = translateToHand(sampleSkill);
107
+ const toml = serializeHandToml(config);
108
+ expect(toml).toContain("[hand]");
109
+ expect(toml).toContain('name = "code-reviewer"');
110
+ expect(toml).toContain("[instructions]");
111
+ expect(toml).toContain("[model]");
112
+ expect(toml).toContain("[limits]");
113
+ expect(toml).toContain("[metadata]");
114
+ });
115
+ it("uses multiline strings for long system_prompt", () => {
116
+ const config = translateToHand(sampleSkill);
117
+ const toml = serializeHandToml(config);
118
+ // Long instructions should use multiline basic strings
119
+ expect(toml).toContain('"""');
120
+ });
121
+ it("escapes special characters in strings", () => {
122
+ const skill = {
123
+ ...sampleSkill,
124
+ description: 'Has "quotes" and \\ backslashes',
125
+ };
126
+ const config = translateToHand(skill);
127
+ const toml = serializeHandToml(config);
128
+ expect(toml).toContain('\\"quotes\\"');
129
+ expect(toml).toContain("\\\\");
130
+ });
131
+ it("escapes control characters in strings", () => {
132
+ const skill = {
133
+ ...sampleSkill,
134
+ description: "Has\ttabs and\rcarriage returns",
135
+ };
136
+ const config = translateToHand(skill);
137
+ const toml = serializeHandToml(config);
138
+ expect(toml).toContain("\\t");
139
+ expect(toml).toContain("\\r");
140
+ });
141
+ it("serializes arrays correctly", () => {
142
+ const config = translateToHand(sampleSkill);
143
+ const toml = serializeHandToml(config);
144
+ expect(toml).toContain('platforms = ["CLAUDE_CODE", "CURSOR"]');
145
+ });
146
+ it("includes numeric values without quotes", () => {
147
+ const config = translateToHand(sampleSkill);
148
+ const toml = serializeHandToml(config);
149
+ expect(toml).toContain("max_tokens = 4096");
150
+ expect(toml).toContain("temperature = 0.3");
151
+ expect(toml).toContain("timeout_seconds = 120");
152
+ expect(toml).toContain("max_retries = 2");
153
+ });
154
+ it("ends with newline", () => {
155
+ const config = translateToHand(sampleSkill);
156
+ const toml = serializeHandToml(config);
157
+ expect(toml.endsWith("\n")).toBe(true);
158
+ });
159
+ });
160
+ //# sourceMappingURL=openfang.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfang.test.js","sourceRoot":"","sources":["../src/openfang.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@skills-hub-ai/skill-parser",
3
+ "version": "0.1.0",
4
+ "files": ["dist"],
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./openfang": {
14
+ "types": "./dist/openfang.d.ts",
15
+ "import": "./dist/openfang.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "test": "vitest run",
22
+ "lint": "tsc --noEmit"
23
+ },
24
+ "dependencies": {
25
+ "@skills-hub-ai/shared": "workspace:*",
26
+ "yaml": "^2.6.0",
27
+ "zod": "^3.23.0"
28
+ },
29
+ "devDependencies": {
30
+ "typescript": "^5.7.0",
31
+ "vitest": "^2.0.0"
32
+ }
33
+ }