veryfront 0.1.853 → 0.1.855

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 (65) hide show
  1. package/esm/cli/commands/generate/command-help.d.ts.map +1 -1
  2. package/esm/cli/commands/generate/command-help.js +7 -2
  3. package/esm/cli/commands/generate/command.d.ts.map +1 -1
  4. package/esm/cli/commands/generate/command.js +25 -101
  5. package/esm/cli/commands/generate/handler.d.ts +1 -1
  6. package/esm/cli/commands/generate/handler.d.ts.map +1 -1
  7. package/esm/cli/commands/generate/handler.js +2 -1
  8. package/esm/cli/commands/generate/integration-generator.js +4 -4
  9. package/esm/cli/commands/init/init-command.d.ts.map +1 -1
  10. package/esm/cli/commands/init/init-command.js +100 -1
  11. package/esm/cli/commands/mcp/command-help.js +1 -1
  12. package/esm/cli/commands/skills/command-help.js +1 -1
  13. package/esm/cli/commands/skills/command.d.ts +1 -1
  14. package/esm/cli/commands/skills/command.js +2 -2
  15. package/esm/cli/commands/skills/create.d.ts.map +1 -1
  16. package/esm/cli/commands/skills/create.js +14 -40
  17. package/esm/cli/commands/skills/handler.js +15 -16
  18. package/esm/cli/commands/skills/validate.d.ts +6 -0
  19. package/esm/cli/commands/skills/validate.d.ts.map +1 -1
  20. package/esm/cli/commands/skills/validate.js +18 -43
  21. package/esm/cli/mcp/server.js +4 -4
  22. package/esm/cli/mcp/standalone.js +4 -4
  23. package/esm/cli/mcp/tools/helpers.d.ts +0 -8
  24. package/esm/cli/mcp/tools/helpers.d.ts.map +1 -1
  25. package/esm/cli/mcp/tools/scaffold-tools.d.ts +2 -2
  26. package/esm/cli/mcp/tools/scaffold-tools.d.ts.map +1 -1
  27. package/esm/cli/mcp/tools/scaffold-tools.js +24 -193
  28. package/esm/cli/scaffold/engine.d.ts +33 -0
  29. package/esm/cli/scaffold/engine.d.ts.map +1 -0
  30. package/esm/cli/scaffold/engine.js +303 -0
  31. package/esm/cli/skills/core-skills.d.ts.map +1 -1
  32. package/esm/cli/skills/core-skills.js +23 -75
  33. package/esm/cli/skills/loader.d.ts +2 -2
  34. package/esm/cli/skills/loader.d.ts.map +1 -1
  35. package/esm/cli/skills/loader.js +14 -15
  36. package/esm/cli/skills/types.d.ts +2 -38
  37. package/esm/cli/skills/types.d.ts.map +1 -1
  38. package/esm/cli/skills/types.js +1 -27
  39. package/esm/cli/templates/index.d.ts +1 -0
  40. package/esm/cli/templates/index.d.ts.map +1 -1
  41. package/esm/cli/templates/index.js +4 -1
  42. package/esm/cli/templates/loader.d.ts +1 -0
  43. package/esm/cli/templates/loader.d.ts.map +1 -1
  44. package/esm/cli/templates/loader.js +6 -0
  45. package/esm/cli/templates/manifest.js +7 -7
  46. package/esm/deno.js +1 -1
  47. package/esm/src/agent/hosted/default-chat-runtime.d.ts.map +1 -1
  48. package/esm/src/agent/hosted/default-chat-runtime.js +6 -1
  49. package/esm/src/agent/runtime/constants.d.ts.map +1 -1
  50. package/esm/src/agent/runtime/constants.js +0 -2
  51. package/esm/src/agent/runtime/model-resolution.d.ts.map +1 -1
  52. package/esm/src/agent/runtime/model-resolution.js +14 -4
  53. package/esm/src/agent/runtime/skill-metadata.d.ts.map +1 -1
  54. package/esm/src/agent/runtime/skill-metadata.js +2 -1
  55. package/esm/src/integrations/_data.js +1 -1
  56. package/esm/src/provider/veryfront-cloud/model-catalog.d.ts +1 -0
  57. package/esm/src/provider/veryfront-cloud/model-catalog.d.ts.map +1 -1
  58. package/esm/src/provider/veryfront-cloud/model-catalog.js +13 -14
  59. package/esm/src/provider/veryfront-cloud/shared.d.ts.map +1 -1
  60. package/esm/src/provider/veryfront-cloud/shared.js +8 -0
  61. package/esm/src/skill/parser.d.ts.map +1 -1
  62. package/esm/src/skill/parser.js +2 -1
  63. package/esm/src/utils/version-constant.d.ts +1 -1
  64. package/esm/src/utils/version-constant.js +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,303 @@
