@vertesia/build-tools 1.3.0 → 1.4.0-dev.20260615.042033Z
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/README.md +3 -3
- package/lib/bin/build.d.ts +35 -0
- package/lib/bin/build.d.ts.map +1 -0
- package/lib/bin/build.js +79 -0
- package/lib/bin/build.js.map +1 -0
- package/lib/bin/config.d.ts +24 -0
- package/lib/bin/config.d.ts.map +1 -0
- package/lib/bin/config.js +91 -0
- package/lib/bin/config.js.map +1 -0
- package/lib/core/compilers/widget.d.ts +27 -0
- package/lib/core/compilers/widget.d.ts.map +1 -0
- package/lib/core/compilers/widget.js +37 -0
- package/lib/core/compilers/widget.js.map +1 -0
- package/lib/{types → core}/parsers/frontmatter.d.ts +1 -1
- package/lib/core/parsers/frontmatter.d.ts.map +1 -0
- package/lib/{esm → core}/parsers/frontmatter.js +1 -1
- package/lib/core/parsers/frontmatter.js.map +1 -0
- package/lib/core/transformers/index.d.ts +10 -0
- package/lib/core/transformers/index.d.ts.map +1 -0
- package/lib/core/transformers/index.js +10 -0
- package/lib/core/transformers/index.js.map +1 -0
- package/lib/{types/presets → core/transformers}/prompt.d.ts +7 -21
- package/lib/core/transformers/prompt.d.ts.map +1 -0
- package/lib/{esm/presets → core/transformers}/prompt.js +17 -14
- package/lib/core/transformers/prompt.js.map +1 -0
- package/lib/core/transformers/raw.d.ts.map +1 -0
- package/lib/{esm/presets → core/transformers}/raw.js +2 -2
- package/lib/core/transformers/raw.js.map +1 -0
- package/lib/core/transformers/skill-collection.d.ts.map +1 -0
- package/lib/{esm/presets → core/transformers}/skill-collection.js +5 -12
- package/lib/core/transformers/skill-collection.js.map +1 -0
- package/lib/core/transformers/skill.d.ts +111 -0
- package/lib/core/transformers/skill.d.ts.map +1 -0
- package/lib/{esm/presets → core/transformers}/skill.js +70 -51
- package/lib/core/transformers/skill.js.map +1 -0
- package/lib/core/transformers/template-collection.d.ts.map +1 -0
- package/lib/{esm/presets → core/transformers}/template-collection.js +5 -12
- package/lib/core/transformers/template-collection.js.map +1 -0
- package/lib/{types/presets → core/transformers}/template.d.ts +7 -22
- package/lib/core/transformers/template.d.ts.map +1 -0
- package/lib/{esm/presets → core/transformers}/template.js +16 -11
- package/lib/core/transformers/template.js.map +1 -0
- package/lib/{types → core}/types.d.ts +5 -61
- package/lib/core/types.d.ts.map +1 -0
- package/lib/core/types.js +6 -0
- package/lib/{cjs → core}/types.js.map +1 -1
- package/lib/core/utils/asset-copy.d.ts.map +1 -0
- package/lib/core/utils/asset-copy.js.map +1 -0
- package/lib/core/utils/asset-discovery.d.ts.map +1 -0
- package/lib/{esm → core}/utils/asset-discovery.js +4 -4
- package/lib/core/utils/asset-discovery.js.map +1 -0
- package/lib/core/utils/template-asset-discovery.d.ts.map +1 -0
- package/lib/{esm → core}/utils/template-asset-discovery.js +3 -7
- package/lib/core/utils/template-asset-discovery.js.map +1 -0
- package/lib/import-transform/builtins.d.ts +21 -0
- package/lib/import-transform/builtins.d.ts.map +1 -0
- package/lib/import-transform/builtins.js +50 -0
- package/lib/import-transform/builtins.js.map +1 -0
- package/lib/import-transform/chunk-emitter.d.ts +24 -0
- package/lib/import-transform/chunk-emitter.d.ts.map +1 -0
- package/lib/import-transform/chunk-emitter.js +35 -0
- package/lib/import-transform/chunk-emitter.js.map +1 -0
- package/lib/import-transform/detector.d.ts +24 -0
- package/lib/import-transform/detector.d.ts.map +1 -0
- package/lib/import-transform/detector.js +34 -0
- package/lib/import-transform/detector.js.map +1 -0
- package/lib/import-transform/index.d.ts +47 -0
- package/lib/import-transform/index.d.ts.map +1 -0
- package/lib/import-transform/index.js +115 -0
- package/lib/import-transform/index.js.map +1 -0
- package/lib/import-transform/patterns.d.ts +25 -0
- package/lib/import-transform/patterns.d.ts.map +1 -0
- package/lib/import-transform/patterns.js +27 -0
- package/lib/import-transform/patterns.js.map +1 -0
- package/lib/import-transform/resolver.d.ts +23 -0
- package/lib/import-transform/resolver.d.ts.map +1 -0
- package/lib/import-transform/resolver.js +30 -0
- package/lib/import-transform/resolver.js.map +1 -0
- package/lib/import-transform/rewriter.d.ts +21 -0
- package/lib/import-transform/rewriter.d.ts.map +1 -0
- package/lib/import-transform/rewriter.js +30 -0
- package/lib/import-transform/rewriter.js.map +1 -0
- package/lib/import-transform/scanner.d.ts +17 -0
- package/lib/import-transform/scanner.d.ts.map +1 -0
- package/lib/import-transform/scanner.js +46 -0
- package/lib/import-transform/scanner.js.map +1 -0
- package/lib/index.d.ts +39 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +43 -0
- package/lib/index.js.map +1 -0
- package/lib/vite/api-server.d.ts +54 -0
- package/lib/vite/api-server.d.ts.map +1 -0
- package/lib/vite/api-server.js +94 -0
- package/lib/vite/api-server.js.map +1 -0
- package/lib/vite/dev-server.d.ts +42 -0
- package/lib/vite/dev-server.d.ts.map +1 -0
- package/lib/vite/dev-server.js +111 -0
- package/lib/vite/dev-server.js.map +1 -0
- package/lib/vite/index.d.ts +15 -0
- package/lib/vite/index.d.ts.map +1 -0
- package/lib/vite/index.js +15 -0
- package/lib/vite/index.js.map +1 -0
- package/package.json +38 -28
- package/src/bin/build.ts +83 -0
- package/src/bin/config.ts +113 -0
- package/src/core/compilers/widget.ts +69 -0
- package/src/{parsers → core/parsers}/frontmatter.ts +2 -2
- package/src/core/transformers/index.ts +27 -0
- package/src/{presets → core/transformers}/prompt.ts +35 -32
- package/src/{presets → core/transformers}/raw.ts +2 -2
- package/src/{presets → core/transformers}/skill-collection.ts +5 -12
- package/src/{presets → core/transformers}/skill.ts +119 -99
- package/src/{presets → core/transformers}/template-collection.ts +76 -83
- package/src/{presets → core/transformers}/template.ts +121 -116
- package/src/core/types.ts +71 -0
- package/src/{utils → core/utils}/asset-copy.ts +3 -2
- package/src/{utils → core/utils}/asset-discovery.ts +5 -5
- package/src/{utils → core/utils}/template-asset-discovery.ts +70 -77
- package/src/import-transform/builtins.ts +56 -0
- package/src/import-transform/chunk-emitter.ts +60 -0
- package/src/import-transform/detector.ts +56 -0
- package/src/import-transform/index.ts +171 -0
- package/src/import-transform/patterns.ts +34 -0
- package/src/import-transform/resolver.ts +57 -0
- package/src/import-transform/rewriter.ts +48 -0
- package/src/import-transform/scanner.ts +55 -0
- package/src/index.ts +67 -42
- package/src/vite/api-server.ts +142 -0
- package/src/vite/dev-server.ts +128 -0
- package/src/vite/index.ts +15 -0
- package/lib/build-tools.js +0 -2054
- package/lib/build-tools.js.map +0 -1
- package/lib/cjs/index.js +0 -43
- package/lib/cjs/index.js.map +0 -1
- package/lib/cjs/package.json +0 -3
- package/lib/cjs/parsers/frontmatter.js +0 -25
- package/lib/cjs/parsers/frontmatter.js.map +0 -1
- package/lib/cjs/plugin.js +0 -150
- package/lib/cjs/plugin.js.map +0 -1
- package/lib/cjs/presets/index.js +0 -25
- package/lib/cjs/presets/index.js.map +0 -1
- package/lib/cjs/presets/prompt.js +0 -185
- package/lib/cjs/presets/prompt.js.map +0 -1
- package/lib/cjs/presets/raw.js +0 -25
- package/lib/cjs/presets/raw.js.map +0 -1
- package/lib/cjs/presets/skill-collection.js +0 -83
- package/lib/cjs/presets/skill-collection.js.map +0 -1
- package/lib/cjs/presets/skill.js +0 -272
- package/lib/cjs/presets/skill.js.map +0 -1
- package/lib/cjs/presets/template-collection.js +0 -80
- package/lib/cjs/presets/template-collection.js.map +0 -1
- package/lib/cjs/presets/template.js +0 -105
- package/lib/cjs/presets/template.js.map +0 -1
- package/lib/cjs/types.js +0 -6
- package/lib/cjs/utils/asset-copy.js +0 -61
- package/lib/cjs/utils/asset-copy.js.map +0 -1
- package/lib/cjs/utils/asset-discovery.js +0 -100
- package/lib/cjs/utils/asset-discovery.js.map +0 -1
- package/lib/cjs/utils/template-asset-discovery.js +0 -63
- package/lib/cjs/utils/template-asset-discovery.js.map +0 -1
- package/lib/cjs/utils/widget-compiler.js +0 -115
- package/lib/cjs/utils/widget-compiler.js.map +0 -1
- package/lib/cjs/vite.js +0 -45
- package/lib/cjs/vite.js.map +0 -1
- package/lib/esm/index.js +0 -26
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/parsers/frontmatter.js.map +0 -1
- package/lib/esm/plugin.js +0 -144
- package/lib/esm/plugin.js.map +0 -1
- package/lib/esm/presets/index.js +0 -10
- package/lib/esm/presets/index.js.map +0 -1
- package/lib/esm/presets/prompt.js.map +0 -1
- package/lib/esm/presets/raw.js.map +0 -1
- package/lib/esm/presets/skill-collection.js.map +0 -1
- package/lib/esm/presets/skill.js.map +0 -1
- package/lib/esm/presets/template-collection.js.map +0 -1
- package/lib/esm/presets/template.js.map +0 -1
- package/lib/esm/types.js +0 -5
- package/lib/esm/types.js.map +0 -1
- package/lib/esm/utils/asset-copy.js.map +0 -1
- package/lib/esm/utils/asset-discovery.js.map +0 -1
- package/lib/esm/utils/template-asset-discovery.js.map +0 -1
- package/lib/esm/utils/widget-compiler.js +0 -76
- package/lib/esm/utils/widget-compiler.js.map +0 -1
- package/lib/esm/vite.js +0 -42
- package/lib/esm/vite.js.map +0 -1
- package/lib/types/index.d.ts +0 -24
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/parsers/frontmatter.d.ts.map +0 -1
- package/lib/types/plugin.d.ts +0 -10
- package/lib/types/plugin.d.ts.map +0 -1
- package/lib/types/presets/index.d.ts +0 -10
- package/lib/types/presets/index.d.ts.map +0 -1
- package/lib/types/presets/prompt.d.ts.map +0 -1
- package/lib/types/presets/raw.d.ts.map +0 -1
- package/lib/types/presets/skill-collection.d.ts.map +0 -1
- package/lib/types/presets/skill.d.ts +0 -361
- package/lib/types/presets/skill.d.ts.map +0 -1
- package/lib/types/presets/template-collection.d.ts.map +0 -1
- package/lib/types/presets/template.d.ts.map +0 -1
- package/lib/types/types.d.ts.map +0 -1
- package/lib/types/utils/asset-copy.d.ts.map +0 -1
- package/lib/types/utils/asset-discovery.d.ts.map +0 -1
- package/lib/types/utils/template-asset-discovery.d.ts.map +0 -1
- package/lib/types/utils/widget-compiler.d.ts +0 -15
- package/lib/types/utils/widget-compiler.d.ts.map +0 -1
- package/lib/types/vite.d.ts +0 -32
- package/lib/types/vite.d.ts.map +0 -1
- package/src/plugin.ts +0 -166
- package/src/presets/index.ts +0 -10
- package/src/types.ts +0 -140
- package/src/utils/widget-compiler.ts +0 -98
- package/src/vite.ts +0 -45
- /package/lib/{types/presets → core/transformers}/raw.d.ts +0 -0
- /package/lib/{types/presets → core/transformers}/skill-collection.d.ts +0 -0
- /package/lib/{types/presets → core/transformers}/template-collection.d.ts +0 -0
- /package/lib/{types → core}/utils/asset-copy.d.ts +0 -0
- /package/lib/{esm → core}/utils/asset-copy.js +0 -0
- /package/lib/{types → core}/utils/asset-discovery.d.ts +0 -0
- /package/lib/{types → core}/utils/template-asset-discovery.d.ts +0 -0
|
@@ -1,116 +1,121 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template transformer preset for markdown files with frontmatter
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import { discoverTemplateAssets } from '../utils/template-asset-discovery.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Zod schema for template frontmatter validation.
|
|
13
|
-
* Only includes fields authored by the user.
|
|
14
|
-
* The name and id are inferred from the directory structure.
|
|
15
|
-
*/
|
|
16
|
-
const TemplateFrontmatterSchema = z
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
assets: assets.
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Template transformer preset for markdown files with frontmatter
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { parseFrontmatter } from '../parsers/frontmatter.js';
|
|
8
|
+
import type { TransformerPreset } from '../types.js';
|
|
9
|
+
import { discoverTemplateAssets } from '../utils/template-asset-discovery.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Zod schema for template frontmatter validation.
|
|
13
|
+
* Only includes fields authored by the user.
|
|
14
|
+
* The name and id are inferred from the directory structure.
|
|
15
|
+
*/
|
|
16
|
+
const TemplateFrontmatterSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
title: z.string().optional(),
|
|
19
|
+
description: z.string().min(1, 'Template description is required'),
|
|
20
|
+
tags: z.array(z.string()).optional(),
|
|
21
|
+
type: z.enum(['presentation', 'document']),
|
|
22
|
+
})
|
|
23
|
+
.strict();
|
|
24
|
+
|
|
25
|
+
type TemplateFrontmatter = z.infer<typeof TemplateFrontmatterSchema>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* MUST be kept in sync with @vertesia/tools-sdk RenderingTemplateDefinition
|
|
29
|
+
* Zod schema for template definition
|
|
30
|
+
*/
|
|
31
|
+
export const RenderingTemplateDefinitionSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
id: z.string().min(1, 'Template id is required'),
|
|
34
|
+
name: z.string().min(1, 'Template name is required'),
|
|
35
|
+
title: z.string().optional(),
|
|
36
|
+
description: z.string().min(1, 'Template description is required'),
|
|
37
|
+
instructions: z.string(),
|
|
38
|
+
tags: z.array(z.string()).optional(),
|
|
39
|
+
type: z.enum(['presentation', 'document']),
|
|
40
|
+
assets: z.array(z.string()),
|
|
41
|
+
})
|
|
42
|
+
.passthrough();
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* TypeScript type inferred from the Zod schema
|
|
46
|
+
*/
|
|
47
|
+
export type RenderingTemplateDefinition = z.infer<typeof RenderingTemplateDefinitionSchema>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Derive the template path segments from the file path.
|
|
51
|
+
*
|
|
52
|
+
* Example: .../templates/examples/report/TEMPLATE.md
|
|
53
|
+
* → category: "examples", name: "report", relative: "examples/report"
|
|
54
|
+
*/
|
|
55
|
+
function deriveTemplatePathInfo(filePath: string): { category: string; templateName: string; relative: string } {
|
|
56
|
+
const templateDir = path.dirname(filePath);
|
|
57
|
+
const templateName = path.basename(templateDir);
|
|
58
|
+
const collectionDir = path.dirname(templateDir);
|
|
59
|
+
const category = path.basename(collectionDir);
|
|
60
|
+
return { category, templateName, relative: `${category}/${templateName}` };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Template transformer preset
|
|
65
|
+
* Transforms markdown files with ?template suffix OR TEMPLATE.md files into template definition objects
|
|
66
|
+
*
|
|
67
|
+
* Matches:
|
|
68
|
+
* - Files with ?template suffix: ./my-template.md?template
|
|
69
|
+
* - TEMPLATE.md files: ./my-template/TEMPLATE.md
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* import template1 from './my-template.md?template';
|
|
74
|
+
* import template2 from './my-template/TEMPLATE.md';
|
|
75
|
+
* // Both are RenderingTemplateDefinition objects
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export const templateTransformer: TransformerPreset = {
|
|
79
|
+
pattern: /(\.md\?template$|\/TEMPLATE\.md$)/,
|
|
80
|
+
schema: RenderingTemplateDefinitionSchema,
|
|
81
|
+
transform: (content: string, filePath: string) => {
|
|
82
|
+
const { frontmatter, content: markdown } = parseFrontmatter(content);
|
|
83
|
+
|
|
84
|
+
// Validate frontmatter
|
|
85
|
+
const frontmatterValidation = TemplateFrontmatterSchema.safeParse(frontmatter);
|
|
86
|
+
if (!frontmatterValidation.success) {
|
|
87
|
+
const errors = frontmatterValidation.error.issues
|
|
88
|
+
.map((err) => {
|
|
89
|
+
const pathStr = err.path.length > 0 ? err.path.join('.') : 'frontmatter';
|
|
90
|
+
return ` - ${pathStr}: ${err.message}`;
|
|
91
|
+
})
|
|
92
|
+
.join('\n');
|
|
93
|
+
throw new Error(`Invalid frontmatter in ${filePath}:\n${errors}`);
|
|
94
|
+
}
|
|
95
|
+
const validatedFrontmatter: TemplateFrontmatter = frontmatterValidation.data;
|
|
96
|
+
|
|
97
|
+
// Derive template path from directory structure
|
|
98
|
+
const { category, templateName, relative: templatePath } = deriveTemplatePathInfo(filePath);
|
|
99
|
+
|
|
100
|
+
// Discover asset files in the template directory
|
|
101
|
+
const assets = discoverTemplateAssets(filePath, templatePath);
|
|
102
|
+
|
|
103
|
+
// Build template definition
|
|
104
|
+
// Assets use absolute paths for direct server-side resolution
|
|
105
|
+
const templateData: RenderingTemplateDefinition = {
|
|
106
|
+
id: `${category}:${templateName}`,
|
|
107
|
+
name: templateName,
|
|
108
|
+
title: validatedFrontmatter.title,
|
|
109
|
+
description: validatedFrontmatter.description,
|
|
110
|
+
instructions: markdown,
|
|
111
|
+
tags: validatedFrontmatter.tags,
|
|
112
|
+
type: validatedFrontmatter.type,
|
|
113
|
+
assets: assets.fileNames.map((f) => `/templates/${templatePath}/${f}`),
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
data: templateData,
|
|
118
|
+
assets: assets.assetFiles,
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions shared across the Vertesia build-tools pipeline:
|
|
3
|
+
* transformers, transformer results, and asset metadata produced by them.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Asset file to be copied during build
|
|
10
|
+
*/
|
|
11
|
+
export interface AssetFile {
|
|
12
|
+
/** Source file path (absolute) */
|
|
13
|
+
sourcePath: string;
|
|
14
|
+
|
|
15
|
+
/** Relative destination path within assets directory */
|
|
16
|
+
destPath: string;
|
|
17
|
+
|
|
18
|
+
/** Asset type for categorization */
|
|
19
|
+
type: 'script' | 'template';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Result of a transform function
|
|
24
|
+
*/
|
|
25
|
+
export interface TransformResult {
|
|
26
|
+
/** The data to export (can be text or JSON object) */
|
|
27
|
+
data: unknown;
|
|
28
|
+
|
|
29
|
+
/** Optional: additional imports to inject at the top of the generated module */
|
|
30
|
+
imports?: string[];
|
|
31
|
+
|
|
32
|
+
/** Optional: custom code to generate instead of default JSON export */
|
|
33
|
+
code?: string;
|
|
34
|
+
|
|
35
|
+
/** Optional: additional asset files to copy */
|
|
36
|
+
assets?: AssetFile[];
|
|
37
|
+
|
|
38
|
+
/** Optional: widget metadata for compilation */
|
|
39
|
+
widgets?: Array<{ name: string; path: string }>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Transform function that converts file content into exportable data
|
|
44
|
+
*/
|
|
45
|
+
export type TransformFunction = (content: string, filePath: string) => TransformResult | Promise<TransformResult>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Configuration for a single import transformer rule
|
|
49
|
+
*/
|
|
50
|
+
export interface TransformerRule {
|
|
51
|
+
/** Pattern to match import paths (e.g., /\.md\?skill$/ or /\?raw$/) */
|
|
52
|
+
pattern: RegExp;
|
|
53
|
+
|
|
54
|
+
/** Transform function to convert file content */
|
|
55
|
+
transform: TransformFunction;
|
|
56
|
+
|
|
57
|
+
/** Optional: Zod schema for validation */
|
|
58
|
+
schema?: z.ZodType<unknown>;
|
|
59
|
+
|
|
60
|
+
/** Optional: If true, the transformer generates virtual modules (no file to read) */
|
|
61
|
+
virtual?: boolean;
|
|
62
|
+
|
|
63
|
+
/** Optional: additional options for this transformer */
|
|
64
|
+
options?: Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Type for transformer presets — alias for `TransformerRule` used by the
|
|
69
|
+
* built-in preset modules (skill, raw, prompt, template, …).
|
|
70
|
+
*/
|
|
71
|
+
export type TransformerPreset = TransformerRule;
|
|
@@ -38,8 +38,9 @@ export function copyAssetFile(asset: AssetFile, assetsRoot: string): void {
|
|
|
38
38
|
copyFileSync(asset.sourcePath, destPath);
|
|
39
39
|
} catch (error) {
|
|
40
40
|
throw new Error(
|
|
41
|
-
`Failed to copy asset from ${asset.sourcePath} to ${destPath}: ${
|
|
42
|
-
|
|
41
|
+
`Failed to copy asset from ${asset.sourcePath} to ${destPath}: ${
|
|
42
|
+
error instanceof Error ? error.message : String(error)
|
|
43
|
+
}`,
|
|
43
44
|
);
|
|
44
45
|
}
|
|
45
46
|
}
|
|
@@ -50,7 +50,7 @@ function isFile(filePath: string): boolean {
|
|
|
50
50
|
*/
|
|
51
51
|
function getFilesInDirectory(dirPath: string): string[] {
|
|
52
52
|
try {
|
|
53
|
-
return readdirSync(dirPath).filter(file => {
|
|
53
|
+
return readdirSync(dirPath).filter((file) => {
|
|
54
54
|
const fullPath = path.join(dirPath, file);
|
|
55
55
|
return isFile(fullPath);
|
|
56
56
|
});
|
|
@@ -92,7 +92,7 @@ export function discoverSkillAssets(
|
|
|
92
92
|
options: {
|
|
93
93
|
scriptsDir?: string;
|
|
94
94
|
widgetsDir?: string;
|
|
95
|
-
} = {}
|
|
95
|
+
} = {},
|
|
96
96
|
): DiscoveredAssets {
|
|
97
97
|
const skillDir = path.dirname(skillFilePath);
|
|
98
98
|
const files = getFilesInDirectory(skillDir);
|
|
@@ -113,7 +113,7 @@ export function discoverSkillAssets(
|
|
|
113
113
|
assetFiles.push({
|
|
114
114
|
sourcePath: fullPath,
|
|
115
115
|
destPath: path.join(scriptsDir, file),
|
|
116
|
-
type: 'script'
|
|
116
|
+
type: 'script',
|
|
117
117
|
});
|
|
118
118
|
} else if (isWidgetFile(file)) {
|
|
119
119
|
// Widget file (.tsx)
|
|
@@ -121,7 +121,7 @@ export function discoverSkillAssets(
|
|
|
121
121
|
widgets.push(widgetName);
|
|
122
122
|
widgetMetadata.push({
|
|
123
123
|
name: widgetName,
|
|
124
|
-
path: fullPath
|
|
124
|
+
path: fullPath,
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
// Note: We don't add widget .tsx files to assetFiles
|
|
@@ -133,6 +133,6 @@ export function discoverSkillAssets(
|
|
|
133
133
|
scripts,
|
|
134
134
|
widgets,
|
|
135
135
|
widgetMetadata,
|
|
136
|
-
assetFiles
|
|
136
|
+
assetFiles,
|
|
137
137
|
};
|
|
138
138
|
}
|
|
@@ -1,77 +1,70 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utilities for discovering asset files in template directories
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { readdirSync, statSync } from 'node:fs';
|
|
6
|
-
import path from 'node:path';
|
|
7
|
-
import type { AssetFile } from '../types.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Discovered assets in a template directory
|
|
11
|
-
*/
|
|
12
|
-
export interface DiscoveredTemplateAssets {
|
|
13
|
-
/** Asset file names (relative to template dir) */
|
|
14
|
-
fileNames: string[];
|
|
15
|
-
|
|
16
|
-
/** Asset files to be copied */
|
|
17
|
-
assetFiles: AssetFile[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Files to exclude from template asset discovery
|
|
22
|
-
* (source files and the template definition itself)
|
|
23
|
-
*/
|
|
24
|
-
const EXCLUDED_PATTERNS = [
|
|
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
|
-
destPath: path.join('templates', templatePath, file),
|
|
72
|
-
type: 'template',
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return { fileNames, assetFiles };
|
|
77
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for discovering asset files in template directories
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import type { AssetFile } from '../types.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Discovered assets in a template directory
|
|
11
|
+
*/
|
|
12
|
+
export interface DiscoveredTemplateAssets {
|
|
13
|
+
/** Asset file names (relative to template dir) */
|
|
14
|
+
fileNames: string[];
|
|
15
|
+
|
|
16
|
+
/** Asset files to be copied */
|
|
17
|
+
assetFiles: AssetFile[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Files to exclude from template asset discovery
|
|
22
|
+
* (source files and the template definition itself)
|
|
23
|
+
*/
|
|
24
|
+
const EXCLUDED_PATTERNS = [/^TEMPLATE\.md$/, /\.ts$/, /\.js$/];
|
|
25
|
+
|
|
26
|
+
function isExcluded(fileName: string): boolean {
|
|
27
|
+
return EXCLUDED_PATTERNS.some((p) => p.test(fileName));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Discover asset files in a template directory.
|
|
32
|
+
* All files except TEMPLATE.md, *.ts, and *.js are considered assets.
|
|
33
|
+
*
|
|
34
|
+
* @param templateFilePath - Absolute path to the TEMPLATE.md file
|
|
35
|
+
* @param templatePath - The template path segment (e.g., "examples/report")
|
|
36
|
+
* @returns Discovered assets and metadata
|
|
37
|
+
*/
|
|
38
|
+
export function discoverTemplateAssets(templateFilePath: string, templatePath: string): DiscoveredTemplateAssets {
|
|
39
|
+
const templateDir = path.dirname(templateFilePath);
|
|
40
|
+
const fileNames: string[] = [];
|
|
41
|
+
const assetFiles: AssetFile[] = [];
|
|
42
|
+
|
|
43
|
+
let files: string[];
|
|
44
|
+
try {
|
|
45
|
+
files = readdirSync(templateDir).filter((file) => {
|
|
46
|
+
try {
|
|
47
|
+
return statSync(path.join(templateDir, file)).isFile();
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
} catch {
|
|
53
|
+
files = [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
if (isExcluded(file)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fileNames.push(file);
|
|
62
|
+
assetFiles.push({
|
|
63
|
+
sourcePath: path.join(templateDir, file),
|
|
64
|
+
destPath: path.join('templates', templatePath, file),
|
|
65
|
+
type: 'template',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { fileNames, assetFiles };
|
|
70
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI-friendly name registry for the built-in transformers.
|
|
3
|
+
*
|
|
4
|
+
* Names mirror the query-suffix convention used in source code:
|
|
5
|
+
* `?skill` → 'skill'
|
|
6
|
+
* `?skills` → 'skills' (collection)
|
|
7
|
+
* `?template`→ 'template'
|
|
8
|
+
* `?templates`→ 'templates' (collection)
|
|
9
|
+
* `?prompt` → 'prompt'
|
|
10
|
+
* `?raw` → 'raw'
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { promptTransformer } from '../core/transformers/prompt.js';
|
|
14
|
+
import { rawTransformer } from '../core/transformers/raw.js';
|
|
15
|
+
import { skillTransformer } from '../core/transformers/skill.js';
|
|
16
|
+
import { skillCollectionTransformer } from '../core/transformers/skill-collection.js';
|
|
17
|
+
import { templateTransformer } from '../core/transformers/template.js';
|
|
18
|
+
import { templateCollectionTransformer } from '../core/transformers/template-collection.js';
|
|
19
|
+
import type { TransformerRule } from '../core/types.js';
|
|
20
|
+
|
|
21
|
+
export const BUILTIN_TRANSFORMERS: Readonly<Record<string, TransformerRule>> = Object.freeze({
|
|
22
|
+
skill: skillTransformer,
|
|
23
|
+
skills: skillCollectionTransformer,
|
|
24
|
+
template: templateTransformer,
|
|
25
|
+
templates: templateCollectionTransformer,
|
|
26
|
+
prompt: promptTransformer,
|
|
27
|
+
raw: rawTransformer,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/** Names of all registered transformers, in stable order. */
|
|
31
|
+
export const BUILTIN_TRANSFORMER_NAMES: readonly string[] = Object.freeze(Object.keys(BUILTIN_TRANSFORMERS));
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a list of transformer names to their concrete `TransformerRule`
|
|
35
|
+
* instances. Throws if any name is unknown.
|
|
36
|
+
*/
|
|
37
|
+
export function resolveTransformerNames(names: readonly string[]): TransformerRule[] {
|
|
38
|
+
const resolved: TransformerRule[] = [];
|
|
39
|
+
const unknown: string[] = [];
|
|
40
|
+
|
|
41
|
+
for (const name of names) {
|
|
42
|
+
const rule = BUILTIN_TRANSFORMERS[name];
|
|
43
|
+
if (rule) {
|
|
44
|
+
resolved.push(rule);
|
|
45
|
+
} else {
|
|
46
|
+
unknown.push(name);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (unknown.length > 0) {
|
|
51
|
+
const known = BUILTIN_TRANSFORMER_NAMES.join(', ');
|
|
52
|
+
throw new Error(`Unknown transformer name(s): ${unknown.join(', ')}. Known transformers: ${known}.`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return resolved;
|
|
56
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs a transformer against a source file and writes the resulting module
|
|
3
|
+
* as a standalone `.js` chunk inside the lib output.
|
|
4
|
+
*
|
|
5
|
+
* The generated module mirrors the historical code produced by the legacy
|
|
6
|
+
* rollup `load()` hook — it supports `imports`, `code`, and default
|
|
7
|
+
* `export default <data>` payloads — so the runtime behavior of
|
|
8
|
+
* import-transformed builds matches the legacy rollup-based pipeline
|
|
9
|
+
* byte-for-byte.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import type { AssetFile, TransformerRule } from '../core/types.js';
|
|
15
|
+
import type { WidgetMetadata } from '../core/utils/asset-discovery.js';
|
|
16
|
+
|
|
17
|
+
export interface EmittedChunk {
|
|
18
|
+
/** Absolute path of the written chunk. */
|
|
19
|
+
chunkPath: string;
|
|
20
|
+
|
|
21
|
+
/** Generated module source (the same bytes written to `chunkPath`). */
|
|
22
|
+
content: string;
|
|
23
|
+
|
|
24
|
+
/** Assets returned by the transformer that should be copied. */
|
|
25
|
+
assets: AssetFile[];
|
|
26
|
+
|
|
27
|
+
/** Widget entries returned by the transformer that should be bundled. */
|
|
28
|
+
widgets: WidgetMetadata[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function emitChunk(
|
|
32
|
+
srcPath: string,
|
|
33
|
+
chunkPath: string,
|
|
34
|
+
transformer: TransformerRule,
|
|
35
|
+
): Promise<EmittedChunk> {
|
|
36
|
+
const content = transformer.virtual ? '' : readFileSync(srcPath, 'utf-8');
|
|
37
|
+
const result = await transformer.transform(content, srcPath);
|
|
38
|
+
|
|
39
|
+
if (transformer.schema) {
|
|
40
|
+
const validation = transformer.schema.safeParse(result.data);
|
|
41
|
+
if (!validation.success) {
|
|
42
|
+
const errors = validation.error.issues.map((err) => ` - ${err.path.join('.')}: ${err.message}`).join('\n');
|
|
43
|
+
throw new Error(`Validation failed for ${srcPath}:\n${errors}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const importsBlock = result.imports && result.imports.length > 0 ? `${result.imports.join('\n')}\n\n` : '';
|
|
48
|
+
const body = result.code ?? `export default ${JSON.stringify(result.data, null, 2)};`;
|
|
49
|
+
const moduleCode = importsBlock + body;
|
|
50
|
+
|
|
51
|
+
mkdirSync(path.dirname(chunkPath), { recursive: true });
|
|
52
|
+
writeFileSync(chunkPath, moduleCode, 'utf-8');
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
chunkPath,
|
|
56
|
+
content: moduleCode,
|
|
57
|
+
assets: result.assets ?? [],
|
|
58
|
+
widgets: result.widgets ?? [],
|
|
59
|
+
};
|
|
60
|
+
}
|