@tmddev/tmd 0.3.0 → 0.3.2

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.
@@ -1,147 +0,0 @@
1
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
2
- import { join } from 'path';
3
- import { getSkillsDir, getSkillDir } from './paths.js';
4
- import yaml from 'js-yaml';
5
- /**
6
- * Fetches and converts a skill from skills.sh to TMD format
7
- */
8
- export async function addSkillFromSkillssh(ownerRepo, skillName) {
9
- // Validate owner/repo format
10
- const parts = ownerRepo.split('/');
11
- if (parts.length !== 2 || !parts[0] || !parts[1]) {
12
- return {
13
- success: false,
14
- error: `Invalid format: "${ownerRepo}". Expected: <owner>/<repo>`
15
- };
16
- }
17
- const [owner, repo] = parts;
18
- // Use provided skill name or derive from repo
19
- const finalSkillName = skillName ?? repo;
20
- // Check if skill already exists
21
- const skillDir = getSkillDir(finalSkillName);
22
- if (existsSync(skillDir)) {
23
- return {
24
- success: false,
25
- error: `Skill already exists: ${finalSkillName}`
26
- };
27
- }
28
- // Fetch skill content from GitHub
29
- const skillContent = await fetchSkillContent(owner, repo, skillName);
30
- if (!skillContent.success) {
31
- return {
32
- success: false,
33
- error: skillContent.error ?? 'Failed to fetch skill'
34
- };
35
- }
36
- // Create skill directory
37
- const skillsDir = getSkillsDir();
38
- if (!existsSync(skillsDir)) {
39
- mkdirSync(skillsDir, { recursive: true });
40
- }
41
- mkdirSync(skillDir, { recursive: true });
42
- // Convert and save skill files
43
- saveSkillFiles(skillDir, finalSkillName, ownerRepo, skillContent.content ?? '', skillName);
44
- return {
45
- success: true,
46
- skillName: finalSkillName,
47
- skillDir
48
- };
49
- }
50
- async function fetchSkillContent(owner, repo, skillName) {
51
- // Build possible paths
52
- const possiblePaths = [];
53
- if (skillName) {
54
- // If skill name is provided, try subdirectory paths (skills.sh format)
55
- const branches = ['main', 'master'];
56
- for (const branch of branches) {
57
- possiblePaths.push(`https://raw.githubusercontent.com/${owner}/${repo}/${branch}/skills/${skillName}/SKILL.md`, `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/skills/${skillName}/skill.md`, `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/skills/${skillName}/README.md`);
58
- }
59
- }
60
- // Also try root-level paths
61
- const branches = ['main', 'master'];
62
- for (const branch of branches) {
63
- possiblePaths.push(`https://raw.githubusercontent.com/${owner}/${repo}/${branch}/SKILL.md`, `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/skill.md`, `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/README.md`);
64
- }
65
- for (const url of possiblePaths) {
66
- try {
67
- const response = await fetch(url);
68
- if (response.ok) {
69
- const content = await response.text();
70
- return { success: true, content };
71
- }
72
- }
73
- catch {
74
- // Continue to next URL
75
- }
76
- }
77
- const skillHint = skillName ? ` (skill: ${skillName})` : '';
78
- return {
79
- success: false,
80
- error: `Could not fetch skill from ${owner}/${repo}${skillHint}. Check that the repository exists and is public.`
81
- };
82
- }
83
- function saveSkillFiles(skillDir, skillName, ownerRepo, content, _originalSkillName) {
84
- // Parse frontmatter if present
85
- const { frontmatter, body } = parseFrontmatter(content);
86
- // Extract name and description from frontmatter or use defaults
87
- const skillNameFromFrontmatter = typeof frontmatter['name'] === 'string' ? frontmatter['name'] : skillName;
88
- const skillDescription = typeof frontmatter['description'] === 'string' ? frontmatter['description'] : `Skill imported from skills.sh: ${ownerRepo}`;
89
- // Create SKILL.md (skills.sh format) with frontmatter
90
- const skillMd = `---
91
- name: ${skillNameFromFrontmatter}
92
- description: ${skillDescription}
93
- ---
94
-
95
- ${body || 'No description available.'}
96
- `;
97
- writeFileSync(join(skillDir, 'SKILL.md'), skillMd);
98
- // Create metadata.yaml with source attribution
99
- // Use frontmatter values if available, otherwise use defaults
100
- const version = typeof frontmatter['version'] === 'string' ? frontmatter['version'] : '1.0.0';
101
- const description = typeof frontmatter['description'] === 'string' ? frontmatter['description'] : `Skill imported from skills.sh: ${ownerRepo}`;
102
- const tags = Array.isArray(frontmatter['tags']) ? frontmatter['tags'] : [];
103
- const metadata = {
104
- name: skillNameFromFrontmatter,
105
- version,
106
- description,
107
- tags,
108
- source: 'skillssh',
109
- repo: ownerRepo,
110
- importedAt: new Date().toISOString(),
111
- interface: {
112
- input: [],
113
- output: {}
114
- }
115
- };
116
- writeFileSync(join(skillDir, 'metadata.yaml'), yaml.dump(metadata));
117
- // Create config.yaml
118
- const config = {
119
- // Default configuration
120
- };
121
- writeFileSync(join(skillDir, 'config.yaml'), yaml.dump(config));
122
- // Create steps.yaml placeholder
123
- const steps = {
124
- steps: [
125
- {
126
- type: 'procedural',
127
- description: 'This skill contains procedural knowledge. See SKILL.md for details.'
128
- }
129
- ]
130
- };
131
- writeFileSync(join(skillDir, 'steps.yaml'), yaml.dump(steps));
132
- }
133
- function parseFrontmatter(content) {
134
- const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
135
- const match = content.match(frontmatterRegex);
136
- if (match?.[1] && match[2]) {
137
- try {
138
- const frontmatter = yaml.load(match[1]);
139
- return { frontmatter: frontmatter ?? {}, body: match[2].trim() };
140
- }
141
- catch {
142
- return { frontmatter: {}, body: content };
143
- }
144
- }
145
- return { frontmatter: {}, body: content };
146
- }
147
- //# sourceMappingURL=skillssh.js.map