@agentforge/tools 0.6.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -261,26 +261,18 @@ var extractImages = core.toolBuilder().name("extract-images").description("Extra
261
261
  }).build();
262
262
  var urlValidator = core.toolBuilder().name("url-validator").description("Validate and parse URLs. Returns detailed information about the URL structure including protocol, hostname, path, query parameters, and hash.").category(core.ToolCategory.WEB).tags(["url", "validator", "parse", "validate"]).schema(zod.z.object({
263
263
  url: zod.z.string().describe("The URL to validate and parse")
264
- })).implement(async (input) => {
265
- try {
266
- const parsed = new URL(input.url);
267
- return {
268
- valid: true,
269
- url: parsed.href,
270
- protocol: parsed.protocol,
271
- hostname: parsed.hostname,
272
- port: parsed.port,
273
- pathname: parsed.pathname,
274
- search: parsed.search,
275
- hash: parsed.hash,
276
- origin: parsed.origin
277
- };
278
- } catch (error) {
279
- return {
280
- valid: false,
281
- error: error instanceof Error ? error.message : "Invalid URL"
282
- };
283
- }
264
+ })).implementSafe(async (input) => {
265
+ const parsed = new URL(input.url);
266
+ return {
267
+ url: parsed.href,
268
+ protocol: parsed.protocol,
269
+ hostname: parsed.hostname,
270
+ port: parsed.port,
271
+ pathname: parsed.pathname,
272
+ search: parsed.search,
273
+ hash: parsed.hash,
274
+ origin: parsed.origin
275
+ };
284
276
  }).build();
