veryfront 0.1.856 → 0.1.858
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/lint/handler.d.ts.map +1 -1
- package/esm/cli/commands/lint/handler.js +9 -12
- package/esm/cli/commands/mcp/handler.d.ts +3 -0
- package/esm/cli/commands/mcp/handler.d.ts.map +1 -1
- package/esm/cli/commands/mcp/handler.js +4 -4
- package/esm/cli/commands/serve/split-mode.d.ts +1 -0
- package/esm/cli/commands/serve/split-mode.d.ts.map +1 -1
- package/esm/cli/commands/serve/split-mode.js +45 -13
- package/esm/cli/commands/test/command.d.ts.map +1 -1
- package/esm/cli/commands/test/command.js +5 -2
- package/esm/cli/commands/test/handler.d.ts.map +1 -1
- package/esm/cli/commands/test/handler.js +19 -13
- package/esm/cli/mcp/standalone.d.ts +7 -0
- package/esm/cli/mcp/standalone.d.ts.map +1 -1
- package/esm/cli/mcp/standalone.js +9 -10
- package/esm/cli/mcp/tools/context7-tools.d.ts.map +1 -1
- package/esm/cli/mcp/tools/context7-tools.js +3 -3
- package/esm/cli/mcp/tools/helpers.d.ts +8 -0
- package/esm/cli/mcp/tools/helpers.d.ts.map +1 -1
- package/esm/cli/mcp/tools/project-tools.d.ts.map +1 -1
- package/esm/cli/mcp/tools/project-tools.js +33 -3
- package/esm/cli/mcp/tools/run-lint-tool.d.ts +6 -0
- package/esm/cli/mcp/tools/run-lint-tool.d.ts.map +1 -1
- package/esm/cli/mcp/tools/run-lint-tool.js +10 -58
- package/esm/cli/mcp/tools/run-tests-tool.d.ts +6 -0
- package/esm/cli/mcp/tools/run-tests-tool.d.ts.map +1 -1
- package/esm/cli/mcp/tools/run-tests-tool.js +8 -32
- package/esm/cli/scaffold/engine.js +1 -1
- package/esm/cli/shared/animation.d.ts +8 -0
- package/esm/cli/shared/animation.d.ts.map +1 -1
- package/esm/cli/shared/animation.js +2 -7
- package/esm/cli/templates/manifest.js +7 -7
- package/esm/cli/utils/write-run-result.js +4 -4
- package/esm/deno.js +1 -1
- package/esm/src/agent/runtime/constants.js +1 -1
- package/esm/src/agent/runtime/index.js +3 -3
- package/esm/src/agent/runtime/text-generation-runtime-message-converter.d.ts +9 -0
- package/esm/src/agent/runtime/text-generation-runtime-message-converter.d.ts.map +1 -1
- package/esm/src/agent/runtime/text-generation-runtime-message-converter.js +15 -0
- package/esm/src/chat/conversation.d.ts.map +1 -1
- package/esm/src/chat/conversation.js +18 -2
- package/esm/src/platform/compat/process/command.d.ts.map +1 -1
- package/esm/src/platform/compat/process/command.js +4 -3
- package/esm/src/platform/compat/process/env.d.ts.map +1 -1
- package/esm/src/platform/compat/process/env.js +13 -9
- package/esm/src/platform/compat/process/lifecycle.d.ts.map +1 -1
- package/esm/src/platform/compat/process/lifecycle.js +55 -37
- package/esm/src/platform/compat/process/runtime-process.d.ts.map +1 -1
- package/esm/src/platform/compat/process/runtime-process.js +4 -3
- package/esm/src/platform/compat/runtime.d.ts +2 -0
- package/esm/src/platform/compat/runtime.d.ts.map +1 -1
- package/esm/src/platform/compat/runtime.js +14 -6
- package/esm/src/platform/compat/stdin.d.ts.map +1 -1
- package/esm/src/platform/compat/stdin.js +17 -13
- 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":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/lint/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/lint/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAMxD,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBxE"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { exitProcess } from "../../utils/index.js";
|
|
2
|
+
import { runCommand } from "../../../src/platform/index.js";
|
|
2
3
|
import { createSuccessEnvelope, isJsonMode, outputJson } from "../../shared/json-output.js";
|
|
3
4
|
import { parseLintJsonOutput } from "./command.js";
|
|
4
5
|
export async function handleLintCommand(_args) {
|
|
5
|
-
const
|
|
6
|
+
const result = await runCommand("deno", {
|
|
6
7
|
args: ["lint", "--json"],
|
|
7
|
-
|
|
8
|
-
stderr: "piped",
|
|
8
|
+
capture: true,
|
|
9
9
|
});
|
|
10
|
-
const
|
|
11
|
-
const stdout = new TextDecoder().decode(result.stdout);
|
|
10
|
+
const stdout = result.stdout ?? "";
|
|
12
11
|
if (isJsonMode()) {
|
|
13
12
|
const parsed = parseLintJsonOutput(stdout, result.code);
|
|
14
13
|
await outputJson(createSuccessEnvelope("lint", parsed));
|
|
@@ -19,15 +18,13 @@ export async function handleLintCommand(_args) {
|
|
|
19
18
|
}
|
|
20
19
|
else {
|
|
21
20
|
// Re-run without --json for human-readable output
|
|
22
|
-
const
|
|
21
|
+
const humanResult = await runCommand("deno", {
|
|
23
22
|
args: ["lint"],
|
|
24
|
-
|
|
25
|
-
stderr: "inherit",
|
|
23
|
+
inherit: true,
|
|
26
24
|
});
|
|
27
|
-
|
|
28
|
-
dntShim.Deno.exit(humanResult.code);
|
|
25
|
+
exitProcess(humanResult.code);
|
|
29
26
|
return;
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
|
-
|
|
29
|
+
exitProcess(result.code);
|
|
33
30
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP command handler
|
|
3
|
+
*/
|
|
1
4
|
import type { ParsedArgs } from "../../shared/types.js";
|
|
2
5
|
export declare const parseMCPArgs: (args: ParsedArgs) => import("../../shared/args.js").SafeParseResult<import("../../../src/extensions/schema/schema-validator.js").InferShape<{
|
|
3
6
|
port: import("../../../src/internal-agents/schema.js").Schema<number | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/mcp/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/mcp/handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAUxD,eAAO,MAAM,YAAY;;GAEvB,CAAC;AAEH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CActE"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP command handler
|
|
3
3
|
*/
|
|
4
|
-
import * as dntShim from "../../../_dnt.shims.js";
|
|
5
4
|
import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
|
|
5
|
+
import { onSignal as registerSignalHandler } from "../../../src/platform/index.js";
|
|
6
6
|
import { createArgParser, parseArgsOrThrow } from "../../shared/args.js";
|
|
7
7
|
const getMCPArgsSchema = defineSchema((v) => v.object({
|
|
8
8
|
port: v.number().optional(),
|
|
@@ -17,11 +17,11 @@ export async function handleMCPCommand(args) {
|
|
|
17
17
|
const mcpServer = createStandaloneMCPServer({ port: data.port });
|
|
18
18
|
// Keep process alive until interrupted, then shut down gracefully
|
|
19
19
|
const { promise, resolve } = Promise.withResolvers();
|
|
20
|
-
const
|
|
20
|
+
const shutdown = () => {
|
|
21
21
|
mcpServer.stop();
|
|
22
22
|
resolve();
|
|
23
23
|
};
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
registerSignalHandler("SIGINT", shutdown);
|
|
25
|
+
registerSignalHandler("SIGTERM", shutdown);
|
|
26
26
|
await promise;
|
|
27
27
|
}
|
|
@@ -5,6 +5,7 @@ interface SplitModeOptions {
|
|
|
5
5
|
binaryPath: string;
|
|
6
6
|
}
|
|
7
7
|
export declare function buildSplitModeEnvForTests(userEnv: Record<string, string>, productionServerPort: number): Record<string, string>;
|
|
8
|
+
export declare function waitForPort(port: number, timeoutMs?: number, attemptTimeoutMs?: number): Promise<boolean>;
|
|
8
9
|
export declare function runSplitMode(options: SplitModeOptions): Promise<void>;
|
|
9
10
|
export {};
|
|
10
11
|
//# sourceMappingURL=split-mode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-mode.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/split-mode.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"split-mode.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/split-mode.ts"],"names":[],"mappings":"AAeA,UAAU,gBAAgB;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA4BD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,oBAAoB,EAAE,MAAM,GAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB;AAwDD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,SAAQ,EACjB,gBAAgB,SAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CASlB;AAwBD,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF3E"}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import * as dntShim from "../../../_dnt.shims.js";
|
|
8
8
|
import { cliLogger } from "../../utils/index.js";
|
|
9
9
|
import { exitProcess } from "../../utils/index.js";
|
|
10
|
+
import { env as getProcessEnv, getEnv, onSignal } from "../../../src/platform/index.js";
|
|
11
|
+
import { getDenoRuntime } from "../../../src/platform/compat/runtime.js";
|
|
10
12
|
import { SERVER_PERMISSIONS } from "../../../src/security/index.js";
|
|
11
13
|
const REQUIRED_ENV_VARS = [
|
|
12
14
|
"VERYFRONT_PROXY_API_BASE_URL",
|
|
@@ -38,7 +40,7 @@ function validateEnvVars() {
|
|
|
38
40
|
const missing = [];
|
|
39
41
|
const env = {};
|
|
40
42
|
for (const name of REQUIRED_ENV_VARS) {
|
|
41
|
-
const value =
|
|
43
|
+
const value = getEnv(name);
|
|
42
44
|
if (!value) {
|
|
43
45
|
missing.push(name);
|
|
44
46
|
}
|
|
@@ -56,26 +58,56 @@ function validateEnvVars() {
|
|
|
56
58
|
}
|
|
57
59
|
return env;
|
|
58
60
|
}
|
|
59
|
-
async function
|
|
61
|
+
async function tryConnectToPort(port, attemptTimeoutMs) {
|
|
62
|
+
const deno = getDenoRuntime();
|
|
63
|
+
if (!deno?.connect) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const connectionPromise = deno.connect({ hostname: "127.0.0.1", port });
|
|
67
|
+
let timeoutId;
|
|
68
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
69
|
+
timeoutId = dntShim.setTimeout(() => resolve("timeout"), attemptTimeoutMs);
|
|
70
|
+
});
|
|
71
|
+
try {
|
|
72
|
+
const result = await Promise.race([connectionPromise, timeoutPromise]);
|
|
73
|
+
if (result === "timeout") {
|
|
74
|
+
connectionPromise.then((conn) => conn.close()).catch(() => { });
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
result.close();
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
if (timeoutId !== undefined) {
|
|
85
|
+
clearTimeout(timeoutId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export async function waitForPort(port, timeoutMs = 10000, attemptTimeoutMs = 500) {
|
|
60
90
|
const start = Date.now();
|
|
61
91
|
while (Date.now() - start < timeoutMs) {
|
|
62
|
-
|
|
63
|
-
const conn = await dntShim.Deno.connect({ hostname: "127.0.0.1", port });
|
|
64
|
-
conn.close();
|
|
92
|
+
if (await tryConnectToPort(port, attemptTimeoutMs)) {
|
|
65
93
|
return true;
|
|
66
94
|
}
|
|
67
|
-
|
|
68
|
-
await new Promise((r) => dntShim.setTimeout(r, 100));
|
|
69
|
-
}
|
|
95
|
+
await new Promise((r) => dntShim.setTimeout(r, 100));
|
|
70
96
|
}
|
|
71
97
|
return false;
|
|
72
98
|
}
|
|
73
|
-
function startProcess(cmd,
|
|
99
|
+
function startProcess(cmd, childEnv, name) {
|
|
74
100
|
cliLogger.info(`Starting ${name}...`);
|
|
75
101
|
const [executable, ...args] = cmd;
|
|
76
|
-
|
|
102
|
+
const deno = getDenoRuntime();
|
|
103
|
+
if (!deno) {
|
|
104
|
+
cliLogger.error("Split mode requires the Deno runtime.");
|
|
105
|
+
exitProcess(1);
|
|
106
|
+
throw new Error("Split mode requires the Deno runtime.");
|
|
107
|
+
}
|
|
108
|
+
return new deno.Command(executable, {
|
|
77
109
|
args,
|
|
78
|
-
env: { ...
|
|
110
|
+
env: { ...getProcessEnv(), ...childEnv },
|
|
79
111
|
stdout: "inherit",
|
|
80
112
|
stderr: "inherit",
|
|
81
113
|
}).spawn();
|
|
@@ -125,8 +157,8 @@ export async function runSplitMode(options) {
|
|
|
125
157
|
shutdownRequested = true;
|
|
126
158
|
shutdown();
|
|
127
159
|
};
|
|
128
|
-
|
|
129
|
-
|
|
160
|
+
onSignal("SIGINT", handleSignal);
|
|
161
|
+
onSignal("SIGTERM", handleSignal);
|
|
130
162
|
// Wait for either process to exit
|
|
131
163
|
const firstExit = await Promise.race([
|
|
132
164
|
productionServerProcess.status.then((status) => ({ name: "production-server", status })),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/test/command.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/test/command.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAoE5E"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export function parseTestOutput(output, exitCode) {
|
|
9
9
|
const lines = output.split("\n");
|
|
10
|
+
const noTestModules = lines.some((line) => line.trim() === "error: No test modules found");
|
|
10
11
|
let passed = 0;
|
|
11
12
|
let failed = 0;
|
|
12
13
|
let skipped = 0;
|
|
@@ -54,10 +55,12 @@ export function parseTestOutput(output, exitCode) {
|
|
|
54
55
|
failures.push({ file, test: testName, error, line });
|
|
55
56
|
}
|
|
56
57
|
}
|
|
58
|
+
const total = passed + failed + skipped;
|
|
59
|
+
const isEmptyNoTestRun = noTestModules && total === 0 && failures.length === 0;
|
|
57
60
|
return {
|
|
58
|
-
success: exitCode === 0,
|
|
61
|
+
success: exitCode === 0 || isEmptyNoTestRun,
|
|
59
62
|
summary: {
|
|
60
|
-
total
|
|
63
|
+
total,
|
|
61
64
|
passed,
|
|
62
65
|
failed,
|
|
63
66
|
skipped,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/test/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/test/handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAyBxD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDvE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
1
|
import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
|
|
3
2
|
import { createArgParser, parseArgsOrThrow } from "../../shared/args.js";
|
|
3
|
+
import { exitProcess } from "../../utils/index.js";
|
|
4
|
+
import { runCommand } from "../../../src/platform/index.js";
|
|
4
5
|
import { createErrorEnvelope, createSuccessEnvelope, isJsonMode, outputJson, } from "../../shared/json-output.js";
|
|
5
6
|
import { parseTestOutput } from "./command.js";
|
|
6
7
|
const getTestArgsSchema = defineSchema((v) => v.object({
|
|
@@ -14,7 +15,7 @@ const parseTestArgs = createArgParser(TestArgsSchema, {
|
|
|
14
15
|
});
|
|
15
16
|
export async function handleTestCommand(args) {
|
|
16
17
|
const opts = parseArgsOrThrow(parseTestArgs, "test", args);
|
|
17
|
-
const
|
|
18
|
+
const result = await runCommand("deno", {
|
|
18
19
|
args: [
|
|
19
20
|
"test",
|
|
20
21
|
"--no-check",
|
|
@@ -24,8 +25,7 @@ export async function handleTestCommand(args) {
|
|
|
24
25
|
...(opts.parallel ? ["--parallel"] : []),
|
|
25
26
|
...(opts.filter ? [`--filter=${opts.filter}`] : []),
|
|
26
27
|
],
|
|
27
|
-
|
|
28
|
-
stderr: "piped",
|
|
28
|
+
capture: true,
|
|
29
29
|
env: {
|
|
30
30
|
VF_DISABLE_LRU_INTERVAL: "1",
|
|
31
31
|
SSR_TRANSFORM_PER_PROJECT_LIMIT: "0",
|
|
@@ -34,12 +34,13 @@ export async function handleTestCommand(args) {
|
|
|
34
34
|
LOG_FORMAT: "text",
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const stderr = new TextDecoder().decode(result.stderr);
|
|
37
|
+
const stdout = result.stdout ?? "";
|
|
38
|
+
const stderr = result.stderr ?? "";
|
|
40
39
|
const fullOutput = stdout + "\n" + stderr;
|
|
40
|
+
const parsed = parseTestOutput(fullOutput, result.code);
|
|
41
|
+
const noTestModules = result.code !== 0 && parsed.success &&
|
|
42
|
+
fullOutput.includes("No test modules found");
|
|
41
43
|
if (isJsonMode()) {
|
|
42
|
-
const parsed = parseTestOutput(fullOutput, result.code);
|
|
43
44
|
if (parsed.success) {
|
|
44
45
|
await outputJson(createSuccessEnvelope("test", parsed));
|
|
45
46
|
}
|
|
@@ -53,10 +54,15 @@ export async function handleTestCommand(args) {
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
else {
|
|
56
|
-
if (
|
|
57
|
-
console.log(
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
if (noTestModules) {
|
|
58
|
+
console.log("No test modules found.");
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (stdout)
|
|
62
|
+
console.log(stdout);
|
|
63
|
+
if (stderr)
|
|
64
|
+
console.error(stderr);
|
|
65
|
+
}
|
|
60
66
|
}
|
|
61
|
-
|
|
67
|
+
exitProcess(parsed.success ? 0 : result.code);
|
|
62
68
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Runs as a separate process (`veryfront mcp`), communicates over stdio.
|
|
5
|
+
* Pulls runtime data from the dev server's Dashboard API over HTTP.
|
|
6
|
+
* Falls back gracefully when the dev server is not running.
|
|
7
|
+
*/
|
|
1
8
|
export interface StandaloneMCPConfig {
|
|
2
9
|
port?: number;
|
|
3
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/standalone.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/standalone.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA8BH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA4B;gBAEnC,MAAM,GAAE,mBAAwB;IAM5C,KAAK,IAAI,IAAI;IAWb,IAAI,IAAI,IAAI;YAME,aAAa;IAW3B,OAAO,CAAC,cAAc;YAgCR,eAAe;IAqB7B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;YAyBb,mBAAmB;IA6CjC,OAAO,CAAC,iBAAiB;YAkBX,gBAAgB;IAwB9B,OAAO,CAAC,WAAW;IAoSnB,OAAO,CAAC,mBAAmB;CA0F5B;AAED,wBAAgB,yBAAyB,CAAC,MAAM,GAAE,mBAAwB,GAAG,mBAAmB,CAI/F"}
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* Pulls runtime data from the dev server's Dashboard API over HTTP.
|
|
6
6
|
* Falls back gracefully when the dev server is not running.
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
9
|
-
import { readTextFile } from "../../src/platform/index.js";
|
|
8
|
+
import { getEnv, readTextFile } from "../../src/platform/index.js";
|
|
10
9
|
import { DevServerClient } from "./dev-server-client.js";
|
|
11
10
|
import { startStdioJsonRpc } from "./stdio.js";
|
|
12
11
|
import { buildInitializeResult, errorResponse, JsonRpcError, JSONRPCRequestSchema, parseError, PromptsGetParamsSchema, ResourcesReadParamsSchema, successResponse, ToolsCallParamsSchema, } from "./jsonrpc.js";
|
|
@@ -355,7 +354,7 @@ export class StandaloneMCPServer {
|
|
|
355
354
|
description: "Run the project's test suite and get structured pass/fail results. " +
|
|
356
355
|
"Returns a summary with total, passed, failed, skipped counts and failure details " +
|
|
357
356
|
"including file path, test name, error message, and line number. " +
|
|
358
|
-
"Do not use for lint checks
|
|
357
|
+
"Do not use for lint checks. Use vf_run_lint instead.",
|
|
359
358
|
inputSchema: {
|
|
360
359
|
type: "object",
|
|
361
360
|
properties: {
|
|
@@ -385,8 +384,8 @@ export class StandaloneMCPServer {
|
|
|
385
384
|
{
|
|
386
385
|
name: "vf_run_lint",
|
|
387
386
|
description: "Run the linter. Returns structured diagnostics with file, line, column, rule code, and message. " +
|
|
388
|
-
"Do not use for test results
|
|
389
|
-
"Do not use for compile/runtime errors
|
|
387
|
+
"Do not use for test results. Use vf_run_tests instead. " +
|
|
388
|
+
"Do not use for compile/runtime errors. Use vf_get_errors instead.",
|
|
390
389
|
inputSchema: {
|
|
391
390
|
type: "object",
|
|
392
391
|
properties: {
|
|
@@ -432,7 +431,7 @@ export class StandaloneMCPServer {
|
|
|
432
431
|
running = true;
|
|
433
432
|
}
|
|
434
433
|
catch {
|
|
435
|
-
// Dev server not running
|
|
434
|
+
// Dev server is not running, so no errors are available.
|
|
436
435
|
}
|
|
437
436
|
return {
|
|
438
437
|
project,
|
|
@@ -447,8 +446,8 @@ export class StandaloneMCPServer {
|
|
|
447
446
|
description: "Deploy a project to an environment via the Veryfront API. " +
|
|
448
447
|
"Creates a release from the specified branch and deploys it to the target environment. " +
|
|
449
448
|
"Requires a valid API token (set VERYFRONT_API_TOKEN or run 'veryfront login'). " +
|
|
450
|
-
"Do not use for local builds
|
|
451
|
-
"Do not use for running tests before deploy
|
|
449
|
+
"Do not use for local builds. Use vf_build instead. " +
|
|
450
|
+
"Do not use for running tests before deploy. Use vf_run_tests instead.",
|
|
452
451
|
inputSchema: {
|
|
453
452
|
type: "object",
|
|
454
453
|
properties: {
|
|
@@ -480,7 +479,7 @@ export class StandaloneMCPServer {
|
|
|
480
479
|
];
|
|
481
480
|
}
|
|
482
481
|
createContext7Tools() {
|
|
483
|
-
const isAvailable = () => Boolean(
|
|
482
|
+
const isAvailable = () => Boolean(getEnv("CONTEXT7_API_KEY"));
|
|
484
483
|
let source;
|
|
485
484
|
const getSource = async () => {
|
|
486
485
|
if (!source) {
|
|
@@ -504,7 +503,7 @@ export class StandaloneMCPServer {
|
|
|
504
503
|
properties: {
|
|
505
504
|
libraryName: {
|
|
506
505
|
type: "string",
|
|
507
|
-
description: "Library name to search for. Use the official name with proper punctuation
|
|
506
|
+
description: "Library name to search for. Use the official name with proper punctuation, for example 'Next.js' not 'nextjs'.",
|
|
508
507
|
},
|
|
509
508
|
query: {
|
|
510
509
|
type: "string",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context7-tools.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/context7-tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context7-tools.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/context7-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAgHzD,eAAO,MAAM,aAAa,EAAE,OAAO,EAAoC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
1
|
import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
|
|
2
|
+
import { getEnv } from "../../../src/platform/index.js";
|
|
3
3
|
import { createContext7ToolSource } from "../../../src/tool/index.js";
|
|
4
4
|
let _source;
|
|
5
5
|
function getSource() {
|
|
@@ -9,7 +9,7 @@ function getSource() {
|
|
|
9
9
|
return _source;
|
|
10
10
|
}
|
|
11
11
|
function isContext7Available() {
|
|
12
|
-
return Boolean(
|
|
12
|
+
return Boolean(getEnv("CONTEXT7_API_KEY"));
|
|
13
13
|
}
|
|
14
14
|
const c7ResolveLibrary = {
|
|
15
15
|
name: "c7_resolve_library",
|
|
@@ -26,7 +26,7 @@ const c7ResolveLibrary = {
|
|
|
26
26
|
inputSchema: lazySchema(defineSchema((v) => v.object({
|
|
27
27
|
libraryName: v
|
|
28
28
|
.string()
|
|
29
|
-
.describe("Library name to search for. Use the official name with proper punctuation
|
|
29
|
+
.describe("Library name to search for. Use the official name with proper punctuation, for example 'Next.js' not 'nextjs'."),
|
|
30
30
|
query: v
|
|
31
31
|
.string()
|
|
32
32
|
.describe("The question or task you need help with. Used to rank results by relevance."),
|
|
@@ -24,6 +24,14 @@ export interface ProjectContext {
|
|
|
24
24
|
components?: string;
|
|
25
25
|
lib?: string;
|
|
26
26
|
ai?: string;
|
|
27
|
+
agents?: string;
|
|
28
|
+
tools?: string;
|
|
29
|
+
workflows?: string;
|
|
30
|
+
tasks?: string;
|
|
31
|
+
prompts?: string;
|
|
32
|
+
resources?: string;
|
|
33
|
+
skills?: string;
|
|
34
|
+
integrations?: string;
|
|
27
35
|
};
|
|
28
36
|
hasAI: boolean;
|
|
29
37
|
integrations: string[];
|
|
@@ -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;
|
|
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;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-tools.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/project-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAK3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAKL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAGf,MAAM,cAAc,CAAC;AAMtB,QAAA,MAAM,kBAAkB;;;GASvB,CAAC;AAGF,KAAK,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC;AAE1E,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,EAAE,CA2B9D,CAAC;AAMF,QAAA,MAAM,yBAAyB;;GAM9B,CAAC;AAGF,KAAK,sBAAsB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"project-tools.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/project-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAK3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAKL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAGf,MAAM,cAAc,CAAC;AAMtB,QAAA,MAAM,kBAAkB;;;GASvB,CAAC;AAGF,KAAK,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC;AAE1E,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,EAAE,CA2B9D,CAAC;AAMF,QAAA,MAAM,yBAAyB;;GAM9B,CAAC;AAGF,KAAK,sBAAsB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAAC;AAyGxF,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,sBAAsB,EAAE,cAAc,CAiC/E,CAAC;AAMF,QAAA,MAAM,wBAAwB;;;GAO7B,CAAC;AAGF,KAAK,qBAAqB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC;AAEtF,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAiBD,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,qBAAqB,EAAE,mBAAmB,CAwDlF,CAAC;AAMF,QAAA,MAAM,yBAAyB;;;GAS9B,CAAC;AAGF,KAAK,sBAAsB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAAC;AAExF,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8ED,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,sBAAsB,EAAE,gBAAgB,EAAE,CAiBnF,CAAC"}
|
|
@@ -41,7 +41,31 @@ const getGetProjectContextInput = defineSchema((v) => v.object({
|
|
|
41
41
|
projectPath: v.string().optional().describe("Project directory (defaults to current working directory)"),
|
|
42
42
|
}));
|
|
43
43
|
const getProjectContextInput = lazySchema(getGetProjectContextInput);
|
|
44
|
-
const STANDARD_DIRS = [
|
|
44
|
+
const STANDARD_DIRS = [
|
|
45
|
+
"app",
|
|
46
|
+
"pages",
|
|
47
|
+
"components",
|
|
48
|
+
"lib",
|
|
49
|
+
"ai",
|
|
50
|
+
"agents",
|
|
51
|
+
"tools",
|
|
52
|
+
"workflows",
|
|
53
|
+
"tasks",
|
|
54
|
+
"prompts",
|
|
55
|
+
"resources",
|
|
56
|
+
"skills",
|
|
57
|
+
"integrations",
|
|
58
|
+
];
|
|
59
|
+
const AI_PRIMITIVE_DIRS = [
|
|
60
|
+
"ai",
|
|
61
|
+
"agents",
|
|
62
|
+
"tools",
|
|
63
|
+
"workflows",
|
|
64
|
+
"tasks",
|
|
65
|
+
"prompts",
|
|
66
|
+
"resources",
|
|
67
|
+
"skills",
|
|
68
|
+
];
|
|
45
69
|
const BUILTIN_AUTH_ROUTES = ["login", "logout", "me", "signup", "register"];
|
|
46
70
|
const FEATURE_PATTERNS = [
|
|
47
71
|
["lib/auth.ts", "auth"],
|
|
@@ -88,6 +112,13 @@ async function detectFeatures(projectDir, hasAI) {
|
|
|
88
112
|
async function hasAgUiRoute(projectDir) {
|
|
89
113
|
return await fileExists(join(projectDir, "app/api/ag-ui/route.ts"));
|
|
90
114
|
}
|
|
115
|
+
async function hasAiPrimitiveDirectory(projectDir) {
|
|
116
|
+
for (const dir of AI_PRIMITIVE_DIRS) {
|
|
117
|
+
if (await directoryExists(join(projectDir, dir)))
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
91
122
|
async function getProjectName(projectDir, fs) {
|
|
92
123
|
try {
|
|
93
124
|
const content = await fs.readTextFile(join(projectDir, "package.json"));
|
|
@@ -117,8 +148,7 @@ export const vfGetProjectContext = {
|
|
|
117
148
|
await scanDirectory(join(projectDir, "app"), "", routes, fs);
|
|
118
149
|
}
|
|
119
150
|
const directories = await detectDirectories(projectDir);
|
|
120
|
-
const hasAI = await
|
|
121
|
-
await hasAgUiRoute(projectDir);
|
|
151
|
+
const hasAI = await hasAiPrimitiveDirectory(projectDir) || await hasAgUiRoute(projectDir);
|
|
122
152
|
const integrations = await detectIntegrations(projectDir, fs);
|
|
123
153
|
const features = await detectFeatures(projectDir, hasAI);
|
|
124
154
|
const name = await getProjectName(projectDir, fs);
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: vf_run_lint
|
|
3
|
+
*
|
|
4
|
+
* Runs the linter via subprocess and returns structured diagnostics.
|
|
5
|
+
* Reuses parseLintJsonOutput from the CLI lint command.
|
|
6
|
+
*/
|
|
1
7
|
import type { InferSchema } from "../../../src/extensions/schema/index.js";
|
|
2
8
|
import type { MCPTool } from "../tools.js";
|
|
3
9
|
import { type LintResult } from "../../commands/lint/command.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-lint-tool.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/run-lint-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-lint-tool.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/run-lint-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAE3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,UAAU,EAAuB,MAAM,gCAAgC,CAAC;AAEtF,QAAA,MAAM,eAAe;;GAMpB,CAAC;AAGF,KAAK,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC;AAEpE,oFAAoF;AACpF,wBAAsB,WAAW,CAC/B,KAAK,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,UAAU,CAAC,CAarB;AAED,eAAO,MAAM,SAAS,EAAE,OAAO,CAAC,YAAY,EAAE,UAAU,CAevD,CAAC"}
|
|
@@ -4,73 +4,25 @@
|
|
|
4
4
|
* Runs the linter via subprocess and returns structured diagnostics.
|
|
5
5
|
* Reuses parseLintJsonOutput from the CLI lint command.
|
|
6
6
|
*/
|
|
7
|
-
import * as dntShim from "../../../_dnt.shims.js";
|
|
8
7
|
import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
|
|
8
|
+
import { runCommand } from "../../../src/platform/index.js";
|
|
9
9
|
import { parseLintJsonOutput } from "../../commands/lint/command.js";
|
|
10
10
|
const getRunLintInput = defineSchema((v) => v.object({
|
|
11
11
|
timeout: v.number().optional().default(120000).describe("Maximum time to wait for lint completion in milliseconds. Defaults to 120000 (2 minutes)."),
|
|
12
12
|
}));
|
|
13
13
|
const runLintInput = lazySchema(getRunLintInput);
|
|
14
|
-
const PROCESS_CLEANUP_TIMEOUT_MS = 1000;
|
|
15
|
-
async function waitForProcessCleanup(outputSettled) {
|
|
16
|
-
let cleanupTimeout;
|
|
17
|
-
try {
|
|
18
|
-
await Promise.race([
|
|
19
|
-
outputSettled,
|
|
20
|
-
new Promise((resolve) => {
|
|
21
|
-
cleanupTimeout = dntShim.setTimeout(resolve, PROCESS_CLEANUP_TIMEOUT_MS);
|
|
22
|
-
dntShim.Deno.unrefTimer(cleanupTimeout);
|
|
23
|
-
}),
|
|
24
|
-
]);
|
|
25
|
-
}
|
|
26
|
-
finally {
|
|
27
|
-
if (cleanupTimeout !== undefined) {
|
|
28
|
-
clearTimeout(cleanupTimeout);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
14
|
/** Spawn deno lint and return structured results. Exported for standalone reuse. */
|
|
33
15
|
export async function executeLint(input = {}) {
|
|
34
|
-
const
|
|
16
|
+
const timeoutMs = input.timeout ?? 120000;
|
|
17
|
+
const result = await runCommand("deno", {
|
|
35
18
|
args: ["lint", "--json"],
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
capture: true,
|
|
20
|
+
timeoutMs,
|
|
38
21
|
});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const outputPromise = child.output();
|
|
42
|
-
const outputSettled = outputPromise.then(() => undefined, () => undefined);
|
|
43
|
-
let timeout;
|
|
44
|
-
try {
|
|
45
|
-
const result = await Promise.race([
|
|
46
|
-
outputPromise,
|
|
47
|
-
new Promise((_, reject) => {
|
|
48
|
-
timeout = dntShim.setTimeout(() => {
|
|
49
|
-
try {
|
|
50
|
-
child.kill();
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// Process may have already exited
|
|
54
|
-
}
|
|
55
|
-
reject(new Error(`Lint execution timed out after ${timeoutMs}ms`));
|
|
56
|
-
}, timeoutMs);
|
|
57
|
-
dntShim.Deno.unrefTimer(timeout);
|
|
58
|
-
}),
|
|
59
|
-
]);
|
|
60
|
-
const stdout = new TextDecoder().decode(result.stdout);
|
|
61
|
-
return parseLintJsonOutput(stdout, result.code);
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
if (error instanceof Error && error.message.includes("timed out")) {
|
|
65
|
-
await waitForProcessCleanup(outputSettled);
|
|
66
|
-
}
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
finally {
|
|
70
|
-
if (timeout !== undefined) {
|
|
71
|
-
clearTimeout(timeout);
|
|
72
|
-
}
|
|
22
|
+
if (result.code === 124) {
|
|
23
|
+
throw new Error(`Lint execution timed out after ${timeoutMs}ms`);
|
|
73
24
|
}
|
|
25
|
+
return parseLintJsonOutput(result.stdout ?? "", result.code);
|
|
74
26
|
}
|
|
75
27
|
export const vfRunLint = {
|
|
76
28
|
name: "vf_run_lint",
|
|
@@ -83,8 +35,8 @@ export const vfRunLint = {
|
|
|
83
35
|
},
|
|
84
36
|
description: "Use this when you need to check for lint issues in the project. " +
|
|
85
37
|
"Returns structured diagnostics with file path, line, column, rule code, and message for each issue. " +
|
|
86
|
-
"Do not use for test results
|
|
87
|
-
"Do not use for compile/runtime errors
|
|
38
|
+
"Do not use for test results. Use vf_run_tests instead. " +
|
|
39
|
+
"Do not use for compile/runtime errors. Use vf_get_errors instead.",
|
|
88
40
|
inputSchema: runLintInput,
|
|
89
41
|
execute: (input) => executeLint(input),
|
|
90
42
|
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: vf_run_tests
|
|
3
|
+
*
|
|
4
|
+
* Runs the project test suite via subprocess and returns structured results.
|
|
5
|
+
* Reuses parseTestOutput from the CLI test command.
|
|
6
|
+
*/
|
|
1
7
|
import type { InferSchema } from "../../../src/extensions/schema/index.js";
|
|
2
8
|
import type { MCPTool } from "../../../src/mcp/index.js";
|
|
3
9
|
import { type TestResult } from "../../commands/test/command.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-tests-tool.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/run-tests-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-tests-tool.d.ts","sourceRoot":"","sources":["../../../../src/cli/mcp/tools/run-tests-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAElF,QAAA,MAAM,gBAAgB;;;;GAYrB,CAAC;AAGF,KAAK,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;AAEtE,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,EAAE,CAUtF;AAED,qDAAqD;AACrD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM3C,CAAC;AAEF,oFAAoF;AACpF,wBAAsB,YAAY,CAChC,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,UAAU,CAAC,CAcrB;AAED,eAAO,MAAM,UAAU,EAAE,OAAO,CAAC,aAAa,EAAE,UAAU,CAgBzD,CAAC"}
|