@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.
Files changed (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +690 -0
  3. package/dist/api/acp/acpServer.d.ts +23 -0
  4. package/dist/api/acp/acpServer.js +814 -0
  5. package/dist/api/acp/index.d.ts +2 -0
  6. package/dist/api/acp/index.js +2 -0
  7. package/dist/api/acp/irisClient.d.ts +58 -0
  8. package/dist/api/acp/irisClient.js +214 -0
  9. package/dist/api/agent.d.ts +14 -0
  10. package/dist/api/agent.js +4171 -0
  11. package/dist/api/backendService.d.ts +4 -0
  12. package/dist/api/backendService.js +14 -0
  13. package/dist/api/core/agent/host/AgentContract.d.ts +82 -0
  14. package/dist/api/core/agent/host/AgentContract.js +1 -0
  15. package/dist/api/core/agent/host/AgentRegistry.d.ts +24 -0
  16. package/dist/api/core/agent/host/AgentRegistry.js +125 -0
  17. package/dist/api/core/agent/host/defaultRegistry.d.ts +15 -0
  18. package/dist/api/core/agent/host/defaultRegistry.js +46 -0
  19. package/dist/api/core/agent/host/externalAgentLifecycle.d.ts +65 -0
  20. package/dist/api/core/agent/host/externalAgentLifecycle.js +117 -0
  21. package/dist/api/core/agent/host/hostSessionManager.d.ts +111 -0
  22. package/dist/api/core/agent/host/hostSessionManager.js +352 -0
  23. package/dist/api/core/agent/host/index.d.ts +5 -0
  24. package/dist/api/core/agent/host/index.js +5 -0
  25. package/dist/api/core/agent/index.d.ts +87 -0
  26. package/dist/api/core/agent/index.js +1024 -0
  27. package/dist/api/core/agent/publicContracts.d.ts +35 -0
  28. package/dist/api/core/agent/publicContracts.js +103 -0
  29. package/dist/api/core/agent/tools/applyDiff.d.ts +51 -0
  30. package/dist/api/core/agent/tools/applyDiff.js +131 -0
  31. package/dist/api/core/agent/tools/backgroundTasks.d.ts +240 -0
  32. package/dist/api/core/agent/tools/backgroundTasks.js +313 -0
  33. package/dist/api/core/agent/tools/createDirectory.d.ts +43 -0
  34. package/dist/api/core/agent/tools/createDirectory.js +77 -0
  35. package/dist/api/core/agent/tools/deleteFile.d.ts +37 -0
  36. package/dist/api/core/agent/tools/deleteFile.js +66 -0
  37. package/dist/api/core/agent/tools/editFile.d.ts +73 -0
  38. package/dist/api/core/agent/tools/editFile.js +173 -0
  39. package/dist/api/core/agent/tools/executeCommand.d.ts +59 -0
  40. package/dist/api/core/agent/tools/executeCommand.js +250 -0
  41. package/dist/api/core/agent/tools/fileContent.d.ts +54 -0
  42. package/dist/api/core/agent/tools/fileContent.js +227 -0
  43. package/dist/api/core/agent/tools/findDefinition.d.ts +72 -0
  44. package/dist/api/core/agent/tools/findDefinition.js +109 -0
  45. package/dist/api/core/agent/tools/findReferences.d.ts +86 -0
  46. package/dist/api/core/agent/tools/findReferences.js +135 -0
  47. package/dist/api/core/agent/tools/formatDocument.d.ts +67 -0
  48. package/dist/api/core/agent/tools/formatDocument.js +90 -0
  49. package/dist/api/core/agent/tools/getCodeActions.d.ts +77 -0
  50. package/dist/api/core/agent/tools/getCodeActions.js +97 -0
  51. package/dist/api/core/agent/tools/getCodeCompletion.d.ts +77 -0
  52. package/dist/api/core/agent/tools/getCodeCompletion.js +174 -0
  53. package/dist/api/core/agent/tools/getCodeContext.d.ts +14 -0
  54. package/dist/api/core/agent/tools/getCodeContext.js +282 -0
  55. package/dist/api/core/agent/tools/getSignatureHelp.d.ts +61 -0
  56. package/dist/api/core/agent/tools/getSignatureHelp.js +85 -0
  57. package/dist/api/core/agent/tools/getSymbols.d.ts +50 -0
  58. package/dist/api/core/agent/tools/getSymbols.js +164 -0
  59. package/dist/api/core/agent/tools/getSymbolsLSP.d.ts +58 -0
  60. package/dist/api/core/agent/tools/getSymbolsLSP.js +147 -0
  61. package/dist/api/core/agent/tools/getTypeInfo.d.ts +70 -0
  62. package/dist/api/core/agent/tools/getTypeInfo.js +84 -0
  63. package/dist/api/core/agent/tools/getWorkspaceInfo.d.ts +80 -0
  64. package/dist/api/core/agent/tools/getWorkspaceInfo.js +281 -0
  65. package/dist/api/core/agent/tools/getWorkspaceSymbols.d.ts +53 -0
  66. package/dist/api/core/agent/tools/getWorkspaceSymbols.js +97 -0
  67. package/dist/api/core/agent/tools/grepSearch.d.ts +100 -0
  68. package/dist/api/core/agent/tools/grepSearch.js +211 -0
  69. package/dist/api/core/agent/tools/languageModelToolsIntegration.d.ts +13 -0
  70. package/dist/api/core/agent/tools/languageModelToolsIntegration.js +22 -0
  71. package/dist/api/core/agent/tools/listDirectory.d.ts +66 -0
  72. package/dist/api/core/agent/tools/listDirectory.js +161 -0
  73. package/dist/api/core/agent/tools/mcpTools.d.ts +48 -0
  74. package/dist/api/core/agent/tools/mcpTools.js +442 -0
  75. package/dist/api/core/agent/tools/queryKnowledgeGraph.d.ts +120 -0
  76. package/dist/api/core/agent/tools/queryKnowledgeGraph.js +306 -0
  77. package/dist/api/core/agent/tools/readFile.d.ts +92 -0
  78. package/dist/api/core/agent/tools/readFile.js +337 -0
  79. package/dist/api/core/agent/tools/renameFile.d.ts +49 -0
  80. package/dist/api/core/agent/tools/renameFile.js +86 -0
  81. package/dist/api/core/agent/tools/renameSymbol.d.ts +70 -0
  82. package/dist/api/core/agent/tools/renameSymbol.js +106 -0
  83. package/dist/api/core/agent/tools/runTerminalCommand.d.ts +72 -0
  84. package/dist/api/core/agent/tools/runTerminalCommand.js +69 -0
  85. package/dist/api/core/agent/tools/searchFiles.d.ts +82 -0
  86. package/dist/api/core/agent/tools/searchFiles.js +280 -0
  87. package/dist/api/core/agent/tools/terminalAutoApprove.d.ts +3 -0
  88. package/dist/api/core/agent/tools/terminalAutoApprove.js +676 -0
  89. package/dist/api/core/agent/tools/treeTraversal.d.ts +60 -0
  90. package/dist/api/core/agent/tools/treeTraversal.js +217 -0
  91. package/dist/api/core/agent/tools/webSearch.d.ts +37 -0
  92. package/dist/api/core/agent/tools/webSearch.js +80 -0
  93. package/dist/api/core/agent/tools/writeFile.d.ts +59 -0
  94. package/dist/api/core/agent/tools/writeFile.js +97 -0
  95. package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.d.ts +12 -0
  96. package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.js +67 -0
  97. package/dist/api/core/agent/utils/diffUtils.d.ts +14 -0
  98. package/dist/api/core/agent/utils/diffUtils.js +39 -0
  99. package/dist/api/core/agent/utils/environmentSnapshot.d.ts +42 -0
  100. package/dist/api/core/agent/utils/environmentSnapshot.js +213 -0
  101. package/dist/api/core/agent/utils/errorRecovery.d.ts +49 -0
  102. package/dist/api/core/agent/utils/errorRecovery.js +229 -0
  103. package/dist/api/core/agent/utils/multimodalTokenLimiter.d.ts +8 -0
  104. package/dist/api/core/agent/utils/multimodalTokenLimiter.js +238 -0
  105. package/dist/api/core/agent/utils/openRouterModelSettings.d.ts +12 -0
  106. package/dist/api/core/agent/utils/openRouterModelSettings.js +34 -0
  107. package/dist/api/core/agent/utils/pathRecovery.d.ts +1 -0
  108. package/dist/api/core/agent/utils/pathRecovery.js +29 -0
  109. package/dist/api/core/agent/utils/repoMapIndex.d.ts +3 -0
  110. package/dist/api/core/agent/utils/repoMapIndex.js +197 -0
  111. package/dist/api/core/agent/utils/skillsDiscovery.d.ts +10 -0
  112. package/dist/api/core/agent/utils/skillsDiscovery.js +50 -0
  113. package/dist/api/core/agent/utils/toolCallBudget.d.ts +9 -0
  114. package/dist/api/core/agent/utils/toolCallBudget.js +55 -0
  115. package/dist/api/core/agent/utils/toolLifecycle.d.ts +30 -0
  116. package/dist/api/core/agent/utils/toolLifecycle.js +361 -0
  117. package/dist/api/core/agent/utils/toolResultSafetyProcessor.d.ts +12 -0
  118. package/dist/api/core/agent/utils/toolResultSafetyProcessor.js +57 -0
  119. package/dist/api/core/agent/utils/workspaceMutationBridge.d.ts +13 -0
  120. package/dist/api/core/agent/utils/workspaceMutationBridge.js +149 -0
  121. package/dist/api/core/agent/utils/workspacePathGuard.d.ts +7 -0
  122. package/dist/api/core/agent/utils/workspacePathGuard.js +79 -0
  123. package/dist/api/core/containers/chat/toolResultSerialization.d.ts +8 -0
  124. package/dist/api/core/containers/chat/toolResultSerialization.js +71 -0
  125. package/dist/api/core/library/BrowserManager.d.ts +11 -0
  126. package/dist/api/core/library/BrowserManager.js +66 -0
  127. package/dist/api/core/library/desktopWorkspace.d.ts +1 -0
  128. package/dist/api/core/library/desktopWorkspace.js +3 -0
  129. package/dist/api/core/library/extensionManager.d.ts +10 -0
  130. package/dist/api/core/library/extensionManager.js +27 -0
  131. package/dist/api/core/library/knowledgeGraph.d.ts +268 -0
  132. package/dist/api/core/library/knowledgeGraph.js +989 -0
  133. package/dist/api/core/library/languageModelTools.d.ts +141 -0
  134. package/dist/api/core/library/languageModelTools.js +207 -0
  135. package/dist/api/core/library/localRuntime.d.ts +23 -0
  136. package/dist/api/core/library/localRuntime.js +144 -0
  137. package/dist/api/core/library/lsp/coreLsp.d.ts +367 -0
  138. package/dist/api/core/library/lsp/coreLsp.js +2076 -0
  139. package/dist/api/core/library/lsp/protocol.d.ts +25 -0
  140. package/dist/api/core/library/lsp/protocol.js +1 -0
  141. package/dist/api/core/library/lsp/serverManager.d.ts +37 -0
  142. package/dist/api/core/library/lsp/serverManager.js +427 -0
  143. package/dist/api/core/library/mcpServerProvider.d.ts +69 -0
  144. package/dist/api/core/library/mcpServerProvider.js +152 -0
  145. package/dist/api/core/library/mcpSettings.d.ts +20 -0
  146. package/dist/api/core/library/mcpSettings.js +131 -0
  147. package/dist/api/core/library/patternMatcher.d.ts +66 -0
  148. package/dist/api/core/library/patternMatcher.js +284 -0
  149. package/dist/api/core/library/regexEscape.d.ts +4 -0
  150. package/dist/api/core/library/regexEscape.js +4 -0
  151. package/dist/api/core/library/runtimeEventBus.d.ts +27 -0
  152. package/dist/api/core/library/runtimeEventBus.js +78 -0
  153. package/dist/api/core/library/safetyMiddleware.d.ts +98 -0
  154. package/dist/api/core/library/safetyMiddleware.js +215 -0
  155. package/dist/api/core/library/tauri.d.ts +71 -0
  156. package/dist/api/core/library/tauri.js +222 -0
  157. package/dist/api/core/library/tauriImport.d.ts +5 -0
  158. package/dist/api/core/library/tauriImport.js +7 -0
  159. package/dist/api/core/library/terminalAutoApproveSettings.d.ts +32 -0
  160. package/dist/api/core/library/terminalAutoApproveSettings.js +529 -0
  161. package/dist/api/core/library/workspaceIdentity.d.ts +10 -0
  162. package/dist/api/core/library/workspaceIdentity.js +49 -0
  163. package/dist/api/core/library/workspaceSummary.d.ts +19 -0
  164. package/dist/api/core/library/workspaceSummary.js +35 -0
  165. package/dist/api/core/skills/agent-customization/SKILL.md +27 -0
  166. package/dist/api/core/skills/bug-fix/SKILL.md +21 -0
  167. package/dist/api/core/skills/create-pr/SKILL.md +32 -0
  168. package/dist/api/core/skills/dev-server/SKILL.md +20 -0
  169. package/dist/api/core/skills/fix-suggestions/SKILL.md +21 -0
  170. package/dist/api/core/skills/github-search/SKILL.md +21 -0
  171. package/dist/api/core/skills/github-summary/SKILL.md +25 -0
  172. package/dist/api/core/skills/integration-tests/SKILL.md +29 -0
  173. package/dist/api/core/skills/pr-comments/SKILL.md +23 -0
  174. package/dist/api/core/skills/project-setup/SKILL.md +20 -0
  175. package/dist/api/core/skills/search-integration/SKILL.md +19 -0
  176. package/dist/api/core/skills/search-results/SKILL.md +19 -0
  177. package/dist/api/core/skills/typescript-upgrade/SKILL.md +21 -0
  178. package/dist/api/data/runStore.d.ts +46 -0
  179. package/dist/api/data/runStore.js +244 -0
  180. package/dist/api/helpers/agentUtils.d.ts +11 -0
  181. package/dist/api/helpers/agentUtils.js +23 -0
  182. package/dist/api/helpers/modelTokenLimits.d.ts +2 -0
  183. package/dist/api/helpers/modelTokenLimits.js +158 -0
  184. package/dist/api/helpers/observationalMemory.d.ts +10 -0
  185. package/dist/api/helpers/observationalMemory.js +36 -0
  186. package/dist/api/helpers/promptBudget.d.ts +30 -0
  187. package/dist/api/helpers/promptBudget.js +216 -0
  188. package/dist/api/helpers/resolveImageMessageParts.d.ts +9 -0
  189. package/dist/api/helpers/resolveImageMessageParts.js +140 -0
  190. package/dist/api/helpers/slashCommands.d.ts +31 -0
  191. package/dist/api/helpers/slashCommands.js +129 -0
  192. package/dist/api/helpers/tokenUsage.d.ts +19 -0
  193. package/dist/api/helpers/tokenUsage.js +81 -0
  194. package/dist/api/routes/fileRoutes.d.ts +2 -0
  195. package/dist/api/routes/fileRoutes.js +108 -0
  196. package/dist/api/routes/lspDocumentRoutes.d.ts +4 -0
  197. package/dist/api/routes/lspDocumentRoutes.js +84 -0
  198. package/dist/api/routes/lspHierarchyRoutes.d.ts +4 -0
  199. package/dist/api/routes/lspHierarchyRoutes.js +122 -0
  200. package/dist/api/routes/lspPositionRoutes.d.ts +4 -0
  201. package/dist/api/routes/lspPositionRoutes.js +263 -0
  202. package/dist/api/routes/lspQueryRoutes.d.ts +4 -0
  203. package/dist/api/routes/lspQueryRoutes.js +679 -0
  204. package/dist/api/routes/lspResolveRoutes.d.ts +4 -0
  205. package/dist/api/routes/lspResolveRoutes.js +143 -0
  206. package/dist/api/routes/lspSemanticDocumentRoutes.d.ts +4 -0
  207. package/dist/api/routes/lspSemanticDocumentRoutes.js +98 -0
  208. package/dist/api/routes/semanticRoutes.d.ts +2 -0
  209. package/dist/api/routes/semanticRoutes.js +126 -0
  210. package/dist/cli.d.ts +8 -0
  211. package/dist/cli.js +160 -0
  212. package/dist/index.d.ts +1 -0
  213. package/dist/index.js +1 -0
  214. package/dist/server.d.ts +2 -0
  215. package/dist/server.js +38 -0
  216. 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;