veryfront 0.1.854 → 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.
- 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 +7 -7
- package/esm/deno.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
|
@@ -1,66 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Skills validate command
|
|
2
|
+
* Skills validate command, validate a skill directory
|
|
3
3
|
*
|
|
4
4
|
* @module cli/commands/skills/validate
|
|
5
5
|
*/
|
|
6
6
|
import * as dntShim from "../../../_dnt.shims.js";
|
|
7
7
|
import { createSuccessEnvelope, isJsonMode, outputJson } from "../../shared/json-output.js";
|
|
8
|
-
import { parseSkillJson } from "../../skills/types.js";
|
|
9
|
-
import { COMMANDS } from "../../help/command-definitions.js";
|
|
10
8
|
import { logError, logSuccess } from "../../utils/index.js";
|
|
11
9
|
import { createFileSystem } from "../../../src/platform/index.js";
|
|
10
|
+
import { basename } from "../../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
11
|
+
import { parseSkillFrontmatter, validateSkillMetadata } from "../../../src/skill/index.js";
|
|
12
12
|
export async function validateSkill(args) {
|
|
13
13
|
const dir = args._[2] ?? ".";
|
|
14
|
+
const issues = await validateSkillDirectory(dir);
|
|
15
|
+
return outputResults(dir, issues);
|
|
16
|
+
}
|
|
17
|
+
export async function validateSkillDirectory(dir) {
|
|
14
18
|
const issues = [];
|
|
15
19
|
const fs = createFileSystem();
|
|
16
|
-
|
|
17
|
-
let manifestRaw;
|
|
20
|
+
let content;
|
|
18
21
|
try {
|
|
19
|
-
|
|
22
|
+
content = await fs.readTextFile(`${dir}/SKILL.md`);
|
|
20
23
|
}
|
|
21
24
|
catch {
|
|
22
|
-
|
|
23
|
-
return outputResults(dir, issues);
|
|
25
|
+
return [{ severity: "error", message: "SKILL.md not found" }];
|
|
24
26
|
}
|
|
25
|
-
let parsed;
|
|
26
27
|
try {
|
|
27
|
-
parsed =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
severity: "error",
|
|
32
|
-
message: "skill.json is not valid JSON",
|
|
33
|
-
});
|
|
34
|
-
return outputResults(dir, issues);
|
|
35
|
-
}
|
|
36
|
-
if (!parsed.success) {
|
|
37
|
-
issues.push({
|
|
38
|
-
severity: "error",
|
|
39
|
-
message: `skill.json schema error: ${parsed.error}`,
|
|
40
|
-
});
|
|
41
|
-
return outputResults(dir, issues);
|
|
42
|
-
}
|
|
43
|
-
// Check SKILL.md exists
|
|
44
|
-
try {
|
|
45
|
-
const content = await fs.readTextFile(`${dir}/SKILL.md`);
|
|
46
|
-
if (!content.trim()) {
|
|
47
|
-
issues.push({ severity: "warning", message: "SKILL.md is empty" });
|
|
28
|
+
const parsed = await parseSkillFrontmatter(content);
|
|
29
|
+
validateSkillMetadata(parsed.frontmatter, basename(dir));
|
|
30
|
+
if (!parsed.body.trim()) {
|
|
31
|
+
issues.push({ severity: "warning", message: "SKILL.md body is empty" });
|
|
48
32
|
}
|
|
49
33
|
}
|
|
50
|
-
catch {
|
|
51
|
-
|
|
34
|
+
catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
issues.push({ severity: "error", message });
|
|
52
37
|
}
|
|
53
|
-
|
|
54
|
-
const cliReqs = parsed.data.requires?.cli ?? [];
|
|
55
|
-
for (const cmd of cliReqs) {
|
|
56
|
-
if (!COMMANDS[cmd]) {
|
|
57
|
-
issues.push({
|
|
58
|
-
severity: "warning",
|
|
59
|
-
message: `Required CLI command "${cmd}" not found in registry`,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return outputResults(dir, issues);
|
|
38
|
+
return issues;
|
|
64
39
|
}
|
|
65
40
|
async function outputResults(dir, issues) {
|
|
66
41
|
const hasErrors = issues.some((i) => i.severity === "error");
|
package/esm/cli/mcp/server.js
CHANGED
|
@@ -325,10 +325,10 @@ export class MCPDevServer {
|
|
|
325
325
|
const { listCoreSkills } = await import("../skills/loader.js");
|
|
326
326
|
const skills = await listCoreSkills();
|
|
327
327
|
const data = skills.map((s) => ({
|
|
328
|
-
name: s.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
328
|
+
name: s.metadata.name,
|
|
329
|
+
description: s.metadata.description,
|
|
330
|
+
allowedTools: s.metadata.allowedTools,
|
|
331
|
+
directory: s.directory,
|
|
332
332
|
}));
|
|
333
333
|
return {
|
|
334
334
|
contents: [{
|
|
@@ -154,10 +154,10 @@ export class StandaloneMCPServer {
|
|
|
154
154
|
const { listCoreSkills } = await import("../skills/loader.js");
|
|
155
155
|
const skills = await listCoreSkills();
|
|
156
156
|
const data = skills.map((s) => ({
|
|
157
|
-
name: s.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
name: s.metadata.name,
|
|
158
|
+
description: s.metadata.description,
|
|
159
|
+
allowedTools: s.metadata.allowedTools,
|
|
160
|
+
directory: s.directory,
|
|
161
161
|
}));
|
|
162
162
|
return {
|
|
163
163
|
contents: [{
|
|
@@ -29,14 +29,6 @@ export interface ProjectContext {
|
|
|
29
29
|
integrations: string[];
|
|
30
30
|
features: string[];
|
|
31
31
|
}
|
|
32
|
-
export interface ScaffoldResult {
|
|
33
|
-
success: boolean;
|
|
34
|
-
files: Array<{
|
|
35
|
-
path: string;
|
|
36
|
-
created: boolean;
|
|
37
|
-
}>;
|
|
38
|
-
message: string;
|
|
39
|
-
}
|
|
40
32
|
export declare function getProjectDir(projectPath?: string): string;
|
|
41
33
|
export declare function scanDirectory(dir: string, baseRoute: string, routes: RouteInfo[], fs: FileSystem): Promise<void>;
|
|
42
34
|
export declare const ROUTE_FILTER_MAP: Record<string, RouteType[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAwB,MAAM,uBAAuB,CAAC;AAG3F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;AAEvF,qDAAqD;AACrD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAMD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;IACF,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAwB,MAAM,uBAAuB,CAAC;AAG3F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;AAEvF,qDAAqD;AACrD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAMD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;IACF,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD,wBAAgB,aAAa,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AA0CD,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,EAAE,EACnB,EAAE,EAAE,UAAU,GACb,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAIxD,CAAC"}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { InferSchema } from "../../../src/extensions/schema/index.js";
|
|
5
5
|
import type { MCPTool } from "../tools.js";
|
|
6
|
-
import { type ScaffoldResult } from "
|
|
6
|
+
import { type ScaffoldResult } from "../../scaffold/engine.js";
|
|
7
7
|
declare const getScaffoldInput: () => import("../../../src/internal-agents/schema.js").Schema<import("../../../src/extensions/schema/schema-validator.js").InferShape<{
|
|
8
|
-
type: import("../../../src/internal-agents/schema.js").Schema<
|
|
8
|
+
type: import("../../../src/internal-agents/schema.js").Schema<"prompt" | "page" | "api" | "agent" | "layout" | "resource" | "component" | "task" | "tool" | "skill" | "workflow">;
|
|
9
9
|
name: import("../../../src/internal-agents/schema.js").Schema<string>;
|
|
10
10
|
methods: import("../../../src/internal-agents/schema.js").Schema<string[] | undefined>;
|
|
11
11
|
projectPath: import("../../../src/internal-agents/schema.js").Schema<string | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-tools.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/scaffold-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"scaffold-tools.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/scaffold-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAE3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,0BAA0B,CAAC;AAOlC,QAAA,MAAM,gBAAgB;;;;;GAarB,CAAC;AAGF,KAAK,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;AAEtE,eAAO,MAAM,UAAU,EAAE,OAAO,CAAC,aAAa,EAAE,cAAc,CA6B7D,CAAC;AAMF,QAAA,MAAM,sBAAsB;;GAQ3B,CAAC;AAGF,KAAK,mBAAmB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC;AAElF,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAkID,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,mBAAmB,EAAE,UAAU,EAAE,CAevE,CAAC"}
|
|
@@ -2,205 +2,34 @@
|
|
|
2
2
|
* MCP tools for scaffolding and conventions.
|
|
3
3
|
*/
|
|
4
4
|
import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
|
|
5
|
-
import { join } from "../../../src/platform/compat/path/index.js";
|
|
6
5
|
import { withSpan } from "../../../src/observability/tracing/otlp-setup.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
// Scaffold Templates
|
|
10
|
-
// ============================================================================
|
|
11
|
-
function generatePageTemplate(name, componentName) {
|
|
12
|
-
return `export default function ${componentName}() {
|
|
13
|
-
return (
|
|
14
|
-
<div>
|
|
15
|
-
<h1>${name}</h1>
|
|
16
|
-
<p>This is the ${name} page.</p>
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
`;
|
|
21
|
-
}
|
|
22
|
-
function generateLayoutTemplate(name, componentName) {
|
|
23
|
-
return `export default function ${componentName}Layout({
|
|
24
|
-
children,
|
|
25
|
-
}: {
|
|
26
|
-
children: React.ReactNode;
|
|
27
|
-
}) {
|
|
28
|
-
return (
|
|
29
|
-
<section className="${name}-layout">
|
|
30
|
-
{children}
|
|
31
|
-
</section>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
`;
|
|
35
|
-
}
|
|
36
|
-
function generateApiTemplate(methods) {
|
|
37
|
-
const handlers = methods.map((method) => {
|
|
38
|
-
if (method === "GET") {
|
|
39
|
-
return `export function GET(req: Request) {
|
|
40
|
-
return Response.json({ ok: true });
|
|
41
|
-
}`;
|
|
42
|
-
}
|
|
43
|
-
return `export async function ${method}(req: Request) {
|
|
44
|
-
const body = await req.json();
|
|
45
|
-
return Response.json({ ok: true, received: body });
|
|
46
|
-
}`;
|
|
47
|
-
});
|
|
48
|
-
return `${handlers.join("\n\n")}\n`;
|
|
49
|
-
}
|
|
50
|
-
function generateComponentTemplate(componentName) {
|
|
51
|
-
return `interface ${componentName}Props {
|
|
52
|
-
children?: React.ReactNode;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function ${componentName}({ children }: ${componentName}Props) {
|
|
56
|
-
return (
|
|
57
|
-
<div className="${componentName.toLowerCase()}">
|
|
58
|
-
{children}
|
|
59
|
-
</div>
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
`;
|
|
63
|
-
}
|
|
64
|
-
function generateToolTemplate(name) {
|
|
65
|
-
return `import { tool } from "veryfront/tool";
|
|
66
|
-
import { defineSchema, lazySchema } from "veryfront/schemas";
|
|
67
|
-
|
|
68
|
-
const getParameters = defineSchema((v) => v.object({
|
|
69
|
-
// Add your parameters here
|
|
70
|
-
input: v.string().describe("Input parameter"),
|
|
71
|
-
}));
|
|
72
|
-
|
|
73
|
-
export default tool({
|
|
74
|
-
id: "${name}",
|
|
75
|
-
description: "Description of what this tool does",
|
|
76
|
-
parameters: lazySchema(getParameters),
|
|
77
|
-
execute: async ({ input }) => {
|
|
78
|
-
// Implement your tool logic here
|
|
79
|
-
return { result: input };
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
`;
|
|
83
|
-
}
|
|
84
|
-
function generateAgentTemplate(name, className) {
|
|
85
|
-
return `import { agent } from "veryfront/agent";
|
|
86
|
-
|
|
87
|
-
export default agent({
|
|
88
|
-
id: "${className.toLowerCase()}",
|
|
89
|
-
name: "${name}",
|
|
90
|
-
description: "Description of this agent's capabilities",
|
|
91
|
-
instructions: \`
|
|
92
|
-
You are an AI assistant specialized in ${name}.
|
|
93
|
-
|
|
94
|
-
Your capabilities:
|
|
95
|
-
- List your agent's capabilities here
|
|
96
|
-
|
|
97
|
-
Guidelines:
|
|
98
|
-
- Be helpful and accurate
|
|
99
|
-
- Ask for clarification when needed
|
|
100
|
-
\`,
|
|
101
|
-
tools: [
|
|
102
|
-
// Add tools this agent can use
|
|
103
|
-
],
|
|
104
|
-
});
|
|
105
|
-
`;
|
|
106
|
-
}
|
|
107
|
-
function generatePromptTemplate(name) {
|
|
108
|
-
return `import { prompt } from "veryfront/prompt";
|
|
109
|
-
import { defineSchema, lazySchema } from "veryfront/schemas";
|
|
110
|
-
|
|
111
|
-
const getArgsSchema = defineSchema((v) => v.object({
|
|
112
|
-
input: v.string().describe("User input"),
|
|
113
|
-
}));
|
|
114
|
-
|
|
115
|
-
export default prompt({
|
|
116
|
-
id: "${name}",
|
|
117
|
-
description: "Description of this prompt template",
|
|
118
|
-
argsSchema: lazySchema(getArgsSchema),
|
|
119
|
-
getContent: ({ input }) => [
|
|
120
|
-
{ role: "system", content: "Role: describe what this assistant should do and its limits." },
|
|
121
|
-
{ role: "user", content: input },
|
|
122
|
-
],
|
|
123
|
-
});
|
|
124
|
-
`;
|
|
125
|
-
}
|
|
6
|
+
import { SCAFFOLD_TYPES, scaffoldProjectFile, } from "../../scaffold/engine.js";
|
|
7
|
+
import { formatError, getProjectDir } from "./helpers.js";
|
|
126
8
|
// ============================================================================
|
|
127
9
|
// Scaffold Configuration
|
|
128
10
|
// ============================================================================
|
|
129
11
|
const getScaffoldInput = defineSchema((v) => v.object({
|
|
130
|
-
type: v.enum(
|
|
12
|
+
type: v.enum(SCAFFOLD_TYPES).describe("Type of project file to scaffold"),
|
|
131
13
|
name: v.string().describe("Name/path of the entity (e.g., 'users', 'api/users', 'dashboard/settings')"),
|
|
132
14
|
methods: v.array(v.enum(["GET", "POST", "PUT", "DELETE", "PATCH"])).optional().describe("HTTP methods for API routes (defaults to GET)"),
|
|
133
15
|
projectPath: v.string().optional().describe("Project directory (defaults to current working directory)"),
|
|
134
16
|
}));
|
|
135
17
|
const scaffoldInput = lazySchema(getScaffoldInput);
|
|
136
|
-
const SCAFFOLD_CONFIGS = {
|
|
137
|
-
page: {
|
|
138
|
-
getDirectory: (projectDir, slug) => join(projectDir, "app", slug),
|
|
139
|
-
getFilename: () => "page.tsx",
|
|
140
|
-
getContent: (name, _slug, componentName) => generatePageTemplate(name, componentName),
|
|
141
|
-
},
|
|
142
|
-
api: {
|
|
143
|
-
getDirectory: (projectDir, slug) => join(projectDir, "app", slug),
|
|
144
|
-
getFilename: () => "route.ts",
|
|
145
|
-
getContent: (_name, _slug, _componentName, methods) => generateApiTemplate(methods ?? ["GET"]),
|
|
146
|
-
},
|
|
147
|
-
layout: {
|
|
148
|
-
getDirectory: (projectDir, slug) => join(projectDir, "app", slug),
|
|
149
|
-
getFilename: () => "layout.tsx",
|
|
150
|
-
getContent: (name, _slug, componentName) => generateLayoutTemplate(name, componentName),
|
|
151
|
-
},
|
|
152
|
-
component: {
|
|
153
|
-
getDirectory: (projectDir) => join(projectDir, "components"),
|
|
154
|
-
getFilename: (_slug, componentName) => `${componentName}.tsx`,
|
|
155
|
-
getContent: (_name, _slug, componentName) => generateComponentTemplate(componentName),
|
|
156
|
-
},
|
|
157
|
-
tool: {
|
|
158
|
-
getDirectory: (projectDir) => join(projectDir, "ai", "tools"),
|
|
159
|
-
getFilename: (slug) => `${slug}.ts`,
|
|
160
|
-
getContent: (name) => generateToolTemplate(name),
|
|
161
|
-
},
|
|
162
|
-
agent: {
|
|
163
|
-
getDirectory: (projectDir) => join(projectDir, "ai", "agents"),
|
|
164
|
-
getFilename: (slug) => `${slug}.ts`,
|
|
165
|
-
getContent: (name, _slug, componentName) => generateAgentTemplate(name, componentName),
|
|
166
|
-
},
|
|
167
|
-
prompt: {
|
|
168
|
-
getDirectory: (projectDir) => join(projectDir, "ai", "prompts"),
|
|
169
|
-
getFilename: (slug) => `${slug}.ts`,
|
|
170
|
-
getContent: (_name, slug) => generatePromptTemplate(slug.replace(/-/g, "_")),
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
18
|
export const vfScaffold = {
|
|
174
19
|
name: "vf_scaffold",
|
|
175
20
|
title: "Scaffold Code",
|
|
176
21
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },
|
|
177
|
-
description: "Use this when you need to generate new pages, API routes, layouts, components,
|
|
22
|
+
description: "Use this when you need to generate new pages, API routes, layouts, components, tools, agents, prompts, workflows, tasks, resources, or skills with Veryfront conventions. Returns created file paths and refuses existing target files. Do not use for creating entire projects. Use vf_create_project instead.",
|
|
178
23
|
inputSchema: scaffoldInput,
|
|
179
24
|
execute: (input) => withSpan("cli.mcp.tool.vf_scaffold", async () => {
|
|
180
25
|
const projectDir = getProjectDir(input.projectPath);
|
|
181
|
-
const fs = getFs();
|
|
182
|
-
const slug = toSlug(input.name);
|
|
183
|
-
const componentName = toComponentName(input.name);
|
|
184
|
-
const config = SCAFFOLD_CONFIGS[input.type];
|
|
185
|
-
const directory = config.getDirectory(projectDir, slug);
|
|
186
|
-
const filename = config.getFilename(slug, componentName);
|
|
187
|
-
const filePath = join(directory, filename);
|
|
188
26
|
try {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
await ensureDir(directory);
|
|
197
|
-
const content = config.getContent(input.name, slug, componentName, input.methods);
|
|
198
|
-
await fs.writeTextFile(filePath, content);
|
|
199
|
-
return {
|
|
200
|
-
success: true,
|
|
201
|
-
files: [{ path: filePath, created: true }],
|
|
202
|
-
message: `Created ${input.type} "${input.name}" successfully`,
|
|
203
|
-
};
|
|
27
|
+
return await scaffoldProjectFile({
|
|
28
|
+
projectDir,
|
|
29
|
+
type: input.type,
|
|
30
|
+
name: input.name,
|
|
31
|
+
methods: input.methods,
|
|
32
|
+
});
|
|
204
33
|
}
|
|
205
34
|
catch (error) {
|
|
206
35
|
return {
|
|
@@ -303,29 +132,31 @@ const CONVENTIONS = {
|
|
|
303
132
|
ai: {
|
|
304
133
|
topic: "AI / Agents",
|
|
305
134
|
rules: [
|
|
306
|
-
"AI
|
|
307
|
-
"
|
|
308
|
-
"
|
|
135
|
+
"AI primitives live at the project root",
|
|
136
|
+
"Tools go in tools/ directory",
|
|
137
|
+
"Agents go in agents/ directory",
|
|
138
|
+
"Prompts go in prompts/ directory",
|
|
139
|
+
"Workflows go in workflows/ directory",
|
|
140
|
+
"Tasks go in tasks/ directory",
|
|
141
|
+
"Resources go in resources/ directory",
|
|
142
|
+
"Skills go in skills/<id>/SKILL.md",
|
|
309
143
|
"Use defineSchema for tool parameter validation",
|
|
310
144
|
"Tools should be focused on a single capability",
|
|
311
145
|
"Agents combine tools with instructions for complex tasks",
|
|
312
146
|
],
|
|
313
147
|
examples: [
|
|
314
148
|
{
|
|
315
|
-
good: "
|
|
149
|
+
good: "tools/search-docs.ts",
|
|
316
150
|
explanation: "Tools in dedicated directory with descriptive names",
|
|
317
151
|
},
|
|
318
152
|
{
|
|
319
|
-
good: `
|
|
153
|
+
good: `export default tool({
|
|
154
|
+
inputSchema: defineSchema((v) => v.object({
|
|
320
155
|
query: v.string(),
|
|
321
|
-
}))
|
|
322
|
-
|
|
323
|
-
export const searchTool = {
|
|
324
|
-
name: "search_docs",
|
|
325
|
-
parameters: lazySchema(getParameters),
|
|
156
|
+
}))(),
|
|
326
157
|
execute: async ({ query }) => { /* ... */ }
|
|
327
|
-
};`,
|
|
328
|
-
explanation: "Tool with
|
|
158
|
+
});`,
|
|
159
|
+
explanation: "Tool with schema-backed input and typed execute function",
|
|
329
160
|
},
|
|
330
161
|
],
|
|
331
162
|
},
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type ScaffoldRouter = "app-router" | "pages-router";
|
|
2
|
+
export declare const SCAFFOLD_TYPES: readonly ["page", "api", "layout", "component", "tool", "agent", "prompt", "workflow", "task", "resource", "skill"];
|
|
3
|
+
export type ScaffoldType = typeof SCAFFOLD_TYPES[number];
|
|
4
|
+
export type ScaffoldHttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
5
|
+
export interface ScaffoldInput {
|
|
6
|
+
projectDir: string;
|
|
7
|
+
type: ScaffoldType;
|
|
8
|
+
name: string;
|
|
9
|
+
router?: ScaffoldRouter;
|
|
10
|
+
methods?: ScaffoldHttpMethod[];
|
|
11
|
+
}
|
|
12
|
+
export interface ScaffoldFilePlan {
|
|
13
|
+
path: string;
|
|
14
|
+
content: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ScaffoldPlan {
|
|
17
|
+
type: ScaffoldType;
|
|
18
|
+
name: string;
|
|
19
|
+
files: ScaffoldFilePlan[];
|
|
20
|
+
}
|
|
21
|
+
export interface ScaffoldResult {
|
|
22
|
+
success: boolean;
|
|
23
|
+
files: Array<{
|
|
24
|
+
path: string;
|
|
25
|
+
created: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
message: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function isScaffoldType(type: string): type is ScaffoldType;
|
|
30
|
+
export declare function planScaffold(input: ScaffoldInput): ScaffoldPlan;
|
|
31
|
+
export declare function writeScaffoldPlan(plan: ScaffoldPlan): Promise<ScaffoldResult>;
|
|
32
|
+
export declare function scaffoldProjectFile(input: ScaffoldInput): Promise<ScaffoldResult>;
|
|
33
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/scaffold/engine.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,cAAc,CAAC;AAC3D,eAAO,MAAM,cAAc,qHAYjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,CAAC;CACjB;AA+ED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,YAAY,CAEjE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAa/D;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA2BnF;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAEvF"}
|