@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.
Files changed (220) hide show
  1. package/README.md +3 -3
  2. package/lib/bin/build.d.ts +35 -0
  3. package/lib/bin/build.d.ts.map +1 -0
  4. package/lib/bin/build.js +79 -0
  5. package/lib/bin/build.js.map +1 -0
  6. package/lib/bin/config.d.ts +24 -0
  7. package/lib/bin/config.d.ts.map +1 -0
  8. package/lib/bin/config.js +91 -0
  9. package/lib/bin/config.js.map +1 -0
  10. package/lib/core/compilers/widget.d.ts +27 -0
  11. package/lib/core/compilers/widget.d.ts.map +1 -0
  12. package/lib/core/compilers/widget.js +37 -0
  13. package/lib/core/compilers/widget.js.map +1 -0
  14. package/lib/{types → core}/parsers/frontmatter.d.ts +1 -1
  15. package/lib/core/parsers/frontmatter.d.ts.map +1 -0
  16. package/lib/{esm → core}/parsers/frontmatter.js +1 -1
  17. package/lib/core/parsers/frontmatter.js.map +1 -0
  18. package/lib/core/transformers/index.d.ts +10 -0
  19. package/lib/core/transformers/index.d.ts.map +1 -0
  20. package/lib/core/transformers/index.js +10 -0
  21. package/lib/core/transformers/index.js.map +1 -0
  22. package/lib/{types/presets → core/transformers}/prompt.d.ts +7 -21
  23. package/lib/core/transformers/prompt.d.ts.map +1 -0
  24. package/lib/{esm/presets → core/transformers}/prompt.js +17 -14
  25. package/lib/core/transformers/prompt.js.map +1 -0
  26. package/lib/core/transformers/raw.d.ts.map +1 -0
  27. package/lib/{esm/presets → core/transformers}/raw.js +2 -2
  28. package/lib/core/transformers/raw.js.map +1 -0
  29. package/lib/core/transformers/skill-collection.d.ts.map +1 -0
  30. package/lib/{esm/presets → core/transformers}/skill-collection.js +5 -12
  31. package/lib/core/transformers/skill-collection.js.map +1 -0
  32. package/lib/core/transformers/skill.d.ts +111 -0
  33. package/lib/core/transformers/skill.d.ts.map +1 -0
  34. package/lib/{esm/presets → core/transformers}/skill.js +70 -51
  35. package/lib/core/transformers/skill.js.map +1 -0
  36. package/lib/core/transformers/template-collection.d.ts.map +1 -0
  37. package/lib/{esm/presets → core/transformers}/template-collection.js +5 -12
  38. package/lib/core/transformers/template-collection.js.map +1 -0
  39. package/lib/{types/presets → core/transformers}/template.d.ts +7 -22
  40. package/lib/core/transformers/template.d.ts.map +1 -0
  41. package/lib/{esm/presets → core/transformers}/template.js +16 -11
  42. package/lib/core/transformers/template.js.map +1 -0
  43. package/lib/{types → core}/types.d.ts +5 -61
  44. package/lib/core/types.d.ts.map +1 -0
  45. package/lib/core/types.js +6 -0
  46. package/lib/{cjs → core}/types.js.map +1 -1
  47. package/lib/core/utils/asset-copy.d.ts.map +1 -0
  48. package/lib/core/utils/asset-copy.js.map +1 -0
  49. package/lib/core/utils/asset-discovery.d.ts.map +1 -0
  50. package/lib/{esm → core}/utils/asset-discovery.js +4 -4
  51. package/lib/core/utils/asset-discovery.js.map +1 -0
  52. package/lib/core/utils/template-asset-discovery.d.ts.map +1 -0
  53. package/lib/{esm → core}/utils/template-asset-discovery.js +3 -7
  54. package/lib/core/utils/template-asset-discovery.js.map +1 -0
  55. package/lib/import-transform/builtins.d.ts +21 -0
  56. package/lib/import-transform/builtins.d.ts.map +1 -0
  57. package/lib/import-transform/builtins.js +50 -0
  58. package/lib/import-transform/builtins.js.map +1 -0
  59. package/lib/import-transform/chunk-emitter.d.ts +24 -0
  60. package/lib/import-transform/chunk-emitter.d.ts.map +1 -0
  61. package/lib/import-transform/chunk-emitter.js +35 -0
  62. package/lib/import-transform/chunk-emitter.js.map +1 -0
  63. package/lib/import-transform/detector.d.ts +24 -0
  64. package/lib/import-transform/detector.d.ts.map +1 -0
  65. package/lib/import-transform/detector.js +34 -0
  66. package/lib/import-transform/detector.js.map +1 -0
  67. package/lib/import-transform/index.d.ts +47 -0
  68. package/lib/import-transform/index.d.ts.map +1 -0
  69. package/lib/import-transform/index.js +115 -0
  70. package/lib/import-transform/index.js.map +1 -0
  71. package/lib/import-transform/patterns.d.ts +25 -0
  72. package/lib/import-transform/patterns.d.ts.map +1 -0
  73. package/lib/import-transform/patterns.js +27 -0
  74. package/lib/import-transform/patterns.js.map +1 -0
  75. package/lib/import-transform/resolver.d.ts +23 -0
  76. package/lib/import-transform/resolver.d.ts.map +1 -0
  77. package/lib/import-transform/resolver.js +30 -0
  78. package/lib/import-transform/resolver.js.map +1 -0
  79. package/lib/import-transform/rewriter.d.ts +21 -0
  80. package/lib/import-transform/rewriter.d.ts.map +1 -0
  81. package/lib/import-transform/rewriter.js +30 -0
  82. package/lib/import-transform/rewriter.js.map +1 -0
  83. package/lib/import-transform/scanner.d.ts +17 -0
  84. package/lib/import-transform/scanner.d.ts.map +1 -0
  85. package/lib/import-transform/scanner.js +46 -0
  86. package/lib/import-transform/scanner.js.map +1 -0
  87. package/lib/index.d.ts +39 -0
  88. package/lib/index.d.ts.map +1 -0
  89. package/lib/index.js +43 -0
  90. package/lib/index.js.map +1 -0
  91. package/lib/vite/api-server.d.ts +54 -0
  92. package/lib/vite/api-server.d.ts.map +1 -0
  93. package/lib/vite/api-server.js +94 -0
  94. package/lib/vite/api-server.js.map +1 -0
  95. package/lib/vite/dev-server.d.ts +42 -0
  96. package/lib/vite/dev-server.d.ts.map +1 -0
  97. package/lib/vite/dev-server.js +111 -0
  98. package/lib/vite/dev-server.js.map +1 -0
  99. package/lib/vite/index.d.ts +15 -0
  100. package/lib/vite/index.d.ts.map +1 -0
  101. package/lib/vite/index.js +15 -0
  102. package/lib/vite/index.js.map +1 -0
  103. package/package.json +38 -28
  104. package/src/bin/build.ts +83 -0
  105. package/src/bin/config.ts +113 -0
  106. package/src/core/compilers/widget.ts +69 -0
  107. package/src/{parsers → core/parsers}/frontmatter.ts +2 -2
  108. package/src/core/transformers/index.ts +27 -0
  109. package/src/{presets → core/transformers}/prompt.ts +35 -32
  110. package/src/{presets → core/transformers}/raw.ts +2 -2
  111. package/src/{presets → core/transformers}/skill-collection.ts +5 -12
  112. package/src/{presets → core/transformers}/skill.ts +119 -99
  113. package/src/{presets → core/transformers}/template-collection.ts +76 -83
  114. package/src/{presets → core/transformers}/template.ts +121 -116
  115. package/src/core/types.ts +71 -0
  116. package/src/{utils → core/utils}/asset-copy.ts +3 -2
  117. package/src/{utils → core/utils}/asset-discovery.ts +5 -5
  118. package/src/{utils → core/utils}/template-asset-discovery.ts +70 -77
  119. package/src/import-transform/builtins.ts +56 -0
  120. package/src/import-transform/chunk-emitter.ts +60 -0
  121. package/src/import-transform/detector.ts +56 -0
  122. package/src/import-transform/index.ts +171 -0
  123. package/src/import-transform/patterns.ts +34 -0
  124. package/src/import-transform/resolver.ts +57 -0
  125. package/src/import-transform/rewriter.ts +48 -0
  126. package/src/import-transform/scanner.ts +55 -0
  127. package/src/index.ts +67 -42
  128. package/src/vite/api-server.ts +142 -0
  129. package/src/vite/dev-server.ts +128 -0
  130. package/src/vite/index.ts +15 -0
  131. package/lib/build-tools.js +0 -2054
  132. package/lib/build-tools.js.map +0 -1
  133. package/lib/cjs/index.js +0 -43
  134. package/lib/cjs/index.js.map +0 -1
  135. package/lib/cjs/package.json +0 -3
  136. package/lib/cjs/parsers/frontmatter.js +0 -25
  137. package/lib/cjs/parsers/frontmatter.js.map +0 -1
  138. package/lib/cjs/plugin.js +0 -150
  139. package/lib/cjs/plugin.js.map +0 -1
  140. package/lib/cjs/presets/index.js +0 -25
  141. package/lib/cjs/presets/index.js.map +0 -1
  142. package/lib/cjs/presets/prompt.js +0 -185
  143. package/lib/cjs/presets/prompt.js.map +0 -1
  144. package/lib/cjs/presets/raw.js +0 -25
  145. package/lib/cjs/presets/raw.js.map +0 -1
  146. package/lib/cjs/presets/skill-collection.js +0 -83
  147. package/lib/cjs/presets/skill-collection.js.map +0 -1
  148. package/lib/cjs/presets/skill.js +0 -272
  149. package/lib/cjs/presets/skill.js.map +0 -1
  150. package/lib/cjs/presets/template-collection.js +0 -80
  151. package/lib/cjs/presets/template-collection.js.map +0 -1
  152. package/lib/cjs/presets/template.js +0 -105
  153. package/lib/cjs/presets/template.js.map +0 -1
  154. package/lib/cjs/types.js +0 -6
  155. package/lib/cjs/utils/asset-copy.js +0 -61
  156. package/lib/cjs/utils/asset-copy.js.map +0 -1
  157. package/lib/cjs/utils/asset-discovery.js +0 -100
  158. package/lib/cjs/utils/asset-discovery.js.map +0 -1
  159. package/lib/cjs/utils/template-asset-discovery.js +0 -63
  160. package/lib/cjs/utils/template-asset-discovery.js.map +0 -1
  161. package/lib/cjs/utils/widget-compiler.js +0 -115
  162. package/lib/cjs/utils/widget-compiler.js.map +0 -1
  163. package/lib/cjs/vite.js +0 -45
  164. package/lib/cjs/vite.js.map +0 -1
  165. package/lib/esm/index.js +0 -26
  166. package/lib/esm/index.js.map +0 -1
  167. package/lib/esm/parsers/frontmatter.js.map +0 -1
  168. package/lib/esm/plugin.js +0 -144
  169. package/lib/esm/plugin.js.map +0 -1
  170. package/lib/esm/presets/index.js +0 -10
  171. package/lib/esm/presets/index.js.map +0 -1
  172. package/lib/esm/presets/prompt.js.map +0 -1
  173. package/lib/esm/presets/raw.js.map +0 -1
  174. package/lib/esm/presets/skill-collection.js.map +0 -1
  175. package/lib/esm/presets/skill.js.map +0 -1
  176. package/lib/esm/presets/template-collection.js.map +0 -1
  177. package/lib/esm/presets/template.js.map +0 -1
  178. package/lib/esm/types.js +0 -5
  179. package/lib/esm/types.js.map +0 -1
  180. package/lib/esm/utils/asset-copy.js.map +0 -1
  181. package/lib/esm/utils/asset-discovery.js.map +0 -1
  182. package/lib/esm/utils/template-asset-discovery.js.map +0 -1
  183. package/lib/esm/utils/widget-compiler.js +0 -76
  184. package/lib/esm/utils/widget-compiler.js.map +0 -1
  185. package/lib/esm/vite.js +0 -42
  186. package/lib/esm/vite.js.map +0 -1
  187. package/lib/types/index.d.ts +0 -24
  188. package/lib/types/index.d.ts.map +0 -1
  189. package/lib/types/parsers/frontmatter.d.ts.map +0 -1
  190. package/lib/types/plugin.d.ts +0 -10
  191. package/lib/types/plugin.d.ts.map +0 -1
  192. package/lib/types/presets/index.d.ts +0 -10
  193. package/lib/types/presets/index.d.ts.map +0 -1
  194. package/lib/types/presets/prompt.d.ts.map +0 -1
  195. package/lib/types/presets/raw.d.ts.map +0 -1
  196. package/lib/types/presets/skill-collection.d.ts.map +0 -1
  197. package/lib/types/presets/skill.d.ts +0 -361
  198. package/lib/types/presets/skill.d.ts.map +0 -1
  199. package/lib/types/presets/template-collection.d.ts.map +0 -1
  200. package/lib/types/presets/template.d.ts.map +0 -1
  201. package/lib/types/types.d.ts.map +0 -1
  202. package/lib/types/utils/asset-copy.d.ts.map +0 -1
  203. package/lib/types/utils/asset-discovery.d.ts.map +0 -1
  204. package/lib/types/utils/template-asset-discovery.d.ts.map +0 -1
  205. package/lib/types/utils/widget-compiler.d.ts +0 -15
  206. package/lib/types/utils/widget-compiler.d.ts.map +0 -1
  207. package/lib/types/vite.d.ts +0 -32
  208. package/lib/types/vite.d.ts.map +0 -1
  209. package/src/plugin.ts +0 -166
  210. package/src/presets/index.ts +0 -10
  211. package/src/types.ts +0 -140
  212. package/src/utils/widget-compiler.ts +0 -98
  213. package/src/vite.ts +0 -45
  214. /package/lib/{types/presets → core/transformers}/raw.d.ts +0 -0
  215. /package/lib/{types/presets → core/transformers}/skill-collection.d.ts +0 -0
  216. /package/lib/{types/presets → core/transformers}/template-collection.d.ts +0 -0
  217. /package/lib/{types → core}/utils/asset-copy.d.ts +0 -0
  218. /package/lib/{esm → core}/utils/asset-copy.js +0 -0
  219. /package/lib/{types → core}/utils/asset-discovery.d.ts +0 -0
  220. /package/lib/{types → core}/utils/template-asset-discovery.d.ts +0 -0
