-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse-skills.ts
More file actions
100 lines (86 loc) · 2.62 KB
/
parse-skills.ts
File metadata and controls
100 lines (86 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Parse the awesome-openclaw-skills README.md into JSON seed data
import * as fs from "fs";
import * as path from "path";
interface SkillEntry {
name: string;
slug: string;
description: string;
clawHubUrl: string;
author: string;
category: string;
}
interface CategoryEntry {
name: string;
slug: string;
skillCount: number;
}
function slugify(text: string): string {
return text
.toLowerCase()
.replace(/&/g, "and")
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)/g, "");
}
function parseReadme(content: string): {
skills: SkillEntry[];
categories: CategoryEntry[];
} {
const skills: SkillEntry[] = [];
const categoryMap = new Map<string, number>();
let currentCategory = "";
const lines = content.split("\n");
for (const line of lines) {
// Detect category headers: <summary><h3 ...>Category Name</h3></summary>
const categoryMatch = line.match(
/<summary><h3[^>]*>([^<]+)<\/h3><\/summary>/
);
if (categoryMatch) {
currentCategory = categoryMatch[1].trim();
if (!categoryMap.has(currentCategory)) {
categoryMap.set(currentCategory, 0);
}
continue;
}
// Detect skill entries: - [name](url) - Description
const skillMatch = line.match(
/^- \[([^\]]+)\]\((https?:\/\/[^)]+)\)\s*-\s*(.+)$/
);
if (skillMatch && currentCategory) {
const [, name, url, description] = skillMatch;
// Extract author from URL: https://clawskills.sh/skills/author-skillname
const authorMatch = url.match(/\/skills\/([^-]+)-/);
const author = authorMatch ? authorMatch[1] : "";
skills.push({
name: name.trim(),
slug: slugify(name.trim()),
description: description.trim(),
clawHubUrl: url,
author,
category: currentCategory,
});
categoryMap.set(
currentCategory,
(categoryMap.get(currentCategory) || 0) + 1
);
}
}
const categories: CategoryEntry[] = Array.from(categoryMap.entries()).map(
([name, count]) => ({
name,
slug: slugify(name),
skillCount: count,
})
);
return { skills, categories };
}
const readmePath =
process.argv[2] || "/tmp/awesome-openclaw-skills-readme.md";
const content = fs.readFileSync(readmePath, "utf-8");
const { skills, categories } = parseReadme(content);
const outputDir = path.join(__dirname, "..", "prisma");
fs.writeFileSync(
path.join(outputDir, "seed-data.json"),
JSON.stringify({ categories, skills }, null, 2)
);
console.log(`Parsed ${categories.length} categories and ${skills.length} skills`);
categories.forEach((c) => console.log(` ${c.name}: ${c.skillCount} skills`));