@veloxts/mcp 0.7.1 → 0.7.3
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/CHANGELOG.md +18 -0
- package/dist/resources/errors.js +12 -21
- package/dist/resources/static-analyzer.js +11 -1
- package/dist/server.js +24 -102
- package/dist/tools/generate.js +31 -61
- package/dist/tools/migrate.js +29 -58
- package/dist/utils/cli.d.ts +16 -0
- package/dist/utils/cli.js +31 -0
- package/dist/utils/project.js +15 -21
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @veloxts/mcp
|
|
2
2
|
|
|
3
|
+
## 0.7.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat(cli): auto-populate Zod schemas from Prisma model fields
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @veloxts/cli@0.7.3
|
|
10
|
+
- @veloxts/router@0.7.3
|
|
11
|
+
- @veloxts/validation@0.7.3
|
|
12
|
+
|
|
13
|
+
## 0.7.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- simplify code for clarity and maintainability
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- @veloxts/core@0.7.2
|
|
20
|
+
|
|
3
21
|
## 0.7.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/resources/errors.js
CHANGED
|
@@ -30,17 +30,23 @@ function getErrorCategory(code) {
|
|
|
30
30
|
return category?.name ?? 'Unknown';
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Convert a catalog error definition to an ErrorInfo
|
|
34
34
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
function toErrorInfo(def) {
|
|
36
|
+
return {
|
|
37
37
|
code: def.code,
|
|
38
38
|
name: def.name,
|
|
39
39
|
message: def.message,
|
|
40
40
|
fix: def.fix,
|
|
41
41
|
docsUrl: def.docsUrl,
|
|
42
42
|
category: getErrorCategory(def.code),
|
|
43
|
-
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get all errors from the catalog
|
|
47
|
+
*/
|
|
48
|
+
export function getErrors() {
|
|
49
|
+
const errors = Object.values(ERROR_CATALOG).map(toErrorInfo);
|
|
44
50
|
const categories = ERROR_CATEGORIES.map((cat) => ({
|
|
45
51
|
prefix: cat.prefix,
|
|
46
52
|
name: cat.name,
|
|
@@ -56,15 +62,7 @@ export function getErrors() {
|
|
|
56
62
|
* Get errors for a specific category
|
|
57
63
|
*/
|
|
58
64
|
export function getErrorsByPrefix(prefix) {
|
|
59
|
-
|
|
60
|
-
return defs.map((def) => ({
|
|
61
|
-
code: def.code,
|
|
62
|
-
name: def.name,
|
|
63
|
-
message: def.message,
|
|
64
|
-
fix: def.fix,
|
|
65
|
-
docsUrl: def.docsUrl,
|
|
66
|
-
category: getErrorCategory(def.code),
|
|
67
|
-
}));
|
|
65
|
+
return getErrorsByCategory(prefix).map(toErrorInfo);
|
|
68
66
|
}
|
|
69
67
|
/**
|
|
70
68
|
* Search errors by keyword
|
|
@@ -76,14 +74,7 @@ export function searchErrors(query) {
|
|
|
76
74
|
def.name.toLowerCase().includes(lowerQuery) ||
|
|
77
75
|
def.message.toLowerCase().includes(lowerQuery) ||
|
|
78
76
|
def.fix?.toLowerCase().includes(lowerQuery))
|
|
79
|
-
.map(
|
|
80
|
-
code: def.code,
|
|
81
|
-
name: def.name,
|
|
82
|
-
message: def.message,
|
|
83
|
-
fix: def.fix,
|
|
84
|
-
docsUrl: def.docsUrl,
|
|
85
|
-
category: getErrorCategory(def.code),
|
|
86
|
-
}));
|
|
77
|
+
.map(toErrorInfo);
|
|
87
78
|
}
|
|
88
79
|
/**
|
|
89
80
|
* Format errors response as text
|
|
@@ -395,7 +395,17 @@ export function formatStaticAnalysisAsText(result) {
|
|
|
395
395
|
lines.push(`## ${namespace}`);
|
|
396
396
|
lines.push('');
|
|
397
397
|
for (const proc of procs) {
|
|
398
|
-
|
|
398
|
+
let type;
|
|
399
|
+
switch (proc.type) {
|
|
400
|
+
case 'query':
|
|
401
|
+
type = 'Q';
|
|
402
|
+
break;
|
|
403
|
+
case 'mutation':
|
|
404
|
+
type = 'M';
|
|
405
|
+
break;
|
|
406
|
+
default:
|
|
407
|
+
type = '?';
|
|
408
|
+
}
|
|
399
409
|
const route = proc.route ? ` -> ${proc.route.method} ${proc.route.path}` : '';
|
|
400
410
|
const guards = proc.hasGuards ? ' [guarded]' : '';
|
|
401
411
|
lines.push(`- [${type}] ${proc.name}${route}${guards}`);
|
package/dist/server.js
CHANGED
|
@@ -105,57 +105,28 @@ export function createVeloxMCPServer(options = {}) {
|
|
|
105
105
|
],
|
|
106
106
|
};
|
|
107
107
|
});
|
|
108
|
+
// Helper to wrap text content as an MCP resource response
|
|
109
|
+
function textResource(uri, text) {
|
|
110
|
+
return { contents: [{ uri, mimeType: 'text/plain', text }] };
|
|
111
|
+
}
|
|
108
112
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
109
113
|
const uri = request.params.uri;
|
|
110
114
|
log(`Reading resource: ${uri}`);
|
|
111
115
|
switch (uri) {
|
|
112
116
|
case 'velox://procedures': {
|
|
113
117
|
const data = await getProcedures(projectRoot);
|
|
114
|
-
return
|
|
115
|
-
contents: [
|
|
116
|
-
{
|
|
117
|
-
uri,
|
|
118
|
-
mimeType: 'text/plain',
|
|
119
|
-
text: formatProceduresAsText(data),
|
|
120
|
-
},
|
|
121
|
-
],
|
|
122
|
-
};
|
|
118
|
+
return textResource(uri, formatProceduresAsText(data));
|
|
123
119
|
}
|
|
124
120
|
case 'velox://routes': {
|
|
125
121
|
const data = await getRoutes(projectRoot);
|
|
126
|
-
return
|
|
127
|
-
contents: [
|
|
128
|
-
{
|
|
129
|
-
uri,
|
|
130
|
-
mimeType: 'text/plain',
|
|
131
|
-
text: formatRoutesAsText(data),
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
};
|
|
122
|
+
return textResource(uri, formatRoutesAsText(data));
|
|
135
123
|
}
|
|
136
124
|
case 'velox://schemas': {
|
|
137
125
|
const data = await getSchemas(projectRoot);
|
|
138
|
-
return
|
|
139
|
-
contents: [
|
|
140
|
-
{
|
|
141
|
-
uri,
|
|
142
|
-
mimeType: 'text/plain',
|
|
143
|
-
text: formatSchemasAsText(data),
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
};
|
|
126
|
+
return textResource(uri, formatSchemasAsText(data));
|
|
147
127
|
}
|
|
148
128
|
case 'velox://errors': {
|
|
149
|
-
|
|
150
|
-
return {
|
|
151
|
-
contents: [
|
|
152
|
-
{
|
|
153
|
-
uri,
|
|
154
|
-
mimeType: 'text/plain',
|
|
155
|
-
text: formatErrorsAsText(data),
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
};
|
|
129
|
+
return textResource(uri, formatErrorsAsText(getErrors()));
|
|
159
130
|
}
|
|
160
131
|
case 'velox://project': {
|
|
161
132
|
const info = await getProjectInfo(projectRoot);
|
|
@@ -177,15 +148,7 @@ export function createVeloxMCPServer(options = {}) {
|
|
|
177
148
|
.filter(Boolean)
|
|
178
149
|
.join('\n')
|
|
179
150
|
: 'No VeloxTS project detected in current directory.';
|
|
180
|
-
return
|
|
181
|
-
contents: [
|
|
182
|
-
{
|
|
183
|
-
uri,
|
|
184
|
-
mimeType: 'text/plain',
|
|
185
|
-
text,
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
};
|
|
151
|
+
return textResource(uri, text);
|
|
189
152
|
}
|
|
190
153
|
case 'velox://auth-context': {
|
|
191
154
|
const text = `# Authentication Context (ctx.user)
|
|
@@ -277,15 +240,7 @@ const fullUser = await getFullUser(ctx);
|
|
|
277
240
|
const orgId = fullUser.organizationId;
|
|
278
241
|
\`\`\`
|
|
279
242
|
`;
|
|
280
|
-
return
|
|
281
|
-
contents: [
|
|
282
|
-
{
|
|
283
|
-
uri,
|
|
284
|
-
mimeType: 'text/plain',
|
|
285
|
-
text,
|
|
286
|
-
},
|
|
287
|
-
],
|
|
288
|
-
};
|
|
243
|
+
return textResource(uri, text);
|
|
289
244
|
}
|
|
290
245
|
default:
|
|
291
246
|
throw new Error(`Unknown resource: ${uri}`);
|
|
@@ -363,21 +318,20 @@ const orgId = fullUser.organizationId;
|
|
|
363
318
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
364
319
|
const { name, arguments: args } = request.params;
|
|
365
320
|
log(`Calling tool: ${name}`);
|
|
321
|
+
// Helper to build a tool response
|
|
322
|
+
function toolResult(text, isError = false) {
|
|
323
|
+
return { content: [{ type: 'text', text }], isError };
|
|
324
|
+
}
|
|
325
|
+
// Helper to format Zod validation errors into a tool error response
|
|
326
|
+
function validationError(toolName, issues) {
|
|
327
|
+
const errors = issues.map((e) => `${e.path.join('.')}: ${e.message}`);
|
|
328
|
+
return toolResult(`Invalid arguments for ${toolName}:\n${errors.join('\n')}`, true);
|
|
329
|
+
}
|
|
366
330
|
switch (name) {
|
|
367
331
|
case 'velox_generate': {
|
|
368
|
-
// Validate arguments with Zod
|
|
369
332
|
const parsed = GenerateArgsSchema.safeParse(args);
|
|
370
333
|
if (!parsed.success) {
|
|
371
|
-
|
|
372
|
-
return {
|
|
373
|
-
content: [
|
|
374
|
-
{
|
|
375
|
-
type: 'text',
|
|
376
|
-
text: `Invalid arguments for velox_generate:\n${errors.join('\n')}`,
|
|
377
|
-
},
|
|
378
|
-
],
|
|
379
|
-
isError: true,
|
|
380
|
-
};
|
|
334
|
+
return validationError('velox_generate', parsed.error.issues);
|
|
381
335
|
}
|
|
382
336
|
const result = await generate({
|
|
383
337
|
type: parsed.data.type,
|
|
@@ -386,30 +340,12 @@ const orgId = fullUser.organizationId;
|
|
|
386
340
|
dryRun: parsed.data.dryRun,
|
|
387
341
|
json: true,
|
|
388
342
|
}, projectRoot);
|
|
389
|
-
return
|
|
390
|
-
content: [
|
|
391
|
-
{
|
|
392
|
-
type: 'text',
|
|
393
|
-
text: formatGenerateResult(result),
|
|
394
|
-
},
|
|
395
|
-
],
|
|
396
|
-
isError: !result.success,
|
|
397
|
-
};
|
|
343
|
+
return toolResult(formatGenerateResult(result), !result.success);
|
|
398
344
|
}
|
|
399
345
|
case 'velox_migrate': {
|
|
400
|
-
// Validate arguments with Zod
|
|
401
346
|
const parsed = MigrateArgsSchema.safeParse(args);
|
|
402
347
|
if (!parsed.success) {
|
|
403
|
-
|
|
404
|
-
return {
|
|
405
|
-
content: [
|
|
406
|
-
{
|
|
407
|
-
type: 'text',
|
|
408
|
-
text: `Invalid arguments for velox_migrate:\n${errors.join('\n')}`,
|
|
409
|
-
},
|
|
410
|
-
],
|
|
411
|
-
isError: true,
|
|
412
|
-
};
|
|
348
|
+
return validationError('velox_migrate', parsed.error.issues);
|
|
413
349
|
}
|
|
414
350
|
const result = await migrate({
|
|
415
351
|
action: parsed.data.action,
|
|
@@ -417,15 +353,7 @@ const orgId = fullUser.organizationId;
|
|
|
417
353
|
dryRun: parsed.data.dryRun,
|
|
418
354
|
json: true,
|
|
419
355
|
}, projectRoot);
|
|
420
|
-
return
|
|
421
|
-
content: [
|
|
422
|
-
{
|
|
423
|
-
type: 'text',
|
|
424
|
-
text: formatMigrateResult(result),
|
|
425
|
-
},
|
|
426
|
-
],
|
|
427
|
-
isError: !result.success,
|
|
428
|
-
};
|
|
356
|
+
return toolResult(formatMigrateResult(result), !result.success);
|
|
429
357
|
}
|
|
430
358
|
default:
|
|
431
359
|
throw new Error(`Unknown tool: ${name}`);
|
|
@@ -436,13 +364,7 @@ const orgId = fullUser.organizationId;
|
|
|
436
364
|
// ===========================================================================
|
|
437
365
|
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
438
366
|
log('Listing prompts');
|
|
439
|
-
|
|
440
|
-
return {
|
|
441
|
-
prompts: prompts.map((p) => ({
|
|
442
|
-
name: p.name,
|
|
443
|
-
description: p.description,
|
|
444
|
-
})),
|
|
445
|
-
};
|
|
367
|
+
return { prompts: listPromptTemplates() };
|
|
446
368
|
});
|
|
447
369
|
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
448
370
|
const { name } = request.params;
|
package/dist/tools/generate.js
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Wraps `velox make` commands for AI tool invocation.
|
|
5
5
|
*/
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
7
6
|
import { z } from 'zod';
|
|
8
|
-
import {
|
|
7
|
+
import { spawnCLI } from '../utils/cli.js';
|
|
9
8
|
import { findProjectRoot } from '../utils/project.js';
|
|
10
9
|
// ============================================================================
|
|
11
10
|
// Output Validation Schemas
|
|
@@ -59,69 +58,40 @@ export async function generate(options, serverProjectRoot) {
|
|
|
59
58
|
};
|
|
60
59
|
}
|
|
61
60
|
const args = buildArgs(options);
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (code === 0) {
|
|
79
|
-
// Try to parse and validate JSON output if requested
|
|
80
|
-
if (options.json) {
|
|
81
|
-
try {
|
|
82
|
-
const jsonData = JSON.parse(stdout);
|
|
83
|
-
const parsed = GenerateOutputSchema.safeParse(jsonData);
|
|
84
|
-
if (parsed.success) {
|
|
85
|
-
resolve({
|
|
86
|
-
success: true,
|
|
87
|
-
type: options.type,
|
|
88
|
-
name: options.name,
|
|
89
|
-
files: parsed.data.files,
|
|
90
|
-
output: stdout,
|
|
91
|
-
});
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
// Invalid JSON structure - fall through to plain output
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
// JSON parse failed - fall through to plain output
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
resolve({
|
|
61
|
+
const result = await spawnCLI(projectRoot, args);
|
|
62
|
+
if (!result.success) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
type: options.type,
|
|
66
|
+
name: options.name,
|
|
67
|
+
error: result.stderr || result.stdout || `Command failed with exit code ${result.code}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Try to parse and validate JSON output if requested
|
|
71
|
+
if (options.json) {
|
|
72
|
+
try {
|
|
73
|
+
const jsonData = JSON.parse(result.stdout);
|
|
74
|
+
const parsed = GenerateOutputSchema.safeParse(jsonData);
|
|
75
|
+
if (parsed.success) {
|
|
76
|
+
return {
|
|
101
77
|
success: true,
|
|
102
78
|
type: options.type,
|
|
103
79
|
name: options.name,
|
|
104
|
-
|
|
105
|
-
|
|
80
|
+
files: parsed.data.files,
|
|
81
|
+
output: result.stdout,
|
|
82
|
+
};
|
|
106
83
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
success: false,
|
|
119
|
-
type: options.type,
|
|
120
|
-
name: options.name,
|
|
121
|
-
error: err.message,
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
});
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// JSON parse failed - fall through to plain output
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
type: options.type,
|
|
92
|
+
name: options.name,
|
|
93
|
+
output: result.stdout,
|
|
94
|
+
};
|
|
125
95
|
}
|
|
126
96
|
/**
|
|
127
97
|
* Generate a procedure
|
package/dist/tools/migrate.js
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Wraps `velox migrate` commands for AI tool invocation.
|
|
5
5
|
*/
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
7
6
|
import { z } from 'zod';
|
|
8
|
-
import {
|
|
7
|
+
import { spawnCLI } from '../utils/cli.js';
|
|
9
8
|
import { findProjectRoot } from '../utils/project.js';
|
|
10
9
|
// ============================================================================
|
|
11
10
|
// Output Validation Schemas
|
|
@@ -58,65 +57,37 @@ export async function migrate(options, serverProjectRoot) {
|
|
|
58
57
|
};
|
|
59
58
|
}
|
|
60
59
|
const args = buildArgs(options);
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
child.on('close', (code) => {
|
|
77
|
-
if (code === 0) {
|
|
78
|
-
// Try to parse and validate JSON output if requested
|
|
79
|
-
if (options.json) {
|
|
80
|
-
try {
|
|
81
|
-
const jsonData = JSON.parse(stdout);
|
|
82
|
-
const parsed = MigrateOutputSchema.safeParse(jsonData);
|
|
83
|
-
if (parsed.success) {
|
|
84
|
-
resolve({
|
|
85
|
-
success: true,
|
|
86
|
-
action: options.action,
|
|
87
|
-
migrations: parsed.data.migrations,
|
|
88
|
-
output: stdout,
|
|
89
|
-
});
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
// Invalid JSON structure - fall through to plain output
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
// JSON parse failed - fall through to plain output
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
resolve({
|
|
60
|
+
const result = await spawnCLI(projectRoot, args);
|
|
61
|
+
if (!result.success) {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
action: options.action,
|
|
65
|
+
error: result.stderr || result.stdout || `Command failed with exit code ${result.code}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Try to parse and validate JSON output if requested
|
|
69
|
+
if (options.json) {
|
|
70
|
+
try {
|
|
71
|
+
const jsonData = JSON.parse(result.stdout);
|
|
72
|
+
const parsed = MigrateOutputSchema.safeParse(jsonData);
|
|
73
|
+
if (parsed.success) {
|
|
74
|
+
return {
|
|
99
75
|
success: true,
|
|
100
76
|
action: options.action,
|
|
101
|
-
|
|
102
|
-
|
|
77
|
+
migrations: parsed.data.migrations,
|
|
78
|
+
output: result.stdout,
|
|
79
|
+
};
|
|
103
80
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
success: false,
|
|
115
|
-
action: options.action,
|
|
116
|
-
error: err.message,
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
});
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// JSON parse failed - fall through to plain output
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
success: true,
|
|
88
|
+
action: options.action,
|
|
89
|
+
output: result.stdout,
|
|
90
|
+
};
|
|
120
91
|
}
|
|
121
92
|
/**
|
|
122
93
|
* Get migration status
|
package/dist/utils/cli.d.ts
CHANGED
|
@@ -25,3 +25,19 @@ export interface ResolvedCLI {
|
|
|
25
25
|
* 5. Fallback to npx @veloxts/cli (slowest, downloads if needed)
|
|
26
26
|
*/
|
|
27
27
|
export declare function resolveVeloxCLI(projectRoot: string, args: string[]): ResolvedCLI;
|
|
28
|
+
/**
|
|
29
|
+
* Result from spawning a CLI command
|
|
30
|
+
*/
|
|
31
|
+
export interface SpawnCLIResult {
|
|
32
|
+
success: boolean;
|
|
33
|
+
stdout: string;
|
|
34
|
+
stderr: string;
|
|
35
|
+
code: number | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Spawn a VeloxTS CLI command and collect its output.
|
|
39
|
+
*
|
|
40
|
+
* Resolves the CLI binary, spawns the process, and returns stdout/stderr.
|
|
41
|
+
* Never rejects - errors are returned in the result.
|
|
42
|
+
*/
|
|
43
|
+
export declare function spawnCLI(projectRoot: string, args: string[]): Promise<SpawnCLIResult>;
|
package/dist/utils/cli.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Utilities for finding and executing the VeloxTS CLI binary.
|
|
5
5
|
*/
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
6
7
|
import { existsSync, readFileSync } from 'node:fs';
|
|
7
8
|
import { join } from 'node:path';
|
|
8
9
|
/**
|
|
@@ -77,3 +78,33 @@ export function resolveVeloxCLI(projectRoot, args) {
|
|
|
77
78
|
isNpx: true,
|
|
78
79
|
};
|
|
79
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Spawn a VeloxTS CLI command and collect its output.
|
|
83
|
+
*
|
|
84
|
+
* Resolves the CLI binary, spawns the process, and returns stdout/stderr.
|
|
85
|
+
* Never rejects - errors are returned in the result.
|
|
86
|
+
*/
|
|
87
|
+
export function spawnCLI(projectRoot, args) {
|
|
88
|
+
const resolved = resolveVeloxCLI(projectRoot, args);
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
const child = spawn(resolved.command, resolved.args, {
|
|
91
|
+
cwd: projectRoot,
|
|
92
|
+
shell: resolved.isNpx,
|
|
93
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
94
|
+
});
|
|
95
|
+
let stdout = '';
|
|
96
|
+
let stderr = '';
|
|
97
|
+
child.stdout?.on('data', (data) => {
|
|
98
|
+
stdout += data.toString();
|
|
99
|
+
});
|
|
100
|
+
child.stderr?.on('data', (data) => {
|
|
101
|
+
stderr += data.toString();
|
|
102
|
+
});
|
|
103
|
+
child.on('close', (code) => {
|
|
104
|
+
resolve({ success: code === 0, stdout, stderr, code });
|
|
105
|
+
});
|
|
106
|
+
child.on('error', (err) => {
|
|
107
|
+
resolve({ success: false, stdout, stderr: err.message, code: null });
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
package/dist/utils/project.js
CHANGED
|
@@ -99,34 +99,28 @@ export async function getProjectInfo(projectRoot) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
|
-
*
|
|
102
|
+
* Resolve a source subdirectory, checking monorepo layout first, then single-package.
|
|
103
103
|
*/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return monorepoProcedures;
|
|
104
|
+
function resolveSourcePath(projectRoot, subdir) {
|
|
105
|
+
const monorepoPath = join(projectRoot, 'apps', 'api', 'src', subdir);
|
|
106
|
+
if (existsSync(monorepoPath)) {
|
|
107
|
+
return monorepoPath;
|
|
109
108
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return singleProcedures;
|
|
109
|
+
const singlePath = join(projectRoot, 'src', subdir);
|
|
110
|
+
if (existsSync(singlePath)) {
|
|
111
|
+
return singlePath;
|
|
114
112
|
}
|
|
115
113
|
return null;
|
|
116
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Get the procedures directory path for a project
|
|
117
|
+
*/
|
|
118
|
+
export function getProceduresPath(projectRoot) {
|
|
119
|
+
return resolveSourcePath(projectRoot, 'procedures');
|
|
120
|
+
}
|
|
117
121
|
/**
|
|
118
122
|
* Get the schemas directory path for a project
|
|
119
123
|
*/
|
|
120
124
|
export function getSchemasPath(projectRoot) {
|
|
121
|
-
|
|
122
|
-
const monorepoSchemas = join(projectRoot, 'apps', 'api', 'src', 'schemas');
|
|
123
|
-
if (existsSync(monorepoSchemas)) {
|
|
124
|
-
return monorepoSchemas;
|
|
125
|
-
}
|
|
126
|
-
// Check single package structure
|
|
127
|
-
const singleSchemas = join(projectRoot, 'src', 'schemas');
|
|
128
|
-
if (existsSync(singleSchemas)) {
|
|
129
|
-
return singleSchemas;
|
|
130
|
-
}
|
|
131
|
-
return null;
|
|
125
|
+
return resolveSourcePath(projectRoot, 'schemas');
|
|
132
126
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/mcp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Model Context Protocol server for VeloxTS - expose project context to AI tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "1.26.0",
|
|
26
26
|
"typescript": "5.9.3",
|
|
27
|
-
"@veloxts/
|
|
28
|
-
"@veloxts/
|
|
29
|
-
"@veloxts/
|
|
27
|
+
"@veloxts/cli": "0.7.3",
|
|
28
|
+
"@veloxts/router": "0.7.3",
|
|
29
|
+
"@veloxts/validation": "0.7.3"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"zod": "^4.3.0"
|