@4onstudios/iris-agent 0.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 +690 -0
- package/dist/api/acp/acpServer.d.ts +23 -0
- package/dist/api/acp/acpServer.js +814 -0
- package/dist/api/acp/index.d.ts +2 -0
- package/dist/api/acp/index.js +2 -0
- package/dist/api/acp/irisClient.d.ts +58 -0
- package/dist/api/acp/irisClient.js +214 -0
- package/dist/api/agent.d.ts +14 -0
- package/dist/api/agent.js +4171 -0
- package/dist/api/backendService.d.ts +4 -0
- package/dist/api/backendService.js +14 -0
- package/dist/api/core/agent/host/AgentContract.d.ts +82 -0
- package/dist/api/core/agent/host/AgentContract.js +1 -0
- package/dist/api/core/agent/host/AgentRegistry.d.ts +24 -0
- package/dist/api/core/agent/host/AgentRegistry.js +125 -0
- package/dist/api/core/agent/host/defaultRegistry.d.ts +15 -0
- package/dist/api/core/agent/host/defaultRegistry.js +46 -0
- package/dist/api/core/agent/host/externalAgentLifecycle.d.ts +65 -0
- package/dist/api/core/agent/host/externalAgentLifecycle.js +117 -0
- package/dist/api/core/agent/host/hostSessionManager.d.ts +111 -0
- package/dist/api/core/agent/host/hostSessionManager.js +352 -0
- package/dist/api/core/agent/host/index.d.ts +5 -0
- package/dist/api/core/agent/host/index.js +5 -0
- package/dist/api/core/agent/index.d.ts +87 -0
- package/dist/api/core/agent/index.js +1024 -0
- package/dist/api/core/agent/publicContracts.d.ts +35 -0
- package/dist/api/core/agent/publicContracts.js +103 -0
- package/dist/api/core/agent/tools/applyDiff.d.ts +51 -0
- package/dist/api/core/agent/tools/applyDiff.js +131 -0
- package/dist/api/core/agent/tools/backgroundTasks.d.ts +240 -0
- package/dist/api/core/agent/tools/backgroundTasks.js +313 -0
- package/dist/api/core/agent/tools/createDirectory.d.ts +43 -0
- package/dist/api/core/agent/tools/createDirectory.js +77 -0
- package/dist/api/core/agent/tools/deleteFile.d.ts +37 -0
- package/dist/api/core/agent/tools/deleteFile.js +66 -0
- package/dist/api/core/agent/tools/editFile.d.ts +73 -0
- package/dist/api/core/agent/tools/editFile.js +173 -0
- package/dist/api/core/agent/tools/executeCommand.d.ts +59 -0
- package/dist/api/core/agent/tools/executeCommand.js +250 -0
- package/dist/api/core/agent/tools/fileContent.d.ts +54 -0
- package/dist/api/core/agent/tools/fileContent.js +227 -0
- package/dist/api/core/agent/tools/findDefinition.d.ts +72 -0
- package/dist/api/core/agent/tools/findDefinition.js +109 -0
- package/dist/api/core/agent/tools/findReferences.d.ts +86 -0
- package/dist/api/core/agent/tools/findReferences.js +135 -0
- package/dist/api/core/agent/tools/formatDocument.d.ts +67 -0
- package/dist/api/core/agent/tools/formatDocument.js +90 -0
- package/dist/api/core/agent/tools/getCodeActions.d.ts +77 -0
- package/dist/api/core/agent/tools/getCodeActions.js +97 -0
- package/dist/api/core/agent/tools/getCodeCompletion.d.ts +77 -0
- package/dist/api/core/agent/tools/getCodeCompletion.js +174 -0
- package/dist/api/core/agent/tools/getCodeContext.d.ts +14 -0
- package/dist/api/core/agent/tools/getCodeContext.js +282 -0
- package/dist/api/core/agent/tools/getSignatureHelp.d.ts +61 -0
- package/dist/api/core/agent/tools/getSignatureHelp.js +85 -0
- package/dist/api/core/agent/tools/getSymbols.d.ts +50 -0
- package/dist/api/core/agent/tools/getSymbols.js +164 -0
- package/dist/api/core/agent/tools/getSymbolsLSP.d.ts +58 -0
- package/dist/api/core/agent/tools/getSymbolsLSP.js +147 -0
- package/dist/api/core/agent/tools/getTypeInfo.d.ts +70 -0
- package/dist/api/core/agent/tools/getTypeInfo.js +84 -0
- package/dist/api/core/agent/tools/getWorkspaceInfo.d.ts +80 -0
- package/dist/api/core/agent/tools/getWorkspaceInfo.js +281 -0
- package/dist/api/core/agent/tools/getWorkspaceSymbols.d.ts +53 -0
- package/dist/api/core/agent/tools/getWorkspaceSymbols.js +97 -0
- package/dist/api/core/agent/tools/grepSearch.d.ts +100 -0
- package/dist/api/core/agent/tools/grepSearch.js +211 -0
- package/dist/api/core/agent/tools/languageModelToolsIntegration.d.ts +13 -0
- package/dist/api/core/agent/tools/languageModelToolsIntegration.js +22 -0
- package/dist/api/core/agent/tools/listDirectory.d.ts +66 -0
- package/dist/api/core/agent/tools/listDirectory.js +161 -0
- package/dist/api/core/agent/tools/mcpTools.d.ts +48 -0
- package/dist/api/core/agent/tools/mcpTools.js +442 -0
- package/dist/api/core/agent/tools/queryKnowledgeGraph.d.ts +120 -0
- package/dist/api/core/agent/tools/queryKnowledgeGraph.js +306 -0
- package/dist/api/core/agent/tools/readFile.d.ts +92 -0
- package/dist/api/core/agent/tools/readFile.js +337 -0
- package/dist/api/core/agent/tools/renameFile.d.ts +49 -0
- package/dist/api/core/agent/tools/renameFile.js +86 -0
- package/dist/api/core/agent/tools/renameSymbol.d.ts +70 -0
- package/dist/api/core/agent/tools/renameSymbol.js +106 -0
- package/dist/api/core/agent/tools/runTerminalCommand.d.ts +72 -0
- package/dist/api/core/agent/tools/runTerminalCommand.js +69 -0
- package/dist/api/core/agent/tools/searchFiles.d.ts +82 -0
- package/dist/api/core/agent/tools/searchFiles.js +280 -0
- package/dist/api/core/agent/tools/terminalAutoApprove.d.ts +3 -0
- package/dist/api/core/agent/tools/terminalAutoApprove.js +676 -0
- package/dist/api/core/agent/tools/treeTraversal.d.ts +60 -0
- package/dist/api/core/agent/tools/treeTraversal.js +217 -0
- package/dist/api/core/agent/tools/webSearch.d.ts +37 -0
- package/dist/api/core/agent/tools/webSearch.js +80 -0
- package/dist/api/core/agent/tools/writeFile.d.ts +59 -0
- package/dist/api/core/agent/tools/writeFile.js +97 -0
- package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.d.ts +12 -0
- package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.js +67 -0
- package/dist/api/core/agent/utils/diffUtils.d.ts +14 -0
- package/dist/api/core/agent/utils/diffUtils.js +39 -0
- package/dist/api/core/agent/utils/environmentSnapshot.d.ts +42 -0
- package/dist/api/core/agent/utils/environmentSnapshot.js +213 -0
- package/dist/api/core/agent/utils/errorRecovery.d.ts +49 -0
- package/dist/api/core/agent/utils/errorRecovery.js +229 -0
- package/dist/api/core/agent/utils/multimodalTokenLimiter.d.ts +8 -0
- package/dist/api/core/agent/utils/multimodalTokenLimiter.js +238 -0
- package/dist/api/core/agent/utils/openRouterModelSettings.d.ts +12 -0
- package/dist/api/core/agent/utils/openRouterModelSettings.js +34 -0
- package/dist/api/core/agent/utils/pathRecovery.d.ts +1 -0
- package/dist/api/core/agent/utils/pathRecovery.js +29 -0
- package/dist/api/core/agent/utils/repoMapIndex.d.ts +3 -0
- package/dist/api/core/agent/utils/repoMapIndex.js +197 -0
- package/dist/api/core/agent/utils/skillsDiscovery.d.ts +10 -0
- package/dist/api/core/agent/utils/skillsDiscovery.js +50 -0
- package/dist/api/core/agent/utils/toolCallBudget.d.ts +9 -0
- package/dist/api/core/agent/utils/toolCallBudget.js +55 -0
- package/dist/api/core/agent/utils/toolLifecycle.d.ts +30 -0
- package/dist/api/core/agent/utils/toolLifecycle.js +361 -0
- package/dist/api/core/agent/utils/toolResultSafetyProcessor.d.ts +12 -0
- package/dist/api/core/agent/utils/toolResultSafetyProcessor.js +57 -0
- package/dist/api/core/agent/utils/workspaceMutationBridge.d.ts +13 -0
- package/dist/api/core/agent/utils/workspaceMutationBridge.js +149 -0
- package/dist/api/core/agent/utils/workspacePathGuard.d.ts +7 -0
- package/dist/api/core/agent/utils/workspacePathGuard.js +79 -0
- package/dist/api/core/containers/chat/toolResultSerialization.d.ts +8 -0
- package/dist/api/core/containers/chat/toolResultSerialization.js +71 -0
- package/dist/api/core/library/BrowserManager.d.ts +11 -0
- package/dist/api/core/library/BrowserManager.js +66 -0
- package/dist/api/core/library/desktopWorkspace.d.ts +1 -0
- package/dist/api/core/library/desktopWorkspace.js +3 -0
- package/dist/api/core/library/extensionManager.d.ts +10 -0
- package/dist/api/core/library/extensionManager.js +27 -0
- package/dist/api/core/library/knowledgeGraph.d.ts +268 -0
- package/dist/api/core/library/knowledgeGraph.js +989 -0
- package/dist/api/core/library/languageModelTools.d.ts +141 -0
- package/dist/api/core/library/languageModelTools.js +207 -0
- package/dist/api/core/library/localRuntime.d.ts +23 -0
- package/dist/api/core/library/localRuntime.js +144 -0
- package/dist/api/core/library/lsp/coreLsp.d.ts +367 -0
- package/dist/api/core/library/lsp/coreLsp.js +2076 -0
- package/dist/api/core/library/lsp/protocol.d.ts +25 -0
- package/dist/api/core/library/lsp/protocol.js +1 -0
- package/dist/api/core/library/lsp/serverManager.d.ts +37 -0
- package/dist/api/core/library/lsp/serverManager.js +427 -0
- package/dist/api/core/library/mcpServerProvider.d.ts +69 -0
- package/dist/api/core/library/mcpServerProvider.js +152 -0
- package/dist/api/core/library/mcpSettings.d.ts +20 -0
- package/dist/api/core/library/mcpSettings.js +131 -0
- package/dist/api/core/library/patternMatcher.d.ts +66 -0
- package/dist/api/core/library/patternMatcher.js +284 -0
- package/dist/api/core/library/regexEscape.d.ts +4 -0
- package/dist/api/core/library/regexEscape.js +4 -0
- package/dist/api/core/library/runtimeEventBus.d.ts +27 -0
- package/dist/api/core/library/runtimeEventBus.js +78 -0
- package/dist/api/core/library/safetyMiddleware.d.ts +98 -0
- package/dist/api/core/library/safetyMiddleware.js +215 -0
- package/dist/api/core/library/tauri.d.ts +71 -0
- package/dist/api/core/library/tauri.js +222 -0
- package/dist/api/core/library/tauriImport.d.ts +5 -0
- package/dist/api/core/library/tauriImport.js +7 -0
- package/dist/api/core/library/terminalAutoApproveSettings.d.ts +32 -0
- package/dist/api/core/library/terminalAutoApproveSettings.js +529 -0
- package/dist/api/core/library/workspaceIdentity.d.ts +10 -0
- package/dist/api/core/library/workspaceIdentity.js +49 -0
- package/dist/api/core/library/workspaceSummary.d.ts +19 -0
- package/dist/api/core/library/workspaceSummary.js +35 -0
- package/dist/api/core/skills/agent-customization/SKILL.md +27 -0
- package/dist/api/core/skills/bug-fix/SKILL.md +21 -0
- package/dist/api/core/skills/create-pr/SKILL.md +32 -0
- package/dist/api/core/skills/dev-server/SKILL.md +20 -0
- package/dist/api/core/skills/fix-suggestions/SKILL.md +21 -0
- package/dist/api/core/skills/github-search/SKILL.md +21 -0
- package/dist/api/core/skills/github-summary/SKILL.md +25 -0
- package/dist/api/core/skills/integration-tests/SKILL.md +29 -0
- package/dist/api/core/skills/pr-comments/SKILL.md +23 -0
- package/dist/api/core/skills/project-setup/SKILL.md +20 -0
- package/dist/api/core/skills/search-integration/SKILL.md +19 -0
- package/dist/api/core/skills/search-results/SKILL.md +19 -0
- package/dist/api/core/skills/typescript-upgrade/SKILL.md +21 -0
- package/dist/api/data/runStore.d.ts +46 -0
- package/dist/api/data/runStore.js +244 -0
- package/dist/api/helpers/agentUtils.d.ts +11 -0
- package/dist/api/helpers/agentUtils.js +23 -0
- package/dist/api/helpers/modelTokenLimits.d.ts +2 -0
- package/dist/api/helpers/modelTokenLimits.js +158 -0
- package/dist/api/helpers/observationalMemory.d.ts +10 -0
- package/dist/api/helpers/observationalMemory.js +36 -0
- package/dist/api/helpers/promptBudget.d.ts +30 -0
- package/dist/api/helpers/promptBudget.js +216 -0
- package/dist/api/helpers/resolveImageMessageParts.d.ts +9 -0
- package/dist/api/helpers/resolveImageMessageParts.js +140 -0
- package/dist/api/helpers/slashCommands.d.ts +31 -0
- package/dist/api/helpers/slashCommands.js +129 -0
- package/dist/api/helpers/tokenUsage.d.ts +19 -0
- package/dist/api/helpers/tokenUsage.js +81 -0
- package/dist/api/routes/fileRoutes.d.ts +2 -0
- package/dist/api/routes/fileRoutes.js +108 -0
- package/dist/api/routes/lspDocumentRoutes.d.ts +4 -0
- package/dist/api/routes/lspDocumentRoutes.js +84 -0
- package/dist/api/routes/lspHierarchyRoutes.d.ts +4 -0
- package/dist/api/routes/lspHierarchyRoutes.js +122 -0
- package/dist/api/routes/lspPositionRoutes.d.ts +4 -0
- package/dist/api/routes/lspPositionRoutes.js +263 -0
- package/dist/api/routes/lspQueryRoutes.d.ts +4 -0
- package/dist/api/routes/lspQueryRoutes.js +679 -0
- package/dist/api/routes/lspResolveRoutes.d.ts +4 -0
- package/dist/api/routes/lspResolveRoutes.js +143 -0
- package/dist/api/routes/lspSemanticDocumentRoutes.d.ts +4 -0
- package/dist/api/routes/lspSemanticDocumentRoutes.js +98 -0
- package/dist/api/routes/semanticRoutes.d.ts +2 -0
- package/dist/api/routes/semanticRoutes.js +126 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +160 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +38 -0
- package/package.json +100 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { getWorkspaceTree } from "../../library/workspaceIdentity.js";
|
|
5
|
+
async function getFileHandleFromPath(rootHandle, filePath) {
|
|
6
|
+
const parts = filePath.split("/").filter(Boolean);
|
|
7
|
+
let currentHandle = rootHandle;
|
|
8
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
9
|
+
currentHandle = await currentHandle.getDirectoryHandle(parts[i]);
|
|
10
|
+
}
|
|
11
|
+
return currentHandle.getFileHandle(parts[parts.length - 1]);
|
|
12
|
+
}
|
|
13
|
+
function searchInStructure(node, fileName, currentPath = "") {
|
|
14
|
+
const nodePath = currentPath ? `${currentPath}/${node.name}` : node.name;
|
|
15
|
+
if (node.type === "file" && node.name === fileName) {
|
|
16
|
+
return {
|
|
17
|
+
found: true,
|
|
18
|
+
path: node.path || nodePath,
|
|
19
|
+
node,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (node.type === "folder" && node.children) {
|
|
23
|
+
for (const child of node.children) {
|
|
24
|
+
const result = searchInStructure(child, fileName, nodePath);
|
|
25
|
+
if (result.found) {
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { found: false };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Tool for finding and reading file content by searching through directory tree
|
|
34
|
+
* Supports both filesystem (Node.js) and web-based File System Access API
|
|
35
|
+
*
|
|
36
|
+
* @param {Object} params - The parameters for finding file content
|
|
37
|
+
* @param {string} params.rootFolder - Root directory to start searching from
|
|
38
|
+
* @param {string} params.fileName - Exact file name to search for (including extension)
|
|
39
|
+
* @param {number} [params.concurrency=32] - Maximum number of parallel filesystem operations
|
|
40
|
+
* @param {boolean} [params.isWebMode=false] - Whether running in web mode (uses File System Access API)
|
|
41
|
+
* @returns {Promise<Object>} Object containing found status, file path, and content or error
|
|
42
|
+
*/
|
|
43
|
+
export async function findFileContent({ rootFolder, fileName, concurrency = 32, isWebMode = false, }) {
|
|
44
|
+
try {
|
|
45
|
+
// Web mode: Use File System Access API via window.directoryHandle
|
|
46
|
+
if (isWebMode) {
|
|
47
|
+
console.log("🌐 Web mode: searching for", fileName, "in workspace structure");
|
|
48
|
+
// Check if we have access to the workspace structure
|
|
49
|
+
const workspaceStructure = typeof window === "undefined"
|
|
50
|
+
? undefined
|
|
51
|
+
: getWorkspaceTree() || undefined;
|
|
52
|
+
if (!workspaceStructure) {
|
|
53
|
+
return {
|
|
54
|
+
found: false,
|
|
55
|
+
error: "No workspace structure available in web mode. Please open a folder first.",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const searchResult = searchInStructure(workspaceStructure, fileName);
|
|
59
|
+
if (!searchResult.found) {
|
|
60
|
+
return {
|
|
61
|
+
found: false,
|
|
62
|
+
error: `File not found: ${fileName}`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Now read the file content using File System Access API
|
|
66
|
+
const directoryHandle = window.directoryHandle;
|
|
67
|
+
if (!directoryHandle) {
|
|
68
|
+
return {
|
|
69
|
+
found: true,
|
|
70
|
+
path: searchResult.path,
|
|
71
|
+
content: null,
|
|
72
|
+
error: "File found but no directory handle available to read content. File must be opened in the editor first.",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const fileHandle = await getFileHandleFromPath(directoryHandle, searchResult.path);
|
|
77
|
+
// Request permission if needed
|
|
78
|
+
const permission = await fileHandle.queryPermission({ mode: "read" });
|
|
79
|
+
if (permission !== "granted") {
|
|
80
|
+
const newPermission = await fileHandle.requestPermission({
|
|
81
|
+
mode: "read",
|
|
82
|
+
});
|
|
83
|
+
if (newPermission !== "granted") {
|
|
84
|
+
return {
|
|
85
|
+
found: true,
|
|
86
|
+
path: searchResult.path,
|
|
87
|
+
content: null,
|
|
88
|
+
error: "Permission denied to read file",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Read the file
|
|
93
|
+
const fileData = await fileHandle.getFile();
|
|
94
|
+
const content = await fileData.text();
|
|
95
|
+
return {
|
|
96
|
+
found: true,
|
|
97
|
+
path: searchResult.path,
|
|
98
|
+
content,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const error = err;
|
|
103
|
+
return {
|
|
104
|
+
found: true,
|
|
105
|
+
path: searchResult.path,
|
|
106
|
+
content: null,
|
|
107
|
+
error: `Error reading file: ${error.message}`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Node.js filesystem mode (default)
|
|
112
|
+
const maxConcurrency = Math.max(1, Math.min(concurrency, 128));
|
|
113
|
+
// Validate root folder
|
|
114
|
+
try {
|
|
115
|
+
const stat = await fs.stat(rootFolder);
|
|
116
|
+
if (!stat.isDirectory()) {
|
|
117
|
+
return {
|
|
118
|
+
found: false,
|
|
119
|
+
error: `rootFolder is not a directory: ${rootFolder}`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
void err;
|
|
125
|
+
return {
|
|
126
|
+
found: false,
|
|
127
|
+
error: `rootFolder does not exist or is not accessible: ${rootFolder}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const queue = [rootFolder];
|
|
131
|
+
let found = false;
|
|
132
|
+
let foundPath = "";
|
|
133
|
+
let content = "";
|
|
134
|
+
const workers = Array.from({ length: maxConcurrency }, async () => {
|
|
135
|
+
while (!found) {
|
|
136
|
+
const dir = queue.shift();
|
|
137
|
+
if (!dir) {
|
|
138
|
+
// Nothing left for this worker
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
let entries;
|
|
142
|
+
try {
|
|
143
|
+
entries = await fs.readdir(dir);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
void err;
|
|
147
|
+
// unreadable dir; skip
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
for (const entry of entries) {
|
|
151
|
+
if (found)
|
|
152
|
+
break;
|
|
153
|
+
const fullPath = path.join(dir, entry);
|
|
154
|
+
let stat;
|
|
155
|
+
try {
|
|
156
|
+
stat = await fs.stat(fullPath);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
void err;
|
|
160
|
+
// cannot stat; skip
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (stat.isFile() && entry === fileName) {
|
|
164
|
+
try {
|
|
165
|
+
content = await fs.readFile(fullPath, "utf8");
|
|
166
|
+
foundPath = fullPath;
|
|
167
|
+
found = true;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
void err;
|
|
172
|
+
// can't read; keep searching
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (stat.isDirectory()) {
|
|
177
|
+
queue.push(fullPath);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
await Promise.all(workers);
|
|
183
|
+
if (!found) {
|
|
184
|
+
return {
|
|
185
|
+
found: false,
|
|
186
|
+
error: `File not found: ${fileName}`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
found: true,
|
|
191
|
+
path: foundPath,
|
|
192
|
+
content,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
const err = error;
|
|
197
|
+
return {
|
|
198
|
+
found: false,
|
|
199
|
+
error: err.message,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Tool metadata for agent system
|
|
205
|
+
*/
|
|
206
|
+
export const findFileContentTool = {
|
|
207
|
+
description: "Traverse a folder tree starting at rootFolder and return the content of the first file whose name matches fileName. Supports both Node.js filesystem and web-based File System Access API. Useful for finding configuration files, specific source files, or any file by exact name across a directory structure.",
|
|
208
|
+
parameters: z.object({
|
|
209
|
+
rootFolder: z.string().describe("Root directory to start searching from"),
|
|
210
|
+
fileName: z
|
|
211
|
+
.string()
|
|
212
|
+
.describe("Exact file name to search for (including extension)"),
|
|
213
|
+
concurrency: z
|
|
214
|
+
.number()
|
|
215
|
+
.int()
|
|
216
|
+
.positive()
|
|
217
|
+
.max(128)
|
|
218
|
+
.default(32)
|
|
219
|
+
.describe("Maximum number of parallel filesystem operations (default: 32, max: 128). Only used in Node.js mode."),
|
|
220
|
+
isWebMode: z
|
|
221
|
+
.boolean()
|
|
222
|
+
.default(false)
|
|
223
|
+
.describe("Whether running in web mode (uses File System Access API via the active workspace tree)"),
|
|
224
|
+
}),
|
|
225
|
+
execute: findFileContent,
|
|
226
|
+
};
|
|
227
|
+
export default findFileContentTool;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find Definition Tool
|
|
3
|
+
* Uses LSP to find where a symbol is defined (go to definition)
|
|
4
|
+
*/
|
|
5
|
+
type LocationRange = {
|
|
6
|
+
start: {
|
|
7
|
+
line: number;
|
|
8
|
+
character: number;
|
|
9
|
+
};
|
|
10
|
+
end: {
|
|
11
|
+
line: number;
|
|
12
|
+
character: number;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type ParsedDefinitionLocation = {
|
|
16
|
+
filePath: string;
|
|
17
|
+
line: number;
|
|
18
|
+
character: number;
|
|
19
|
+
endLine: number;
|
|
20
|
+
endCharacter: number;
|
|
21
|
+
range: LocationRange;
|
|
22
|
+
};
|
|
23
|
+
type FindDefinitionParams = {
|
|
24
|
+
filePath: string;
|
|
25
|
+
line: number;
|
|
26
|
+
character: number;
|
|
27
|
+
};
|
|
28
|
+
type FindDefinitionResult = {
|
|
29
|
+
success: true;
|
|
30
|
+
sourceFile: string;
|
|
31
|
+
sourcePosition: {
|
|
32
|
+
line: number;
|
|
33
|
+
character: number;
|
|
34
|
+
};
|
|
35
|
+
definitions: ParsedDefinitionLocation[];
|
|
36
|
+
primaryDefinition: ParsedDefinitionLocation;
|
|
37
|
+
context: string | null;
|
|
38
|
+
count: number;
|
|
39
|
+
} | {
|
|
40
|
+
success: false;
|
|
41
|
+
message?: string;
|
|
42
|
+
error?: string;
|
|
43
|
+
filePath: string;
|
|
44
|
+
position: {
|
|
45
|
+
line: number;
|
|
46
|
+
character: number;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
declare const findDefinitionTool: {
|
|
50
|
+
name: string;
|
|
51
|
+
description: string;
|
|
52
|
+
parameters: {
|
|
53
|
+
type: string;
|
|
54
|
+
properties: {
|
|
55
|
+
filePath: {
|
|
56
|
+
type: string;
|
|
57
|
+
description: string;
|
|
58
|
+
};
|
|
59
|
+
line: {
|
|
60
|
+
type: string;
|
|
61
|
+
description: string;
|
|
62
|
+
};
|
|
63
|
+
character: {
|
|
64
|
+
type: string;
|
|
65
|
+
description: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
required: string[];
|
|
69
|
+
};
|
|
70
|
+
execute({ filePath, line, character, }: FindDefinitionParams): Promise<FindDefinitionResult>;
|
|
71
|
+
};
|
|
72
|
+
export default findDefinitionTool;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find Definition Tool
|
|
3
|
+
* Uses LSP to find where a symbol is defined (go to definition)
|
|
4
|
+
*/
|
|
5
|
+
import { coreLsp } from "../../library/lsp/coreLsp.js";
|
|
6
|
+
import fs from "fs/promises";
|
|
7
|
+
const findDefinitionTool = {
|
|
8
|
+
name: "findDefinition",
|
|
9
|
+
description: `Find the definition location of a symbol at a specific position.
|
|
10
|
+
Goes to where a function, class, variable, or import is defined.
|
|
11
|
+
Returns file path, line, and character of the definition.
|
|
12
|
+
|
|
13
|
+
Use this when you need to:
|
|
14
|
+
- Navigate to function/class definition
|
|
15
|
+
- Find where a variable is declared
|
|
16
|
+
- Trace imports to their source
|
|
17
|
+
- Understand symbol origins`,
|
|
18
|
+
parameters: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
filePath: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Absolute path to the file containing the symbol",
|
|
24
|
+
},
|
|
25
|
+
line: {
|
|
26
|
+
type: "number",
|
|
27
|
+
description: "Line number (1-based) where the symbol is located",
|
|
28
|
+
},
|
|
29
|
+
character: {
|
|
30
|
+
type: "number",
|
|
31
|
+
description: "Character position (1-based) within the line",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: ["filePath", "line", "character"],
|
|
35
|
+
},
|
|
36
|
+
async execute({ filePath, line, character, }) {
|
|
37
|
+
try {
|
|
38
|
+
// Verify file exists
|
|
39
|
+
await fs.access(filePath);
|
|
40
|
+
// Get definition from LSP
|
|
41
|
+
const definitions = await coreLsp.getDefinition(filePath, line, character);
|
|
42
|
+
if (!definitions ||
|
|
43
|
+
(Array.isArray(definitions) && definitions.length === 0)) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
message: `No definition found for symbol at ${filePath}:${line}:${character}`,
|
|
47
|
+
filePath,
|
|
48
|
+
position: { line, character },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Handle both single location and array of locations
|
|
52
|
+
const locations = (Array.isArray(definitions)
|
|
53
|
+
? definitions
|
|
54
|
+
: [definitions]);
|
|
55
|
+
// Parse locations
|
|
56
|
+
const parsedLocations = locations.map((loc) => {
|
|
57
|
+
const uri = loc.uri || loc.targetUri;
|
|
58
|
+
const range = loc.range || loc.targetRange;
|
|
59
|
+
if (!uri || !range) {
|
|
60
|
+
throw new Error("Definition location is missing uri or range");
|
|
61
|
+
}
|
|
62
|
+
// Convert file:// URI to path
|
|
63
|
+
const definitionPath = uri.replace("file://", "");
|
|
64
|
+
return {
|
|
65
|
+
filePath: definitionPath,
|
|
66
|
+
line: range.start.line + 1, // Convert to 1-based
|
|
67
|
+
character: range.start.character + 1,
|
|
68
|
+
endLine: range.end.line + 1,
|
|
69
|
+
endCharacter: range.end.character + 1,
|
|
70
|
+
range,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
// Read context from definition location
|
|
74
|
+
const primaryLocation = parsedLocations[0];
|
|
75
|
+
let context = null;
|
|
76
|
+
try {
|
|
77
|
+
const fileContent = await fs.readFile(primaryLocation.filePath, "utf-8");
|
|
78
|
+
const lines = fileContent.split("\n");
|
|
79
|
+
// Get 3 lines before and after for context
|
|
80
|
+
const startLine = Math.max(0, primaryLocation.line - 4);
|
|
81
|
+
const endLine = Math.min(lines.length, primaryLocation.line + 3);
|
|
82
|
+
context = lines.slice(startLine, endLine).join("\n");
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
const error = err;
|
|
86
|
+
console.warn("Could not read definition context:", error.message || String(err) || "Unknown error");
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
success: true,
|
|
90
|
+
sourceFile: filePath,
|
|
91
|
+
sourcePosition: { line, character },
|
|
92
|
+
definitions: parsedLocations,
|
|
93
|
+
primaryDefinition: primaryLocation,
|
|
94
|
+
context,
|
|
95
|
+
count: parsedLocations.length,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const err = error;
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: err.message,
|
|
103
|
+
filePath,
|
|
104
|
+
position: { line, character },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
export default findDefinitionTool;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find References Tool
|
|
3
|
+
* Uses LSP to find all references to a symbol in the workspace
|
|
4
|
+
*/
|
|
5
|
+
type LocationRange = {
|
|
6
|
+
start: {
|
|
7
|
+
line: number;
|
|
8
|
+
character: number;
|
|
9
|
+
};
|
|
10
|
+
end: {
|
|
11
|
+
line: number;
|
|
12
|
+
character: number;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type ReferenceLocation = {
|
|
16
|
+
line: number;
|
|
17
|
+
character: number;
|
|
18
|
+
endLine: number;
|
|
19
|
+
endCharacter: number;
|
|
20
|
+
range: LocationRange;
|
|
21
|
+
context?: string;
|
|
22
|
+
};
|
|
23
|
+
type ReferenceFileGroup = {
|
|
24
|
+
filePath: string;
|
|
25
|
+
references: ReferenceLocation[];
|
|
26
|
+
count: number;
|
|
27
|
+
error?: string;
|
|
28
|
+
};
|
|
29
|
+
type FindReferencesParams = {
|
|
30
|
+
filePath: string;
|
|
31
|
+
line: number;
|
|
32
|
+
character: number;
|
|
33
|
+
includeDeclaration?: boolean;
|
|
34
|
+
};
|
|
35
|
+
type FindReferencesResult = {
|
|
36
|
+
success: true;
|
|
37
|
+
sourceFile: string;
|
|
38
|
+
sourcePosition: {
|
|
39
|
+
line: number;
|
|
40
|
+
character: number;
|
|
41
|
+
};
|
|
42
|
+
totalReferences: number;
|
|
43
|
+
totalFiles: number;
|
|
44
|
+
files: ReferenceFileGroup[];
|
|
45
|
+
hasMore: boolean;
|
|
46
|
+
allFiles: string[];
|
|
47
|
+
} | {
|
|
48
|
+
success: false;
|
|
49
|
+
message?: string;
|
|
50
|
+
error?: string;
|
|
51
|
+
filePath: string;
|
|
52
|
+
position: {
|
|
53
|
+
line: number;
|
|
54
|
+
character: number;
|
|
55
|
+
};
|
|
56
|
+
count?: number;
|
|
57
|
+
};
|
|
58
|
+
declare const findReferencesTool: {
|
|
59
|
+
name: string;
|
|
60
|
+
description: string;
|
|
61
|
+
parameters: {
|
|
62
|
+
type: string;
|
|
63
|
+
properties: {
|
|
64
|
+
filePath: {
|
|
65
|
+
type: string;
|
|
66
|
+
description: string;
|
|
67
|
+
};
|
|
68
|
+
line: {
|
|
69
|
+
type: string;
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
72
|
+
character: {
|
|
73
|
+
type: string;
|
|
74
|
+
description: string;
|
|
75
|
+
};
|
|
76
|
+
includeDeclaration: {
|
|
77
|
+
type: string;
|
|
78
|
+
description: string;
|
|
79
|
+
default: boolean;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
required: string[];
|
|
83
|
+
};
|
|
84
|
+
execute({ filePath, line, character, includeDeclaration, }: FindReferencesParams): Promise<FindReferencesResult>;
|
|
85
|
+
};
|
|
86
|
+
export default findReferencesTool;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find References Tool
|
|
3
|
+
* Uses LSP to find all references to a symbol in the workspace
|
|
4
|
+
*/
|
|
5
|
+
import { coreLsp } from "../../library/lsp/coreLsp.js";
|
|
6
|
+
import fs from "fs/promises";
|
|
7
|
+
const findReferencesTool = {
|
|
8
|
+
name: "findReferences",
|
|
9
|
+
description: `Find all references to a symbol in the workspace.
|
|
10
|
+
Shows everywhere a function, class, variable, or type is used.
|
|
11
|
+
Useful for impact analysis before refactoring.
|
|
12
|
+
|
|
13
|
+
Use this when you need to:
|
|
14
|
+
- See all usages of a function/class
|
|
15
|
+
- Understand impact of changes
|
|
16
|
+
- Find where a symbol is called
|
|
17
|
+
- Prepare for safe refactoring`,
|
|
18
|
+
parameters: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
filePath: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Absolute path to the file containing the symbol",
|
|
24
|
+
},
|
|
25
|
+
line: {
|
|
26
|
+
type: "number",
|
|
27
|
+
description: "Line number (1-based) where the symbol is located",
|
|
28
|
+
},
|
|
29
|
+
character: {
|
|
30
|
+
type: "number",
|
|
31
|
+
description: "Character position (1-based) within the line",
|
|
32
|
+
},
|
|
33
|
+
includeDeclaration: {
|
|
34
|
+
type: "boolean",
|
|
35
|
+
description: "Whether to include the declaration in results (default: true)",
|
|
36
|
+
default: true,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["filePath", "line", "character"],
|
|
40
|
+
},
|
|
41
|
+
async execute({ filePath, line, character, includeDeclaration = true, }) {
|
|
42
|
+
try {
|
|
43
|
+
// Verify file exists
|
|
44
|
+
await fs.access(filePath);
|
|
45
|
+
// Get references from LSP
|
|
46
|
+
const referencesResult = await coreLsp.getReferences(filePath, line, character, includeDeclaration);
|
|
47
|
+
const references = referencesResult;
|
|
48
|
+
if (!references || references.length === 0) {
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
message: `No references found for symbol at ${filePath}:${line}:${character}`,
|
|
52
|
+
filePath,
|
|
53
|
+
position: { line, character },
|
|
54
|
+
count: 0,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// Group references by file
|
|
58
|
+
const referencesByFile = new Map();
|
|
59
|
+
for (const ref of references) {
|
|
60
|
+
const uri = ref.uri;
|
|
61
|
+
const range = ref.range;
|
|
62
|
+
if (!uri || !range?.start || !range?.end) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Convert file:// URI to path
|
|
66
|
+
const refPath = uri.replace("file://", "");
|
|
67
|
+
if (!referencesByFile.has(refPath)) {
|
|
68
|
+
referencesByFile.set(refPath, []);
|
|
69
|
+
}
|
|
70
|
+
referencesByFile.get(refPath).push({
|
|
71
|
+
line: range.start.line + 1, // Convert to 1-based
|
|
72
|
+
character: range.start.character + 1,
|
|
73
|
+
endLine: range.end.line + 1,
|
|
74
|
+
endCharacter: range.end.character + 1,
|
|
75
|
+
range,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Read context for each reference (limit to first 5 files to avoid huge responses)
|
|
79
|
+
const filesWithContext = [];
|
|
80
|
+
const fileEntries = Array.from(referencesByFile.entries()).slice(0, 5);
|
|
81
|
+
for (const [refPath, locations] of fileEntries) {
|
|
82
|
+
try {
|
|
83
|
+
const fileContent = await fs.readFile(refPath, "utf-8");
|
|
84
|
+
const lines = fileContent.split("\n");
|
|
85
|
+
const locationsWithContext = locations.map((loc) => {
|
|
86
|
+
// Get context line
|
|
87
|
+
const contextLine = lines[loc.line - 1] || "";
|
|
88
|
+
return {
|
|
89
|
+
...loc,
|
|
90
|
+
context: contextLine.trim(),
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
filesWithContext.push({
|
|
94
|
+
filePath: refPath,
|
|
95
|
+
references: locationsWithContext,
|
|
96
|
+
count: locationsWithContext.length,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
const error = err;
|
|
101
|
+
console.warn("Could not read reference context:", error.message || String(err) || "Unknown error");
|
|
102
|
+
filesWithContext.push({
|
|
103
|
+
filePath: refPath,
|
|
104
|
+
references: locations,
|
|
105
|
+
count: locations.length,
|
|
106
|
+
error: "Could not read file",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Summary statistics
|
|
111
|
+
const totalFiles = referencesByFile.size;
|
|
112
|
+
const totalReferences = references.length;
|
|
113
|
+
return {
|
|
114
|
+
success: true,
|
|
115
|
+
sourceFile: filePath,
|
|
116
|
+
sourcePosition: { line, character },
|
|
117
|
+
totalReferences,
|
|
118
|
+
totalFiles,
|
|
119
|
+
files: filesWithContext,
|
|
120
|
+
hasMore: totalFiles > 5,
|
|
121
|
+
allFiles: Array.from(referencesByFile.keys()),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
const err = error;
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
error: err.message,
|
|
129
|
+
filePath,
|
|
130
|
+
position: { line, character },
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
export default findReferencesTool;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Document Tool
|
|
3
|
+
* Uses LSP to format an entire file according to language server formatting rules.
|
|
4
|
+
*/
|
|
5
|
+
type FormatDocumentParams = {
|
|
6
|
+
filePath: string;
|
|
7
|
+
tabSize?: number;
|
|
8
|
+
insertSpaces?: boolean;
|
|
9
|
+
trimTrailingWhitespace?: boolean;
|
|
10
|
+
insertFinalNewline?: boolean;
|
|
11
|
+
trimFinalNewlines?: boolean;
|
|
12
|
+
};
|
|
13
|
+
type FormattingEdit = {
|
|
14
|
+
startLine: number;
|
|
15
|
+
startCharacter: number;
|
|
16
|
+
endLine: number;
|
|
17
|
+
endCharacter: number;
|
|
18
|
+
newText: string;
|
|
19
|
+
};
|
|
20
|
+
type FormatDocumentResult = {
|
|
21
|
+
success: true;
|
|
22
|
+
filePath: string;
|
|
23
|
+
editCount: number;
|
|
24
|
+
edits: FormattingEdit[];
|
|
25
|
+
summary: string;
|
|
26
|
+
} | {
|
|
27
|
+
success: false;
|
|
28
|
+
message?: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
filePath: string;
|
|
31
|
+
};
|
|
32
|
+
declare const formatDocumentTool: {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
parameters: {
|
|
36
|
+
type: string;
|
|
37
|
+
properties: {
|
|
38
|
+
filePath: {
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
tabSize: {
|
|
43
|
+
type: string;
|
|
44
|
+
description: string;
|
|
45
|
+
};
|
|
46
|
+
insertSpaces: {
|
|
47
|
+
type: string;
|
|
48
|
+
description: string;
|
|
49
|
+
};
|
|
50
|
+
trimTrailingWhitespace: {
|
|
51
|
+
type: string;
|
|
52
|
+
description: string;
|
|
53
|
+
};
|
|
54
|
+
insertFinalNewline: {
|
|
55
|
+
type: string;
|
|
56
|
+
description: string;
|
|
57
|
+
};
|
|
58
|
+
trimFinalNewlines: {
|
|
59
|
+
type: string;
|
|
60
|
+
description: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
required: string[];
|
|
64
|
+
};
|
|
65
|
+
execute({ filePath, tabSize, insertSpaces, trimTrailingWhitespace, insertFinalNewline, trimFinalNewlines, }: FormatDocumentParams): Promise<FormatDocumentResult>;
|
|
66
|
+
};
|
|
67
|
+
export default formatDocumentTool;
|