transskill 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.
Files changed (107) hide show
  1. package/README.md +187 -0
  2. package/README.zh.md +190 -0
  3. package/dist/core/errors.d.ts +8 -0
  4. package/dist/core/errors.d.ts.map +1 -0
  5. package/dist/core/errors.js +12 -0
  6. package/dist/core/errors.js.map +1 -0
  7. package/dist/core/types.d.ts +105 -0
  8. package/dist/core/types.d.ts.map +1 -0
  9. package/dist/core/types.js +2 -0
  10. package/dist/core/types.js.map +1 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +249 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/mapper/default.mapper.d.ts +18 -0
  16. package/dist/mapper/default.mapper.d.ts.map +1 -0
  17. package/dist/mapper/default.mapper.js +107 -0
  18. package/dist/mapper/default.mapper.js.map +1 -0
  19. package/dist/mapper/index.d.ts +3 -0
  20. package/dist/mapper/index.d.ts.map +1 -0
  21. package/dist/mapper/index.js +2 -0
  22. package/dist/mapper/index.js.map +1 -0
  23. package/dist/mapper/mapper.interface.d.ts +25 -0
  24. package/dist/mapper/mapper.interface.d.ts.map +1 -0
  25. package/dist/mapper/mapper.interface.js +2 -0
  26. package/dist/mapper/mapper.interface.js.map +1 -0
  27. package/dist/parser/cursor-rules.parser.d.ts +16 -0
  28. package/dist/parser/cursor-rules.parser.d.ts.map +1 -0
  29. package/dist/parser/cursor-rules.parser.js +38 -0
  30. package/dist/parser/cursor-rules.parser.js.map +1 -0
  31. package/dist/parser/index.d.ts +6 -0
  32. package/dist/parser/index.d.ts.map +1 -0
  33. package/dist/parser/index.js +5 -0
  34. package/dist/parser/index.js.map +1 -0
  35. package/dist/parser/mdc.parser.d.ts +17 -0
  36. package/dist/parser/mdc.parser.d.ts.map +1 -0
  37. package/dist/parser/mdc.parser.js +62 -0
  38. package/dist/parser/mdc.parser.js.map +1 -0
  39. package/dist/parser/parser-registry.d.ts +25 -0
  40. package/dist/parser/parser-registry.d.ts.map +1 -0
  41. package/dist/parser/parser-registry.js +44 -0
  42. package/dist/parser/parser-registry.js.map +1 -0
  43. package/dist/parser/parser.interface.d.ts +16 -0
  44. package/dist/parser/parser.interface.d.ts.map +1 -0
  45. package/dist/parser/parser.interface.js +2 -0
  46. package/dist/parser/parser.interface.js.map +1 -0
  47. package/dist/parser/skill-md.parser.d.ts +17 -0
  48. package/dist/parser/skill-md.parser.d.ts.map +1 -0
  49. package/dist/parser/skill-md.parser.js +117 -0
  50. package/dist/parser/skill-md.parser.js.map +1 -0
  51. package/dist/renderer/cursor-rules.renderer.d.ts +17 -0
  52. package/dist/renderer/cursor-rules.renderer.d.ts.map +1 -0
  53. package/dist/renderer/cursor-rules.renderer.js +61 -0
  54. package/dist/renderer/cursor-rules.renderer.js.map +1 -0
  55. package/dist/renderer/index.d.ts +6 -0
  56. package/dist/renderer/index.d.ts.map +1 -0
  57. package/dist/renderer/index.js +5 -0
  58. package/dist/renderer/index.js.map +1 -0
  59. package/dist/renderer/mdc.renderer.d.ts +15 -0
  60. package/dist/renderer/mdc.renderer.d.ts.map +1 -0
  61. package/dist/renderer/mdc.renderer.js +52 -0
  62. package/dist/renderer/mdc.renderer.js.map +1 -0
  63. package/dist/renderer/renderer-registry.d.ts +6 -0
  64. package/dist/renderer/renderer-registry.d.ts.map +1 -0
  65. package/dist/renderer/renderer-registry.js +16 -0
  66. package/dist/renderer/renderer-registry.js.map +1 -0
  67. package/dist/renderer/renderer.interface.d.ts +15 -0
  68. package/dist/renderer/renderer.interface.d.ts.map +1 -0
  69. package/dist/renderer/renderer.interface.js +2 -0
  70. package/dist/renderer/renderer.interface.js.map +1 -0
  71. package/dist/renderer/skill-md.renderer.d.ts +15 -0
  72. package/dist/renderer/skill-md.renderer.d.ts.map +1 -0
  73. package/dist/renderer/skill-md.renderer.js +76 -0
  74. package/dist/renderer/skill-md.renderer.js.map +1 -0
  75. package/dist/resolver/github.resolver.d.ts +11 -0
  76. package/dist/resolver/github.resolver.d.ts.map +1 -0
  77. package/dist/resolver/github.resolver.js +89 -0
  78. package/dist/resolver/github.resolver.js.map +1 -0
  79. package/dist/resolver/index.d.ts +5 -0
  80. package/dist/resolver/index.d.ts.map +1 -0
  81. package/dist/resolver/index.js +4 -0
  82. package/dist/resolver/index.js.map +1 -0
  83. package/dist/resolver/local.resolver.d.ts +11 -0
  84. package/dist/resolver/local.resolver.d.ts.map +1 -0
  85. package/dist/resolver/local.resolver.js +55 -0
  86. package/dist/resolver/local.resolver.js.map +1 -0
  87. package/dist/resolver/resolver-registry.d.ts +14 -0
  88. package/dist/resolver/resolver-registry.d.ts.map +1 -0
  89. package/dist/resolver/resolver-registry.js +31 -0
  90. package/dist/resolver/resolver-registry.js.map +1 -0
  91. package/dist/resolver/resolver.interface.d.ts +12 -0
  92. package/dist/resolver/resolver.interface.d.ts.map +1 -0
  93. package/dist/resolver/resolver.interface.js +2 -0
  94. package/dist/resolver/resolver.interface.js.map +1 -0
  95. package/dist/utils/file-utils.d.ts +9 -0
  96. package/dist/utils/file-utils.d.ts.map +1 -0
  97. package/dist/utils/file-utils.js +37 -0
  98. package/dist/utils/file-utils.js.map +1 -0
  99. package/dist/utils/format-detector.d.ts +11 -0
  100. package/dist/utils/format-detector.d.ts.map +1 -0
  101. package/dist/utils/format-detector.js +42 -0
  102. package/dist/utils/format-detector.js.map +1 -0
  103. package/dist/utils/logger.d.ts +7 -0
  104. package/dist/utils/logger.d.ts.map +1 -0
  105. package/dist/utils/logger.js +20 -0
  106. package/dist/utils/logger.js.map +1 -0
  107. package/package.json +49 -0
