@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,281 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import { exec } from "child_process";
4
+ import { promisify } from "util";
5
+ import { z } from "zod";
6
+ import { countNodes, getMaxDepth, findAllNodes } from "./treeTraversal.js";
7
+ const execAsync = promisify(exec);
8
+ /**
9
+ * Tool for getting workspace information
10
+ * @param {Object} params - The parameters for getting workspace info
11
+ * @param {string} [params.workspacePath] - The path to the workspace
12
+ * @param {boolean} [params.includeTree] - Whether to include directory tree
13
+ * @param {number} [params.maxDepth] - Maximum depth for directory tree
14
+ * @returns {Promise<Object>} Object containing workspace information or error
15
+ */
16
+ export async function getWorkspaceInfo({ workspacePath = process.cwd(), includeTree = false, maxDepth = 3, }) {
17
+ try {
18
+ const absolutePath = path.resolve(workspacePath);
19
+ // Check if path exists
20
+ try {
21
+ await fs.access(absolutePath, fs.constants.R_OK);
22
+ }
23
+ catch (err) {
24
+ return {
25
+ success: false,
26
+ error: `Workspace path not found or not readable: ${workspacePath}`,
27
+ };
28
+ }
29
+ const stats = await fs.stat(absolutePath);
30
+ if (!stats.isDirectory()) {
31
+ return {
32
+ success: false,
33
+ error: "Workspace path is not a directory",
34
+ };
35
+ }
36
+ // Get workspace name
37
+ const workspaceName = path.basename(absolutePath);
38
+ // Try to get git information
39
+ let gitInfo = null;
40
+ try {
41
+ const { stdout: branch } = await execAsync("git rev-parse --abbrev-ref HEAD", { cwd: absolutePath });
42
+ const { stdout: remote } = await execAsync("git config --get remote.origin.url", { cwd: absolutePath });
43
+ const { stdout: rootPath } = await execAsync("git rev-parse --show-toplevel", { cwd: absolutePath });
44
+ gitInfo = {
45
+ isGitRepo: true,
46
+ branch: branch.trim(),
47
+ remote: remote.trim(),
48
+ rootPath: rootPath.trim(),
49
+ };
50
+ // Check for uncommitted changes
51
+ const { stdout: status } = await execAsync("git status --porcelain", {
52
+ cwd: absolutePath,
53
+ });
54
+ gitInfo.hasUncommittedChanges = status.trim().length > 0;
55
+ gitInfo.uncommittedFiles = status
56
+ .trim()
57
+ .split("\n")
58
+ .filter(Boolean).length;
59
+ }
60
+ catch (err) {
61
+ gitInfo = { isGitRepo: false };
62
+ }
63
+ // Try to detect project type by looking for common files
64
+ const projectTypes = [];
65
+ const commonFiles = [
66
+ { file: "package.json", type: "Node.js/JavaScript" },
67
+ { file: "requirements.txt", type: "Python" },
68
+ { file: "Pipfile", type: "Python (Pipenv)" },
69
+ { file: "pyproject.toml", type: "Python (Poetry)" },
70
+ { file: "Cargo.toml", type: "Rust" },
71
+ { file: "go.mod", type: "Go" },
72
+ { file: "pom.xml", type: "Java (Maven)" },
73
+ { file: "build.gradle", type: "Java (Gradle)" },
74
+ { file: "Gemfile", type: "Ruby" },
75
+ { file: "composer.json", type: "PHP" },
76
+ { file: ".csproj", type: ".NET" },
77
+ ];
78
+ for (const { file, type } of commonFiles) {
79
+ try {
80
+ if (file.startsWith(".")) {
81
+ // Special handling for extension-based files
82
+ const files = await fs.readdir(absolutePath);
83
+ if (files.some((f) => f.endsWith(file))) {
84
+ projectTypes.push(type);
85
+ }
86
+ }
87
+ else {
88
+ await fs.access(path.join(absolutePath, file), fs.constants.F_OK);
89
+ projectTypes.push(type);
90
+ }
91
+ }
92
+ catch (err) {
93
+ // File doesn't exist, skip
94
+ }
95
+ }
96
+ // Try to read package.json if it exists
97
+ let packageInfo = null;
98
+ try {
99
+ const packageJsonPath = path.join(absolutePath, "package.json");
100
+ const packageJsonContent = await fs.readFile(packageJsonPath, "utf8");
101
+ const packageJson = JSON.parse(packageJsonContent);
102
+ packageInfo = {
103
+ name: typeof packageJson.name === "string" ? packageJson.name : undefined,
104
+ version: typeof packageJson.version === "string" ? packageJson.version : undefined,
105
+ description: typeof packageJson.description === "string"
106
+ ? packageJson.description
107
+ : undefined,
108
+ dependencies: Object.keys(packageJson.dependencies || {}),
109
+ devDependencies: Object.keys(packageJson.devDependencies || {}),
110
+ scripts: Object.keys(packageJson.scripts || {}),
111
+ };
112
+ }
113
+ catch (err) {
114
+ // package.json doesn't exist or is invalid
115
+ }
116
+ // Count files and directories
117
+ let fileCount = 0;
118
+ let dirCount = 0;
119
+ try {
120
+ const entries = await fs.readdir(absolutePath, { withFileTypes: true });
121
+ for (const entry of entries) {
122
+ if (entry.name.startsWith("."))
123
+ continue;
124
+ if (entry.isDirectory())
125
+ dirCount++;
126
+ else
127
+ fileCount++;
128
+ }
129
+ }
130
+ catch (err) {
131
+ // Unable to count
132
+ }
133
+ // Optionally build directory tree structure
134
+ let directoryTree = null;
135
+ let treeStats = null;
136
+ if (includeTree) {
137
+ try {
138
+ directoryTree = await buildDirectoryTree(absolutePath, maxDepth);
139
+ // Calculate tree statistics using efficient traversal utilities
140
+ if (directoryTree) {
141
+ const allFiles = findAllNodes(directoryTree, (node) => node.type === "file");
142
+ const allDirs = findAllNodes(directoryTree, (node) => node.type === "directory");
143
+ treeStats = {
144
+ totalNodes: countNodes(directoryTree),
145
+ totalFiles: allFiles.length,
146
+ totalDirectories: allDirs.length,
147
+ maxDepth: getMaxDepth(directoryTree),
148
+ };
149
+ }
150
+ }
151
+ catch (err) {
152
+ console.error("Failed to build directory tree:", err);
153
+ }
154
+ }
155
+ return {
156
+ success: true,
157
+ workspacePath: absolutePath,
158
+ workspaceName,
159
+ projectTypes,
160
+ fileCount,
161
+ dirCount,
162
+ git: gitInfo,
163
+ package: packageInfo,
164
+ directoryTree,
165
+ treeStats,
166
+ };
167
+ }
168
+ catch (error) {
169
+ const err = error;
170
+ return {
171
+ success: false,
172
+ error: err.message,
173
+ };
174
+ }
175
+ }
176
+ /**
177
+ * Build a directory tree structure using BFS (Breadth-First Search)
178
+ * More efficient than recursive DFS, prevents stack overflow on deep trees
179
+ */
180
+ async function buildDirectoryTree(dirPath, maxDepth = 3) {
181
+ const ignorePatterns = [
182
+ "node_modules",
183
+ ".git",
184
+ "dist",
185
+ "build",
186
+ ".next",
187
+ "target",
188
+ "coverage",
189
+ ".cache",
190
+ ".vscode",
191
+ ".idea",
192
+ ];
193
+ // Root node
194
+ const root = {
195
+ name: path.basename(dirPath),
196
+ path: dirPath,
197
+ type: "directory",
198
+ children: [],
199
+ depth: 0,
200
+ };
201
+ // Queue for BFS traversal: [node, parentNode]
202
+ const queue = [[dirPath, root, 0]];
203
+ while (queue.length > 0) {
204
+ const next = queue.shift();
205
+ if (!next) {
206
+ continue;
207
+ }
208
+ const [currentPath, parentNode, currentDepth] = next;
209
+ // Stop if max depth reached
210
+ if (currentDepth >= maxDepth)
211
+ continue;
212
+ try {
213
+ const entries = await fs.readdir(currentPath, { withFileTypes: true });
214
+ // Sort entries: directories first, then files alphabetically
215
+ const sortedEntries = entries.sort((a, b) => {
216
+ if (a.isDirectory() === b.isDirectory()) {
217
+ return a.name.localeCompare(b.name);
218
+ }
219
+ return a.isDirectory() ? -1 : 1;
220
+ });
221
+ for (const entry of sortedEntries) {
222
+ // Skip hidden files and ignored patterns
223
+ if (entry.name.startsWith(".") || ignorePatterns.includes(entry.name)) {
224
+ continue;
225
+ }
226
+ const children = parentNode.children ?? (parentNode.children = []);
227
+ const childPath = path.join(currentPath, entry.name);
228
+ if (entry.isDirectory()) {
229
+ const dirNode = {
230
+ name: entry.name,
231
+ path: childPath,
232
+ type: "directory",
233
+ children: [],
234
+ depth: currentDepth + 1,
235
+ };
236
+ children.push(dirNode);
237
+ // Add to queue for further exploration
238
+ queue.push([childPath, dirNode, currentDepth + 1]);
239
+ }
240
+ else {
241
+ // Add file node
242
+ children.push({
243
+ name: entry.name,
244
+ path: childPath,
245
+ type: "file",
246
+ depth: currentDepth + 1,
247
+ children: [],
248
+ });
249
+ }
250
+ }
251
+ }
252
+ catch (err) {
253
+ const error = err;
254
+ // Skip directories we can't read (permissions, etc.)
255
+ console.error(`Cannot read directory ${currentPath}:`, error.message || String(err) || "Unknown error");
256
+ }
257
+ }
258
+ return root;
259
+ }
260
+ /**
261
+ * Tool metadata for agent system
262
+ */
263
+ export const getWorkspaceInfoTool = {
264
+ description: "Get information about the current workspace including git status, project type, and structure. IMPORTANT: Leave workspacePath empty to use the current workspace - do NOT pass project names like 'my-project'. Can optionally include the full directory tree to understand the folder structure.",
265
+ parameters: z.object({
266
+ workspacePath: z
267
+ .string()
268
+ .optional()
269
+ .describe("Leave empty to use current workspace. Only provide an absolute path if you need a different workspace."),
270
+ includeTree: z
271
+ .boolean()
272
+ .default(false)
273
+ .describe("Whether to include the full directory tree structure (useful for understanding folder organization)"),
274
+ maxDepth: z
275
+ .number()
276
+ .default(3)
277
+ .describe("Maximum depth for directory tree (only used if includeTree is true)"),
278
+ }),
279
+ execute: getWorkspaceInfo,
280
+ };
281
+ export default getWorkspaceInfoTool;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Get Workspace Symbols Tool
3
+ * Uses LSP to search for symbols across the entire workspace by name/query.
4
+ */
5
+ type GetWorkspaceSymbolsParams = {
6
+ query: string;
7
+ languageId?: string;
8
+ maxResults?: number;
9
+ };
10
+ type WorkspaceSymbol = {
11
+ name: string;
12
+ kind: string;
13
+ containerName: string;
14
+ filePath: string;
15
+ line: number;
16
+ character: number;
17
+ };
18
+ type GetWorkspaceSymbolsResult = {
19
+ success: true;
20
+ query: string;
21
+ totalSymbols: number;
22
+ symbols: WorkspaceSymbol[];
23
+ byKind: Record<string, WorkspaceSymbol[]>;
24
+ } | {
25
+ success: false;
26
+ message?: string;
27
+ error?: string;
28
+ query: string;
29
+ };
30
+ declare const getWorkspaceSymbolsTool: {
31
+ name: string;
32
+ description: string;
33
+ parameters: {
34
+ type: string;
35
+ properties: {
36
+ query: {
37
+ type: string;
38
+ description: string;
39
+ };
40
+ languageId: {
41
+ type: string;
42
+ description: string;
43
+ };
44
+ maxResults: {
45
+ type: string;
46
+ description: string;
47
+ };
48
+ };
49
+ required: string[];
50
+ };
51
+ execute({ query, languageId, maxResults }: GetWorkspaceSymbolsParams): Promise<GetWorkspaceSymbolsResult>;
52
+ };
53
+ export default getWorkspaceSymbolsTool;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Get Workspace Symbols Tool
3
+ * Uses LSP to search for symbols across the entire workspace by name/query.
4
+ */
5
+ import { coreLsp } from "../../library/lsp/coreLsp.js";
6
+ import { fileURLToPath } from "url";
7
+ const symbolKindNames = {
8
+ 1: "File", 2: "Module", 3: "Namespace", 4: "Package", 5: "Class",
9
+ 6: "Method", 7: "Property", 8: "Field", 9: "Constructor", 10: "Enum",
10
+ 11: "Interface", 12: "Function", 13: "Variable", 14: "Constant",
11
+ 15: "String", 16: "Number", 17: "Boolean", 18: "Array", 19: "Object",
12
+ 20: "Key", 21: "Null", 22: "EnumMember", 23: "Struct", 24: "Event",
13
+ 25: "Operator", 26: "TypeParameter",
14
+ };
15
+ const getWorkspaceSymbolsTool = {
16
+ name: "getWorkspaceSymbols",
17
+ description: `Search for symbols (functions, classes, variables, types) across the entire workspace by name.
18
+ Returns matching symbols with their file locations and kinds.
19
+
20
+ Use this when you need to:
21
+ - Find where a class or function is defined without knowing the file
22
+ - Search for all symbols matching a pattern across the project
23
+ - Get a list of all exports or public API symbols
24
+ - Locate a symbol quickly by partial name`,
25
+ parameters: {
26
+ type: "object",
27
+ properties: {
28
+ query: {
29
+ type: "string",
30
+ description: "Search query — partial name or pattern to match symbols against",
31
+ },
32
+ languageId: {
33
+ type: "string",
34
+ description: "Optional language ID to limit search to one language server (e.g. 'typescript')",
35
+ },
36
+ maxResults: {
37
+ type: "number",
38
+ description: "Maximum number of results to return (default: 50)",
39
+ },
40
+ },
41
+ required: ["query"],
42
+ },
43
+ async execute({ query, languageId, maxResults = 50 }) {
44
+ try {
45
+ const result = (await coreLsp.getWorkspaceSymbols(query, languageId));
46
+ if (!result || result.length === 0) {
47
+ return {
48
+ success: false,
49
+ message: `No workspace symbols found matching "${query}"`,
50
+ query,
51
+ };
52
+ }
53
+ const symbols = result
54
+ .slice(0, maxResults)
55
+ .map((sym) => {
56
+ const uri = sym.location?.uri ?? "";
57
+ let filePath = uri;
58
+ try {
59
+ filePath = uri.startsWith("file://") ? fileURLToPath(uri) : uri;
60
+ }
61
+ catch {
62
+ filePath = uri.replace("file://", "");
63
+ }
64
+ return {
65
+ name: sym.name ?? "",
66
+ kind: symbolKindNames[sym.kind ?? 0] ?? `Unknown(${sym.kind})`,
67
+ containerName: sym.containerName ?? "",
68
+ filePath,
69
+ line: (sym.location?.range?.start?.line ?? 0) + 1,
70
+ character: (sym.location?.range?.start?.character ?? 0) + 1,
71
+ };
72
+ });
73
+ const byKind = {};
74
+ for (const sym of symbols) {
75
+ if (!byKind[sym.kind])
76
+ byKind[sym.kind] = [];
77
+ byKind[sym.kind].push(sym);
78
+ }
79
+ return {
80
+ success: true,
81
+ query,
82
+ totalSymbols: symbols.length,
83
+ symbols,
84
+ byKind,
85
+ };
86
+ }
87
+ catch (error) {
88
+ const err = error;
89
+ return {
90
+ success: false,
91
+ error: err.message,
92
+ query,
93
+ };
94
+ }
95
+ },
96
+ };
97
+ export default getWorkspaceSymbolsTool;
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+ type GrepSearchParams = {
3
+ searchText: string;
4
+ filePattern?: string;
5
+ cwd?: string;
6
+ caseSensitive?: boolean;
7
+ regex?: boolean;
8
+ includeLineNumbers?: boolean;
9
+ contextLines?: number;
10
+ maxResults?: number;
11
+ };
12
+ type ContextLine = {
13
+ lineNumber: number;
14
+ line: string;
15
+ };
16
+ type LineMatch = {
17
+ text: string;
18
+ index: number;
19
+ };
20
+ type GrepMatch = {
21
+ lineNumber: number;
22
+ line: string;
23
+ matches: LineMatch[];
24
+ before?: ContextLine[];
25
+ after?: ContextLine[];
26
+ };
27
+ type GrepFileResult = {
28
+ file: string;
29
+ relativePath: string;
30
+ matchCount: number;
31
+ matches: GrepMatch[];
32
+ };
33
+ type GrepSearchSuccessResult = {
34
+ success: true;
35
+ searchText: string;
36
+ pattern: string;
37
+ caseSensitive: boolean;
38
+ regex: boolean;
39
+ note?: string;
40
+ totalFiles: number;
41
+ filesWithMatches: number;
42
+ totalMatches: number;
43
+ skippedBinaryFiles: number;
44
+ results: GrepFileResult[];
45
+ };
46
+ type GrepSearchErrorResult = {
47
+ success: false;
48
+ error: string;
49
+ };
50
+ type GrepSearchResult = GrepSearchSuccessResult | GrepSearchErrorResult;
51
+ /**
52
+ * Tool for searching text content across files (like grep)
53
+ * @param {Object} params - The parameters for grep search
54
+ * @param {string} params.searchText - The text to search for
55
+ * @param {string} [params.filePattern] - Glob pattern for files to search
56
+ * @param {string} [params.cwd] - Current working directory for search
57
+ * @param {boolean} [params.caseSensitive] - Whether search is case sensitive
58
+ * @param {boolean} [params.regex] - Whether searchText is a regex pattern
59
+ * @param {boolean} [params.includeLineNumbers] - Whether to include line numbers
60
+ * @param {number} [params.contextLines] - Number of context lines to show before/after match
61
+ * @param {number} [params.maxResults] - Maximum number of results to return
62
+ * @returns {Promise<Object>} Object containing success status and search results or error
63
+ */
64
+ export declare function grepSearch({ searchText, filePattern, cwd, caseSensitive, regex, includeLineNumbers, contextLines, maxResults, }: GrepSearchParams): Promise<GrepSearchResult>;
65
+ /**
66
+ * Tool metadata for agent system
67
+ */
68
+ export declare const grepSearchTool: {
69
+ description: string;
70
+ parameters: z.ZodObject<{
71
+ searchText: z.ZodString;
72
+ filePattern: z.ZodDefault<z.ZodString>;
73
+ cwd: z.ZodDefault<z.ZodString>;
74
+ caseSensitive: z.ZodDefault<z.ZodBoolean>;
75
+ regex: z.ZodDefault<z.ZodBoolean>;
76
+ includeLineNumbers: z.ZodDefault<z.ZodBoolean>;
77
+ contextLines: z.ZodDefault<z.ZodNumber>;
78
+ maxResults: z.ZodDefault<z.ZodNumber>;
79
+ }, "strip", z.ZodTypeAny, {
80
+ cwd?: string;
81
+ searchText?: string;
82
+ filePattern?: string;
83
+ caseSensitive?: boolean;
84
+ regex?: boolean;
85
+ includeLineNumbers?: boolean;
86
+ contextLines?: number;
87
+ maxResults?: number;
88
+ }, {
89
+ cwd?: string;
90
+ searchText?: string;
91
+ filePattern?: string;
92
+ caseSensitive?: boolean;
93
+ regex?: boolean;
94
+ includeLineNumbers?: boolean;
95
+ contextLines?: number;
96
+ maxResults?: number;
97
+ }>;
98
+ execute: typeof grepSearch;
99
+ };
100
+ export default grepSearchTool;