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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,YAAY,EAAE,WAuB1B,CAAC"}
|
|
@@ -8,12 +8,17 @@ export const generateHelp = {
|
|
|
8
8
|
"veryfront generate page about",
|
|
9
9
|
"veryfront generate layout admin",
|
|
10
10
|
"veryfront generate api users/[id]",
|
|
11
|
-
"veryfront generate
|
|
11
|
+
"veryfront generate agent researcher",
|
|
12
|
+
"veryfront generate tool search-docs",
|
|
13
|
+
"veryfront generate workflow content-pipeline",
|
|
14
|
+
"veryfront generate task sync-data",
|
|
15
|
+
"veryfront generate resource docs",
|
|
16
|
+
"veryfront generate skill code-review",
|
|
12
17
|
"veryfront generate integration # Interactive wizard",
|
|
13
18
|
"veryfront generate integration twilio # With name preset",
|
|
14
19
|
],
|
|
15
20
|
notes: [
|
|
16
|
-
"Types: page, layout,
|
|
21
|
+
"Types: page, api, layout, component, tool, agent, prompt, workflow, task, resource, skill, integration",
|
|
17
22
|
"Integration type launches interactive wizard if name not provided",
|
|
18
23
|
],
|
|
19
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate/command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate/command.ts"],"names":[],"mappings":"AAsBA,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAkCf"}
|
|
@@ -1,124 +1,48 @@
|
|
|
1
|
-
import { join } from "../../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
2
1
|
import { getConfig } from "../../../src/config/index.js";
|
|
3
2
|
import { cliLogger } from "../../utils/index.js";
|
|
4
3
|
import { createError, toError } from "../../../src/errors/index.js";
|
|
5
|
-
import { createFileSystem } from "../../../src/platform/index.js";
|
|
6
4
|
import { generateIntegration } from "./integration-generator.js";
|
|
7
|
-
import {
|
|
8
|
-
import { toComponentName, toSlug } from "../../utils/string.js";
|
|
5
|
+
import { isScaffoldType, scaffoldProjectFile } from "../../scaffold/engine.js";
|
|
9
6
|
async function getPreferredRouter(projectDir) {
|
|
10
7
|
try {
|
|
11
8
|
const { runtime } = await import("../../../src/platform/index.js");
|
|
12
9
|
const adapter = await runtime.get();
|
|
13
10
|
const cfg = await getConfig(projectDir, adapter);
|
|
14
11
|
const pref = cfg?.generate?.preferredRouter ?? cfg?.router;
|
|
15
|
-
if (pref === "app-router" || pref === "
|
|
16
|
-
return
|
|
12
|
+
if (pref === "app-router" || pref === "app")
|
|
13
|
+
return "app-router";
|
|
14
|
+
if (pref === "pages-router" || pref === "pages")
|
|
15
|
+
return "pages-router";
|
|
17
16
|
}
|
|
18
17
|
catch {
|
|
19
18
|
cliLogger.debug("Could not load config for generate command, using defaults");
|
|
20
19
|
}
|
|
21
|
-
return "
|
|
20
|
+
return "app-router";
|
|
22
21
|
}
|
|
23
22
|
export async function generateCommand(projectDir, type, name) {
|
|
24
|
-
const fs = createFileSystem();
|
|
25
23
|
const preferred = await getPreferredRouter(projectDir);
|
|
26
|
-
const slug = toSlug(name);
|
|
27
24
|
if (type === "integration") {
|
|
28
25
|
await generateIntegration(projectDir, { name: name || undefined });
|
|
29
26
|
return;
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
await fs.writeTextFile(file, content);
|
|
49
|
-
cliLogger.info(`Created ${file}`);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
case "page": {
|
|
53
|
-
if (preferred === "app-router") {
|
|
54
|
-
const pageDir = join(projectDir, "app", slug || "");
|
|
55
|
-
await ensureDir(pageDir);
|
|
56
|
-
const file = join(pageDir, "page.tsx");
|
|
57
|
-
const title = slug.split("/").pop() || "Page";
|
|
58
|
-
const componentName = toComponentName(title);
|
|
59
|
-
const content = `export default function ${componentName}(){ return <div>${title}</div>; }\n`;
|
|
60
|
-
await fs.writeTextFile(file, content);
|
|
61
|
-
cliLogger.info(`Created ${file}`);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const parts = slug.split("/");
|
|
65
|
-
const subdir = slug.includes("/") ? parts.slice(0, -1).join("/") : "";
|
|
66
|
-
const base = join(projectDir, "pages");
|
|
67
|
-
const targetDir = subdir ? join(base, subdir) : base;
|
|
68
|
-
await ensureDir(targetDir);
|
|
69
|
-
const fname = `${parts.pop() || "index"}.mdx`;
|
|
70
|
-
const file = join(targetDir, fname);
|
|
71
|
-
const title = slug.split("/").pop() || "Page";
|
|
72
|
-
const content = `---\ntitle: ${title}\n---\n\n# ${title}\n\nThis is a new page.\n`;
|
|
73
|
-
await fs.writeTextFile(file, content);
|
|
74
|
-
cliLogger.info(`Created ${file}`);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
case "layout": {
|
|
78
|
-
if (preferred === "app-router") {
|
|
79
|
-
const dir = join(projectDir, "app", slug || "");
|
|
80
|
-
await ensureDir(dir);
|
|
81
|
-
const file = join(dir, "layout.tsx");
|
|
82
|
-
const content = `export default function Layout({ children }: { children: React.ReactNode }){ return (<section>${slug || "root"}{children}</section>); }\n`;
|
|
83
|
-
await fs.writeTextFile(file, content);
|
|
84
|
-
cliLogger.info(`Created ${file}`);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
const dir = join(projectDir, "layouts");
|
|
88
|
-
await ensureDir(dir);
|
|
89
|
-
const file = join(dir, `${slug}.mdx`);
|
|
90
|
-
const componentName = toComponentName(slug);
|
|
91
|
-
const content = `---\nisLayout: true\n---\n\nexport default function ${componentName}({ children }) {\n return (<div className="${slug}-layout"><main>{children}</main></div>);\n}\n`;
|
|
92
|
-
await fs.writeTextFile(file, content);
|
|
93
|
-
cliLogger.info(`Created ${file}`);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
case "api": {
|
|
97
|
-
if (preferred === "app-router") {
|
|
98
|
-
const routeDir = join(projectDir, "app", slug || "");
|
|
99
|
-
await ensureDir(routeDir);
|
|
100
|
-
const file = join(routeDir, "route.ts");
|
|
101
|
-
const content = `export const GET = (_req: Request) => Response.json({ ok: true });\n`;
|
|
102
|
-
await fs.writeTextFile(file, content);
|
|
103
|
-
cliLogger.info(`Created ${file}`);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
const parts = slug.split("/");
|
|
107
|
-
const subdir = slug.includes("/") ? parts.slice(0, -1).join("/") : "";
|
|
108
|
-
const apiBase = join(projectDir, "pages", "api");
|
|
109
|
-
const targetDir = subdir ? join(apiBase, subdir) : apiBase;
|
|
110
|
-
await ensureDir(targetDir);
|
|
111
|
-
const fname = `${parts.pop() || "index"}.ts`;
|
|
112
|
-
const file = join(targetDir, fname);
|
|
113
|
-
const content = `export function GET(_req: Request) {\n return new Response(JSON.stringify({ ok: true }), { headers: { 'content-type': 'application/json' } });\n}\n`;
|
|
114
|
-
await fs.writeTextFile(file, content);
|
|
115
|
-
cliLogger.info(`Created ${file}`);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
default:
|
|
119
|
-
throw toError(createError({
|
|
120
|
-
type: "config",
|
|
121
|
-
message: `Unknown generate type: ${type}`,
|
|
122
|
-
}));
|
|
28
|
+
if (!isScaffoldType(type)) {
|
|
29
|
+
throw toError(createError({
|
|
30
|
+
type: "config",
|
|
31
|
+
message: `Unknown generate type: ${type}`,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
const result = await scaffoldProjectFile({
|
|
35
|
+
projectDir,
|
|
36
|
+
type,
|
|
37
|
+
name,
|
|
38
|
+
router: preferred,
|
|
39
|
+
});
|
|
40
|
+
if (!result.success) {
|
|
41
|
+
throw toError(createError({
|
|
42
|
+
type: "config",
|
|
43
|
+
message: result.message,
|
|
44
|
+
}));
|
|
123
45
|
}
|
|
46
|
+
for (const file of result.files)
|
|
47
|
+
cliLogger.info(`Created ${file.path}`);
|
|
124
48
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { ParsedArgs } from "../../shared/types.js";
|
|
5
5
|
export declare const parseGenerateArgs: (args: ParsedArgs) => import("../../shared/args.js").SafeParseResult<import("../../../src/extensions/schema/schema-validator.js").InferShape<{
|
|
6
|
-
type: import("../../../src/internal-agents/schema.js").Schema<"page" | "api" | "layout" | "
|
|
6
|
+
type: import("../../../src/internal-agents/schema.js").Schema<"prompt" | "page" | "api" | "agent" | "layout" | "resource" | "component" | "task" | "tool" | "integration" | "skill" | "workflow" | undefined>;
|
|
7
7
|
name: import("../../../src/internal-agents/schema.js").Schema<string | undefined>;
|
|
8
8
|
}>>;
|
|
9
9
|
export declare function handleGenerateCommand(args: ParsedArgs): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate/handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate/handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAexD,eAAO,MAAM,iBAAiB;;;GAG5B,CAAC;AAEH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B3E"}
|
|
@@ -6,7 +6,8 @@ import { generateCommand } from "./index.js";
|
|
|
6
6
|
import { showLogo } from "../../utils/index.js";
|
|
7
7
|
import { createArgParser } from "../../shared/args.js";
|
|
8
8
|
import { cwd } from "../../../src/platform/index.js";
|
|
9
|
-
|
|
9
|
+
import { SCAFFOLD_TYPES } from "../../scaffold/engine.js";
|
|
10
|
+
const VALID_TYPES = [...SCAFFOLD_TYPES, "integration"];
|
|
10
11
|
const getGenerateArgsSchema = defineSchema((v) => v.object({
|
|
11
12
|
type: v.enum(VALID_TYPES).optional(),
|
|
12
13
|
name: v.string().optional(),
|
|
@@ -34,7 +34,7 @@ export async function generateIntegration(projectDir, options = {}) {
|
|
|
34
34
|
console.log(green("Integration created successfully!"));
|
|
35
35
|
console.log("");
|
|
36
36
|
console.log("Files created:");
|
|
37
|
-
console.log(` ${cyan("
|
|
37
|
+
console.log(` ${cyan("integrations/" + config.name + "/")} - Integration directory`);
|
|
38
38
|
console.log("");
|
|
39
39
|
console.log("Next steps:");
|
|
40
40
|
console.log(` 1. Add your ${config.envVarPrefix}_* environment variables to .env`);
|
|
@@ -42,7 +42,7 @@ export async function generateIntegration(projectDir, options = {}) {
|
|
|
42
42
|
console.log(` 2. Configure OAuth app in ${config.displayName} developer portal`);
|
|
43
43
|
console.log(` 3. Set callback URL to: /api/auth/${config.name}/callback`);
|
|
44
44
|
}
|
|
45
|
-
console.log(` 4. Customize the generated tools in
|
|
45
|
+
console.log(` 4. Customize the generated tools in integrations/${config.name}/tools/`);
|
|
46
46
|
console.log("");
|
|
47
47
|
}
|
|
48
48
|
async function getInteractiveConfig(options) {
|
|
@@ -103,7 +103,7 @@ async function getInteractiveConfig(options) {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
async function createIntegrationFiles(projectDir, config) {
|
|
106
|
-
const baseDir = join(projectDir, "
|
|
106
|
+
const baseDir = join(projectDir, "integrations", config.name);
|
|
107
107
|
await ensureDir(baseDir);
|
|
108
108
|
await ensureDir(join(baseDir, "lib"));
|
|
109
109
|
await ensureDir(join(baseDir, "tools"));
|
|
@@ -381,7 +381,7 @@ export async function GET(): Promise<Response> {
|
|
|
381
381
|
import {
|
|
382
382
|
exchangeCodeForTokens,
|
|
383
383
|
setTokens,
|
|
384
|
-
} from "../../../../
|
|
384
|
+
} from "../../../../integrations/${config.name}/lib/token-store.ts";
|
|
385
385
|
|
|
386
386
|
const USE_PKCE = ${usePKCELiteral};
|
|
387
387
|
const PKCE_COOKIE_NAME = ${JSON.stringify(pkceCookieName)};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/init-command.ts"],"names":[],"mappings":"AAAA;;;iCAGiC;AAWjC,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"init-command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/init-command.ts"],"names":[],"mappings":"AAAA;;;iCAGiC;AAWjC,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,YAAY,CAAC;AA6PzE;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6arE"}
|
|
@@ -138,6 +138,80 @@ function dedupeEnvVars(envVars) {
|
|
|
138
138
|
return true;
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
|
+
const STRUCTURE_ORDER = [
|
|
142
|
+
"app",
|
|
143
|
+
"pages",
|
|
144
|
+
"agents",
|
|
145
|
+
"tools",
|
|
146
|
+
"workflows",
|
|
147
|
+
"tasks",
|
|
148
|
+
"prompts",
|
|
149
|
+
"resources",
|
|
150
|
+
"skills",
|
|
151
|
+
"components",
|
|
152
|
+
"lib",
|
|
153
|
+
"content",
|
|
154
|
+
"AGENTS.md",
|
|
155
|
+
"README.md",
|
|
156
|
+
"package.json",
|
|
157
|
+
"deno.json",
|
|
158
|
+
"tsconfig.json",
|
|
159
|
+
".env",
|
|
160
|
+
".env.example",
|
|
161
|
+
".gitignore",
|
|
162
|
+
];
|
|
163
|
+
function structureRank(name) {
|
|
164
|
+
const index = STRUCTURE_ORDER.indexOf(name);
|
|
165
|
+
return index === -1 ? STRUCTURE_ORDER.length : index;
|
|
166
|
+
}
|
|
167
|
+
function sortStructureEntries([nameA, nodeA], [nameB, nodeB]) {
|
|
168
|
+
const rankDiff = structureRank(nameA) - structureRank(nameB);
|
|
169
|
+
if (rankDiff !== 0)
|
|
170
|
+
return rankDiff;
|
|
171
|
+
if (nodeA.file !== nodeB.file)
|
|
172
|
+
return nodeA.file ? 1 : -1;
|
|
173
|
+
return nameA.localeCompare(nameB);
|
|
174
|
+
}
|
|
175
|
+
function renderProjectStructure(rootName, paths, maxLines = 22) {
|
|
176
|
+
const root = { file: false, children: new Map() };
|
|
177
|
+
const normalizedPaths = [...new Set(paths)]
|
|
178
|
+
.filter((path) => path && !path.endsWith("/"))
|
|
179
|
+
.sort();
|
|
180
|
+
for (const path of normalizedPaths) {
|
|
181
|
+
const parts = path.split("/").filter(Boolean);
|
|
182
|
+
let current = root;
|
|
183
|
+
for (const [index, part] of parts.entries()) {
|
|
184
|
+
const isFile = index === parts.length - 1;
|
|
185
|
+
let child = current.children.get(part);
|
|
186
|
+
if (!child) {
|
|
187
|
+
child = { file: isFile, children: new Map() };
|
|
188
|
+
current.children.set(part, child);
|
|
189
|
+
}
|
|
190
|
+
if (isFile)
|
|
191
|
+
child.file = true;
|
|
192
|
+
current = child;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const lines = [`${rootName}/`];
|
|
196
|
+
let omitted = 0;
|
|
197
|
+
function walk(node, depth) {
|
|
198
|
+
const entries = [...node.children.entries()].sort(sortStructureEntries);
|
|
199
|
+
for (const [name, child] of entries) {
|
|
200
|
+
if (lines.length >= maxLines) {
|
|
201
|
+
omitted++;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
lines.push(`${" ".repeat(depth)}${name}${child.file ? "" : "/"}`);
|
|
205
|
+
if (!child.file)
|
|
206
|
+
walk(child, depth + 1);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
walk(root, 1);
|
|
210
|
+
if (omitted > 0) {
|
|
211
|
+
lines.push(`${" ".repeat(1)}... ${omitted} more ${omitted === 1 ? "entry" : "entries"}`);
|
|
212
|
+
}
|
|
213
|
+
return lines;
|
|
214
|
+
}
|
|
141
215
|
/**
|
|
142
216
|
* Initializes a new Veryfront project with the specified template
|
|
143
217
|
*/
|
|
@@ -204,7 +278,7 @@ export async function initCommand(options) {
|
|
|
204
278
|
message: `Directory "${projectName}" already exists. Choose a different name or use --force to overwrite.`,
|
|
205
279
|
}));
|
|
206
280
|
}
|
|
207
|
-
const { getTemplate, getTemplateConfig } = await import("../../templates/index.js");
|
|
281
|
+
const { getAiRuleTemplate, getTemplate, getTemplateConfig } = await import("../../templates/index.js");
|
|
208
282
|
let templateFiles = await getTemplate(template);
|
|
209
283
|
const templateConfig = getTemplateConfig(template);
|
|
210
284
|
if (!templateFiles) {
|
|
@@ -213,6 +287,18 @@ export async function initCommand(options) {
|
|
|
213
287
|
message: `Template ${template} not found`,
|
|
214
288
|
}));
|
|
215
289
|
}
|
|
290
|
+
const agentsGuide = getAiRuleTemplate("agents.md");
|
|
291
|
+
if (!agentsGuide) {
|
|
292
|
+
throw toError(createError({
|
|
293
|
+
type: "config",
|
|
294
|
+
message: "Project agent guide template not found",
|
|
295
|
+
}));
|
|
296
|
+
}
|
|
297
|
+
if (!templateFiles.some((file) => file.path === "AGENTS.md")) {
|
|
298
|
+
templateFiles = mergeFiles(templateFiles, [
|
|
299
|
+
{ path: "AGENTS.md", content: agentsGuide },
|
|
300
|
+
]);
|
|
301
|
+
}
|
|
216
302
|
const allEnvVars = templateConfig?.envVars ? [...templateConfig.envVars] : [];
|
|
217
303
|
const featureTips = [];
|
|
218
304
|
let loadedIntegrations = [];
|
|
@@ -274,6 +360,7 @@ export async function initCommand(options) {
|
|
|
274
360
|
await ensureDir(projectDir);
|
|
275
361
|
// Create project files with progress spinner
|
|
276
362
|
const filesSpinner = quiet ? null : createSpinner("Creating project files...");
|
|
363
|
+
const createdPaths = [];
|
|
277
364
|
try {
|
|
278
365
|
for (const file of templateFiles) {
|
|
279
366
|
if (file.path === ".env" || file.path === ".env.example")
|
|
@@ -283,6 +370,7 @@ export async function initCommand(options) {
|
|
|
283
370
|
if (fileDir !== projectDir)
|
|
284
371
|
await ensureDir(fileDir);
|
|
285
372
|
await fs.writeTextFile(filePath, file.content);
|
|
373
|
+
createdPaths.push(file.path);
|
|
286
374
|
logger.debug(`Created file: ${file.path}`);
|
|
287
375
|
}
|
|
288
376
|
// Skip in quiet/TUI mode since local dev uses CDN and package.json can cause hydration issues
|
|
@@ -294,8 +382,10 @@ export async function initCommand(options) {
|
|
|
294
382
|
npmDependencies: integration.config.npmDependencies,
|
|
295
383
|
})),
|
|
296
384
|
});
|
|
385
|
+
createdPaths.push("package.json");
|
|
297
386
|
if (runtime === "deno") {
|
|
298
387
|
await createDenoConfig(projectDir);
|
|
388
|
+
createdPaths.push("deno.json");
|
|
299
389
|
}
|
|
300
390
|
}
|
|
301
391
|
if (allEnvVars.length) {
|
|
@@ -304,8 +394,10 @@ export async function initCommand(options) {
|
|
|
304
394
|
prefilledValues: options.env,
|
|
305
395
|
});
|
|
306
396
|
await fs.writeTextFile(join(projectDir, ".env"), envResult.envContent);
|
|
397
|
+
createdPaths.push(".env");
|
|
307
398
|
logger.debug("Created file: .env");
|
|
308
399
|
await fs.writeTextFile(join(projectDir, ".env.example"), envResult.envExampleContent);
|
|
400
|
+
createdPaths.push(".env.example");
|
|
309
401
|
logger.debug("Created file: .env.example");
|
|
310
402
|
}
|
|
311
403
|
const gitignorePath = join(projectDir, ".gitignore");
|
|
@@ -317,6 +409,7 @@ export async function initCommand(options) {
|
|
|
317
409
|
existingGitignore = undefined;
|
|
318
410
|
}
|
|
319
411
|
await fs.writeTextFile(gitignorePath, generateGitignoreContent(existingGitignore));
|
|
412
|
+
createdPaths.push(".gitignore");
|
|
320
413
|
logger.debug("Updated file: .gitignore");
|
|
321
414
|
filesSpinner?.success("Project files created");
|
|
322
415
|
}
|
|
@@ -422,9 +515,15 @@ export async function initCommand(options) {
|
|
|
422
515
|
}
|
|
423
516
|
localSteps.push(devCommand);
|
|
424
517
|
const displayName = projectName ?? "Project";
|
|
518
|
+
const structureRoot = projectName ?? ".";
|
|
519
|
+
const structureLines = renderProjectStructure(structureRoot, createdPaths);
|
|
425
520
|
const successContent = [
|
|
426
521
|
`${green("✓")} ${displayName} ready!`,
|
|
427
522
|
"",
|
|
523
|
+
`${brand("Project structure")}`,
|
|
524
|
+
...structureLines,
|
|
525
|
+
"",
|
|
526
|
+
`${brand("Next steps")}`,
|
|
428
527
|
...localSteps,
|
|
429
528
|
];
|
|
430
529
|
if (deployedSlug) {
|
|
@@ -26,7 +26,7 @@ export const mcpHelp = {
|
|
|
26
26
|
" • vf_create_project - Create new project from template",
|
|
27
27
|
" • vf_get_errors - Real-time compile/runtime errors",
|
|
28
28
|
" • vf_preview_route - HTTP response without browser",
|
|
29
|
-
" • vf_scaffold - Generate
|
|
29
|
+
" • vf_scaffold - Generate routes, components, and AI primitives",
|
|
30
30
|
" • vf_list_routes - Structured route manifest",
|
|
31
31
|
" • vf_trigger_hmr - Force browser refresh",
|
|
32
32
|
],
|
|
@@ -12,7 +12,7 @@ export const skillsHelp = {
|
|
|
12
12
|
"veryfront skills info scaffold-app",
|
|
13
13
|
"veryfront skills info deploy-safely --json",
|
|
14
14
|
"veryfront skills create my-skill",
|
|
15
|
-
"veryfront skills validate ./my-skill",
|
|
15
|
+
"veryfront skills validate ./skills/my-skill",
|
|
16
16
|
],
|
|
17
17
|
notes: [
|
|
18
18
|
"Subcommands: list (default), info, create, validate",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Skills command
|
|
2
|
+
* Skills command, list and inspect agent skills
|
|
3
3
|
*
|
|
4
4
|
* @module cli/commands/skills
|
|
5
5
|
*/
|
|
@@ -9,7 +9,7 @@ export async function listSkills() {
|
|
|
9
9
|
}
|
|
10
10
|
export async function getSkillInfo(name) {
|
|
11
11
|
const skills = await listAllSkills();
|
|
12
|
-
const found = skills.find((s) => s.
|
|
12
|
+
const found = skills.find((s) => s.metadata.name === name);
|
|
13
13
|
if (found)
|
|
14
14
|
return found;
|
|
15
15
|
// Try loading directly by path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/skills/create.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/skills/create.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAQxD,wBAAsB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCjE"}
|
|
@@ -1,43 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Skills create command
|
|
2
|
+
* Skills create command, scaffold a new skill
|
|
3
3
|
*
|
|
4
4
|
* @module cli/commands/skills/create
|
|
5
5
|
*/
|
|
6
6
|
import * as dntShim from "../../../_dnt.shims.js";
|
|
7
|
+
import { relative } from "../../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
7
8
|
import { createSuccessEnvelope, isJsonMode, outputJson } from "../../shared/json-output.js";
|
|
8
9
|
import { logSuccess } from "../../utils/index.js";
|
|
9
|
-
import {
|
|
10
|
+
import { scaffoldProjectFile } from "../../scaffold/engine.js";
|
|
10
11
|
const VALID_SKILL_NAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
11
|
-
const SKILL_JSON_TEMPLATE = (name) => JSON.stringify({
|
|
12
|
-
name,
|
|
13
|
-
version: "1.0.0",
|
|
14
|
-
description: `${name} skill`,
|
|
15
|
-
requires: {
|
|
16
|
-
cli: [],
|
|
17
|
-
mcp: [],
|
|
18
|
-
},
|
|
19
|
-
inputs: {},
|
|
20
|
-
}, null, 2);
|
|
21
|
-
const SKILL_MD_TEMPLATE = (name) => `# ${name}
|
|
22
|
-
|
|
23
|
-
## Overview
|
|
24
|
-
|
|
25
|
-
Describe what this skill does.
|
|
26
|
-
|
|
27
|
-
## Steps
|
|
28
|
-
|
|
29
|
-
1. **Step 1** — Description
|
|
30
|
-
\`\`\`bash
|
|
31
|
-
veryfront <command> --json
|
|
32
|
-
\`\`\`
|
|
33
|
-
|
|
34
|
-
2. **Step 2** — Description
|
|
35
|
-
|
|
36
|
-
## Error Recovery
|
|
37
|
-
|
|
38
|
-
- If step 1 fails: ...
|
|
39
|
-
- If step 2 fails: ...
|
|
40
|
-
`;
|
|
41
12
|
export async function createSkill(args) {
|
|
42
13
|
const name = args._[2];
|
|
43
14
|
if (!name) {
|
|
@@ -48,18 +19,21 @@ export async function createSkill(args) {
|
|
|
48
19
|
console.error(`Invalid skill name "${name}". Use lowercase letters, numbers, and hyphens (e.g. "my-skill").`);
|
|
49
20
|
dntShim.Deno.exit(1);
|
|
50
21
|
}
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
22
|
+
const projectDir = dntShim.Deno.cwd();
|
|
23
|
+
const result = await scaffoldProjectFile({
|
|
24
|
+
projectDir,
|
|
25
|
+
type: "skill",
|
|
26
|
+
name,
|
|
27
|
+
});
|
|
28
|
+
if (!result.success)
|
|
29
|
+
throw new Error(result.message);
|
|
56
30
|
if (isJsonMode()) {
|
|
57
31
|
await outputJson(createSuccessEnvelope("skills", {
|
|
58
32
|
created: name,
|
|
59
|
-
files:
|
|
33
|
+
files: result.files.map((file) => relative(projectDir, file.path)),
|
|
60
34
|
}));
|
|
61
35
|
return;
|
|
62
36
|
}
|
|
63
|
-
logSuccess(`Created skill "${name}" at
|
|
64
|
-
console.log(` Files:
|
|
37
|
+
logSuccess(`Created skill "${name}" at ./skills/${name}/`);
|
|
38
|
+
console.log(` Files: skills/${name}/SKILL.md`);
|
|
65
39
|
}
|
|
@@ -20,10 +20,10 @@ async function handleSkillList() {
|
|
|
20
20
|
const skills = await listSkills();
|
|
21
21
|
if (isJsonMode()) {
|
|
22
22
|
await outputJson(createSuccessEnvelope("skills", skills.map((s) => ({
|
|
23
|
-
name: s.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
name: s.metadata.name,
|
|
24
|
+
description: s.metadata.description,
|
|
25
|
+
allowedTools: s.metadata.allowedTools,
|
|
26
|
+
directory: s.directory,
|
|
27
27
|
}))));
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
@@ -34,8 +34,10 @@ async function handleSkillList() {
|
|
|
34
34
|
}
|
|
35
35
|
console.log(`\n ${bold("Available Skills")}\n`);
|
|
36
36
|
for (const skill of skills) {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
const version = skill.metadata.metadata?.version;
|
|
38
|
+
const suffix = version ? ` ${dim(`v${version}`)}` : "";
|
|
39
|
+
console.log(` ${bold(skill.metadata.name)}${suffix}`);
|
|
40
|
+
console.log(` ${skill.metadata.description}`);
|
|
39
41
|
}
|
|
40
42
|
console.log();
|
|
41
43
|
}
|
|
@@ -52,21 +54,18 @@ async function handleSkillInfo(args) {
|
|
|
52
54
|
}
|
|
53
55
|
if (isJsonMode()) {
|
|
54
56
|
await outputJson(createSuccessEnvelope("skills", {
|
|
55
|
-
...skill.
|
|
57
|
+
...skill.metadata,
|
|
56
58
|
content: skill.skillMd,
|
|
57
59
|
directory: skill.directory,
|
|
58
60
|
}));
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
if (skill.manifest.requires.mcp?.length) {
|
|
68
|
-
console.log(` ${dim("MCP:")} ${skill.manifest.requires.mcp.join(", ")}`);
|
|
69
|
-
}
|
|
63
|
+
const version = skill.metadata.metadata?.version;
|
|
64
|
+
const suffix = version ? ` ${dim(`v${version}`)}` : "";
|
|
65
|
+
console.log(`\n ${bold(skill.metadata.name)}${suffix}`);
|
|
66
|
+
console.log(` ${skill.metadata.description}\n`);
|
|
67
|
+
if (skill.metadata.allowedTools?.length) {
|
|
68
|
+
console.log(` ${dim("Allowed tools:")} ${skill.metadata.allowedTools.join(", ")}`);
|
|
70
69
|
}
|
|
71
70
|
if (skill.skillMd) {
|
|
72
71
|
console.log(`\n${skill.skillMd}`);
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { ParsedArgs } from "../../shared/types.js";
|
|
2
|
+
interface ValidationIssue {
|
|
3
|
+
severity: "error" | "warning";
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
2
6
|
export declare function validateSkill(args: ParsedArgs): Promise<void>;
|
|
7
|
+
export declare function validateSkillDirectory(dir: string): Promise<ValidationIssue[]>;
|
|
8
|
+
export {};
|
|
3
9
|
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/skills/validate.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/skills/validate.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAOxD,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnE;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAuBpF"}
|