@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,313 @@
1
+ import { spawn } from "child_process";
2
+ import { z } from "zod";
3
+ const OUTPUT_LIMIT_BYTES = 64 * 1024;
4
+ const TERMINATION_GRACE_MS = 1500;
5
+ const TERMINAL_TASK_TTL_MS = 60 * 60 * 1000;
6
+ const MAX_TERMINAL_TASKS_RETAINED = 200;
7
+ const tasks = new Map();
8
+ let evictedTasksTotal = 0;
9
+ const getRetentionStats = () => ({
10
+ maxTerminalTasksRetained: MAX_TERMINAL_TASKS_RETAINED,
11
+ terminalTaskTtlMs: TERMINAL_TASK_TTL_MS,
12
+ evictedTasksTotal,
13
+ });
14
+ const sweepTerminalTasks = () => {
15
+ const now = Date.now();
16
+ const terminalEntries = Array.from(tasks.entries()).filter(([, task]) => ["completed", "failed", "stopped"].includes(task.status));
17
+ for (const [id, task] of terminalEntries) {
18
+ const terminalAt = task.endedAt || task.startedAt;
19
+ if (now - terminalAt > TERMINAL_TASK_TTL_MS) {
20
+ tasks.delete(id);
21
+ evictedTasksTotal += 1;
22
+ }
23
+ }
24
+ const remainingTerminal = Array.from(tasks.entries())
25
+ .filter(([, task]) => ["completed", "failed", "stopped"].includes(task.status))
26
+ .sort((a, b) => {
27
+ const aTime = a[1].endedAt || a[1].startedAt;
28
+ const bTime = b[1].endedAt || b[1].startedAt;
29
+ return bTime - aTime;
30
+ });
31
+ if (remainingTerminal.length > MAX_TERMINAL_TASKS_RETAINED) {
32
+ const overflow = remainingTerminal.slice(MAX_TERMINAL_TASKS_RETAINED);
33
+ for (const [id] of overflow) {
34
+ tasks.delete(id);
35
+ evictedTasksTotal += 1;
36
+ }
37
+ }
38
+ };
39
+ const waitForProcessExit = async (child, timeoutMs) => {
40
+ if (child.exitCode !== null || child.signalCode !== null) {
41
+ return true;
42
+ }
43
+ return await new Promise((resolve) => {
44
+ let settled = false;
45
+ const finish = () => {
46
+ if (settled)
47
+ return;
48
+ settled = true;
49
+ clearTimeout(timer);
50
+ child.off("close", finish);
51
+ child.off("exit", finish);
52
+ resolve(true);
53
+ };
54
+ const timer = setTimeout(() => {
55
+ if (settled)
56
+ return;
57
+ settled = true;
58
+ child.off("close", finish);
59
+ child.off("exit", finish);
60
+ resolve(false);
61
+ }, timeoutMs);
62
+ child.once("close", finish);
63
+ child.once("exit", finish);
64
+ });
65
+ };
66
+ const taskKillOnWindows = async (pid, force) => {
67
+ return await new Promise((resolve) => {
68
+ const args = ["/PID", String(pid), "/T", ...(force ? ["/F"] : [])];
69
+ const killer = spawn("taskkill", args, {
70
+ windowsHide: true,
71
+ stdio: "ignore",
72
+ });
73
+ killer.on("error", () => resolve(false));
74
+ killer.on("close", (code) => resolve(code === 0));
75
+ });
76
+ };
77
+ const sendTerminationSignal = async (task, force) => {
78
+ const pid = task.pid;
79
+ if (!pid)
80
+ return false;
81
+ if (process.platform === "win32") {
82
+ return taskKillOnWindows(pid, force);
83
+ }
84
+ try {
85
+ const signal = force ? "SIGKILL" : "SIGTERM";
86
+ if (task.usesProcessGroup) {
87
+ process.kill(-pid, signal);
88
+ return true;
89
+ }
90
+ process.kill(pid, signal);
91
+ return true;
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ };
97
+ const terminateTaskProcess = async (task) => {
98
+ const child = task.process;
99
+ if (!child)
100
+ return true;
101
+ await sendTerminationSignal(task, false);
102
+ let exited = await waitForProcessExit(child, TERMINATION_GRACE_MS);
103
+ if (exited)
104
+ return true;
105
+ await sendTerminationSignal(task, true);
106
+ exited = await waitForProcessExit(child, TERMINATION_GRACE_MS);
107
+ return exited;
108
+ };
109
+ export const __resetBackgroundTasksForTests = async () => {
110
+ const runningTasks = Array.from(tasks.values()).filter((task) => task.status === "running");
111
+ await Promise.all(runningTasks.map(async (task) => {
112
+ task.status = "stopped";
113
+ task.endedAt = Date.now();
114
+ task.stopReason = "Stopped by test reset";
115
+ appendTaskOutput(task, "\n[background-task-stop] Stopped by test reset\n");
116
+ await terminateTaskProcess(task);
117
+ }));
118
+ tasks.clear();
119
+ evictedTasksTotal = 0;
120
+ };
121
+ const trimUtf8TailToByteLimit = (input, maxBytes) => {
122
+ if (maxBytes <= 0)
123
+ return "";
124
+ const buffer = Buffer.from(input, "utf8");
125
+ if (buffer.length <= maxBytes) {
126
+ return input;
127
+ }
128
+ let start = buffer.length - maxBytes;
129
+ // Avoid starting in the middle of a UTF-8 continuation sequence.
130
+ while (start < buffer.length && (buffer[start] & 0b11000000) === 0b10000000) {
131
+ start += 1;
132
+ }
133
+ return buffer.subarray(start).toString("utf8");
134
+ };
135
+ const appendTaskOutput = (task, chunk) => {
136
+ if (!chunk)
137
+ return;
138
+ const nextOutput = task.output + chunk;
139
+ if (Buffer.byteLength(nextOutput, "utf8") <= OUTPUT_LIMIT_BYTES) {
140
+ task.output = nextOutput;
141
+ return;
142
+ }
143
+ task.outputTruncated = true;
144
+ task.output = trimUtf8TailToByteLimit(nextOutput, OUTPUT_LIMIT_BYTES);
145
+ };
146
+ const makeTaskId = () => `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
147
+ export const startBackgroundTask = ({ command, cwd, env = {}, description, }) => {
148
+ sweepTerminalTasks();
149
+ const id = makeTaskId();
150
+ const usesProcessGroup = process.platform !== "win32";
151
+ const child = spawn(command, {
152
+ cwd,
153
+ env: { ...process.env, ...env },
154
+ shell: true,
155
+ detached: usesProcessGroup,
156
+ });
157
+ const task = {
158
+ id,
159
+ command,
160
+ cwd,
161
+ description: description || command,
162
+ status: "running",
163
+ startedAt: Date.now(),
164
+ output: "",
165
+ outputTruncated: false,
166
+ pid: child.pid,
167
+ process: child,
168
+ usesProcessGroup,
169
+ };
170
+ tasks.set(id, task);
171
+ child.stdout?.on("data", (data) => {
172
+ appendTaskOutput(task, data.toString());
173
+ });
174
+ child.stderr?.on("data", (data) => {
175
+ appendTaskOutput(task, data.toString());
176
+ });
177
+ child.on("error", (error) => {
178
+ appendTaskOutput(task, `\n[background-task-error] ${error.message}\n`);
179
+ task.status = "failed";
180
+ task.endedAt = Date.now();
181
+ task.exitCode = 1;
182
+ });
183
+ child.on("close", (code, signal) => {
184
+ if (task.status === "stopped") {
185
+ task.endedAt = task.endedAt || Date.now();
186
+ task.exitCode = code;
187
+ task.signal = signal;
188
+ task.process = undefined;
189
+ return;
190
+ }
191
+ task.status = code === 0 ? "completed" : "failed";
192
+ task.endedAt = Date.now();
193
+ task.exitCode = code;
194
+ task.signal = signal;
195
+ task.process = undefined;
196
+ });
197
+ return {
198
+ success: true,
199
+ status: "in_progress",
200
+ taskId: id,
201
+ pid: child.pid,
202
+ command,
203
+ cwd,
204
+ description: task.description,
205
+ startedAt: task.startedAt,
206
+ message: `Started background task ${id}`,
207
+ };
208
+ };
209
+ export const listBackgroundTasks = ({ activeOnly = true, limit = 20, }) => {
210
+ sweepTerminalTasks();
211
+ const ordered = Array.from(tasks.values())
212
+ .filter((task) => (activeOnly ? task.status === "running" : true))
213
+ .sort((a, b) => b.startedAt - a.startedAt)
214
+ .slice(0, Math.max(1, Math.min(limit, 100)));
215
+ return ordered.map((task) => ({
216
+ taskId: task.id,
217
+ command: task.command,
218
+ description: task.description,
219
+ cwd: task.cwd,
220
+ status: task.status,
221
+ startedAt: task.startedAt,
222
+ endedAt: task.endedAt,
223
+ pid: task.pid,
224
+ exitCode: task.exitCode,
225
+ signal: task.signal,
226
+ retention: getRetentionStats(),
227
+ }));
228
+ };
229
+ export const getBackgroundTaskOutput = ({ taskId, tailChars = 3000, }) => {
230
+ sweepTerminalTasks();
231
+ const task = tasks.get(taskId);
232
+ if (!task) {
233
+ return {
234
+ success: false,
235
+ error: `Background task '${taskId}' not found`,
236
+ };
237
+ }
238
+ const normalizedTailChars = Math.max(256, Math.min(tailChars, 20000));
239
+ return {
240
+ success: true,
241
+ taskId,
242
+ status: task.status,
243
+ command: task.command,
244
+ description: task.description,
245
+ startedAt: task.startedAt,
246
+ endedAt: task.endedAt,
247
+ exitCode: task.exitCode,
248
+ signal: task.signal,
249
+ output: task.output.slice(-normalizedTailChars),
250
+ outputTruncated: task.outputTruncated || task.output.length > normalizedTailChars,
251
+ totalOutputChars: task.output.length,
252
+ retention: getRetentionStats(),
253
+ };
254
+ };
255
+ export const stopBackgroundTask = ({ taskId, reason = "Stopped by TaskStop", }) => {
256
+ sweepTerminalTasks();
257
+ const task = tasks.get(taskId);
258
+ if (!task) {
259
+ return {
260
+ success: false,
261
+ error: `Background task '${taskId}' not found`,
262
+ };
263
+ }
264
+ if (task.status !== "running") {
265
+ return {
266
+ success: true,
267
+ taskId,
268
+ status: task.status,
269
+ message: `Task ${taskId} is already in terminal status '${task.status}'`,
270
+ };
271
+ }
272
+ task.status = "stopped";
273
+ task.endedAt = Date.now();
274
+ task.stopReason = reason;
275
+ appendTaskOutput(task, `\n[background-task-stop] ${reason}\n`);
276
+ return terminateTaskProcess(task).then((killed) => ({
277
+ success: true,
278
+ taskId,
279
+ status: task.status,
280
+ killed,
281
+ reason,
282
+ retention: getRetentionStats(),
283
+ message: `Stop signal sent to task ${taskId}`,
284
+ }));
285
+ };
286
+ export const taskListTool = {
287
+ description: "List background tasks started with runInBackground. Use activeOnly=true by default.",
288
+ parameters: z.object({
289
+ activeOnly: z.boolean().default(true),
290
+ limit: z.number().min(1).max(100).default(20),
291
+ }),
292
+ execute: async ({ activeOnly = true, limit = 20 }) => ({
293
+ success: true,
294
+ tasks: listBackgroundTasks({ activeOnly, limit }),
295
+ retention: getRetentionStats(),
296
+ }),
297
+ };
298
+ export const taskOutputTool = {
299
+ description: "Get non-blocking status and output snapshot for a background task.",
300
+ parameters: z.object({
301
+ taskId: z.string().describe("Background task ID"),
302
+ tailChars: z.number().min(256).max(20000).default(3000),
303
+ }),
304
+ execute: async ({ taskId, tailChars = 3000 }) => getBackgroundTaskOutput({ taskId, tailChars }),
305
+ };
306
+ export const taskStopTool = {
307
+ description: "Stop a running background task by task ID.",
308
+ parameters: z.object({
309
+ taskId: z.string().describe("Background task ID"),
310
+ reason: z.string().default("Stopped by TaskStop"),
311
+ }),
312
+ execute: async ({ taskId, reason = "Stopped by TaskStop" }) => await stopBackgroundTask({ taskId, reason }),
313
+ };
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ type CreateDirectoryParams = {
3
+ dirPath: string;
4
+ recursive?: boolean;
5
+ };
6
+ type CreateDirectorySuccessResult = {
7
+ success: true;
8
+ dirPath: string;
9
+ created?: Date;
10
+ alreadyExists: boolean;
11
+ message: string;
12
+ };
13
+ type CreateDirectoryErrorResult = {
14
+ success: false;
15
+ error: string;
16
+ };
17
+ type CreateDirectoryResult = CreateDirectorySuccessResult | CreateDirectoryErrorResult;
18
+ /**
19
+ * Tool for creating directories
20
+ * @param {Object} params - The parameters for creating a directory
21
+ * @param {string} params.dirPath - The path to the directory to create
22
+ * @param {boolean} [params.recursive=true] - Whether to create parent directories
23
+ * @returns {Promise<Object>} Object containing success status and directory info or error
24
+ */
25
+ export declare function createDirectory({ dirPath, recursive, }: CreateDirectoryParams): Promise<CreateDirectoryResult>;
26
+ /**
27
+ * Tool metadata for agent system
28
+ */
29
+ export declare const createDirectoryTool: {
30
+ description: string;
31
+ parameters: z.ZodObject<{
32
+ dirPath: z.ZodString;
33
+ recursive: z.ZodDefault<z.ZodBoolean>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ recursive?: boolean;
36
+ dirPath?: string;
37
+ }, {
38
+ recursive?: boolean;
39
+ dirPath?: string;
40
+ }>;
41
+ execute: typeof createDirectory;
42
+ };
43
+ export default createDirectoryTool;
@@ -0,0 +1,77 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import { z } from "zod";
4
+ /**
5
+ * Tool for creating directories
6
+ * @param {Object} params - The parameters for creating a directory
7
+ * @param {string} params.dirPath - The path to the directory to create
8
+ * @param {boolean} [params.recursive=true] - Whether to create parent directories
9
+ * @returns {Promise<Object>} Object containing success status and directory info or error
10
+ */
11
+ export async function createDirectory({ dirPath, recursive = true, }) {
12
+ try {
13
+ // Validate input
14
+ if (!dirPath) {
15
+ return {
16
+ success: false,
17
+ error: "Directory path is required",
18
+ };
19
+ }
20
+ // Resolve to absolute path
21
+ const absolutePath = path.resolve(dirPath);
22
+ // Check if directory already exists
23
+ try {
24
+ const stats = await fs.stat(absolutePath);
25
+ if (stats.isDirectory()) {
26
+ return {
27
+ success: true,
28
+ dirPath: absolutePath,
29
+ alreadyExists: true,
30
+ message: "Directory already exists",
31
+ };
32
+ }
33
+ else {
34
+ return {
35
+ success: false,
36
+ error: "Path exists but is not a directory",
37
+ };
38
+ }
39
+ }
40
+ catch (err) {
41
+ // Directory doesn't exist, continue with creation
42
+ }
43
+ // Create the directory
44
+ await fs.mkdir(absolutePath, { recursive });
45
+ // Get directory stats
46
+ const stats = await fs.stat(absolutePath);
47
+ return {
48
+ success: true,
49
+ dirPath: absolutePath,
50
+ created: stats.birthtime,
51
+ alreadyExists: false,
52
+ message: "Directory created successfully",
53
+ };
54
+ }
55
+ catch (error) {
56
+ const err = error;
57
+ return {
58
+ success: false,
59
+ error: err.message,
60
+ };
61
+ }
62
+ }
63
+ /**
64
+ * Tool metadata for agent system
65
+ */
66
+ export const createDirectoryTool = {
67
+ description: "Create a new directory, optionally creating parent directories",
68
+ parameters: z.object({
69
+ dirPath: z.string().describe("The path to the directory to create"),
70
+ recursive: z
71
+ .boolean()
72
+ .default(true)
73
+ .describe("Whether to create parent directories if they don't exist"),
74
+ }),
75
+ execute: createDirectory,
76
+ };
77
+ export default createDirectoryTool;
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ type DeleteFileParams = {
3
+ filePath: string;
4
+ };
5
+ type DeleteFileSuccessResult = {
6
+ success: true;
7
+ filePath: string;
8
+ deletedSize: number;
9
+ message: string;
10
+ };
11
+ type DeleteFileErrorResult = {
12
+ success: false;
13
+ error: string;
14
+ };
15
+ type DeleteFileResult = DeleteFileSuccessResult | DeleteFileErrorResult;
16
+ /**
17
+ * Tool for deleting files
18
+ * @param {Object} params - The parameters for deleting a file
19
+ * @param {string} params.filePath - The path to the file to delete
20
+ * @returns {Promise<Object>} Object containing success status and deletion info or error
21
+ */
22
+ export declare function deleteFile({ filePath, }: DeleteFileParams): Promise<DeleteFileResult>;
23
+ /**
24
+ * Tool metadata for agent system
25
+ */
26
+ export declare const deleteFileTool: {
27
+ description: string;
28
+ parameters: z.ZodObject<{
29
+ filePath: z.ZodString;
30
+ }, "strip", z.ZodTypeAny, {
31
+ filePath?: string;
32
+ }, {
33
+ filePath?: string;
34
+ }>;
35
+ execute: typeof deleteFile;
36
+ };
37
+ export default deleteFileTool;
@@ -0,0 +1,66 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import { z } from "zod";
4
+ /**
5
+ * Tool for deleting files
6
+ * @param {Object} params - The parameters for deleting a file
7
+ * @param {string} params.filePath - The path to the file to delete
8
+ * @returns {Promise<Object>} Object containing success status and deletion info or error
9
+ */
10
+ export async function deleteFile({ filePath, }) {
11
+ try {
12
+ // Validate input
13
+ if (!filePath) {
14
+ return {
15
+ success: false,
16
+ error: "File path is required",
17
+ };
18
+ }
19
+ // Resolve to absolute path
20
+ const absolutePath = path.resolve(filePath);
21
+ // Check if file exists
22
+ try {
23
+ await fs.access(absolutePath, fs.constants.F_OK);
24
+ }
25
+ catch (err) {
26
+ return {
27
+ success: false,
28
+ error: `File not found: ${filePath}`,
29
+ };
30
+ }
31
+ // Get file stats before deletion
32
+ const stats = await fs.stat(absolutePath);
33
+ if (!stats.isFile()) {
34
+ return {
35
+ success: false,
36
+ error: `Path is not a file: ${filePath}`,
37
+ };
38
+ }
39
+ // Delete the file
40
+ await fs.unlink(absolutePath);
41
+ return {
42
+ success: true,
43
+ filePath: absolutePath,
44
+ deletedSize: stats.size,
45
+ message: "File deleted successfully",
46
+ };
47
+ }
48
+ catch (error) {
49
+ const err = error;
50
+ return {
51
+ success: false,
52
+ error: err.message,
53
+ };
54
+ }
55
+ }
56
+ /**
57
+ * Tool metadata for agent system
58
+ */
59
+ export const deleteFileTool = {
60
+ description: "Delete a file from the file system",
61
+ parameters: z.object({
62
+ filePath: z.string().describe("The path to the file to delete"),
63
+ }),
64
+ execute: deleteFile,
65
+ };
66
+ export default deleteFileTool;
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ type EditFileParams = {
3
+ filePath: string;
4
+ oldContent?: string;
5
+ newContent?: string;
6
+ startLine?: number;
7
+ endLine?: number;
8
+ lineContent?: string;
9
+ encoding?: BufferEncoding;
10
+ };
11
+ type EditFileSuccessResult = {
12
+ success: true;
13
+ filePath: string;
14
+ fileExisted: true;
15
+ size: number;
16
+ modified: Date;
17
+ linesAdded: number;
18
+ linesRemoved: number;
19
+ diff: string;
20
+ oldContent: string;
21
+ newContent: string;
22
+ };
23
+ type EditFileErrorResult = {
24
+ success: false;
25
+ error: string;
26
+ };
27
+ type EditFileResult = EditFileSuccessResult | EditFileErrorResult;
28
+ /**
29
+ * Tool for editing files by replacing content or specific lines
30
+ * @param {Object} params - The parameters for editing a file
31
+ * @param {string} params.filePath - The path to the file to edit
32
+ * @param {string} [params.oldContent] - The old content to replace (must match exactly)
33
+ * @param {string} [params.newContent] - The new content to replace with
34
+ * @param {number} [params.startLine] - Starting line number to replace (1-indexed)
35
+ * @param {number} [params.endLine] - Ending line number to replace (1-indexed)
36
+ * @param {string} [params.lineContent] - New content for the line range
37
+ * @param {string} [params.encoding='utf8'] - The encoding to use
38
+ * @returns {Promise<Object>} Object containing success status and edit info or error
39
+ */
40
+ export declare function editFile({ filePath, oldContent, newContent, startLine, endLine, lineContent, encoding, }: EditFileParams): Promise<EditFileResult>;
41
+ /**
42
+ * Tool metadata for agent system
43
+ */
44
+ export declare const editFileTool: {
45
+ description: string;
46
+ parameters: z.ZodObject<{
47
+ filePath: z.ZodString;
48
+ oldContent: z.ZodOptional<z.ZodString>;
49
+ newContent: z.ZodOptional<z.ZodString>;
50
+ startLine: z.ZodOptional<z.ZodNumber>;
51
+ endLine: z.ZodOptional<z.ZodNumber>;
52
+ lineContent: z.ZodOptional<z.ZodString>;
53
+ encoding: z.ZodDefault<z.ZodEnum<["utf8", "ascii", "base64", "binary", "hex"]>>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ encoding?: "ascii" | "utf8" | "base64" | "binary" | "hex";
56
+ filePath?: string;
57
+ startLine?: number;
58
+ endLine?: number;
59
+ oldContent?: string;
60
+ newContent?: string;
61
+ lineContent?: string;
62
+ }, {
63
+ encoding?: "ascii" | "utf8" | "base64" | "binary" | "hex";
64
+ filePath?: string;
65
+ startLine?: number;
66
+ endLine?: number;
67
+ oldContent?: string;
68
+ newContent?: string;
69
+ lineContent?: string;
70
+ }>;
71
+ execute: typeof editFile;
72
+ };
73
+ export default editFileTool;