@@ -2,11 +2,11 @@
2
2
  * Skill transformer preset for markdown files with frontmatter
3
3
  */
4
4
 
5
- import path from 'node:path';
6
5
  import { existsSync } from 'node:fs';
6
+ import path from 'node:path';
7
7
  import { z } from 'zod';
8
- import type { TransformerPreset } from '../types.js';
9
8
  import { parseFrontmatter } from '../parsers/frontmatter.js';
9
+ import type { TransformerPreset } from '../types.js';
10
10
  import { discoverSkillAssets } from '../utils/asset-discovery.js';
11
11
 
12
12
  /**
@@ -17,77 +17,88 @@ export type SkillContentType = 'md' | 'jst';
17
17
  /**
18
18
  * Context triggers for auto-injection of skills (for frontmatter validation)
19
19
  */
20
- const SkillContextTriggersFrontmatterSchema = z.object({
21
- keywords: z.array(z.string()).optional(),
22
- tool_names: z.array(z.string()).optional(),
23
- data_patterns: z.array(z.string()).optional()
24
- }).strict();
20
+ const SkillContextTriggersFrontmatterSchema = z
21
+ .object({
22
+ keywords: z.array(z.string()).optional(),
23
+ tool_names: z.array(z.string()).optional(),
24
+ data_patterns: z.array(z.string()).optional(),
25
+ })
26
+ .strict();
25
27
 
