claude-ide-bridge 1.1.0
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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/activityLog.d.ts +26 -0
- package/dist/activityLog.js +76 -0
- package/dist/activityLog.js.map +1 -0
- package/dist/bridge.d.ts +19 -0
- package/dist/bridge.js +277 -0
- package/dist/bridge.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +221 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensionClient.d.ts +193 -0
- package/dist/extensionClient.js +698 -0
- package/dist/extensionClient.js.map +1 -0
- package/dist/fileLock.d.ts +12 -0
- package/dist/fileLock.js +30 -0
- package/dist/fileLock.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/lockfile.d.ts +12 -0
- package/dist/lockfile.js +127 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +68 -0
- package/dist/logger.js.map +1 -0
- package/dist/probe.d.ts +22 -0
- package/dist/probe.js +45 -0
- package/dist/probe.js.map +1 -0
- package/dist/server.d.ts +25 -0
- package/dist/server.js +265 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/activityLog.d.ts +39 -0
- package/dist/tools/activityLog.js +49 -0
- package/dist/tools/activityLog.js.map +1 -0
- package/dist/tools/aiComments.d.ts +26 -0
- package/dist/tools/aiComments.js +196 -0
- package/dist/tools/aiComments.js.map +1 -0
- package/dist/tools/bridgeStatus.d.ts +21 -0
- package/dist/tools/bridgeStatus.js +41 -0
- package/dist/tools/bridgeStatus.js.map +1 -0
- package/dist/tools/checkDocumentDirty.d.ts +28 -0
- package/dist/tools/checkDocumentDirty.js +61 -0
- package/dist/tools/checkDocumentDirty.js.map +1 -0
- package/dist/tools/clipboard.d.ts +50 -0
- package/dist/tools/clipboard.js +82 -0
- package/dist/tools/clipboard.js.map +1 -0
- package/dist/tools/closeTabs.d.ts +49 -0
- package/dist/tools/closeTabs.js +77 -0
- package/dist/tools/closeTabs.js.map +1 -0
- package/dist/tools/debug.d.ts +154 -0
- package/dist/tools/debug.js +248 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/decorations.d.ts +92 -0
- package/dist/tools/decorations.js +150 -0
- package/dist/tools/decorations.js.map +1 -0
- package/dist/tools/diffDebugger.d.ts +62 -0
- package/dist/tools/diffDebugger.js +245 -0
- package/dist/tools/diffDebugger.js.map +1 -0
- package/dist/tools/editText.d.ts +80 -0
- package/dist/tools/editText.js +274 -0
- package/dist/tools/editText.js.map +1 -0
- package/dist/tools/fileOperations.d.ts +111 -0
- package/dist/tools/fileOperations.js +280 -0
- package/dist/tools/fileOperations.js.map +1 -0
- package/dist/tools/fileWatcher.d.ts +54 -0
- package/dist/tools/fileWatcher.js +100 -0
- package/dist/tools/fileWatcher.js.map +1 -0
- package/dist/tools/findFiles.d.ts +31 -0
- package/dist/tools/findFiles.js +119 -0
- package/dist/tools/findFiles.js.map +1 -0
- package/dist/tools/fixAllLintErrors.d.ts +29 -0
- package/dist/tools/fixAllLintErrors.js +114 -0
- package/dist/tools/fixAllLintErrors.js.map +1 -0
- package/dist/tools/flowGuardian.d.ts +61 -0
- package/dist/tools/flowGuardian.js +311 -0
- package/dist/tools/flowGuardian.js.map +1 -0
- package/dist/tools/formatDocument.d.ts +30 -0
- package/dist/tools/formatDocument.js +132 -0
- package/dist/tools/formatDocument.js.map +1 -0
- package/dist/tools/formatFile.d.ts +28 -0
- package/dist/tools/formatFile.js +110 -0
- package/dist/tools/formatFile.js.map +1 -0
- package/dist/tools/getBufferContent.d.ts +38 -0
- package/dist/tools/getBufferContent.js +100 -0
- package/dist/tools/getBufferContent.js.map +1 -0
- package/dist/tools/getCurrentSelection.d.ts +43 -0
- package/dist/tools/getCurrentSelection.js +75 -0
- package/dist/tools/getCurrentSelection.js.map +1 -0
- package/dist/tools/getDiagnostics.d.ts +38 -0
- package/dist/tools/getDiagnostics.js +204 -0
- package/dist/tools/getDiagnostics.js.map +1 -0
- package/dist/tools/getDocumentSymbols.d.ts +27 -0
- package/dist/tools/getDocumentSymbols.js +133 -0
- package/dist/tools/getDocumentSymbols.js.map +1 -0
- package/dist/tools/getFileTree.d.ts +36 -0
- package/dist/tools/getFileTree.js +111 -0
- package/dist/tools/getFileTree.js.map +1 -0
- package/dist/tools/getGitDiff.d.ts +34 -0
- package/dist/tools/getGitDiff.js +57 -0
- package/dist/tools/getGitDiff.js.map +1 -0
- package/dist/tools/getGitLog.d.ts +30 -0
- package/dist/tools/getGitLog.js +65 -0
- package/dist/tools/getGitLog.js.map +1 -0
- package/dist/tools/getGitStatus.d.ts +26 -0
- package/dist/tools/getGitStatus.js +95 -0
- package/dist/tools/getGitStatus.js.map +1 -0
- package/dist/tools/getOpenEditors.d.ts +21 -0
- package/dist/tools/getOpenEditors.js +84 -0
- package/dist/tools/getOpenEditors.js.map +1 -0
- package/dist/tools/getProjectInfo.d.ts +20 -0
- package/dist/tools/getProjectInfo.js +315 -0
- package/dist/tools/getProjectInfo.js.map +1 -0
- package/dist/tools/getToolCapabilities.d.ts +23 -0
- package/dist/tools/getToolCapabilities.js +249 -0
- package/dist/tools/getToolCapabilities.js.map +1 -0
- package/dist/tools/getWorkspaceFolders.d.ts +21 -0
- package/dist/tools/getWorkspaceFolders.js +47 -0
- package/dist/tools/getWorkspaceFolders.js.map +1 -0
- package/dist/tools/gitHistory.d.ts +78 -0
- package/dist/tools/gitHistory.js +151 -0
- package/dist/tools/gitHistory.js.map +1 -0
- package/dist/tools/gitWrite.d.ts +335 -0
- package/dist/tools/gitWrite.js +859 -0
- package/dist/tools/gitWrite.js.map +1 -0
- package/dist/tools/github/actions.d.ts +67 -0
- package/dist/tools/github/actions.js +155 -0
- package/dist/tools/github/actions.js.map +1 -0
- package/dist/tools/github/index.d.ts +4 -0
- package/dist/tools/github/index.js +5 -0
- package/dist/tools/github/index.js.map +1 -0
- package/dist/tools/github/issues.d.ts +140 -0
- package/dist/tools/github/issues.js +279 -0
- package/dist/tools/github/issues.js.map +1 -0
- package/dist/tools/github/pr.d.ts +101 -0
- package/dist/tools/github/pr.js +215 -0
- package/dist/tools/github/pr.js.map +1 -0
- package/dist/tools/github/review.d.ts +101 -0
- package/dist/tools/github/review.js +292 -0
- package/dist/tools/github/review.js.map +1 -0
- package/dist/tools/github/shared.d.ts +4 -0
- package/dist/tools/github/shared.js +12 -0
- package/dist/tools/github/shared.js.map +1 -0
- package/dist/tools/github.d.ts +308 -0
- package/dist/tools/github.js +656 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/hoverAtCursor.d.ts +22 -0
- package/dist/tools/hoverAtCursor.js +51 -0
- package/dist/tools/hoverAtCursor.js.map +1 -0
- package/dist/tools/httpClient.d.ts +83 -0
- package/dist/tools/httpClient.js +335 -0
- package/dist/tools/httpClient.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +246 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/inlayHints.d.ts +38 -0
- package/dist/tools/inlayHints.js +56 -0
- package/dist/tools/inlayHints.js.map +1 -0
- package/dist/tools/linters/biome.d.ts +2 -0
- package/dist/tools/linters/biome.js +44 -0
- package/dist/tools/linters/biome.js.map +1 -0
- package/dist/tools/linters/cargo.d.ts +2 -0
- package/dist/tools/linters/cargo.js +45 -0
- package/dist/tools/linters/cargo.js.map +1 -0
- package/dist/tools/linters/eslint.d.ts +2 -0
- package/dist/tools/linters/eslint.js +59 -0
- package/dist/tools/linters/eslint.js.map +1 -0
- package/dist/tools/linters/govet.d.ts +2 -0
- package/dist/tools/linters/govet.js +37 -0
- package/dist/tools/linters/govet.js.map +1 -0
- package/dist/tools/linters/pyright.d.ts +2 -0
- package/dist/tools/linters/pyright.js +34 -0
- package/dist/tools/linters/pyright.js.map +1 -0
- package/dist/tools/linters/ruff.d.ts +2 -0
- package/dist/tools/linters/ruff.js +30 -0
- package/dist/tools/linters/ruff.js.map +1 -0
- package/dist/tools/linters/types.d.ts +16 -0
- package/dist/tools/linters/types.js +2 -0
- package/dist/tools/linters/types.js.map +1 -0
- package/dist/tools/linters/typescript.d.ts +2 -0
- package/dist/tools/linters/typescript.js +38 -0
- package/dist/tools/linters/typescript.js.map +1 -0
- package/dist/tools/lsp.d.ts +310 -0
- package/dist/tools/lsp.js +684 -0
- package/dist/tools/lsp.js.map +1 -0
- package/dist/tools/notebook.d.ts +95 -0
- package/dist/tools/notebook.js +144 -0
- package/dist/tools/notebook.js.map +1 -0
- package/dist/tools/openDiff.d.ts +41 -0
- package/dist/tools/openDiff.js +116 -0
- package/dist/tools/openDiff.js.map +1 -0
- package/dist/tools/openFile.d.ts +34 -0
- package/dist/tools/openFile.js +102 -0
- package/dist/tools/openFile.js.map +1 -0
- package/dist/tools/organizeImports.d.ts +29 -0
- package/dist/tools/organizeImports.js +64 -0
- package/dist/tools/organizeImports.js.map +1 -0
- package/dist/tools/planPersistence.d.ts +196 -0
- package/dist/tools/planPersistence.js +437 -0
- package/dist/tools/planPersistence.js.map +1 -0
- package/dist/tools/replaceBlock.d.ts +40 -0
- package/dist/tools/replaceBlock.js +105 -0
- package/dist/tools/replaceBlock.js.map +1 -0
- package/dist/tools/runCommand.d.ts +43 -0
- package/dist/tools/runCommand.js +141 -0
- package/dist/tools/runCommand.js.map +1 -0
- package/dist/tools/runTests.d.ts +32 -0
- package/dist/tools/runTests.js +160 -0
- package/dist/tools/runTests.js.map +1 -0
- package/dist/tools/saveDocument.d.ts +28 -0
- package/dist/tools/saveDocument.js +58 -0
- package/dist/tools/saveDocument.js.map +1 -0
- package/dist/tools/searchAndReplace.d.ts +50 -0
- package/dist/tools/searchAndReplace.js +203 -0
- package/dist/tools/searchAndReplace.js.map +1 -0
- package/dist/tools/searchWorkspace.d.ts +52 -0
- package/dist/tools/searchWorkspace.js +159 -0
- package/dist/tools/searchWorkspace.js.map +1 -0
- package/dist/tools/setActiveWorkspaceFolder.d.ts +28 -0
- package/dist/tools/setActiveWorkspaceFolder.js +32 -0
- package/dist/tools/setActiveWorkspaceFolder.js.map +1 -0
- package/dist/tools/tasks.d.ts +56 -0
- package/dist/tools/tasks.js +89 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/terminal.d.ts +241 -0
- package/dist/tools/terminal.js +539 -0
- package/dist/tools/terminal.js.map +1 -0
- package/dist/tools/testRunners/cargoTest.d.ts +2 -0
- package/dist/tools/testRunners/cargoTest.js +123 -0
- package/dist/tools/testRunners/cargoTest.js.map +1 -0
- package/dist/tools/testRunners/goTest.d.ts +2 -0
- package/dist/tools/testRunners/goTest.js +106 -0
- package/dist/tools/testRunners/goTest.js.map +1 -0
- package/dist/tools/testRunners/pytest.d.ts +2 -0
- package/dist/tools/testRunners/pytest.js +133 -0
- package/dist/tools/testRunners/pytest.js.map +1 -0
- package/dist/tools/testRunners/types.d.ts +18 -0
- package/dist/tools/testRunners/types.js +2 -0
- package/dist/tools/testRunners/types.js.map +1 -0
- package/dist/tools/testRunners/vitestJest.d.ts +3 -0
- package/dist/tools/testRunners/vitestJest.js +178 -0
- package/dist/tools/testRunners/vitestJest.js.map +1 -0
- package/dist/tools/typeHierarchy.d.ts +45 -0
- package/dist/tools/typeHierarchy.js +65 -0
- package/dist/tools/typeHierarchy.js.map +1 -0
- package/dist/tools/utils.d.ts +54 -0
- package/dist/tools/utils.js +267 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/vscodeCommands.d.ts +59 -0
- package/dist/tools/vscodeCommands.js +108 -0
- package/dist/tools/vscodeCommands.js.map +1 -0
- package/dist/tools/watchDiagnostics.d.ts +32 -0
- package/dist/tools/watchDiagnostics.js +87 -0
- package/dist/tools/watchDiagnostics.js.map +1 -0
- package/dist/tools/workspaceSettings.d.ts +67 -0
- package/dist/tools/workspaceSettings.js +102 -0
- package/dist/tools/workspaceSettings.js.map +1 -0
- package/dist/tools/workspaceSnapshots.d.ts +174 -0
- package/dist/tools/workspaceSnapshots.js +474 -0
- package/dist/tools/workspaceSnapshots.js.map +1 -0
- package/dist/transport.d.ts +57 -0
- package/dist/transport.js +417 -0
- package/dist/transport.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/wsUtils.d.ts +9 -0
- package/dist/wsUtils.js +54 -0
- package/dist/wsUtils.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { INTERPRETER_COMMANDS } from "../config.js";
|
|
2
|
+
import { execSafe, optionalInt, optionalString, requireString, resolveFilePath, success, truncateOutput, } from "./utils.js";
|
|
3
|
+
const MAX_ARGS = 100;
|
|
4
|
+
const MAX_ARG_LENGTH = 4096;
|
|
5
|
+
/** Flags that allow interpreter commands to execute arbitrary code */
|
|
6
|
+
const DANGEROUS_INTERPRETER_FLAGS = new Set([
|
|
7
|
+
"-e",
|
|
8
|
+
"--eval",
|
|
9
|
+
"-c",
|
|
10
|
+
"--print",
|
|
11
|
+
"-p",
|
|
12
|
+
"--input-type",
|
|
13
|
+
"--import", // Node.js ESM loader
|
|
14
|
+
"--loader", // Custom ESM loader
|
|
15
|
+
"--experimental-loader", // Custom ESM loader (legacy)
|
|
16
|
+
"-m", // Python module execution
|
|
17
|
+
]);
|
|
18
|
+
/** Flags that redirect where commands read config/manifests from */
|
|
19
|
+
const DANGEROUS_PATH_FLAGS = new Set([
|
|
20
|
+
"--prefix",
|
|
21
|
+
"--manifest-path",
|
|
22
|
+
"--config",
|
|
23
|
+
"--rcfile",
|
|
24
|
+
"--require",
|
|
25
|
+
"-r",
|
|
26
|
+
"--userconfig", // npm config redirection
|
|
27
|
+
"--globalconfig", // npm config redirection
|
|
28
|
+
"-f",
|
|
29
|
+
"--makefile", // make Makefile path
|
|
30
|
+
]);
|
|
31
|
+
function validateCommand(command, allowlist) {
|
|
32
|
+
if (command.includes("/") ||
|
|
33
|
+
command.includes("\\") ||
|
|
34
|
+
command.includes("..") ||
|
|
35
|
+
command.includes(" ")) {
|
|
36
|
+
throw new Error(`Invalid command "${command}": must be a simple basename without /, \\, .., or spaces`);
|
|
37
|
+
}
|
|
38
|
+
if (!allowlist.some((entry) => entry.toLowerCase() === command)) {
|
|
39
|
+
throw new Error(`Command "${command}" is not in the allowlist. Use --allow-command ${command} to add it. Run getToolCapabilities to see allowed commands.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function validateArgs(args, command) {
|
|
43
|
+
if (args === undefined || args === null)
|
|
44
|
+
return [];
|
|
45
|
+
if (!Array.isArray(args)) {
|
|
46
|
+
throw new Error("args must be an array of strings");
|
|
47
|
+
}
|
|
48
|
+
if (args.length > MAX_ARGS) {
|
|
49
|
+
throw new Error(`args exceeds maximum length of ${MAX_ARGS}`);
|
|
50
|
+
}
|
|
51
|
+
const isInterpreter = INTERPRETER_COMMANDS.has(command);
|
|
52
|
+
for (let i = 0; i < args.length; i++) {
|
|
53
|
+
const arg = args[i];
|
|
54
|
+
if (typeof arg !== "string") {
|
|
55
|
+
throw new Error(`args[${i}] must be a string`);
|
|
56
|
+
}
|
|
57
|
+
if (arg.length > MAX_ARG_LENGTH) {
|
|
58
|
+
throw new Error(`args[${i}] exceeds maximum length of ${MAX_ARG_LENGTH}`);
|
|
59
|
+
}
|
|
60
|
+
// Block code-execution flags for interpreter commands
|
|
61
|
+
if (isInterpreter && DANGEROUS_INTERPRETER_FLAGS.has(arg)) {
|
|
62
|
+
throw new Error(`Flag "${arg}" is blocked for interpreter command "${command}" — it allows arbitrary code execution`);
|
|
63
|
+
}
|
|
64
|
+
// Block config/path-override flags for all commands
|
|
65
|
+
if (DANGEROUS_PATH_FLAGS.has(arg)) {
|
|
66
|
+
throw new Error(`Flag "${arg}" is blocked — it can redirect command execution outside the workspace`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return args;
|
|
70
|
+
}
|
|
71
|
+
export function createRunCommandTool(workspace, config) {
|
|
72
|
+
return {
|
|
73
|
+
schema: {
|
|
74
|
+
name: "runCommand",
|
|
75
|
+
description: "Execute an allowlisted command in the workspace. Returns stdout, stderr, exit code, and timing information. Commands run without a shell for security.",
|
|
76
|
+
annotations: { destructiveHint: true },
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: {
|
|
80
|
+
command: {
|
|
81
|
+
type: "string",
|
|
82
|
+
description: "Command basename to run (must be in the allowlist, no paths)",
|
|
83
|
+
},
|
|
84
|
+
args: {
|
|
85
|
+
type: "array",
|
|
86
|
+
items: { type: "string" },
|
|
87
|
+
description: "Command arguments",
|
|
88
|
+
},
|
|
89
|
+
cwd: {
|
|
90
|
+
type: "string",
|
|
91
|
+
description: "Working directory for the command (absolute or workspace-relative, default: workspace root)",
|
|
92
|
+
},
|
|
93
|
+
timeout: {
|
|
94
|
+
type: "integer",
|
|
95
|
+
description: `Timeout in milliseconds (default: ${config.commandTimeout}, max: 120000)`,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["command"],
|
|
99
|
+
additionalProperties: false,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
timeoutMs: 300_000,
|
|
103
|
+
handler: async (args, signal) => {
|
|
104
|
+
// Normalize to lowercase before all validation — prevents case-sensitivity bypass
|
|
105
|
+
// on case-insensitive filesystems (macOS HFS+, Windows) where "NODE" resolves to "node"
|
|
106
|
+
const command = requireString(args, "command", 256).toLowerCase();
|
|
107
|
+
validateCommand(command, config.commandAllowlist);
|
|
108
|
+
const cmdArgs = validateArgs(args.args, command);
|
|
109
|
+
const cwdRaw = optionalString(args, "cwd");
|
|
110
|
+
const timeout = optionalInt(args, "timeout", 1000, 120_000) ?? config.commandTimeout;
|
|
111
|
+
const cwd = cwdRaw ? resolveFilePath(cwdRaw, workspace) : workspace;
|
|
112
|
+
const maxBytes = config.maxResultSize * 1024;
|
|
113
|
+
const result = await execSafe(command, cmdArgs, {
|
|
114
|
+
cwd,
|
|
115
|
+
timeout,
|
|
116
|
+
maxBuffer: maxBytes,
|
|
117
|
+
signal,
|
|
118
|
+
});
|
|
119
|
+
const stdoutResult = truncateOutput(result.stdout, maxBytes);
|
|
120
|
+
const stderrResult = truncateOutput(result.stderr, maxBytes);
|
|
121
|
+
const anyTruncated = stdoutResult.truncated || stderrResult.truncated;
|
|
122
|
+
return success({
|
|
123
|
+
exitCode: result.exitCode,
|
|
124
|
+
stdout: stdoutResult.text,
|
|
125
|
+
stderr: stderrResult.text,
|
|
126
|
+
durationMs: result.durationMs,
|
|
127
|
+
timedOut: result.timedOut,
|
|
128
|
+
...(anyTruncated
|
|
129
|
+
? {
|
|
130
|
+
truncated: true,
|
|
131
|
+
stdoutTruncated: stdoutResult.truncated,
|
|
132
|
+
stderrTruncated: stderrResult.truncated,
|
|
133
|
+
maxBytes,
|
|
134
|
+
note: "Output exceeded limit. Redirect to a file (command > out.txt) to capture full output.",
|
|
135
|
+
}
|
|
136
|
+
: {}),
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=runCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../src/tools/runCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ProbeResults } from "../probe.js";
|
|
2
|
+
import type { ProgressFn } from "../transport.js";
|
|
3
|
+
export declare function createRunTestsTool(workspace: string, probes?: ProbeResults): {
|
|
4
|
+
schema: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: "object";
|
|
9
|
+
properties: {
|
|
10
|
+
filter: {
|
|
11
|
+
type: string;
|
|
12
|
+
description: string;
|
|
13
|
+
};
|
|
14
|
+
runner: {
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
};
|
|
18
|
+
noCache: {
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
additionalProperties: false;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
handler(args: Record<string, unknown>, signal?: AbortSignal, progress?: ProgressFn): Promise<{
|
|
27
|
+
content: Array<{
|
|
28
|
+
type: string;
|
|
29
|
+
text: string;
|
|
30
|
+
}>;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { cargoTestRunner } from "./testRunners/cargoTest.js";
|
|
2
|
+
import { goTestRunner } from "./testRunners/goTest.js";
|
|
3
|
+
import { pytestRunner } from "./testRunners/pytest.js";
|
|
4
|
+
import { jestRunner, vitestRunner } from "./testRunners/vitestJest.js";
|
|
5
|
+
import { optionalBool, optionalString, success } from "./utils.js";
|
|
6
|
+
const MAX_CACHE_ENTRIES = 50;
|
|
7
|
+
const ALL_RUNNERS = [
|
|
8
|
+
vitestRunner,
|
|
9
|
+
jestRunner,
|
|
10
|
+
pytestRunner,
|
|
11
|
+
cargoTestRunner,
|
|
12
|
+
goTestRunner,
|
|
13
|
+
];
|
|
14
|
+
export function createRunTestsTool(workspace, probes) {
|
|
15
|
+
const availableRunners = probes
|
|
16
|
+
? ALL_RUNNERS.filter((r) => r.detect(workspace, probes))
|
|
17
|
+
: [];
|
|
18
|
+
const caches = new Map();
|
|
19
|
+
const runningPromises = new Map();
|
|
20
|
+
const runnerErrors = new Map();
|
|
21
|
+
async function runRunner(runner, filter, signal) {
|
|
22
|
+
const cacheKey = `${runner.name}:${filter ?? ""}`;
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const cached = caches.get(cacheKey);
|
|
25
|
+
if (cached && now - cached.timestamp < runner.cacheTtl) {
|
|
26
|
+
return cached.data;
|
|
27
|
+
}
|
|
28
|
+
let running = runningPromises.get(cacheKey);
|
|
29
|
+
if (!running) {
|
|
30
|
+
running = runner
|
|
31
|
+
.run(workspace, filter, signal)
|
|
32
|
+
.then((data) => {
|
|
33
|
+
// Evict oldest entry if cache is full
|
|
34
|
+
if (caches.size >= MAX_CACHE_ENTRIES) {
|
|
35
|
+
const oldestKey = caches.keys().next().value;
|
|
36
|
+
if (oldestKey)
|
|
37
|
+
caches.delete(oldestKey);
|
|
38
|
+
}
|
|
39
|
+
caches.set(cacheKey, { data, timestamp: Date.now() });
|
|
40
|
+
// Clear any previous error for this runner on success
|
|
41
|
+
runnerErrors.delete(runner.name);
|
|
42
|
+
return data;
|
|
43
|
+
})
|
|
44
|
+
.catch((err) => {
|
|
45
|
+
if (!(err instanceof Error) || err.name !== "AbortError") {
|
|
46
|
+
caches.set(cacheKey, { data: [], timestamp: Date.now() });
|
|
47
|
+
runnerErrors.set(runner.name, err instanceof Error ? err.message : String(err));
|
|
48
|
+
}
|
|
49
|
+
return [];
|
|
50
|
+
})
|
|
51
|
+
.finally(() => {
|
|
52
|
+
runningPromises.delete(cacheKey);
|
|
53
|
+
});
|
|
54
|
+
runningPromises.set(cacheKey, running);
|
|
55
|
+
}
|
|
56
|
+
return running;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
schema: {
|
|
60
|
+
name: "runTests",
|
|
61
|
+
description: "Run tests using auto-detected frameworks (Vitest, Jest, Pytest, Cargo test, Go test). Returns structured results with pass/fail status, failure messages, and file:line locations for correlation with code changes. Results are cached per runner (30s TTL) — use noCache: true after code changes to get fresh results.",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
filter: {
|
|
66
|
+
type: "string",
|
|
67
|
+
description: "Test name pattern or file path to filter which tests run",
|
|
68
|
+
},
|
|
69
|
+
runner: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Specific runner to use (e.g., 'vitest', 'jest', 'pytest', 'cargo-test', 'go-test'). Default: all detected",
|
|
72
|
+
},
|
|
73
|
+
noCache: {
|
|
74
|
+
type: "boolean",
|
|
75
|
+
description: "Skip cache and force a fresh run. Default: false",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
additionalProperties: false,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
async handler(args, signal, progress) {
|
|
82
|
+
progress?.(0, 100);
|
|
83
|
+
const filter = optionalString(args, "filter");
|
|
84
|
+
const runnerName = optionalString(args, "runner");
|
|
85
|
+
const noCache = optionalBool(args, "noCache") ?? false;
|
|
86
|
+
if (availableRunners.length === 0) {
|
|
87
|
+
return success({
|
|
88
|
+
available: false,
|
|
89
|
+
runners: [],
|
|
90
|
+
summary: {
|
|
91
|
+
total: 0,
|
|
92
|
+
passed: 0,
|
|
93
|
+
failed: 0,
|
|
94
|
+
skipped: 0,
|
|
95
|
+
errored: 0,
|
|
96
|
+
durationMs: 0,
|
|
97
|
+
},
|
|
98
|
+
results: [],
|
|
99
|
+
failures: [],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
let runners = availableRunners;
|
|
103
|
+
if (runnerName) {
|
|
104
|
+
runners = availableRunners.filter((r) => r.name === runnerName);
|
|
105
|
+
if (runners.length === 0) {
|
|
106
|
+
return success({
|
|
107
|
+
available: true,
|
|
108
|
+
runners: availableRunners.map((r) => r.name),
|
|
109
|
+
error: `Runner '${runnerName}' not found. Available: ${availableRunners.map((r) => r.name).join(", ")}`,
|
|
110
|
+
summary: {
|
|
111
|
+
total: 0,
|
|
112
|
+
passed: 0,
|
|
113
|
+
failed: 0,
|
|
114
|
+
skipped: 0,
|
|
115
|
+
errored: 0,
|
|
116
|
+
durationMs: 0,
|
|
117
|
+
},
|
|
118
|
+
results: [],
|
|
119
|
+
failures: [],
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (noCache) {
|
|
124
|
+
for (const r of runners) {
|
|
125
|
+
const key = `${r.name}:${filter ?? ""}`;
|
|
126
|
+
caches.delete(key);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const startTime = Date.now();
|
|
130
|
+
const allResults = await Promise.all(runners.map((r) => runRunner(r, filter, signal)));
|
|
131
|
+
const results = allResults.flat();
|
|
132
|
+
const durationMs = Date.now() - startTime;
|
|
133
|
+
const summary = {
|
|
134
|
+
total: results.length,
|
|
135
|
+
passed: results.filter((r) => r.status === "passed").length,
|
|
136
|
+
failed: results.filter((r) => r.status === "failed").length,
|
|
137
|
+
skipped: results.filter((r) => r.status === "skipped").length,
|
|
138
|
+
errored: results.filter((r) => r.status === "errored").length,
|
|
139
|
+
durationMs,
|
|
140
|
+
};
|
|
141
|
+
// Collect any runner errors from this execution
|
|
142
|
+
const errors = {};
|
|
143
|
+
for (const r of runners) {
|
|
144
|
+
const err = runnerErrors.get(r.name);
|
|
145
|
+
if (err)
|
|
146
|
+
errors[r.name] = err;
|
|
147
|
+
}
|
|
148
|
+
progress?.(100, 100);
|
|
149
|
+
return success({
|
|
150
|
+
available: true,
|
|
151
|
+
runners: runners.map((r) => r.name),
|
|
152
|
+
summary,
|
|
153
|
+
results,
|
|
154
|
+
failures: results.filter((r) => r.status === "failed" || r.status === "errored"),
|
|
155
|
+
...(Object.keys(errors).length > 0 && { runnerErrors: errors }),
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=runTests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runTests.js","sourceRoot":"","sources":["../../src/tools/runTests.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ExtensionClient } from "../extensionClient.js";
|
|
2
|
+
export declare function createSaveDocumentTool(workspace: string, extensionClient?: ExtensionClient): {
|
|
3
|
+
schema: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
annotations: {
|
|
7
|
+
destructiveHint: boolean;
|
|
8
|
+
};
|
|
9
|
+
inputSchema: {
|
|
10
|
+
$schema: string;
|
|
11
|
+
type: string;
|
|
12
|
+
additionalProperties: boolean;
|
|
13
|
+
required: string[];
|
|
14
|
+
properties: {
|
|
15
|
+
filePath: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
handler(args: Record<string, unknown>): Promise<{
|
|
23
|
+
content: Array<{
|
|
24
|
+
type: string;
|
|
25
|
+
text: string;
|
|
26
|
+
}>;
|
|
27
|
+
}>;
|
|
28
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ExtensionTimeoutError, } from "../extensionClient.js";
|
|
2
|
+
import { requireString, resolveFilePath, success } from "./utils.js";
|
|
3
|
+
export function createSaveDocumentTool(workspace, extensionClient) {
|
|
4
|
+
return {
|
|
5
|
+
schema: {
|
|
6
|
+
name: "saveDocument",
|
|
7
|
+
description: "Save a document with unsaved changes. Uses VS Code's real buffer save when the extension is connected (ensures editor state matches disk). Without the extension, this is a no-op — edits applied via editText are already written directly to disk.",
|
|
8
|
+
annotations: { destructiveHint: true },
|
|
9
|
+
inputSchema: {
|
|
10
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
11
|
+
type: "object",
|
|
12
|
+
additionalProperties: false,
|
|
13
|
+
required: ["filePath"],
|
|
14
|
+
properties: {
|
|
15
|
+
filePath: { type: "string", description: "Path to the file to save" },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
async handler(args) {
|
|
20
|
+
const rawPath = requireString(args, "filePath");
|
|
21
|
+
const filePath = resolveFilePath(rawPath, workspace);
|
|
22
|
+
// Use extension for real buffer flush when available
|
|
23
|
+
if (extensionClient?.isConnected()) {
|
|
24
|
+
try {
|
|
25
|
+
const saved = await extensionClient.saveFile(filePath);
|
|
26
|
+
if (saved) {
|
|
27
|
+
return success({
|
|
28
|
+
success: true,
|
|
29
|
+
filePath,
|
|
30
|
+
saved: true,
|
|
31
|
+
source: "vscode-buffer",
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// false — file not open in editor (already on disk from editText or never opened)
|
|
35
|
+
return success({
|
|
36
|
+
success: true,
|
|
37
|
+
filePath,
|
|
38
|
+
saved: false,
|
|
39
|
+
message: "File is not open in VS Code editor — content is already persisted to disk",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (!(err instanceof ExtensionTimeoutError))
|
|
44
|
+
throw err;
|
|
45
|
+
// Timeout — fall through to no-op response
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Without the extension, editText already writes directly to disk
|
|
49
|
+
return success({
|
|
50
|
+
success: true,
|
|
51
|
+
filePath,
|
|
52
|
+
saved: false,
|
|
53
|
+
message: "Extension not connected — edits are written directly to disk by editText; no buffer flush needed",
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=saveDocument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saveDocument.js","sourceRoot":"","sources":["../../src/tools/saveDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,eAAiC;IAEjC,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,cAAc;YACpB,WAAW,EACT,sPAAsP;YACxP,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;YACtC,WAAW,EAAE;gBACX,OAAO,EAAE,yCAAyC;gBAClD,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,QAAQ,EAAE,CAAC,UAAU,CAAC;gBACtB,UAAU,EAAE;oBACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;iBACtE;aACF;SACF;QAED,KAAK,CAAC,OAAO,CAAC,IAA6B;YACzC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAErD,qDAAqD;YACrD,IAAI,eAAe,EAAE,WAAW,EAAE,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBACvD,IAAI,KAAK,EAAE,CAAC;wBACV,OAAO,OAAO,CAAC;4BACb,OAAO,EAAE,IAAI;4BACb,QAAQ;4BACR,KAAK,EAAE,IAAI;4BACX,MAAM,EAAE,eAAe;yBACxB,CAAC,CAAC;oBACL,CAAC;oBACD,kFAAkF;oBAClF,OAAO,OAAO,CAAC;wBACb,OAAO,EAAE,IAAI;wBACb,QAAQ;wBACR,KAAK,EAAE,KAAK;wBACZ,OAAO,EACL,2EAA2E;qBAC9E,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,CAAC,GAAG,YAAY,qBAAqB,CAAC;wBAAE,MAAM,GAAG,CAAC;oBACvD,2CAA2C;gBAC7C,CAAC;YACH,CAAC;YAED,kEAAkE;YAClE,OAAO,OAAO,CAAC;gBACb,OAAO,EAAE,IAAI;gBACb,QAAQ;gBACR,KAAK,EAAE,KAAK;gBACZ,OAAO,EACL,kGAAkG;aACrG,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export declare function createSearchAndReplaceTool(workspace: string): {
|
|
2
|
+
schema: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
annotations: {
|
|
6
|
+
destructiveHint: boolean;
|
|
7
|
+
};
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object";
|
|
10
|
+
properties: {
|
|
11
|
+
pattern: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
replacement: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
glob: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
isRegex: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
caseSensitive: {
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
dryRun: {
|
|
32
|
+
type: string;
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
includeIgnored: {
|
|
36
|
+
type: string;
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
required: string[];
|
|
41
|
+
additionalProperties: false;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
handler: (args: Record<string, unknown>) => Promise<{
|
|
45
|
+
content: Array<{
|
|
46
|
+
type: string;
|
|
47
|
+
text: string;
|
|
48
|
+
}>;
|
|
49
|
+
}>;
|
|
50
|
+
};
|