1
+ import { dirname, join } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
2
+ import { createFileSystem } from "../../src/platform/index.js";
3
+ import { ensureDir, fileExists } from "../utils/fs.js";
4
+ import { toComponentName, toSlug } from "../utils/string.js";
5
+ export const SCAFFOLD_TYPES = [
6
+ "page",
7
+ "api",
8
+ "layout",
9
+ "component",
10
+ "tool",
11
+ "agent",
12
+ "prompt",
13
+ "workflow",
14
+ "task",
15
+ "resource",
16
+ "skill",
17
+ ];
18
+ const DEFAULT_METHODS = ["GET"];
19
+ const SCAFFOLD_DEFINITIONS = {
20
+ page: {
21
+ getPath: ({ projectDir, router, slug }) => router === "app-router"
22
+ ? join(projectDir, "app", slug, "page.tsx")
23
+ : joinPagesFile(join(projectDir, "pages"), slug, ".mdx"),
24
+ getContent: ({ router, slug, componentName }) => {
25
+ const title = slug.split("/").pop() || "Page";
26
+ if (router === "app-router")
27
+ return generateAppPageTemplate(title, componentName);
28
+ return generatePagesPageTemplate(title);
29
+ },
30
+ },
31
+ api: {
32
+ getPath: ({ projectDir, router, slug }) => router === "app-router"
33
+ ? join(projectDir, "app", slug, "route.ts")
34
+ : joinPagesFile(join(projectDir, "pages", "api"), slug, ".ts"),
35
+ getContent: ({ router, methods }) => generateApiTemplate(methods, router),
36
+ },
37
+ layout: {
38
+ getPath: ({ projectDir, router, slug, componentName }) => router === "app-router"
39
+ ? join(projectDir, "app", slug, "layout.tsx")
40
+ : join(projectDir, "layouts", `${componentName || "Layout"}.mdx`),
41
+ getContent: ({ router, slug, componentName }) => router === "app-router"
42
+ ? generateAppLayoutTemplate(slug)
43
+ : generatePagesLayoutTemplate(slug, componentName),
44
+ },
45
+ component: {
46
+ getPath: ({ projectDir, componentName }) => join(projectDir, "components", `${componentName}.tsx`),
47
+ getContent: ({ componentName }) => generateComponentTemplate(componentName),
48
+ },
49
+ tool: {
50
+ getPath: ({ projectDir, slug }) => join(projectDir, "tools", `${slug}.ts`),
51
+ getContent: ({ name }) => generateToolTemplate(name),
52
+ },
53
+ agent: {
54
+ getPath: ({ projectDir, slug }) => join(projectDir, "agents", `${slug}.ts`),
55
+ getContent: ({ name, slug }) => generateAgentTemplate(name, slug),
56
+ },
57
+ prompt: {
58
+ getPath: ({ projectDir, slug }) => join(projectDir, "prompts", `${slug}.ts`),
59
+ getContent: ({ slug }) => generatePromptTemplate(slug.replace(/-/g, "_")),
60
+ },
61
+ workflow: {
62
+ getPath: ({ projectDir, slug }) => join(projectDir, "workflows", `${slug}.ts`),
63
+ getContent: ({ slug }) => generateWorkflowTemplate(slug),
64
+ },
65
+ task: {
66
+ getPath: ({ projectDir, slug }) => join(projectDir, "tasks", `${slug}.ts`),
67
+ getContent: ({ slug }) => generateTaskTemplate(slug),
68
+ },
69
+ resource: {
70
+ getPath: ({ projectDir, slug }) => join(projectDir, "resources", `${slug}.ts`),
71
+ getContent: ({ slug }) => generateResourceTemplate(slug),
72
+ },
73
+ skill: {
74
+ getPath: ({ projectDir, slug }) => join(projectDir, "skills", slug, "SKILL.md"),
75
+ getContent: ({ slug }) => generateSkillTemplate(slug),
76
+ },
77
+ };
78
+ export function isScaffoldType(type) {
79
+ return SCAFFOLD_TYPES.includes(type);
80
+ }
81
+ export function planScaffold(input) {
82
+ const resolved = resolveInput(input);
83
+ const definition = SCAFFOLD_DEFINITIONS[resolved.type];
84
+ const file = {
85
+ path: definition.getPath(resolved),
86
+ content: definition.getContent(resolved),
87
+ };
88
+ return {
89
+ type: resolved.type,
90
+ name: resolved.name,
91
+ files: [file],
92
+ };
93
+ }
94
+ export async function writeScaffoldPlan(plan) {
95
+ const conflicts = [];
96
+ for (const file of plan.files) {
97
+ if (await fileExists(file.path))
98
+ conflicts.push(file.path);
99
+ }
100
+ if (conflicts.length) {
101
+ return {
102
+ success: false,
103
+ files: conflicts.map((path) => ({ path, created: false })),
104
+ message: `${plan.type} already exists at ${conflicts.join(", ")}`,
105
+ };
106
+ }
107
+ const fs = createFileSystem();
108
+ for (const file of plan.files) {
109
+ await ensureDir(dirname(file.path));
110
+ await fs.writeTextFile(file.path, file.content);
111
+ }
112
+ return {
113
+ success: true,
114
+ files: plan.files.map((file) => ({ path: file.path, created: true })),
115
+ message: `Created ${plan.type} "${plan.name}" successfully`,
116
+ };
117
+ }
118
+ export async function scaffoldProjectFile(input) {
119
+ return writeScaffoldPlan(planScaffold(input));
120
+ }
121
+ function resolveInput(input) {
122
+ const slug = toSlug(input.name);
123
+ return {
124
+ projectDir: input.projectDir,
125
+ type: input.type,
126
+ name: input.name,
127
+ router: input.router ?? "app-router",
128
+ methods: input.methods?.length ? input.methods : DEFAULT_METHODS,
129
+ slug,
130
+ componentName: toComponentName(slug),
131
+ };
132
+ }
133
+ function joinPagesFile(base, slug, extension) {
134
+ const parts = slug.split("/").filter(Boolean);
135
+ const fileName = `${parts.pop() || "index"}${extension}`;
136
+ return parts.length ? join(base, ...parts, fileName) : join(base, fileName);
137
+ }
138
+ function generateAppPageTemplate(title, componentName) {
139
+ return `export default function ${componentName || "Page"}() {
140
+ return <div>${title}</div>;
141
+ }
142
+ `;
143
+ }
144
+ function generatePagesPageTemplate(title) {
145
+ return `---
146
+ title: ${title}
147
+ ---
148
+
149
+ # ${title}
150
+
151
+ This is a new page.
152
+ `;
153
+ }
154
+ function generateAppLayoutTemplate(slug) {
155
+ return `export default function Layout({ children }: { children: React.ReactNode }) {
156
+ return <section data-route="${slug || "root"}">{children}</section>;
157
+ }
158
+ `;
159
+ }
160
+ function generatePagesLayoutTemplate(slug, componentName) {
161
+ const layoutName = componentName || "Layout";
162
+ return `---
163
+ isLayout: true
164
+ ---
165
+
166
+ export default function ${layoutName}({ children }) {
167
+ return (
168
+ <div className="${slug}-layout">
169
+ <main>{children}</main>
170
+ </div>
171
+ );
172
+ }
173
+ `;
174
+ }
175
+ function generateApiTemplate(methods, router) {
176
+ const handlers = methods.map((method) => {
177
+ if (method === "GET") {
178
+ return router === "app-router"
179
+ ? `export const GET = (_req: Request) => Response.json({ ok: true });`
180
+ : `export function GET(_req: Request) {
181
+ return new Response(JSON.stringify({ ok: true }), {
182
+ headers: { "content-type": "application/json" },
183
+ });
184
+ }`;
185
+ }
186
+ return `export async function ${method}(req: Request) {
187
+ const body = await req.json();
188
+ return Response.json({ ok: true, received: body });
189
+ }`;
190
+ });
191
+ return `${handlers.join("\n\n")}\n`;
192
+ }
193
+ function generateComponentTemplate(componentName) {
194
+ return `interface ${componentName}Props {
195
+ children?: React.ReactNode;
196
+ }
197
+
198
+ export function ${componentName}({ children }: ${componentName}Props) {
199
+ return (
200
+ <div className="${componentName.toLowerCase()}">
201
+ {children}
202
+ </div>
203
+ );
204
+ }
205
+ `;
206
+ }
207
+ function generateToolTemplate(name) {
208
+ return `import { defineSchema } from "veryfront/schemas";
209
+ import { tool } from "veryfront/tool";
210
+
211
+ const inputSchema = defineSchema((v) => v.object({
212
+ input: v.string().describe("Input parameter"),
213
+ }))();
214
+
215
+ export default tool({
216
+ id: "${name}",
217
+ description: "Description of what this tool does",
218
+ inputSchema,
219
+ execute: async ({ input }) => {
220
+ return { result: input };
221
+ },
222
+ });
223
+ `;
224
+ }
225
+ function generateAgentTemplate(name, slug) {
226
+ return `import { agent } from "veryfront/agent";
227
+
228
+ export default agent({
229
+ id: "${slug}",
230
+ system: "You are an assistant specialized in ${name}. Answer clearly and ask for missing context.",
231
+ });
232
+ `;
233
+ }
234
+ function generatePromptTemplate(name) {
235
+ return `import { prompt } from "veryfront/prompt";
236
+
237
+ export default prompt({
238
+ id: "${name}",
239
+ description: "Description of this prompt template",
240
+ content: "Use the following input:\\n\\n{input}",
241
+ });
242
+ `;
243
+ }
244
+ function generateWorkflowTemplate(slug) {
245
+ const title = toTitle(slug);
246
+ return `import { step, workflow } from "veryfront/workflow";
247
+
248
+ export default workflow({
249
+ id: "${slug}",
250
+ description: "${title} workflow",
251
+ steps: [
252
+ step("start", {
253
+ agent: "assistant",
254
+ }),
255
+ ],
256
+ });
257
+ `;
258
+ }
259
+ function generateTaskTemplate(slug) {
260
+ const title = toTitle(slug);
261
+ return `export default {
262
+ name: "${title}",
263
+ description: "Run ${title.toLowerCase()}.",
264
+ schedulable: false,
265
+ async run() {
266
+ return { ok: true };
267
+ },
268
+ };
269
+ `;
270
+ }
271
+ function generateResourceTemplate(slug) {
272
+ const title = toTitle(slug);
273
+ return `import { resource } from "veryfront/resource";
274
+ import { defineSchema } from "veryfront/schemas";
275
+
276
+ export default resource({
277
+ description: "Load ${title.toLowerCase()}.",
278
+ paramsSchema: defineSchema((v) => v.object({}))(),
279
+ load: async () => {
280
+ return { content: "${title}" };
281
+ },
282
+ });
283
+ `;
284
+ }
285
+ function generateSkillTemplate(slug) {
286
+ const title = toTitle(slug);
287
+ return `---
288
+ name: ${slug}
289
+ description: ${title} instructions.
290
+ ---
291
+
292
+ # ${title}
293
+
294
+ Use this skill when the task requires ${title.toLowerCase()}.
295
+ `;
296
+ }
297
+ function toTitle(value) {
298
+ return value
299
+ .split(/[-/_\s]+/)
300
+ .filter(Boolean)
301
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
302
+ .join(" ") || "Item";
303
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"core-skills.d.ts","sourceRoot":"","sources":["../../../src/cli/skills/core-skills.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,WAAW,EAAE,WAAW,EA+NpC,CAAC"}
1
+ {"version":3,"file":"core-skills.d.ts","sourceRoot":"","sources":["../../../src/cli/skills/core-skills.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,WAAW,EAAE,WAAW,EA2KpC,CAAC"}
@@ -6,22 +6,10 @@
6
6
  */
7
7
  export const CORE_SKILLS = [
8
8
  {
9
- manifest: {
9
+ metadata: {
10
10
  name: "scaffold-app",
11
- version: "1.0.0",
12
11
  description: "Scaffold a new Veryfront app with the right structure, config, and conventions",
13
- requires: {
14
- cli: ["init", "dev", "doctor"],
15
- mcp: ["vf_list_templates", "vf_create_project"],
16
- },
17
- inputs: {
18
- name: { type: "string", description: "Project name" },
19
- template: {
20
- type: "string",
21
- default: "minimal",
22
- description: "Template to use",
23
- },
24
- },
12
+ metadata: { version: "1.0.0" },
25
13
  },
26
14
  skillMd: `# Scaffold App
27
15
 
@@ -59,22 +47,10 @@ Create a new Veryfront application with proper structure and conventions.
59
47
  directory: "core:scaffold-app",
60
48
  },
61
49
  {
62
- manifest: {
50
+ metadata: {
63
51
  name: "scaffold-ai-app",
64
- version: "1.0.0",
65
52
  description: "Scaffold a Veryfront app with AI tools, agent definitions, and knowledge base",
66
- requires: {
67
- cli: ["init", "dev", "doctor", "workflow"],
68
- mcp: ["vf_list_templates", "vf_create_project", "vf_scaffold"],
69
- },
70
- inputs: {
71
- name: { type: "string", description: "Project name" },
72
- provider: {
73
- type: "string",
74
- default: "anthropic",
75
- description: "LLM provider to configure",
76
- },
77
- },
53
+ metadata: { version: "1.0.0" },
78
54
  },
79
55
  skillMd: `# Scaffold AI App
80
56
 
@@ -82,48 +58,32 @@ Create a Veryfront app with AI capabilities.
82
58
 
83
59
  ## Steps
84
60
 
85
- 1. \`veryfront init <name> --template ai --yes --json\`
86
- 2. \`veryfront install --with ai --yes --json\`
87
- 3. Use vf_scaffold to generate AI components
88
- 4. Configure provider API key in .env
61
+ 1. \`veryfront init <name> --template ai-agent --yes --json\`
62
+ 2. Use vf_scaffold to generate agents, tools, prompts, and workflows
63
+ 3. Add an app route such as app/api/ag-ui/route.ts
64
+ 4. Configure the provider token in .env
89
65
  5. \`veryfront doctor --json\` then \`veryfront dev\`
90
66
 
91
67
  ## Error Recovery
92
68
 
93
- - **Missing API key**: Set provider key in .env
69
+ - **Missing provider token**: Set the expected provider token in .env
94
70
  - **Tool generation fails**: Use vf_get_conventions, scaffold manually`,
95
71
  directory: "core:scaffold-ai-app",
96
72
  },
97
73
  {
98
- manifest: {
74
+ metadata: {
99
75
  name: "deploy-safely",
100
- version: "1.0.0",
101
- description: "Build, test, deploy, and verify — with automatic rollback on failure",
102
- requires: {
103
- cli: ["build", "test", "deploy"],
104
- mcp: ["vf_get_errors"],
105
- },
106
- inputs: {
107
- environment: {
108
- type: "string",
109
- default: "production",
110
- description: "Target environment",
111
- },
112
- branch: {
113
- type: "string",
114
- default: "main",
115
- description: "Branch to deploy",
116
- },
117
- },
76
+ description: "Build, test, deploy, and verify with rollback on failure",
77
+ metadata: { version: "1.0.0" },
118
78
  },
119
79
  skillMd: `# Deploy Safely
120
80
 
121
- Build, test, deploy, and verify with rollback on failure.
81
+ Build, test, deploy, and verify with rollback on failure.
122
82
 
123
83
  ## Steps
124
84
 
125
- 1. \`veryfront build --json\` abort if success: false
126
- 2. \`veryfront test --json\` abort if any test fails
85
+ 1. \`veryfront build --json\`, abort if success: false
86
+ 2. \`veryfront test --json\`, abort if any test fails
127
87
  3. \`veryfront deploy --env <environment> --branch <branch> --yes --json\`
128
88
  4. Use vf_get_errors to verify no runtime errors after deploy
129
89
  5. If errors: redeploy previous version
@@ -137,14 +97,10 @@ Build, test, deploy, and verify — with rollback on failure.
137
97
  directory: "core:deploy-safely",
138
98
  },
139
99
  {
140
- manifest: {
100
+ metadata: {
141
101
  name: "debug-build",
142
- version: "1.0.0",
143
102
  description: "Diagnose and fix build failures using structured error output",
144
- requires: {
145
- cli: ["build", "doctor"],
146
- mcp: ["vf_get_errors", "vf_get_debug_context"],
147
- },
103
+ metadata: { version: "1.0.0" },
148
104
  },
149
105
  skillMd: `# Debug Build
150
106
 
@@ -152,7 +108,7 @@ Diagnose and fix build failures.
152
108
 
153
109
  ## Steps
154
110
 
155
- 1. \`veryfront build --json\` capture error envelope
111
+ 1. \`veryfront build --json\`, capture error envelope
156
112
  2. Use vf_get_errors and vf_get_debug_context for details
157
113
  3. Common issues: import resolution, type errors, config errors
158
114
  4. Apply fix, rebuild: \`veryfront build --json\`
@@ -166,14 +122,10 @@ Diagnose and fix build failures.
166
122
  directory: "core:debug-build",
167
123
  },
168
124
  {
169
- manifest: {
125
+ metadata: {
170
126
  name: "debug-runtime",
171
- version: "1.0.0",
172
127
  description: "Diagnose runtime errors by connecting to dev server via MCP",
173
- requires: {
174
- cli: ["dev"],
175
- mcp: ["vf_get_errors", "vf_get_debug_context"],
176
- },
128
+ metadata: { version: "1.0.0" },
177
129
  },
178
130
  skillMd: `# Debug Runtime
179
131
 
@@ -196,14 +148,10 @@ Diagnose runtime errors via MCP.
196
148
  directory: "core:debug-runtime",
197
149
  },
198
150
  {
199
- manifest: {
151
+ metadata: {
200
152
  name: "contribute",
201
- version: "1.0.0",
202
- description: "Onboard to veryfront-code — architecture, testing, conventions, PR process",
203
- requires: {
204
- cli: ["test", "lint", "schema"],
205
- mcp: ["vf_get_conventions"],
206
- },
153
+ description: "Onboard to veryfront-code architecture, testing, conventions, and PR process",
154
+ metadata: { version: "1.0.0" },
207
155
  },
208
156
  skillMd: `# Contribute
209
157
 
@@ -1,9 +1,9 @@
1
- import { type LoadedSkill } from "./types.js";
1
+ import type { LoadedSkill } from "./types.js";
2
2
  export declare function loadSkill(directory: string): Promise<LoadedSkill | null>;
3
3
  export declare function listCoreSkills(): Promise<LoadedSkill[]>;
4
4
  /**
5
5
  * Scan the current working directory for local skill directories.
6
- * A local skill is any subdirectory containing a skill.json file.
6
+ * A local skill is any skills/<id>/ directory containing a SKILL.md file.
7
7
  */
8
8
  export declare function listLocalSkills(): Promise<LoadedSkill[]>;
9
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/cli/skills/loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,YAAY,CAAC;AAO9D,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAe7B;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAqB7D;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAgB9D;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAqB5D"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/cli/skills/loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAW7B;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAqB7D;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAgB9D;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAqB5D"}
@@ -1,6 +1,7 @@
1
1
  import { createFileSystem } from "../../src/platform/index.js";
2
2
  import { cwd } from "../../src/platform/index.js";
3
- import { parseSkillJson } from "./types.js";
3
+ import { basename } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
4
+ import { parseSkillFrontmatter, validateSkillMetadata } from "../../src/skill/index.js";
4
5
  import { CORE_SKILLS } from "./core-skills.js";
5
6
  function getCoreSkillsDir() {
6
7
  return new URL("../mcp/skills", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url).pathname;
@@ -8,12 +9,10 @@ function getCoreSkillsDir() {
8
9
  export async function loadSkill(directory) {
9
10
  const fs = createFileSystem();
10
11
  try {
11
- const manifestRaw = await fs.readTextFile(`${directory}/skill.json`);
12
- const manifest = parseSkillJson(JSON.parse(manifestRaw));
13
- if (!manifest.success)
14
- return null;
15
- const skillMd = await fs.readTextFile(`${directory}/SKILL.md`).catch(() => "");
16
- return { manifest: manifest.data, skillMd, directory };
12
+ const content = await fs.readTextFile(`${directory}/SKILL.md`);
13
+ const parsed = await parseSkillFrontmatter(content);
14
+ const metadata = validateSkillMetadata(parsed.frontmatter, basename(directory));
15
+ return { metadata, skillMd: parsed.body.trimStart(), directory };
17
16
  }
18
17
  catch {
19
18
  return null;
@@ -33,7 +32,7 @@ export async function listCoreSkills() {
33
32
  }
34
33
  }
35
34
  catch {
36
- // Filesystem skills not available (compiled binary) use embedded
35
+ // Filesystem skills not available in compiled binaries. Use embedded skills.
37
36
  }
38
37
  // Fall back to embedded core skills if none loaded from filesystem
39
38
  if (skills.length === 0) {
@@ -43,23 +42,23 @@ export async function listCoreSkills() {
43
42
  }
44
43
  /**
45
44
  * Scan the current working directory for local skill directories.
46
- * A local skill is any subdirectory containing a skill.json file.
45
+ * A local skill is any skills/<id>/ directory containing a SKILL.md file.
47
46
  */
48
47
  export async function listLocalSkills() {
49
48
  const fs = createFileSystem();
50
49
  const skills = [];
51
- const dir = cwd();
50
+ const skillsDir = `${cwd()}/skills`;
52
51
  try {
53
- for await (const entry of fs.readDir(dir)) {
52
+ for await (const entry of fs.readDir(skillsDir)) {
54
53
  if (!entry.isDirectory)
55
54
  continue;
56
- const skill = await loadSkill(`${dir}/${entry.name}`);
55
+ const skill = await loadSkill(`${skillsDir}/${entry.name}`);
57
56
  if (skill)
58
57
  skills.push(skill);
59
58
  }
60
59
  }
61
60
  catch {
62
- // cwd not readable
61
+ // local skills directory not readable
63
62
  }
64
63
  return skills;
65
64
  }
@@ -75,11 +74,11 @@ export async function listAllSkills() {
75
74
  const seen = new Set();
76
75
  const result = [];
77
76
  for (const skill of local) {
78
- seen.add(skill.manifest.name);
77
+ seen.add(skill.metadata.name);
79
78
  result.push(skill);
80
79
  }
81
80
  for (const skill of core) {
82
- if (!seen.has(skill.manifest.name)) {
81
+ if (!seen.has(skill.metadata.name)) {
83
82
  result.push(skill);
84
83
  }
85
84
  }
@@ -1,42 +1,6 @@
1
- import type { InferSchema } from "../../src/extensions/schema/index.js";
2
- export declare const getSkillManifestSchema: () => import("../../src/internal-agents/schema.js").Schema<import("../../src/extensions/schema/schema-validator.js").InferShape<{
3
- name: import("../../src/internal-agents/schema.js").Schema<string>;
4
- version: import("../../src/internal-agents/schema.js").Schema<string>;
5
- description: import("../../src/internal-agents/schema.js").Schema<string>;
6
- requires: import("../../src/internal-agents/schema.js").Schema<import("../../src/extensions/schema/schema-validator.js").InferShape<{
7
- cli: import("../../src/internal-agents/schema.js").Schema<string[] | undefined>;
8
- mcp: import("../../src/internal-agents/schema.js").Schema<string[] | undefined>;
9
- }> | undefined>;
10
- inputs: import("../../src/internal-agents/schema.js").Schema<Record<string, import("../../src/extensions/schema/schema-validator.js").InferShape<{
11
- type: import("../../src/internal-agents/schema.js").Schema<string>;
12
- default: import("../../src/internal-agents/schema.js").Schema<unknown>;
13
- description: import("../../src/internal-agents/schema.js").Schema<string | undefined>;
14
- }>> | undefined>;
15
- }>>;
16
- export declare const SkillManifestSchema: import("../../src/internal-agents/schema.js").Schema<import("../../src/extensions/schema/schema-validator.js").InferShape<{
17
- name: import("../../src/internal-agents/schema.js").Schema<string>;
18
- version: import("../../src/internal-agents/schema.js").Schema<string>;
19
- description: import("../../src/internal-agents/schema.js").Schema<string>;
20
- requires: import("../../src/internal-agents/schema.js").Schema<import("../../src/extensions/schema/schema-validator.js").InferShape<{
21
- cli: import("../../src/internal-agents/schema.js").Schema<string[] | undefined>;
22
- mcp: import("../../src/internal-agents/schema.js").Schema<string[] | undefined>;
23
- }> | undefined>;
24
- inputs: import("../../src/internal-agents/schema.js").Schema<Record<string, import("../../src/extensions/schema/schema-validator.js").InferShape<{
25
- type: import("../../src/internal-agents/schema.js").Schema<string>;
26
- default: import("../../src/internal-agents/schema.js").Schema<unknown>;
27
- description: import("../../src/internal-agents/schema.js").Schema<string | undefined>;
28
- }>> | undefined>;
29
- }>>;
30
- export type SkillManifest = InferSchema<ReturnType<typeof getSkillManifestSchema>>;
31
- export declare function parseSkillJson(raw: unknown): {
32
- success: true;
33
- data: SkillManifest;
34
- } | {
35
- success: false;
36
- error: string;
37
- };
1
+ import type { SkillMetadata } from "../../src/skill/index.js";
38
2
  export interface LoadedSkill {
39
- manifest: SkillManifest;
3
+ metadata: SkillMetadata;
40
4
  skillMd: string;
41
5
  directory: string;
42
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/skills/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAExE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;GAsBlC,CAAC;AACF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;GAAqC,CAAC;AAEtE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC;AAEnF,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,GACX;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK5E;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/skills/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -1,27 +1 @@
1
- import { defineSchema, lazySchema } from "../../src/schemas/index.js";
2
- export const getSkillManifestSchema = defineSchema((v) => v.object({
3
- name: v.string(),
4
- version: v.string(),
5
- description: v.string(),
6
- requires: v
7
- .object({
8
- cli: v.array(v.string()).optional(),
9
- mcp: v.array(v.string()).optional(),
10
- })
11
- .optional(),
12
- inputs: v
13
- .record(v.string(), v.object({
14
- type: v.string(),
15
- default: v.unknown().optional(),
16
- description: v.string().optional(),
17
- }))
18
- .optional(),
19
- }));
20
- export const SkillManifestSchema = lazySchema(getSkillManifestSchema);
21
- export function parseSkillJson(raw) {
22
- const result = SkillManifestSchema.safeParse(raw);
23
- if (result.success)
24
- return { success: true, data: result.data };
25
- const message = result.issues?.map((i) => i.message).join("; ") ?? "Validation failed";
26
- return { success: false, error: message };
27
- }
1
+ export {};
@@ -11,4 +11,5 @@ export { AVAILABLE_FEATURES, featureExists, loadFeature, loadFeatureConfig, merg
11
11
  export declare const templateConfigs: Partial<Record<TemplateName, TemplateConfig>>;
12
12
  export declare function getTemplate(name: TemplateName): Promise<TemplateFile[] | null>;
13
13
  export declare function getTemplateConfig(name: TemplateName): TemplateConfig | null;
14
+ export declare function getAiRuleTemplate(templateName: string): string | null;
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,GACb,CAAC;AAEF,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CAOzE,CAAC;AAIF,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,CAmBpF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,IAAI,CAE3E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,GACb,CAAC;AAEF,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CAOzE,CAAC;AAIF,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,CAmBpF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,IAAI,CAE3E;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAErE"}