26
28
  /**
27
29
  * Context triggers for auto-injection of skills (for output validation)
28
30
  */
29
- const SkillContextTriggersSchema = z.object({
30
- keywords: z.array(z.string()).optional(),
31
- tool_names: z.array(z.string()).optional(),
32
- data_patterns: z.array(z.string()).optional()
33
- }).optional();
31
+ const SkillContextTriggersSchema = z
32
+ .object({
33
+ keywords: z.array(z.string()).optional(),
34
+ tool_names: z.array(z.string()).optional(),
35
+ data_patterns: z.array(z.string()).optional(),
36
+ })
37
+ .optional();
34
38
 
35
39
  /**
36
40
  * Execution configuration for skills that need code execution (for frontmatter validation)
37
41
  */
38
- const SkillExecutionFrontmatterSchema = z.object({
39
- language: z.string(),
40
- packages: z.array(z.string()).optional(),
41
- system_packages: z.array(z.string()).optional(),
42
- template: z.string().optional()
43
- }).strict();
42
+ const SkillExecutionFrontmatterSchema = z
43
+ .object({
44
+ language: z.string(),
45
+ packages: z.array(z.string()).optional(),
46
+ system_packages: z.array(z.string()).optional(),
47
+ template: z.string().optional(),
48
+ })
49
+ .strict();
44
50
 
