veryfront 0.1.142 → 0.1.144

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 (45) hide show
  1. package/esm/cli/commands/knowledge/command.d.ts.map +1 -1
  2. package/esm/cli/commands/knowledge/command.js +3 -3
  3. package/esm/cli/mcp/server.d.ts +1 -0
  4. package/esm/cli/mcp/server.d.ts.map +1 -1
  5. package/esm/cli/mcp/server.js +11 -6
  6. package/esm/cli/mcp/standalone.d.ts +1 -0
  7. package/esm/cli/mcp/standalone.d.ts.map +1 -1
  8. package/esm/cli/mcp/standalone.js +14 -11
  9. package/esm/cli/shared/config.d.ts.map +1 -1
  10. package/esm/cli/shared/config.js +13 -2
  11. package/esm/cli/templates/manifest.d.ts +484 -484
  12. package/esm/cli/templates/manifest.js +534 -534
  13. package/esm/deno.js +1 -1
  14. package/esm/src/build/embedded/preset.d.ts +10 -0
  15. package/esm/src/build/embedded/preset.d.ts.map +1 -1
  16. package/esm/src/build/embedded/preset.js +23 -11
  17. package/esm/src/mcp/server.d.ts +2 -0
  18. package/esm/src/mcp/server.d.ts.map +1 -1
  19. package/esm/src/mcp/server.js +42 -8
  20. package/esm/src/resource/factory.d.ts.map +1 -1
  21. package/esm/src/resource/factory.js +1 -0
  22. package/esm/src/resource/types.d.ts +2 -0
  23. package/esm/src/resource/types.d.ts.map +1 -1
  24. package/esm/src/server/dev-ui/manifest.d.ts +11 -11
  25. package/esm/src/server/dev-ui/manifest.js +12 -12
  26. package/esm/src/server/services/rsc/endpoints/action-parser.js +1 -1
  27. package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
  28. package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
  29. package/esm/src/utils/version-constant.d.ts +1 -1
  30. package/esm/src/utils/version-constant.js +1 -1
  31. package/package.json +1 -1
  32. package/src/cli/commands/knowledge/command.ts +5 -3
  33. package/src/cli/mcp/server.ts +12 -6
  34. package/src/cli/mcp/standalone.ts +15 -11
  35. package/src/cli/shared/config.ts +14 -2
  36. package/src/cli/templates/manifest.js +534 -534
  37. package/src/deno.js +1 -1
  38. package/src/src/build/embedded/preset.ts +26 -10
  39. package/src/src/mcp/server.ts +52 -8
  40. package/src/src/resource/factory.ts +1 -0
  41. package/src/src/resource/types.ts +2 -0
  42. package/src/src/server/dev-ui/manifest.js +12 -12
  43. package/src/src/server/services/rsc/endpoints/action-parser.ts +1 -1
  44. package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
  45. package/src/src/utils/version-constant.ts +1 -1
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.142",
3
+ "version": "0.1.144",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -59,7 +59,7 @@ export async function buildEmbeddedPreset(
59
59
  adapter,
60
60
  });
61
61
 
62
- await fs.mkdir(dirname(r.filePath), { recursive: true });
62
+ await fs.mkdir(presetDirname(r.filePath), { recursive: true });
63
63
  await fs.writeTextFile(r.filePath, compiled.code);
64
64
 
65
65
  const fileRel = r.filePath.slice(embeddedDir.length + 1).replace(/\\/g, "/");
@@ -93,7 +93,7 @@ export async function buildEmbeddedPreset(
93
93
  target: "es2020",
94
94
  format: "esm",
95
95
  });
96
- const name = basename(srcPath).replace(/\.tsx?$/, ".js");
96
+ const name = presetBasename(srcPath).replace(/\.tsx?$/, ".js");
97
97
  await fs.writeTextFile(join(embeddedDir, "rsc", name), res.code);
