@clinebot/core 0.0.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 (200) hide show
  1. package/README.md +88 -0
  2. package/dist/account/cline-account-service.d.ts +34 -0
  3. package/dist/account/index.d.ts +3 -0
  4. package/dist/account/rpc.d.ts +38 -0
  5. package/dist/account/types.d.ts +74 -0
  6. package/dist/agents/agent-config-loader.d.ts +18 -0
  7. package/dist/agents/agent-config-parser.d.ts +25 -0
  8. package/dist/agents/hooks-config-loader.d.ts +23 -0
  9. package/dist/agents/index.d.ts +11 -0
  10. package/dist/agents/plugin-config-loader.d.ts +22 -0
  11. package/dist/agents/plugin-loader.d.ts +9 -0
  12. package/dist/agents/plugin-sandbox.d.ts +12 -0
  13. package/dist/agents/unified-config-file-watcher.d.ts +77 -0
  14. package/dist/agents/user-instruction-config-loader.d.ts +63 -0
  15. package/dist/auth/client.d.ts +11 -0
  16. package/dist/auth/cline.d.ts +41 -0
  17. package/dist/auth/codex.d.ts +39 -0
  18. package/dist/auth/oca.d.ts +22 -0
  19. package/dist/auth/server.d.ts +22 -0
  20. package/dist/auth/types.d.ts +72 -0
  21. package/dist/auth/utils.d.ts +32 -0
  22. package/dist/chat/chat-schema.d.ts +145 -0
  23. package/dist/default-tools/constants.d.ts +23 -0
  24. package/dist/default-tools/definitions.d.ts +96 -0
  25. package/dist/default-tools/executors/apply-patch-parser.d.ts +68 -0
  26. package/dist/default-tools/executors/apply-patch.d.ts +26 -0
  27. package/dist/default-tools/executors/bash.d.ts +49 -0
  28. package/dist/default-tools/executors/editor.d.ts +31 -0
  29. package/dist/default-tools/executors/file-read.d.ts +40 -0
  30. package/dist/default-tools/executors/index.d.ts +44 -0
  31. package/dist/default-tools/executors/search.d.ts +50 -0
  32. package/dist/default-tools/executors/web-fetch.d.ts +58 -0
  33. package/dist/default-tools/index.d.ts +57 -0
  34. package/dist/default-tools/presets.d.ts +124 -0
  35. package/dist/default-tools/schemas.d.ts +121 -0
  36. package/dist/default-tools/types.d.ts +237 -0
  37. package/dist/index.d.ts +23 -0
  38. package/dist/index.js +220 -0
  39. package/dist/input/file-indexer.d.ts +5 -0
  40. package/dist/input/index.d.ts +4 -0
  41. package/dist/input/mention-enricher.d.ts +12 -0
  42. package/dist/mcp/config-loader.d.ts +15 -0
  43. package/dist/mcp/index.d.ts +4 -0
  44. package/dist/mcp/manager.d.ts +24 -0
  45. package/dist/mcp/types.d.ts +66 -0
  46. package/dist/runtime/hook-file-hooks.d.ts +18 -0
  47. package/dist/runtime/rules.d.ts +5 -0
  48. package/dist/runtime/runtime-builder.d.ts +5 -0
  49. package/dist/runtime/sandbox/subprocess-sandbox.d.ts +19 -0
  50. package/dist/runtime/session-runtime.d.ts +36 -0
  51. package/dist/runtime/tool-approval.d.ts +9 -0
  52. package/dist/runtime/workflows.d.ts +13 -0
  53. package/dist/server/index.d.ts +47 -0
  54. package/dist/server/index.js +641 -0
  55. package/dist/session/default-session-manager.d.ts +77 -0
  56. package/dist/session/rpc-session-service.d.ts +12 -0
  57. package/dist/session/runtime-oauth-token-manager.d.ts +28 -0
  58. package/dist/session/session-artifacts.d.ts +19 -0
  59. package/dist/session/session-graph.d.ts +15 -0
  60. package/dist/session/session-host.d.ts +21 -0
  61. package/dist/session/session-manager.d.ts +50 -0
  62. package/dist/session/session-manifest.d.ts +30 -0
  63. package/dist/session/session-service.d.ts +113 -0
  64. package/dist/session/sqlite-rpc-session-backend.d.ts +30 -0
  65. package/dist/session/unified-session-persistence-service.d.ts +93 -0
  66. package/dist/session/workspace-manager.d.ts +28 -0
  67. package/dist/session/workspace-manifest.d.ts +25 -0
  68. package/dist/storage/provider-settings-legacy-migration.d.ts +13 -0
  69. package/dist/storage/provider-settings-manager.d.ts +20 -0
  70. package/dist/storage/sqlite-session-store.d.ts +29 -0
  71. package/dist/storage/sqlite-team-store.d.ts +31 -0
  72. package/dist/storage/team-store.d.ts +2 -0
  73. package/dist/team/index.d.ts +1 -0
  74. package/dist/team/projections.d.ts +8 -0
  75. package/dist/types/common.d.ts +10 -0
  76. package/dist/types/config.d.ts +37 -0
  77. package/dist/types/events.d.ts +54 -0
  78. package/dist/types/provider-settings.d.ts +20 -0
  79. package/dist/types/sessions.d.ts +9 -0
  80. package/dist/types/storage.d.ts +37 -0
  81. package/dist/types/workspace.d.ts +7 -0
  82. package/dist/types.d.ts +26 -0
  83. package/package.json +63 -0
  84. package/src/account/cline-account-service.test.ts +101 -0
  85. package/src/account/cline-account-service.ts +267 -0
  86. package/src/account/index.ts +20 -0
  87. package/src/account/rpc.test.ts +62 -0
  88. package/src/account/rpc.ts +172 -0
  89. package/src/account/types.ts +80 -0
  90. package/src/agents/agent-config-loader.test.ts +234 -0
  91. package/src/agents/agent-config-loader.ts +107 -0
  92. package/src/agents/agent-config-parser.ts +191 -0
  93. package/src/agents/hooks-config-loader.ts +97 -0
  94. package/src/agents/index.ts +84 -0
  95. package/src/agents/plugin-config-loader.test.ts +91 -0
  96. package/src/agents/plugin-config-loader.ts +160 -0
  97. package/src/agents/plugin-loader.test.ts +102 -0
  98. package/src/agents/plugin-loader.ts +105 -0
  99. package/src/agents/plugin-sandbox.test.ts +120 -0
  100. package/src/agents/plugin-sandbox.ts +471 -0
  101. package/src/agents/unified-config-file-watcher.test.ts +196 -0
  102. package/src/agents/unified-config-file-watcher.ts +483 -0
  103. package/src/agents/user-instruction-config-loader.test.ts +158 -0
  104. package/src/agents/user-instruction-config-loader.ts +438 -0
  105. package/src/auth/client.test.ts +40 -0
  106. package/src/auth/client.ts +25 -0
  107. package/src/auth/cline.test.ts +130 -0
  108. package/src/auth/cline.ts +414 -0
  109. package/src/auth/codex.test.ts +170 -0
  110. package/src/auth/codex.ts +466 -0
  111. package/src/auth/oca.test.ts +215 -0
  112. package/src/auth/oca.ts +546 -0
  113. package/src/auth/server.ts +216 -0
  114. package/src/auth/types.ts +78 -0
  115. package/src/auth/utils.test.ts +128 -0
  116. package/src/auth/utils.ts +247 -0
  117. package/src/chat/chat-schema.ts +82 -0
  118. package/src/default-tools/constants.ts +35 -0
  119. package/src/default-tools/definitions.test.ts +233 -0
  120. package/src/default-tools/definitions.ts +632 -0
  121. package/src/default-tools/executors/apply-patch-parser.ts +520 -0
  122. package/src/default-tools/executors/apply-patch.ts +359 -0
  123. package/src/default-tools/executors/bash.ts +205 -0
  124. package/src/default-tools/executors/editor.ts +231 -0
  125. package/src/default-tools/executors/file-read.test.ts +25 -0
  126. package/src/default-tools/executors/file-read.ts +94 -0
  127. package/src/default-tools/executors/index.ts +75 -0
  128. package/src/default-tools/executors/search.ts +278 -0
  129. package/src/default-tools/executors/web-fetch.ts +259 -0
  130. package/src/default-tools/index.ts +161 -0
  131. package/src/default-tools/presets.test.ts +63 -0
  132. package/src/default-tools/presets.ts +168 -0
  133. package/src/default-tools/schemas.ts +228 -0
  134. package/src/default-tools/types.ts +324 -0
  135. package/src/index.ts +119 -0
  136. package/src/input/file-indexer.d.ts +11 -0
  137. package/src/input/file-indexer.test.ts +87 -0
  138. package/src/input/file-indexer.ts +280 -0
  139. package/src/input/index.ts +7 -0
  140. package/src/input/mention-enricher.test.ts +82 -0
  141. package/src/input/mention-enricher.ts +119 -0
  142. package/src/mcp/config-loader.test.ts +238 -0
  143. package/src/mcp/config-loader.ts +219 -0
  144. package/src/mcp/index.ts +26 -0
  145. package/src/mcp/manager.test.ts +106 -0
  146. package/src/mcp/manager.ts +262 -0
  147. package/src/mcp/types.ts +88 -0
  148. package/src/runtime/hook-file-hooks.test.ts +106 -0
  149. package/src/runtime/hook-file-hooks.ts +736 -0
  150. package/src/runtime/index.ts +27 -0
  151. package/src/runtime/rules.ts +34 -0
  152. package/src/runtime/runtime-builder.team-persistence.test.ts +203 -0
  153. package/src/runtime/runtime-builder.test.ts +215 -0
  154. package/src/runtime/runtime-builder.ts +515 -0
  155. package/src/runtime/runtime-parity.test.ts +132 -0
  156. package/src/runtime/sandbox/subprocess-sandbox.ts +207 -0
  157. package/src/runtime/session-runtime.ts +44 -0
  158. package/src/runtime/tool-approval.ts +104 -0
  159. package/src/runtime/workflows.test.ts +119 -0
  160. package/src/runtime/workflows.ts +54 -0
  161. package/src/server/index.ts +282 -0
  162. package/src/session/default-session-manager.e2e.test.ts +354 -0
  163. package/src/session/default-session-manager.test.ts +816 -0
  164. package/src/session/default-session-manager.ts +1286 -0
  165. package/src/session/index.ts +37 -0
  166. package/src/session/rpc-session-service.ts +189 -0
  167. package/src/session/runtime-oauth-token-manager.test.ts +137 -0
  168. package/src/session/runtime-oauth-token-manager.ts +265 -0
  169. package/src/session/session-artifacts.ts +106 -0
  170. package/src/session/session-graph.ts +90 -0
  171. package/src/session/session-host.ts +190 -0
  172. package/src/session/session-manager.ts +56 -0
  173. package/src/session/session-manifest.ts +29 -0
  174. package/src/session/session-service.team-persistence.test.ts +48 -0
  175. package/src/session/session-service.ts +610 -0
  176. package/src/session/sqlite-rpc-session-backend.ts +303 -0
  177. package/src/session/unified-session-persistence-service.ts +781 -0
  178. package/src/session/workspace-manager.ts +98 -0
  179. package/src/session/workspace-manifest.ts +100 -0
  180. package/src/storage/artifact-store.ts +1 -0
  181. package/src/storage/index.ts +11 -0
  182. package/src/storage/provider-settings-legacy-migration.test.ts +175 -0
  183. package/src/storage/provider-settings-legacy-migration.ts +637 -0
  184. package/src/storage/provider-settings-manager.test.ts +111 -0
  185. package/src/storage/provider-settings-manager.ts +129 -0
  186. package/src/storage/session-store.ts +1 -0
  187. package/src/storage/sqlite-session-store.ts +270 -0
  188. package/src/storage/sqlite-team-store.ts +443 -0
  189. package/src/storage/team-store.ts +5 -0
  190. package/src/team/index.ts +4 -0
  191. package/src/team/projections.ts +285 -0
  192. package/src/types/common.ts +14 -0
  193. package/src/types/config.ts +64 -0
  194. package/src/types/events.ts +46 -0
  195. package/src/types/index.ts +24 -0
  196. package/src/types/provider-settings.ts +43 -0
  197. package/src/types/sessions.ts +16 -0
  198. package/src/types/storage.ts +64 -0
  199. package/src/types/workspace.ts +7 -0
  200. package/src/types.ts +127 -0