45
51
  /**
46
52
  * Execution configuration for skills that need code execution (for output validation)
47
53
  */
48
- const SkillExecutionSchema = z.object({
49
- language: z.string(),
50
- packages: z.array(z.string()).optional(),
51
- system_packages: z.array(z.string()).optional(),
52
- template: z.string().optional()
53
- }).optional();
54
+ const SkillExecutionSchema = z
55
+ .object({
56
+ language: z.string(),
57
+ packages: z.array(z.string()).optional(),
58
+ system_packages: z.array(z.string()).optional(),
59
+ template: z.string().optional(),
60
+ })
61
+ .optional();
54
62
 
55
63
  /**
56
64
  * Zod schema for skill frontmatter validation
57
65
  * This validates the YAML frontmatter before transformation
58
66
  * Supports both flat and nested structures
59
67
  */
60
- const SkillFrontmatterSchema = z.object({
61
- // Required fields
62
- name: z.string().min(1, 'Skill name is required'),
63
- description: z.string().min(1, 'Skill description is required'),
64
-
65
- // Optional fields
66
- title: z.string().optional(),
67
- content_type: z.enum(['md', 'jst']).optional(),
68
-
69
- // Flat structure fields (legacy)
70
- keywords: z.array(z.string()).optional(),
71
- tools: z.array(z.string()).optional(),
72
- data_patterns: z.array(z.string()).optional(),
73
- language: z.string().optional(),
74
- packages: z.array(z.string()).optional(),
75
- system_packages: z.array(z.string()).optional(),
76
-
77
- // Nested structure fields
78
- context_triggers: SkillContextTriggersFrontmatterSchema.optional(),
79
- execution: SkillExecutionFrontmatterSchema.optional(),
80
- related_tools: z.array(z.string()).optional(),
81
- input_schema: z.object({
82
- type: z.literal('object'),
83
- properties: z.record(z.any()).optional(),
84
- required: z.array(z.string()).optional()
85
- }).optional(),
86
-
87
- // Asset fields (auto-discovered but can be overridden)
88
- scripts: z.array(z.string()).optional(),
89
- widgets: z.array(z.string()).optional()
90
- }).strict();
68
+ const SkillFrontmatterSchema = z
69
+ .object({
70
+ // Required fields
71
+ name: z.string().min(1, 'Skill name is required'),
72
+ description: z.string().min(1, 'Skill description is required'),
73
+
74
+ // Optional fields
75
+ title: z.string().optional(),
76
+ content_type: z.enum(['md', 'jst']).optional(),
77
+
78
+ // Flat structure fields (legacy)
79
+ keywords: z.array(z.string()).optional(),
80
+ tools: z.array(z.string()).optional(),
81
+ data_patterns: z.array(z.string()).optional(),
82
+ language: z.string().optional(),
83
+ packages: z.array(z.string()).optional(),
84
+ system_packages: z.array(z.string()).optional(),
85
+
86
+ // Nested structure fields
87
+ context_triggers: SkillContextTriggersFrontmatterSchema.optional(),
88
+ execution: SkillExecutionFrontmatterSchema.optional(),
89
+ input_schema: z
90
+ .object({
91
+ type: z.literal('object'),
92
+ properties: z.record(z.string(), z.unknown()).optional(),
93
+ required: z.array(z.string()).optional(),
94
+ })
95
+ .optional(),
96
+
97
+ // Asset fields (auto-discovered but can be overridden)
98
+ scripts: z.array(z.string()).optional(),
99
+ widgets: z.array(z.string()).optional(),
100
+ })
101
+ .strict();
91
102
 