package/dist/index.js ADDED
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { readFileSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, join } from 'node:path';
6
+ import { registerResolver, LocalResolver, GitHubResolver, resolveInput } from './resolver/index.js';
7
+ import { registerParser, SKILLMdParser, CursorRulesParser, MdcParser, getRegisteredFormats } from './parser/index.js';
8
+ import { DefaultMapper } from './mapper/index.js';
9
+ import { registerRenderer, SKILLMdRenderer, CursorRulesRenderer, MdcRenderer, getRegisteredRenderers } from './renderer/index.js';
10
+ import { detectFormatFromPath } from './utils/format-detector.js';
11
+ import { writeOutput, ensureDir, displayPath } from './utils/file-utils.js';
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
15
+ // ============================================================
16
+ // Bootstrap: register all plugins
17
+ // ============================================================
18
+ registerResolver(new GitHubResolver());
19
+ registerResolver(new LocalResolver());
20
+ registerParser(new SKILLMdParser());
21
+ registerParser(new CursorRulesParser());
22
+ registerParser(new MdcParser());
23
+ const mapper = new DefaultMapper();
24
+ registerRenderer(new SKILLMdRenderer());
25
+ registerRenderer(new CursorRulesRenderer());
26
+ registerRenderer(new MdcRenderer());
27
+ // ============================================================
28
+ // CLI
29
+ // ============================================================
30
+ const program = new Command();
31
+ program
32
+ .name('transskill')
33
+ .description('Cross-platform AI agent skill converter - Write once, run on any agent')
34
+ .version(pkg.version);
35
+ program
36
+ .command('convert <input>')
37
+ .description('Convert a skill file/directory/GitHub repo to another format')
38
+ .requiredOption('-t, --to <format>', 'Target format (skill.md, .cursorrules, .mdc)')
39
+ .option('-o, --output <path>', 'Output directory (default: current directory)')
40
+ .option('--install-to <path>', 'Install directly to target agent config directory')
41
+ .option('--glob <pattern>', 'File glob pattern (for .mdc output)')
42
+ .option('--always-apply', 'Always apply rule (for .mdc output)')
43
+ .option('--dry-run', 'Preview what would happen without actually writing')
44
+ .option('-v, --verbose', 'Show detailed conversion report')
45
+ .action(async (input, options) => {
46
+ try {
47
+ console.log(`\n🔄 TransSkill v${pkg.version}`);
48
+ console.log(`${'─'.repeat(40)}`);
49
+ // Step 1: Resolve input
50
+ const resolved = await resolveInput(input);
51
+ if (options.verbose) {
52
+ console.log(` Source: ${resolved.isRemote ? 'GitHub (remote)' : 'Local'}`);
53
+ console.log(` Path: ${resolved.localPath}`);
54
+ console.log(` Type: ${resolved.type}`);
55
+ }
56
+ // Step 2: Detect format
57
+ const { format: sourceFormat, isDirectory } = detectFormatFromPath(resolved.localPath);
58
+ const targetFormat = options.to;
59
+ console.log(` From: ${sourceFormat}${isDirectory ? ' (directory)' : ''}`);
60
+ console.log(` To: ${targetFormat}`);
61
+ // Step 3: Get parser and renderer
62
+ const { getParser } = await import('./parser/parser-registry.js');
63
+ const { getRenderer } = await import('./renderer/renderer-registry.js');
64
+ const parser = getParser(sourceFormat);
65
+ const renderer = getRenderer(targetFormat);
66
+ if (options.dryRun) {
67
+ console.log(`\n${'─'.repeat(40)}`);
68
+ console.log(`🔍 DRY RUN - no files will be written`);
69
+ console.log(`${'─'.repeat(40)}`);
70
+ console.log(` Pipeline: ${sourceFormat} → ${targetFormat}`);
71
+ console.log(` Input: ${input}`);
72
+ console.log(` Source file: ${resolved.localPath}`);
73
+ if (options.output)
74
+ console.log(` Output: ${options.output}`);
75
+ if (options.installTo)
76
+ console.log(` Install to: ${options.installTo}`);
77
+ if (options.glob)
78
+ console.log(` Glob: ${options.glob}`);
79
+ if (options.alwaysApply)
80
+ console.log(` Always apply: yes`);
81
+ console.log(`${'─'.repeat(40)}\n`);
82
+ console.log('✅ Dry-run complete. Remove --dry-run to execute.\n');
83
+ if (resolved.cleanup)
84
+ await resolved.cleanup();
85
+ return;
86
+ }
87
+ // Step 4: Determine output path
88
+ const cwd = options.installTo || options.output || process.cwd();
89
+ ensureDir(cwd);
90
+ // Step 5: Process
91
+ if (isDirectory) {
92
+ // Directory mode
93
+ const skillDir = parser.parseDirectory(resolved.localPath);
94
+ // Read and parse SKILL.md
95
+ const { readInput } = await import('./utils/file-utils.js');
96
+ const content = readInput(skillDir.skillFile);
97
+ const skill = parser.parse(content, skillDir.skillFile);
98
+ // Apply mapper
99
+ const { skill: mapped, report } = mapper.map(skill, targetFormat);
100
+ // Apply CLI options to mapped skill
101
+ if (options.glob && mapped.platformSpecific.cursor) {
102
+ mapped.platformSpecific.cursor.globs = [options.glob];
103
+ }
104
+ if (options.alwaysApply && mapped.platformSpecific.cursor) {
105
+ mapped.platformSpecific.cursor.alwaysApply = true;
106
+ }
107
+ // Render directory
108
+ if (renderer.renderDirectory) {
109
+ const result = renderer.renderDirectory(skillDir, mapped, cwd);
110
+ console.log(`\n${'─'.repeat(40)}`);
111
+ console.log('✅ Directory conversion complete');
112
+ console.log(` Main: ${displayPath(result.mainOutput)}`);
113
+ for (const copied of result.copiedFiles) {
114
+ console.log(` Copied: ${displayPath(copied)}`);
115
+ }
116
+ for (const skipped of result.skippedFiles) {
117
+ console.log(` ⚠️ Skipped: ${displayPath(skipped)}`);
118
+ }
119
+ }
120
+ else {
121
+ // Fallback: single file output for directory input
122
+ const outPath = join(cwd, `${skillDir.name}${renderer.extension}`);
123
+ writeOutput(outPath, renderer.render(mapped));
124
+ console.log(`\n✅ Converted: ${displayPath(outPath)}`);
125
+ }
126
+ // Show report
127
+ if (report.warnings.length > 0) {
128
+ console.log('');
129
+ for (const w of report.warnings) {
130
+ console.log(` ⚠️ ${w}`);
131
+ }
132
+ }
133
+ if (options.verbose && report.lost.length > 0) {
134
+ console.log(`\n Lost fields: ${report.lost.join(', ')}`);
135
+ }
136
+ }
137
+ else {
138
+ // File mode
139
+ const { readInput } = await import('./utils/file-utils.js');
140
+ const content = readInput(resolved.localPath);
141
+ const skill = parser.parse(content, resolved.localPath);
142
+ // Apply mapper
143
+ const { skill: mapped, report } = mapper.map(skill, targetFormat);
144
+ // Apply CLI options
145
+ if (options.glob && mapped.platformSpecific.cursor) {
146
+ mapped.platformSpecific.cursor.globs = [options.glob];
147
+ }
148
+ if (options.alwaysApply && mapped.platformSpecific.cursor) {
149
+ mapped.platformSpecific.cursor.alwaysApply = true;
150
+ }
151
+ // Render
152
+ const rendered = renderer.render(mapped);
153
+ const { basename, extname } = await import('node:path');
154
+ const outName = basename(resolved.localPath, extname(resolved.localPath)) + renderer.extension;
155
+ const outPath = join(cwd, outName);
156
+ writeOutput(outPath, rendered);
157
+ console.log(`\n${'─'.repeat(40)}`);
158
+ console.log('✅ Conversion complete');
159
+ console.log(` Output: ${displayPath(outPath)}`);
160
+ if (report.warnings.length > 0) {
161
+ console.log('');
162
+ for (const w of report.warnings) {
163
+ console.log(` ⚠️ ${w}`);
164
+ }
165
+ }
166
+ if (options.verbose && report.lost.length > 0) {
167
+ console.log(`\n Lost fields: ${report.lost.join(', ')}`);
168
+ }
169
+ }
170
+ console.log('');
171
+ // Cleanup
172
+ if (resolved.cleanup)
173
+ await resolved.cleanup();
174
+ }
175
+ catch (err) {
176
+ const message = err instanceof Error ? err.message : String(err);
177
+ console.error(`\n❌ Error: ${message}\n`);
178
+ process.exit(1);
179
+ }
180
+ });
181
+ program
182
+ .command('list-formats')
183
+ .description('List all supported input/output formats')
184
+ .action(() => {
185
+ console.log('\n📦 Supported formats:\n');
186
+ console.log(' Input → Output');
187
+ console.log(' ────────────────');
188
+ console.log(' SKILL.md → .cursorrules, .mdc');
189
+ console.log(' .cursorrules → SKILL.md, .mdc');
190
+ console.log(' .mdc → SKILL.md, .cursorrules');
191
+ console.log(' MCP JSON → SKILL.md');
192
+ console.log('');
193
+ console.log(' Input sources:');
194
+ console.log(' ./file Local file');
195
+ console.log(' ./dir/ Local skill directory');
196
+ console.log(' gh:user/repo GitHub repository');
197
+ console.log(' https://github.com/user/repo GitHub URL');
198
+ console.log('');
199
+ console.log(` Parsers: ${getRegisteredFormats().join(', ')}`);
200
+ console.log(` Renderers: ${getRegisteredRenderers().map((r) => r.format).join(', ')}`);
201
+ console.log('');
202
+ });
203
+ program
204
+ .command('validate <input>')
205
+ .description('Validate a skill file or directory')
206
+ .option('-f, --format <format>', 'Specify input format (auto-detected if omitted)')
207
+ .action(async (input, _options) => {
208
+ try {
209
+ console.log(`\n🔍 Validating: ${input}`);
210
+ const resolved = await resolveInput(input);
211
+ console.log(` Resolved: ${resolved.localPath}`);
212
+ console.log(` Type: ${resolved.type}`);
213
+ if (resolved.type === 'directory') {
214
+ const { getParser, detectFormat } = await import('./parser/parser-registry.js');
215
+ const parser = getParser('skill.md');
216
+ const dir = parser.parseDirectory(resolved.localPath);
217
+ console.log(` Skill: ${dir.name}`);
218
+ console.log(` SKILL.md: ${dir.skillFile}`);
219
+ if (dir.scriptsDir)
220
+ console.log(` Scripts: ${dir.scriptsDir}`);
221
+ if (dir.referencesDir)
222
+ console.log(` References: ${dir.referencesDir}`);
223
+ if (dir.assetsDir)
224
+ console.log(` Assets: ${dir.assetsDir}`);
225
+ }
226
+ else {
227
+ const { readInput } = await import('./utils/file-utils.js');
228
+ const content = readInput(resolved.localPath);
229
+ const { detectFormat } = await import('./parser/parser-registry.js');
230
+ const format = detectFormat(content, resolved.localPath);
231
+ if (format) {
232
+ console.log(` Format: ${format}`);
233
+ }
234
+ else {
235
+ console.log(` Format: unknown (use --format to specify)`);
236
+ }
237
+ }
238
+ console.log('\n✅ Validation passed - input looks valid.\n');
239
+ if (resolved.cleanup)
240
+ await resolved.cleanup();
241
+ }
242
+ catch (err) {
243
+ const message = err instanceof Error ? err.message : String(err);
244
+ console.error(`\n❌ Validation failed: ${message}\n`);
245
+ process.exit(1);
246
+ }
247
+ });
248
+ program.parse();
249
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Mapper, MappedResult } from './mapper.interface.js';
2
+ import type { FormatType, IntermediateSkill } from '../core/types.js';
3
+ /**
4
+ * Default mapper handles all bidirectional conversions:
5
+ * SKILL.md ↔ .cursorrules
6
+ * SKILL.md ↔ .mdc
7
+ * .cursorrules ↔ .mdc
8
+ */
9
+ export declare class DefaultMapper implements Mapper {
10
+ private readonly biMap;
11
+ supportedSources(): FormatType[];
12
+ supportedTargets(): FormatType[];
13
+ map(skill: IntermediateSkill, targetFormat: FormatType): MappedResult;
14
+ /** Remove platform-specific fields irrelevant to the target */
15
+ private cleanupPlatformFields;
16
+ private deepClone;
17
+ }
18
+ //# sourceMappingURL=default.mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.mapper.d.ts","sourceRoot":"","sources":["../../src/mapper/default.mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAoB,MAAM,uBAAuB,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEtE;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,MAAM;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAIpB;IAEF,gBAAgB,IAAI,UAAU,EAAE;IAIhC,gBAAgB,IAAI,UAAU,EAAE;IAQhC,GAAG,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,UAAU,GAAG,YAAY;IAmFrE,+DAA+D;IAC/D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,SAAS;CAGlB"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Default mapper handles all bidirectional conversions:
3
+ * SKILL.md ↔ .cursorrules
4
+ * SKILL.md ↔ .mdc
5
+ * .cursorrules ↔ .mdc
6
+ */
7
+ export class DefaultMapper {
8
+ biMap = {
9
+ 'skill.md': ['.cursorrules', '.mdc'],
10
+ '.cursorrules': ['skill.md', '.mdc'],
11
+ '.mdc': ['skill.md', '.cursorrules'],
12
+ };
13
+ supportedSources() {
14
+ return Object.keys(this.biMap);
15
+ }
16
+ supportedTargets() {
17
+ const set = new Set();
18
+ for (const targets of Object.values(this.biMap)) {
19
+ targets.forEach((t) => set.add(t));
20
+ }
21
+ return Array.from(set);
22
+ }
23
+ map(skill, targetFormat) {
24
+ const report = {
25
+ sourceFormat: skill.metadata.sourceFormat,
26
+ targetFormat,
27
+ warnings: [],
28
+ preserved: ['name', 'description', 'instructions'],
29
+ lost: [],
30
+ };
31
+ const result = this.deepClone(skill);
32
+ result.metadata.sourceFormat = targetFormat;
33
+ switch (targetFormat) {
34
+ case '.cursorrules': {
35
+ // .cursorrules has no frontmatter — scripts and asset refs are lost
36
+ if (result.metadata.attachedFiles && result.metadata.attachedFiles.length > 0) {
37
+ report.warnings.push('Scripts and asset references from the skill directory will not work in .cursorrules (pure text format). Files have been copied alongside the output.');
38
+ report.lost.push('attachedFiles (scripts, assets, references)');
39
+ }
40
+ // Claude-specific fields are meaningless in Cursor
41
+ if (result.platformSpecific.claude?.disableModelInvocation) {
42
+ report.warnings.push('.cursorrules does not support disableModelInvocation — rules always apply.');
43
+ report.lost.push('platformSpecific.claude.disableModelInvocation');
44
+ }
45
+ if (result.platformSpecific.claude?.manualOnly) {
46
+ report.lost.push('platformSpecific.claude.manualOnly');
47
+ }
48
+ break;
49
+ }
50
+ case '.mdc': {
51
+ // Ensure cursor-specific fields exist
52
+ if (!result.platformSpecific.cursor) {
53
+ result.platformSpecific.cursor = { alwaysApply: false };
54
+ }
55
+ // Transfer attached files info if available
56
+ if (result.metadata.attachedFiles && result.metadata.attachedFiles.length > 0) {
57
+ report.warnings.push('Attached files were copied but .mdc cannot reference them natively.');
58
+ }
59
+ // Claude-specific fields
60
+ if (result.platformSpecific.claude?.disableModelInvocation) {
61
+ report.warnings.push('disableModelInvocation has no equivalent in .mdc — use alwaysApply for similar effect.');
62
+ report.lost.push('platformSpecific.claude.disableModelInvocation');
63
+ }
64
+ break;
65
+ }
66
+ case 'skill.md': {
67
+ // SKILL.md is the richest format — most fields preserve
68
+ report.preserved.push('metadata.tags', 'metadata.author', 'metadata.version');
69
+ // Cursor-specific globs have no direct equivalent
70
+ if (result.platformSpecific.cursor?.globs) {
71
+ report.warnings.push('File glob scoping (globs) is not supported in SKILL.md. Consider splitting into multiple skills.');
72
+ report.lost.push('platformSpecific.cursor.globs');
73
+ }
74
+ break;
75
+ }
76
+ default: {
77
+ report.warnings.push(`Target format "${targetFormat}" uses generic mapping.`);
78
+ }
79
+ }
80
+ // Clean up platform fields that don't apply to target
81
+ this.cleanupPlatformFields(result, targetFormat);
82
+ return { skill: result, report };
83
+ }
84
+ /** Remove platform-specific fields irrelevant to the target */
85
+ cleanupPlatformFields(skill, targetFormat) {
86
+ switch (targetFormat) {
87
+ case '.cursorrules':
88
+ case '.mdc':
89
+ delete skill.platformSpecific.claude;
90
+ delete skill.platformSpecific.openclaw;
91
+ delete skill.platformSpecific.mcp;
92
+ break;
93
+ case 'skill.md':
94
+ // Keep everything — SKILL.md is the canonical format
95
+ break;
96
+ default:
97
+ delete skill.platformSpecific.cursor;
98
+ delete skill.platformSpecific.claude;
99
+ delete skill.platformSpecific.openclaw;
100
+ delete skill.platformSpecific.mcp;
101
+ }
102
+ }
103
+ deepClone(obj) {
104
+ return JSON.parse(JSON.stringify(obj));
105
+ }
106
+ }
107
+ //# sourceMappingURL=default.mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.mapper.js","sourceRoot":"","sources":["../../src/mapper/default.mapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { DefaultMapper } from './default.mapper.js';
2
+ export type { Mapper, MappedResult, ConversionReport } from './mapper.interface.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mapper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { DefaultMapper } from './default.mapper.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mapper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { FormatType, IntermediateSkill } from '../core/types.js';
2
+ export interface ConversionReport {
3
+ sourceFormat: FormatType;
4
+ targetFormat: FormatType;
5
+ warnings: string[];
6
+ preserved: string[];
7
+ lost: string[];
8
+ }
9
+ /**
10
+ * Mapper interface - maps fields between platform skill formats.
11
+ * Reports what was preserved and what was lost during conversion.
12
+ */
13
+ export interface Mapper {
14
+ /** Map an IntermediateSkill to a target format */
15
+ map(skill: IntermediateSkill, targetFormat: FormatType): MappedResult;
16
+ /** List source formats this mapper supports */
17
+ supportedSources(): FormatType[];
18
+ /** List target formats this mapper supports */
19
+ supportedTargets(): FormatType[];
20
+ }
21
+ export interface MappedResult {
22
+ skill: IntermediateSkill;
23
+ report: ConversionReport;
24
+ }
25
+ //# sourceMappingURL=mapper.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapper.interface.d.ts","sourceRoot":"","sources":["../../src/mapper/mapper.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,UAAU,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,kDAAkD;IAClD,GAAG,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,UAAU,GAAG,YAAY,CAAC;IAEtE,+CAA+C;IAC/C,gBAAgB,IAAI,UAAU,EAAE,CAAC;IAEjC,+CAA+C;IAC/C,gBAAgB,IAAI,UAAU,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,gBAAgB,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mapper.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapper.interface.js","sourceRoot":"","sources":["../../src/mapper/mapper.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import type { Parser } from './parser.interface.js';
2
+ import type { FormatType, IntermediateSkill, SkillDirectory } from '../core/types.js';
3
+ /**
4
+ * Parser for .cursorrules format.
5
+ *
6
+ * .cursorrules is a plain text file with instructions for Cursor IDE.
7
+ * It has no frontmatter — the entire content is treated as instructions.
8
+ * Used by: Cursor IDE (legacy format)
9
+ */
10
+ export declare class CursorRulesParser implements Parser {
11
+ readonly format: FormatType;
12
+ detect(_content: string, filePath?: string): boolean;
13
+ parse(content: string, filePath?: string): IntermediateSkill;
14
+ parseDirectory(dirPath: string): SkillDirectory;
15
+ }
16
+ //# sourceMappingURL=cursor-rules.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-rules.parser.d.ts","sourceRoot":"","sources":["../../src/parser/cursor-rules.parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGtF;;;;;;GAMG;AACH,qBAAa,iBAAkB,YAAW,MAAM;IAC9C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAkB;IAE7C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAIpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAuB5D,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc;CAOhD"}
@@ -0,0 +1,38 @@
1
+ import { basename, extname } from 'node:path';
2
+ import { TransSkillError } from '../core/errors.js';
3
+ /**
4
+ * Parser for .cursorrules format.
5
+ *
6
+ * .cursorrules is a plain text file with instructions for Cursor IDE.
7
+ * It has no frontmatter — the entire content is treated as instructions.
8
+ * Used by: Cursor IDE (legacy format)
9
+ */
10
+ export class CursorRulesParser {
11
+ format = '.cursorrules';
12
+ detect(_content, filePath) {
13
+ return filePath?.endsWith('.cursorrules') ?? false;
14
+ }
15
+ parse(content, filePath) {
16
+ const instructions = content.trim();
17
+ // Derive name from filename (or parent directory)
18
+ const name = filePath
19
+ ? basename(filePath, extname(filePath))
20
+ : 'untitled-rules';
21
+ // Extract first meaningful line as description
22
+ const firstLine = instructions.split('\n')[0]?.replace(/^[#\s]*/, '').trim() || '';
23
+ const description = firstLine.length > 0 ? firstLine : `Cursor rules from ${name}`;
24
+ return {
25
+ name,
26
+ description,
27
+ instructions,
28
+ metadata: {
29
+ sourceFormat: '.cursorrules',
30
+ },
31
+ platformSpecific: {},
32
+ };
33
+ }
34
+ parseDirectory(dirPath) {
35
+ throw new TransSkillError(`.cursorrules does not support directory parsing — use single file mode`, 'UNSUPPORTED_INPUT', { dirPath });
36
+ }
37
+ }
38
+ //# sourceMappingURL=cursor-rules.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-rules.parser.js","sourceRoot":"","sources":["../../src/parser/cursor-rules.parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACnB,MAAM,GAAe,cAAc,CAAC;IAE7C,MAAM,CAAC,QAAgB,EAAE,QAAiB;QACxC,OAAO,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,QAAiB;QACtC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpC,kDAAkD;QAClD,MAAM,IAAI,GAAG,QAAQ;YACnB,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvC,CAAC,CAAC,gBAAgB,CAAC;QAErB,+CAA+C;QAC/C,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACnF,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,IAAI,EAAE,CAAC;QAEnF,OAAO;YACL,IAAI;YACJ,WAAW;YACX,YAAY;YACZ,QAAQ,EAAE;gBACR,YAAY,EAAE,cAAc;aAC7B;YACD,gBAAgB,EAAE,EAAE;SACrB,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,OAAe;QAC5B,MAAM,IAAI,eAAe,CACvB,wEAAwE,EACxE,mBAAmB,EACnB,EAAE,OAAO,EAAE,CACZ,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export { registerParser, getParser, detectFormat, getRegisteredFormats, isFormatSupported } from './parser-registry.js';
2
+ export { SKILLMdParser } from './skill-md.parser.js';
3
+ export { CursorRulesParser } from './cursor-rules.parser.js';
4
+ export { MdcParser } from './mdc.parser.js';
5
+ export type { Parser } from './parser.interface.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { registerParser, getParser, detectFormat, getRegisteredFormats, isFormatSupported } from './parser-registry.js';
2
+ export { SKILLMdParser } from './skill-md.parser.js';
3
+ export { CursorRulesParser } from './cursor-rules.parser.js';
4
+ export { MdcParser } from './mdc.parser.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Parser } from './parser.interface.js';
2
+ import type { FormatType, IntermediateSkill, SkillDirectory } from '../core/types.js';
3
+ /**
4
+ * Parser for .mdc format (Cursor 2.3+ rules).
5
+ *
6
+ * .mdc files have YAML frontmatter with description, globs, and alwaysApply fields.
7
+ * The body contains the rule instructions in Markdown.
8
+ *
9
+ * Used by: Cursor IDE (.cursor/rules/*.mdc)
10
+ */
11
+ export declare class MdcParser implements Parser {
12
+ readonly format: FormatType;
13
+ detect(_content: string, filePath?: string): boolean;
14
+ parse(content: string, filePath?: string): IntermediateSkill;
15
+ parseDirectory(dirPath: string): SkillDirectory;
16
+ }
17
+ //# sourceMappingURL=mdc.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdc.parser.d.ts","sourceRoot":"","sources":["../../src/parser/mdc.parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGtF;;;;;;;GAOG;AACH,qBAAa,SAAU,YAAW,MAAM;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAU;IAErC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAIpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB;IA6C5D,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc;CAOhD"}
@@ -0,0 +1,62 @@
1
+ import matter from 'gray-matter';
2
+ import { basename, extname } from 'node:path';
3
+ import { TransSkillError } from '../core/errors.js';
4
+ /**
5
+ * Parser for .mdc format (Cursor 2.3+ rules).
6
+ *
7
+ * .mdc files have YAML frontmatter with description, globs, and alwaysApply fields.
8
+ * The body contains the rule instructions in Markdown.
9
+ *
10
+ * Used by: Cursor IDE (.cursor/rules/*.mdc)
11
+ */
12
+ export class MdcParser {
13
+ format = '.mdc';
14
+ detect(_content, filePath) {
15
+ return filePath?.endsWith('.mdc') ?? false;
16
+ }
17
+ parse(content, filePath) {
18
+ let parsed;
19
+ try {
20
+ parsed = matter(content);
21
+ }
22
+ catch {
23
+ // No valid frontmatter — treat as plain text (fallback)
24
+ const instructions = content.trim();
25
+ const name = filePath ? basename(filePath, extname(filePath)) : 'untitled-rule';
26
+ return {
27
+ name,
28
+ description: instructions.split('\n')[0]?.replace(/^[#\s]*/, '').trim() || name,
29
+ instructions,
30
+ metadata: { sourceFormat: '.mdc' },
31
+ platformSpecific: { cursor: {} },
32
+ };
33
+ }
34
+ const frontmatter = parsed.data;
35
+ const instructions = parsed.content.trim();
36
+ const name = filePath ? basename(filePath, extname(filePath)) : 'untitled-rule';
37
+ const description = typeof frontmatter.description === 'string' ? frontmatter.description : name;
38
+ const cursorSpecific = {};
39
+ if (typeof frontmatter.globs === 'string') {
40
+ cursorSpecific.globs = [frontmatter.globs];
41
+ }
42
+ if (typeof frontmatter.alwaysApply === 'boolean') {
43
+ cursorSpecific.alwaysApply = frontmatter.alwaysApply;
44
+ }
45
+ return {
46
+ name,
47
+ description,
48
+ instructions,
49
+ metadata: {
50
+ sourceFormat: '.mdc',
51
+ rawFrontmatter: { ...frontmatter, description: undefined },
52
+ },
53
+ platformSpecific: {
54
+ cursor: Object.keys(cursorSpecific).length > 0 ? cursorSpecific : undefined,
55
+ },
56
+ };
57
+ }
58
+ parseDirectory(dirPath) {
59
+ throw new TransSkillError('.mdc format does not support directory parsing — use single file mode', 'UNSUPPORTED_INPUT', { dirPath });
60
+ }
61
+ }
62
+ //# sourceMappingURL=mdc.parser.js.map