@@ -0,0 +1,632 @@
1
+ /**
2
+ * Default Tool Definitions
3
+ *
4
+ * Factory functions for creating the default tools.
5
+ */
6
+
7
+ import { createTool, type Tool } from "@clinebot/agents";
8
+ import { validateWithZod, zodToJsonSchema } from "@clinebot/shared";
9
+ import {
10
+ type ApplyPatchInput,
11
+ ApplyPatchInputSchema,
12
+ ApplyPatchInputUnionSchema,
13
+ type AskQuestionInput,
14
+ AskQuestionInputSchema,
15
+ type EditFileInput,
16
+ EditFileInputSchema,
17
+ type FetchWebContentInput,
18
+ FetchWebContentInputSchema,
19
+ type ReadFilesInput,
20
+ ReadFilesInputSchema,
21
+ ReadFilesInputUnionSchema,
22
+ type RunCommandsInput,
23
+ RunCommandsInputSchema,
24
+ RunCommandsInputUnionSchema,
25
+ type SearchCodebaseInput,
26
+ SearchCodebaseInputSchema,
27
+ type SkillsInput,
28
+ SkillsInputSchema,
29
+ } from "./schemas.js";
30
+ import type {
31
+ ApplyPatchExecutor,
32
+ AskQuestionExecutor,
33
+ BashExecutor,
34
+ CreateDefaultToolsOptions,
35
+ DefaultToolsConfig,
36
+ EditorExecutor,
37
+ FileReadExecutor,
38
+ SearchExecutor,
39
+ SkillsExecutor,
40
+ ToolOperationResult,
41
+ WebFetchExecutor,
42
+ } from "./types.js";
43
+
44
+ // =============================================================================
45
+ // Helper Functions
46
+ // =============================================================================
47
+
48
+ /**
49
+ * Format an error into a string message
50
+ */
51
+ function formatError(error: unknown): string {
52
+ if (error instanceof Error) {
53
+ return error.message;
54
+ }
55
+ return String(error);
56
+ }
57
+
58
+ /**
59
+ * Create a timeout-wrapped promise
60
+ */
61
+ function withTimeout<T>(
62
+ promise: Promise<T>,
63
+ ms: number,
64
+ message: string,
65
+ ): Promise<T> {
66
+ return Promise.race([
67
+ promise,
68
+ new Promise<never>((_, reject) => {
69
+ setTimeout(() => reject(new Error(message)), ms);
70
+ }),
71
+ ]);
72
+ }
73
+
74
+ const APPLY_PATCH_TOOL_DESC = `This is a custom utility that makes it more convenient to add, remove, move, or edit code in a single file. \`apply_patch\` effectively allows you to execute a diff/patch against a file, but the format of the diff specification is unique to this task, so pay careful attention to these instructions. To use the \`apply_patch\` command, you should pass a message of the following structure as "input":
75
+
76
+ %%bash
77
+ apply_patch <<"EOF"
78
+ *** Begin Patch
79
+ [YOUR_PATCH]
80
+ *** End Patch
81
+ EOF
82
+
83
+ Where [YOUR_PATCH] is the actual content of your patch, specified in the following V4A diff format.
84
+
85
+ *** [ACTION] File: [path/to/file] -> ACTION can be one of Add, Update, or Delete.
86
+
87
+ In a Add File section, every line of the new file (including blank/empty lines) MUST start with a \`+\` prefix. Do not include any unprefixed lines inside an Add section
88
+ In a Update/Delete section, repeat the following for each snippet of code that needs to be changed:
89
+ [context_before] -> See below for further instructions on context.
90
+ - [old_code] -> Precede the old code with a minus sign.
91
+ + [new_code] -> Precede the new, replacement code with a plus sign.
92
+ [context_after] -> See below for further instructions on context.
93
+
94
+ For instructions on [context_before] and [context_after]:
95
+ - By default, show 3 lines of code immediately above and 3 lines immediately below each change. If a change is within 3 lines of a previous change, do NOT duplicate the first change’s [context_after] lines in the second change’s [context_before] lines.
96
+ - If 3 lines of context is insufficient to uniquely identify the snippet of code within the file, use the @@ operator to indicate the class or function to which the snippet belongs. For instance, we might have:
97
+ @@ class BaseClass
98
+ [3 lines of pre-context]
99
+ - [old_code]
100
+ + [new_code]
101
+ [3 lines of post-context]
102
+
103
+ - If a code block is repeated so many times in a class or function such that even a single @@ statement and 3 lines of context cannot uniquely identify the snippet of code, you can use multiple \`@@\` statements to jump to the right context. For instance:
104
+
105
+ @@ class BaseClass
106
+ @@ def method():
107
+ [3 lines of pre-context]
108
+ - [old_code]
109
+ + [new_code]
110
+ [3 lines of post-context]
111
+
112
+ Note, then, that we do not use line numbers in this diff format, as the context is enough to uniquely identify code. An example of a message that you might pass as "input" to this function, in order to apply a patch, is shown below.
113
+
114
+ %%bash
115
+ apply_patch <<"EOF"
116
+ *** Begin Patch
117
+ *** Update File: pygorithm/searching/binary_search.py
118
+ @@ class BaseClass
119
+ @@ def search():
120
+ - pass
121
+ + raise NotImplementedError()
122
+
123
+ @@ class Subclass
124
+ @@ def search():
125
+ - pass
126
+ + raise NotImplementedError()
127
+
128
+ *** End Patch
129
+ EOF`;
130
+
131
+ // =============================================================================
132
+ // Tool Factory Functions
133
+ // =============================================================================
134
+
135
+ /**
136
+ * Create the read_files tool
137
+ *
138
+ * Reads the content of one or more files from the filesystem.
139
+ */
140
+ export function createReadFilesTool(
141
+ executor: FileReadExecutor,
142
+ config: Pick<DefaultToolsConfig, "fileReadTimeoutMs"> = {},
143
+ ): Tool<ReadFilesInput, ToolOperationResult[]> {
144
+ const timeoutMs = config.fileReadTimeoutMs ?? 10000;
145
+
146
+ return createTool<ReadFilesInput, ToolOperationResult[]>({
147
+ name: "read_files",
148
+ description:
149
+ "Read the FULL content of text file at the provided absolute paths. " +
150
+ "Returns file contents or error messages for each path. ",
151
+ inputSchema: zodToJsonSchema(ReadFilesInputSchema),
152
+ timeoutMs: timeoutMs * 2, // Account for multiple files
153
+ retryable: true,
154
+ maxRetries: 1,
155
+ execute: async (input, context) => {
156
+ // Validate input with Zod schema
157
+ const validate = validateWithZod(ReadFilesInputUnionSchema, input);
158
+ const filePaths = Array.isArray(validate)
159
+ ? validate
160
+ : typeof validate === "object"
161
+ ? validate.file_paths
162
+ : [validate];
163
+
164
+ return Promise.all(
165
+ filePaths.map(async (filePath): Promise<ToolOperationResult> => {
166
+ try {
167
+ const content = await withTimeout(
168
+ executor(filePath, context),
169
+ timeoutMs,
170
+ `File read timed out after ${timeoutMs}ms`,
171
+ );
172
+ return {
173
+ query: filePath,
174
+ result: content,
175
+ success: true,
176
+ };
177
+ } catch (error) {
178
+ const msg = formatError(error);
179
+ return {
180
+ query: filePath,
181
+ result: "",
182
+ error: `Error reading file: ${msg}`,
183
+ success: false,
184
+ };
185
+ }
186
+ }),
187
+ );
188
+ },
189
+ });
190
+ }
191
+
192
+ /**
193
+ * Create the search_codebase tool
194
+ *
195
+ * Performs regex pattern searches across the codebase.
196
+ */
197
+ export function createSearchTool(
198
+ executor: SearchExecutor,
199
+ config: Pick<DefaultToolsConfig, "cwd" | "searchTimeoutMs"> = {},
200
+ ): Tool<SearchCodebaseInput, ToolOperationResult[]> {
201
+ const timeoutMs = config.searchTimeoutMs ?? 30000;
202
+ const cwd = config.cwd ?? process.cwd();
203
+
204
+ return createTool<SearchCodebaseInput, ToolOperationResult[]>({
205
+ name: "search_codebase",
206
+ description:
207
+ "Perform regex pattern searches across the codebase. " +
208
+ "Supports multiple parallel searches. " +
209
+ "Use for finding code patterns, function definitions, class names, imports, etc.",
210
+ inputSchema: zodToJsonSchema(SearchCodebaseInputSchema),
211
+ timeoutMs: timeoutMs * 2,
212
+ retryable: true,
213
+ maxRetries: 1,
214
+ execute: async (input, context) => {
215
+ // Validate input with Zod schema
216
+ const validatedInput = validateWithZod(SearchCodebaseInputSchema, input);
217
+
218
+ return Promise.all(
219
+ validatedInput.queries.map(
220
+ async (query): Promise<ToolOperationResult> => {
221
+ try {
222
+ const results = await withTimeout(
223
+ executor(query, cwd, context),
224
+ timeoutMs,
225
+ `Search timed out after ${timeoutMs}ms`,
226
+ );
227
+ // Check if results contain matches
228
+ const hasResults =
229
+ results.length > 0 && !results.includes("No results found");
230
+ return {
231
+ query,
232
+ result: results,
233
+ success: hasResults,
234
+ };
235
+ } catch (error) {
236
+ const msg = formatError(error);
237
+ return {
238
+ query,
239
+ result: "",
240
+ error: `Search failed: ${msg}`,
241
+ success: false,
242
+ };
243
+ }
244
+ },
245
+ ),
246
+ );
247
+ },
248
+ });
249
+ }
250
+
251
+ /**
252
+ * Create the run_commands tool
253
+ *
254
+ * Executes shell commands in the project directory.
255
+ */
256
+ export function createBashTool(
257
+ executor: BashExecutor,
258
+ config: Pick<DefaultToolsConfig, "cwd" | "bashTimeoutMs"> = {},
259
+ ): Tool<RunCommandsInput, ToolOperationResult[]> {
260
+ const timeoutMs = config.bashTimeoutMs ?? 30000;
261
+ const cwd = config.cwd ?? process.cwd();
262
+
263
+ return createTool<RunCommandsInput, ToolOperationResult[]>({
264
+ name: "run_commands",
265
+ description:
266
+ "Run shell commands at the root of the project. " +
267
+ "Use for listing files, checking git status, running builds, executing tests, etc. " +
268
+ "Commands should be properly shell-escaped.",
269
+ inputSchema: zodToJsonSchema(RunCommandsInputSchema),
270
+ timeoutMs: timeoutMs * 2,
271
+ retryable: false, // Shell commands often have side effects
272
+ maxRetries: 0,
273
+ execute: async (input, context) => {
274
+ const validate = validateWithZod(RunCommandsInputUnionSchema, input);
275
+ const commands = Array.isArray(validate)
276
+ ? validate
277
+ : typeof validate === "object"
278
+ ? validate.commands
279
+ : [validate];
280
+
281
+ return Promise.all(
282
+ commands.map(async (command): Promise<ToolOperationResult> => {
283
+ try {
284
+ const output = await withTimeout(
285
+ executor(command, cwd, context),
286
+ timeoutMs,
287
+ `Command timed out after ${timeoutMs}ms`,
288
+ );
289
+ return {
290
+ query: command,
291
+ result: output,
292
+ success: true,
293
+ };
294
+ } catch (error) {
295
+ const msg = formatError(error);
296
+ return {
297
+ query: command,
298
+ result: "",
299
+ error: `Command failed: ${msg}`,
300
+ success: false,
301
+ };
302
+ }
303
+ }),
304
+ );
305
+ },
306
+ });
307
+ }
308
+
309
+ /**
310
+ * Create the fetch_web_content tool
311
+ *
312
+ * Fetches content from URLs and analyzes them using provided prompts.
313
+ */
314
+ export function createWebFetchTool(
315
+ executor: WebFetchExecutor,
316
+ config: Pick<DefaultToolsConfig, "webFetchTimeoutMs"> = {},
317
+ ): Tool<FetchWebContentInput, ToolOperationResult[]> {
318
+ const timeoutMs = config.webFetchTimeoutMs ?? 30000;
319
+
320
+ return createTool<FetchWebContentInput, ToolOperationResult[]>({
321
+ name: "fetch_web_content",
322
+ description:
323
+ "Fetch content from URLs and analyze them using the provided prompts. " +
324
+ "Use for retrieving documentation, API references, or any web content. " +
325
+ "Each request includes a URL and a prompt describing what information to extract.",
326
+ inputSchema: zodToJsonSchema(FetchWebContentInputSchema),
327
+ timeoutMs: timeoutMs * 2,
328
+ retryable: true,
329
+ maxRetries: 2,
330
+ execute: async (input, context) => {
331
+ // Validate input with Zod schema
332
+ const validatedInput = validateWithZod(FetchWebContentInputSchema, input);
333
+
334
+ return Promise.all(
335
+ validatedInput.requests.map(
336
+ async (request): Promise<ToolOperationResult> => {
337
+ try {
338
+ const content = await withTimeout(
339
+ executor(request.url, request.prompt, context),
340
+ timeoutMs,
341
+ `Web fetch timed out after ${timeoutMs}ms`,
342
+ );
343
+ return {
344
+ query: request.url,
345
+ result: content,
346
+ success: true,
347
+ };
348
+ } catch (error) {
349
+ const msg = formatError(error);
350
+ return {
351
+ query: request.url,
352
+ result: "",
353
+ error: `Error fetching web content: ${msg}`,
354
+ success: false,
355
+ };
356
+ }
357
+ },
358
+ ),
359
+ );
360
+ },
361
+ });
362
+ }
363
+
364
+ /**
365
+ * Create the apply_patch tool
366
+ *
367
+ * Applies the legacy Cline patch format to one or more files.
368
+ */
369
+ export function createApplyPatchTool(
370
+ executor: ApplyPatchExecutor,
371
+ config: Pick<DefaultToolsConfig, "cwd" | "applyPatchTimeoutMs"> = {},
372
+ ): Tool<ApplyPatchInput, ToolOperationResult> {
373
+ const timeoutMs = config.applyPatchTimeoutMs ?? 30000;
374
+ const cwd = config.cwd ?? process.cwd();
375
+
376
+ return createTool<ApplyPatchInput, ToolOperationResult>({
377
+ name: "apply_patch",
378
+ description: APPLY_PATCH_TOOL_DESC,
379
+ inputSchema: zodToJsonSchema(ApplyPatchInputSchema),
380
+ timeoutMs,
381
+ retryable: false,
382
+ maxRetries: 0,
383
+ execute: async (input, context) => {
384
+ const validate = validateWithZod(ApplyPatchInputUnionSchema, input);
385
+ const patchInput =
386
+ typeof validate === "string" ? validate : validate.input;
387
+
388
+ try {
389
+ const result = await withTimeout(
390
+ executor({ input: patchInput }, cwd, context),
391
+ timeoutMs,
392
+ `apply_patch timed out after ${timeoutMs}ms`,
393
+ );
394
+
395
+ return {
396
+ query: "apply_patch",
397
+ result,
398
+ success: true,
399
+ };
400
+ } catch (error) {
401
+ const msg = formatError(error);
402
+ return {
403
+ query: "apply_patch",
404
+ result: "",
405
+ error: `apply_patch failed: ${msg}`,
406
+ success: false,
407
+ };
408
+ }
409
+ },
410
+ });
411
+ }
412
+
413
+ /**
414
+ * Create the editor tool
415
+ *
416
+ * Supports controlled filesystem edits with create, replace, and insert commands.
417
+ */
418
+ export function createEditorTool(
419
+ executor: EditorExecutor,
420
+ config: Pick<DefaultToolsConfig, "cwd" | "editorTimeoutMs"> = {},
421
+ ): Tool<EditFileInput, ToolOperationResult> {
422
+ const timeoutMs = config.editorTimeoutMs ?? 30000;
423
+ const cwd = config.cwd ?? process.cwd();
424
+
425
+ return createTool<EditFileInput, ToolOperationResult>({
426
+ name: "editor",
427
+ description:
428
+ "Edit file using absolute path with create, string replacement, and line insert operations. " +
429
+ "Supported commands: create, str_replace, insert, undo_edit.",
430
+ inputSchema: zodToJsonSchema(EditFileInputSchema),
431
+ timeoutMs,
432
+ retryable: false, // Editing operations are stateful and should not auto-retry
433
+ maxRetries: 0,
434
+ execute: async (input, context) => {
435
+ const validatedInput = validateWithZod(EditFileInputSchema, input);
436
+
437
+ try {
438
+ const result = await withTimeout(
439
+ executor(validatedInput, cwd, context),
440
+ timeoutMs,
441
+ `Editor operation timed out after ${timeoutMs}ms`,
442
+ );
443
+
444
+ return {
445
+ query: `${validatedInput.command}:${validatedInput.path}`,
446
+ result,
447
+ success: true,
448
+ };
449
+ } catch (error) {
450
+ const msg = formatError(error);
451
+ return {
452
+ query: `${validatedInput.command}:${validatedInput.path}`,
453
+ result: "",
454
+ error: `Editor operation failed: ${msg}`,
455
+ success: false,
456
+ };
457
+ }
458
+ },
459
+ });
460
+ }
461
+
462
+ /**
463
+ * Create the skills tool
464
+ *
465
+ * Invokes a configured skill by name and optional arguments.
466
+ */
467
+ export function createSkillsTool(
468
+ executor: SkillsExecutor,
469
+ config: Pick<DefaultToolsConfig, "skillsTimeoutMs"> = {},
470
+ ): Tool<SkillsInput, string> {
471
+ const timeoutMs = config.skillsTimeoutMs ?? 15000;
472
+
473
+ return createTool<SkillsInput, string>({
474
+ name: "skills",
475
+ description:
476
+ "Execute a skill within the main conversation. " +
477
+ "When users ask you to perform tasks, check if any available skills match. " +
478
+ 'When users reference a slash command (for example "/commit" or "/review-pr"), invoke this tool. ' +
479
+ 'Input: `skill` (required) and optional `args`. Example: `skill: "pdf"`, `skill: "commit", args: "-m \\"Fix bug\\""`, `skill: "review-pr", args: "123"`, `skill: "ms-office-suite:pdf"`. ' +
480
+ "Available skills are listed in system-reminder messages in the conversation. " +
481
+ "When a skill matches the user's request, invoking this tool is a blocking requirement before any other response. " +
482
+ "Never mention a skill without invoking this tool.",
483
+ inputSchema: zodToJsonSchema(SkillsInputSchema),
484
+ timeoutMs,
485
+ retryable: false,
486
+ maxRetries: 0,
487
+ execute: async (input, context) => {
488
+ const validatedInput = validateWithZod(SkillsInputSchema, input);
489
+ return withTimeout(
490
+ executor(validatedInput.skill, validatedInput.args, context),
491
+ timeoutMs,
492
+ `Skills operation timed out after ${timeoutMs}ms`,
493
+ );
494
+ },
495
+ });
496
+ }
497
+
498
+ /**
499
+ * Create the ask_question tool
500
+ *
501
+ * Asks the user a single clarifying question with 2-5 selectable options.
502
+ */
503
+ export function createAskQuestionTool(
504
+ executor: AskQuestionExecutor,
505
+ config: Pick<DefaultToolsConfig, "askQuestionTimeoutMs"> = {},
506
+ ): Tool<AskQuestionInput, string> {
507
+ const timeoutMs = config.askQuestionTimeoutMs ?? 15000;
508
+
509
+ return createTool<AskQuestionInput, string>({
510
+ name: "ask_question",
511
+ description:
512
+ "Ask user a question for clarifying or gathering information needed to complete the task. " +
513
+ "For example, ask the user clarifying questions about a key implementation decision. " +
514
+ "You should only ask one question. " +
515
+ "Provide an array of 2-5 options for the user to choose from. " +
516
+ "Never include an option to toggle to Act mode.",
517
+ inputSchema: zodToJsonSchema(AskQuestionInputSchema),
518
+ timeoutMs,
519
+ retryable: false,
520
+ maxRetries: 0,
521
+ execute: async (input, context) => {
522
+ const validatedInput = validateWithZod(AskQuestionInputSchema, input);
523
+ return withTimeout(
524
+ executor(validatedInput.question, validatedInput.options, context),
525
+ timeoutMs,
526
+ `ask_question timed out after ${timeoutMs}ms`,
527
+ );
528
+ },
529
+ });
530
+ }
531
+
532
+ // =============================================================================
533
+ // Default Tools Factory
534
+ // =============================================================================
535
+
536
+ /**
537
+ * Create a set of default tools for an agent
538
+ *
539
+ * This function creates the default tools based on the provided configuration
540
+ * and executors. Only tools that are enabled AND have an executor provided
541
+ * will be included in the returned array.
542
+ *
543
+ * @example
544
+ * ```typescript
545
+ * import { Agent } from "@clinebot/agents"
546
+ * import { createDefaultTools } from "@clinebot/core/server"
547
+ * import * as fs from "fs/promises"
548
+ * import { exec } from "child_process"
549
+ *
550
+ * const tools = createDefaultTools({
551
+ * executors: {
552
+ * readFile: async (path) => fs.readFile(path, "utf-8"),
553
+ * bash: async (cmd, cwd) => {
554
+ * return new Promise((resolve, reject) => {
555
+ * exec(cmd, { cwd }, (err, stdout, stderr) => {
556
+ * if (err) reject(new Error(stderr || err.message))
557
+ * else resolve(stdout)
558
+ * })
559
+ * })
560
+ * },
561
+ * },
562
+ * enableReadFiles: true,
563
+ * enableBash: true,
564
+ * enableSearch: false, // Disabled
565
+ * enableWebFetch: false, // Disabled
566
+ * cwd: "/path/to/project",
567
+ * })
568
+ *
569
+ * const agent = new Agent({
570
+ * // ... provider config
571
+ * tools,
572
+ * })
573
+ * ```
574
+ */
575
+ export function createDefaultTools(options: CreateDefaultToolsOptions): Tool[] {
576
+ const {
577
+ executors,
578
+ enableReadFiles = true,
579
+ enableSearch = true,
580
+ enableBash = true,
581
+ enableWebFetch = true,
582
+ enableApplyPatch = false,
583
+ enableEditor = true,
584
+ enableSkills = true,
585
+ enableAskQuestion = true,
586
+ ...config
587
+ } = options;
588
+
589
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
590
+ const tools: Tool<any, any>[] = [];
591
+
592
+ // Add read_files tool if enabled and executor provided
593
+ if (enableReadFiles && executors.readFile) {
594
+ tools.push(createReadFilesTool(executors.readFile, config));
595
+ }
596
+
597
+ // Add search_codebase tool if enabled and executor provided
598
+ if (enableSearch && executors.search) {
599
+ tools.push(createSearchTool(executors.search, config));
600
+ }
601
+
602
+ // Add run_commands tool if enabled and executor provided
603
+ if (enableBash && executors.bash) {
604
+ tools.push(createBashTool(executors.bash, config));
605
+ }
606
+
607
+ // Add fetch_web_content tool if enabled and executor provided
608
+ if (enableWebFetch && executors.webFetch) {
609
+ tools.push(createWebFetchTool(executors.webFetch, config));
610
+ }
611
+
612
+ // Add editor tool if enabled and executor provided,
613
+ // else check if apply_patch tool is enabled and executor provided
614
+ // NOTE: Do not enable two similar tools at the same time.
615
+ if (enableEditor && executors.editor) {
616
+ tools.push(createEditorTool(executors.editor, config));
617
+ } else if (enableApplyPatch && executors.applyPatch) {
618
+ tools.push(createApplyPatchTool(executors.applyPatch, config));
619
+ }
620
+
621
+ // Add skills tool if enabled and executor provided
622
+ if (enableSkills && executors.skills) {
623
+ tools.push(createSkillsTool(executors.skills, config));
624
+ }
625
+
626
+ // Add ask_question tool if enabled and executor provided
627
+ if (enableAskQuestion && executors.askQuestion) {
628
+ tools.push(createAskQuestionTool(executors.askQuestion, config));
629
+ }
630
+
631
+ return tools;
632
+ }