@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,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { TerminalAutoApproveRules } from "../../library/terminalAutoApproveSettings.js";
|
|
3
|
+
type RunTerminalCommandParams = {
|
|
4
|
+
command: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
workspaceRoot?: string;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
runInBackground?: boolean;
|
|
10
|
+
description?: string;
|
|
11
|
+
skipConfirmation?: boolean;
|
|
12
|
+
autoApproveRules?: TerminalAutoApproveRules;
|
|
13
|
+
};
|
|
14
|
+
type CommandResult = Record<string, unknown> & {
|
|
15
|
+
success?: boolean;
|
|
16
|
+
error?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Tool for running terminal commands
|
|
20
|
+
*
|
|
21
|
+
* Safe readonly commands can be auto-approved using wrapper-aware parsing.
|
|
22
|
+
* Commands that do not match the allow-list still return pending_confirmation,
|
|
23
|
+
* which triggers the existing user approval dialog in the UI.
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} params - The parameters for running a command
|
|
26
|
+
* @param {string} params.command - The command to execute
|
|
27
|
+
* @param {string} [params.cwd] - Current working directory for the command
|
|
28
|
+
* @param {number} [params.timeout=30000] - Timeout in milliseconds
|
|
29
|
+
* @param {Object} [params.env] - Environment variables
|
|
30
|
+
* @param {boolean} [params.skipConfirmation=false] - Skip user confirmation (used internally after user approves)
|
|
31
|
+
* @returns {Promise<Object>} Object containing success status and command output or error
|
|
32
|
+
*/
|
|
33
|
+
export declare function runTerminalCommand({ command, cwd, workspaceRoot, timeout, env, runInBackground, description, skipConfirmation, autoApproveRules, }: RunTerminalCommandParams): Promise<CommandResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Tool metadata for agent system
|
|
36
|
+
*/
|
|
37
|
+
export declare const runTerminalCommandTool: {
|
|
38
|
+
description: string;
|
|
39
|
+
parameters: z.ZodObject<{
|
|
40
|
+
command: z.ZodString;
|
|
41
|
+
cwd: z.ZodDefault<z.ZodString>;
|
|
42
|
+
workspaceRoot: z.ZodOptional<z.ZodString>;
|
|
43
|
+
timeout: z.ZodDefault<z.ZodNumber>;
|
|
44
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
45
|
+
runInBackground: z.ZodDefault<z.ZodBoolean>;
|
|
46
|
+
description: z.ZodOptional<z.ZodString>;
|
|
47
|
+
skipConfirmation: z.ZodDefault<z.ZodBoolean>;
|
|
48
|
+
autoApproveRules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
command?: string;
|
|
51
|
+
cwd?: string;
|
|
52
|
+
env?: Record<string, string>;
|
|
53
|
+
description?: string;
|
|
54
|
+
timeout?: number;
|
|
55
|
+
workspaceRoot?: string;
|
|
56
|
+
runInBackground?: boolean;
|
|
57
|
+
skipConfirmation?: boolean;
|
|
58
|
+
autoApproveRules?: Record<string, any>;
|
|
59
|
+
}, {
|
|
60
|
+
command?: string;
|
|
61
|
+
cwd?: string;
|
|
62
|
+
env?: Record<string, string>;
|
|
63
|
+
description?: string;
|
|
64
|
+
timeout?: number;
|
|
65
|
+
workspaceRoot?: string;
|
|
66
|
+
runInBackground?: boolean;
|
|
67
|
+
skipConfirmation?: boolean;
|
|
68
|
+
autoApproveRules?: Record<string, any>;
|
|
69
|
+
}>;
|
|
70
|
+
execute: typeof runTerminalCommand;
|
|
71
|
+
};
|
|
72
|
+
export default runTerminalCommandTool;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { executeCommand } from "./executeCommand.js";
|
|
3
|
+
/**
|
|
4
|
+
* Tool for running terminal commands
|
|
5
|
+
*
|
|
6
|
+
* Safe readonly commands can be auto-approved using wrapper-aware parsing.
|
|
7
|
+
* Commands that do not match the allow-list still return pending_confirmation,
|
|
8
|
+
* which triggers the existing user approval dialog in the UI.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} params - The parameters for running a command
|
|
11
|
+
* @param {string} params.command - The command to execute
|
|
12
|
+
* @param {string} [params.cwd] - Current working directory for the command
|
|
13
|
+
* @param {number} [params.timeout=30000] - Timeout in milliseconds
|
|
14
|
+
* @param {Object} [params.env] - Environment variables
|
|
15
|
+
* @param {boolean} [params.skipConfirmation=false] - Skip user confirmation (used internally after user approves)
|
|
16
|
+
* @returns {Promise<Object>} Object containing success status and command output or error
|
|
17
|
+
*/
|
|
18
|
+
export async function runTerminalCommand({ command, cwd = process.cwd(), workspaceRoot, timeout = 30000, env = {}, runInBackground = false, description, skipConfirmation = false, autoApproveRules, }) {
|
|
19
|
+
// Route through executeCommand for consistent confirmation flow
|
|
20
|
+
return executeCommand({
|
|
21
|
+
command,
|
|
22
|
+
cwd,
|
|
23
|
+
workspaceRoot,
|
|
24
|
+
timeout,
|
|
25
|
+
env,
|
|
26
|
+
runInBackground,
|
|
27
|
+
description,
|
|
28
|
+
skipConfirmation,
|
|
29
|
+
approvalPolicy: "auto_approve_safe",
|
|
30
|
+
autoApproveRules,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Tool metadata for agent system
|
|
35
|
+
*/
|
|
36
|
+
export const runTerminalCommandTool = {
|
|
37
|
+
description: "Execute a terminal command and return its output. Safe readonly commands may auto-run; other commands require confirmation.",
|
|
38
|
+
parameters: z.object({
|
|
39
|
+
command: z.string().describe("The command to execute"),
|
|
40
|
+
cwd: z
|
|
41
|
+
.string()
|
|
42
|
+
.default(process.cwd())
|
|
43
|
+
.describe("Current working directory for the command"),
|
|
44
|
+
workspaceRoot: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe("Workspace root path for security validation - defaults to inferred repo root"),
|
|
48
|
+
timeout: z.number().default(30000).describe("Timeout in milliseconds"),
|
|
49
|
+
env: z.record(z.string()).optional().describe("Environment variables"),
|
|
50
|
+
runInBackground: z
|
|
51
|
+
.boolean()
|
|
52
|
+
.default(false)
|
|
53
|
+
.describe("Run command as managed background task"),
|
|
54
|
+
description: z
|
|
55
|
+
.string()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Optional short task description for background execution"),
|
|
58
|
+
skipConfirmation: z
|
|
59
|
+
.boolean()
|
|
60
|
+
.default(false)
|
|
61
|
+
.describe("Skip user confirmation - only used internally after user approves the command"),
|
|
62
|
+
autoApproveRules: z
|
|
63
|
+
.record(z.any())
|
|
64
|
+
.optional()
|
|
65
|
+
.describe("Optional auto-approve rule map for internal runtime configuration."),
|
|
66
|
+
}),
|
|
67
|
+
execute: runTerminalCommand,
|
|
68
|
+
};
|
|
69
|
+
export default runTerminalCommandTool;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
type SearchFilesParams = {
|
|
3
|
+
pattern?: string;
|
|
4
|
+
filePath?: string;
|
|
5
|
+
startLine?: number;
|
|
6
|
+
endLine?: number;
|
|
7
|
+
cwd?: string;
|
|
8
|
+
encoding?: BufferEncoding;
|
|
9
|
+
};
|
|
10
|
+
type FileSearchResult = {
|
|
11
|
+
path: string;
|
|
12
|
+
relativePath: string;
|
|
13
|
+
size: number;
|
|
14
|
+
lastModified: Date;
|
|
15
|
+
};
|
|
16
|
+
type SearchFilesReadSuccessResult = {
|
|
17
|
+
success: true;
|
|
18
|
+
filePath: string;
|
|
19
|
+
resolvedBy: "direct" | "repo_map" | "terminal_find";
|
|
20
|
+
startLine?: number;
|
|
21
|
+
endLine?: number;
|
|
22
|
+
totalLines: number;
|
|
23
|
+
content: string;
|
|
24
|
+
lines: string[];
|
|
25
|
+
size: number;
|
|
26
|
+
lastModified: Date;
|
|
27
|
+
};
|
|
28
|
+
type SearchFilesPatternSuccessResult = {
|
|
29
|
+
success: true;
|
|
30
|
+
message?: string;
|
|
31
|
+
pattern: string;
|
|
32
|
+
resolvedBy?: "glob" | "repo_map" | "terminal_find" | "repo_map_ranked";
|
|
33
|
+
count?: number;
|
|
34
|
+
files: FileSearchResult[];
|
|
35
|
+
};
|
|
36
|
+
type SearchFilesErrorResult = {
|
|
37
|
+
success: false;
|
|
38
|
+
error: string;
|
|
39
|
+
};
|
|
40
|
+
type SearchFilesResult = SearchFilesReadSuccessResult | SearchFilesPatternSuccessResult | SearchFilesErrorResult;
|
|
41
|
+
/**
|
|
42
|
+
* Tool for searching files and reading specific line ranges
|
|
43
|
+
* @param {Object} params - The parameters for searching files
|
|
44
|
+
* @param {string} [params.pattern] - Glob pattern to search for files
|
|
45
|
+
* @param {string} [params.filePath] - Specific file path to read (alternative to pattern)
|
|
46
|
+
* @param {number} [params.startLine] - Starting line number (1-indexed)
|
|
47
|
+
* @param {number} [params.endLine] - Ending line number (1-indexed)
|
|
48
|
+
* @param {string} [params.cwd] - Current working directory for search
|
|
49
|
+
* @param {string} [params.encoding='utf8'] - The encoding to use when reading the file
|
|
50
|
+
* @returns {Promise<Object>} Object containing success status and search results or file content
|
|
51
|
+
*/
|
|
52
|
+
export declare function searchFiles({ pattern, filePath, startLine, endLine, cwd, encoding, }: SearchFilesParams): Promise<SearchFilesResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Tool metadata for agent system
|
|
55
|
+
*/
|
|
56
|
+
export declare const searchFilesTool: {
|
|
57
|
+
description: string;
|
|
58
|
+
parameters: z.ZodObject<{
|
|
59
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
60
|
+
filePath: z.ZodOptional<z.ZodString>;
|
|
61
|
+
startLine: z.ZodOptional<z.ZodNumber>;
|
|
62
|
+
endLine: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
cwd: z.ZodDefault<z.ZodString>;
|
|
64
|
+
encoding: z.ZodDefault<z.ZodEnum<["utf8", "ascii", "base64", "binary", "hex"]>>;
|
|
65
|
+
}, "strip", z.ZodTypeAny, {
|
|
66
|
+
cwd?: string;
|
|
67
|
+
pattern?: string;
|
|
68
|
+
encoding?: "ascii" | "utf8" | "base64" | "binary" | "hex";
|
|
69
|
+
filePath?: string;
|
|
70
|
+
startLine?: number;
|
|
71
|
+
endLine?: number;
|
|
72
|
+
}, {
|
|
73
|
+
cwd?: string;
|
|
74
|
+
pattern?: string;
|
|
75
|
+
encoding?: "ascii" | "utf8" | "base64" | "binary" | "hex";
|
|
76
|
+
filePath?: string;
|
|
77
|
+
startLine?: number;
|
|
78
|
+
endLine?: number;
|
|
79
|
+
}>;
|
|
80
|
+
execute: typeof searchFiles;
|
|
81
|
+
};
|
|
82
|
+
export default searchFilesTool;
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { glob } from "glob";
|
|
4
|
+
import { execFile } from "child_process";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { findFilesViaRepoMap, rankFileCandidates, } from "../utils/repoMapIndex.js";
|
|
8
|
+
import { buildRecoveryQueries } from "../utils/pathRecovery.js";
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const normalizeRelativeInputPath = (value) => value.replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\//, "");
|
|
11
|
+
const hasGlobMeta = (value) => /[*?[\]{}]/.test(value);
|
|
12
|
+
const isNumber = (value) => typeof value === "number";
|
|
13
|
+
const isPathInsideBase = (basePath, targetPath) => {
|
|
14
|
+
const relative = path.relative(basePath, targetPath);
|
|
15
|
+
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
16
|
+
};
|
|
17
|
+
const normalizeGlobPattern = (inputPattern) => {
|
|
18
|
+
const normalized = inputPattern.replace(/\\/g, "/");
|
|
19
|
+
const anchoredToRoot = normalized.startsWith("/");
|
|
20
|
+
const primary = anchoredToRoot ? normalized.slice(1) : normalized;
|
|
21
|
+
const patterns = [primary];
|
|
22
|
+
if (primary.startsWith("**/")) {
|
|
23
|
+
patterns.push(primary.slice(3));
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
patterns: Array.from(new Set(patterns.filter(Boolean))),
|
|
27
|
+
anchoredToRoot,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const findFilesViaTerminal = async (cwd, query) => {
|
|
31
|
+
const normalizedQuery = normalizeRelativeInputPath(query);
|
|
32
|
+
const baseName = path.basename(normalizedQuery);
|
|
33
|
+
const attempts = [];
|
|
34
|
+
// Exact relative path match first (most deterministic).
|
|
35
|
+
if (normalizedQuery && normalizedQuery !== baseName) {
|
|
36
|
+
attempts.push([
|
|
37
|
+
".",
|
|
38
|
+
"-type",
|
|
39
|
+
"f",
|
|
40
|
+
"-path",
|
|
41
|
+
`./${normalizedQuery}`,
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
// Then basename match to recover from partial/incorrect relative paths.
|
|
45
|
+
if (baseName) {
|
|
46
|
+
attempts.push([".", "-type", "f", "-name", baseName]);
|
|
47
|
+
}
|
|
48
|
+
for (const args of attempts) {
|
|
49
|
+
try {
|
|
50
|
+
const { stdout } = await execFileAsync("find", args, {
|
|
51
|
+
cwd,
|
|
52
|
+
maxBuffer: 1024 * 1024 * 4,
|
|
53
|
+
});
|
|
54
|
+
const matches = stdout
|
|
55
|
+
.split(/\r?\n/)
|
|
56
|
+
.map((line) => line.trim())
|
|
57
|
+
.filter(Boolean)
|
|
58
|
+
.map((line) => path.resolve(cwd, line));
|
|
59
|
+
if (matches.length > 0) {
|
|
60
|
+
return rankFileCandidates(cwd, query, matches);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Ignore and continue to next fallback strategy.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return [];
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Tool for searching files and reading specific line ranges
|
|
71
|
+
* @param {Object} params - The parameters for searching files
|
|
72
|
+
* @param {string} [params.pattern] - Glob pattern to search for files
|
|
73
|
+
* @param {string} [params.filePath] - Specific file path to read (alternative to pattern)
|
|
74
|
+
* @param {number} [params.startLine] - Starting line number (1-indexed)
|
|
75
|
+
* @param {number} [params.endLine] - Ending line number (1-indexed)
|
|
76
|
+
* @param {string} [params.cwd] - Current working directory for search
|
|
77
|
+
* @param {string} [params.encoding='utf8'] - The encoding to use when reading the file
|
|
78
|
+
* @returns {Promise<Object>} Object containing success status and search results or file content
|
|
79
|
+
*/
|
|
80
|
+
export async function searchFiles({ pattern, filePath, startLine, endLine, cwd = process.cwd(), encoding = "utf8", }) {
|
|
81
|
+
try {
|
|
82
|
+
const requestedStartLine = startLine;
|
|
83
|
+
const requestedEndLine = endLine;
|
|
84
|
+
if (isNumber(requestedStartLine) || isNumber(requestedEndLine)) {
|
|
85
|
+
if (!isNumber(requestedStartLine) || !isNumber(requestedEndLine)) {
|
|
86
|
+
return {
|
|
87
|
+
success: false,
|
|
88
|
+
error: "Both startLine and endLine must be provided together",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (!Number.isInteger(requestedStartLine)
|
|
92
|
+
|| !Number.isInteger(requestedEndLine)
|
|
93
|
+
|| requestedStartLine < 1
|
|
94
|
+
|| requestedEndLine < 1) {
|
|
95
|
+
return {
|
|
96
|
+
success: false,
|
|
97
|
+
error: "startLine and endLine must be positive integers",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (requestedStartLine > requestedEndLine) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: "startLine cannot be greater than endLine",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const absoluteCwd = path.resolve(cwd);
|
|
108
|
+
// If filePath is provided, read that specific file
|
|
109
|
+
if (filePath) {
|
|
110
|
+
const absolutePath = path.isAbsolute(filePath)
|
|
111
|
+
? path.resolve(filePath)
|
|
112
|
+
: path.resolve(absoluteCwd, filePath);
|
|
113
|
+
// Reads are allowed outside the workspace root when the resolved path is
|
|
114
|
+
// directly readable, so callers can inspect sibling repos and shared files.
|
|
115
|
+
let readablePath = absolutePath;
|
|
116
|
+
let resolvedBy = "direct";
|
|
117
|
+
// Check if file exists
|
|
118
|
+
try {
|
|
119
|
+
await fs.access(readablePath, fs.constants.R_OK);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
const recoveryQueries = buildRecoveryQueries(filePath, absoluteCwd);
|
|
123
|
+
const safeRecoveredMatches = [];
|
|
124
|
+
let foundByRepoMap = false;
|
|
125
|
+
for (const query of recoveryQueries) {
|
|
126
|
+
const repoMapMatches = await findFilesViaRepoMap(cwd, query, 5);
|
|
127
|
+
const recoveredMatches = repoMapMatches.length > 0
|
|
128
|
+
? repoMapMatches
|
|
129
|
+
: await findFilesViaTerminal(cwd, query);
|
|
130
|
+
const safeMatches = recoveredMatches.filter((candidate) => isPathInsideBase(absoluteCwd, path.resolve(candidate)));
|
|
131
|
+
if (safeMatches.length > 0) {
|
|
132
|
+
safeRecoveredMatches.push(...safeMatches);
|
|
133
|
+
foundByRepoMap = repoMapMatches.length > 0;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (safeRecoveredMatches.length === 0) {
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
error: `File not found or not readable: ${filePath}`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
readablePath = safeRecoveredMatches[0];
|
|
144
|
+
resolvedBy = foundByRepoMap ? "repo_map" : "terminal_find";
|
|
145
|
+
}
|
|
146
|
+
// Read file content
|
|
147
|
+
const content = await fs.readFile(readablePath, encoding);
|
|
148
|
+
const lines = content.split("\n");
|
|
149
|
+
// Get stats
|
|
150
|
+
const stats = await fs.stat(readablePath);
|
|
151
|
+
// If line range is specified, extract those lines
|
|
152
|
+
if (startLine !== undefined && endLine !== undefined) {
|
|
153
|
+
const start = startLine - 1; // Convert to 0-indexed
|
|
154
|
+
const end = endLine;
|
|
155
|
+
if (start >= lines.length) {
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
error: `Start line ${startLine} exceeds file length (${lines.length} lines)`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const selectedLines = lines.slice(start, end);
|
|
162
|
+
return {
|
|
163
|
+
success: true,
|
|
164
|
+
filePath: readablePath,
|
|
165
|
+
resolvedBy,
|
|
166
|
+
startLine: start + 1,
|
|
167
|
+
endLine: Math.min(end, lines.length),
|
|
168
|
+
totalLines: lines.length,
|
|
169
|
+
content: selectedLines.join("\n"),
|
|
170
|
+
lines: selectedLines,
|
|
171
|
+
size: stats.size,
|
|
172
|
+
lastModified: stats.mtime,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Return entire file if no line range specified
|
|
176
|
+
return {
|
|
177
|
+
success: true,
|
|
178
|
+
filePath: readablePath,
|
|
179
|
+
resolvedBy,
|
|
180
|
+
totalLines: lines.length,
|
|
181
|
+
content,
|
|
182
|
+
lines,
|
|
183
|
+
size: stats.size,
|
|
184
|
+
lastModified: stats.mtime,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// If pattern is provided, search for matching files
|
|
188
|
+
if (pattern) {
|
|
189
|
+
let resolvedBy = "glob";
|
|
190
|
+
const { patterns, anchoredToRoot } = normalizeGlobPattern(pattern);
|
|
191
|
+
const fileSets = await Promise.all(patterns.map((singlePattern) => glob(singlePattern, {
|
|
192
|
+
cwd: absoluteCwd,
|
|
193
|
+
absolute: true,
|
|
194
|
+
nodir: true,
|
|
195
|
+
dot: true,
|
|
196
|
+
matchBase: !anchoredToRoot,
|
|
197
|
+
ignore: [
|
|
198
|
+
"**/node_modules/**",
|
|
199
|
+
"**/dist/**",
|
|
200
|
+
"**/build/**",
|
|
201
|
+
"**/.git/**",
|
|
202
|
+
],
|
|
203
|
+
})));
|
|
204
|
+
const files = Array.from(new Set(fileSets.flat().filter((candidate) => isPathInsideBase(absoluteCwd, path.resolve(candidate)))));
|
|
205
|
+
let resolvedFiles = files;
|
|
206
|
+
// Fallback to terminal file search for plain names/paths when glob misses.
|
|
207
|
+
if (resolvedFiles.length === 0 && !hasGlobMeta(pattern)) {
|
|
208
|
+
const repoMapMatches = await findFilesViaRepoMap(cwd, pattern, 50);
|
|
209
|
+
const fallbackFiles = repoMapMatches.length > 0
|
|
210
|
+
? repoMapMatches
|
|
211
|
+
: await findFilesViaTerminal(cwd, pattern);
|
|
212
|
+
resolvedFiles = fallbackFiles.filter((candidate) => isPathInsideBase(absoluteCwd, path.resolve(candidate)));
|
|
213
|
+
resolvedBy = repoMapMatches.length > 0 ? "repo_map" : "terminal_find";
|
|
214
|
+
}
|
|
215
|
+
else if (resolvedFiles.length > 1 && !hasGlobMeta(pattern)) {
|
|
216
|
+
resolvedFiles = await rankFileCandidates(cwd, pattern, resolvedFiles);
|
|
217
|
+
resolvedBy = "repo_map_ranked";
|
|
218
|
+
}
|
|
219
|
+
if (resolvedFiles.length === 0) {
|
|
220
|
+
return {
|
|
221
|
+
success: true,
|
|
222
|
+
message: "No files found matching the pattern",
|
|
223
|
+
pattern,
|
|
224
|
+
resolvedBy,
|
|
225
|
+
files: [],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// Get file details
|
|
229
|
+
const fileDetails = await Promise.all(resolvedFiles.map(async (file) => {
|
|
230
|
+
try {
|
|
231
|
+
const stats = await fs.stat(file);
|
|
232
|
+
return {
|
|
233
|
+
path: file,
|
|
234
|
+
relativePath: path.relative(absoluteCwd, file),
|
|
235
|
+
size: stats.size,
|
|
236
|
+
lastModified: stats.mtime,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
}));
|
|
243
|
+
const validFiles = fileDetails.filter((file) => file !== null);
|
|
244
|
+
return {
|
|
245
|
+
success: true,
|
|
246
|
+
pattern,
|
|
247
|
+
resolvedBy,
|
|
248
|
+
count: resolvedFiles.length,
|
|
249
|
+
files: validFiles,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
success: false,
|
|
254
|
+
error: "Either pattern or filePath must be provided",
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
const err = error;
|
|
259
|
+
return {
|
|
260
|
+
success: false,
|
|
261
|
+
error: err.message,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Tool metadata for agent system
|
|
267
|
+
*/
|
|
268
|
+
export const searchFilesTool = {
|
|
269
|
+
description: "Search for files using glob patterns or read specific line ranges from a file",
|
|
270
|
+
parameters: z.object({
|
|
271
|
+
pattern: z.string().optional().describe("Glob pattern to search for files (e.g., \"**/*.js\", \"src/**/*.json\")"),
|
|
272
|
+
filePath: z.string().optional().describe("Specific file path to read (alternative to pattern)"),
|
|
273
|
+
startLine: z.number().optional().describe("Starting line number to read (1-indexed, inclusive)"),
|
|
274
|
+
endLine: z.number().optional().describe("Ending line number to read (1-indexed, inclusive)"),
|
|
275
|
+
cwd: z.string().default(process.cwd()).describe("Current working directory for search"),
|
|
276
|
+
encoding: z.enum(["utf8", "ascii", "base64", "binary", "hex"]).default("utf8").describe("The encoding to use when reading the file"),
|
|
277
|
+
}),
|
|
278
|
+
execute: searchFiles,
|
|
279
|
+
};
|
|
280
|
+
export default searchFilesTool;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TerminalAutoApproveRules } from "../../library/terminalAutoApproveSettings.js";
|
|
2
|
+
export type TerminalApprovalPolicy = "always_prompt" | "auto_approve_safe";
|
|
3
|
+
export declare function shouldAutoApproveTerminalCommand(commandLine: string | undefined, customRuleConfig?: TerminalAutoApproveRules): boolean;
|