@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,259 @@
1
+ /**
2
+ * Web Fetch Executor
3
+ *
4
+ * Built-in implementation for fetching web content using native fetch.
5
+ */
6
+
7
+ import type { ToolContext } from "@clinebot/agents";
8
+ import type { WebFetchExecutor } from "../types.js";
9
+
10
+ /**
11
+ * Options for the web fetch executor
12
+ */
13
+ export interface WebFetchExecutorOptions {
14
+ /**
15
+ * Timeout for fetch requests in milliseconds
16
+ * @default 30000 (30 seconds)
17
+ */
18
+ timeoutMs?: number;
19
+
20
+ /**
21
+ * Maximum response size in bytes
22
+ * @default 5_000_000 (5MB)
23
+ */
24
+ maxResponseBytes?: number;
25
+
26
+ /**
27
+ * User agent string
28
+ * @default "Mozilla/5.0 (compatible; AgentBot/1.0)"
29
+ */
30
+ userAgent?: string;
31
+
32
+ /**
33
+ * Additional headers
34
+ */
35
+ headers?: Record<string, string>;
36
+
37
+ /**
38
+ * Whether to follow redirects
39
+ * @default true
40
+ */
41
+ followRedirects?: boolean;
42
+
43
+ /**
44
+ * Maximum number of redirects to follow
45
+ * @default 5
46
+ */
47
+ maxRedirects?: number;
48
+ }
49
+
50
+ /**
51
+ * Extract text content from HTML
52
+ * Simple implementation - strips tags and normalizes whitespace
53
+ */
54
+ function htmlToText(html: string): string {
55
+ return (
56
+ html
57
+ // Remove script and style elements
58
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
59
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
60
+ // Remove HTML comments
61
+ .replace(/<!--[\s\S]*?-->/g, "")
62
+ // Replace block elements with newlines
63
+ .replace(/<(p|div|br|hr|h[1-6]|li|tr)[^>]*>/gi, "\n")
64
+ // Remove all remaining tags
65
+ .replace(/<[^>]+>/g, " ")
66
+ // Decode HTML entities
67
+ .replace(/&nbsp;/g, " ")
68
+ .replace(/&amp;/g, "&")
69
+ .replace(/&lt;/g, "<")
70
+ .replace(/&gt;/g, ">")
71
+ .replace(/&quot;/g, '"')
72
+ .replace(/&#(\d+);/g, (_, n) => String.fromCharCode(parseInt(n, 10)))
73
+ // Normalize whitespace
74
+ .replace(/\s+/g, " ")
75
+ .replace(/\n\s+/g, "\n")
76
+ .replace(/\n{3,}/g, "\n\n")
77
+ .trim()
78
+ );
79
+ }
80
+
81
+ /**
82
+ * Create a web fetch executor using native fetch
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const webFetch = createWebFetchExecutor({
87
+ * timeoutMs: 15000,
88
+ * maxResponseBytes: 2_000_000,
89
+ * })
90
+ *
91
+ * const content = await webFetch(
92
+ * "https://docs.example.com/api",
93
+ * "Extract the authentication section",
94
+ * context
95
+ * )
96
+ * ```
97
+ */
98
+ export function createWebFetchExecutor(
99
+ options: WebFetchExecutorOptions = {},
100
+ ): WebFetchExecutor {
101
+ const {
102
+ timeoutMs = 30000,
103
+ maxResponseBytes = 5_000_000,
104
+ userAgent = "Mozilla/5.0 (compatible; AgentBot/1.0)",
105
+ headers = {},
106
+ followRedirects = true,
107
+ // maxRedirects is available in options but native fetch handles it automatically
108
+ } = options;
109
+
110
+ return async (
111
+ url: string,
112
+ prompt: string,
113
+ context: ToolContext,
114
+ ): Promise<string> => {
115
+ // Validate URL
116
+ let parsedUrl: URL;
117
+ try {
118
+ parsedUrl = new URL(url);
119
+ } catch {
120
+ throw new Error(`Invalid URL: ${url}`);
121
+ }
122
+
123
+ // Only allow http and https
124
+ if (!["http:", "https:"].includes(parsedUrl.protocol)) {
125
+ throw new Error(
126
+ `Invalid protocol: ${parsedUrl.protocol}. Only http and https are supported.`,
127
+ );
128
+ }
129
+
130
+ // Create abort controller for timeout
131
+ const controller = new AbortController();
132
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
133
+ let contextAbortHandler: (() => void) | undefined;
134
+
135
+ // Combine with context abort signal
136
+ if (context.abortSignal) {
137
+ contextAbortHandler = () => controller.abort();
138
+ context.abortSignal.addEventListener("abort", contextAbortHandler);
139
+ }
140
+
141
+ try {
142
+ const response = await fetch(url, {
143
+ method: "GET",
144
+ headers: {
145
+ "User-Agent": userAgent,
146
+ Accept:
147
+ "text/html,application/xhtml+xml,application/xml;q=0.9,text/plain;q=0.8,*/*;q=0.7",
148
+ "Accept-Language": "en-US,en;q=0.9",
149
+ ...headers,
150
+ },
151
+ redirect: followRedirects ? "follow" : "manual",
152
+ signal: controller.signal,
153
+ });
154
+
155
+ clearTimeout(timeout);
156
+
157
+ // Check for redirect limit (if we're checking manually)
158
+ if (!followRedirects && response.status >= 300 && response.status < 400) {
159
+ const location = response.headers.get("location");
160
+ return `Redirect to: ${location}`;
161
+ }
162
+
163
+ // Check response status
164
+ if (!response.ok) {
165
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
166
+ }
167
+
168
+ // Get content type
169
+ const contentType = response.headers.get("content-type") || "";
170
+
171
+ // Read response body with size limit
172
+ const reader = response.body?.getReader();
173
+ if (!reader) {
174
+ throw new Error("Failed to read response body");
175
+ }
176
+
177
+ const chunks: Uint8Array[] = [];
178
+ let totalSize = 0;
179
+
180
+ while (true) {
181
+ const { done, value } = await reader.read();
182
+ if (done) break;
183
+
184
+ totalSize += value.length;
185
+ if (totalSize > maxResponseBytes) {
186
+ reader.cancel();
187
+ throw new Error(
188
+ `Response too large: exceeded ${maxResponseBytes} bytes`,
189
+ );
190
+ }
191
+
192
+ chunks.push(value);
193
+ }
194
+
195
+ // Combine chunks
196
+ const buffer = new Uint8Array(totalSize);
197
+ let offset = 0;
198
+ for (const chunk of chunks) {
199
+ buffer.set(chunk, offset);
200
+ offset += chunk.length;
201
+ }
202
+
203
+ // Decode as text
204
+ const text = new TextDecoder("utf-8").decode(buffer);
205
+
206
+ // Process content based on type
207
+ let content: string;
208
+ if (
209
+ contentType.includes("text/html") ||
210
+ contentType.includes("application/xhtml")
211
+ ) {
212
+ content = htmlToText(text);
213
+ } else if (contentType.includes("application/json")) {
214
+ try {
215
+ const json = JSON.parse(text);
216
+ content = JSON.stringify(json, null, 2);
217
+ } catch {
218
+ content = text;
219
+ }
220
+ } else {
221
+ content = text;
222
+ }
223
+
224
+ // Format output with metadata
225
+ const outputLines = [
226
+ `URL: ${url}`,
227
+ `Content-Type: ${contentType}`,
228
+ `Size: ${totalSize} bytes`,
229
+ ``,
230
+ `--- Content ---`,
231
+ content.slice(0, 50000), // Limit content size for output
232
+ ];
233
+
234
+ if (content.length > 50000) {
235
+ outputLines.push(
236
+ `\n[Content truncated: showing first 50000 of ${content.length} characters]`,
237
+ );
238
+ }
239
+
240
+ outputLines.push(``, `--- Analysis Request ---`, `Prompt: ${prompt}`);
241
+
242
+ return outputLines.join("\n");
243
+ } catch (error) {
244
+ clearTimeout(timeout);
245
+
246
+ if (error instanceof Error) {
247
+ if (error.name === "AbortError") {
248
+ throw new Error(`Request timed out after ${timeoutMs}ms`);
249
+ }
250
+ throw error;
251
+ }
252
+ throw new Error(`Fetch failed: ${String(error)}`);
253
+ } finally {
254
+ if (context.abortSignal && contextAbortHandler) {
255
+ context.abortSignal.removeEventListener("abort", contextAbortHandler);
256
+ }
257
+ }
258
+ };
259
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Default Tools
3
+ *
4
+ * This module provides a set of configurable default tools for agents.
5
+ */
6
+
7
+ // Zod Utilities
8
+ export { validateWithZod, zodToJsonSchema } from "@clinebot/shared";
9
+ // Constants
10
+ export { ALL_DEFAULT_TOOL_NAMES, DefaultToolNames } from "./constants.js";
11
+ // Tool Definitions
12
+ export {
13
+ createApplyPatchTool,
14
+ createAskQuestionTool,
15
+ createBashTool,
16
+ createDefaultTools,
17
+ createEditorTool,
18
+ createReadFilesTool,
19
+ createSearchTool,
20
+ createSkillsTool,
21
+ createWebFetchTool,
22
+ } from "./definitions.js";
23
+ // Built-in Executors
24
+ export {
25
+ type ApplyPatchExecutorOptions,
26
+ type BashExecutorOptions,
27
+ createApplyPatchExecutor,
28
+ createBashExecutor,
29
+ createDefaultExecutors,
30
+ createEditorExecutor,
31
+ createFileReadExecutor,
32
+ createSearchExecutor,
33
+ createWebFetchExecutor,
34
+ type DefaultExecutorsOptions,
35
+ type EditorExecutorOptions,
36
+ type FileReadExecutorOptions,
37
+ type SearchExecutorOptions,
38
+ type WebFetchExecutorOptions,
39
+ } from "./executors/index.js";
40
+ // Presets
41
+ export {
42
+ createDefaultToolsWithPreset,
43
+ createToolPoliciesWithPreset,
44
+ type ToolPolicyPresetName,
45
+ type ToolPresetName,
46
+ ToolPresets,
47
+ } from "./presets.js";
48
+ // Schemas
49
+ export {
50
+ type ApplyPatchInput,
51
+ ApplyPatchInputSchema,
52
+ type AskQuestionInput,
53
+ AskQuestionInputSchema,
54
+ type EditFileInput,
55
+ EditFileInputSchema,
56
+ type FetchWebContentInput,
57
+ FetchWebContentInputSchema,
58
+ type ReadFilesInput,
59
+ ReadFilesInputSchema,
60
+ type RunCommandsInput,
61
+ RunCommandsInputSchema,
62
+ type SearchCodebaseInput,
63
+ SearchCodebaseInputSchema,
64
+ type SkillsInput,
65
+ SkillsInputSchema,
66
+ type WebFetchRequest,
67
+ WebFetchRequestSchema,
68
+ } from "./schemas.js";
69
+ // Types
70
+ export type {
71
+ ApplyPatchExecutor,
72
+ AskQuestionExecutor,
73
+ BashExecutor,
74
+ CreateDefaultToolsOptions,
75
+ DefaultToolName,
76
+ DefaultToolsConfig,
77
+ EditorExecutor,
78
+ FileReadExecutor,
79
+ SearchExecutor,
80
+ SkillsExecutor,
81
+ SkillsExecutorSkillMetadata,
82
+ SkillsExecutorWithMetadata,
83
+ ToolExecutors,
84
+ ToolOperationResult,
85
+ WebFetchExecutor,
86
+ } from "./types.js";
87
+
88
+ // =============================================================================
89
+ // Convenience: Create Tools with Built-in Executors
90
+ // =============================================================================
91
+
92
+ import type { Tool } from "@clinebot/agents";
93
+ import { createDefaultTools } from "./definitions.js";
94
+ import {
95
+ createDefaultExecutors,
96
+ type DefaultExecutorsOptions,
97
+ } from "./executors/index.js";
98
+ import type { CreateDefaultToolsOptions, ToolExecutors } from "./types.js";
99
+
100
+ /**
101
+ * Options for creating default tools with built-in executors
102
+ */
103
+ export interface CreateBuiltinToolsOptions
104
+ extends Omit<CreateDefaultToolsOptions, "executors"> {
105
+ /**
106
+ * Configuration for the built-in executors
107
+ */
108
+ executorOptions?: DefaultExecutorsOptions;
109
+ /**
110
+ * Optional executor overrides/additions for tools without built-ins
111
+ */
112
+ executors?: Partial<ToolExecutors>;
113
+ }
114
+
115
+ /**
116
+ * Create default tools with built-in Node.js executors
117
+ *
118
+ * This is a convenience function that creates the default tools with
119
+ * working implementations using Node.js built-in modules.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * import { Agent } from "@clinebot/agents"
124
+ * import { createBuiltinTools } from "@clinebot/core/server"
125
+ *
126
+ * const tools = createBuiltinTools({
127
+ * cwd: "/path/to/project",
128
+ * enableBash: true,
129
+ * enableWebFetch: false, // Disable web fetching
130
+ * executorOptions: {
131
+ * bash: { timeoutMs: 60000 },
132
+ * },
133
+ * })
134
+ *
135
+ * const agent = new Agent({
136
+ * providerId: "anthropic",
137
+ * modelId: "claude-sonnet-4-20250514",
138
+ * systemPrompt: "You are a coding assistant.",
139
+ * tools,
140
+ * })
141
+ * ```
142
+ */
143
+ export function createBuiltinTools(
144
+ options: CreateBuiltinToolsOptions = {},
145
+ ): Tool[] {
146
+ const {
147
+ executorOptions = {},
148
+ executors: executorOverrides,
149
+ ...toolsConfig
150
+ } = options;
151
+
152
+ const executors = {
153
+ ...createDefaultExecutors(executorOptions),
154
+ ...(executorOverrides ?? {}),
155
+ };
156
+
157
+ return createDefaultTools({
158
+ ...toolsConfig,
159
+ executors,
160
+ });
161
+ }
@@ -0,0 +1,63 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ createDefaultToolsWithPreset,
4
+ createToolPoliciesWithPreset,
5
+ ToolPresets,
6
+ } from "./presets.js";
7
+
8
+ describe("default tool presets", () => {
9
+ it("explicitly configures ask_question across presets", () => {
10
+ expect(ToolPresets.search.enableAskQuestion).toBe(false);
11
+ expect(ToolPresets.development.enableAskQuestion).toBe(true);
12
+ expect(ToolPresets.readonly.enableAskQuestion).toBe(true);
13
+ expect(ToolPresets.minimal.enableAskQuestion).toBe(true);
14
+ expect(ToolPresets.yolo.enableAskQuestion).toBe(true);
15
+ });
16
+
17
+ it("yolo preset enables all default tools when executors exist", () => {
18
+ const tools = createDefaultToolsWithPreset("yolo", {
19
+ executors: {
20
+ readFile: async () => "ok",
21
+ search: async () => "ok",
22
+ bash: async () => "ok",
23
+ webFetch: async () => "ok",
24
+ applyPatch: async () => "ok",
25
+ editor: async () => "ok",
26
+ skills: async () => "ok",
27
+ askQuestion: async () => "ok",
28
+ },
29
+ });
30
+
31
+ expect(tools.map((tool) => tool.name)).toEqual([
32
+ "read_files",
33
+ "search_codebase",
34
+ "run_commands",
35
+ "fetch_web_content",
36
+ "editor",
37
+ "skills",
38
+ "ask_question",
39
+ ]);
40
+ });
41
+ });
42
+
43
+ describe("tool policy presets", () => {
44
+ it("returns empty policies for default", () => {
45
+ expect(createToolPoliciesWithPreset("default")).toEqual({});
46
+ });
47
+
48
+ it("yolo preset enables and auto-approves all tools", () => {
49
+ const policies = createToolPoliciesWithPreset("yolo");
50
+ expect(policies["*"]).toEqual({
51
+ enabled: true,
52
+ autoApprove: true,
53
+ });
54
+ expect(policies.ask_question).toEqual({
55
+ enabled: true,
56
+ autoApprove: true,
57
+ });
58
+ expect(policies.skills).toEqual({
59
+ enabled: true,
60
+ autoApprove: true,
61
+ });
62
+ });
63
+ });
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Tool Presets
3
+ *
4
+ * Pre-configured tool combinations for common use cases.
5
+ */
6
+
7
+ import type { Tool, ToolPolicy } from "@clinebot/shared";
8
+ import { ALL_DEFAULT_TOOL_NAMES } from "./constants.js";
9
+ import { createDefaultTools } from "./definitions.js";
10
+ import type { CreateDefaultToolsOptions, DefaultToolsConfig } from "./types.js";
11
+
12
+ /**
13
+ * Preset configurations for common use cases
14
+ */
15
+ export const ToolPresets = {
16
+ /**
17
+ * Browser-based tools (no shell access, no web fetch)
18
+ */
19
+ browser: {
20
+ enableReadFiles: false,
21
+ enableSearch: false,
22
+ enableBash: false,
23
+ enableWebFetch: false,
24
+ enableApplyPatch: false,
25
+ enableEditor: false,
26
+ enableSkills: true,
27
+ enableAskQuestion: true,
28
+ },
29
+
30
+ /**
31
+ * Search-focused tools (read_files + search_codebase)
32
+ * Good for code exploration and analysis agents
33
+ */
34
+ search: {
35
+ enableReadFiles: true,
36
+ enableSearch: true,
37
+ enableBash: false,
38
+ enableWebFetch: false,
39
+ enableApplyPatch: false,
40
+ enableEditor: false,
41
+ enableSkills: false,
42
+ enableAskQuestion: false,
43
+ },
44
+
45
+ /**
46
+ * Full development tools (all tools enabled) - Act mode
47
+ * Good for coding assistants and task automation
48
+ */
49
+ development: {
50
+ enableReadFiles: true,
51
+ enableSearch: true,
52
+ enableBash: true,
53
+ enableWebFetch: true,
54
+ enableApplyPatch: false,
55
+ enableEditor: true,
56
+ enableSkills: true,
57
+ enableAskQuestion: true,
58
+ },
59
+
60
+ /**
61
+ * Read-only tools (no shell access) - Plan mode
62
+ * Good for analysis and documentation agents
63
+ */
64
+ readonly: {
65
+ enableReadFiles: true,
66
+ enableSearch: true,
67
+ enableBash: true,
68
+ enableWebFetch: true,
69
+ enableApplyPatch: false,
70
+ enableEditor: false,
71
+ enableSkills: true,
72
+ enableAskQuestion: true,
73
+ },
74
+
75
+ /**
76
+ * Minimal tools (file reading only)
77
+ * Good for focused single-file tasks
78
+ */
79
+ minimal: {
80
+ enableReadFiles: false,
81
+ enableSearch: false,
82
+ enableBash: false,
83
+ enableWebFetch: false,
84
+ enableApplyPatch: false,
85
+ enableEditor: false,
86
+ enableSkills: false,
87
+ enableAskQuestion: true,
88
+ },
89
+
90
+ /**
91
+ * YOLO mode (everything enabled + no approval required)
92
+ * Good for trusted local automation workflows.
93
+ */
94
+ yolo: {
95
+ enableReadFiles: true,
96
+ enableSearch: true,
97
+ enableBash: true,
98
+ enableWebFetch: true,
99
+ enableApplyPatch: false,
100
+ enableEditor: true,
101
+ enableSkills: true,
102
+ enableAskQuestion: true,
103
+ },
104
+ } as const satisfies Record<string, DefaultToolsConfig>;
105
+
106
+ /**
107
+ * Type for preset names
108
+ */
109
+ export type ToolPresetName = keyof typeof ToolPresets;
110
+
111
+ /**
112
+ * Tool policy preset names
113
+ */
114
+ export type ToolPolicyPresetName = "default" | "yolo";
115
+
116
+ /**
117
+ * Build tool policies for a preset.
118
+ * `yolo` guarantees all tools are enabled and auto-approved.
119
+ */
120
+ export function createToolPoliciesWithPreset(
121
+ presetName: ToolPolicyPresetName,
122
+ ): Record<string, ToolPolicy> {
123
+ if (presetName !== "yolo") {
124
+ return {};
125
+ }
126
+
127
+ const yoloPolicy: ToolPolicy = {
128
+ enabled: true,
129
+ autoApprove: true,
130
+ };
131
+
132
+ const policies: Record<string, ToolPolicy> = {
133
+ "*": yoloPolicy,
134
+ };
135
+
136
+ for (const toolName of ALL_DEFAULT_TOOL_NAMES) {
137
+ policies[toolName] = yoloPolicy;
138
+ }
139
+
140
+ return policies;
141
+ }
142
+
143
+ /**
144
+ * Create default tools using a preset configuration
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const tools = createDefaultToolsWithPreset("readonly", {
149
+ * executors: {
150
+ * readFile: async (path) => fs.readFile(path, "utf-8"),
151
+ * search: async (query, cwd) => searchFiles(query, cwd),
152
+ * webFetch: async (url, prompt) => fetchAndAnalyze(url, prompt),
153
+ * },
154
+ * cwd: "/path/to/project",
155
+ * })
156
+ * ```
157
+ */
158
+ export function createDefaultToolsWithPreset(
159
+ presetName: ToolPresetName,
160
+ options: Omit<CreateDefaultToolsOptions, keyof DefaultToolsConfig> &
161
+ Partial<DefaultToolsConfig>,
162
+ ): Tool[] {
163
+ const preset = ToolPresets[presetName];
164
+ return createDefaultTools({
165
+ ...preset,
166
+ ...options,
167
+ });
168
+ }