transskill 0.1.2 → 0.2.1
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 +83 -3
- package/dist/index.js.map +1 -1
- package/dist/mapper/default.mapper.js +2 -2
- package/dist/mapper/default.mapper.js.map +1 -1
- package/dist/parser/cursor-rules.parser.d.ts +5 -0
- package/dist/parser/cursor-rules.parser.d.ts.map +1 -1
- package/dist/parser/cursor-rules.parser.js +28 -5
- package/dist/parser/cursor-rules.parser.js.map +1 -1
- package/dist/parser/skill-md.parser.d.ts.map +1 -1
- package/dist/parser/skill-md.parser.js +4 -5
- package/dist/parser/skill-md.parser.js.map +1 -1
- package/dist/renderer/claude-md.renderer.d.ts +0 -6
- package/dist/renderer/claude-md.renderer.d.ts.map +1 -1
- package/dist/renderer/claude-md.renderer.js +25 -22
- package/dist/renderer/claude-md.renderer.js.map +1 -1
- package/dist/renderer/cursor-rules.renderer.d.ts +0 -8
- package/dist/renderer/cursor-rules.renderer.d.ts.map +1 -1
- package/dist/renderer/cursor-rules.renderer.js +20 -37
- package/dist/renderer/cursor-rules.renderer.js.map +1 -1
- package/dist/renderer/mcp-json.renderer.d.ts +0 -7
- package/dist/renderer/mcp-json.renderer.d.ts.map +1 -1
- package/dist/renderer/mcp-json.renderer.js +11 -15
- package/dist/renderer/mcp-json.renderer.js.map +1 -1
- package/dist/renderer/mdc.renderer.d.ts +0 -6
- package/dist/renderer/mdc.renderer.d.ts.map +1 -1
- package/dist/renderer/mdc.renderer.js +18 -24
- package/dist/renderer/mdc.renderer.js.map +1 -1
- package/dist/renderer/skill-md.renderer.d.ts +0 -3
- package/dist/renderer/skill-md.renderer.d.ts.map +1 -1
- package/dist/renderer/skill-md.renderer.js +21 -29
- package/dist/renderer/skill-md.renderer.js.map +1 -1
- package/dist/utils/directory-scanner.d.ts +12 -0
- package/dist/utils/directory-scanner.d.ts.map +1 -0
- package/dist/utils/directory-scanner.js +133 -0
- package/dist/utils/directory-scanner.js.map +1 -0
- package/dist/utils/file-copier.d.ts +15 -0
- package/dist/utils/file-copier.d.ts.map +1 -0
- package/dist/utils/file-copier.js +69 -0
- package/dist/utils/file-copier.js.map +1 -0
- package/dist/utils/format-detector.d.ts +0 -1
- package/dist/utils/format-detector.d.ts.map +1 -1
- package/dist/utils/format-detector.js +39 -6
- package/dist/utils/format-detector.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { writeFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
|
|
4
|
-
* Renders IntermediateSkill to MCP JSON format.
|
|
5
|
-
*
|
|
6
|
-
* Output: { name, description, tools[] }
|
|
7
|
-
* Only includes tools from platformSpecific.mcp.tools.
|
|
8
|
-
* Falls back to generating a single tool from the skill instructions.
|
|
9
|
-
*/
|
|
3
|
+
import { copyAttachedFiles } from '../utils/file-copier.js';
|
|
10
4
|
export class MCPJsonRenderer {
|
|
11
5
|
format = 'mcp.json';
|
|
12
6
|
extension = '.json';
|
|
@@ -24,16 +18,11 @@ export class MCPJsonRenderer {
|
|
|
24
18
|
}));
|
|
25
19
|
}
|
|
26
20
|
else {
|
|
27
|
-
// Fallback: generate a single tool from instructions
|
|
28
21
|
output.tools = [
|
|
29
22
|
{
|
|
30
23
|
name: skill.name.replace(/[^a-z0-9_]/gi, '_').toLowerCase(),
|
|
31
24
|
description: skill.description || 'Tool generated from skill',
|
|
32
|
-
inputSchema: {
|
|
33
|
-
type: 'object',
|
|
34
|
-
properties: {},
|
|
35
|
-
required: [],
|
|
36
|
-
},
|
|
25
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
37
26
|
},
|
|
38
27
|
];
|
|
39
28
|
}
|
|
@@ -42,11 +31,18 @@ export class MCPJsonRenderer {
|
|
|
42
31
|
renderDirectory(skillDir, skill, outputPath) {
|
|
43
32
|
const jsonPath = join(outputPath, `${skillDir.name}.mcp.json`);
|
|
44
33
|
writeFileSync(jsonPath, this.render(skill), 'utf-8');
|
|
34
|
+
const allCopied = [];
|
|
35
|
+
const allSkipped = [];
|
|
36
|
+
if (skill.metadata.attachedFiles && skill.metadata.attachedFiles.length > 0) {
|
|
37
|
+
const result = copyAttachedFiles(skill.metadata.attachedFiles, outputPath);
|
|
38
|
+
allCopied.push(...result.copied);
|
|
39
|
+
allSkipped.push(...result.skipped);
|
|
40
|
+
}
|
|
45
41
|
return {
|
|
46
42
|
skillName: skill.name,
|
|
47
43
|
mainOutput: jsonPath,
|
|
48
|
-
copiedFiles:
|
|
49
|
-
skippedFiles:
|
|
44
|
+
copiedFiles: allCopied,
|
|
45
|
+
skippedFiles: allSkipped,
|
|
50
46
|
};
|
|
51
47
|
}
|
|
52
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-json.renderer.js","sourceRoot":"","sources":["../../src/renderer/mcp-json.renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-json.renderer.js","sourceRoot":"","sources":["../../src/renderer/mcp-json.renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,OAAO,eAAe;IACjB,MAAM,GAAe,UAAU,CAAC;IAChC,SAAS,GAAG,OAAO,CAAC;IAE7B,MAAM,CAAC,KAAwB;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC;QAChD,MAAM,MAAM,GAA4B;YACtC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC;QAEF,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;aAC3B,CAAC,CAAC,CAAC;QACN,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,GAAG;gBACb;oBACE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;oBAC3D,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,2BAA2B;oBAC7D,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;iBAC9D;aACF,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,CAAC;IAED,eAAe,CACb,QAAwB,EACxB,KAAwB,EACxB,UAAkB;QAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC;QAC/D,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAErD,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5E,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;YAC3E,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QAED,OAAO;YACL,SAAS,EAAE,KAAK,CAAC,IAAI;YACrB,UAAU,EAAE,QAAQ;YACpB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,UAAU;SACzB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { Renderer } from './renderer.interface.js';
|
|
2
2
|
import type { FormatType, IntermediateSkill, SkillDirectory, DirectoryConversionResult } from '../core/types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Renders IntermediateSkill to .mdc format (Cursor 2.3+).
|
|
5
|
-
*
|
|
6
|
-
* .mdc files have YAML frontmatter with description, globs, and alwaysApply.
|
|
7
|
-
* The body contains the rule instructions.
|
|
8
|
-
*/
|
|
9
3
|
export declare class MdcRenderer implements Renderer {
|
|
10
4
|
readonly format: FormatType;
|
|
11
5
|
readonly extension = ".mdc";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdc.renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/mdc.renderer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"mdc.renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/mdc.renderer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAGjH,qBAAa,WAAY,YAAW,QAAQ;IAC1C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAU;IACrC,QAAQ,CAAC,SAAS,UAAU;IAE5B,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAiBxC,eAAe,CACb,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,iBAAiB,EACxB,UAAU,EAAE,MAAM,GACjB,yBAAyB;CAyB7B"}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import { writeFileSync
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
|
-
|
|
5
|
-
* Renders IntermediateSkill to .mdc format (Cursor 2.3+).
|
|
6
|
-
*
|
|
7
|
-
* .mdc files have YAML frontmatter with description, globs, and alwaysApply.
|
|
8
|
-
* The body contains the rule instructions.
|
|
9
|
-
*/
|
|
4
|
+
import { copyAttachedFiles, copyDirectoryTree } from '../utils/file-copier.js';
|
|
10
5
|
export class MdcRenderer {
|
|
11
6
|
format = '.mdc';
|
|
12
7
|
extension = '.mdc';
|
|
@@ -18,34 +13,33 @@ export class MdcRenderer {
|
|
|
18
13
|
if (cursor?.globs && cursor.globs.length > 0) {
|
|
19
14
|
frontmatter.globs = cursor.globs.length === 1 ? cursor.globs[0] : cursor.globs.join(', ');
|
|
20
15
|
}
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
// Only emit alwaysApply when true — false is the Cursor default
|
|
17
|
+
if (cursor?.alwaysApply === true) {
|
|
18
|
+
frontmatter.alwaysApply = true;
|
|
23
19
|
}
|
|
24
20
|
return matter.stringify(skill.instructions || '', frontmatter);
|
|
25
21
|
}
|
|
26
22
|
renderDirectory(skillDir, skill, outputPath) {
|
|
27
|
-
const
|
|
28
|
-
const
|
|
23
|
+
const allCopied = [];
|
|
24
|
+
const allSkipped = [];
|
|
29
25
|
const mdcPath = join(outputPath, `${skillDir.name}.mdc`);
|
|
30
26
|
writeFileSync(mdcPath, this.render(skill), 'utf-8');
|
|
31
|
-
if (
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
catch {
|
|
41
|
-
skipped.push(skillDir.scriptsDir);
|
|
27
|
+
if (skill.metadata.attachedFiles && skill.metadata.attachedFiles.length > 0) {
|
|
28
|
+
const result = copyAttachedFiles(skill.metadata.attachedFiles, outputPath);
|
|
29
|
+
allCopied.push(...result.copied);
|
|
30
|
+
allSkipped.push(...result.skipped);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
if (skillDir.scriptsDir) {
|
|
34
|
+
const target = join(outputPath, 'scripts');
|
|
35
|
+
allCopied.push(...copyDirectoryTree(skillDir.scriptsDir, target));
|
|
42
36
|
}
|
|
43
37
|
}
|
|
44
38
|
return {
|
|
45
39
|
skillName: skill.name,
|
|
46
40
|
mainOutput: mdcPath,
|
|
47
|
-
copiedFiles:
|
|
48
|
-
skippedFiles:
|
|
41
|
+
copiedFiles: allCopied,
|
|
42
|
+
skippedFiles: allSkipped,
|
|
49
43
|
};
|
|
50
44
|
}
|
|
51
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdc.renderer.js","sourceRoot":"","sources":["../../src/renderer/mdc.renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"mdc.renderer.js","sourceRoot":"","sources":["../../src/renderer/mdc.renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE/E,MAAM,OAAO,WAAW;IACb,MAAM,GAAe,MAAM,CAAC;IAC5B,SAAS,GAAG,MAAM,CAAC;IAE5B,MAAM,CAAC,KAAwB;QAC7B,MAAM,WAAW,GAA4B;YAC3C,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC;QAEF,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAC7C,IAAI,MAAM,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,WAAW,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5F,CAAC;QACD,gEAAgE;QAChE,IAAI,MAAM,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC;YACjC,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC;QACjC,CAAC;QAED,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAED,eAAe,CACb,QAAwB,EACxB,KAAwB,EACxB,UAAkB;QAElB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC;QACzD,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAEpD,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5E,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;YAC3E,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;gBAC3C,SAAS,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QAED,OAAO;YACL,SAAS,EAAE,KAAK,CAAC,IAAI;YACrB,UAAU,EAAE,OAAO;YACnB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,UAAU;SACzB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -2,9 +2,6 @@ import type { Renderer } from './renderer.interface.js';
|
|
|
2
2
|
import type { FormatType, IntermediateSkill, SkillDirectory, DirectoryConversionResult } from '../core/types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Renders IntermediateSkill back to SKILL.md format.
|
|
5
|
-
*
|
|
6
|
-
* Output: YAML frontmatter (name, description, tags, author, version)
|
|
7
|
-
* + Markdown body (instructions)
|
|
8
5
|
*/
|
|
9
6
|
export declare class SKILLMdRenderer implements Renderer {
|
|
10
7
|
readonly format: FormatType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-md.renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/skill-md.renderer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"skill-md.renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/skill-md.renderer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAGjH;;GAEG;AACH,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAc;IACzC,QAAQ,CAAC,SAAS,SAAS;IAE3B,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAqBxC,eAAe,CACb,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,iBAAiB,EACxB,UAAU,EAAE,MAAM,GACjB,yBAAyB;CAsC7B"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import { writeFileSync
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
|
+
import { copyAttachedFiles, copyDirectoryTree } from '../utils/file-copier.js';
|
|
4
5
|
/**
|
|
5
6
|
* Renders IntermediateSkill back to SKILL.md format.
|
|
6
|
-
*
|
|
7
|
-
* Output: YAML frontmatter (name, description, tags, author, version)
|
|
8
|
-
* + Markdown body (instructions)
|
|
9
7
|
*/
|
|
10
8
|
export class SKILLMdRenderer {
|
|
11
9
|
format = 'skill.md';
|
|
@@ -35,34 +33,28 @@ export class SKILLMdRenderer {
|
|
|
35
33
|
const skipped = [];
|
|
36
34
|
const skillMdPath = join(outputPath, 'SKILL.md');
|
|
37
35
|
writeFileSync(skillMdPath, this.render(skill), 'utf-8');
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
skipped.push(skillDir.scriptsDir);
|
|
46
|
-
}
|
|
36
|
+
// Copy attached files from skill metadata (survives mapper transform)
|
|
37
|
+
if (skill.metadata.attachedFiles && skill.metadata.attachedFiles.length > 0) {
|
|
38
|
+
const result = copyAttachedFiles(skill.metadata.attachedFiles, outputPath);
|
|
39
|
+
copied.push(...result.copied);
|
|
40
|
+
skipped.push(...result.skipped);
|
|
47
41
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
else {
|
|
43
|
+
// Fallback: copy from skillDir directly (pre-mapper paths)
|
|
44
|
+
if (skillDir.scriptsDir) {
|
|
45
|
+
const target = join(outputPath, 'scripts');
|
|
46
|
+
const dirCopied = copyDirectoryTree(skillDir.scriptsDir, target);
|
|
47
|
+
copied.push(...dirCopied);
|
|
53
48
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (skillDir.assetsDir) {
|
|
59
|
-
const target = join(outputPath, 'assets');
|
|
60
|
-
try {
|
|
61
|
-
cpSync(skillDir.assetsDir, target, { recursive: true });
|
|
62
|
-
copied.push(target);
|
|
49
|
+
if (skillDir.referencesDir) {
|
|
50
|
+
const target = join(outputPath, 'references');
|
|
51
|
+
const dirCopied = copyDirectoryTree(skillDir.referencesDir, target);
|
|
52
|
+
copied.push(...dirCopied);
|
|
63
53
|
}
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
if (skillDir.assetsDir) {
|
|
55
|
+
const target = join(outputPath, 'assets');
|
|
56
|
+
const dirCopied = copyDirectoryTree(skillDir.assetsDir, target);
|
|
57
|
+
copied.push(...dirCopied);
|
|
66
58
|
}
|
|
67
59
|
}
|
|
68
60
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-md.renderer.js","sourceRoot":"","sources":["../../src/renderer/skill-md.renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"skill-md.renderer.js","sourceRoot":"","sources":["../../src/renderer/skill-md.renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SkillDirectory, AttachedFile } from '../core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build SkillDirectory by scanning a path (file or directory).
|
|
4
|
+
* For files, still returns a minimal SkillDirectory for context.
|
|
5
|
+
*/
|
|
6
|
+
export declare function scanSkillDirectory(localPath: string): SkillDirectory;
|
|
7
|
+
/**
|
|
8
|
+
* Convert a SkillDirectory scan result into AttachedFile[] array
|
|
9
|
+
* that can be stored in IntermediateSkill.metadata.attachedFiles.
|
|
10
|
+
*/
|
|
11
|
+
export declare function skillDirToAttachedFiles(dir: SkillDirectory): AttachedFile[];
|
|
12
|
+
//# sourceMappingURL=directory-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-scanner.d.ts","sourceRoot":"","sources":["../../src/utils/directory-scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAkBrE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CA8DpE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,cAAc,GAAG,YAAY,EAAE,CAwC3E"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readdirSync, statSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Known subdirectory names that carry skill-related files
|
|
5
|
+
*/
|
|
6
|
+
const KNOWN_DIRS = ['scripts', 'references', 'assets', 'templates', 'examples', 'rules'];
|
|
7
|
+
/**
|
|
8
|
+
* Scan a file path and determine its type based on parent directory.
|
|
9
|
+
*/
|
|
10
|
+
function classifyAttachedFile(filePath, rootPath) {
|
|
11
|
+
const rel = relative(rootPath, filePath).replace(/\\/g, '/');
|
|
12
|
+
if (rel.startsWith('scripts/'))
|
|
13
|
+
return 'script';
|
|
14
|
+
if (rel.startsWith('references/'))
|
|
15
|
+
return 'reference';
|
|
16
|
+
if (rel.startsWith('assets/'))
|
|
17
|
+
return 'asset';
|
|
18
|
+
return 'unknown';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build SkillDirectory by scanning a path (file or directory).
|
|
22
|
+
* For files, still returns a minimal SkillDirectory for context.
|
|
23
|
+
*/
|
|
24
|
+
export function scanSkillDirectory(localPath) {
|
|
25
|
+
const stat = statSync(localPath);
|
|
26
|
+
const rootPath = stat.isDirectory() ? localPath : join(localPath, '..');
|
|
27
|
+
const name = rootPath.split('/').pop() || rootPath.split('\\').pop() || 'skill';
|
|
28
|
+
// Find the main skill file
|
|
29
|
+
let skillFile;
|
|
30
|
+
if (stat.isFile()) {
|
|
31
|
+
skillFile = localPath;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Look for known entry point filenames in priority order
|
|
35
|
+
const candidates = ['SKILL.md', 'SOUL.md', 'CLAUDE.md', 'claude.md', 'AGENTS.md'];
|
|
36
|
+
skillFile = '';
|
|
37
|
+
for (const candidate of candidates) {
|
|
38
|
+
const fullPath = join(localPath, candidate);
|
|
39
|
+
if (existsSync(fullPath) && statSync(fullPath).isFile()) {
|
|
40
|
+
skillFile = fullPath;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!skillFile) {
|
|
45
|
+
// Fallback: first .md file
|
|
46
|
+
const files = readdirSync(localPath);
|
|
47
|
+
const mdFile = files.find((f) => f.endsWith('.md') || f.endsWith('.cursorrules') || f.endsWith('.mdc'));
|
|
48
|
+
skillFile = mdFile ? join(localPath, mdFile) : localPath;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Scan for known directories
|
|
52
|
+
let scriptsDir;
|
|
53
|
+
let referencesDir;
|
|
54
|
+
let assetsDir;
|
|
55
|
+
const extraFiles = [];
|
|
56
|
+
try {
|
|
57
|
+
const entries = readdirSync(rootPath, { withFileTypes: true });
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
if (!entry.isDirectory())
|
|
60
|
+
continue;
|
|
61
|
+
if (entry.name === 'scripts')
|
|
62
|
+
scriptsDir = join(rootPath, 'scripts');
|
|
63
|
+
else if (entry.name === 'references')
|
|
64
|
+
referencesDir = join(rootPath, 'references');
|
|
65
|
+
else if (entry.name === 'assets')
|
|
66
|
+
assetsDir = join(rootPath, 'assets');
|
|
67
|
+
else if (KNOWN_DIRS.includes(entry.name)) {
|
|
68
|
+
// Scan extra directories for individual files
|
|
69
|
+
const dirFiles = readdirSync(join(rootPath, entry.name));
|
|
70
|
+
for (const f of dirFiles) {
|
|
71
|
+
extraFiles.push(join(rootPath, entry.name, f));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Not a directory or no access
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
name,
|
|
81
|
+
rootPath,
|
|
82
|
+
skillFile,
|
|
83
|
+
scriptsDir,
|
|
84
|
+
referencesDir,
|
|
85
|
+
assetsDir,
|
|
86
|
+
extraFiles,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Convert a SkillDirectory scan result into AttachedFile[] array
|
|
91
|
+
* that can be stored in IntermediateSkill.metadata.attachedFiles.
|
|
92
|
+
*/
|
|
93
|
+
export function skillDirToAttachedFiles(dir) {
|
|
94
|
+
const files = [];
|
|
95
|
+
const collectFiles = (dirPath, type) => {
|
|
96
|
+
if (!dirPath)
|
|
97
|
+
return;
|
|
98
|
+
try {
|
|
99
|
+
const entries = readdirSync(dirPath, { withFileTypes: true });
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
if (entry.isFile()) {
|
|
102
|
+
files.push({
|
|
103
|
+
relativePath: join(dirPath.replace(dir.rootPath, ''), entry.name).replace(/^\//, ''),
|
|
104
|
+
absolutePath: join(dirPath, entry.name),
|
|
105
|
+
type,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// skip
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
collectFiles(dir.scriptsDir, 'script');
|
|
115
|
+
collectFiles(dir.referencesDir, 'reference');
|
|
116
|
+
collectFiles(dir.assetsDir, 'asset');
|
|
117
|
+
for (const extra of dir.extraFiles) {
|
|
118
|
+
try {
|
|
119
|
+
if (statSync(extra).isFile()) {
|
|
120
|
+
files.push({
|
|
121
|
+
relativePath: extra.replace(dir.rootPath, '').replace(/^\//, ''),
|
|
122
|
+
absolutePath: extra,
|
|
123
|
+
type: classifyAttachedFile(extra, dir.rootPath),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// skip
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return files;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=directory-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-scanner.js","sourceRoot":"","sources":["../../src/utils/directory-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AttachedFile } from '../core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Copy attached files from a skill's metadata into the output directory,
|
|
4
|
+
* preserving relative directory structure.
|
|
5
|
+
*/
|
|
6
|
+
export declare function copyAttachedFiles(attachedFiles: AttachedFile[] | undefined, outputPath: string): {
|
|
7
|
+
copied: string[];
|
|
8
|
+
skipped: string[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Copy all files from a source directory tree to a target directory.
|
|
12
|
+
* Used for copying scripts/references/assets directories entirely.
|
|
13
|
+
*/
|
|
14
|
+
export declare function copyDirectoryTree(sourceDir: string, targetDir: string): string[];
|
|
15
|
+
//# sourceMappingURL=file-copier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-copier.d.ts","sourceRoot":"","sources":["../../src/utils/file-copier.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,YAAY,EAAE,GAAG,SAAS,EACzC,UAAU,EAAE,MAAM,GACjB;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAoCzC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BhF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { mkdirSync, existsSync, cpSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Copy attached files from a skill's metadata into the output directory,
|
|
5
|
+
* preserving relative directory structure.
|
|
6
|
+
*/
|
|
7
|
+
export function copyAttachedFiles(attachedFiles, outputPath) {
|
|
8
|
+
const copied = [];
|
|
9
|
+
const skipped = [];
|
|
10
|
+
if (!attachedFiles || attachedFiles.length === 0) {
|
|
11
|
+
return { copied, skipped };
|
|
12
|
+
}
|
|
13
|
+
for (const file of attachedFiles) {
|
|
14
|
+
const targetPath = join(outputPath, file.relativePath);
|
|
15
|
+
const targetDir = dirname(targetPath);
|
|
16
|
+
try {
|
|
17
|
+
if (!existsSync(targetDir)) {
|
|
18
|
+
mkdirSync(targetDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
// Skip if source doesn't exist
|
|
21
|
+
try {
|
|
22
|
+
if (!existsSync(file.absolutePath)) {
|
|
23
|
+
skipped.push(file.absolutePath);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
skipped.push(file.absolutePath);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
cpSync(file.absolutePath, targetPath, { recursive: true, force: true });
|
|
32
|
+
copied.push(targetPath);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
skipped.push(file.absolutePath);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { copied, skipped };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Copy all files from a source directory tree to a target directory.
|
|
42
|
+
* Used for copying scripts/references/assets directories entirely.
|
|
43
|
+
*/
|
|
44
|
+
export function copyDirectoryTree(sourceDir, targetDir) {
|
|
45
|
+
const copied = [];
|
|
46
|
+
try {
|
|
47
|
+
const entries = readdirSync(sourceDir, { withFileTypes: true });
|
|
48
|
+
if (!existsSync(targetDir)) {
|
|
49
|
+
mkdirSync(targetDir, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
const srcPath = join(sourceDir, entry.name);
|
|
53
|
+
const dstPath = join(targetDir, entry.name);
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
const subCopied = copyDirectoryTree(srcPath, dstPath);
|
|
56
|
+
copied.push(...subCopied);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
cpSync(srcPath, dstPath, { force: true });
|
|
60
|
+
copied.push(dstPath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// silently skip
|
|
66
|
+
}
|
|
67
|
+
return copied;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=file-copier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-copier.js","sourceRoot":"","sources":["../../src/utils/file-copier.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@ export interface FormatDetectionResult {
|
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Detect format from a local file or directory path.
|
|
8
|
-
* For directories, checks if it contains a SKILL.md.
|
|
9
8
|
*/
|
|
10
9
|
export declare function detectFormatFromPath(localPath: string): FormatDetectionResult;
|
|
11
10
|
//# sourceMappingURL=format-detector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-detector.d.ts","sourceRoot":"","sources":["../../src/utils/format-detector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"format-detector.d.ts","sourceRoot":"","sources":["../../src/utils/format-detector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB;AAiBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,qBAAqB,CA8E7E"}
|
|
@@ -1,18 +1,51 @@
|
|
|
1
|
-
import { readFileSync, statSync,
|
|
2
|
-
import { extname,
|
|
1
|
+
import { readFileSync, statSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { extname, basename } from 'node:path';
|
|
3
3
|
import { detectFormat } from '../parser/parser-registry.js';
|
|
4
4
|
import { TransSkillError } from '../core/errors.js';
|
|
5
|
+
/**
|
|
6
|
+
/**
|
|
7
|
+
* Determine format by filename.
|
|
8
|
+
*/
|
|
9
|
+
function formatByFilename(filename) {
|
|
10
|
+
const name = basename(filename);
|
|
11
|
+
if (name === 'SKILL.md')
|
|
12
|
+
return { format: 'skill.md', isDirectory: true };
|
|
13
|
+
if (name === 'SOUL.md')
|
|
14
|
+
return { format: 'soul.md', isDirectory: true };
|
|
15
|
+
if (name === 'CLAUDE.md' || name === 'claude.md')
|
|
16
|
+
return { format: 'claude.md', isDirectory: true };
|
|
17
|
+
if (name === 'AGENTS.md')
|
|
18
|
+
return { format: 'agents.md', isDirectory: true };
|
|
19
|
+
if (name.endsWith('.cursorrules'))
|
|
20
|
+
return { format: '.cursorrules', isDirectory: true };
|
|
21
|
+
if (name.endsWith('.mdc'))
|
|
22
|
+
return { format: '.mdc', isDirectory: true };
|
|
23
|
+
return { format: 'skill.md', isDirectory: true };
|
|
24
|
+
}
|
|
5
25
|
/**
|
|
6
26
|
* Detect format from a local file or directory path.
|
|
7
|
-
* For directories, checks if it contains a SKILL.md.
|
|
8
27
|
*/
|
|
9
28
|
export function detectFormatFromPath(localPath) {
|
|
10
29
|
const stat = statSync(localPath);
|
|
11
30
|
if (stat.isDirectory()) {
|
|
12
|
-
// Directory mode - check for
|
|
13
|
-
|
|
14
|
-
|
|
31
|
+
// Directory mode - check for known skill files in priority order
|
|
32
|
+
const priorityFiles = ['SKILL.md', 'SOUL.md', 'CLAUDE.md', 'claude.md', 'AGENTS.md'];
|
|
33
|
+
const dirEntries = readdirSync(localPath);
|
|
34
|
+
for (const pf of priorityFiles) {
|
|
35
|
+
if (dirEntries.includes(pf)) {
|
|
36
|
+
return formatByFilename(pf);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Check for .cursorrules or .mdc as main file
|
|
40
|
+
const hasCursorrules = dirEntries.find((f) => f.endsWith('.cursorrules'));
|
|
41
|
+
if (hasCursorrules) {
|
|
42
|
+
return { format: '.cursorrules', isDirectory: true };
|
|
43
|
+
}
|
|
44
|
+
const hasMdc = dirEntries.find((f) => f.endsWith('.mdc'));
|
|
45
|
+
if (hasMdc) {
|
|
46
|
+
return { format: '.mdc', isDirectory: true };
|
|
15
47
|
}
|
|
48
|
+
// Fallback: SKILL.md
|
|
16
49
|
return { format: 'skill.md', isDirectory: true };
|
|
17
50
|
}
|
|
18
51
|
// File mode - detect by extension and content
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-detector.js","sourceRoot":"","sources":["../../src/utils/format-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"format-detector.js","sourceRoot":"","sources":["../../src/utils/format-detector.ts"],"names":[],"mappings":"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"}
|