veryfront 0.1.854 → 0.1.856
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/esm/cli/commands/generate/command-help.d.ts.map +1 -1
- package/esm/cli/commands/generate/command-help.js +7 -2
- package/esm/cli/commands/generate/command.d.ts.map +1 -1
- package/esm/cli/commands/generate/command.js +25 -101
- package/esm/cli/commands/generate/handler.d.ts +1 -1
- package/esm/cli/commands/generate/handler.d.ts.map +1 -1
- package/esm/cli/commands/generate/handler.js +2 -1
- package/esm/cli/commands/generate/integration-generator.js +4 -4
- package/esm/cli/commands/init/init-command.d.ts.map +1 -1
- package/esm/cli/commands/init/init-command.js +100 -1
- package/esm/cli/commands/mcp/command-help.js +1 -1
- package/esm/cli/commands/skills/command-help.js +1 -1
- package/esm/cli/commands/skills/command.d.ts +1 -1
- package/esm/cli/commands/skills/command.js +2 -2
- package/esm/cli/commands/skills/create.d.ts.map +1 -1
- package/esm/cli/commands/skills/create.js +14 -40
- package/esm/cli/commands/skills/handler.js +15 -16
- package/esm/cli/commands/skills/validate.d.ts +6 -0
- package/esm/cli/commands/skills/validate.d.ts.map +1 -1
- package/esm/cli/commands/skills/validate.js +18 -43
- package/esm/cli/mcp/server.js +4 -4
- package/esm/cli/mcp/standalone.js +4 -4
- package/esm/cli/mcp/tools/helpers.d.ts +0 -8
- package/esm/cli/mcp/tools/helpers.d.ts.map +1 -1
- package/esm/cli/mcp/tools/scaffold-tools.d.ts +2 -2
- package/esm/cli/mcp/tools/scaffold-tools.d.ts.map +1 -1
- package/esm/cli/mcp/tools/scaffold-tools.js +24 -193
- package/esm/cli/scaffold/engine.d.ts +33 -0
- package/esm/cli/scaffold/engine.d.ts.map +1 -0
- package/esm/cli/scaffold/engine.js +303 -0
- package/esm/cli/skills/core-skills.d.ts.map +1 -1
- package/esm/cli/skills/core-skills.js +23 -75
- package/esm/cli/skills/loader.d.ts +2 -2
- package/esm/cli/skills/loader.d.ts.map +1 -1
- package/esm/cli/skills/loader.js +14 -15
- package/esm/cli/skills/types.d.ts +2 -38
- package/esm/cli/skills/types.d.ts.map +1 -1
- package/esm/cli/skills/types.js +1 -27
- package/esm/cli/templates/index.d.ts +1 -0
- package/esm/cli/templates/index.d.ts.map +1 -1
- package/esm/cli/templates/index.js +4 -1
- package/esm/cli/templates/loader.d.ts +1 -0
- package/esm/cli/templates/loader.d.ts.map +1 -1
- package/esm/cli/templates/loader.js +6 -0
- package/esm/cli/templates/manifest.js +17 -17
- package/esm/deno.js +1 -1
- package/esm/src/agent/react/use-chat/types.d.ts +2 -2
- package/esm/src/agent/react/use-chat/types.d.ts.map +1 -1
- package/esm/src/agent/react/use-chat/use-chat.js +1 -1
- package/esm/src/agent/runtime/constants.d.ts.map +1 -1
- package/esm/src/agent/runtime/constants.js +0 -2
- package/esm/src/agent/runtime/model-resolution.d.ts.map +1 -1
- package/esm/src/agent/runtime/model-resolution.js +14 -4
- package/esm/src/agent/runtime/skill-metadata.d.ts.map +1 -1
- package/esm/src/agent/runtime/skill-metadata.js +2 -1
- package/esm/src/integrations/_data.js +1 -1
- package/esm/src/provider/veryfront-cloud/model-catalog.d.ts +1 -0
- package/esm/src/provider/veryfront-cloud/model-catalog.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/model-catalog.js +13 -14
- package/esm/src/provider/veryfront-cloud/shared.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/shared.js +8 -0
- package/esm/src/skill/parser.d.ts.map +1 -1
- package/esm/src/skill/parser.js +2 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- 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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
87
|
-
3.
|
|
88
|
-
4. Configure provider
|
|
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
|
|
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
|
-
|
|
74
|
+
metadata: {
|
|
99
75
|
name: "deploy-safely",
|
|
100
|
-
|
|
101
|
-
|
|
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
|
|
81
|
+
Build, test, deploy, and verify with rollback on failure.
|
|
122
82
|
|
|
123
83
|
## Steps
|
|
124
84
|
|
|
125
|
-
1. \`veryfront build --json
|
|
126
|
-
2. \`veryfront test --json
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
151
|
+
metadata: {
|
|
200
152
|
name: "contribute",
|
|
201
|
-
|
|
202
|
-
|
|
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 {
|
|
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
|
|
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":"
|
|
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"}
|
package/esm/cli/skills/loader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createFileSystem } from "../../src/platform/index.js";
|
|
2
2
|
import { cwd } from "../../src/platform/index.js";
|
|
3
|
-
import {
|
|
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
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
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
|
|
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
|
|
50
|
+
const skillsDir = `${cwd()}/skills`;
|
|
52
51
|
try {
|
|
53
|
-
for await (const entry of fs.readDir(
|
|
52
|
+
for await (const entry of fs.readDir(skillsDir)) {
|
|
54
53
|
if (!entry.isDirectory)
|
|
55
54
|
continue;
|
|
56
|
-
const skill = await loadSkill(`${
|
|
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
|
-
//
|
|
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.
|
|
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.
|
|
81
|
+
if (!seen.has(skill.metadata.name)) {
|
|
83
82
|
result.push(skill);
|
|
84
83
|
}
|
|
85
84
|
}
|
|
@@ -1,42 +1,6 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
|
|
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":"
|
|
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"}
|
package/esm/cli/skills/types.js
CHANGED
|
@@ -1,27 +1 @@
|
|
|
1
|
-
|
|
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;
|
|
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"}
|