285
277
  var urlBuilder = core.toolBuilder().name("url-builder").description("Build a URL from components (protocol, hostname, path, query parameters, hash).").category(core.ToolCategory.WEB).tags(["url", "builder", "construct"]).schema(zod.z.object({
286
278
  protocol: zod.z.string().default("https").describe("Protocol (http, https, etc.)"),
@@ -693,89 +685,55 @@ var webSearch = core.toolBuilder().name("web-search").description(
693
685
  var jsonParser = core.toolBuilder().name("json-parser").description("Parse JSON string into an object. Validates JSON syntax and returns parsed data or error details.").category(core.ToolCategory.UTILITY).tags(["json", "parse", "data"]).schema(zod.z.object({
694
686
  json: zod.z.string().describe("JSON string to parse"),
695
687
  strict: zod.z.boolean().default(true).describe("Use strict JSON parsing (no trailing commas, etc.)")
696
- })).implement(async (input) => {
697
- try {
698
- const parsed = JSON.parse(input.json);
699
- return {
700
- success: true,
701
- data: parsed,
702
- type: Array.isArray(parsed) ? "array" : typeof parsed
703
- };
704
- } catch (error) {
705
- return {
706
- success: false,
707
- error: error instanceof Error ? error.message : "Failed to parse JSON"
708
- };
709
- }
688
+ })).implementSafe(async (input) => {
689
+ const parsed = JSON.parse(input.json);
690
+ return {
691
+ data: parsed,
692
+ type: Array.isArray(parsed) ? "array" : typeof parsed
693
+ };
710
694
  }).build();
711
695
  var jsonStringify = core.toolBuilder().name("json-stringify").description("Convert an object to a JSON string with optional formatting (pretty print).").category(core.ToolCategory.UTILITY).tags(["json", "stringify", "format", "data"]).schema(zod.z.object({
712
696
  data: zod.z.any().describe("Data to convert to JSON string"),
713
697
  pretty: zod.z.boolean().default(false).describe("Format with indentation for readability"),
714
698
  indent: zod.z.number().default(2).describe("Number of spaces for indentation (when pretty is true)")
715
- })).implement(async (input) => {
716
- try {
717
- const json = input.pretty ? JSON.stringify(input.data, null, input.indent) : JSON.stringify(input.data);
718
- return {
719
- success: true,
720
- json,
721
- length: json.length
722
- };
723
- } catch (error) {
724
- return {
725
- success: false,
726
- error: error instanceof Error ? error.message : "Failed to stringify data"
727
- };
728
- }
699
+ })).implementSafe(async (input) => {
700
+ const json = input.pretty ? JSON.stringify(input.data, null, input.indent) : JSON.stringify(input.data);
701
+ return {
702
+ json,
703
+ length: json.length
704
+ };
729
705
  }).build();
730
706
  var jsonQuery = core.toolBuilder().name("json-query").description('Query JSON data using dot notation path (e.g., "user.address.city"). Supports array indexing.').category(core.ToolCategory.UTILITY).tags(["json", "query", "path", "data"]).schema(zod.z.object({
731
707
  data: zod.z.any().describe("JSON data to query"),
732
708
  path: zod.z.string().describe('Dot notation path to query (e.g., "user.name" or "items[0].id")')
733
- })).implement(async (input) => {
734
- try {
735
- const parts = input.path.split(".");
736
- let current = input.data;
737
- for (const part of parts) {
738
- const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
739
- if (arrayMatch) {
740
- const [, key, index] = arrayMatch;
741
- current = current[key][parseInt(index, 10)];
742
- } else {
743
- current = current[part];
744
- }
745
- if (current === void 0) {
746
- return {
747
- success: false,
748
- error: `Path not found: ${input.path}`
749
- };
750
- }
709
+ })).implementSafe(async (input) => {
710
+ const parts = input.path.split(".");
711
+ let current = input.data;
712
+ for (const part of parts) {
713
+ const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
714
+ if (arrayMatch) {
715
+ const [, key, index] = arrayMatch;
716
+ current = current[key][parseInt(index, 10)];
717
+ } else {
718
+ current = current[part];
719
+ }
720
+ if (current === void 0) {
721
+ throw new Error(`Path not found: ${input.path}`);
751
722
  }
752
- return {
753
- success: true,
754
- value: current,
755
- type: Array.isArray(current) ? "array" : typeof current
756
- };
757
- } catch (error) {
758
- return {
759
- success: false,
760
- error: error instanceof Error ? error.message : "Failed to query JSON"
761
- };
762
723
  }
724
+ return {
725
+ value: current,
726
+ type: Array.isArray(current) ? "array" : typeof current
727
+ };
763
728
  }).build();
764
729
  var jsonValidator = core.toolBuilder().name("json-validator").description("Validate JSON string syntax without parsing. Returns whether the JSON is valid and any error details.").category(core.ToolCategory.UTILITY).tags(["json", "validate", "check", "data"]).schema(zod.z.object({
765
730
  json: zod.z.string().describe("JSON string to validate")
766
- })).implement(async (input) => {
767
- try {
768
- JSON.parse(input.json);
769
- return {
770
- valid: true,
771
- message: "Valid JSON"
772
- };
773
- } catch (error) {
774
- return {
775
- valid: false,
776
- error: error instanceof Error ? error.message : "Invalid JSON"
777
- };
778
- }
731
+ })).implementSafe(async (input) => {
732
+ JSON.parse(input.json);
733
+ return {
734
+ valid: true,
735
+ message: "Valid JSON"
736
+ };
779
737
  }).build();
780
738
  var jsonMerge = core.toolBuilder().name("json-merge").description("Merge two or more JSON objects. Later objects override earlier ones for conflicting keys.").category(core.ToolCategory.UTILITY).tags(["json", "merge", "combine", "data"]).schema(zod.z.object({
781
739
  objects: zod.z.array(zod.z.any().describe("Object to merge")).describe("Array of objects to merge"),
@@ -1121,90 +1079,54 @@ var objectOmit = core.toolBuilder().name("object-omit").description("Create a ne
1121
1079
  var fileReader = core.toolBuilder().name("file-reader").description("Read the contents of a file from the file system. Supports text and binary files with various encodings.").category(core.ToolCategory.FILE_SYSTEM).tags(["file", "read", "io", "filesystem"]).schema(zod.z.object({
1122
1080
  path: zod.z.string().describe("Path to the file to read"),
1123
1081
  encoding: zod.z.enum(["utf8", "utf-8", "ascii", "base64", "hex", "binary"]).default("utf8").describe("File encoding")
1124
- })).implement(async (input) => {
1125
- try {
1126
- const content = await fs.promises.readFile(input.path, input.encoding);
1127
- const stats = await fs.promises.stat(input.path);
1128
- return {
1129
- success: true,
1130
- content,
1131
- size: stats.size,
1132
- path: input.path,
1133
- encoding: input.encoding
1134
- };
1135
- } catch (error) {
1136
- return {
1137
- success: false,
1138
- error: error instanceof Error ? error.message : "Failed to read file",
1139
- path: input.path
1140
- };
1141
- }
1082
+ })).implementSafe(async (input) => {
1083
+ const content = await fs.promises.readFile(input.path, input.encoding);
1084
+ const stats = await fs.promises.stat(input.path);
1085
+ return {
1086
+ content,
1087
+ size: stats.size,
1088
+ path: input.path,
1089
+ encoding: input.encoding
1090
+ };
1142
1091
  }).build();
1143
1092
  var fileWriter = core.toolBuilder().name("file-writer").description("Write content to a file. Creates the file if it doesn't exist, or overwrites it if it does.").category(core.ToolCategory.FILE_SYSTEM).tags(["file", "write", "io", "filesystem"]).schema(zod.z.object({
1144
1093
  path: zod.z.string().describe("Path to the file to write"),
1145
1094
  content: zod.z.string().describe("Content to write to the file"),
1146
1095
  encoding: zod.z.enum(["utf8", "utf-8", "ascii", "base64", "hex"]).default("utf8").describe("File encoding"),
1147
1096
  createDirs: zod.z.boolean().default(false).describe("Create parent directories if they don't exist")
1148
- })).implement(async (input) => {
1149
- try {
1150
- if (input.createDirs) {
1151
- const dir = path3__namespace.dirname(input.path);
1152
- await fs.promises.mkdir(dir, { recursive: true });
1153
- }
1154
- await fs.promises.writeFile(input.path, input.content, input.encoding);
1155
- const stats = await fs.promises.stat(input.path);
1156
- return {
1157
- success: true,
1158
- path: input.path,
1159
- size: stats.size,
1160
- encoding: input.encoding
1161
- };
1162
- } catch (error) {
1163
- return {
1164
- success: false,
1165
- error: error instanceof Error ? error.message : "Failed to write file",
1166
- path: input.path
1167
- };
1097
+ })).implementSafe(async (input) => {
1098
+ if (input.createDirs) {
1099
+ const dir = path3__namespace.dirname(input.path);
1100
+ await fs.promises.mkdir(dir, { recursive: true });
1168
1101
  }
1102
+ await fs.promises.writeFile(input.path, input.content, input.encoding);
1103
+ const stats = await fs.promises.stat(input.path);
1104
+ return {
1105
+ path: input.path,
1106
+ size: stats.size,
1107
+ encoding: input.encoding
1108
+ };
1169
1109
  }).build();
1170
1110
  var fileAppend = core.toolBuilder().name("file-append").description("Append content to the end of a file. Creates the file if it doesn't exist.").category(core.ToolCategory.FILE_SYSTEM).tags(["file", "append", "io", "filesystem"]).schema(zod.z.object({
1171
1111
  path: zod.z.string().describe("Path to the file to append to"),
1172
1112
  content: zod.z.string().describe("Content to append to the file"),
1173
1113
  encoding: zod.z.enum(["utf8", "utf-8", "ascii"]).default("utf8").describe("File encoding")
1174
- })).implement(async (input) => {
1175
- try {
1176
- await fs.promises.appendFile(input.path, input.content, input.encoding);
1177
- const stats = await fs.promises.stat(input.path);
1178
- return {
1179
- success: true,
1180
- path: input.path,
1181
- size: stats.size
1182
- };
1183
- } catch (error) {
1184
- return {
1185
- success: false,
1186
- error: error instanceof Error ? error.message : "Failed to append to file",
1187
- path: input.path
1188
- };
1189
- }
1114
+ })).implementSafe(async (input) => {
1115
+ await fs.promises.appendFile(input.path, input.content, input.encoding);
1116
+ const stats = await fs.promises.stat(input.path);
1117
+ return {
1118
+ path: input.path,
1119
+ size: stats.size
1120
+ };
1190
1121
  }).build();
1191
1122
  var fileDelete = core.toolBuilder().name("file-delete").description("Delete a file from the file system. Returns an error if the file doesn't exist.").category(core.ToolCategory.FILE_SYSTEM).tags(["file", "delete", "remove", "filesystem"]).schema(zod.z.object({
1192
1123
  path: zod.z.string().describe("Path to the file to delete")
1193
- })).implement(async (input) => {
1194
- try {
1195
- await fs.promises.unlink(input.path);
1196
- return {
1197
- success: true,
1198
- path: input.path,
1199
- message: "File deleted successfully"
1200
- };
1201
- } catch (error) {
1202
- return {
1203
- success: false,
1204
- error: error instanceof Error ? error.message : "Failed to delete file",
1205
- path: input.path
1206
- };
1207
- }
1124
+ })).implementSafe(async (input) => {
1125
+ await fs.promises.unlink(input.path);
1126
+ return {
1127
+ path: input.path,
1128
+ message: "File deleted successfully"
1129
+ };
1208
1130
  }).build();
1209
1131
  var fileExists = core.toolBuilder().name("file-exists").description("Check if a file or directory exists at the specified path.").category(core.ToolCategory.FILE_SYSTEM).tags(["file", "exists", "check", "filesystem"]).schema(zod.z.object({
1210
1132
  path: zod.z.string().describe("Path to check")
@@ -1232,137 +1154,101 @@ var directoryList = core.toolBuilder().name("directory-list").description("List
1232
1154
  recursive: zod.z.boolean().default(false).describe("List files recursively in subdirectories"),
1233
1155
  includeDetails: zod.z.boolean().default(false).describe("Include file size, type, and modification date"),
1234
1156
  extension: zod.z.string().optional().describe('Optional file extension filter (e.g., ".txt", ".js")')
1235
- })).implement(async (input) => {
1236
- try {
1237
- const listFiles = async (dir, recursive) => {
1238
- const entries = await fs.promises.readdir(dir, { withFileTypes: true });
1239
- const files2 = [];
1240
- for (const entry of entries) {
1241
- const fullPath = path3__namespace.join(dir, entry.name);
1242
- const relativePath = path3__namespace.relative(input.path, fullPath);
1243
- if (input.extension && !entry.name.endsWith(input.extension)) {
1244
- if (!entry.isDirectory() || !recursive) {
1245
- continue;
1246
- }
1247
- }
1248
- if (input.includeDetails) {
1249
- const stats = await fs.promises.stat(fullPath);
1250
- files2.push({
1251
- name: entry.name,
1252
- path: relativePath,
1253
- fullPath,
1254
- isFile: entry.isFile(),
1255
- isDirectory: entry.isDirectory(),
1256
- size: stats.size,
1257
- modified: stats.mtime.toISOString()
1258
- });
1259
- } else {
1260
- files2.push({
1261
- name: entry.name,
1262
- path: relativePath,
1263
- isFile: entry.isFile(),
1264
- isDirectory: entry.isDirectory()
1265
- });
1266
- }
1267
- if (recursive && entry.isDirectory()) {
1268
- const subFiles = await listFiles(fullPath, true);
1269
- files2.push(...subFiles);
1157
+ })).implementSafe(async (input) => {
1158
+ const listFiles = async (dir, recursive) => {
1159
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
1160
+ const files2 = [];
1161
+ for (const entry of entries) {
1162
+ const fullPath = path3__namespace.join(dir, entry.name);
1163
+ const relativePath = path3__namespace.relative(input.path, fullPath);
1164
+ if (input.extension && !entry.name.endsWith(input.extension)) {
1165
+ if (!entry.isDirectory() || !recursive) {
1166
+ continue;
1270
1167
  }
1271
1168
  }
1272
- return files2;
1273
- };
1274
- const files = await listFiles(input.path, input.recursive ?? false);
1275
- return {
1276
- success: true,
1277
- path: input.path,
1278
- files,
1279
- count: files.length
1280
- };
1281
- } catch (error) {
1282
- return {
1283
- success: false,
1284
- error: error instanceof Error ? error.message : "Failed to list directory",
1285
- path: input.path
1286
- };
1287
- }
1169
+ if (input.includeDetails) {
1170
+ const stats = await fs.promises.stat(fullPath);
1171
+ files2.push({
1172
+ name: entry.name,
1173
+ path: relativePath,
1174
+ fullPath,
1175
+ isFile: entry.isFile(),
1176
+ isDirectory: entry.isDirectory(),
1177
+ size: stats.size,
1178
+ modified: stats.mtime.toISOString()
1179
+ });
1180
+ } else {
1181
+ files2.push({
1182
+ name: entry.name,
1183
+ path: relativePath,
1184
+ isFile: entry.isFile(),
1185
+ isDirectory: entry.isDirectory()
1186
+ });
1187
+ }
1188
+ if (recursive && entry.isDirectory()) {
1189
+ const subFiles = await listFiles(fullPath, true);
1190
+ files2.push(...subFiles);
1191
+ }
1192
+ }
1193
+ return files2;
1194
+ };
1195
+ const files = await listFiles(input.path, input.recursive ?? false);
1196
+ return {
1197
+ path: input.path,
1198
+ files,
1199
+ count: files.length
1200
+ };
1288
1201
  }).build();
1289
1202
  var directoryCreate = core.toolBuilder().name("directory-create").description("Create a new directory. Can optionally create parent directories if they don't exist.").category(core.ToolCategory.FILE_SYSTEM).tags(["directory", "create", "mkdir", "filesystem"]).schema(zod.z.object({
1290
1203
  path: zod.z.string().describe("Path to the directory to create"),
1291
1204
  recursive: zod.z.boolean().default(true).describe("Create parent directories if they don't exist")
1292
- })).implement(async (input) => {
1293
- try {
1294
- await fs.promises.mkdir(input.path, { recursive: input.recursive });
1295
- return {
1296
- success: true,
1297
- path: input.path,
1298
- message: "Directory created successfully"
1299
- };
1300
- } catch (error) {
1301
- return {
1302
- success: false,
1303
- error: error instanceof Error ? error.message : "Failed to create directory",
1304
- path: input.path
1305
- };
1306
- }
1205
+ })).implementSafe(async (input) => {
1206
+ await fs.promises.mkdir(input.path, { recursive: input.recursive });
1207
+ return {
1208
+ path: input.path,
1209
+ message: "Directory created successfully"
1210
+ };
1307
1211
  }).build();
1308
1212
  var directoryDelete = core.toolBuilder().name("directory-delete").description("Delete a directory. Can optionally delete non-empty directories recursively.").category(core.ToolCategory.FILE_SYSTEM).tags(["directory", "delete", "remove", "filesystem"]).schema(zod.z.object({
1309
1213
  path: zod.z.string().describe("Path to the directory to delete"),
1310
1214
  recursive: zod.z.boolean().default(false).describe("Delete directory and all its contents")
1311
- })).implement(async (input) => {
1312
- try {
1313
- await fs.promises.rm(input.path, { recursive: input.recursive, force: false });
1314
- return {
1315
- success: true,
1316
- path: input.path,
1317
- message: "Directory deleted successfully"
1318
- };
1319
- } catch (error) {
1320
- return {
1321
- success: false,
1322
- error: error instanceof Error ? error.message : "Failed to delete directory",
1323
- path: input.path
1324
- };
1325
- }
1215
+ })).implementSafe(async (input) => {
1216
+ await fs.promises.rm(input.path, { recursive: input.recursive, force: false });
1217
+ return {
1218
+ path: input.path,
1219
+ message: "Directory deleted successfully"
1220
+ };
1326
1221
  }).build();
1327
1222
  var fileSearch = core.toolBuilder().name("file-search").description("Search for files by name pattern in a directory. Supports wildcards and recursive search.").category(core.ToolCategory.FILE_SYSTEM).tags(["file", "search", "find", "filesystem"]).schema(zod.z.object({
1328
1223
  directory: zod.z.string().describe("Directory to search in"),
1329
1224
  pattern: zod.z.string().describe("File name pattern to search for (supports * wildcard)"),
1330
1225
  recursive: zod.z.boolean().default(true).describe("Search in subdirectories"),
1331
1226
  caseSensitive: zod.z.boolean().default(false).describe("Case-sensitive pattern matching")
1332
- })).implement(async (input) => {
1333
- try {
1334
- const searchFiles = async (dir) => {
1335
- const entries = await fs.promises.readdir(dir, { withFileTypes: true });
1336
- const matches2 = [];
1337
- const regexPattern = input.pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
1338
- const regex = new RegExp(`^${regexPattern}$`, input.caseSensitive ? "" : "i");
1339
- for (const entry of entries) {
1340
- const fullPath = path3__namespace.join(dir, entry.name);
1341
- if (entry.isFile() && regex.test(entry.name)) {
1342
- matches2.push(fullPath);
1343
- }
1344
- if (input.recursive && entry.isDirectory()) {
1345
- const subMatches = await searchFiles(fullPath);
1346
- matches2.push(...subMatches);
1347
- }
1227
+ })).implementSafe(async (input) => {
1228
+ const searchFiles = async (dir) => {
1229
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
1230
+ const matches2 = [];
1231
+ const regexPattern = input.pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
1232
+ const regex = new RegExp(`^${regexPattern}$`, input.caseSensitive ? "" : "i");
1233
+ for (const entry of entries) {
1234
+ const fullPath = path3__namespace.join(dir, entry.name);
1235
+ if (entry.isFile() && regex.test(entry.name)) {
1236
+ matches2.push(fullPath);
1348
1237
  }
1349
- return matches2;
1350
- };
1351
- const matches = await searchFiles(input.directory);
1352
- return {
1353
- success: true,
1354
- directory: input.directory,
1355
- pattern: input.pattern,
1356
- matches,
1357
- count: matches.length
1358
- };
1359
- } catch (error) {
1360
- return {
1361
- success: false,
1362
- error: error instanceof Error ? error.message : "Failed to search files",
1363
- directory: input.directory
1364
- };
1365
- }
1238
+ if (input.recursive && entry.isDirectory()) {
1239
+ const subMatches = await searchFiles(fullPath);
1240
+ matches2.push(...subMatches);
1241
+ }
1242
+ }
1243
+ return matches2;
1244
+ };
1245
+ const matches = await searchFiles(input.directory);
1246
+ return {
1247
+ directory: input.directory,
1248
+ pattern: input.pattern,
1249
+ matches,
1250
+ count: matches.length
1251
+ };
1366
1252
  }).build();
1367
1253
  var pathJoin = core.toolBuilder().name("path-join").description("Join multiple path segments into a single path. Handles platform-specific separators.").category(core.ToolCategory.FILE_SYSTEM).tags(["path", "join", "filesystem"]).schema(zod.z.object({
1368
1254
  segments: zod.z.array(zod.z.string().describe("String value")).describe("Path segments to join")