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.
Files changed (63) 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/runtime/constants.d.ts.map +1 -1
  48. package/esm/src/agent/runtime/constants.js +0 -2
  49. package/esm/src/agent/runtime/model-resolution.d.ts.map +1 -1
  50. package/esm/src/agent/runtime/model-resolution.js +14 -4
  51. package/esm/src/agent/runtime/skill-metadata.d.ts.map +1 -1
  52. package/esm/src/agent/runtime/skill-metadata.js +2 -1
  53. package/esm/src/integrations/_data.js +1 -1
  54. package/esm/src/provider/veryfront-cloud/model-catalog.d.ts +1 -0
  55. package/esm/src/provider/veryfront-cloud/model-catalog.d.ts.map +1 -1
  56. package/esm/src/provider/veryfront-cloud/model-catalog.js +13 -14
  57. package/esm/src/provider/veryfront-cloud/shared.d.ts.map +1 -1
  58. package/esm/src/provider/veryfront-cloud/shared.js +8 -0
  59. package/esm/src/skill/parser.d.ts.map +1 -1
  60. package/esm/src/skill/parser.js +2 -1
  61. package/esm/src/utils/version-constant.d.ts +1 -1
  62. package/esm/src/utils/version-constant.js +1 -1
  63. package/package.json +1 -1
@@ -1,66 +1,41 @@
1
1
  /**
2
- * Skills validate command validate a skill directory
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
- // Check skill.json exists and parses
17
- let manifestRaw;
20
+ let content;
18
21
  try {
19
- manifestRaw = await fs.readTextFile(`${dir}/skill.json`);
22
+ content = await fs.readTextFile(`${dir}/SKILL.md`);
20
23
  }
21
24
  catch {
22
- issues.push({ severity: "error", message: "skill.json not found" });
23
- return outputResults(dir, issues);
25
+ return [{ severity: "error", message: "SKILL.md not found" }];
24
26
  }
25
- let parsed;
26
27
  try {
27
- parsed = parseSkillJson(JSON.parse(manifestRaw));
28
- }
29
- catch {
30
- issues.push({
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
- issues.push({ severity: "error", message: "SKILL.md not found" });
34
+ catch (error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ issues.push({ severity: "error", message });
52
37
  }
53
- // Check required CLI commands exist
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");
@@ -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.manifest.name,
329
- version: s.manifest.version,
330
- description: s.manifest.description,
331
- requires: s.manifest.requires,
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.manifest.name,
158
- version: s.manifest.version,
159
- description: s.manifest.description,
160
- requires: s.manifest.requires,
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;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;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"}
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 "./helpers.js";
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<string>;
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;AAG3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAML,KAAK,cAAc,EAGpB,MAAM,cAAc,CAAC;AAsItB,QAAA,MAAM,gBAAgB;;;;;GAerB,CAAC;AAGF,KAAK,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;AA+CtE,eAAO,MAAM,UAAU,EAAE,OAAO,CAAC,aAAa,EAAE,cAAc,CAiD7D,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;AAgID,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,mBAAmB,EAAE,UAAU,EAAE,CAevE,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 { ensureDir, fileExists, formatError, getFs, getProjectDir, toComponentName, toSlug, } from "./helpers.js";
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(["page", "api", "layout", "component", "tool", "agent", "prompt"]).describe("Type of entity to scaffold"),
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, AI tools, agents, or prompts with proper Veryfront conventions. Returns the created file path and content. May overwrite existing files at the target path. Do not use for creating entire projects use vf_create_project instead.",
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
- if (await fileExists(filePath)) {
190
- return {
191
- success: false,
192
- files: [],
193
- message: `${input.type} already exists at ${filePath}`,
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 tools go in ai/tools/ directory",
307
- "Agents go in ai/agents/ directory",
308
- "Prompts go in ai/prompts/ directory",
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: "ai/tools/search-docs.ts",
149
+ good: "tools/search-docs.ts",
316
150
  explanation: "Tools in dedicated directory with descriptive names",
317
151
  },
318
152
  {
319
- good: `const getParameters = defineSchema((v) => v.object({
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 lazy schema parameters and typed execute function",
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"}