92
103
  /**
93
104
  * MUST be kept in sync with @vertesia/tools-sdk SkillDefinition
@@ -98,23 +109,27 @@ const SkillFrontmatterSchema = z.object({
98
109
  * Note: The isEnabled property is not included in this schema because Zod cannot
99
110
  * properly validate function signatures. It will be type-checked by TypeScript instead.
100
111
  */
101
- export const SkillDefinitionSchema = z.object({
102
- name: z.string().min(1, 'Skill name is required'),
103
- title: z.string().optional(),
104
- description: z.string().min(1, 'Skill description is required'),
105
- instructions: z.string(),
106
- content_type: z.enum(['md', 'jst']),
107
- input_schema: z.object({
108
- type: z.literal('object'),
109
- properties: z.record(z.any()).optional(),
110
- required: z.array(z.string()).optional()
111
- }).optional(),
112
- context_triggers: SkillContextTriggersSchema,
113
- execution: SkillExecutionSchema,
114
- related_tools: z.array(z.string()).optional(),
115
- scripts: z.array(z.string()).optional(),
116
- widgets: z.array(z.string()).optional()
117
- }).passthrough();
112
+ export const SkillDefinitionSchema = z
113
+ .object({
114
+ name: z.string().min(1, 'Skill name is required'),
115
+ title: z.string().optional(),
116
+ description: z.string().min(1, 'Skill description is required'),
117
+ instructions: z.string(),
118
+ content_type: z.enum(['md', 'jst']),
119
+ input_schema: z
120
+ .object({
121
+ type: z.literal('object'),
122
+ properties: z.record(z.string(), z.unknown()).optional(),
123
+ required: z.array(z.string()).optional(),
124
+ })
125
+ .optional(),
126
+ context_triggers: SkillContextTriggersSchema,
127
+ execution: SkillExecutionSchema,
128
+ tools: z.array(z.string()).optional(),
129
+ scripts: z.array(z.string()).optional(),
130
+ widgets: z.array(z.string()).optional(),
131
+ })
132
+ .passthrough();
118
133
 
