@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,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;
|