98
98
  } catch (e) {
99
99
  logger.warn("embedded: failed to process RSC file", { error: String(e) } as unknown);
@@ -141,16 +141,35 @@ export async function buildEmbeddedPreset(
141
141
  return { manifest };
142
142
  }
143
143
 
144
- function dirname(path: string): string {
144
+ /** @internal exported for testing */
145
+ export function presetDirname(path: string): string {
145
146
  const idx = path.lastIndexOf("/");
146
147
  return idx === -1 ? "" : path.slice(0, idx);
147
148
  }
148
149
 
149
- function basename(path: string): string {
150
+ /** @internal exported for testing */
151
+ export function presetBasename(path: string): string {
150
152
  const idx = path.lastIndexOf("/");
151
153
  return idx === -1 ? path : path.slice(idx + 1);
152
154
  }
153
155
 
156
+ /** @internal — exported for testing */
157
+ export function normalizeAppRoutePath(rel: string): string {
158
+ return rel === "" ? "/" : rel.startsWith("/") ? rel : `/${rel}`;
159
+ }
160
+
161
+ /** @internal — exported for testing */
162
+ export function normalizePageRoutePath(relPath: string): string {
163
+ const withoutExt = relPath.replace(/\.(mdx|md)$/, "");
164
+ const norm = `/${withoutExt}`;
165
+ return norm.replace(/\/+/g, "/") || "/";
166
+ }
167
+
168
+ /** @internal — exported for testing */
169
+ export function isPageFile(name: string): boolean {
170
+ return (name.endsWith(".mdx") || name.endsWith(".md")) && !name.startsWith("_");
171
+ }
172
+
154
173
  async function findOrCreateEntryPath(
155
174
  fs: ReturnType<typeof createFileSystem>,
156
175
  projectDir: string,
@@ -260,7 +279,7 @@ async function discoverAppRoutes(
260
279
  if (!ent.isFile || (ent.name !== "page.mdx" && ent.name !== "page.md")) continue;
261
280
 
262
281
  const routePath = rel.replace(/\/page\.(mdx|md)$/, "").replace(/(^$)/, "/");
263
- const norm = routePath === "" ? "/" : routePath.startsWith("/") ? routePath : `/${routePath}`;
282
+ const norm = normalizeAppRoutePath(routePath);
264
283
 
265
284
  const filePath = join(embeddedDir, routePath === "" ? "app.js" : `app${norm}.js`);
266
285
  results.push({ routePath: norm, filePath, sourcePath: abs });
@@ -295,12 +314,9 @@ async function discoverPagesRoutes(
295
314
  }
296
315
 
297
316
  if (!ent.isFile) continue;
298
- if (!ent.name.endsWith(".mdx") && !ent.name.endsWith(".md")) continue;
299
- if (ent.name.startsWith("_")) continue;
317
+ if (!isPageFile(ent.name)) continue;
300
318
 
301
- const withoutExt = relNext.replace(/\.(mdx|md)$/, "");
302
- const norm = `/${withoutExt}`;
303
- const routePath = norm.replace(/\/+/g, "/") ? norm.replace(/\/+/g, "/") : "/";
319
+ const routePath = normalizePageRoutePath(relNext);
304
320
  const filePath = join(embeddedDir, `pages${routePath}.js`.replace(/\/+/g, "/"));
305
321
  results.push({ routePath, filePath, sourcePath: abs });
306
322
  }
@@ -159,21 +159,25 @@ export class MCPServer {
159
159
  ): Promise<unknown> {
160
160
  switch (method) {
161
161
  case "tools/list":
162
- return this.listTools();
162
+ return this.listTools(params);
163
163
  case "tools/call":
164
164
  return this.callTool(params, context);
165
165
  case "resources/list":
166
- return this.listResources();
166
+ return this.listResources(params);
167
167
  case "resources/read":
168
168
  return this.readResource(params);
169
+ case "resources/templates/list":
170
+ return this.listResourceTemplates(params);
169
171
  case "prompts/list":
170
- return this.listPrompts();
172
+ return this.listPrompts(params);
171
173
  case "prompts/get":
172
174
  return this.getPrompt(params);
173
175
  case "initialize":
174
176
  return this.initialize(params);
175
177
  case "notifications/initialized":
176
178
  return Promise.resolve({});
179
+ case "completion/complete":
180
+ return this.complete(params);
177
181
  default:
178
182
  throw toError(
179
183
  createError({
@@ -204,13 +208,14 @@ export class MCPServer {
204
208
  tools: { listChanged: true },
205
209
  resources: { subscribe: true, listChanged: true },
206
210
  prompts: { listChanged: true },
211
+ completions: {},
207
212
  },
208
213
  instructions:
209
214
  "Veryfront MCP server provides development tools. Use vf_get_errors to check for code errors, vf_get_logs for server logs, vf_scaffold for code generation, and vf_get_project_context for project structure.",
210
215
  });
211
216
  }
212
217
 
213
- private async listTools(): Promise<{ tools: ToolListEntry[] }> {
218
+ private async listTools(_params?: JSONRPCParams): Promise<{ tools: ToolListEntry[] }> {
214
219
  // Sync integration config to API on first tools/list call
215
220
  if (this.integrationLoader && !this.integrationsLoaded) {
216
221
  try {
@@ -287,17 +292,44 @@ export class MCPServer {
287
292
  );
288
293
  }
289
294
 
290
- private listResources(): Promise<{ resources: Array<Record<string, unknown>> }> {
295
+ private listResourceTemplates(
296
+ _params?: JSONRPCParams,
297
+ ): Promise<{ resourceTemplates: Array<Record<string, unknown>> }> {
298
+ const registry = getMCPRegistry();
299
+ const templates: Array<Record<string, unknown>> = [];
300
+
301
+ for (const [id, resource] of registry.resources.entries()) {
302
+ if (/:(\w+)/.test(resource.pattern)) {
303
+ const uriTemplate = resource.pattern.replace(/:(\w+)/g, "{$1}");
304
+ const entry: Record<string, unknown> = {
305
+ uriTemplate,
306
+ name: id,
307
+ description: resource.description,
308
+ mimeType: "application/json",
309
+ };
310
+ if (resource.title) entry.title = resource.title;
311
+ templates.push(entry);
312
+ }
313
+ }
314
+
315
+ return Promise.resolve({ resourceTemplates: templates });
316
+ }
317
+
318
+ private listResources(
319
+ _params?: JSONRPCParams,
320
+ ): Promise<{ resources: Array<Record<string, unknown>> }> {
291
321
  const registry = getMCPRegistry();
292
322
  const resources: Array<Record<string, unknown>> = [];
293
323
 
294
324
  for (const [id, resource] of registry.resources.entries()) {
295
- resources.push({
325
+ const entry: Record<string, unknown> = {
296
326
  uri: resource.pattern,
297
327
  name: id,
298
328
  description: resource.description,
299
329
  mimeType: "application/json",
300
- });
330
+ };
331
+ if (resource.title) entry.title = resource.title;
332
+ resources.push(entry);
301
333
  }
302
334
 
303
335
  return Promise.resolve({ resources });
@@ -348,7 +380,9 @@ export class MCPServer {
348
380
  );
349
381
  }
350
382
 
351
- private listPrompts(): Promise<{ prompts: Array<Record<string, unknown>> }> {
383
+ private listPrompts(
384
+ _params?: JSONRPCParams,
385
+ ): Promise<{ prompts: Array<Record<string, unknown>> }> {
352
386
  const registry = getMCPRegistry();
353
387
  const prompts: Array<Record<string, unknown>> = [];
354
388
 
@@ -401,6 +435,16 @@ export class MCPServer {
401
435
  );
402
436
  }
403
437
 
438
+ private complete(
439
+ _params: JSONRPCParams | undefined,
440
+ ): Promise<{ completion: { values: string[]; total?: number; hasMore: boolean } }> {
441
+ // Stub: returns empty completions for all refs.
442
+ // Real logic will resolve values from resource templates and prompts.
443
+ return Promise.resolve({
444
+ completion: { values: [], total: 0, hasMore: false },
445
+ });
446
+ }
447
+
404
448
  createHTTPHandler(): (request: dntShim.Request) => Promise<dntShim.Response> {
405
449
  return async (request: dntShim.Request) => {
406
450
  const requestOrigin = request.headers.get("Origin");
@@ -19,6 +19,7 @@ export function resource<TParams = unknown, TData = unknown>(
19
19
  id,
20
20
  pattern,
21
21
  description: config.description,
22
+ title: config.title,
22
23
  paramsSchema: config.paramsSchema,
23
24
  load: async (params: TParams): Promise<TData> => {
24
25
  try {
@@ -17,6 +17,7 @@ import type { McpConfig } from "./schemas/index.js";
17
17
  export interface ResourceConfig<TParams = unknown, TData = unknown> {
18
18
  pattern?: string;
19
19
  description: string;
20
+ title?: string;
20
21
  paramsSchema: z.ZodSchema<TParams>;
21
22
  load: (params: TParams) => Promise<TData> | TData;
22
23
  subscribe?: (params: TParams) => AsyncIterable<TData>;
@@ -27,6 +28,7 @@ export interface Resource<TParams = unknown, TData = unknown> {
27
28
  id: string;
28
29
  pattern: string;
29
30
  description: string;
31
+ title?: string;
30
32
  paramsSchema: z.ZodSchema<TParams>;
31
33
  load: (params: TParams) => Promise<TData>;
32
34
  subscribe?: (params: TParams) => AsyncIterable<TData>;