@yolo-labs/core-tools 1.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.
@@ -0,0 +1,127 @@
1
+ import { ToolRegistry, Tool, ToolDefinition, SandboxProvider } from '@yolo-labs/core-types';
2
+
3
+ /**
4
+ * Default {@link ToolRegistry} implementation with JSON Schema input validation.
5
+ *
6
+ * @remarks
7
+ * Tools are stored in a Map keyed by name. Duplicate registration throws.
8
+ * Use `executeWithValidation` for schema-checked execution, or `get` a
9
+ * tool and call its `execute` method directly.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const registry = new ToolRegistryImpl();
14
+ * registry.register(readFileTool);
15
+ * registry.register(writeFileTool);
16
+ * const defs = registry.toAIToolDefinitions();
17
+ * ```
18
+ */
19
+ declare class ToolRegistryImpl implements ToolRegistry {
20
+ private tools;
21
+ /**
22
+ * Registers a tool in the registry.
23
+ *
24
+ * @param tool - The tool to register.
25
+ * @throws Error if a tool with the same name is already registered.
26
+ */
27
+ register(tool: Tool): void;
28
+ /**
29
+ * Removes a tool from the registry by name.
30
+ *
31
+ * @param name - The name of the tool to remove.
32
+ * @throws Error if the tool is not registered.
33
+ */
34
+ unregister(name: string): void;
35
+ /**
36
+ * Retrieves a registered tool by name.
37
+ *
38
+ * @param name - The tool name to look up.
39
+ * @returns The tool instance, or `undefined` if not found.
40
+ */
41
+ get(name: string): Tool | undefined;
42
+ /** Returns all registered tools. */
43
+ list(): Tool[];
44
+ /**
45
+ * Serializes all registered tools to the canonical AI tool definition format.
46
+ *
47
+ * @returns An array of {@link ToolDefinition} objects suitable for passing to an AI provider.
48
+ */
49
+ toAIToolDefinitions(): ToolDefinition[];
50
+ /**
51
+ * Validates tool input against its JSON Schema and executes the tool.
52
+ *
53
+ * @param name - The name of the tool to execute.
54
+ * @param input - The input object to validate and pass to the tool.
55
+ * @param args - Remaining arguments forwarded to the tool's execute method.
56
+ * @returns The tool result, or a failure result if validation fails.
57
+ * @throws Error if the tool is not found in the registry.
58
+ */
59
+ executeWithValidation(name: string, input: Record<string, unknown>, ...args: Parameters<Tool['execute']> extends [unknown, ...infer Rest] ? Rest : never): Promise<ReturnType<Tool['execute']>>;
60
+ }
61
+
62
+ /** Result of validating tool input against a JSON Schema. */
63
+ interface ValidationResult {
64
+ valid: boolean;
65
+ errors: string[];
66
+ }
67
+ /**
68
+ * Validates a tool input object against a JSON Schema.
69
+ *
70
+ * @param input - The input object to validate.
71
+ * @param schema - A JSON Schema object to validate against.
72
+ * @returns A {@link ValidationResult} indicating validity and any errors.
73
+ *
74
+ * @remarks
75
+ * Performs lightweight validation: checks required fields and basic type
76
+ * matching (string, number, integer, boolean, array, object). Does not
77
+ * support advanced JSON Schema features like `$ref`, `allOf`, or `pattern`.
78
+ */
79
+ declare function validateInput(input: Record<string, unknown>, schema: Record<string, unknown>): ValidationResult;
80
+
81
+ /** Reference tool: creates or overwrites a file in the sandbox. */
82
+ declare const writeFileTool: Tool;
83
+
84
+ /** Reference tool: reads the contents of a file from the sandbox. */
85
+ declare const readFileTool: Tool;
86
+
87
+ /** Reference tool: lists files and directories in a sandbox directory. */
88
+ declare const listFilesTool: Tool;
89
+
90
+ /** Reference tool: deletes a file from the sandbox file system. */
91
+ declare const deleteFileTool: Tool;
92
+
93
+ /** Reference tool: runs a shell command in the sandbox environment. */
94
+ declare const executeCommandTool: Tool;
95
+
96
+ /** Reference tool: targeted find/replace edit on a file in the sandbox. */
97
+ declare const editFileTool: Tool;
98
+
99
+ /** Reference tool: searches file contents for a pattern across the project. */
100
+ declare const searchFilesTool: Tool;
101
+
102
+ interface WalkOptions {
103
+ /** Directories to skip (basename match). Defaults to node_modules, .git, dist, .next. */
104
+ exclude?: string[];
105
+ /** Maximum directory depth (0 = only top-level). Defaults to Infinity. */
106
+ maxDepth?: number;
107
+ }
108
+ /**
109
+ * Recursively walk a directory tree using the SandboxProvider interface.
110
+ *
111
+ * Uses `sandbox.listFiles()` to enumerate entries and probes each entry
112
+ * with another `listFiles()` call to determine if it is a directory.
113
+ * Returns a flat list of file paths (not directories).
114
+ */
115
+ declare function walkDir(sandbox: SandboxProvider, dir: string, opts?: WalkOptions): Promise<string[]>;
116
+
117
+ /**
118
+ * Returns all 7 reference tools: read_file, write_file, list_files, delete_file,
119
+ * execute_command, edit_file, search_files.
120
+ *
121
+ * @remarks
122
+ * Convenience function for registering the standard tool set. Used by
123
+ * {@link createHeadlessAgent} when `tools: 'default'` is specified in config.
124
+ */
125
+ declare function getDefaultTools(): Tool[];
126
+
127
+ export { ToolRegistryImpl, type ValidationResult, type WalkOptions, deleteFileTool, editFileTool, executeCommandTool, getDefaultTools, listFilesTool, readFileTool, searchFilesTool, validateInput, walkDir, writeFileTool };
package/dist/index.js ADDED
@@ -0,0 +1,502 @@
1
+ // src/validation.ts
2
+ function validateInput(input, schema) {
3
+ const errors = [];
4
+ if (schema.type !== "object") {
5
+ return { valid: true, errors: [] };
6
+ }
7
+ const required = schema.required ?? [];
8
+ for (const field of required) {
9
+ if (!(field in input) || input[field] === void 0 || input[field] === null) {
10
+ errors.push(`Missing required field: '${field}'`);
11
+ }
12
+ }
13
+ const properties = schema.properties ?? {};
14
+ for (const [key, value] of Object.entries(input)) {
15
+ const propSchema = properties[key];
16
+ if (!propSchema) continue;
17
+ const expectedType = propSchema.type;
18
+ if (!expectedType) continue;
19
+ const actualType = Array.isArray(value) ? "array" : typeof value;
20
+ if (expectedType === "integer") {
21
+ if (typeof value !== "number" || !Number.isInteger(value)) {
22
+ errors.push(`Field '${key}': expected integer, got ${actualType}`);
23
+ }
24
+ } else if (expectedType !== actualType) {
25
+ errors.push(`Field '${key}': expected ${expectedType}, got ${actualType}`);
26
+ }
27
+ }
28
+ return { valid: errors.length === 0, errors };
29
+ }
30
+
31
+ // src/registry.ts
32
+ var ToolRegistryImpl = class {
33
+ tools = /* @__PURE__ */ new Map();
34
+ /**
35
+ * Registers a tool in the registry.
36
+ *
37
+ * @param tool - The tool to register.
38
+ * @throws Error if a tool with the same name is already registered.
39
+ */
40
+ register(tool) {
41
+ if (this.tools.has(tool.name)) {
42
+ throw new Error(`Tool '${tool.name}' is already registered`);
43
+ }
44
+ this.tools.set(tool.name, tool);
45
+ }
46
+ /**
47
+ * Removes a tool from the registry by name.
48
+ *
49
+ * @param name - The name of the tool to remove.
50
+ * @throws Error if the tool is not registered.
51
+ */
52
+ unregister(name) {
53
+ if (!this.tools.has(name)) {
54
+ throw new Error(`Tool '${name}' is not registered`);
55
+ }
56
+ this.tools.delete(name);
57
+ }
58
+ /**
59
+ * Retrieves a registered tool by name.
60
+ *
61
+ * @param name - The tool name to look up.
62
+ * @returns The tool instance, or `undefined` if not found.
63
+ */
64
+ get(name) {
65
+ return this.tools.get(name);
66
+ }
67
+ /** Returns all registered tools. */
68
+ list() {
69
+ return Array.from(this.tools.values());
70
+ }
71
+ /**
72
+ * Serializes all registered tools to the canonical AI tool definition format.
73
+ *
74
+ * @returns An array of {@link ToolDefinition} objects suitable for passing to an AI provider.
75
+ */
76
+ toAIToolDefinitions() {
77
+ return Array.from(this.tools.values()).map((tool) => ({
78
+ name: tool.name,
79
+ description: tool.description,
80
+ inputSchema: tool.inputSchema
81
+ }));
82
+ }
83
+ /**
84
+ * Validates tool input against its JSON Schema and executes the tool.
85
+ *
86
+ * @param name - The name of the tool to execute.
87
+ * @param input - The input object to validate and pass to the tool.
88
+ * @param args - Remaining arguments forwarded to the tool's execute method.
89
+ * @returns The tool result, or a failure result if validation fails.
90
+ * @throws Error if the tool is not found in the registry.
91
+ */
92
+ async executeWithValidation(name, input, ...args) {
93
+ const tool = this.tools.get(name);
94
+ if (!tool) {
95
+ throw new Error(`Tool '${name}' not found in registry`);
96
+ }
97
+ const validation = validateInput(input, tool.inputSchema);
98
+ if (!validation.valid) {
99
+ return {
100
+ success: false,
101
+ output: null,
102
+ error: `Validation failed: ${validation.errors.join(", ")}`
103
+ };
104
+ }
105
+ return tool.execute(input, ...args);
106
+ }
107
+ };
108
+
109
+ // src/reference/write-file.ts
110
+ var writeFileTool = {
111
+ name: "write_file",
112
+ description: "Create or overwrite a file in the sandbox file system",
113
+ inputSchema: {
114
+ type: "object",
115
+ properties: {
116
+ path: { type: "string", description: "File path to write to" },
117
+ content: { type: "string", description: "Content to write to the file" }
118
+ },
119
+ required: ["path", "content"]
120
+ },
121
+ async execute(input, context) {
122
+ const path = input.path;
123
+ const content = input.content;
124
+ try {
125
+ await context.sandbox.writeFile(path, content);
126
+ return {
127
+ success: true,
128
+ output: `Successfully wrote ${content.length} characters to ${path}`,
129
+ preview: content.length > 200 ? content.slice(0, 200) + "..." : content
130
+ };
131
+ } catch (err) {
132
+ return {
133
+ success: false,
134
+ output: null,
135
+ error: err instanceof Error ? err.message : String(err)
136
+ };
137
+ }
138
+ }
139
+ };
140
+
141
+ // src/reference/read-file.ts
142
+ var readFileTool = {
143
+ name: "read_file",
144
+ description: "Read the contents of a file from the sandbox file system",
145
+ inputSchema: {
146
+ type: "object",
147
+ properties: {
148
+ path: { type: "string", description: "File path to read from" }
149
+ },
150
+ required: ["path"]
151
+ },
152
+ async execute(input, context) {
153
+ const path = input.path;
154
+ try {
155
+ const content = await context.sandbox.readFile(path);
156
+ return {
157
+ success: true,
158
+ output: content,
159
+ preview: content.length > 200 ? content.slice(0, 200) + "..." : content
160
+ };
161
+ } catch (err) {
162
+ return {
163
+ success: false,
164
+ output: null,
165
+ error: err instanceof Error ? err.message : String(err)
166
+ };
167
+ }
168
+ }
169
+ };
170
+
171
+ // src/reference/walk.ts
172
+ var DEFAULT_EXCLUDE = ["node_modules", ".git", "dist", ".next"];
173
+ async function walkDir(sandbox, dir, opts) {
174
+ const exclude = opts?.exclude ?? DEFAULT_EXCLUDE;
175
+ const maxDepth = opts?.maxDepth ?? Infinity;
176
+ const results = [];
177
+ await walkRecursive(sandbox, dir, exclude, maxDepth, 0, results);
178
+ return results;
179
+ }
180
+ async function walkRecursive(sandbox, dir, exclude, maxDepth, depth, results) {
181
+ let entries;
182
+ try {
183
+ entries = await sandbox.listFiles(dir);
184
+ } catch {
185
+ return;
186
+ }
187
+ for (const entry of entries) {
188
+ const fullPath = dir === "." ? entry : `${dir}/${entry}`;
189
+ const basename = entry.split("/").pop() ?? entry;
190
+ if (exclude.includes(basename)) {
191
+ continue;
192
+ }
193
+ let isDir = false;
194
+ try {
195
+ await sandbox.listFiles(fullPath);
196
+ isDir = true;
197
+ } catch {
198
+ }
199
+ if (isDir) {
200
+ if (depth < maxDepth) {
201
+ await walkRecursive(sandbox, fullPath, exclude, maxDepth, depth + 1, results);
202
+ }
203
+ } else {
204
+ results.push(fullPath);
205
+ }
206
+ }
207
+ }
208
+
209
+ // src/reference/list-files.ts
210
+ var MAX_RECURSIVE_ENTRIES = 500;
211
+ var listFilesTool = {
212
+ name: "list_files",
213
+ description: "List files and directories in a sandbox directory. Use recursive mode to explore the full project structure.",
214
+ inputSchema: {
215
+ type: "object",
216
+ properties: {
217
+ path: {
218
+ type: "string",
219
+ description: "Directory path to list (defaults to root)"
220
+ },
221
+ recursive: {
222
+ type: "boolean",
223
+ description: "If true, recursively list all files (excludes node_modules, .git, dist). Defaults to false."
224
+ }
225
+ },
226
+ required: []
227
+ },
228
+ async execute(input, context) {
229
+ const path = input.path ?? ".";
230
+ const recursive = input.recursive ?? false;
231
+ try {
232
+ if (!recursive) {
233
+ const files = await context.sandbox.listFiles(path);
234
+ return {
235
+ success: true,
236
+ output: files,
237
+ preview: files.join("\n")
238
+ };
239
+ }
240
+ const allFiles = await walkDir(context.sandbox, path);
241
+ const capped = allFiles.slice(0, MAX_RECURSIVE_ENTRIES);
242
+ const suffix = allFiles.length > MAX_RECURSIVE_ENTRIES ? `
243
+ (${allFiles.length - MAX_RECURSIVE_ENTRIES} more files not shown)` : "";
244
+ const listing = capped.join("\n") + suffix;
245
+ return {
246
+ success: true,
247
+ output: capped,
248
+ preview: listing.length > 200 ? listing.slice(0, 200) + "..." : listing,
249
+ metadata: { total: allFiles.length, shown: capped.length }
250
+ };
251
+ } catch (err) {
252
+ return {
253
+ success: false,
254
+ output: null,
255
+ error: err instanceof Error ? err.message : String(err)
256
+ };
257
+ }
258
+ }
259
+ };
260
+
261
+ // src/reference/delete-file.ts
262
+ var deleteFileTool = {
263
+ name: "delete_file",
264
+ description: "Delete a file from the sandbox file system",
265
+ inputSchema: {
266
+ type: "object",
267
+ properties: {
268
+ path: { type: "string", description: "File path to delete" }
269
+ },
270
+ required: ["path"]
271
+ },
272
+ async execute(input, context) {
273
+ const path = input.path;
274
+ try {
275
+ await context.sandbox.deleteFile(path);
276
+ return {
277
+ success: true,
278
+ output: `Successfully deleted ${path}`
279
+ };
280
+ } catch (err) {
281
+ return {
282
+ success: false,
283
+ output: null,
284
+ error: err instanceof Error ? err.message : String(err)
285
+ };
286
+ }
287
+ }
288
+ };
289
+
290
+ // src/reference/execute-command.ts
291
+ var executeCommandTool = {
292
+ name: "execute_command",
293
+ description: "Run a shell command in the sandbox environment",
294
+ inputSchema: {
295
+ type: "object",
296
+ properties: {
297
+ command: { type: "string", description: "Shell command to execute" },
298
+ cwd: { type: "string", description: "Working directory (optional)" },
299
+ timeout: {
300
+ type: "number",
301
+ description: "Timeout in milliseconds (optional)"
302
+ }
303
+ },
304
+ required: ["command"]
305
+ },
306
+ async execute(input, context, onProgress) {
307
+ const command = input.command;
308
+ const cwd = input.cwd;
309
+ const timeout = input.timeout;
310
+ try {
311
+ const result = await context.sandbox.executeCommand(command, {
312
+ cwd,
313
+ timeout,
314
+ env: context.env,
315
+ onStdout: (data) => {
316
+ onProgress?.({ message: data });
317
+ },
318
+ onStderr: (data) => {
319
+ onProgress?.({ message: `stderr: ${data}` });
320
+ }
321
+ });
322
+ const output = [result.stdout, result.stderr].filter(Boolean).join("\n");
323
+ return {
324
+ success: result.exitCode === 0,
325
+ output,
326
+ error: result.exitCode !== 0 ? `Command exited with code ${result.exitCode}` : void 0,
327
+ metadata: { exitCode: result.exitCode }
328
+ };
329
+ } catch (err) {
330
+ return {
331
+ success: false,
332
+ output: null,
333
+ error: err instanceof Error ? err.message : String(err)
334
+ };
335
+ }
336
+ }
337
+ };
338
+
339
+ // src/reference/edit-file.ts
340
+ var editFileTool = {
341
+ name: "edit_file",
342
+ description: "Edit a file by replacing an exact string match. The old_string must appear exactly once in the file to ensure a precise, unambiguous edit.",
343
+ inputSchema: {
344
+ type: "object",
345
+ properties: {
346
+ path: { type: "string", description: "File path to edit" },
347
+ old_string: {
348
+ type: "string",
349
+ description: "Exact string to find (must appear exactly once)"
350
+ },
351
+ new_string: {
352
+ type: "string",
353
+ description: "Replacement string"
354
+ }
355
+ },
356
+ required: ["path", "old_string", "new_string"]
357
+ },
358
+ async execute(input, context) {
359
+ const path = input.path;
360
+ const oldStr = input.old_string;
361
+ const newStr = input.new_string;
362
+ try {
363
+ const content = await context.sandbox.readFile(path);
364
+ let count = 0;
365
+ let idx = 0;
366
+ while ((idx = content.indexOf(oldStr, idx)) !== -1) {
367
+ count++;
368
+ idx += oldStr.length;
369
+ }
370
+ if (count === 0) {
371
+ return {
372
+ success: false,
373
+ output: null,
374
+ error: `old_string not found in ${path}. Make sure the string matches exactly, including whitespace and indentation.`
375
+ };
376
+ }
377
+ if (count > 1) {
378
+ return {
379
+ success: false,
380
+ output: null,
381
+ error: `old_string appears ${count} times in ${path}. Provide more surrounding context to make the match unique.`
382
+ };
383
+ }
384
+ const updated = content.replace(oldStr, newStr);
385
+ await context.sandbox.writeFile(path, updated);
386
+ return {
387
+ success: true,
388
+ output: `Successfully edited ${path}`,
389
+ preview: `Replaced ${oldStr.length} chars with ${newStr.length} chars`
390
+ };
391
+ } catch (err) {
392
+ return {
393
+ success: false,
394
+ output: null,
395
+ error: err instanceof Error ? err.message : String(err)
396
+ };
397
+ }
398
+ }
399
+ };
400
+
401
+ // src/reference/search-files.ts
402
+ var MAX_MATCHES = 50;
403
+ var searchFilesTool = {
404
+ name: "search_files",
405
+ description: "Search file contents for a text pattern. Returns matching lines in file:line_number:content format. Searches recursively from the given path.",
406
+ inputSchema: {
407
+ type: "object",
408
+ properties: {
409
+ pattern: {
410
+ type: "string",
411
+ description: "Text pattern to search for (substring match)"
412
+ },
413
+ path: {
414
+ type: "string",
415
+ description: "Directory to search in (defaults to project root)"
416
+ },
417
+ include: {
418
+ type: "string",
419
+ description: 'File extension filter, e.g. "*.ts" (optional)'
420
+ }
421
+ },
422
+ required: ["pattern"]
423
+ },
424
+ async execute(input, context) {
425
+ const pattern = input.pattern;
426
+ const searchPath = input.path ?? ".";
427
+ const include = input.include;
428
+ try {
429
+ const files = await walkDir(context.sandbox, searchPath);
430
+ let filtered = files;
431
+ if (include) {
432
+ const ext = include.startsWith("*.") ? include.slice(1) : include;
433
+ filtered = files.filter((f) => f.endsWith(ext));
434
+ }
435
+ const matches = [];
436
+ for (const file of filtered) {
437
+ if (matches.length >= MAX_MATCHES) break;
438
+ let content;
439
+ try {
440
+ content = await context.sandbox.readFile(file);
441
+ } catch {
442
+ continue;
443
+ }
444
+ const lines = content.split("\n");
445
+ for (let i = 0; i < lines.length; i++) {
446
+ if (lines[i].includes(pattern)) {
447
+ matches.push(`${file}:${i + 1}:${lines[i]}`);
448
+ if (matches.length >= MAX_MATCHES) break;
449
+ }
450
+ }
451
+ }
452
+ if (matches.length === 0) {
453
+ return {
454
+ success: true,
455
+ output: "No matches found.",
456
+ preview: "No matches found."
457
+ };
458
+ }
459
+ const output = matches.join("\n");
460
+ const suffix = matches.length >= MAX_MATCHES ? `
461
+ (results capped at ${MAX_MATCHES})` : "";
462
+ return {
463
+ success: true,
464
+ output: output + suffix,
465
+ preview: output.length > 200 ? output.slice(0, 200) + "..." : output
466
+ };
467
+ } catch (err) {
468
+ return {
469
+ success: false,
470
+ output: null,
471
+ error: err instanceof Error ? err.message : String(err)
472
+ };
473
+ }
474
+ }
475
+ };
476
+
477
+ // src/index.ts
478
+ function getDefaultTools() {
479
+ return [
480
+ readFileTool,
481
+ writeFileTool,
482
+ listFilesTool,
483
+ deleteFileTool,
484
+ executeCommandTool,
485
+ editFileTool,
486
+ searchFilesTool
487
+ ];
488
+ }
489
+ export {
490
+ ToolRegistryImpl,
491
+ deleteFileTool,
492
+ editFileTool,
493
+ executeCommandTool,
494
+ getDefaultTools,
495
+ listFilesTool,
496
+ readFileTool,
497
+ searchFilesTool,
498
+ validateInput,
499
+ walkDir,
500
+ writeFileTool
501
+ };
502
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/validation.ts","../src/registry.ts","../src/reference/write-file.ts","../src/reference/read-file.ts","../src/reference/walk.ts","../src/reference/list-files.ts","../src/reference/delete-file.ts","../src/reference/execute-command.ts","../src/reference/edit-file.ts","../src/reference/search-files.ts","../src/index.ts"],"sourcesContent":["// Task 26d: JSON Schema validation for tool inputs\n\n/** Result of validating tool input against a JSON Schema. */\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validates a tool input object against a JSON Schema.\n *\n * @param input - The input object to validate.\n * @param schema - A JSON Schema object to validate against.\n * @returns A {@link ValidationResult} indicating validity and any errors.\n *\n * @remarks\n * Performs lightweight validation: checks required fields and basic type\n * matching (string, number, integer, boolean, array, object). Does not\n * support advanced JSON Schema features like `$ref`, `allOf`, or `pattern`.\n */\nexport function validateInput(\n input: Record<string, unknown>,\n schema: Record<string, unknown>,\n): ValidationResult {\n const errors: string[] = [];\n\n if (schema.type !== 'object') {\n return { valid: true, errors: [] };\n }\n\n // Check required fields\n const required = (schema.required as string[]) ?? [];\n for (const field of required) {\n if (!(field in input) || input[field] === undefined || input[field] === null) {\n errors.push(`Missing required field: '${field}'`);\n }\n }\n\n // Check property types\n const properties = (schema.properties as Record<string, Record<string, unknown>>) ?? {};\n for (const [key, value] of Object.entries(input)) {\n const propSchema = properties[key];\n if (!propSchema) continue;\n\n const expectedType = propSchema.type as string;\n if (!expectedType) continue;\n\n const actualType = Array.isArray(value) ? 'array' : typeof value;\n\n if (expectedType === 'integer') {\n if (typeof value !== 'number' || !Number.isInteger(value)) {\n errors.push(`Field '${key}': expected integer, got ${actualType}`);\n }\n } else if (expectedType !== actualType) {\n errors.push(`Field '${key}': expected ${expectedType}, got ${actualType}`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n","// Task 26: ToolRegistryImpl\n\nimport type { Tool, ToolDefinition, ToolRegistry } from '@yolo-labs/core-types';\nimport { validateInput } from './validation.js';\n\n/**\n * Default {@link ToolRegistry} implementation with JSON Schema input validation.\n *\n * @remarks\n * Tools are stored in a Map keyed by name. Duplicate registration throws.\n * Use `executeWithValidation` for schema-checked execution, or `get` a\n * tool and call its `execute` method directly.\n *\n * @example\n * ```ts\n * const registry = new ToolRegistryImpl();\n * registry.register(readFileTool);\n * registry.register(writeFileTool);\n * const defs = registry.toAIToolDefinitions();\n * ```\n */\nexport class ToolRegistryImpl implements ToolRegistry {\n private tools = new Map<string, Tool>();\n\n /**\n * Registers a tool in the registry.\n *\n * @param tool - The tool to register.\n * @throws Error if a tool with the same name is already registered.\n */\n register(tool: Tool): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool '${tool.name}' is already registered`);\n }\n this.tools.set(tool.name, tool);\n }\n\n /**\n * Removes a tool from the registry by name.\n *\n * @param name - The name of the tool to remove.\n * @throws Error if the tool is not registered.\n */\n unregister(name: string): void {\n if (!this.tools.has(name)) {\n throw new Error(`Tool '${name}' is not registered`);\n }\n this.tools.delete(name);\n }\n\n /**\n * Retrieves a registered tool by name.\n *\n * @param name - The tool name to look up.\n * @returns The tool instance, or `undefined` if not found.\n */\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n /** Returns all registered tools. */\n list(): Tool[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Serializes all registered tools to the canonical AI tool definition format.\n *\n * @returns An array of {@link ToolDefinition} objects suitable for passing to an AI provider.\n */\n toAIToolDefinitions(): ToolDefinition[] {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }));\n }\n\n /**\n * Validates tool input against its JSON Schema and executes the tool.\n *\n * @param name - The name of the tool to execute.\n * @param input - The input object to validate and pass to the tool.\n * @param args - Remaining arguments forwarded to the tool's execute method.\n * @returns The tool result, or a failure result if validation fails.\n * @throws Error if the tool is not found in the registry.\n */\n async executeWithValidation(\n name: string,\n input: Record<string, unknown>,\n ...args: Parameters<Tool['execute']> extends [unknown, ...infer Rest] ? Rest : never\n ): Promise<ReturnType<Tool['execute']>> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new Error(`Tool '${name}' not found in registry`);\n }\n\n const validation = validateInput(input, tool.inputSchema);\n if (!validation.valid) {\n return {\n success: false,\n output: null,\n error: `Validation failed: ${validation.errors.join(', ')}`,\n };\n }\n\n return tool.execute(input, ...args);\n }\n}\n","// Task 27: write_file reference tool\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\n\n/** Reference tool: creates or overwrites a file in the sandbox. */\nexport const writeFileTool: Tool = {\n name: 'write_file',\n description: 'Create or overwrite a file in the sandbox file system',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path to write to' },\n content: { type: 'string', description: 'Content to write to the file' },\n },\n required: ['path', 'content'],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n ): Promise<ToolResult> {\n const path = input.path as string;\n const content = input.content as string;\n\n try {\n await context.sandbox.writeFile(path, content);\n return {\n success: true,\n output: `Successfully wrote ${content.length} characters to ${path}`,\n preview: content.length > 200 ? content.slice(0, 200) + '...' : content,\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// Task 28: read_file reference tool\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\n\n/** Reference tool: reads the contents of a file from the sandbox. */\nexport const readFileTool: Tool = {\n name: 'read_file',\n description: 'Read the contents of a file from the sandbox file system',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path to read from' },\n },\n required: ['path'],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n ): Promise<ToolResult> {\n const path = input.path as string;\n\n try {\n const content = await context.sandbox.readFile(path);\n return {\n success: true,\n output: content,\n preview: content.length > 200 ? content.slice(0, 200) + '...' : content,\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// Task 123: Shared recursive directory walker\n\nimport type { SandboxProvider } from '@yolo-labs/core-types';\n\n/** Default directories to exclude from recursive walks. */\nconst DEFAULT_EXCLUDE = ['node_modules', '.git', 'dist', '.next'];\n\nexport interface WalkOptions {\n /** Directories to skip (basename match). Defaults to node_modules, .git, dist, .next. */\n exclude?: string[];\n /** Maximum directory depth (0 = only top-level). Defaults to Infinity. */\n maxDepth?: number;\n}\n\n/**\n * Recursively walk a directory tree using the SandboxProvider interface.\n *\n * Uses `sandbox.listFiles()` to enumerate entries and probes each entry\n * with another `listFiles()` call to determine if it is a directory.\n * Returns a flat list of file paths (not directories).\n */\nexport async function walkDir(\n sandbox: SandboxProvider,\n dir: string,\n opts?: WalkOptions,\n): Promise<string[]> {\n const exclude = opts?.exclude ?? DEFAULT_EXCLUDE;\n const maxDepth = opts?.maxDepth ?? Infinity;\n\n const results: string[] = [];\n await walkRecursive(sandbox, dir, exclude, maxDepth, 0, results);\n return results;\n}\n\nasync function walkRecursive(\n sandbox: SandboxProvider,\n dir: string,\n exclude: string[],\n maxDepth: number,\n depth: number,\n results: string[],\n): Promise<void> {\n let entries: string[];\n try {\n entries = await sandbox.listFiles(dir);\n } catch {\n return; // dir doesn't exist or can't be listed — skip\n }\n\n for (const entry of entries) {\n const fullPath = dir === '.' ? entry : `${dir}/${entry}`;\n const basename = entry.split('/').pop() ?? entry;\n\n // Skip excluded directories\n if (exclude.includes(basename)) {\n continue;\n }\n\n // Probe: if listFiles succeeds, it's a directory\n let isDir = false;\n try {\n await sandbox.listFiles(fullPath);\n isDir = true;\n } catch {\n // Not a directory — it's a file\n }\n\n if (isDir) {\n if (depth < maxDepth) {\n await walkRecursive(sandbox, fullPath, exclude, maxDepth, depth + 1, results);\n }\n // At maxDepth, skip directories (only return files)\n } else {\n results.push(fullPath);\n }\n }\n}\n","// Task 29: list_files reference tool\n// Task 126: Enhanced with recursive option\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\nimport { walkDir } from './walk.js';\n\n/** Maximum entries returned in recursive mode. */\nconst MAX_RECURSIVE_ENTRIES = 500;\n\n/** Reference tool: lists files and directories in a sandbox directory. */\nexport const listFilesTool: Tool = {\n name: 'list_files',\n description:\n 'List files and directories in a sandbox directory. Use recursive mode to explore the full project structure.',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Directory path to list (defaults to root)',\n },\n recursive: {\n type: 'boolean',\n description:\n 'If true, recursively list all files (excludes node_modules, .git, dist). Defaults to false.',\n },\n },\n required: [],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n ): Promise<ToolResult> {\n const path = (input.path as string) ?? '.';\n const recursive = (input.recursive as boolean) ?? false;\n\n try {\n if (!recursive) {\n const files = await context.sandbox.listFiles(path);\n return {\n success: true,\n output: files,\n preview: files.join('\\n'),\n };\n }\n\n // Recursive mode: use walkDir helper\n const allFiles = await walkDir(context.sandbox, path);\n const capped = allFiles.slice(0, MAX_RECURSIVE_ENTRIES);\n const suffix =\n allFiles.length > MAX_RECURSIVE_ENTRIES\n ? `\\n(${allFiles.length - MAX_RECURSIVE_ENTRIES} more files not shown)`\n : '';\n\n const listing = capped.join('\\n') + suffix;\n return {\n success: true,\n output: capped,\n preview:\n listing.length > 200 ? listing.slice(0, 200) + '...' : listing,\n metadata: { total: allFiles.length, shown: capped.length },\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// Task 30: delete_file reference tool\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\n\n/** Reference tool: deletes a file from the sandbox file system. */\nexport const deleteFileTool: Tool = {\n name: 'delete_file',\n description: 'Delete a file from the sandbox file system',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path to delete' },\n },\n required: ['path'],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n ): Promise<ToolResult> {\n const path = input.path as string;\n\n try {\n await context.sandbox.deleteFile(path);\n return {\n success: true,\n output: `Successfully deleted ${path}`,\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// Task 31: execute_command reference tool\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\n\n/** Reference tool: runs a shell command in the sandbox environment. */\nexport const executeCommandTool: Tool = {\n name: 'execute_command',\n description: 'Run a shell command in the sandbox environment',\n inputSchema: {\n type: 'object',\n properties: {\n command: { type: 'string', description: 'Shell command to execute' },\n cwd: { type: 'string', description: 'Working directory (optional)' },\n timeout: {\n type: 'number',\n description: 'Timeout in milliseconds (optional)',\n },\n },\n required: ['command'],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n onProgress?: (progress: { message: string }) => void,\n ): Promise<ToolResult> {\n const command = input.command as string;\n const cwd = input.cwd as string | undefined;\n const timeout = input.timeout as number | undefined;\n\n try {\n const result = await context.sandbox.executeCommand(command, {\n cwd,\n timeout,\n env: context.env,\n onStdout: (data) => {\n onProgress?.({ message: data });\n },\n onStderr: (data) => {\n onProgress?.({ message: `stderr: ${data}` });\n },\n });\n\n const output = [result.stdout, result.stderr].filter(Boolean).join('\\n');\n\n return {\n success: result.exitCode === 0,\n output,\n error:\n result.exitCode !== 0\n ? `Command exited with code ${result.exitCode}`\n : undefined,\n metadata: { exitCode: result.exitCode },\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// Task 124: edit_file reference tool — find/replace editing\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\n\n/** Reference tool: targeted find/replace edit on a file in the sandbox. */\nexport const editFileTool: Tool = {\n name: 'edit_file',\n description:\n 'Edit a file by replacing an exact string match. The old_string must appear exactly once in the file to ensure a precise, unambiguous edit.',\n inputSchema: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'File path to edit' },\n old_string: {\n type: 'string',\n description: 'Exact string to find (must appear exactly once)',\n },\n new_string: {\n type: 'string',\n description: 'Replacement string',\n },\n },\n required: ['path', 'old_string', 'new_string'],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n ): Promise<ToolResult> {\n const path = input.path as string;\n const oldStr = input.old_string as string;\n const newStr = input.new_string as string;\n\n try {\n const content = await context.sandbox.readFile(path);\n\n // Count occurrences\n let count = 0;\n let idx = 0;\n while ((idx = content.indexOf(oldStr, idx)) !== -1) {\n count++;\n idx += oldStr.length;\n }\n\n if (count === 0) {\n return {\n success: false,\n output: null,\n error: `old_string not found in ${path}. Make sure the string matches exactly, including whitespace and indentation.`,\n };\n }\n\n if (count > 1) {\n return {\n success: false,\n output: null,\n error: `old_string appears ${count} times in ${path}. Provide more surrounding context to make the match unique.`,\n };\n }\n\n // Exactly one match — replace\n const updated = content.replace(oldStr, newStr);\n await context.sandbox.writeFile(path, updated);\n\n return {\n success: true,\n output: `Successfully edited ${path}`,\n preview: `Replaced ${oldStr.length} chars with ${newStr.length} chars`,\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// Task 125: search_files reference tool — content search across files\n\nimport type { Tool, SandboxContext, ToolResult } from '@yolo-labs/core-types';\nimport { walkDir } from './walk.js';\n\n/** Maximum number of matching lines returned. */\nconst MAX_MATCHES = 50;\n\n/** Reference tool: searches file contents for a pattern across the project. */\nexport const searchFilesTool: Tool = {\n name: 'search_files',\n description:\n 'Search file contents for a text pattern. Returns matching lines in file:line_number:content format. Searches recursively from the given path.',\n inputSchema: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: 'Text pattern to search for (substring match)',\n },\n path: {\n type: 'string',\n description: 'Directory to search in (defaults to project root)',\n },\n include: {\n type: 'string',\n description: 'File extension filter, e.g. \"*.ts\" (optional)',\n },\n },\n required: ['pattern'],\n },\n async execute(\n input: Record<string, unknown>,\n context: SandboxContext,\n ): Promise<ToolResult> {\n const pattern = input.pattern as string;\n const searchPath = (input.path as string) ?? '.';\n const include = input.include as string | undefined;\n\n try {\n const files = await walkDir(context.sandbox, searchPath);\n\n // Filter by extension if include is specified (e.g. \"*.ts\" → \".ts\")\n let filtered = files;\n if (include) {\n const ext = include.startsWith('*.') ? include.slice(1) : include;\n filtered = files.filter((f) => f.endsWith(ext));\n }\n\n const matches: string[] = [];\n\n for (const file of filtered) {\n if (matches.length >= MAX_MATCHES) break;\n\n let content: string;\n try {\n content = await context.sandbox.readFile(file);\n } catch {\n continue; // Skip unreadable files\n }\n\n const lines = content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].includes(pattern)) {\n matches.push(`${file}:${i + 1}:${lines[i]}`);\n if (matches.length >= MAX_MATCHES) break;\n }\n }\n }\n\n if (matches.length === 0) {\n return {\n success: true,\n output: 'No matches found.',\n preview: 'No matches found.',\n };\n }\n\n const output = matches.join('\\n');\n const suffix = matches.length >= MAX_MATCHES ? `\\n(results capped at ${MAX_MATCHES})` : '';\n return {\n success: true,\n output: output + suffix,\n preview:\n output.length > 200 ? output.slice(0, 200) + '...' : output,\n };\n } catch (err) {\n return {\n success: false,\n output: null,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n },\n};\n","// @yolo-labs/core-tools — Tool registry, tool execution, tool result types\n\nimport type { Tool } from '@yolo-labs/core-types';\n\nexport { ToolRegistryImpl } from './registry.js';\nexport { validateInput } from './validation.js';\nexport type { ValidationResult } from './validation.js';\n\n// Reference tools (opt-in)\nexport {\n writeFileTool,\n readFileTool,\n listFilesTool,\n deleteFileTool,\n executeCommandTool,\n editFileTool,\n searchFilesTool,\n walkDir,\n} from './reference/index.js';\nexport type { WalkOptions } from './reference/index.js';\n\nimport {\n writeFileTool,\n readFileTool,\n listFilesTool,\n deleteFileTool,\n executeCommandTool,\n editFileTool,\n searchFilesTool,\n} from './reference/index.js';\n\n/**\n * Returns all 7 reference tools: read_file, write_file, list_files, delete_file,\n * execute_command, edit_file, search_files.\n *\n * @remarks\n * Convenience function for registering the standard tool set. Used by\n * {@link createHeadlessAgent} when `tools: 'default'` is specified in config.\n */\nexport function getDefaultTools(): Tool[] {\n return [\n readFileTool,\n writeFileTool,\n listFilesTool,\n deleteFileTool,\n executeCommandTool,\n editFileTool,\n searchFilesTool,\n ];\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@yolo-labs/core-tools",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ }
10
+ },
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "dependencies": {
17
+ "@yolo-labs/core-types": "1.0.0"
18
+ },
19
+ "devDependencies": {
20
+ "tsup": "^8.0.0",
21
+ "typescript": "^5.5.0"
22
+ },
23
+ "description": "Tool registry, input validation, and reference tools for AI agents",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/yolo-labs-hq/monorepo.git",
28
+ "directory": "yolo-core/packages/tools"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public",
32
+ "registry": "https://registry.npmjs.org/"
33
+ },
34
+ "homepage": "https://github.com/yolo-labs-hq/monorepo/tree/main/yolo-core#readme",
35
+ "bugs": {
36
+ "url": "https://github.com/yolo-labs-hq/monorepo/issues"
37
+ },
38
+ "scripts": {
39
+ "build": "tsup",
40
+ "clean": "rm -rf dist *.tsbuildinfo"
41
+ }
42
+ }