119
134
  /**
120
135
  * Schema for validating properties exported from properties.ts
@@ -132,6 +147,8 @@ export const SkillPropertiesSchema = SkillDefinitionSchema.partial().passthrough
132
147
  */
133
148
  export type SkillDefinition = z.infer<typeof SkillDefinitionSchema>;
134
149
 
150
+ type SkillFrontmatter = z.infer<typeof SkillFrontmatterSchema>;
151
+
135
152
  /**
136
153
  * Build a SkillDefinition from frontmatter and markdown content.
137
154
  * This mirrors the logic in @vertesia/tools-sdk parseSkillFile function.
@@ -151,7 +168,7 @@ export type SkillDefinition = z.infer<typeof SkillDefinitionSchema>;
151
168
  * execution:
152
169
  * language: python
153
170
  * packages: [...]
154
- * related_tools: [...]
171
+ * tools: [...]
155
172
  *
156
173
  * @param frontmatter - Parsed frontmatter object
157
174
  * @param instructions - Markdown content (body of the file)
@@ -161,11 +178,11 @@ export type SkillDefinition = z.infer<typeof SkillDefinitionSchema>;
161
178
  * @returns Skill definition object
162
179
  */
163
180
  function buildSkillDefinition(
164
- frontmatter: Record<string, any>,
181
+ frontmatter: SkillFrontmatter,
165
182
  instructions: string,
166
183
  contentType: SkillContentType,
167
184
  widgets: string[],
168
- scripts: string[]
185
+ scripts: string[],
169
186
  ): SkillDefinition {
170
187
  const skill: SkillDefinition = {
171
188
  name: frontmatter.name,
@@ -181,7 +198,7 @@ function buildSkillDefinition(
181
198
  // Nested: context_triggers: { keywords: [...], tool_names: [...] }
182
199
  // Flat: keywords: [...], tools: [...]
183
200
  const contextTriggers = frontmatter.context_triggers;
184
- const hasNestedTriggers = contextTriggers && typeof contextTriggers === 'object';
201
+ const hasNestedTriggers = contextTriggers !== undefined;
185
202
  const hasFlatTriggers = frontmatter.keywords || frontmatter.tools || frontmatter.data_patterns;
186
203
 
187
204
  if (hasNestedTriggers || hasFlatTriggers) {
@@ -194,29 +211,32 @@ function buildSkillDefinition(
194
211
 
195
212
  // Build execution config - support both flat and nested structure
196
213
  const execution = frontmatter.execution;
197
- const hasNestedExecution = execution && typeof execution === 'object';
198
- const hasFlatExecution = frontmatter.language;
199
214
 
200
- if (hasNestedExecution || hasFlatExecution) {
215
+ if (execution) {
201
216
  skill.execution = {
202
- language: hasNestedExecution ? execution.language : frontmatter.language,
203
- packages: hasNestedExecution ? execution.packages : frontmatter.packages,
204
- system_packages: hasNestedExecution ? execution.system_packages : frontmatter.system_packages,
217
+ language: execution.language,
218
+ packages: execution.packages,
219
+ system_packages: execution.system_packages,
205
220
  };
221
+ } else if (frontmatter.language) {
222
+ skill.execution = {
223
+ language: frontmatter.language,
224
+ packages: frontmatter.packages,
225
+ system_packages: frontmatter.system_packages,
226
+ };
227
+ }
206
228
 
229
+ if (skill.execution) {
207
230
  // Extract code template from instructions if present
208
231
  const codeBlockMatch = instructions.match(/```(?:python|javascript|typescript|js|ts|py)\n([\s\S]*?)```/);
209
- if (codeBlockMatch) {
232
+ if (codeBlockMatch?.[1]) {
210
233
  skill.execution.template = codeBlockMatch[1].trim();
211
234
  }
212
235
  }
213
236
 
214
- // Related tools - support both direct field and from tools field
215
- if (frontmatter.related_tools) {
216
- skill.related_tools = frontmatter.related_tools;
217
- } else if (frontmatter.tools && !hasNestedTriggers) {
218
- // If tools is not part of context_triggers, use it as related_tools
219
- skill.related_tools = frontmatter.tools;
237
+ // Tools unlocked by this skill (from frontmatter `tools:` key)
238
+ if (frontmatter.tools) {
239
+ skill.tools = frontmatter.tools;
220
240
  }
221
241
 
222
242
  // Input schema from frontmatter
@@ -256,30 +276,30 @@ export const skillTransformer: TransformerPreset = {
256
276
  // Validate frontmatter first to catch unknown properties
257
277
  const frontmatterValidation = SkillFrontmatterSchema.safeParse(frontmatter);
258
278
  if (!frontmatterValidation.success) {
259
- const errors = frontmatterValidation.error.errors
279
+ const errors = frontmatterValidation.error.issues
260
280
  .map((err) => {
261
281
  const pathStr = err.path.length > 0 ? err.path.join('.') : 'frontmatter';
262
282
  return ` - ${pathStr}: ${err.message}`;
263
283
  })
264
284
  .join('\n');
265
- throw new Error(
266
- `Invalid frontmatter in ${filePath}:\n${errors}`
267
- );
285
+ throw new Error(`Invalid frontmatter in ${filePath}:\n${errors}`);
268
286
  }
269
287
 
288
+ const validatedFrontmatter = frontmatterValidation.data;
289
+
270
290
  // Determine content type from frontmatter or file extension
271
- const content_type: SkillContentType = frontmatter.content_type || 'md';
291
+ const content_type: SkillContentType = validatedFrontmatter.content_type || 'md';
272
292
 
273
293
  // Discover assets (scripts and widgets) in the skill directory
274
294
  const assets = discoverSkillAssets(filePath);
275
295
 
276
296
  // Build skill definition using the same logic as parseSkillFile in tools-sdk
277
297
  const skillData = buildSkillDefinition(
278
- frontmatter,
298
+ validatedFrontmatter,
279
299
  markdown,
280
300
  content_type,
281
301
  assets.widgets,
282
- assets.scripts
302
+ assets.scripts,
283
303
  );
284
304
 
285
305
  // Check if properties.ts exists in the skill directory
@@ -306,14 +326,14 @@ export default { ...skill, ...properties };
306
326
  data: skillData,
307
327
  assets: assets.assetFiles,
308
328
  widgets: assets.widgetMetadata,
309
- code
329
+ code,
310
330
  };
311
331
  }
312
332
 
313
333
  return {
314
334
  data: skillData,
315
335
  assets: assets.assetFiles,
316
- widgets: assets.widgetMetadata
336
+ widgets: assets.widgetMetadata,
317
337
  };
318
- }
338
+ },
319
339
  };
@@ -1,83 +1,76 @@
1
- /**
2
- * Template collection transformer for directory-based template imports
3
- * Scans a directory for subdirectories containing TEMPLATE.md files
4
- */
5
-
6
- import { readdirSync, statSync, existsSync } from 'node:fs';
7
- import path from 'node:path';
8
- import type { TransformerPreset } from '../types.js';
9
-
10
- /**
11
- * Template collection transformer preset
12
- * Transforms directory imports with ?templates suffix into an array of template imports
13
- *
14
- * Matches:
15
- * - ./all?templates (recommended - generates all.js in the directory)
16
- * - Any path ending with a filename and ?templates
17
- *
18
- * NOTE: A filename before ?templates is REQUIRED to avoid naming conflicts.
19
- * The filename becomes the output module name.
20
- *
21
- * @example
22
- * ```typescript
23
- * import templates from './all?templates';
24
- * // Scans current directory for subdirectories with TEMPLATE.md
25
- * // Generates all.js containing array of all templates
26
- * ```
27
- */
28
- export const templateCollectionTransformer: TransformerPreset = {
29
- pattern: /\/[^/?]+\?templates$/,
30
- virtual: true,
31
- transform: (_content: string, filePath: string) => {
32
- // Remove ?templates suffix and the filename to get directory path
33
- const pathWithoutQuery = filePath.replace(/\?templates$/, '');
34
- const dirPath = path.dirname(pathWithoutQuery);
35
-
36
- if (!existsSync(dirPath)) {
37
- throw new Error(`Directory not found: ${dirPath}`);
38
- }
39
-
40
- if (!statSync(dirPath).isDirectory()) {
41
- throw new Error(`Not a directory: ${dirPath}`);
42
- }
43
-
44
- // Scan for subdirectories containing TEMPLATE.md
45
- const entries = readdirSync(dirPath);
46
- const imports: string[] = [];
47
- const names: string[] = [];
48
-
49
- for (const entry of entries) {
50
- const entryPath = path.join(dirPath, entry);
51
-
52
- try {
53
- if (statSync(entryPath).isDirectory()) {
54
- const templateFile = path.join(entryPath, 'TEMPLATE.md');
55
- if (existsSync(templateFile)) {
56
- const identifier = `Template_${entry.replace(/[^a-zA-Z0-9_]/g, '_')}`;
57
- imports.push(`import ${identifier} from './${entry}/TEMPLATE.md';`);
58
- names.push(identifier);
59
- }
60
- }
61
- } catch (_err) {
62
- // Skip entries that can't be read
63
- continue;
64
- }
65
- }
66
-
67
- if (names.length === 0) {
68
- console.warn(`No TEMPLATE.md files found in subdirectories of ${dirPath}`);
69
- }
70
-
71
- // Generate code that imports all templates and exports as array
72
- const code = [
73
- ...imports,
74
- '',
75
- `export default [${names.join(', ')}];`
76
- ].join('\n');
77
-
78
- return {
79
- data: null,
80
- code
81
- };
82
- }
83
- };
1
+ /**
2
+ * Template collection transformer for directory-based template imports
3
+ * Scans a directory for subdirectories containing TEMPLATE.md files
4
+ */
5
+
6
+ import { existsSync, readdirSync, statSync } from 'node:fs';
7
+ import path from 'node:path';
8
+ import type { TransformerPreset } from '../types.js';
9
+
10
+ /**
11
+ * Template collection transformer preset
12
+ * Transforms directory imports with ?templates suffix into an array of template imports
13
+ *
14
+ * Matches:
15
+ * - ./all?templates (recommended - generates all.js in the directory)
16
+ * - Any path ending with a filename and ?templates
17
+ *
18
+ * NOTE: A filename before ?templates is REQUIRED to avoid naming conflicts.
19
+ * The filename becomes the output module name.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import templates from './all?templates';
24
+ * // Scans current directory for subdirectories with TEMPLATE.md
25
+ * // Generates all.js containing array of all templates
26
+ * ```
27
+ */
28
+ export const templateCollectionTransformer: TransformerPreset = {
29
+ pattern: /\/[^/?]+\?templates$/,
30
+ virtual: true,
31
+ transform: (_content: string, filePath: string) => {
32
+ // Remove ?templates suffix and the filename to get directory path
33
+ const pathWithoutQuery = filePath.replace(/\?templates$/, '');
34
+ const dirPath = path.dirname(pathWithoutQuery);
35
+
36
+ if (!existsSync(dirPath)) {
37
+ throw new Error(`Directory not found: ${dirPath}`);
38
+ }
39
+
40
+ if (!statSync(dirPath).isDirectory()) {
41
+ throw new Error(`Not a directory: ${dirPath}`);
42
+ }
43
+
44
+ // Scan for subdirectories containing TEMPLATE.md
45
+ const entries = readdirSync(dirPath);
46
+ const imports: string[] = [];
47
+ const names: string[] = [];
48
+
49
+ for (const entry of entries) {
50
+ const entryPath = path.join(dirPath, entry);
51
+
52
+ try {
53
+ if (statSync(entryPath).isDirectory()) {
54
+ const templateFile = path.join(entryPath, 'TEMPLATE.md');
55
+ if (existsSync(templateFile)) {
56
+ const identifier = `Template_${entry.replace(/[^a-zA-Z0-9_]/g, '_')}`;
57
+ imports.push(`import ${identifier} from './${entry}/TEMPLATE.md';`);
58
+ names.push(identifier);
59
+ }
60
+ }
61
+ } catch (_err) {}
62
+ }
63
+
64
+ if (names.length === 0) {
65
+ console.warn(`No TEMPLATE.md files found in subdirectories of ${dirPath}`);
66
+ }
67
+
68
+ // Generate code that imports all templates and exports as array
69
+ const code = [...imports, '', `export default [${names.join(', ')}];`].join('\n');
70
+
71
+ return {
72
+ data: null,
73
+ code,
74
+ };
75
+ },
76
+ };