@agentforge/tools 0.10.0 → 0.10.1

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.js CHANGED
@@ -1,17 +1,17 @@
1
1
  import { toolBuilder, ToolCategory, LogLevel, createLogger } from '@agentforge/core';
2
+ import axios12 from 'axios';
2
3
  import { z } from 'zod';
3
- import axios from 'axios';
4
- import * as cheerio2 from 'cheerio';
4
+ import * as cheerio from 'cheerio';
5
5
  import { WebClient } from '@slack/web-api';
6
6
  import { parse } from 'csv-parse/sync';
7
7
  import { stringify } from 'csv-stringify/sync';
8
8
  import { XMLParser, XMLBuilder } from 'fast-xml-parser';
9
9
  import { promises } from 'fs';
10
- import * as path3 from 'path';
10
+ import * as path7 from 'path';
11
11
  import { format, parse as parse$1, isValid, add, sub, differenceInDays, differenceInHours, differenceInMinutes, isAfter, isBefore } from 'date-fns';
12
12
  import { randomUUID } from 'crypto';
13
13
 
14
- // src/web/http-client.ts
14
+ // src/web/http/tools/http-client.ts
15
15
  var HttpMethod = z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]);
16
16
  var httpRequestSchema = z.object({
17
17
  url: z.string().url().describe("The URL to make the request to"),
@@ -21,54 +21,79 @@ var httpRequestSchema = z.object({
21
21
  timeout: z.number().default(3e4).describe("Request timeout in milliseconds"),
22
22
  params: z.record(z.string()).optional().describe("Optional URL query parameters")
23
23
  });
24
- var httpClient = toolBuilder().name("http-client").description("Make HTTP requests to web APIs and services. Supports GET, POST, PUT, DELETE, PATCH methods with custom headers and body.").category(ToolCategory.WEB).tags(["http", "api", "request", "web"]).schema(httpRequestSchema).implement(async (input) => {
25
- const config = {
26
- method: input.method,
27
- url: input.url,
28
- headers: input.headers,
29
- data: input.body,
30
- timeout: input.timeout,
31
- params: input.params,
32
- validateStatus: () => true
33
- // Don't throw on any status code
34
- };
35
- const response = await axios(config);
36
- return {
37
- status: response.status,
38
- statusText: response.statusText,
39
- headers: response.headers,
40
- data: response.data,
41
- url: input.url,
42
- method: input.method ?? "GET"
43
- };
44
- }).build();
45
- var httpGet = toolBuilder().name("http-get").description("Make a simple HTTP GET request to a URL and return the response data.").category(ToolCategory.WEB).tags(["http", "get", "fetch", "web"]).schema(z.object({
24
+ var httpGetSchema = z.object({
46
25
  url: z.string().url().describe("The URL to fetch"),
47
26
  headers: z.record(z.string()).optional().describe("Optional HTTP headers"),
48
27
  params: z.record(z.string()).optional().describe("Optional URL query parameters")
49
- })).implement(async (input) => {
50
- const response = await axios.get(input.url, {
51
- headers: input.headers,
52
- params: input.params,
53
- timeout: 3e4
54
- });
55
- return response.data;
56
- }).build();
57
- var httpPost = toolBuilder().name("http-post").description("Make a simple HTTP POST request with JSON body and return the response data.").category(ToolCategory.WEB).tags(["http", "post", "api", "web"]).schema(z.object({
28
+ });
29
+ var httpPostSchema = z.object({
58
30
  url: z.string().url().describe("The URL to post to"),
59
31
  body: z.any().describe("The request body (will be sent as JSON)"),
60
32
  headers: z.record(z.string()).optional().describe("Optional HTTP headers")
61
- })).implement(async (input) => {
62
- const response = await axios.post(input.url, input.body, {
63
- headers: {
64
- "Content-Type": "application/json",
65
- ...input.headers
66
- },
67
- timeout: 3e4
68
- });
69
- return response.data;
70
- }).build();
71
- var webScraper = toolBuilder().name("web-scraper").description("Scrape and extract data from web pages. Can extract text, HTML, links, images, and use CSS selectors to target specific elements.").category(ToolCategory.WEB).tags(["scraper", "web", "html", "extract", "parse"]).schema(z.object({
33
+ });
34
+
35
+ // src/web/http/tools/http-client.ts
36
+ function createHttpClientTool(defaultTimeout = 3e4, defaultHeaders = {}) {
37
+ return toolBuilder().name("http-client").description("Make HTTP requests to web APIs and services. Supports GET, POST, PUT, DELETE, PATCH methods with custom headers and body.").category(ToolCategory.WEB).tags(["http", "api", "request", "web"]).schema(httpRequestSchema).implement(async (input) => {
38
+ const config = {
39
+ method: input.method,
40
+ url: input.url,
41
+ headers: { ...defaultHeaders, ...input.headers },
42
+ data: input.body,
43
+ timeout: input.timeout ?? defaultTimeout,
44
+ params: input.params,
45
+ validateStatus: () => true
46
+ // Don't throw on any status code
47
+ };
48
+ const response = await axios12(config);
49
+ return {
50
+ status: response.status,
51
+ statusText: response.statusText,
52
+ headers: response.headers,
53
+ data: response.data,
54
+ url: input.url,
55
+ method: input.method ?? "GET"
56
+ };
57
+ }).build();
58
+ }
59
+ function createHttpGetTool(defaultTimeout = 3e4, defaultHeaders = {}) {
60
+ return toolBuilder().name("http-get").description("Make a simple HTTP GET request to a URL and return the response data.").category(ToolCategory.WEB).tags(["http", "get", "fetch", "web"]).schema(httpGetSchema).implement(async (input) => {
61
+ const response = await axios12.get(input.url, {
62
+ headers: { ...defaultHeaders, ...input.headers },
63
+ params: input.params,
64
+ timeout: defaultTimeout
65
+ });
66
+ return response.data;
67
+ }).build();
68
+ }
69
+ function createHttpPostTool(defaultTimeout = 3e4, defaultHeaders = {}) {
70
+ return toolBuilder().name("http-post").description("Make a simple HTTP POST request with JSON body and return the response data.").category(ToolCategory.WEB).tags(["http", "post", "api", "web"]).schema(httpPostSchema).implement(async (input) => {
71
+ const response = await axios12.post(input.url, input.body, {
72
+ headers: {
73
+ "Content-Type": "application/json",
74
+ ...defaultHeaders,
75
+ ...input.headers
76
+ },
77
+ timeout: defaultTimeout
78
+ });
79
+ return response.data;
80
+ }).build();
81
+ }
82
+
83
+ // src/web/http/index.ts
84
+ var httpClient = createHttpClientTool();
85
+ var httpGet = createHttpGetTool();
86
+ var httpPost = createHttpPostTool();
87
+ var httpTools = [httpClient, httpGet, httpPost];
88
+ function createHttpTools(config = {}) {
89
+ const { defaultTimeout = 3e4, defaultHeaders = {} } = config;
90
+ return [
91
+ createHttpClientTool(defaultTimeout, defaultHeaders),
92
+ createHttpGetTool(defaultTimeout, defaultHeaders),
93
+ createHttpPostTool(defaultTimeout, defaultHeaders)
94
+ ];
95
+ }
96
+ var webScraperSchema = z.object({
72
97
  url: z.string().url().describe("The URL of the web page to scrape"),
73
98
  selector: z.string().optional().describe("Optional CSS selector to extract specific elements"),
74
99
  extractText: z.boolean().default(true).describe("Extract text content from the page"),
@@ -77,240 +102,295 @@ var webScraper = toolBuilder().name("web-scraper").description("Scrape and extra
77
102
  extractImages: z.boolean().default(false).describe("Extract all image URLs from the page"),
78
103
  extractMetadata: z.boolean().default(false).describe("Extract meta tags (title, description, etc.)"),
79
104
  timeout: z.number().default(3e4).describe("Request timeout in milliseconds")
80
- })).implement(async (input) => {
81
- const response = await axios.get(input.url, {
82
- timeout: input.timeout,
83
- headers: {
84
- "User-Agent": "Mozilla/5.0 (compatible; AgentForge/1.0; +https://agentforge.dev)"
85
- }
86
- });
87
- const html = response.data;
88
- const $ = cheerio2.load(html);
89
- const result = {
90
- url: input.url
91
- };
92
- const $selected = input.selector ? $(input.selector) : $("body");
93
- if (input.extractText) {
94
- result.text = $selected.text().trim();
95
- }
96
- if (input.extractHtml) {
97
- result.html = $selected.html() || "";
98
- }
99
- if (input.extractLinks) {
100
- result.links = [];
101
- $("a[href]").each((_, el) => {
102
- const href = $(el).attr("href");
103
- if (href) {
104
- try {
105
- const absoluteUrl = new URL(href, input.url).href;
106
- result.links.push(absoluteUrl);
107
- } catch {
108
- result.links.push(href);
109
- }
105
+ });
106
+ function createWebScraperTool(defaultTimeout = 3e4, userAgent = "Mozilla/5.0 (compatible; AgentForge/1.0; +https://agentforge.dev)") {
107
+ return toolBuilder().name("web-scraper").description("Scrape and extract data from web pages. Can extract text, HTML, links, images, and use CSS selectors to target specific elements.").category(ToolCategory.WEB).tags(["scraper", "web", "html", "extract", "parse"]).schema(webScraperSchema).implement(async (input) => {
108
+ const response = await axios12.get(input.url, {
109
+ timeout: input.timeout || defaultTimeout,
110
+ headers: {
111
+ "User-Agent": userAgent
110
112
  }
111
113
  });
112
- }
113
- if (input.extractImages) {
114
- result.images = [];
115
- $("img[src]").each((_, el) => {
116
- const src = $(el).attr("src");
117
- if (src) {
118
- try {
119
- const absoluteUrl = new URL(src, input.url).href;
120
- result.images.push(absoluteUrl);
121
- } catch {
122
- result.images.push(src);
114
+ const html = response.data;
115
+ const $ = cheerio.load(html);
116
+ const result = {
117
+ url: input.url
118
+ };
119
+ const $selected = input.selector ? $(input.selector) : $("body");
120
+ if (input.extractText) {
121
+ result.text = $selected.text().trim();
122
+ }
123
+ if (input.extractHtml) {
124
+ result.html = $selected.html() || "";
125
+ }
126
+ if (input.extractLinks) {
127
+ result.links = [];
128
+ $("a[href]").each((_, el) => {
129
+ const href = $(el).attr("href");
130
+ if (href) {
131
+ try {
132
+ const absoluteUrl = new URL(href, input.url).href;
133
+ result.links.push(absoluteUrl);
134
+ } catch {
135
+ result.links.push(href);
136
+ }
123
137
  }
124
- }
125
- });
126
- }
127
- if (input.extractMetadata) {
128
- result.metadata = {};
129
- const title = $("title").text() || $('meta[property="og:title"]').attr("content");
130
- if (title) result.metadata.title = title;
131
- const description = $('meta[name="description"]').attr("content") || $('meta[property="og:description"]').attr("content");
132
- if (description) result.metadata.description = description;
133
- $("meta[name], meta[property]").each((_, el) => {
134
- const name = $(el).attr("name") || $(el).attr("property");
135
- const content = $(el).attr("content");
136
- if (name && content) {
137
- result.metadata[name] = content;
138
- }
139
- });
140
- }
141
- if (input.selector) {
142
- result.selected = $selected.map((_, el) => ({
143
- text: $(el).text().trim(),
144
- html: $(el).html()
145
- })).get();
146
- }
147
- return result;
148
- }).build();
149
- var htmlParser = toolBuilder().name("html-parser").description("Parse HTML content and extract data using CSS selectors. Returns text, attributes, and structure of selected elements.").category(ToolCategory.WEB).tags(["html", "parser", "css", "selector", "extract"]).schema(z.object({
138
+ });
139
+ }
140
+ if (input.extractImages) {
141
+ result.images = [];
142
+ $("img[src]").each((_, el) => {
143
+ const src = $(el).attr("src");
144
+ if (src) {
145
+ try {
146
+ const absoluteUrl = new URL(src, input.url).href;
147
+ result.images.push(absoluteUrl);
148
+ } catch {
149
+ result.images.push(src);
150
+ }
151
+ }
152
+ });
153
+ }
154
+ if (input.extractMetadata) {
155
+ result.metadata = {};
156
+ const title = $("title").text() || $('meta[property="og:title"]').attr("content");
157
+ if (title) result.metadata.title = title;
158
+ const description = $('meta[name="description"]').attr("content") || $('meta[property="og:description"]').attr("content");
159
+ if (description) result.metadata.description = description;
160
+ $("meta[name], meta[property]").each((_, el) => {
161
+ const name = $(el).attr("name") || $(el).attr("property");
162
+ const content = $(el).attr("content");
163
+ if (name && content) {
164
+ result.metadata[name] = content;
165
+ }
166
+ });
167
+ }
168
+ if (input.selector) {
169
+ result.selected = $selected.map((_, el) => ({
170
+ text: $(el).text().trim(),
171
+ html: $(el).html()
172
+ })).get();
173
+ }
174
+ return result;
175
+ }).build();
176
+ }
177
+
178
+ // src/web/scraper/index.ts
179
+ var webScraper = createWebScraperTool();
180
+ var scraperTools = [webScraper];
181
+ function createScraperTools(config = {}) {
182
+ const { defaultTimeout = 3e4, userAgent = "Mozilla/5.0 (compatible; AgentForge/1.0; +https://agentforge.dev)" } = config;
183
+ return [createWebScraperTool(defaultTimeout, userAgent)];
184
+ }
185
+ var htmlParserSchema = z.object({
150
186
  html: z.string().describe("The HTML content to parse"),
151
187
  selector: z.string().describe("CSS selector to find elements"),
152
188
  extractText: z.boolean().default(true).describe("Extract text content from selected elements"),
153
189
  extractHtml: z.boolean().default(false).describe("Extract inner HTML of selected elements"),
154
190
  extractAttributes: z.array(z.string().describe("String value")).optional().describe('List of attributes to extract (e.g., ["href", "src", "class"])')
155
- })).implement(async (input) => {
156
- const $ = cheerio2.load(input.html);
157
- const $selected = $(input.selector);
158
- const results = $selected.map((_, el) => {
159
- const $el = $(el);
160
- const item = {};
161
- if (input.extractText) {
162
- item.text = $el.text().trim();
163
- }
164
- if (input.extractHtml) {
165
- item.html = $el.html();
166
- }
167
- if (input.extractAttributes && input.extractAttributes.length > 0) {
168
- item.attributes = {};
169
- for (const attr of input.extractAttributes) {
170
- const value = $el.attr(attr);
171
- if (value !== void 0) {
172
- item.attributes[attr] = value;
173
- }
174
- }
175
- }
176
- return item;
177
- }).get();
178
- return {
179
- count: results.length,
180
- results
181
- };
182
- }).build();
183
- var extractLinks = toolBuilder().name("extract-links").description("Extract all links (anchor tags) from HTML content with their text and href attributes.").category(ToolCategory.WEB).tags(["html", "links", "extract", "anchor"]).schema(z.object({
191
+ });
192
+ var extractLinksSchema = z.object({
184
193
  html: z.string().describe("The HTML content to extract links from"),
185
194
  baseUrl: z.string().url().optional().describe("Optional base URL to resolve relative links")
186
- })).implement(async (input) => {
187
- const $ = cheerio2.load(input.html);
188
- const links = [];
189
- $("a[href]").each((_, el) => {
190
- const $el = $(el);
191
- let href = $el.attr("href") || "";
192
- if (input.baseUrl && href) {
193
- try {
194
- href = new URL(href, input.baseUrl).href;
195
- } catch {
196
- }
197
- }
198
- links.push({
199
- text: $el.text().trim(),
200
- href,
201
- title: $el.attr("title")
202
- });
203
- });
204
- return {
205
- count: links.length,
206
- links
207
- };
208
- }).build();
209
- var extractImages = toolBuilder().name("extract-images").description("Extract all images from HTML content with their src, alt, and other attributes.").category(ToolCategory.WEB).tags(["html", "images", "extract", "img"]).schema(z.object({
195
+ });
196
+ var extractImagesSchema = z.object({
210
197
  html: z.string().describe("The HTML content to extract images from"),
211
198
  baseUrl: z.string().url().optional().describe("Optional base URL to resolve relative image URLs")
212
- })).implement(async (input) => {
213
- const $ = cheerio2.load(input.html);
214
- const images = [];
215
- $("img[src]").each((_, el) => {
216
- const $el = $(el);
217
- let src = $el.attr("src") || "";
218
- if (input.baseUrl && src) {
219
- try {
220
- src = new URL(src, input.baseUrl).href;
221
- } catch {
199
+ });
200
+ function createHtmlParserTool() {
201
+ return toolBuilder().name("html-parser").description("Parse HTML content and extract data using CSS selectors. Returns text, attributes, and structure of selected elements.").category(ToolCategory.WEB).tags(["html", "parser", "css", "selector", "extract"]).schema(htmlParserSchema).implement(async (input) => {
202
+ const $ = cheerio.load(input.html);
203
+ const $selected = $(input.selector);
204
+ const results = $selected.map((_, el) => {
205
+ const $el = $(el);
206
+ const item = {};
207
+ if (input.extractText) {
208
+ item.text = $el.text().trim();
222
209
  }
223
- }
224
- images.push({
225
- src,
226
- alt: $el.attr("alt"),
227
- title: $el.attr("title"),
228
- width: $el.attr("width"),
229
- height: $el.attr("height")
210
+ if (input.extractHtml) {
211
+ item.html = $el.html();
212
+ }
213
+ if (input.extractAttributes && input.extractAttributes.length > 0) {
214
+ item.attributes = {};
215
+ for (const attr of input.extractAttributes) {
216
+ const value = $el.attr(attr);
217
+ if (value !== void 0) {
218
+ item.attributes[attr] = value;
219
+ }
220
+ }
221
+ }
222
+ return item;
223
+ }).get();
224
+ return {
225
+ count: results.length,
226
+ results
227
+ };
228
+ }).build();
229
+ }
230
+ function createExtractLinksTool() {
231
+ return toolBuilder().name("extract-links").description("Extract all links (anchor tags) from HTML content with their text and href attributes.").category(ToolCategory.WEB).tags(["html", "links", "extract", "anchor"]).schema(extractLinksSchema).implement(async (input) => {
232
+ const $ = cheerio.load(input.html);
233
+ const links = [];
234
+ $("a[href]").each((_, el) => {
235
+ const $el = $(el);
236
+ let href = $el.attr("href") || "";
237
+ if (input.baseUrl && href) {
238
+ try {
239
+ href = new URL(href, input.baseUrl).href;
240
+ } catch {
241
+ }
242
+ }
243
+ links.push({
244
+ text: $el.text().trim(),
245
+ href,
246
+ title: $el.attr("title")
247
+ });
230
248
  });
231
- });
232
- return {
233
- count: images.length,
234
- images
235
- };
236
- }).build();
237
- var urlValidator = 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(ToolCategory.WEB).tags(["url", "validator", "parse", "validate"]).schema(z.object({
249
+ return {
250
+ count: links.length,
251
+ links
252
+ };
253
+ }).build();
254
+ }
255
+ function createExtractImagesTool() {
256
+ return toolBuilder().name("extract-images").description("Extract all images from HTML content with their src, alt, and other attributes.").category(ToolCategory.WEB).tags(["html", "images", "extract", "img"]).schema(extractImagesSchema).implement(async (input) => {
257
+ const $ = cheerio.load(input.html);
258
+ const images = [];
259
+ $("img[src]").each((_, el) => {
260
+ const $el = $(el);
261
+ let src = $el.attr("src") || "";
262
+ if (input.baseUrl && src) {
263
+ try {
264
+ src = new URL(src, input.baseUrl).href;
265
+ } catch {
266
+ }
267
+ }
268
+ images.push({
269
+ src,
270
+ alt: $el.attr("alt"),
271
+ title: $el.attr("title"),
272
+ width: $el.attr("width"),
273
+ height: $el.attr("height")
274
+ });
275
+ });
276
+ return {
277
+ count: images.length,
278
+ images
279
+ };
280
+ }).build();
281
+ }
282
+
283
+ // src/web/html-parser/index.ts
284
+ var htmlParser = createHtmlParserTool();
285
+ var extractLinks = createExtractLinksTool();
286
+ var extractImages = createExtractImagesTool();
287
+ var htmlParserTools = [htmlParser, extractLinks, extractImages];
288
+ function createHtmlParserTools(config = {}) {
289
+ return [
290
+ createHtmlParserTool(),
291
+ createExtractLinksTool(),
292
+ createExtractImagesTool()
293
+ ];
294
+ }
295
+ var urlValidatorSchema = z.object({
238
296
  url: z.string().describe("The URL to validate and parse")
239
- })).implementSafe(async (input) => {
240
- const parsed = new URL(input.url);
241
- return {
242
- url: parsed.href,
243
- protocol: parsed.protocol,
244
- hostname: parsed.hostname,
245
- port: parsed.port,
246
- pathname: parsed.pathname,
247
- search: parsed.search,
248
- hash: parsed.hash,
249
- origin: parsed.origin
250
- };
251
- }).build();
252
- var urlBuilder = toolBuilder().name("url-builder").description("Build a URL from components (protocol, hostname, path, query parameters, hash).").category(ToolCategory.WEB).tags(["url", "builder", "construct"]).schema(z.object({
297
+ });
298
+ var urlBuilderSchema = z.object({
253
299
  protocol: z.string().default("https").describe("Protocol (http, https, etc.)"),
254
300
  hostname: z.string().describe("Hostname or domain name"),
255
301
  port: z.string().optional().describe("Optional port number"),
256
302
  pathname: z.string().default("/").describe("URL path"),
257
303
  query: z.record(z.string()).optional().describe("Query parameters as key-value pairs"),
258
304
  hash: z.string().optional().describe("URL hash/fragment")
259
- })).implement(async (input) => {
260
- const url = new URL(`${input.protocol}://${input.hostname}`);
261
- if (input.port) {
262
- url.port = input.port;
263
- }
264
- url.pathname = input.pathname ?? "/";
265
- if (input.query) {
266
- Object.entries(input.query).forEach(([key, value]) => {
267
- url.searchParams.append(key, value);
268
- });
269
- }
270
- if (input.hash) {
271
- url.hash = input.hash;
272
- }
273
- return {
274
- url: url.href,
275
- components: {
276
- protocol: url.protocol,
277
- hostname: url.hostname,
278
- port: url.port,
279
- pathname: url.pathname,
280
- search: url.search,
281
- hash: url.hash,
282
- origin: url.origin
283
- }
284
- };
285
- }).build();
286
- var urlQueryParser = toolBuilder().name("url-query-parser").description("Parse query parameters from a URL or query string into a key-value object.").category(ToolCategory.WEB).tags(["url", "query", "parse", "params"]).schema(z.object({
305
+ });
306
+ var urlQueryParserSchema = z.object({
287
307
  input: z.string().describe('URL or query string to parse (e.g., "?foo=bar&baz=qux" or full URL)')
288
- })).implement(async (input) => {
289
- let searchParams;
290
- try {
291
- const url = new URL(input.input);
292
- searchParams = url.searchParams;
293
- } catch {
294
- const queryString = input.input.startsWith("?") ? input.input.slice(1) : input.input;
295
- searchParams = new URLSearchParams(queryString);
296
- }
297
- const params = {};
298
- searchParams.forEach((value, key) => {
299
- if (params[key]) {
300
- if (Array.isArray(params[key])) {
301
- params[key].push(value);
302
- } else {
303
- params[key] = [params[key], value];
308
+ });
309
+ function createUrlValidatorTool() {
310
+ return 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(ToolCategory.WEB).tags(["url", "validator", "parse", "validate"]).schema(urlValidatorSchema).implementSafe(async (input) => {
311
+ const parsed = new URL(input.url);
312
+ return {
313
+ url: parsed.href,
314
+ protocol: parsed.protocol,
315
+ hostname: parsed.hostname,
316
+ port: parsed.port,
317
+ pathname: parsed.pathname,
318
+ search: parsed.search,
319
+ hash: parsed.hash,
320
+ origin: parsed.origin
321
+ };
322
+ }).build();
323
+ }
324
+ function createUrlBuilderTool() {
325
+ return toolBuilder().name("url-builder").description("Build a URL from components (protocol, hostname, path, query parameters, hash).").category(ToolCategory.WEB).tags(["url", "builder", "construct"]).schema(urlBuilderSchema).implement(async (input) => {
326
+ const url = new URL(`${input.protocol}://${input.hostname}`);
327
+ if (input.port) {
328
+ url.port = input.port;
329
+ }
330
+ url.pathname = input.pathname ?? "/";
331
+ if (input.query) {
332
+ Object.entries(input.query).forEach(([key, value]) => {
333
+ url.searchParams.append(key, value);
334
+ });
335
+ }
336
+ if (input.hash) {
337
+ url.hash = input.hash;
338
+ }
339
+ return {
340
+ url: url.href,
341
+ components: {
342
+ protocol: url.protocol,
343
+ hostname: url.hostname,
344
+ port: url.port,
345
+ pathname: url.pathname,
346
+ search: url.search,
347
+ hash: url.hash,
348
+ origin: url.origin
304
349
  }
305
- } else {
306
- params[key] = value;
350
+ };
351
+ }).build();
352
+ }
353
+ function createUrlQueryParserTool() {
354
+ return toolBuilder().name("url-query-parser").description("Parse query parameters from a URL or query string into a key-value object.").category(ToolCategory.WEB).tags(["url", "query", "parse", "params"]).schema(urlQueryParserSchema).implement(async (input) => {
355
+ let searchParams;
356
+ try {
357
+ const url = new URL(input.input);
358
+ searchParams = url.searchParams;
359
+ } catch {
360
+ const queryString = input.input.startsWith("?") ? input.input.slice(1) : input.input;
361
+ searchParams = new URLSearchParams(queryString);
307
362
  }
308
- });
309
- return {
310
- params,
311
- count: Object.keys(params).length
312
- };
313
- }).build();
363
+ const params = {};
364
+ searchParams.forEach((value, key) => {
365
+ if (params[key]) {
366
+ if (Array.isArray(params[key])) {
367
+ params[key].push(value);
368
+ } else {
369
+ params[key] = [params[key], value];
370
+ }
371
+ } else {
372
+ params[key] = value;
373
+ }
374
+ });
375
+ return {
376
+ params,
377
+ count: Object.keys(params).length
378
+ };
379
+ }).build();
380
+ }
381
+
382
+ // src/web/url-validator/index.ts
383
+ var urlValidator = createUrlValidatorTool();
384
+ var urlBuilder = createUrlBuilderTool();
385
+ var urlQueryParser = createUrlQueryParserTool();
386
+ var urlValidatorTools = [urlValidator, urlBuilder, urlQueryParser];
387
+ function createUrlValidatorTools(config = {}) {
388
+ return [
389
+ createUrlValidatorTool(),
390
+ createUrlBuilderTool(),
391
+ createUrlQueryParserTool()
392
+ ];
393
+ }
314
394
  var webSearchSchema = z.object({
315
395
  query: z.string().min(1).describe("The search query"),
316
396
  maxResults: z.number().min(1).max(50).default(10).describe("Maximum number of results to return (1-50)"),
@@ -415,7 +495,7 @@ var DuckDuckGoProvider = class {
415
495
  async search(query, maxResults, timeout = DEFAULT_TIMEOUT) {
416
496
  return retryWithBackoff(async () => {
417
497
  try {
418
- const response = await axios.get(
498
+ const response = await axios12.get(
419
499
  "https://api.duckduckgo.com/",
420
500
  {
421
501
  params: {
@@ -519,7 +599,7 @@ var SerperProvider = class {
519
599
  }
520
600
  return retryWithBackoff(async () => {
521
601
  try {
522
- const response = await axios.post(
602
+ const response = await axios12.post(
523
603
  "https://google.serper.dev/search",
524
604
  {
525
605
  q: query,
@@ -657,8 +737,28 @@ var webSearch = toolBuilder().name("web-search").description(
657
737
  };
658
738
  }
659
739
  }).build();
660
- var logLevel = process.env.LOG_LEVEL?.toLowerCase() || LogLevel.INFO;
661
- var logger = createLogger("tools:slack", { level: logLevel });
740
+ function createGetConfiguredSlackClient(token, botName = "AgentForge Bot", botIcon = ":robot_face:") {
741
+ let configuredClient = null;
742
+ return function getConfiguredSlackClient() {
743
+ if (!configuredClient) {
744
+ const slackToken = token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN;
745
+ if (!slackToken) {
746
+ throw new Error(
747
+ "Slack token not configured. Please provide a token in config or set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
748
+ );
749
+ }
750
+ configuredClient = new WebClient(slackToken);
751
+ }
752
+ return {
753
+ client: configuredClient,
754
+ config: {
755
+ token: token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN || "",
756
+ botName,
757
+ botIcon
758
+ }
759
+ };
760
+ };
761
+ }
662
762
  var defaultSlackClient = null;
663
763
  function getDefaultSlackClient() {
664
764
  if (!defaultSlackClient) {
@@ -670,196 +770,17 @@ function getDefaultSlackClient() {
670
770
  }
671
771
  defaultSlackClient = new WebClient(token);
672
772
  }
673
- return defaultSlackClient;
674
- }
675
- var sendSlackMessage = toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
676
- "Use this for general team communication. For notifications with @mentions, consider using notify-slack instead. Use get-slack-channels first if you need to find the right channel."
677
- ).suggests(["get-slack-channels"]).schema(
678
- z.object({
679
- channel: z.string().describe("Channel name (e.g., 'general') or ID (e.g., 'C123456')"),
680
- message: z.string().describe("Message content to send")
681
- })
682
- ).implementSafe(async ({ channel, message }) => {
683
- logger.info("send-slack-message called", { channel, messageLength: message.length });
684
- try {
685
- const slack = getDefaultSlackClient();
686
- const result = await slack.chat.postMessage({
687
- channel,
688
- text: message,
689
- username: "AgentForge Bot",
690
- icon_emoji: ":robot_face:"
691
- });
692
- logger.info("send-slack-message result", {
693
- channel: result.channel,
694
- timestamp: result.ts,
695
- messageLength: message.length,
696
- success: true
697
- });
698
- return {
699
- channel: result.channel,
700
- message,
701
- timestamp: result.ts,
702
- message_id: result.ts
703
- };
704
- } catch (error) {
705
- logger.error("send-slack-message failed", {
706
- channel,
707
- error: error.message,
708
- data: error.data
709
- });
710
- throw error;
711
- }
712
- }).build();
713
- var notifySlack = toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
714
- "Use this for urgent notifications that require @mentions. For general messages without mentions, use send-slack-message instead."
715
- ).suggests(["get-slack-channels"]).schema(
716
- z.object({
717
- channel: z.string().describe("Channel name or ID"),
718
- message: z.string().describe("Notification message"),
719
- mentions: z.array(z.string()).optional().describe("List of usernames to mention (without @)")
720
- })
721
- ).implementSafe(async ({ channel, message, mentions = [] }) => {
722
- logger.info("notify-slack called", {
723
- channel,
724
- messageLength: message.length,
725
- mentionCount: mentions.length
726
- });
727
- const slack = getDefaultSlackClient();
728
- const mentionText = mentions.length > 0 ? mentions.map((m) => `<@${m}>`).join(" ") + " " : "";
729
- const fullMessage = `${mentionText}${message}`;
730
- const result = await slack.chat.postMessage({
731
- channel,
732
- text: fullMessage,
733
- username: "AgentForge Bot",
734
- icon_emoji: ":robot_face:"
735
- });
736
- logger.info("notify-slack result", {
737
- channel: result.channel,
738
- timestamp: result.ts,
739
- mentions: mentions.length
740
- });
741
- return {
742
- channel: result.channel,
743
- message: fullMessage,
744
- mentions,
745
- timestamp: result.ts,
746
- notification_id: result.ts
747
- };
748
- }).build();
749
- var getSlackChannels = toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
750
- "Use this first to discover available channels before sending messages. Helps ensure you are sending to the correct channel."
751
- ).follows(["send-slack-message", "notify-slack"]).schema(
752
- z.object({
753
- include_private: z.boolean().optional().describe("Include private channels (default: false)")
754
- })
755
- ).implementSafe(async ({ include_private = false }) => {
756
- logger.info("get-slack-channels called", { include_private });
757
- const slack = getDefaultSlackClient();
758
- const publicChannels = await slack.conversations.list({
759
- types: "public_channel",
760
- exclude_archived: true
761
- });
762
- let allChannels = publicChannels.channels || [];
763
- if (include_private) {
764
- const privateChannels = await slack.conversations.list({
765
- types: "private_channel",
766
- exclude_archived: true
767
- });
768
- allChannels = [...allChannels, ...privateChannels.channels || []];
769
- }
770
- logger.info("get-slack-channels result", {
771
- channelCount: allChannels.length,
772
- includePrivate: include_private
773
- });
774
773
  return {
775
- count: allChannels.length,
776
- channels: allChannels.map((c) => ({
777
- id: c.id,
778
- name: c.name,
779
- is_private: c.is_private || false,
780
- num_members: c.num_members || 0
781
- }))
782
- };
783
- }).build();
784
- var getSlackMessages = toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
785
- "Use this to read recent messages from a channel. Use get-slack-channels first if you need to find the channel ID. Returns messages in reverse chronological order (newest first)."
786
- ).suggests(["get-slack-channels"]).schema(
787
- z.object({
788
- channel: z.string().describe("Channel name (e.g., 'general') or ID (e.g., 'C123456')"),
789
- limit: z.number().int().min(1).max(100).optional().describe("Number of messages to retrieve (default: 20, max: 100)")
790
- })
791
- ).implementSafe(async ({ channel, limit = 20 }) => {
792
- logger.info("get-slack-messages called", { channel, limit });
793
- try {
794
- const slack = getDefaultSlackClient();
795
- let channelId = channel;
796
- if (!channel.startsWith("C") && !channel.startsWith("D")) {
797
- const channels = await slack.conversations.list({
798
- types: "public_channel,private_channel",
799
- exclude_archived: true
800
- });
801
- const found = channels.channels?.find((c) => c.name === channel);
802
- if (!found) {
803
- logger.error("get-slack-messages: channel not found", { channel });
804
- throw new Error(
805
- `Channel '${channel}' not found. Use get-slack-channels to see available channels.`
806
- );
807
- }
808
- channelId = found.id;
809
- }
810
- const result = await slack.conversations.history({
811
- channel: channelId,
812
- limit: Math.min(limit, 100)
813
- // Cap at 100 for performance
814
- });
815
- logger.info("get-slack-messages result", {
816
- channel: channelId,
817
- messageCount: result.messages?.length || 0,
818
- limit
819
- });
820
- return {
821
- channel: channelId,
822
- count: result.messages?.length || 0,
823
- messages: result.messages?.map((m) => ({
824
- user: m.user || "unknown",
825
- text: m.text || "",
826
- timestamp: m.ts,
827
- thread_ts: m.thread_ts,
828
- type: m.type,
829
- subtype: m.subtype
830
- })) || []
831
- };
832
- } catch (error) {
833
- logger.error("get-slack-messages failed", {
834
- channel,
835
- error: error.message,
836
- data: error.data
837
- });
838
- throw error;
839
- }
840
- }).build();
841
- function createSlackTools(config = {}) {
842
- const {
843
- token,
844
- botName = "AgentForge Bot",
845
- botIcon = ":robot_face:",
846
- logLevel: customLogLevel
847
- } = config;
848
- let configuredClient = null;
849
- function getConfiguredSlackClient() {
850
- if (!configuredClient) {
851
- const slackToken = token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN;
852
- if (!slackToken) {
853
- throw new Error(
854
- "Slack token not configured. Please provide a token in config or set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
855
- );
856
- }
857
- configuredClient = new WebClient(slackToken);
774
+ client: defaultSlackClient,
775
+ config: {
776
+ token: process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN || "",
777
+ botName: "AgentForge Bot",
778
+ botIcon: ":robot_face:"
858
779
  }
859
- return configuredClient;
860
- }
861
- const toolLogger = customLogLevel ? createLogger("tools:slack", { level: customLogLevel }) : logger;
862
- const sendMessage = toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
780
+ };
781
+ }
782
+ function createSendSlackMessageTool(getSlackClient, logger4) {
783
+ return toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
863
784
  "Use this for general team communication. For notifications with @mentions, consider using notify-slack instead. Use get-slack-channels first if you need to find the right channel."
864
785
  ).suggests(["get-slack-channels"]).schema(
865
786
  z.object({
@@ -867,16 +788,16 @@ function createSlackTools(config = {}) {
867
788
  message: z.string().describe("Message content to send")
868
789
  })
869
790
  ).implementSafe(async ({ channel, message }) => {
870
- toolLogger.info("send-slack-message called", { channel, messageLength: message.length });
791
+ logger4.info("send-slack-message called", { channel, messageLength: message.length });
871
792
  try {
872
- const slack = getConfiguredSlackClient();
793
+ const { client: slack, config } = getSlackClient();
873
794
  const result = await slack.chat.postMessage({
874
795
  channel,
875
796
  text: message,
876
- username: botName,
877
- icon_emoji: botIcon
797
+ username: config.botName,
798
+ icon_emoji: config.botIcon
878
799
  });
879
- toolLogger.info("send-slack-message result", {
800
+ logger4.info("send-slack-message result", {
880
801
  channel: result.channel,
881
802
  timestamp: result.ts,
882
803
  messageLength: message.length,
@@ -889,7 +810,7 @@ function createSlackTools(config = {}) {
889
810
  message_id: result.ts
890
811
  };
891
812
  } catch (error) {
892
- toolLogger.error("send-slack-message failed", {
813
+ logger4.error("send-slack-message failed", {
893
814
  channel,
894
815
  error: error.message,
895
816
  data: error.data
@@ -897,7 +818,9 @@ function createSlackTools(config = {}) {
897
818
  throw error;
898
819
  }
899
820
  }).build();
900
- const notify = toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
821
+ }
822
+ function createNotifySlackTool(getSlackClient, logger4) {
823
+ return toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
901
824
  "Use this for urgent notifications that require @mentions. For general messages without mentions, use send-slack-message instead."
902
825
  ).suggests(["get-slack-channels"]).schema(
903
826
  z.object({
@@ -906,21 +829,21 @@ function createSlackTools(config = {}) {
906
829
  mentions: z.array(z.string()).optional().describe("List of usernames to mention (without @)")
907
830
  })
908
831
  ).implementSafe(async ({ channel, message, mentions = [] }) => {
909
- toolLogger.info("notify-slack called", {
832
+ logger4.info("notify-slack called", {
910
833
  channel,
911
834
  messageLength: message.length,
912
835
  mentionCount: mentions.length
913
836
  });
914
- const slack = getConfiguredSlackClient();
837
+ const { client: slack, config } = getSlackClient();
915
838
  const mentionText = mentions.length > 0 ? mentions.map((m) => `<@${m}>`).join(" ") + " " : "";
916
839
  const fullMessage = `${mentionText}${message}`;
917
840
  const result = await slack.chat.postMessage({
918
841
  channel,
919
842
  text: fullMessage,
920
- username: botName,
921
- icon_emoji: botIcon
843
+ username: config.botName,
844
+ icon_emoji: config.botIcon
922
845
  });
923
- toolLogger.info("notify-slack result", {
846
+ logger4.info("notify-slack result", {
924
847
  channel: result.channel,
925
848
  timestamp: result.ts,
926
849
  mentions: mentions.length
@@ -933,15 +856,17 @@ function createSlackTools(config = {}) {
933
856
  notification_id: result.ts
934
857
  };
935
858
  }).build();
936
- const getChannels = toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
859
+ }
860
+ function createGetSlackChannelsTool(getSlackClient, logger4) {
861
+ return toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
937
862
  "Use this first to discover available channels before sending messages. Helps ensure you are sending to the correct channel."
938
863
  ).follows(["send-slack-message", "notify-slack"]).schema(
939
864
  z.object({
940
865
  include_private: z.boolean().optional().describe("Include private channels (default: false)")
941
866
  })
942
867
  ).implementSafe(async ({ include_private = false }) => {
943
- toolLogger.info("get-slack-channels called", { include_private });
944
- const slack = getConfiguredSlackClient();
868
+ logger4.info("get-slack-channels called", { include_private });
869
+ const { client: slack } = getSlackClient();
945
870
  const publicChannels = await slack.conversations.list({
946
871
  types: "public_channel",
947
872
  exclude_archived: true
@@ -954,7 +879,7 @@ function createSlackTools(config = {}) {
954
879
  });
955
880
  allChannels = [...allChannels, ...privateChannels.channels || []];
956
881
  }
957
- toolLogger.info("get-slack-channels result", {
882
+ logger4.info("get-slack-channels result", {
958
883
  channelCount: allChannels.length,
959
884
  includePrivate: include_private
960
885
  });
@@ -968,7 +893,9 @@ function createSlackTools(config = {}) {
968
893
  }))
969
894
  };
970
895
  }).build();
971
- const getMessages = toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
896
+ }
897
+ function createGetSlackMessagesTool(getSlackClient, logger4) {
898
+ return toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
972
899
  "Use this to read recent messages from a channel. Use get-slack-channels first if you need to find the channel ID. Returns messages in reverse chronological order (newest first)."
973
900
  ).suggests(["get-slack-channels"]).schema(
974
901
  z.object({
@@ -976,9 +903,9 @@ function createSlackTools(config = {}) {
976
903
  limit: z.number().int().min(1).max(100).optional().describe("Number of messages to retrieve (default: 20, max: 100)")
977
904
  })
978
905
  ).implementSafe(async ({ channel, limit = 20 }) => {
979
- toolLogger.info("get-slack-messages called", { channel, limit });
906
+ logger4.info("get-slack-messages called", { channel, limit });
980
907
  try {
981
- const slack = getConfiguredSlackClient();
908
+ const { client: slack } = getSlackClient();
982
909
  let channelId = channel;
983
910
  if (!channel.startsWith("C") && !channel.startsWith("D")) {
984
911
  const channels = await slack.conversations.list({
@@ -987,7 +914,7 @@ function createSlackTools(config = {}) {
987
914
  });
988
915
  const found = channels.channels?.find((c) => c.name === channel);
989
916
  if (!found) {
990
- toolLogger.error("get-slack-messages: channel not found", { channel });
917
+ logger4.error("get-slack-messages: channel not found", { channel });
991
918
  throw new Error(
992
919
  `Channel '${channel}' not found. Use get-slack-channels to see available channels.`
993
920
  );
@@ -997,8 +924,9 @@ function createSlackTools(config = {}) {
997
924
  const result = await slack.conversations.history({
998
925
  channel: channelId,
999
926
  limit: Math.min(limit, 100)
927
+ // Cap at 100 for performance
1000
928
  });
1001
- toolLogger.info("get-slack-messages result", {
929
+ logger4.info("get-slack-messages result", {
1002
930
  channel: channelId,
1003
931
  messageCount: result.messages?.length || 0,
1004
932
  limit
@@ -1016,7 +944,7 @@ function createSlackTools(config = {}) {
1016
944
  })) || []
1017
945
  };
1018
946
  } catch (error) {
1019
- toolLogger.error("get-slack-messages failed", {
947
+ logger4.error("get-slack-messages failed", {
1020
948
  channel,
1021
949
  error: error.message,
1022
950
  data: error.data
@@ -1024,21 +952,50 @@ function createSlackTools(config = {}) {
1024
952
  throw error;
1025
953
  }
1026
954
  }).build();
1027
- return {
1028
- sendMessage,
1029
- notify,
1030
- getChannels,
1031
- getMessages
1032
- };
1033
955
  }
1034
- var slackTools = [sendSlackMessage, notifySlack, getSlackChannels, getSlackMessages];
1035
956
 
1036
- // src/web/confluence/auth.ts
1037
- function createGetConfiguredAuth(apiKey, email, siteUrl) {
1038
- return function getConfiguredAuth() {
1039
- const ATLASSIAN_API_KEY = apiKey || process.env.ATLASSIAN_API_KEY || "";
1040
- const ATLASSIAN_EMAIL = email || process.env.ATLASSIAN_EMAIL || "";
1041
- const ATLASSIAN_SITE_URL = (siteUrl || process.env.ATLASSIAN_SITE_URL || "").replace(/\/$/, "");
957
+ // src/web/slack/index.ts
958
+ var logLevel = process.env.LOG_LEVEL?.toLowerCase() || LogLevel.INFO;
959
+ var logger = createLogger("[tools:slack]", { level: logLevel });
960
+ var sendSlackMessage = createSendSlackMessageTool(getDefaultSlackClient, logger);
961
+ var notifySlack = createNotifySlackTool(getDefaultSlackClient, logger);
962
+ var getSlackChannels = createGetSlackChannelsTool(getDefaultSlackClient, logger);
963
+ var getSlackMessages = createGetSlackMessagesTool(getDefaultSlackClient, logger);
964
+ var slackTools = [
965
+ // Write tools
966
+ sendSlackMessage,
967
+ notifySlack,
968
+ // Read tools
969
+ getSlackChannels,
970
+ getSlackMessages
971
+ ];
972
+ function createSlackTools(config = {}) {
973
+ const {
974
+ token,
975
+ botName = "AgentForge Bot",
976
+ botIcon = ":robot_face:",
977
+ logLevel: customLogLevel
978
+ } = config;
979
+ const getConfiguredSlackClient = createGetConfiguredSlackClient(token, botName, botIcon);
980
+ const toolLogger = customLogLevel ? createLogger("[tools:slack]", { level: customLogLevel }) : logger;
981
+ const sendMessage = createSendSlackMessageTool(getConfiguredSlackClient, toolLogger);
982
+ const notify = createNotifySlackTool(getConfiguredSlackClient, toolLogger);
983
+ const getChannels = createGetSlackChannelsTool(getConfiguredSlackClient, toolLogger);
984
+ const getMessages = createGetSlackMessagesTool(getConfiguredSlackClient, toolLogger);
985
+ return {
986
+ sendMessage,
987
+ notify,
988
+ getChannels,
989
+ getMessages
990
+ };
991
+ }
992
+
993
+ // src/web/confluence/auth.ts
994
+ function createGetConfiguredAuth(apiKey, email, siteUrl) {
995
+ return function getConfiguredAuth() {
996
+ const ATLASSIAN_API_KEY = apiKey || process.env.ATLASSIAN_API_KEY || "";
997
+ const ATLASSIAN_EMAIL = email || process.env.ATLASSIAN_EMAIL || "";
998
+ const ATLASSIAN_SITE_URL = (siteUrl || process.env.ATLASSIAN_SITE_URL || "").replace(/\/$/, "");
1042
999
  if (!ATLASSIAN_API_KEY || !ATLASSIAN_EMAIL || !ATLASSIAN_SITE_URL) {
1043
1000
  throw new Error(
1044
1001
  "Confluence credentials not configured. Set ATLASSIAN_API_KEY, ATLASSIAN_EMAIL, and ATLASSIAN_SITE_URL in config or environment variables."
@@ -1076,7 +1033,7 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger4) {
1076
1033
  logger4.info("search-confluence called", { query, limit });
1077
1034
  try {
1078
1035
  const { ATLASSIAN_SITE_URL } = getAuth();
1079
- const response = await axios.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/search`, {
1036
+ const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/search`, {
1080
1037
  headers: {
1081
1038
  Authorization: getAuthHeader2(),
1082
1039
  Accept: "application/json"
@@ -1138,7 +1095,7 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger4) {
1138
1095
  logger4.info("get-confluence-page called", { page_id });
1139
1096
  try {
1140
1097
  const { ATLASSIAN_SITE_URL } = getAuth();
1141
- const response = await axios.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`, {
1098
+ const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`, {
1142
1099
  headers: {
1143
1100
  Authorization: getAuthHeader2(),
1144
1101
  Accept: "application/json"
@@ -1189,7 +1146,7 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger4) {
1189
1146
  logger4.info("list-confluence-spaces called", { limit });
1190
1147
  try {
1191
1148
  const { ATLASSIAN_SITE_URL } = getAuth();
1192
- const response = await axios.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/space`, {
1149
+ const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/space`, {
1193
1150
  headers: {
1194
1151
  Authorization: getAuthHeader2(),
1195
1152
  Accept: "application/json"
@@ -1235,7 +1192,7 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger4) {
1235
1192
  logger4.info("get-space-pages called", { space_key, limit });
1236
1193
  try {
1237
1194
  const { ATLASSIAN_SITE_URL } = getAuth();
1238
- const response = await axios.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`, {
1195
+ const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`, {
1239
1196
  headers: {
1240
1197
  Authorization: getAuthHeader2(),
1241
1198
  Accept: "application/json"
@@ -1309,7 +1266,7 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
1309
1266
  if (parent_page_id) {
1310
1267
  pageData.ancestors = [{ id: parent_page_id }];
1311
1268
  }
1312
- const response = await axios.post(
1269
+ const response = await axios12.post(
1313
1270
  `${ATLASSIAN_SITE_URL}/wiki/rest/api/content`,
1314
1271
  pageData,
1315
1272
  {
@@ -1357,7 +1314,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
1357
1314
  logger4.info("update-confluence-page called", { page_id, title });
1358
1315
  try {
1359
1316
  const { ATLASSIAN_SITE_URL } = getAuth();
1360
- const getResponse = await axios.get(
1317
+ const getResponse = await axios12.get(
1361
1318
  `${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
1362
1319
  {
1363
1320
  headers: {
@@ -1367,7 +1324,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
1367
1324
  }
1368
1325
  );
1369
1326
  const currentVersion = getResponse.data.version.number;
1370
- const updateResponse = await axios.put(
1327
+ const updateResponse = await axios12.put(
1371
1328
  `${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
1372
1329
  {
1373
1330
  type: "page",
@@ -1425,7 +1382,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger4) {
1425
1382
  logger4.info("archive-confluence-page called", { page_id, reason });
1426
1383
  try {
1427
1384
  const { ATLASSIAN_SITE_URL } = getAuth();
1428
- const getResponse = await axios.get(
1385
+ const getResponse = await axios12.get(
1429
1386
  `${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
1430
1387
  {
1431
1388
  headers: {
@@ -1436,7 +1393,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger4) {
1436
1393
  );
1437
1394
  const currentVersion = getResponse.data.version.number;
1438
1395
  const pageData = getResponse.data;
1439
- await axios.put(
1396
+ await axios12.put(
1440
1397
  `${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
1441
1398
  {
1442
1399
  version: { number: currentVersion + 1 },
@@ -1532,1204 +1489,1664 @@ function createConfluenceTools(config = {}) {
1532
1489
  archiveConfluencePage: archiveConfluencePage2
1533
1490
  };
1534
1491
  }
1535
- var jsonParser = toolBuilder().name("json-parser").description("Parse JSON string into an object. Validates JSON syntax and returns parsed data or error details.").category(ToolCategory.UTILITY).tags(["json", "parse", "data"]).schema(z.object({
1536
- json: z.string().describe("JSON string to parse"),
1537
- strict: z.boolean().default(true).describe("Use strict JSON parsing (no trailing commas, etc.)")
1538
- })).implementSafe(async (input) => {
1539
- const parsed = JSON.parse(input.json);
1540
- return {
1541
- data: parsed,
1542
- type: Array.isArray(parsed) ? "array" : typeof parsed
1543
- };
1544
- }).build();
1545
- var jsonStringify = toolBuilder().name("json-stringify").description("Convert an object to a JSON string with optional formatting (pretty print).").category(ToolCategory.UTILITY).tags(["json", "stringify", "format", "data"]).schema(z.object({
1546
- data: z.any().describe("Data to convert to JSON string"),
1547
- pretty: z.boolean().default(false).describe("Format with indentation for readability"),
1548
- indent: z.number().default(2).describe("Number of spaces for indentation (when pretty is true)")
1549
- })).implementSafe(async (input) => {
1550
- const json = input.pretty ? JSON.stringify(input.data, null, input.indent) : JSON.stringify(input.data);
1551
- return {
1552
- json,
1553
- length: json.length
1554
- };
1555
- }).build();
1556
- var jsonQuery = toolBuilder().name("json-query").description('Query JSON data using dot notation path (e.g., "user.address.city"). Supports array indexing.').category(ToolCategory.UTILITY).tags(["json", "query", "path", "data"]).schema(z.object({
1557
- data: z.any().describe("JSON data to query"),
1558
- path: z.string().describe('Dot notation path to query (e.g., "user.name" or "items[0].id")')
1559
- })).implementSafe(async (input) => {
1560
- const parts = input.path.split(".");
1561
- let current = input.data;
1562
- for (const part of parts) {
1563
- const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
1564
- if (arrayMatch) {
1565
- const [, key, index] = arrayMatch;
1566
- current = current[key][parseInt(index, 10)];
1567
- } else {
1568
- current = current[part];
1569
- }
1570
- if (current === void 0) {
1571
- throw new Error(`Path not found: ${input.path}`);
1572
- }
1573
- }
1574
- return {
1575
- value: current,
1576
- type: Array.isArray(current) ? "array" : typeof current
1577
- };
1578
- }).build();
1579
- var jsonValidator = toolBuilder().name("json-validator").description("Validate JSON string syntax without parsing. Returns whether the JSON is valid and any error details.").category(ToolCategory.UTILITY).tags(["json", "validate", "check", "data"]).schema(z.object({
1580
- json: z.string().describe("JSON string to validate")
1581
- })).implementSafe(async (input) => {
1582
- JSON.parse(input.json);
1583
- return {
1584
- valid: true,
1585
- message: "Valid JSON"
1586
- };
1587
- }).build();
1588
- var jsonMerge = toolBuilder().name("json-merge").description("Merge two or more JSON objects. Later objects override earlier ones for conflicting keys.").category(ToolCategory.UTILITY).tags(["json", "merge", "combine", "data"]).schema(z.object({
1589
- objects: z.array(z.any().describe("Object to merge")).describe("Array of objects to merge"),
1590
- deep: z.boolean().default(false).describe("Perform deep merge (nested objects)")
1591
- })).implement(async (input) => {
1592
- if (input.deep) {
1593
- const deepMerge = (target, source) => {
1594
- const output = { ...target };
1595
- for (const key in source) {
1596
- if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
1597
- output[key] = deepMerge(output[key] || {}, source[key]);
1598
- } else {
1599
- output[key] = source[key];
1600
- }
1601
- }
1602
- return output;
1603
- };
1604
- return input.objects.reduce((acc, obj) => deepMerge(acc, obj), {});
1605
- } else {
1606
- return Object.assign({}, ...input.objects);
1607
- }
1608
- }).build();
1609
- var csvParser = toolBuilder().name("csv-parser").description("Parse CSV string into an array of objects. Supports custom delimiters, headers, and options.").category(ToolCategory.UTILITY).tags(["csv", "parse", "data", "table"]).schema(z.object({
1492
+ var csvParserSchema = z.object({
1610
1493
  csv: z.string().describe("CSV string to parse"),
1611
1494
  delimiter: z.string().default(",").describe("Column delimiter character"),
1612
1495
  hasHeaders: z.boolean().default(true).describe("First row contains column headers"),
1613
1496
  skipEmptyLines: z.boolean().default(true).describe("Skip empty lines in the CSV"),
1614
1497
  trim: z.boolean().default(true).describe("Trim whitespace from values")
1615
- })).implement(async (input) => {
1616
- try {
1617
- const records = parse(input.csv, {
1618
- delimiter: input.delimiter,
1619
- columns: input.hasHeaders,
1620
- skip_empty_lines: input.skipEmptyLines,
1621
- trim: input.trim,
1622
- relax_column_count: true
1623
- });
1624
- return {
1625
- success: true,
1626
- data: records,
1627
- rowCount: records.length,
1628
- columnCount: records.length > 0 ? Object.keys(records[0]).length : 0
1629
- };
1630
- } catch (error) {
1631
- return {
1632
- success: false,
1633
- error: error instanceof Error ? error.message : "Failed to parse CSV"
1634
- };
1635
- }
1636
- }).build();
1637
- var csvGenerator = toolBuilder().name("csv-generator").description("Convert an array of objects to CSV string. Automatically extracts headers from object keys.").category(ToolCategory.UTILITY).tags(["csv", "generate", "stringify", "data"]).schema(z.object({
1498
+ });
1499
+ var csvGeneratorSchema = z.object({
1638
1500
  data: z.array(z.record(z.any().describe("Column value"))).describe("Array of objects to convert to CSV"),
1639
1501
  delimiter: z.string().default(",").describe("Column delimiter character"),
1640
1502
  includeHeaders: z.boolean().default(true).describe("Include header row with column names"),
1641
1503
  columns: z.array(z.string().describe("String value")).optional().describe("Optional list of columns to include (in order)")
1642
- })).implement(async (input) => {
1643
- try {
1644
- const csv = stringify(input.data, {
1645
- delimiter: input.delimiter,
1646
- header: input.includeHeaders,
1647
- columns: input.columns
1648
- });
1649
- return {
1650
- success: true,
1651
- csv,
1652
- rowCount: input.data.length
1653
- };
1654
- } catch (error) {
1655
- return {
1656
- success: false,
1657
- error: error instanceof Error ? error.message : "Failed to generate CSV"
1658
- };
1659
- }
1660
- }).build();
1661
- var csvToJson = toolBuilder().name("csv-to-json").description("Convert CSV string to JSON array. Each row becomes an object with column headers as keys.").category(ToolCategory.UTILITY).tags(["csv", "json", "convert", "data"]).schema(z.object({
1504
+ });
1505
+ var csvToJsonSchema = z.object({
1662
1506
  csv: z.string().describe("CSV string to convert"),
1663
1507
  delimiter: z.string().default(",").describe("Column delimiter character"),
1664
1508
  pretty: z.boolean().default(false).describe("Format JSON with indentation")
1665
- })).implement(async (input) => {
1666
- try {
1667
- const records = parse(input.csv, {
1668
- delimiter: input.delimiter,
1669
- columns: true,
1670
- skip_empty_lines: true,
1671
- trim: true
1672
- });
1673
- const json = input.pretty ? JSON.stringify(records, null, 2) : JSON.stringify(records);
1674
- return {
1675
- success: true,
1676
- json,
1677
- recordCount: records.length
1678
- };
1679
- } catch (error) {
1680
- return {
1681
- success: false,
1682
- error: error instanceof Error ? error.message : "Failed to convert CSV to JSON"
1683
- };
1684
- }
1685
- }).build();
1686
- var jsonToCsv = toolBuilder().name("json-to-csv").description("Convert JSON array to CSV string. Each object becomes a row with keys as column headers.").category(ToolCategory.UTILITY).tags(["json", "csv", "convert", "data"]).schema(z.object({
1509
+ });
1510
+ var jsonToCsvSchema = z.object({
1687
1511
  json: z.string().describe("JSON array string to convert"),
1688
1512
  delimiter: z.string().default(",").describe("Column delimiter character")
1689
- })).implement(async (input) => {
1690
- try {
1691
- const data = JSON.parse(input.json);
1692
- if (!Array.isArray(data)) {
1513
+ });
1514
+ function createCsvParserTool(defaultDelimiter = ",", defaultHasHeaders = true, defaultSkipEmptyLines = true, defaultTrim = true) {
1515
+ return toolBuilder().name("csv-parser").description("Parse CSV string into an array of objects. Supports custom delimiters, headers, and options.").category(ToolCategory.UTILITY).tags(["csv", "parse", "data", "table"]).schema(csvParserSchema).implement(async (input) => {
1516
+ try {
1517
+ const records = parse(input.csv, {
1518
+ delimiter: input.delimiter ?? defaultDelimiter,
1519
+ columns: input.hasHeaders ?? defaultHasHeaders,
1520
+ skip_empty_lines: input.skipEmptyLines ?? defaultSkipEmptyLines,
1521
+ trim: input.trim ?? defaultTrim,
1522
+ relax_column_count: true
1523
+ });
1524
+ return {
1525
+ success: true,
1526
+ data: records,
1527
+ rowCount: records.length,
1528
+ columnCount: records.length > 0 ? Object.keys(records[0]).length : 0
1529
+ };
1530
+ } catch (error) {
1693
1531
  return {
1694
1532
  success: false,
1695
- error: "Input must be a JSON array"
1533
+ error: error instanceof Error ? error.message : "Failed to parse CSV"
1696
1534
  };
1697
1535
  }
1698
- const csv = stringify(data, {
1699
- delimiter: input.delimiter,
1700
- header: true
1701
- });
1536
+ }).build();
1537
+ }
1538
+ function createCsvGeneratorTool(defaultDelimiter = ",") {
1539
+ return toolBuilder().name("csv-generator").description("Convert an array of objects to CSV string. Automatically extracts headers from object keys.").category(ToolCategory.UTILITY).tags(["csv", "generate", "stringify", "data"]).schema(csvGeneratorSchema).implement(async (input) => {
1540
+ try {
1541
+ const csv = stringify(input.data, {
1542
+ delimiter: input.delimiter ?? defaultDelimiter,
1543
+ header: input.includeHeaders,
1544
+ columns: input.columns
1545
+ });
1546
+ return {
1547
+ success: true,
1548
+ csv,
1549
+ rowCount: input.data.length
1550
+ };
1551
+ } catch (error) {
1552
+ return {
1553
+ success: false,
1554
+ error: error instanceof Error ? error.message : "Failed to generate CSV"
1555
+ };
1556
+ }
1557
+ }).build();
1558
+ }
1559
+ function createCsvToJsonTool(defaultDelimiter = ",") {
1560
+ return toolBuilder().name("csv-to-json").description("Convert CSV string to JSON array. Each row becomes an object with column headers as keys.").category(ToolCategory.UTILITY).tags(["csv", "json", "convert", "data"]).schema(csvToJsonSchema).implement(async (input) => {
1561
+ try {
1562
+ const records = parse(input.csv, {
1563
+ delimiter: input.delimiter ?? defaultDelimiter,
1564
+ columns: true,
1565
+ skip_empty_lines: true,
1566
+ trim: true
1567
+ });
1568
+ const json = input.pretty ? JSON.stringify(records, null, 2) : JSON.stringify(records);
1569
+ return {
1570
+ success: true,
1571
+ json,
1572
+ recordCount: records.length
1573
+ };
1574
+ } catch (error) {
1575
+ return {
1576
+ success: false,
1577
+ error: error instanceof Error ? error.message : "Failed to convert CSV to JSON"
1578
+ };
1579
+ }
1580
+ }).build();
1581
+ }
1582
+ function createJsonToCsvTool(defaultDelimiter = ",") {
1583
+ return toolBuilder().name("json-to-csv").description("Convert JSON array to CSV string. Each object becomes a row with keys as column headers.").category(ToolCategory.UTILITY).tags(["json", "csv", "convert", "data"]).schema(jsonToCsvSchema).implement(async (input) => {
1584
+ try {
1585
+ const data = JSON.parse(input.json);
1586
+ if (!Array.isArray(data)) {
1587
+ return {
1588
+ success: false,
1589
+ error: "Input must be a JSON array"
1590
+ };
1591
+ }
1592
+ const csv = stringify(data, {
1593
+ delimiter: input.delimiter ?? defaultDelimiter,
1594
+ header: true
1595
+ });
1596
+ return {
1597
+ success: true,
1598
+ csv,
1599
+ rowCount: data.length
1600
+ };
1601
+ } catch (error) {
1602
+ return {
1603
+ success: false,
1604
+ error: error instanceof Error ? error.message : "Failed to convert JSON to CSV"
1605
+ };
1606
+ }
1607
+ }).build();
1608
+ }
1609
+
1610
+ // src/data/csv/index.ts
1611
+ var csvParser = createCsvParserTool();
1612
+ var csvGenerator = createCsvGeneratorTool();
1613
+ var csvToJson = createCsvToJsonTool();
1614
+ var jsonToCsv = createJsonToCsvTool();
1615
+ var csvTools = [csvParser, csvGenerator, csvToJson, jsonToCsv];
1616
+ function createCsvTools(config = {}) {
1617
+ const {
1618
+ defaultDelimiter = ",",
1619
+ defaultHasHeaders = true,
1620
+ defaultSkipEmptyLines = true,
1621
+ defaultTrim = true
1622
+ } = config;
1623
+ return [
1624
+ createCsvParserTool(defaultDelimiter, defaultHasHeaders, defaultSkipEmptyLines, defaultTrim),
1625
+ createCsvGeneratorTool(defaultDelimiter),
1626
+ createCsvToJsonTool(defaultDelimiter),
1627
+ createJsonToCsvTool(defaultDelimiter)
1628
+ ];
1629
+ }
1630
+ var jsonParserSchema = z.object({
1631
+ json: z.string().describe("JSON string to parse"),
1632
+ strict: z.boolean().default(true).describe("Use strict JSON parsing (no trailing commas, etc.)")
1633
+ });
1634
+ var jsonStringifySchema = z.object({
1635
+ data: z.any().describe("Data to convert to JSON string"),
1636
+ pretty: z.boolean().default(false).describe("Format with indentation for readability"),
1637
+ indent: z.number().default(2).describe("Number of spaces for indentation (when pretty is true)")
1638
+ });
1639
+ var jsonQuerySchema = z.object({
1640
+ data: z.any().describe("JSON data to query"),
1641
+ path: z.string().describe('Dot notation path to query (e.g., "user.name" or "items[0].id")')
1642
+ });
1643
+ var jsonValidatorSchema = z.object({
1644
+ json: z.string().describe("JSON string to validate")
1645
+ });
1646
+ var jsonMergeSchema = z.object({
1647
+ objects: z.array(z.any().describe("Object to merge")).describe("Array of objects to merge"),
1648
+ deep: z.boolean().default(false).describe("Perform deep merge (nested objects)")
1649
+ });
1650
+ function createJsonParserTool() {
1651
+ return toolBuilder().name("json-parser").description("Parse JSON string into an object. Validates JSON syntax and returns parsed data or error details.").category(ToolCategory.UTILITY).tags(["json", "parse", "data"]).schema(jsonParserSchema).implementSafe(async (input) => {
1652
+ const parsed = JSON.parse(input.json);
1702
1653
  return {
1703
- success: true,
1704
- csv,
1705
- rowCount: data.length
1654
+ data: parsed,
1655
+ type: Array.isArray(parsed) ? "array" : typeof parsed
1706
1656
  };
1707
- } catch (error) {
1657
+ }).build();
1658
+ }
1659
+ function createJsonStringifyTool(defaultIndent = 2, defaultPretty = false) {
1660
+ return toolBuilder().name("json-stringify").description("Convert an object to a JSON string with optional formatting (pretty print).").category(ToolCategory.UTILITY).tags(["json", "stringify", "format", "data"]).schema(jsonStringifySchema).implementSafe(async (input) => {
1661
+ const pretty = input.pretty ?? defaultPretty;
1662
+ const indent = input.indent ?? defaultIndent;
1663
+ const json = pretty ? JSON.stringify(input.data, null, indent) : JSON.stringify(input.data);
1708
1664
  return {
1709
- success: false,
1710
- error: error instanceof Error ? error.message : "Failed to convert JSON to CSV"
1665
+ json,
1666
+ length: json.length
1711
1667
  };
1712
- }
1713
- }).build();
1714
- var xmlParser = toolBuilder().name("xml-parser").description("Parse XML string into a JavaScript object. Supports attributes, CDATA, and nested elements.").category(ToolCategory.UTILITY).tags(["xml", "parse", "data"]).schema(z.object({
1715
- xml: z.string().describe("XML string to parse"),
1716
- ignoreAttributes: z.boolean().default(false).describe("Ignore XML attributes"),
1717
- parseAttributeValue: z.boolean().default(true).describe("Parse attribute values (numbers, booleans)"),
1718
- trimValues: z.boolean().default(true).describe("Trim whitespace from text values")
1719
- })).implement(async (input) => {
1720
- try {
1721
- const parser = new XMLParser({
1722
- ignoreAttributes: input.ignoreAttributes,
1723
- parseAttributeValue: input.parseAttributeValue,
1724
- trimValues: input.trimValues,
1725
- parseTagValue: true
1726
- });
1727
- const result = parser.parse(input.xml);
1668
+ }).build();
1669
+ }
1670
+ function createJsonQueryTool() {
1671
+ return toolBuilder().name("json-query").description('Query JSON data using dot notation path (e.g., "user.address.city"). Supports array indexing.').category(ToolCategory.UTILITY).tags(["json", "query", "path", "data"]).schema(jsonQuerySchema).implementSafe(async (input) => {
1672
+ const parts = input.path.split(".");
1673
+ let current = input.data;
1674
+ for (const part of parts) {
1675
+ const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
1676
+ if (arrayMatch) {
1677
+ const [, key, index] = arrayMatch;
1678
+ current = current[key][parseInt(index, 10)];
1679
+ } else {
1680
+ current = current[part];
1681
+ }
1682
+ if (current === void 0) {
1683
+ throw new Error(`Path not found: ${input.path}`);
1684
+ }
1685
+ }
1728
1686
  return {
1729
- success: true,
1730
- data: result
1687
+ value: current,
1688
+ type: Array.isArray(current) ? "array" : typeof current
1731
1689
  };
1732
- } catch (error) {
1690
+ }).build();
1691
+ }
1692
+ function createJsonValidatorTool() {
1693
+ return toolBuilder().name("json-validator").description("Validate JSON string syntax without parsing. Returns whether the JSON is valid and any error details.").category(ToolCategory.UTILITY).tags(["json", "validate", "check", "data"]).schema(jsonValidatorSchema).implementSafe(async (input) => {
1694
+ JSON.parse(input.json);
1733
1695
  return {
1734
- success: false,
1735
- error: error instanceof Error ? error.message : "Failed to parse XML"
1696
+ valid: true,
1697
+ message: "Valid JSON"
1736
1698
  };
1737
- }
1738
- }).build();
1739
- var xmlGenerator = toolBuilder().name("xml-generator").description("Convert a JavaScript object to XML string. Supports attributes, CDATA, and nested elements.").category(ToolCategory.UTILITY).tags(["xml", "generate", "stringify", "data"]).schema(z.object({
1699
+ }).build();
1700
+ }
1701
+ function createJsonMergeTool() {
1702
+ return toolBuilder().name("json-merge").description("Merge two or more JSON objects. Later objects override earlier ones for conflicting keys.").category(ToolCategory.UTILITY).tags(["json", "merge", "combine", "data"]).schema(jsonMergeSchema).implement(async (input) => {
1703
+ if (input.deep) {
1704
+ const deepMerge = (target, source) => {
1705
+ const output = { ...target };
1706
+ for (const key in source) {
1707
+ if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
1708
+ output[key] = deepMerge(output[key] || {}, source[key]);
1709
+ } else {
1710
+ output[key] = source[key];
1711
+ }
1712
+ }
1713
+ return output;
1714
+ };
1715
+ return input.objects.reduce((acc, obj) => deepMerge(acc, obj), {});
1716
+ } else {
1717
+ return Object.assign({}, ...input.objects);
1718
+ }
1719
+ }).build();
1720
+ }
1721
+
1722
+ // src/data/json/index.ts
1723
+ var jsonParser = createJsonParserTool();
1724
+ var jsonStringify = createJsonStringifyTool();
1725
+ var jsonQuery = createJsonQueryTool();
1726
+ var jsonValidator = createJsonValidatorTool();
1727
+ var jsonMerge = createJsonMergeTool();
1728
+ var jsonTools = [jsonParser, jsonStringify, jsonQuery, jsonValidator, jsonMerge];
1729
+ function createJsonTools(config = {}) {
1730
+ const {
1731
+ defaultIndent = 2,
1732
+ defaultPretty = false
1733
+ } = config;
1734
+ return [
1735
+ createJsonParserTool(),
1736
+ createJsonStringifyTool(defaultIndent, defaultPretty),
1737
+ createJsonQueryTool(),
1738
+ createJsonValidatorTool(),
1739
+ createJsonMergeTool()
1740
+ ];
1741
+ }
1742
+ var xmlParserSchema = z.object({
1743
+ xml: z.string().describe("XML string to parse"),
1744
+ ignoreAttributes: z.boolean().default(false).describe("Ignore XML attributes"),
1745
+ parseAttributeValue: z.boolean().default(true).describe("Parse attribute values (numbers, booleans)"),
1746
+ trimValues: z.boolean().default(true).describe("Trim whitespace from text values")
1747
+ });
1748
+ var xmlGeneratorSchema = z.object({
1740
1749
  data: z.any().describe("Object to convert to XML"),
1741
1750
  rootName: z.string().default("root").describe("Name of the root XML element"),
1742
1751
  format: z.boolean().default(false).describe("Format XML with indentation"),
1743
1752
  indentSize: z.number().default(2).describe("Number of spaces for indentation (when format is true)")
1744
- })).implement(async (input) => {
1745
- try {
1746
- const indentSize = input.indentSize ?? 2;
1747
- const rootName = input.rootName ?? "root";
1748
- const builder = new XMLBuilder({
1749
- format: input.format ?? false,
1750
- indentBy: " ".repeat(indentSize),
1751
- ignoreAttributes: false
1752
- });
1753
- const dataToConvert = input.data[rootName] ? input.data : { [rootName]: input.data };
1754
- const xml = builder.build(dataToConvert);
1755
- return {
1756
- success: true,
1757
- xml
1758
- };
1759
- } catch (error) {
1760
- return {
1761
- success: false,
1762
- error: error instanceof Error ? error.message : "Failed to generate XML"
1763
- };
1764
- }
1765
- }).build();
1766
- var xmlToJson = toolBuilder().name("xml-to-json").description("Convert XML string to JSON. Preserves structure and can include or exclude attributes.").category(ToolCategory.UTILITY).tags(["xml", "json", "convert", "data"]).schema(z.object({
1753
+ });
1754
+ var xmlToJsonSchema = z.object({
1767
1755
  xml: z.string().describe("XML string to convert"),
1768
1756
  ignoreAttributes: z.boolean().default(false).describe("Ignore XML attributes in conversion"),
1769
1757
  pretty: z.boolean().default(false).describe("Format JSON with indentation")
1770
- })).implement(async (input) => {
1771
- try {
1772
- const parser = new XMLParser({
1773
- ignoreAttributes: input.ignoreAttributes,
1774
- parseAttributeValue: true,
1775
- trimValues: true
1776
- });
1777
- const result = parser.parse(input.xml);
1778
- const json = input.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
1779
- return {
1780
- success: true,
1781
- json
1782
- };
1783
- } catch (error) {
1784
- return {
1785
- success: false,
1786
- error: error instanceof Error ? error.message : "Failed to convert XML to JSON"
1787
- };
1788
- }
1789
- }).build();
1790
- var jsonToXml = toolBuilder().name("json-to-xml").description("Convert JSON string to XML. Each object key becomes an XML element.").category(ToolCategory.UTILITY).tags(["json", "xml", "convert", "data"]).schema(z.object({
1758
+ });
1759
+ var jsonToXmlSchema = z.object({
1791
1760
  json: z.string().describe("JSON string to convert"),
1792
1761
  rootName: z.string().default("root").describe("Name of the root XML element"),
1793
1762
  format: z.boolean().default(false).describe("Format XML with indentation")
1794
- })).implement(async (input) => {
1795
- try {
1796
- const data = JSON.parse(input.json);
1797
- const rootName = input.rootName ?? "root";
1798
- const builder = new XMLBuilder({
1799
- format: input.format ?? false,
1800
- indentBy: " ",
1801
- ignoreAttributes: false
1802
- });
1803
- const dataToConvert = data[rootName] ? data : { [rootName]: data };
1804
- const xml = builder.build(dataToConvert);
1805
- return {
1806
- success: true,
1807
- xml
1808
- };
1809
- } catch (error) {
1810
- return {
1811
- success: false,
1812
- error: error instanceof Error ? error.message : "Failed to convert JSON to XML"
1813
- };
1814
- }
1815
- }).build();
1816
- var arrayFilter = toolBuilder().name("array-filter").description("Filter an array based on a property value. Supports equality, comparison, and contains operations.").category(ToolCategory.UTILITY).tags(["array", "filter", "data", "transform"]).schema(z.object({
1817
- array: z.array(z.any().describe("Array element")).describe("Array to filter"),
1818
- property: z.string().describe("Property name to filter by (use dot notation for nested properties)"),
1819
- operator: z.enum(["equals", "not-equals", "greater-than", "less-than", "contains", "starts-with", "ends-with"]).describe("Comparison operator"),
1820
- value: z.any().describe("Value to compare against")
1821
- })).implement(async (input) => {
1822
- const getNestedValue = (obj, path4) => {
1823
- return path4.split(".").reduce((current, key) => current?.[key], obj);
1824
- };
1825
- const filtered = input.array.filter((item) => {
1826
- const itemValue = getNestedValue(item, input.property);
1827
- switch (input.operator) {
1828
- case "equals":
1829
- return itemValue === input.value;
1830
- case "not-equals":
1831
- return itemValue !== input.value;
1832
- case "greater-than":
1833
- return itemValue > input.value;
1834
- case "less-than":
1835
- return itemValue < input.value;
1836
- case "contains":
1837
- return String(itemValue).includes(String(input.value));
1838
- case "starts-with":
1839
- return String(itemValue).startsWith(String(input.value));
1840
- case "ends-with":
1841
- return String(itemValue).endsWith(String(input.value));
1842
- default:
1843
- return false;
1844
- }
1845
- });
1846
- return {
1847
- filtered,
1848
- originalCount: input.array.length,
1849
- filteredCount: filtered.length
1850
- };
1851
- }).build();
1852
- var arrayMap = toolBuilder().name("array-map").description("Extract specific properties from each object in an array. Creates a new array with only the selected properties.").category(ToolCategory.UTILITY).tags(["array", "map", "data", "transform"]).schema(z.object({
1763
+ });
1764
+ function createXmlParserTool() {
1765
+ return toolBuilder().name("xml-parser").description("Parse XML string into a JavaScript object. Supports attributes, CDATA, and nested elements.").category(ToolCategory.UTILITY).tags(["xml", "parse", "data"]).schema(xmlParserSchema).implement(async (input) => {
1766
+ try {
1767
+ const parser = new XMLParser({
1768
+ ignoreAttributes: input.ignoreAttributes,
1769
+ parseAttributeValue: input.parseAttributeValue,
1770
+ trimValues: input.trimValues,
1771
+ parseTagValue: true
1772
+ });
1773
+ const result = parser.parse(input.xml);
1774
+ return {
1775
+ success: true,
1776
+ data: result
1777
+ };
1778
+ } catch (error) {
1779
+ return {
1780
+ success: false,
1781
+ error: error instanceof Error ? error.message : "Failed to parse XML"
1782
+ };
1783
+ }
1784
+ }).build();
1785
+ }
1786
+ function createXmlGeneratorTool(defaultRootName = "root", defaultFormat = false, defaultIndentSize = 2) {
1787
+ return toolBuilder().name("xml-generator").description("Convert a JavaScript object to XML string. Supports attributes, CDATA, and nested elements.").category(ToolCategory.UTILITY).tags(["xml", "generate", "stringify", "data"]).schema(xmlGeneratorSchema).implement(async (input) => {
1788
+ try {
1789
+ const indentSize = input.indentSize ?? defaultIndentSize;
1790
+ const rootName = input.rootName ?? defaultRootName;
1791
+ const format3 = input.format ?? defaultFormat;
1792
+ const builder = new XMLBuilder({
1793
+ format: format3,
1794
+ indentBy: " ".repeat(indentSize),
1795
+ ignoreAttributes: false
1796
+ });
1797
+ const dataToConvert = input.data[rootName] ? input.data : { [rootName]: input.data };
1798
+ const xml = builder.build(dataToConvert);
1799
+ return {
1800
+ success: true,
1801
+ xml
1802
+ };
1803
+ } catch (error) {
1804
+ return {
1805
+ success: false,
1806
+ error: error instanceof Error ? error.message : "Failed to generate XML"
1807
+ };
1808
+ }
1809
+ }).build();
1810
+ }
1811
+ function createXmlToJsonTool() {
1812
+ return toolBuilder().name("xml-to-json").description("Convert XML string to JSON. Preserves structure and can include or exclude attributes.").category(ToolCategory.UTILITY).tags(["xml", "json", "convert", "data"]).schema(xmlToJsonSchema).implement(async (input) => {
1813
+ try {
1814
+ const parser = new XMLParser({
1815
+ ignoreAttributes: input.ignoreAttributes,
1816
+ parseAttributeValue: true,
1817
+ trimValues: true
1818
+ });
1819
+ const result = parser.parse(input.xml);
1820
+ const json = input.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
1821
+ return {
1822
+ success: true,
1823
+ json
1824
+ };
1825
+ } catch (error) {
1826
+ return {
1827
+ success: false,
1828
+ error: error instanceof Error ? error.message : "Failed to convert XML to JSON"
1829
+ };
1830
+ }
1831
+ }).build();
1832
+ }
1833
+ function createJsonToXmlTool(defaultRootName = "root", defaultFormat = false) {
1834
+ return toolBuilder().name("json-to-xml").description("Convert JSON string to XML. Each object key becomes an XML element.").category(ToolCategory.UTILITY).tags(["json", "xml", "convert", "data"]).schema(jsonToXmlSchema).implement(async (input) => {
1835
+ try {
1836
+ const data = JSON.parse(input.json);
1837
+ const rootName = input.rootName ?? defaultRootName;
1838
+ const format3 = input.format ?? defaultFormat;
1839
+ const builder = new XMLBuilder({
1840
+ format: format3,
1841
+ indentBy: " ",
1842
+ ignoreAttributes: false
1843
+ });
1844
+ const dataToConvert = data[rootName] ? data : { [rootName]: data };
1845
+ const xml = builder.build(dataToConvert);
1846
+ return {
1847
+ success: true,
1848
+ xml
1849
+ };
1850
+ } catch (error) {
1851
+ return {
1852
+ success: false,
1853
+ error: error instanceof Error ? error.message : "Failed to convert JSON to XML"
1854
+ };
1855
+ }
1856
+ }).build();
1857
+ }
1858
+
1859
+ // src/data/xml/index.ts
1860
+ var xmlParser = createXmlParserTool();
1861
+ var xmlGenerator = createXmlGeneratorTool();
1862
+ var xmlToJson = createXmlToJsonTool();
1863
+ var jsonToXml = createJsonToXmlTool();
1864
+ var xmlTools = [xmlParser, xmlGenerator, xmlToJson, jsonToXml];
1865
+ function createXmlTools(config = {}) {
1866
+ const {
1867
+ defaultRootName = "root",
1868
+ defaultFormat = false,
1869
+ defaultIndentSize = 2
1870
+ } = config;
1871
+ return [
1872
+ createXmlParserTool(),
1873
+ createXmlGeneratorTool(defaultRootName, defaultFormat, defaultIndentSize),
1874
+ createXmlToJsonTool(),
1875
+ createJsonToXmlTool(defaultRootName, defaultFormat)
1876
+ ];
1877
+ }
1878
+ var arrayFilterSchema = z.object({
1879
+ array: z.array(z.any().describe("Array element")).describe("Array to filter"),
1880
+ property: z.string().describe("Property name to filter by (use dot notation for nested properties)"),
1881
+ operator: z.enum(["equals", "not-equals", "greater-than", "less-than", "contains", "starts-with", "ends-with"]).describe("Comparison operator"),
1882
+ value: z.any().describe("Value to compare against")
1883
+ });
1884
+ var arrayMapSchema = z.object({
1853
1885
  array: z.array(z.any().describe("Array element")).describe("Array to map"),
1854
1886
  properties: z.array(z.string().describe("String value")).describe("List of property names to extract from each object")
1855
- })).implement(async (input) => {
1856
- const mapped = input.array.map((item) => {
1857
- const result = {};
1858
- for (const prop of input.properties) {
1859
- const value = prop.split(".").reduce((current, key) => current?.[key], item);
1860
- result[prop] = value;
1861
- }
1862
- return result;
1863
- });
1864
- return {
1865
- mapped,
1866
- count: mapped.length
1867
- };
1868
- }).build();
1869
- var arraySort = toolBuilder().name("array-sort").description("Sort an array by a property value. Supports ascending and descending order.").category(ToolCategory.UTILITY).tags(["array", "sort", "data", "transform"]).schema(z.object({
1887
+ });
1888
+ var arraySortSchema = z.object({
1870
1889
  array: z.array(z.any().describe("Array element")).describe("Array to sort"),
1871
1890
  property: z.string().describe("Property name to sort by (use dot notation for nested properties)"),
1872
1891
  order: z.enum(["asc", "desc"]).default("asc").describe("Sort order: ascending or descending")
1873
- })).implement(async (input) => {
1874
- const getNestedValue = (obj, path4) => {
1875
- return path4.split(".").reduce((current, key) => current?.[key], obj);
1876
- };
1877
- const sorted = [...input.array].sort((a, b) => {
1878
- const aValue = getNestedValue(a, input.property);
1879
- const bValue = getNestedValue(b, input.property);
1880
- if (aValue < bValue) return input.order === "asc" ? -1 : 1;
1881
- if (aValue > bValue) return input.order === "asc" ? 1 : -1;
1882
- return 0;
1883
- });
1884
- return {
1885
- sorted,
1886
- count: sorted.length
1887
- };
1888
- }).build();
1889
- var arrayGroupBy = toolBuilder().name("array-group-by").description("Group an array of objects by a property value. Returns an object with groups as keys.").category(ToolCategory.UTILITY).tags(["array", "group", "data", "transform"]).schema(z.object({
1892
+ });
1893
+ var arrayGroupBySchema = z.object({
1890
1894
  array: z.array(z.any().describe("Array element")).describe("Array to group"),
1891
1895
  property: z.string().describe("Property name to group by")
1892
- })).implement(async (input) => {
1893
- const groups = {};
1894
- for (const item of input.array) {
1895
- const key = String(item[input.property]);
1896
- if (!groups[key]) {
1897
- groups[key] = [];
1898
- }
1899
- groups[key].push(item);
1900
- }
1901
- return {
1902
- groups,
1903
- groupCount: Object.keys(groups).length,
1904
- totalItems: input.array.length
1905
- };
1906
- }).build();
1907
- var objectPick = toolBuilder().name("object-pick").description("Create a new object with only the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "pick", "data", "transform"]).schema(z.object({
1896
+ });
1897
+ var objectPickSchema = z.object({
1908
1898
  object: z.record(z.any().describe("Property value")).describe("Source object"),
1909
1899
  properties: z.array(z.string().describe("String value")).describe("List of property names to pick")
1910
- })).implement(async (input) => {
1911
- const picked = {};
1912
- for (const prop of input.properties) {
1913
- if (prop in input.object) {
1914
- picked[prop] = input.object[prop];
1915
- }
1916
- }
1917
- return picked;
1918
- }).build();
1919
- var objectOmit = toolBuilder().name("object-omit").description("Create a new object excluding the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "omit", "data", "transform"]).schema(z.object({
1900
+ });
1901
+ var objectOmitSchema = z.object({
1920
1902
  object: z.record(z.any().describe("Property value")).describe("Source object"),
1921
1903
  properties: z.array(z.string().describe("String value")).describe("List of property names to omit")
1922
- })).implement(async (input) => {
1923
- const omitted = { ...input.object };
1924
- for (const prop of input.properties) {
1925
- delete omitted[prop];
1926
- }
1927
- return omitted;
1928
- }).build();
1929
- var fileReader = toolBuilder().name("file-reader").description("Read the contents of a file from the file system. Supports text and binary files with various encodings.").category(ToolCategory.FILE_SYSTEM).tags(["file", "read", "io", "filesystem"]).schema(z.object({
1904
+ });
1905
+ function createArrayFilterTool() {
1906
+ return toolBuilder().name("array-filter").description("Filter an array based on a property value. Supports equality, comparison, and contains operations.").category(ToolCategory.UTILITY).tags(["array", "filter", "data", "transform"]).schema(arrayFilterSchema).implement(async (input) => {
1907
+ const getNestedValue = (obj, path12) => {
1908
+ return path12.split(".").reduce((current, key) => current?.[key], obj);
1909
+ };
1910
+ const filtered = input.array.filter((item) => {
1911
+ const itemValue = getNestedValue(item, input.property);
1912
+ switch (input.operator) {
1913
+ case "equals":
1914
+ return itemValue === input.value;
1915
+ case "not-equals":
1916
+ return itemValue !== input.value;
1917
+ case "greater-than":
1918
+ return itemValue > input.value;
1919
+ case "less-than":
1920
+ return itemValue < input.value;
1921
+ case "contains":
1922
+ return String(itemValue).includes(String(input.value));
1923
+ case "starts-with":
1924
+ return String(itemValue).startsWith(String(input.value));
1925
+ case "ends-with":
1926
+ return String(itemValue).endsWith(String(input.value));
1927
+ default:
1928
+ return false;
1929
+ }
1930
+ });
1931
+ return {
1932
+ filtered,
1933
+ originalCount: input.array.length,
1934
+ filteredCount: filtered.length
1935
+ };
1936
+ }).build();
1937
+ }
1938
+ function createArrayMapTool() {
1939
+ return toolBuilder().name("array-map").description("Extract specific properties from each object in an array. Creates a new array with only the selected properties.").category(ToolCategory.UTILITY).tags(["array", "map", "data", "transform"]).schema(arrayMapSchema).implement(async (input) => {
1940
+ const mapped = input.array.map((item) => {
1941
+ const result = {};
1942
+ for (const prop of input.properties) {
1943
+ const value = prop.split(".").reduce((current, key) => current?.[key], item);
1944
+ result[prop] = value;
1945
+ }
1946
+ return result;
1947
+ });
1948
+ return {
1949
+ mapped,
1950
+ count: mapped.length
1951
+ };
1952
+ }).build();
1953
+ }
1954
+ function createArraySortTool() {
1955
+ return toolBuilder().name("array-sort").description("Sort an array by a property value. Supports ascending and descending order.").category(ToolCategory.UTILITY).tags(["array", "sort", "data", "transform"]).schema(arraySortSchema).implement(async (input) => {
1956
+ const getNestedValue = (obj, path12) => {
1957
+ return path12.split(".").reduce((current, key) => current?.[key], obj);
1958
+ };
1959
+ const sorted = [...input.array].sort((a, b) => {
1960
+ const aValue = getNestedValue(a, input.property);
1961
+ const bValue = getNestedValue(b, input.property);
1962
+ if (aValue < bValue) return input.order === "asc" ? -1 : 1;
1963
+ if (aValue > bValue) return input.order === "asc" ? 1 : -1;
1964
+ return 0;
1965
+ });
1966
+ return {
1967
+ sorted,
1968
+ count: sorted.length
1969
+ };
1970
+ }).build();
1971
+ }
1972
+ function createArrayGroupByTool() {
1973
+ return toolBuilder().name("array-group-by").description("Group an array of objects by a property value. Returns an object with groups as keys.").category(ToolCategory.UTILITY).tags(["array", "group", "data", "transform"]).schema(arrayGroupBySchema).implement(async (input) => {
1974
+ const groups = {};
1975
+ for (const item of input.array) {
1976
+ const key = String(item[input.property]);
1977
+ if (!groups[key]) {
1978
+ groups[key] = [];
1979
+ }
1980
+ groups[key].push(item);
1981
+ }
1982
+ return {
1983
+ groups,
1984
+ groupCount: Object.keys(groups).length,
1985
+ totalItems: input.array.length
1986
+ };
1987
+ }).build();
1988
+ }
1989
+ function createObjectPickTool() {
1990
+ return toolBuilder().name("object-pick").description("Create a new object with only the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "pick", "data", "transform"]).schema(objectPickSchema).implement(async (input) => {
1991
+ const picked = {};
1992
+ for (const prop of input.properties) {
1993
+ if (prop in input.object) {
1994
+ picked[prop] = input.object[prop];
1995
+ }
1996
+ }
1997
+ return picked;
1998
+ }).build();
1999
+ }
2000
+ function createObjectOmitTool() {
2001
+ return toolBuilder().name("object-omit").description("Create a new object excluding the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "omit", "data", "transform"]).schema(objectOmitSchema).implement(async (input) => {
2002
+ const omitted = { ...input.object };
2003
+ for (const prop of input.properties) {
2004
+ delete omitted[prop];
2005
+ }
2006
+ return omitted;
2007
+ }).build();
2008
+ }
2009
+
2010
+ // src/data/transformer/index.ts
2011
+ var arrayFilter = createArrayFilterTool();
2012
+ var arrayMap = createArrayMapTool();
2013
+ var arraySort = createArraySortTool();
2014
+ var arrayGroupBy = createArrayGroupByTool();
2015
+ var objectPick = createObjectPickTool();
2016
+ var objectOmit = createObjectOmitTool();
2017
+ var transformerTools = [arrayFilter, arrayMap, arraySort, arrayGroupBy, objectPick, objectOmit];
2018
+ function createTransformerTools(config = {}) {
2019
+ return [
2020
+ createArrayFilterTool(),
2021
+ createArrayMapTool(),
2022
+ createArraySortTool(),
2023
+ createArrayGroupByTool(),
2024
+ createObjectPickTool(),
2025
+ createObjectOmitTool()
2026
+ ];
2027
+ }
2028
+ var fileReaderSchema = z.object({
1930
2029
  path: z.string().describe("Path to the file to read"),
1931
2030
  encoding: z.enum(["utf8", "utf-8", "ascii", "base64", "hex", "binary"]).default("utf8").describe("File encoding")
1932
- })).implementSafe(async (input) => {
1933
- const content = await promises.readFile(input.path, input.encoding);
1934
- const stats = await promises.stat(input.path);
1935
- return {
1936
- content,
1937
- size: stats.size,
1938
- path: input.path,
1939
- encoding: input.encoding
1940
- };
1941
- }).build();
1942
- var fileWriter = 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(ToolCategory.FILE_SYSTEM).tags(["file", "write", "io", "filesystem"]).schema(z.object({
2031
+ });
2032
+ var fileWriterSchema = z.object({
1943
2033
  path: z.string().describe("Path to the file to write"),
1944
2034
  content: z.string().describe("Content to write to the file"),
1945
2035
  encoding: z.enum(["utf8", "utf-8", "ascii", "base64", "hex"]).default("utf8").describe("File encoding"),
1946
2036
  createDirs: z.boolean().default(false).describe("Create parent directories if they don't exist")
1947
- })).implementSafe(async (input) => {
1948
- if (input.createDirs) {
1949
- const dir = path3.dirname(input.path);
1950
- await promises.mkdir(dir, { recursive: true });
1951
- }
1952
- await promises.writeFile(input.path, input.content, input.encoding);
1953
- const stats = await promises.stat(input.path);
1954
- return {
1955
- path: input.path,
1956
- size: stats.size,
1957
- encoding: input.encoding
1958
- };
1959
- }).build();
1960
- var fileAppend = toolBuilder().name("file-append").description("Append content to the end of a file. Creates the file if it doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "append", "io", "filesystem"]).schema(z.object({
2037
+ });
2038
+ var fileAppendSchema = z.object({
1961
2039
  path: z.string().describe("Path to the file to append to"),
1962
2040
  content: z.string().describe("Content to append to the file"),
1963
2041
  encoding: z.enum(["utf8", "utf-8", "ascii"]).default("utf8").describe("File encoding")
1964
- })).implementSafe(async (input) => {
1965
- await promises.appendFile(input.path, input.content, input.encoding);
1966
- const stats = await promises.stat(input.path);
1967
- return {
1968
- path: input.path,
1969
- size: stats.size
1970
- };
1971
- }).build();
1972
- var fileDelete = toolBuilder().name("file-delete").description("Delete a file from the file system. Returns an error if the file doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "delete", "remove", "filesystem"]).schema(z.object({
2042
+ });
2043
+ var fileDeleteSchema = z.object({
1973
2044
  path: z.string().describe("Path to the file to delete")
1974
- })).implementSafe(async (input) => {
1975
- await promises.unlink(input.path);
1976
- return {
1977
- path: input.path,
1978
- message: "File deleted successfully"
1979
- };
1980
- }).build();
1981
- var fileExists = toolBuilder().name("file-exists").description("Check if a file or directory exists at the specified path.").category(ToolCategory.FILE_SYSTEM).tags(["file", "exists", "check", "filesystem"]).schema(z.object({
2045
+ });
2046
+ var fileExistsSchema = z.object({
1982
2047
  path: z.string().describe("Path to check")
1983
- })).implement(async (input) => {
1984
- try {
1985
- await promises.access(input.path);
2048
+ });
2049
+ function createFileReaderTool(defaultEncoding = "utf8") {
2050
+ return toolBuilder().name("file-reader").description("Read the contents of a file from the file system. Supports text and binary files with various encodings.").category(ToolCategory.FILE_SYSTEM).tags(["file", "read", "io", "filesystem"]).schema(fileReaderSchema).implementSafe(async (input) => {
2051
+ const encoding = input.encoding || defaultEncoding;
2052
+ const content = await promises.readFile(input.path, encoding);
2053
+ const stats = await promises.stat(input.path);
2054
+ return {
2055
+ content,
2056
+ size: stats.size,
2057
+ path: input.path,
2058
+ encoding
2059
+ };
2060
+ }).build();
2061
+ }
2062
+ function createFileWriterTool(defaultEncoding = "utf8", createDirsDefault = false) {
2063
+ return 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(ToolCategory.FILE_SYSTEM).tags(["file", "write", "io", "filesystem"]).schema(fileWriterSchema).implementSafe(async (input) => {
2064
+ const encoding = input.encoding || defaultEncoding;
2065
+ const createDirs = input.createDirs ?? createDirsDefault;
2066
+ if (createDirs) {
2067
+ const dir = path7.dirname(input.path);
2068
+ await promises.mkdir(dir, { recursive: true });
2069
+ }
2070
+ await promises.writeFile(input.path, input.content, encoding);
1986
2071
  const stats = await promises.stat(input.path);
1987
2072
  return {
1988
- exists: true,
1989
2073
  path: input.path,
1990
- isFile: stats.isFile(),
1991
- isDirectory: stats.isDirectory(),
1992
2074
  size: stats.size,
1993
- modified: stats.mtime.toISOString()
2075
+ encoding
1994
2076
  };
1995
- } catch {
2077
+ }).build();
2078
+ }
2079
+ function createFileAppendTool(defaultEncoding = "utf8") {
2080
+ return toolBuilder().name("file-append").description("Append content to the end of a file. Creates the file if it doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "append", "io", "filesystem"]).schema(fileAppendSchema).implementSafe(async (input) => {
2081
+ const encoding = input.encoding || defaultEncoding;
2082
+ await promises.appendFile(input.path, input.content, encoding);
2083
+ const stats = await promises.stat(input.path);
1996
2084
  return {
1997
- exists: false,
1998
- path: input.path
2085
+ path: input.path,
2086
+ size: stats.size
1999
2087
  };
2000
- }
2001
- }).build();
2002
- var directoryList = toolBuilder().name("directory-list").description("List all files and directories in a directory. Can optionally include file details and filter by extension.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "list", "files", "filesystem"]).schema(z.object({
2088
+ }).build();
2089
+ }
2090
+ function createFileDeleteTool() {
2091
+ return toolBuilder().name("file-delete").description("Delete a file from the file system. Returns an error if the file doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "delete", "remove", "filesystem"]).schema(fileDeleteSchema).implementSafe(async (input) => {
2092
+ await promises.unlink(input.path);
2093
+ return {
2094
+ path: input.path,
2095
+ message: "File deleted successfully"
2096
+ };
2097
+ }).build();
2098
+ }
2099
+ function createFileExistsTool() {
2100
+ return toolBuilder().name("file-exists").description("Check if a file or directory exists at the specified path.").category(ToolCategory.FILE_SYSTEM).tags(["file", "exists", "check", "filesystem"]).schema(fileExistsSchema).implement(async (input) => {
2101
+ try {
2102
+ await promises.access(input.path);
2103
+ const stats = await promises.stat(input.path);
2104
+ return {
2105
+ exists: true,
2106
+ path: input.path,
2107
+ isFile: stats.isFile(),
2108
+ isDirectory: stats.isDirectory(),
2109
+ size: stats.size,
2110
+ modified: stats.mtime.toISOString()
2111
+ };
2112
+ } catch {
2113
+ return {
2114
+ exists: false,
2115
+ path: input.path
2116
+ };
2117
+ }
2118
+ }).build();
2119
+ }
2120
+
2121
+ // src/file/operations/index.ts
2122
+ var fileReader = createFileReaderTool();
2123
+ var fileWriter = createFileWriterTool();
2124
+ var fileAppend = createFileAppendTool();
2125
+ var fileDelete = createFileDeleteTool();
2126
+ var fileExists = createFileExistsTool();
2127
+ var fileOperationTools = [
2128
+ fileReader,
2129
+ fileWriter,
2130
+ fileAppend,
2131
+ fileDelete,
2132
+ fileExists
2133
+ ];
2134
+ function createFileOperationTools(config = {}) {
2135
+ const {
2136
+ defaultEncoding = "utf8",
2137
+ createDirsDefault = false
2138
+ } = config;
2139
+ return [
2140
+ createFileReaderTool(defaultEncoding),
2141
+ createFileWriterTool(defaultEncoding, createDirsDefault),
2142
+ createFileAppendTool(defaultEncoding),
2143
+ createFileDeleteTool(),
2144
+ createFileExistsTool()
2145
+ ];
2146
+ }
2147
+ var directoryListSchema = z.object({
2003
2148
  path: z.string().describe("Path to the directory to list"),
2004
2149
  recursive: z.boolean().default(false).describe("List files recursively in subdirectories"),
2005
2150
  includeDetails: z.boolean().default(false).describe("Include file size, type, and modification date"),
2006
2151
  extension: z.string().optional().describe('Optional file extension filter (e.g., ".txt", ".js")')
2007
- })).implementSafe(async (input) => {
2008
- const listFiles = async (dir, recursive) => {
2009
- const entries = await promises.readdir(dir, { withFileTypes: true });
2010
- const files2 = [];
2011
- for (const entry of entries) {
2012
- const fullPath = path3.join(dir, entry.name);
2013
- const relativePath = path3.relative(input.path, fullPath);
2014
- if (input.extension && !entry.name.endsWith(input.extension)) {
2015
- if (!entry.isDirectory() || !recursive) {
2016
- continue;
2017
- }
2018
- }
2019
- if (input.includeDetails) {
2020
- const stats = await promises.stat(fullPath);
2021
- files2.push({
2022
- name: entry.name,
2023
- path: relativePath,
2024
- fullPath,
2025
- isFile: entry.isFile(),
2026
- isDirectory: entry.isDirectory(),
2027
- size: stats.size,
2028
- modified: stats.mtime.toISOString()
2029
- });
2030
- } else {
2031
- files2.push({
2032
- name: entry.name,
2033
- path: relativePath,
2034
- isFile: entry.isFile(),
2035
- isDirectory: entry.isDirectory()
2036
- });
2037
- }
2038
- if (recursive && entry.isDirectory()) {
2039
- const subFiles = await listFiles(fullPath, true);
2040
- files2.push(...subFiles);
2041
- }
2042
- }
2043
- return files2;
2044
- };
2045
- const files = await listFiles(input.path, input.recursive ?? false);
2046
- return {
2047
- path: input.path,
2048
- files,
2049
- count: files.length
2050
- };
2051
- }).build();
2052
- var directoryCreate = toolBuilder().name("directory-create").description("Create a new directory. Can optionally create parent directories if they don't exist.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "create", "mkdir", "filesystem"]).schema(z.object({
2152
+ });
2153
+ var directoryCreateSchema = z.object({
2053
2154
  path: z.string().describe("Path to the directory to create"),
2054
2155
  recursive: z.boolean().default(true).describe("Create parent directories if they don't exist")
2055
- })).implementSafe(async (input) => {
2056
- await promises.mkdir(input.path, { recursive: input.recursive });
2057
- return {
2058
- path: input.path,
2059
- message: "Directory created successfully"
2060
- };
2061
- }).build();
2062
- var directoryDelete = toolBuilder().name("directory-delete").description("Delete a directory. Can optionally delete non-empty directories recursively.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "delete", "remove", "filesystem"]).schema(z.object({
2156
+ });
2157
+ var directoryDeleteSchema = z.object({
2063
2158
  path: z.string().describe("Path to the directory to delete"),
2064
2159
  recursive: z.boolean().default(false).describe("Delete directory and all its contents")
2065
- })).implementSafe(async (input) => {
2066
- await promises.rm(input.path, { recursive: input.recursive, force: false });
2067
- return {
2068
- path: input.path,
2069
- message: "Directory deleted successfully"
2070
- };
2071
- }).build();
2072
- var fileSearch = toolBuilder().name("file-search").description("Search for files by name pattern in a directory. Supports wildcards and recursive search.").category(ToolCategory.FILE_SYSTEM).tags(["file", "search", "find", "filesystem"]).schema(z.object({
2160
+ });
2161
+ var fileSearchSchema = z.object({
2073
2162
  directory: z.string().describe("Directory to search in"),
2074
2163
  pattern: z.string().describe("File name pattern to search for (supports * wildcard)"),
2075
2164
  recursive: z.boolean().default(true).describe("Search in subdirectories"),
2076
2165
  caseSensitive: z.boolean().default(false).describe("Case-sensitive pattern matching")
2077
- })).implementSafe(async (input) => {
2078
- const searchFiles = async (dir) => {
2079
- const entries = await promises.readdir(dir, { withFileTypes: true });
2080
- const matches2 = [];
2081
- const regexPattern = input.pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
2082
- const regex = new RegExp(`^${regexPattern}$`, input.caseSensitive ? "" : "i");
2083
- for (const entry of entries) {
2084
- const fullPath = path3.join(dir, entry.name);
2085
- if (entry.isFile() && regex.test(entry.name)) {
2086
- matches2.push(fullPath);
2166
+ });
2167
+ function createDirectoryListTool(defaultRecursive = false, defaultIncludeDetails = false) {
2168
+ return toolBuilder().name("directory-list").description("List all files and directories in a directory. Can optionally include file details and filter by extension.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "list", "files", "filesystem"]).schema(directoryListSchema).implementSafe(async (input) => {
2169
+ const listFiles = async (dir, recursive2) => {
2170
+ const entries = await promises.readdir(dir, { withFileTypes: true });
2171
+ const files2 = [];
2172
+ for (const entry of entries) {
2173
+ const fullPath = path7.join(dir, entry.name);
2174
+ const relativePath = path7.relative(input.path, fullPath);
2175
+ if (input.extension && !entry.name.endsWith(input.extension)) {
2176
+ if (!entry.isDirectory() || !recursive2) {
2177
+ continue;
2178
+ }
2179
+ }
2180
+ if (input.includeDetails) {
2181
+ const stats = await promises.stat(fullPath);
2182
+ files2.push({
2183
+ name: entry.name,
2184
+ path: relativePath,
2185
+ fullPath,
2186
+ isFile: entry.isFile(),
2187
+ isDirectory: entry.isDirectory(),
2188
+ size: stats.size,
2189
+ modified: stats.mtime.toISOString()
2190
+ });
2191
+ } else {
2192
+ files2.push({
2193
+ name: entry.name,
2194
+ path: relativePath,
2195
+ isFile: entry.isFile(),
2196
+ isDirectory: entry.isDirectory()
2197
+ });
2198
+ }
2199
+ if (recursive2 && entry.isDirectory()) {
2200
+ const subFiles = await listFiles(fullPath, true);
2201
+ files2.push(...subFiles);
2202
+ }
2087
2203
  }
2088
- if (input.recursive && entry.isDirectory()) {
2089
- const subMatches = await searchFiles(fullPath);
2090
- matches2.push(...subMatches);
2204
+ return files2;
2205
+ };
2206
+ const recursive = input.recursive ?? defaultRecursive;
2207
+ const files = await listFiles(input.path, recursive);
2208
+ return {
2209
+ path: input.path,
2210
+ files,
2211
+ count: files.length
2212
+ };
2213
+ }).build();
2214
+ }
2215
+ function createDirectoryCreateTool(defaultRecursive = true) {
2216
+ return toolBuilder().name("directory-create").description("Create a new directory. Can optionally create parent directories if they don't exist.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "create", "mkdir", "filesystem"]).schema(directoryCreateSchema).implementSafe(async (input) => {
2217
+ const recursive = input.recursive ?? defaultRecursive;
2218
+ await promises.mkdir(input.path, { recursive });
2219
+ return {
2220
+ path: input.path,
2221
+ message: "Directory created successfully"
2222
+ };
2223
+ }).build();
2224
+ }
2225
+ function createDirectoryDeleteTool(defaultRecursive = false) {
2226
+ return toolBuilder().name("directory-delete").description("Delete a directory. Can optionally delete non-empty directories recursively.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "delete", "remove", "filesystem"]).schema(directoryDeleteSchema).implementSafe(async (input) => {
2227
+ const recursive = input.recursive ?? defaultRecursive;
2228
+ await promises.rm(input.path, { recursive, force: false });
2229
+ return {
2230
+ path: input.path,
2231
+ message: "Directory deleted successfully"
2232
+ };
2233
+ }).build();
2234
+ }
2235
+ function createFileSearchTool(defaultRecursive = true, defaultCaseSensitive = false) {
2236
+ return toolBuilder().name("file-search").description("Search for files by name pattern in a directory. Supports wildcards and recursive search.").category(ToolCategory.FILE_SYSTEM).tags(["file", "search", "find", "filesystem"]).schema(fileSearchSchema).implementSafe(async (input) => {
2237
+ const recursive = input.recursive ?? defaultRecursive;
2238
+ const caseSensitive = input.caseSensitive ?? defaultCaseSensitive;
2239
+ const searchFiles = async (dir) => {
2240
+ const entries = await promises.readdir(dir, { withFileTypes: true });
2241
+ const matches2 = [];
2242
+ const regexPattern = input.pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
2243
+ const regex = new RegExp(`^${regexPattern}$`, caseSensitive ? "" : "i");
2244
+ for (const entry of entries) {
2245
+ const fullPath = path7.join(dir, entry.name);
2246
+ if (entry.isFile() && regex.test(entry.name)) {
2247
+ matches2.push(fullPath);
2248
+ }
2249
+ if (recursive && entry.isDirectory()) {
2250
+ const subMatches = await searchFiles(fullPath);
2251
+ matches2.push(...subMatches);
2252
+ }
2091
2253
  }
2092
- }
2093
- return matches2;
2094
- };
2095
- const matches = await searchFiles(input.directory);
2096
- return {
2097
- directory: input.directory,
2098
- pattern: input.pattern,
2099
- matches,
2100
- count: matches.length
2101
- };
2102
- }).build();
2103
- var pathJoin = toolBuilder().name("path-join").description("Join multiple path segments into a single path. Handles platform-specific separators.").category(ToolCategory.FILE_SYSTEM).tags(["path", "join", "filesystem"]).schema(z.object({
2254
+ return matches2;
2255
+ };
2256
+ const matches = await searchFiles(input.directory);
2257
+ return {
2258
+ directory: input.directory,
2259
+ pattern: input.pattern,
2260
+ matches,
2261
+ count: matches.length
2262
+ };
2263
+ }).build();
2264
+ }
2265
+
2266
+ // src/file/directory/index.ts
2267
+ var directoryList = createDirectoryListTool();
2268
+ var directoryCreate = createDirectoryCreateTool();
2269
+ var directoryDelete = createDirectoryDeleteTool();
2270
+ var fileSearch = createFileSearchTool();
2271
+ var directoryOperationTools = [
2272
+ directoryList,
2273
+ directoryCreate,
2274
+ directoryDelete,
2275
+ fileSearch
2276
+ ];
2277
+ function createDirectoryOperationTools(config = {}) {
2278
+ const {
2279
+ defaultRecursive = false,
2280
+ defaultIncludeDetails = false,
2281
+ defaultCaseSensitive = false
2282
+ } = config;
2283
+ return [
2284
+ createDirectoryListTool(defaultRecursive, defaultIncludeDetails),
2285
+ createDirectoryCreateTool(true),
2286
+ // Always default to true for create
2287
+ createDirectoryDeleteTool(false),
2288
+ // Always default to false for delete (safety)
2289
+ createFileSearchTool(defaultRecursive, defaultCaseSensitive)
2290
+ ];
2291
+ }
2292
+ var pathJoinSchema = z.object({
2104
2293
  segments: z.array(z.string().describe("String value")).describe("Path segments to join")
2105
- })).implement(async (input) => {
2106
- const joined = path3.join(...input.segments);
2107
- return {
2108
- path: joined,
2109
- segments: input.segments
2110
- };
2111
- }).build();
2112
- var pathResolve = toolBuilder().name("path-resolve").description("Resolve a sequence of paths into an absolute path. Resolves relative paths from the current working directory.").category(ToolCategory.FILE_SYSTEM).tags(["path", "resolve", "absolute", "filesystem"]).schema(z.object({
2294
+ });
2295
+ var pathResolveSchema = z.object({
2113
2296
  paths: z.array(z.string().describe("String value")).describe("Paths to resolve")
2114
- })).implement(async (input) => {
2115
- const resolved = path3.resolve(...input.paths);
2116
- return {
2117
- path: resolved,
2118
- isAbsolute: path3.isAbsolute(resolved)
2119
- };
2120
- }).build();
2121
- var pathParse = toolBuilder().name("path-parse").description("Parse a file path into its components (directory, filename, extension, etc.).").category(ToolCategory.FILE_SYSTEM).tags(["path", "parse", "filesystem"]).schema(z.object({
2297
+ });
2298
+ var pathParseSchema = z.object({
2122
2299
  path: z.string().describe("File path to parse")
2123
- })).implement(async (input) => {
2124
- const parsed = path3.parse(input.path);
2125
- return {
2126
- root: parsed.root,
2127
- dir: parsed.dir,
2128
- base: parsed.base,
2129
- name: parsed.name,
2130
- ext: parsed.ext,
2131
- isAbsolute: path3.isAbsolute(input.path)
2132
- };
2133
- }).build();
2134
- var pathBasename = toolBuilder().name("path-basename").description("Get the last portion of a path (filename with extension). Optionally remove the extension.").category(ToolCategory.FILE_SYSTEM).tags(["path", "basename", "filename", "filesystem"]).schema(z.object({
2300
+ });
2301
+ var pathBasenameSchema = z.object({
2135
2302
  path: z.string().describe("File path"),
2136
2303
  removeExtension: z.boolean().default(false).describe("Remove the file extension")
2137
- })).implement(async (input) => {
2138
- const basename2 = input.removeExtension ? path3.basename(input.path, path3.extname(input.path)) : path3.basename(input.path);
2139
- return {
2140
- basename: basename2,
2141
- extension: path3.extname(input.path)
2142
- };
2143
- }).build();
2144
- var pathDirname = toolBuilder().name("path-dirname").description("Get the directory name of a path (everything except the last portion).").category(ToolCategory.FILE_SYSTEM).tags(["path", "dirname", "directory", "filesystem"]).schema(z.object({
2304
+ });
2305
+ var pathDirnameSchema = z.object({
2145
2306
  path: z.string().describe("File path")
2146
- })).implement(async (input) => {
2147
- const dirname3 = path3.dirname(input.path);
2148
- return {
2149
- dirname: dirname3,
2150
- basename: path3.basename(input.path)
2151
- };
2152
- }).build();
2153
- var pathExtension = toolBuilder().name("path-extension").description('Get the file extension from a path (including the dot, e.g., ".txt").').category(ToolCategory.FILE_SYSTEM).tags(["path", "extension", "ext", "filesystem"]).schema(z.object({
2307
+ });
2308
+ var pathExtensionSchema = z.object({
2154
2309
  path: z.string().describe("File path")
2155
- })).implement(async (input) => {
2156
- const ext = path3.extname(input.path);
2157
- return {
2158
- extension: ext,
2159
- hasExtension: ext.length > 0,
2160
- filename: path3.basename(input.path, ext)
2161
- };
2162
- }).build();
2163
- var pathRelative = toolBuilder().name("path-relative").description("Get the relative path from one path to another.").category(ToolCategory.FILE_SYSTEM).tags(["path", "relative", "filesystem"]).schema(z.object({
2310
+ });
2311
+ var pathRelativeSchema = z.object({
2164
2312
  from: z.string().describe("Source path"),
2165
2313
  to: z.string().describe("Destination path")
2166
- })).implement(async (input) => {
2167
- const relative3 = path3.relative(input.from, input.to);
2168
- return {
2169
- relativePath: relative3,
2170
- from: input.from,
2171
- to: input.to
2172
- };
2173
- }).build();
2174
- var pathNormalize = toolBuilder().name("path-normalize").description('Normalize a path by resolving ".." and "." segments and removing duplicate separators.').category(ToolCategory.FILE_SYSTEM).tags(["path", "normalize", "filesystem"]).schema(z.object({
2314
+ });
2315
+ var pathNormalizeSchema = z.object({
2175
2316
  path: z.string().describe("Path to normalize")
2176
- })).implement(async (input) => {
2177
- const normalized = path3.normalize(input.path);
2178
- return {
2179
- normalized,
2180
- original: input.path
2181
- };
2182
- }).build();
2183
- var currentDateTime = toolBuilder().name("current-date-time").description("Get the current date and time in various formats (ISO, Unix timestamp, formatted string).").category(ToolCategory.UTILITY).tags(["date", "time", "now", "current"]).schema(z.object({
2317
+ });
2318
+ function createPathJoinTool() {
2319
+ return toolBuilder().name("path-join").description("Join multiple path segments into a single path. Handles platform-specific separators.").category(ToolCategory.FILE_SYSTEM).tags(["path", "join", "filesystem"]).schema(pathJoinSchema).implement(async (input) => {
2320
+ const joined = path7.join(...input.segments);
2321
+ return {
2322
+ path: joined,
2323
+ segments: input.segments
2324
+ };
2325
+ }).build();
2326
+ }
2327
+ function createPathResolveTool() {
2328
+ return toolBuilder().name("path-resolve").description("Resolve a sequence of paths into an absolute path. Resolves relative paths from the current working directory.").category(ToolCategory.FILE_SYSTEM).tags(["path", "resolve", "absolute", "filesystem"]).schema(pathResolveSchema).implement(async (input) => {
2329
+ const resolved = path7.resolve(...input.paths);
2330
+ return {
2331
+ path: resolved,
2332
+ isAbsolute: path7.isAbsolute(resolved)
2333
+ };
2334
+ }).build();
2335
+ }
2336
+ function createPathParseTool() {
2337
+ return toolBuilder().name("path-parse").description("Parse a file path into its components (directory, filename, extension, etc.).").category(ToolCategory.FILE_SYSTEM).tags(["path", "parse", "filesystem"]).schema(pathParseSchema).implement(async (input) => {
2338
+ const parsed = path7.parse(input.path);
2339
+ return {
2340
+ root: parsed.root,
2341
+ dir: parsed.dir,
2342
+ base: parsed.base,
2343
+ name: parsed.name,
2344
+ ext: parsed.ext,
2345
+ isAbsolute: path7.isAbsolute(input.path)
2346
+ };
2347
+ }).build();
2348
+ }
2349
+ function createPathBasenameTool() {
2350
+ return toolBuilder().name("path-basename").description("Get the last portion of a path (filename with extension). Optionally remove the extension.").category(ToolCategory.FILE_SYSTEM).tags(["path", "basename", "filename", "filesystem"]).schema(pathBasenameSchema).implement(async (input) => {
2351
+ const basename4 = input.removeExtension ? path7.basename(input.path, path7.extname(input.path)) : path7.basename(input.path);
2352
+ return {
2353
+ basename: basename4,
2354
+ extension: path7.extname(input.path)
2355
+ };
2356
+ }).build();
2357
+ }
2358
+ function createPathDirnameTool() {
2359
+ return toolBuilder().name("path-dirname").description("Get the directory name of a path (everything except the last portion).").category(ToolCategory.FILE_SYSTEM).tags(["path", "dirname", "directory", "filesystem"]).schema(pathDirnameSchema).implement(async (input) => {
2360
+ const dirname3 = path7.dirname(input.path);
2361
+ return {
2362
+ dirname: dirname3,
2363
+ basename: path7.basename(input.path)
2364
+ };
2365
+ }).build();
2366
+ }
2367
+ function createPathExtensionTool() {
2368
+ return toolBuilder().name("path-extension").description('Get the file extension from a path (including the dot, e.g., ".txt").').category(ToolCategory.FILE_SYSTEM).tags(["path", "extension", "ext", "filesystem"]).schema(pathExtensionSchema).implement(async (input) => {
2369
+ const ext = path7.extname(input.path);
2370
+ return {
2371
+ extension: ext,
2372
+ hasExtension: ext.length > 0,
2373
+ filename: path7.basename(input.path, ext)
2374
+ };
2375
+ }).build();
2376
+ }
2377
+ function createPathRelativeTool() {
2378
+ return toolBuilder().name("path-relative").description("Get the relative path from one path to another.").category(ToolCategory.FILE_SYSTEM).tags(["path", "relative", "filesystem"]).schema(pathRelativeSchema).implement(async (input) => {
2379
+ const relative3 = path7.relative(input.from, input.to);
2380
+ return {
2381
+ relativePath: relative3,
2382
+ from: input.from,
2383
+ to: input.to
2384
+ };
2385
+ }).build();
2386
+ }
2387
+ function createPathNormalizeTool() {
2388
+ return toolBuilder().name("path-normalize").description('Normalize a path by resolving ".." and "." segments and removing duplicate separators.').category(ToolCategory.FILE_SYSTEM).tags(["path", "normalize", "filesystem"]).schema(pathNormalizeSchema).implement(async (input) => {
2389
+ const normalized = path7.normalize(input.path);
2390
+ return {
2391
+ normalized,
2392
+ original: input.path
2393
+ };
2394
+ }).build();
2395
+ }
2396
+
2397
+ // src/file/path/index.ts
2398
+ var pathJoin = createPathJoinTool();
2399
+ var pathResolve = createPathResolveTool();
2400
+ var pathParse = createPathParseTool();
2401
+ var pathBasename = createPathBasenameTool();
2402
+ var pathDirname = createPathDirnameTool();
2403
+ var pathExtension = createPathExtensionTool();
2404
+ var pathRelative = createPathRelativeTool();
2405
+ var pathNormalize = createPathNormalizeTool();
2406
+ var pathUtilityTools = [
2407
+ pathJoin,
2408
+ pathResolve,
2409
+ pathParse,
2410
+ pathBasename,
2411
+ pathDirname,
2412
+ pathExtension,
2413
+ pathRelative,
2414
+ pathNormalize
2415
+ ];
2416
+ function createPathUtilityTools(config = {}) {
2417
+ return [
2418
+ createPathJoinTool(),
2419
+ createPathResolveTool(),
2420
+ createPathParseTool(),
2421
+ createPathBasenameTool(),
2422
+ createPathDirnameTool(),
2423
+ createPathExtensionTool(),
2424
+ createPathRelativeTool(),
2425
+ createPathNormalizeTool()
2426
+ ];
2427
+ }
2428
+ var CurrentDateTimeSchema = z.object({
2184
2429
  format: z.enum(["iso", "unix", "custom"]).default("iso").describe("Output format"),
2185
2430
  customFormat: z.string().optional().describe('Custom format string (e.g., "yyyy-MM-dd HH:mm:ss") when format is "custom"'),
2186
2431
  timezone: z.string().optional().describe('Timezone (e.g., "America/New_York")')
2187
- })).implement(async (input) => {
2188
- const now = /* @__PURE__ */ new Date();
2189
- let formatted;
2190
- if (input.format === "iso") {
2191
- formatted = now.toISOString();
2192
- } else if (input.format === "unix") {
2193
- formatted = Math.floor(now.getTime() / 1e3);
2194
- } else if (input.format === "custom" && input.customFormat) {
2195
- formatted = format(now, input.customFormat);
2196
- } else {
2197
- formatted = now.toISOString();
2198
- }
2199
- return {
2200
- formatted,
2201
- iso: now.toISOString(),
2202
- unix: Math.floor(now.getTime() / 1e3),
2203
- year: now.getFullYear(),
2204
- month: now.getMonth() + 1,
2205
- day: now.getDate(),
2206
- hour: now.getHours(),
2207
- minute: now.getMinutes(),
2208
- second: now.getSeconds()
2209
- };
2210
- }).build();
2211
- var dateFormatter = toolBuilder().name("date-formatter").description("Format a date string or timestamp into a different format. Supports ISO, Unix timestamps, and custom formats.").category(ToolCategory.UTILITY).tags(["date", "format", "time"]).schema(z.object({
2432
+ });
2433
+ var DateFormatterSchema = z.object({
2212
2434
  date: z.string().describe("Date string or Unix timestamp to format"),
2213
2435
  outputFormat: z.string().describe('Output format string (e.g., "yyyy-MM-dd", "MMM dd, yyyy")'),
2214
2436
  inputFormat: z.string().optional().describe("Input format string (optional, auto-detected if not provided)")
2215
- })).implement(async (input) => {
2216
- try {
2217
- let date;
2218
- if (input.inputFormat) {
2219
- date = parse$1(input.date, input.inputFormat, /* @__PURE__ */ new Date());
2220
- } else if (!isNaN(Number(input.date))) {
2221
- date = new Date(Number(input.date) * 1e3);
2437
+ });
2438
+ var DateArithmeticSchema = z.object({
2439
+ date: z.string().describe("Starting date (ISO string or Unix timestamp)"),
2440
+ operation: z.enum(["add", "subtract"]).describe("Operation to perform"),
2441
+ amount: z.number().describe("Amount to add or subtract"),
2442
+ unit: z.enum(["years", "months", "weeks", "days", "hours", "minutes", "seconds"]).describe("Time unit")
2443
+ });
2444
+ var DateDifferenceSchema = z.object({
2445
+ startDate: z.string().describe("Start date (ISO string or Unix timestamp)"),
2446
+ endDate: z.string().describe("End date (ISO string or Unix timestamp)"),
2447
+ unit: z.enum(["days", "hours", "minutes"]).default("days").describe("Unit for the difference")
2448
+ });
2449
+ var DateComparisonSchema = z.object({
2450
+ date1: z.string().describe("First date to compare"),
2451
+ date2: z.string().describe("Second date to compare")
2452
+ });
2453
+
2454
+ // src/utility/date-time/tools/current-date-time.ts
2455
+ function createCurrentDateTimeTool() {
2456
+ return toolBuilder().name("current-date-time").description("Get the current date and time in various formats (ISO, Unix timestamp, formatted string).").category(ToolCategory.UTILITY).tags(["date", "time", "now", "current"]).schema(CurrentDateTimeSchema).implement(async (input) => {
2457
+ const now = /* @__PURE__ */ new Date();
2458
+ let formatted;
2459
+ if (input.format === "iso") {
2460
+ formatted = now.toISOString();
2461
+ } else if (input.format === "unix") {
2462
+ formatted = Math.floor(now.getTime() / 1e3);
2463
+ } else if (input.format === "custom" && input.customFormat) {
2464
+ formatted = format(now, input.customFormat);
2222
2465
  } else {
2223
- date = new Date(input.date);
2466
+ formatted = now.toISOString();
2224
2467
  }
2225
- if (!isValid(date)) {
2226
- return {
2227
- success: false,
2228
- error: "Invalid date"
2229
- };
2230
- }
2231
- const formatted = format(date, input.outputFormat);
2232
2468
  return {
2233
- success: true,
2234
2469
  formatted,
2235
- iso: date.toISOString()
2470
+ iso: now.toISOString(),
2471
+ unix: Math.floor(now.getTime() / 1e3),
2472
+ year: now.getFullYear(),
2473
+ month: now.getMonth() + 1,
2474
+ day: now.getDate(),
2475
+ hour: now.getHours(),
2476
+ minute: now.getMinutes(),
2477
+ second: now.getSeconds()
2236
2478
  };
2237
- } catch (error) {
2238
- return {
2239
- success: false,
2240
- error: error instanceof Error ? error.message : "Failed to format date"
2241
- };
2242
- }
2243
- }).build();
2244
- var dateArithmetic = toolBuilder().name("date-arithmetic").description("Add or subtract time from a date. Supports years, months, weeks, days, hours, minutes, and seconds.").category(ToolCategory.UTILITY).tags(["date", "time", "add", "subtract", "arithmetic"]).schema(z.object({
2245
- date: z.string().describe("Starting date (ISO string or Unix timestamp)"),
2246
- operation: z.enum(["add", "subtract"]).describe("Operation to perform"),
2247
- amount: z.number().describe("Amount to add or subtract"),
2248
- unit: z.enum(["years", "months", "weeks", "days", "hours", "minutes", "seconds"]).describe("Time unit")
2249
- })).implement(async (input) => {
2250
- try {
2251
- const date = new Date(input.date);
2252
- if (!isValid(date)) {
2479
+ }).build();
2480
+ }
2481
+ function createDateFormatterTool() {
2482
+ return toolBuilder().name("date-formatter").description("Format a date string or timestamp into a different format. Supports ISO, Unix timestamps, and custom formats.").category(ToolCategory.UTILITY).tags(["date", "format", "time"]).schema(DateFormatterSchema).implement(async (input) => {
2483
+ try {
2484
+ let date;
2485
+ if (input.inputFormat) {
2486
+ date = parse$1(input.date, input.inputFormat, /* @__PURE__ */ new Date());
2487
+ } else if (!isNaN(Number(input.date))) {
2488
+ date = new Date(Number(input.date) * 1e3);
2489
+ } else {
2490
+ date = new Date(input.date);
2491
+ }
2492
+ if (!isValid(date)) {
2493
+ return {
2494
+ success: false,
2495
+ error: "Invalid date"
2496
+ };
2497
+ }
2498
+ const formatted = format(date, input.outputFormat);
2499
+ return {
2500
+ success: true,
2501
+ formatted,
2502
+ iso: date.toISOString()
2503
+ };
2504
+ } catch (error) {
2253
2505
  return {
2254
2506
  success: false,
2255
- error: "Invalid date"
2507
+ error: error instanceof Error ? error.message : "Failed to format date"
2256
2508
  };
2257
2509
  }
2258
- const duration = { [input.unit]: input.amount };
2259
- const result = input.operation === "add" ? add(date, duration) : sub(date, duration);
2260
- return {
2261
- success: true,
2262
- result: result.toISOString(),
2263
- unix: Math.floor(result.getTime() / 1e3)
2264
- };
2265
- } catch (error) {
2266
- return {
2267
- success: false,
2268
- error: error instanceof Error ? error.message : "Failed to perform date arithmetic"
2269
- };
2270
- }
2271
- }).build();
2272
- var dateDifference = toolBuilder().name("date-difference").description("Calculate the difference between two dates in various units (days, hours, minutes).").category(ToolCategory.UTILITY).tags(["date", "time", "difference", "duration"]).schema(z.object({
2273
- startDate: z.string().describe("Start date (ISO string or Unix timestamp)"),
2274
- endDate: z.string().describe("End date (ISO string or Unix timestamp)"),
2275
- unit: z.enum(["days", "hours", "minutes"]).default("days").describe("Unit for the difference")
2276
- })).implement(async (input) => {
2277
- try {
2278
- const start = new Date(input.startDate);
2279
- const end = new Date(input.endDate);
2280
- if (!isValid(start) || !isValid(end)) {
2510
+ }).build();
2511
+ }
2512
+ function createDateArithmeticTool() {
2513
+ return toolBuilder().name("date-arithmetic").description("Add or subtract time from a date. Supports years, months, weeks, days, hours, minutes, and seconds.").category(ToolCategory.UTILITY).tags(["date", "time", "add", "subtract", "arithmetic"]).schema(DateArithmeticSchema).implement(async (input) => {
2514
+ try {
2515
+ const date = new Date(input.date);
2516
+ if (!isValid(date)) {
2517
+ return {
2518
+ success: false,
2519
+ error: "Invalid date"
2520
+ };
2521
+ }
2522
+ const duration = { [input.unit]: input.amount };
2523
+ const result = input.operation === "add" ? add(date, duration) : sub(date, duration);
2524
+ return {
2525
+ success: true,
2526
+ result: result.toISOString(),
2527
+ unix: Math.floor(result.getTime() / 1e3)
2528
+ };
2529
+ } catch (error) {
2281
2530
  return {
2282
2531
  success: false,
2283
- error: "Invalid date(s)"
2532
+ error: error instanceof Error ? error.message : "Failed to perform date arithmetic"
2284
2533
  };
2285
2534
  }
2286
- let difference;
2287
- if (input.unit === "days") {
2288
- difference = differenceInDays(end, start);
2289
- } else if (input.unit === "hours") {
2290
- difference = differenceInHours(end, start);
2291
- } else {
2292
- difference = differenceInMinutes(end, start);
2535
+ }).build();
2536
+ }
2537
+ function createDateDifferenceTool() {
2538
+ return toolBuilder().name("date-difference").description("Calculate the difference between two dates in various units (days, hours, minutes).").category(ToolCategory.UTILITY).tags(["date", "time", "difference", "duration"]).schema(DateDifferenceSchema).implement(async (input) => {
2539
+ try {
2540
+ const start = new Date(input.startDate);
2541
+ const end = new Date(input.endDate);
2542
+ if (!isValid(start) || !isValid(end)) {
2543
+ return {
2544
+ success: false,
2545
+ error: "Invalid date(s)"
2546
+ };
2547
+ }
2548
+ let difference;
2549
+ if (input.unit === "days") {
2550
+ difference = differenceInDays(end, start);
2551
+ } else if (input.unit === "hours") {
2552
+ difference = differenceInHours(end, start);
2553
+ } else {
2554
+ difference = differenceInMinutes(end, start);
2555
+ }
2556
+ return {
2557
+ success: true,
2558
+ difference,
2559
+ unit: input.unit,
2560
+ startDate: start.toISOString(),
2561
+ endDate: end.toISOString()
2562
+ };
2563
+ } catch (error) {
2564
+ return {
2565
+ success: false,
2566
+ error: error instanceof Error ? error.message : "Failed to calculate date difference"
2567
+ };
2293
2568
  }
2294
- return {
2295
- success: true,
2296
- difference,
2297
- unit: input.unit,
2298
- startDate: start.toISOString(),
2299
- endDate: end.toISOString()
2300
- };
2301
- } catch (error) {
2302
- return {
2303
- success: false,
2304
- error: error instanceof Error ? error.message : "Failed to calculate date difference"
2305
- };
2306
- }
2307
- }).build();
2308
- var dateComparison = toolBuilder().name("date-comparison").description("Compare two dates to determine if one is before, after, or equal to the other.").category(ToolCategory.UTILITY).tags(["date", "time", "compare", "comparison"]).schema(z.object({
2309
- date1: z.string().describe("First date to compare"),
2310
- date2: z.string().describe("Second date to compare")
2311
- })).implement(async (input) => {
2312
- try {
2313
- const d1 = new Date(input.date1);
2314
- const d2 = new Date(input.date2);
2315
- if (!isValid(d1) || !isValid(d2)) {
2569
+ }).build();
2570
+ }
2571
+ function createDateComparisonTool() {
2572
+ return toolBuilder().name("date-comparison").description("Compare two dates to determine if one is before, after, or equal to the other.").category(ToolCategory.UTILITY).tags(["date", "time", "compare", "comparison"]).schema(DateComparisonSchema).implement(async (input) => {
2573
+ try {
2574
+ const d1 = new Date(input.date1);
2575
+ const d2 = new Date(input.date2);
2576
+ if (!isValid(d1) || !isValid(d2)) {
2577
+ return {
2578
+ success: false,
2579
+ error: "Invalid date(s)"
2580
+ };
2581
+ }
2582
+ return {
2583
+ success: true,
2584
+ date1IsBefore: isBefore(d1, d2),
2585
+ date1IsAfter: isAfter(d1, d2),
2586
+ datesAreEqual: d1.getTime() === d2.getTime(),
2587
+ date1: d1.toISOString(),
2588
+ date2: d2.toISOString()
2589
+ };
2590
+ } catch (error) {
2316
2591
  return {
2317
2592
  success: false,
2318
- error: "Invalid date(s)"
2593
+ error: error instanceof Error ? error.message : "Failed to compare dates"
2319
2594
  };
2320
2595
  }
2321
- return {
2322
- success: true,
2323
- date1IsBefore: isBefore(d1, d2),
2324
- date1IsAfter: isAfter(d1, d2),
2325
- datesAreEqual: d1.getTime() === d2.getTime(),
2326
- date1: d1.toISOString(),
2327
- date2: d2.toISOString()
2328
- };
2329
- } catch (error) {
2330
- return {
2331
- success: false,
2332
- error: error instanceof Error ? error.message : "Failed to compare dates"
2333
- };
2334
- }
2335
- }).build();
2336
- var stringCaseConverter = toolBuilder().name("string-case-converter").description("Convert string to different cases: lowercase, uppercase, title case, camel case, snake case, kebab case.").category(ToolCategory.UTILITY).tags(["string", "case", "convert", "transform"]).schema(z.object({
2596
+ }).build();
2597
+ }
2598
+
2599
+ // src/utility/date-time/index.ts
2600
+ var currentDateTime = createCurrentDateTimeTool();
2601
+ var dateFormatter = createDateFormatterTool();
2602
+ var dateArithmetic = createDateArithmeticTool();
2603
+ var dateDifference = createDateDifferenceTool();
2604
+ var dateComparison = createDateComparisonTool();
2605
+ var dateTimeTools = [
2606
+ currentDateTime,
2607
+ dateFormatter,
2608
+ dateArithmetic,
2609
+ dateDifference,
2610
+ dateComparison
2611
+ ];
2612
+ function createDateTimeTools(config = {}) {
2613
+ return [
2614
+ createCurrentDateTimeTool(),
2615
+ createDateFormatterTool(),
2616
+ createDateArithmeticTool(),
2617
+ createDateDifferenceTool(),
2618
+ createDateComparisonTool()
2619
+ ];
2620
+ }
2621
+ var StringCaseConverterSchema = z.object({
2337
2622
  text: z.string().describe("Text to convert"),
2338
2623
  targetCase: z.enum(["lowercase", "uppercase", "title", "camel", "snake", "kebab", "pascal"]).describe("Target case format")
2339
- })).implement(async (input) => {
2340
- let result;
2341
- switch (input.targetCase) {
2342
- case "lowercase":
2343
- result = input.text.toLowerCase();
2344
- break;
2345
- case "uppercase":
2346
- result = input.text.toUpperCase();
2347
- break;
2348
- case "title":
2349
- result = input.text.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
2350
- break;
2351
- case "camel":
2352
- result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase());
2353
- break;
2354
- case "snake":
2355
- result = input.text.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
2356
- break;
2357
- case "kebab":
2358
- result = input.text.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2359
- break;
2360
- case "pascal":
2361
- result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toUpperCase());
2362
- break;
2363
- default:
2364
- result = input.text;
2365
- }
2366
- return {
2367
- original: input.text,
2368
- converted: result,
2369
- targetCase: input.targetCase
2370
- };
2371
- }).build();
2372
- var stringTrim = toolBuilder().name("string-trim").description("Remove whitespace from the beginning and/or end of a string. Supports trim, trim start, and trim end.").category(ToolCategory.UTILITY).tags(["string", "trim", "whitespace"]).schema(z.object({
2624
+ });
2625
+ var StringTrimSchema = z.object({
2373
2626
  text: z.string().describe("Text to trim"),
2374
2627
  mode: z.enum(["both", "start", "end"]).default("both").describe("Which side to trim"),
2375
2628
  characters: z.string().optional().describe("Optional custom characters to trim (default: whitespace)")
2376
- })).implement(async (input) => {
2377
- let result;
2378
- if (input.characters) {
2379
- const chars = input.characters.split("").map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
2380
- const regex = input.mode === "both" ? new RegExp(`^[${chars}]+|[${chars}]+$`, "g") : input.mode === "start" ? new RegExp(`^[${chars}]+`, "g") : new RegExp(`[${chars}]+$`, "g");
2381
- result = input.text.replace(regex, "");
2382
- } else {
2383
- result = input.mode === "both" ? input.text.trim() : input.mode === "start" ? input.text.trimStart() : input.text.trimEnd();
2384
- }
2385
- return {
2386
- original: input.text,
2387
- trimmed: result,
2388
- removed: input.text.length - result.length
2389
- };
2390
- }).build();
2391
- var stringReplace = toolBuilder().name("string-replace").description("Replace occurrences of a substring or pattern in a string. Supports regex patterns and global replacement.").category(ToolCategory.UTILITY).tags(["string", "replace", "substitute"]).schema(z.object({
2629
+ });
2630
+ var StringReplaceSchema = z.object({
2392
2631
  text: z.string().describe("Text to search in"),
2393
2632
  search: z.string().describe("String or regex pattern to search for"),
2394
2633
  replace: z.string().describe("Replacement string"),
2395
2634
  global: z.boolean().default(true).describe("Replace all occurrences (true) or just the first (false)"),
2396
2635
  caseInsensitive: z.boolean().default(false).describe("Case-insensitive search")
2397
- })).implement(async (input) => {
2398
- const flags = (input.global ? "g" : "") + (input.caseInsensitive ? "i" : "");
2399
- const regex = new RegExp(input.search, flags);
2400
- const result = input.text.replace(regex, input.replace);
2401
- const matches = input.text.match(regex);
2402
- const count = matches ? matches.length : 0;
2403
- return {
2404
- original: input.text,
2405
- result,
2406
- replacements: count
2407
- };
2408
- }).build();
2409
- var stringSplit = toolBuilder().name("string-split").description("Split a string into an array of substrings using a delimiter. Supports regex delimiters and limit.").category(ToolCategory.UTILITY).tags(["string", "split", "array"]).schema(z.object({
2636
+ });
2637
+ var StringSplitSchema = z.object({
2410
2638
  text: z.string().describe("Text to split"),
2411
2639
  delimiter: z.string().describe("Delimiter to split on (can be a regex pattern)"),
2412
2640
  limit: z.number().optional().describe("Maximum number of splits")
2413
- })).implement(async (input) => {
2414
- const parts = input.text.split(input.delimiter, input.limit);
2415
- return {
2416
- parts,
2417
- count: parts.length
2418
- };
2419
- }).build();
2420
- var stringJoin = toolBuilder().name("string-join").description("Join an array of strings into a single string with a separator.").category(ToolCategory.UTILITY).tags(["string", "join", "array"]).schema(z.object({
2641
+ });
2642
+ var StringJoinSchema = z.object({
2421
2643
  parts: z.array(z.string().describe("String value")).describe("Array of strings to join"),
2422
2644
  separator: z.string().default("").describe("Separator to use between parts")
2423
- })).implement(async (input) => {
2424
- const result = input.parts.join(input.separator);
2425
- return {
2426
- result,
2427
- partCount: input.parts.length,
2428
- length: result.length
2429
- };
2430
- }).build();
2431
- var stringSubstring = toolBuilder().name("string-substring").description("Extract a substring from a string using start and end positions.").category(ToolCategory.UTILITY).tags(["string", "substring", "slice"]).schema(z.object({
2645
+ });
2646
+ var StringSubstringSchema = z.object({
2432
2647
  text: z.string().describe("Source text"),
2433
2648
  start: z.number().describe("Start position (0-based)"),
2434
2649
  end: z.number().optional().describe("End position (optional, defaults to end of string)")
2435
- })).implement(async (input) => {
2436
- const result = input.text.substring(input.start, input.end);
2437
- return {
2438
- result,
2439
- length: result.length,
2440
- start: input.start,
2441
- end: input.end ?? input.text.length
2442
- };
2443
- }).build();
2444
- var stringLength = toolBuilder().name("string-length").description("Get the length of a string in characters, words, or lines.").category(ToolCategory.UTILITY).tags(["string", "length", "count"]).schema(z.object({
2650
+ });
2651
+ var StringLengthSchema = z.object({
2445
2652
  text: z.string().describe("Text to measure")
2446
- })).implement(async (input) => {
2447
- const words = input.text.trim().split(/\s+/).filter((w) => w.length > 0);
2448
- const lines = input.text.split("\n");
2449
- return {
2450
- characters: input.text.length,
2451
- words: words.length,
2452
- lines: lines.length
2453
- };
2454
- }).build();
2455
- var calculator = toolBuilder().name("calculator").description("Perform basic arithmetic operations: add, subtract, multiply, divide, power, modulo.").category(ToolCategory.UTILITY).tags(["math", "calculator", "arithmetic"]).schema(z.object({
2653
+ });
2654
+
2655
+ // src/utility/string/tools/string-case-converter.ts
2656
+ function createStringCaseConverterTool() {
2657
+ return toolBuilder().name("string-case-converter").description("Convert string to different cases: lowercase, uppercase, title case, camel case, snake case, kebab case.").category(ToolCategory.UTILITY).tags(["string", "case", "convert", "transform"]).schema(StringCaseConverterSchema).implement(async (input) => {
2658
+ let result;
2659
+ switch (input.targetCase) {
2660
+ case "lowercase":
2661
+ result = input.text.toLowerCase();
2662
+ break;
2663
+ case "uppercase":
2664
+ result = input.text.toUpperCase();
2665
+ break;
2666
+ case "title":
2667
+ result = input.text.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
2668
+ break;
2669
+ case "camel":
2670
+ result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase());
2671
+ break;
2672
+ case "snake":
2673
+ result = input.text.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
2674
+ break;
2675
+ case "kebab":
2676
+ result = input.text.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2677
+ break;
2678
+ case "pascal":
2679
+ result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toUpperCase());
2680
+ break;
2681
+ default:
2682
+ result = input.text;
2683
+ }
2684
+ return {
2685
+ original: input.text,
2686
+ converted: result,
2687
+ targetCase: input.targetCase
2688
+ };
2689
+ }).build();
2690
+ }
2691
+ function createStringTrimTool() {
2692
+ return toolBuilder().name("string-trim").description("Remove whitespace from the beginning and/or end of a string. Supports trim, trim start, and trim end.").category(ToolCategory.UTILITY).tags(["string", "trim", "whitespace"]).schema(StringTrimSchema).implement(async (input) => {
2693
+ let result;
2694
+ if (input.characters) {
2695
+ const chars = input.characters.split("").map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
2696
+ const regex = input.mode === "both" ? new RegExp(`^[${chars}]+|[${chars}]+$`, "g") : input.mode === "start" ? new RegExp(`^[${chars}]+`, "g") : new RegExp(`[${chars}]+$`, "g");
2697
+ result = input.text.replace(regex, "");
2698
+ } else {
2699
+ result = input.mode === "both" ? input.text.trim() : input.mode === "start" ? input.text.trimStart() : input.text.trimEnd();
2700
+ }
2701
+ return {
2702
+ original: input.text,
2703
+ trimmed: result,
2704
+ removed: input.text.length - result.length
2705
+ };
2706
+ }).build();
2707
+ }
2708
+ function createStringReplaceTool() {
2709
+ return toolBuilder().name("string-replace").description("Replace occurrences of a substring or pattern in a string. Supports regex patterns and global replacement.").category(ToolCategory.UTILITY).tags(["string", "replace", "substitute"]).schema(StringReplaceSchema).implement(async (input) => {
2710
+ const flags = (input.global ? "g" : "") + (input.caseInsensitive ? "i" : "");
2711
+ const regex = new RegExp(input.search, flags);
2712
+ const result = input.text.replace(regex, input.replace);
2713
+ const matches = input.text.match(regex);
2714
+ const count = matches ? matches.length : 0;
2715
+ return {
2716
+ original: input.text,
2717
+ result,
2718
+ replacements: count
2719
+ };
2720
+ }).build();
2721
+ }
2722
+ function createStringSplitTool() {
2723
+ return toolBuilder().name("string-split").description("Split a string into an array of substrings using a delimiter. Supports regex delimiters and limit.").category(ToolCategory.UTILITY).tags(["string", "split", "array"]).schema(StringSplitSchema).implement(async (input) => {
2724
+ const parts = input.text.split(input.delimiter, input.limit);
2725
+ return {
2726
+ parts,
2727
+ count: parts.length
2728
+ };
2729
+ }).build();
2730
+ }
2731
+ function createStringJoinTool() {
2732
+ return toolBuilder().name("string-join").description("Join an array of strings into a single string with a separator.").category(ToolCategory.UTILITY).tags(["string", "join", "array"]).schema(StringJoinSchema).implement(async (input) => {
2733
+ const result = input.parts.join(input.separator);
2734
+ return {
2735
+ result,
2736
+ partCount: input.parts.length,
2737
+ length: result.length
2738
+ };
2739
+ }).build();
2740
+ }
2741
+ function createStringSubstringTool() {
2742
+ return toolBuilder().name("string-substring").description("Extract a substring from a string using start and end positions.").category(ToolCategory.UTILITY).tags(["string", "substring", "slice"]).schema(StringSubstringSchema).implement(async (input) => {
2743
+ const result = input.text.substring(input.start, input.end);
2744
+ return {
2745
+ result,
2746
+ length: result.length,
2747
+ start: input.start,
2748
+ end: input.end ?? input.text.length
2749
+ };
2750
+ }).build();
2751
+ }
2752
+ function createStringLengthTool() {
2753
+ return toolBuilder().name("string-length").description("Get the length of a string in characters, words, or lines.").category(ToolCategory.UTILITY).tags(["string", "length", "count"]).schema(StringLengthSchema).implement(async (input) => {
2754
+ const words = input.text.trim().split(/\s+/).filter((w) => w.length > 0);
2755
+ const lines = input.text.split("\n");
2756
+ return {
2757
+ characters: input.text.length,
2758
+ words: words.length,
2759
+ lines: lines.length
2760
+ };
2761
+ }).build();
2762
+ }
2763
+
2764
+ // src/utility/string/index.ts
2765
+ var stringCaseConverter = createStringCaseConverterTool();
2766
+ var stringTrim = createStringTrimTool();
2767
+ var stringReplace = createStringReplaceTool();
2768
+ var stringSplit = createStringSplitTool();
2769
+ var stringJoin = createStringJoinTool();
2770
+ var stringSubstring = createStringSubstringTool();
2771
+ var stringLength = createStringLengthTool();
2772
+ var stringUtilityTools = [
2773
+ stringCaseConverter,
2774
+ stringTrim,
2775
+ stringReplace,
2776
+ stringSplit,
2777
+ stringJoin,
2778
+ stringSubstring,
2779
+ stringLength
2780
+ ];
2781
+ function createStringUtilityTools(config = {}) {
2782
+ return [
2783
+ createStringCaseConverterTool(),
2784
+ createStringTrimTool(),
2785
+ createStringReplaceTool(),
2786
+ createStringSplitTool(),
2787
+ createStringJoinTool(),
2788
+ createStringSubstringTool(),
2789
+ createStringLengthTool()
2790
+ ];
2791
+ }
2792
+ var CalculatorSchema = z.object({
2456
2793
  operation: z.enum(["add", "subtract", "multiply", "divide", "power", "modulo"]).describe("Mathematical operation to perform"),
2457
2794
  a: z.number().describe("First number"),
2458
2795
  b: z.number().describe("Second number")
2459
- })).implement(async (input) => {
2460
- let result;
2461
- switch (input.operation) {
2462
- case "add":
2463
- result = input.a + input.b;
2464
- break;
2465
- case "subtract":
2466
- result = input.a - input.b;
2467
- break;
2468
- case "multiply":
2469
- result = input.a * input.b;
2470
- break;
2471
- case "divide":
2472
- if (input.b === 0) {
2473
- return {
2474
- success: false,
2475
- error: "Division by zero"
2476
- };
2477
- }
2478
- result = input.a / input.b;
2479
- break;
2480
- case "power":
2481
- result = Math.pow(input.a, input.b);
2482
- break;
2483
- case "modulo":
2484
- result = input.a % input.b;
2485
- break;
2486
- default:
2487
- return {
2488
- success: false,
2489
- error: "Unknown operation"
2490
- };
2491
- }
2492
- return {
2493
- success: true,
2494
- result,
2495
- operation: input.operation,
2496
- a: input.a,
2497
- b: input.b
2498
- };
2499
- }).build();
2500
- var mathFunctions = toolBuilder().name("math-functions").description("Apply mathematical functions: sqrt, abs, round, floor, ceil, sin, cos, tan, log, exp.").category(ToolCategory.UTILITY).tags(["math", "functions", "trigonometry"]).schema(z.object({
2796
+ });
2797
+ var MathFunctionsSchema = z.object({
2501
2798
  function: z.enum(["sqrt", "abs", "round", "floor", "ceil", "sin", "cos", "tan", "log", "exp"]).describe("Mathematical function to apply"),
2502
2799
  value: z.number().describe("Input value")
2503
- })).implement(async (input) => {
2504
- let result;
2505
- try {
2506
- switch (input.function) {
2507
- case "sqrt":
2508
- result = Math.sqrt(input.value);
2509
- break;
2510
- case "abs":
2511
- result = Math.abs(input.value);
2512
- break;
2513
- case "round":
2514
- result = Math.round(input.value);
2515
- break;
2516
- case "floor":
2517
- result = Math.floor(input.value);
2518
- break;
2519
- case "ceil":
2520
- result = Math.ceil(input.value);
2800
+ });
2801
+ var RandomNumberSchema = z.object({
2802
+ min: z.number().default(0).describe("Minimum value (inclusive)"),
2803
+ max: z.number().default(1).describe("Maximum value (exclusive for decimals, inclusive for integers)"),
2804
+ integer: z.boolean().default(false).describe("Generate an integer (true) or decimal (false)")
2805
+ });
2806
+ var StatisticsSchema = z.object({
2807
+ numbers: z.array(z.number().describe("Number value")).describe("Array of numbers to analyze")
2808
+ });
2809
+
2810
+ // src/utility/math/tools/calculator.ts
2811
+ function createCalculatorTool() {
2812
+ return toolBuilder().name("calculator").description("Perform basic arithmetic operations: add, subtract, multiply, divide, power, modulo.").category(ToolCategory.UTILITY).tags(["math", "calculator", "arithmetic"]).schema(CalculatorSchema).implement(async (input) => {
2813
+ let result;
2814
+ switch (input.operation) {
2815
+ case "add":
2816
+ result = input.a + input.b;
2521
2817
  break;
2522
- case "sin":
2523
- result = Math.sin(input.value);
2818
+ case "subtract":
2819
+ result = input.a - input.b;
2524
2820
  break;
2525
- case "cos":
2526
- result = Math.cos(input.value);
2821
+ case "multiply":
2822
+ result = input.a * input.b;
2527
2823
  break;
2528
- case "tan":
2529
- result = Math.tan(input.value);
2824
+ case "divide":
2825
+ if (input.b === 0) {
2826
+ return {
2827
+ success: false,
2828
+ error: "Division by zero"
2829
+ };
2830
+ }
2831
+ result = input.a / input.b;
2530
2832
  break;
2531
- case "log":
2532
- result = Math.log(input.value);
2833
+ case "power":
2834
+ result = Math.pow(input.a, input.b);
2533
2835
  break;
2534
- case "exp":
2535
- result = Math.exp(input.value);
2836
+ case "modulo":
2837
+ result = input.a % input.b;
2536
2838
  break;
2537
2839
  default:
2538
2840
  return {
2539
2841
  success: false,
2540
- error: "Unknown function"
2842
+ error: "Unknown operation"
2541
2843
  };
2542
2844
  }
2543
- if (isNaN(result) || !isFinite(result)) {
2845
+ return {
2846
+ success: true,
2847
+ result,
2848
+ operation: input.operation,
2849
+ a: input.a,
2850
+ b: input.b
2851
+ };
2852
+ }).build();
2853
+ }
2854
+ function createMathFunctionsTool() {
2855
+ return toolBuilder().name("math-functions").description("Apply mathematical functions: sqrt, abs, round, floor, ceil, sin, cos, tan, log, exp.").category(ToolCategory.UTILITY).tags(["math", "functions", "trigonometry"]).schema(MathFunctionsSchema).implement(async (input) => {
2856
+ let result;
2857
+ try {
2858
+ switch (input.function) {
2859
+ case "sqrt":
2860
+ result = Math.sqrt(input.value);
2861
+ break;
2862
+ case "abs":
2863
+ result = Math.abs(input.value);
2864
+ break;
2865
+ case "round":
2866
+ result = Math.round(input.value);
2867
+ break;
2868
+ case "floor":
2869
+ result = Math.floor(input.value);
2870
+ break;
2871
+ case "ceil":
2872
+ result = Math.ceil(input.value);
2873
+ break;
2874
+ case "sin":
2875
+ result = Math.sin(input.value);
2876
+ break;
2877
+ case "cos":
2878
+ result = Math.cos(input.value);
2879
+ break;
2880
+ case "tan":
2881
+ result = Math.tan(input.value);
2882
+ break;
2883
+ case "log":
2884
+ result = Math.log(input.value);
2885
+ break;
2886
+ case "exp":
2887
+ result = Math.exp(input.value);
2888
+ break;
2889
+ default:
2890
+ return {
2891
+ success: false,
2892
+ error: "Unknown function"
2893
+ };
2894
+ }
2895
+ if (isNaN(result) || !isFinite(result)) {
2896
+ return {
2897
+ success: false,
2898
+ error: "Invalid result (NaN or Infinity)"
2899
+ };
2900
+ }
2901
+ return {
2902
+ success: true,
2903
+ result,
2904
+ function: input.function,
2905
+ input: input.value
2906
+ };
2907
+ } catch (error) {
2544
2908
  return {
2545
2909
  success: false,
2546
- error: "Invalid result (NaN or Infinity)"
2910
+ error: error instanceof Error ? error.message : "Math operation failed"
2547
2911
  };
2548
2912
  }
2913
+ }).build();
2914
+ }
2915
+ function createRandomNumberTool() {
2916
+ return toolBuilder().name("random-number").description("Generate a random number within a specified range. Supports integers and decimals.").category(ToolCategory.UTILITY).tags(["random", "number", "generator"]).schema(RandomNumberSchema).implement(async (input) => {
2917
+ const min = input.min ?? 0;
2918
+ const max = input.max ?? 1;
2919
+ const integer = input.integer ?? false;
2920
+ let result;
2921
+ if (integer) {
2922
+ result = Math.floor(Math.random() * (max - min + 1)) + min;
2923
+ } else {
2924
+ result = Math.random() * (max - min) + min;
2925
+ }
2549
2926
  return {
2550
- success: true,
2551
2927
  result,
2552
- function: input.function,
2553
- input: input.value
2554
- };
2555
- } catch (error) {
2556
- return {
2557
- success: false,
2558
- error: error instanceof Error ? error.message : "Math operation failed"
2928
+ min,
2929
+ max,
2930
+ integer
2559
2931
  };
2560
- }
2561
- }).build();
2562
- var randomNumber = toolBuilder().name("random-number").description("Generate a random number within a specified range. Supports integers and decimals.").category(ToolCategory.UTILITY).tags(["random", "number", "generator"]).schema(z.object({
2563
- min: z.number().default(0).describe("Minimum value (inclusive)"),
2564
- max: z.number().default(1).describe("Maximum value (exclusive for decimals, inclusive for integers)"),
2565
- integer: z.boolean().default(false).describe("Generate an integer (true) or decimal (false)")
2566
- })).implement(async (input) => {
2567
- const min = input.min ?? 0;
2568
- const max = input.max ?? 1;
2569
- const integer = input.integer ?? false;
2570
- let result;
2571
- if (integer) {
2572
- result = Math.floor(Math.random() * (max - min + 1)) + min;
2573
- } else {
2574
- result = Math.random() * (max - min) + min;
2575
- }
2576
- return {
2577
- result,
2578
- min,
2579
- max,
2580
- integer
2581
- };
2582
- }).build();
2583
- var statistics = toolBuilder().name("statistics").description("Calculate statistics for an array of numbers: sum, average, min, max, median, standard deviation.").category(ToolCategory.UTILITY).tags(["math", "statistics", "average", "sum"]).schema(z.object({
2584
- numbers: z.array(z.number().describe("Number value")).describe("Array of numbers to analyze")
2585
- })).implement(async (input) => {
2586
- if (input.numbers.length === 0) {
2932
+ }).build();
2933
+ }
2934
+ function createStatisticsTool() {
2935
+ return toolBuilder().name("statistics").description("Calculate statistics for an array of numbers: sum, average, min, max, median, standard deviation.").category(ToolCategory.UTILITY).tags(["math", "statistics", "average", "sum"]).schema(StatisticsSchema).implement(async (input) => {
2936
+ if (input.numbers.length === 0) {
2937
+ return {
2938
+ success: false,
2939
+ error: "Empty array"
2940
+ };
2941
+ }
2942
+ const sorted = [...input.numbers].sort((a, b) => a - b);
2943
+ const sum = input.numbers.reduce((acc, n) => acc + n, 0);
2944
+ const average = sum / input.numbers.length;
2945
+ const min = sorted[0];
2946
+ const max = sorted[sorted.length - 1];
2947
+ const mid = Math.floor(sorted.length / 2);
2948
+ const median = sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
2949
+ const variance = input.numbers.reduce((acc, n) => acc + Math.pow(n - average, 2), 0) / input.numbers.length;
2950
+ const stdDev = Math.sqrt(variance);
2587
2951
  return {
2588
- success: false,
2589
- error: "Empty array"
2952
+ success: true,
2953
+ count: input.numbers.length,
2954
+ sum,
2955
+ average,
2956
+ min,
2957
+ max,
2958
+ median,
2959
+ standardDeviation: stdDev,
2960
+ variance
2590
2961
  };
2591
- }
2592
- const sorted = [...input.numbers].sort((a, b) => a - b);
2593
- const sum = input.numbers.reduce((acc, n) => acc + n, 0);
2594
- const average = sum / input.numbers.length;
2595
- const min = sorted[0];
2596
- const max = sorted[sorted.length - 1];
2597
- const mid = Math.floor(sorted.length / 2);
2598
- const median = sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
2599
- const variance = input.numbers.reduce((acc, n) => acc + Math.pow(n - average, 2), 0) / input.numbers.length;
2600
- const stdDev = Math.sqrt(variance);
2601
- return {
2602
- success: true,
2603
- count: input.numbers.length,
2604
- sum,
2605
- average,
2606
- min,
2607
- max,
2608
- median,
2609
- standardDeviation: stdDev,
2610
- variance
2611
- };
2612
- }).build();
2613
- var emailValidator = toolBuilder().name("email-validator").description("Validate if a string is a valid email address format.").category(ToolCategory.UTILITY).tags(["validation", "email", "validate"]).schema(z.object({
2962
+ }).build();
2963
+ }
2964
+
2965
+ // src/utility/math/index.ts
2966
+ var calculator = createCalculatorTool();
2967
+ var mathFunctions = createMathFunctionsTool();
2968
+ var randomNumber = createRandomNumberTool();
2969
+ var statistics = createStatisticsTool();
2970
+ var mathOperationTools = [
2971
+ calculator,
2972
+ mathFunctions,
2973
+ randomNumber,
2974
+ statistics
2975
+ ];
2976
+ function createMathOperationTools(config = {}) {
2977
+ return [
2978
+ createCalculatorTool(),
2979
+ createMathFunctionsTool(),
2980
+ createRandomNumberTool(),
2981
+ createStatisticsTool()
2982
+ ];
2983
+ }
2984
+ var EmailValidatorSchema = z.object({
2614
2985
  email: z.string().describe("Email address to validate")
2615
- })).implement(async (input) => {
2616
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2617
- const valid = emailRegex.test(input.email);
2618
- return {
2619
- valid,
2620
- email: input.email,
2621
- message: valid ? "Valid email address" : "Invalid email address format"
2622
- };
2623
- }).build();
2624
- var urlValidatorSimple = toolBuilder().name("url-validator-simple").description("Validate if a string is a valid URL format.").category(ToolCategory.UTILITY).tags(["validation", "url", "validate"]).schema(z.object({
2986
+ });
2987
+ var UrlValidatorSimpleSchema = z.object({
2625
2988
  url: z.string().describe("URL to validate")
2626
- })).implement(async (input) => {
2627
- try {
2628
- new URL(input.url);
2989
+ });
2990
+ var PhoneValidatorSchema = z.object({
2991
+ phone: z.string().describe("Phone number to validate"),
2992
+ strict: z.boolean().default(false).describe("Use strict validation (requires country code)")
2993
+ });
2994
+ var CreditCardValidatorSchema = z.object({
2995
+ cardNumber: z.string().describe("Credit card number to validate")
2996
+ });
2997
+ var IpValidatorSchema = z.object({
2998
+ ip: z.string().describe("IP address to validate"),
2999
+ version: z.enum(["v4", "v6", "any"]).default("any").describe("IP version to validate against")
3000
+ });
3001
+ var UuidValidatorSchema = z.object({
3002
+ uuid: z.string().describe("UUID to validate")
3003
+ });
3004
+
3005
+ // src/utility/validation/tools/email-validator.ts
3006
+ function createEmailValidatorTool() {
3007
+ return toolBuilder().name("email-validator").description("Validate if a string is a valid email address format.").category(ToolCategory.UTILITY).tags(["validation", "email", "validate"]).schema(EmailValidatorSchema).implement(async (input) => {
3008
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
3009
+ const valid = emailRegex.test(input.email);
2629
3010
  return {
2630
- valid: true,
2631
- url: input.url,
2632
- message: "Valid URL"
3011
+ valid,
3012
+ email: input.email,
3013
+ message: valid ? "Valid email address" : "Invalid email address format"
2633
3014
  };
2634
- } catch {
3015
+ }).build();
3016
+ }
3017
+ function createUrlValidatorSimpleTool() {
3018
+ return toolBuilder().name("url-validator-simple").description("Validate if a string is a valid URL format.").category(ToolCategory.UTILITY).tags(["validation", "url", "validate"]).schema(UrlValidatorSimpleSchema).implement(async (input) => {
3019
+ try {
3020
+ new URL(input.url);
3021
+ return {
3022
+ valid: true,
3023
+ url: input.url,
3024
+ message: "Valid URL"
3025
+ };
3026
+ } catch {
3027
+ return {
3028
+ valid: false,
3029
+ url: input.url,
3030
+ message: "Invalid URL format"
3031
+ };
3032
+ }
3033
+ }).build();
3034
+ }
3035
+ function createPhoneValidatorTool() {
3036
+ return toolBuilder().name("phone-validator").description("Validate if a string is a valid phone number format. Supports various international formats.").category(ToolCategory.UTILITY).tags(["validation", "phone", "validate"]).schema(PhoneValidatorSchema).implement(async (input) => {
3037
+ const basicRegex = /^[\d\s\-\+\(\)]+$/;
3038
+ const strictRegex = /^\+?[1-9]\d{1,14}$/;
3039
+ const regex = input.strict ? strictRegex : basicRegex;
3040
+ const valid = regex.test(input.phone.replace(/\s/g, ""));
2635
3041
  return {
2636
- valid: false,
2637
- url: input.url,
2638
- message: "Invalid URL format"
3042
+ valid,
3043
+ phone: input.phone,
3044
+ message: valid ? "Valid phone number format" : "Invalid phone number format"
2639
3045
  };
2640
- }
2641
- }).build();
2642
- var phoneValidator = toolBuilder().name("phone-validator").description("Validate if a string is a valid phone number format. Supports various international formats.").category(ToolCategory.UTILITY).tags(["validation", "phone", "validate"]).schema(z.object({
2643
- phone: z.string().describe("Phone number to validate"),
2644
- strict: z.boolean().default(false).describe("Use strict validation (requires country code)")
2645
- })).implement(async (input) => {
2646
- const basicRegex = /^[\d\s\-\+\(\)]+$/;
2647
- const strictRegex = /^\+?[1-9]\d{1,14}$/;
2648
- const regex = input.strict ? strictRegex : basicRegex;
2649
- const valid = regex.test(input.phone.replace(/\s/g, ""));
2650
- return {
2651
- valid,
2652
- phone: input.phone,
2653
- message: valid ? "Valid phone number format" : "Invalid phone number format"
2654
- };
2655
- }).build();
2656
- var creditCardValidator = toolBuilder().name("credit-card-validator").description("Validate if a string is a valid credit card number using the Luhn algorithm.").category(ToolCategory.UTILITY).tags(["validation", "credit-card", "validate", "luhn"]).schema(z.object({
2657
- cardNumber: z.string().describe("Credit card number to validate")
2658
- })).implement(async (input) => {
2659
- const cleaned = input.cardNumber.replace(/[\s\-]/g, "");
2660
- if (!/^\d+$/.test(cleaned)) {
3046
+ }).build();
3047
+ }
3048
+ function createCreditCardValidatorTool() {
3049
+ return toolBuilder().name("credit-card-validator").description("Validate if a string is a valid credit card number using the Luhn algorithm.").category(ToolCategory.UTILITY).tags(["validation", "credit-card", "validate", "luhn"]).schema(CreditCardValidatorSchema).implement(async (input) => {
3050
+ const cleaned = input.cardNumber.replace(/[\s\-]/g, "");
3051
+ if (!/^\d+$/.test(cleaned)) {
3052
+ return {
3053
+ valid: false,
3054
+ message: "Card number must contain only digits"
3055
+ };
3056
+ }
3057
+ let sum = 0;
3058
+ let isEven = false;
3059
+ for (let i = cleaned.length - 1; i >= 0; i--) {
3060
+ let digit = parseInt(cleaned[i], 10);
3061
+ if (isEven) {
3062
+ digit *= 2;
3063
+ if (digit > 9) {
3064
+ digit -= 9;
3065
+ }
3066
+ }
3067
+ sum += digit;
3068
+ isEven = !isEven;
3069
+ }
3070
+ const valid = sum % 10 === 0;
2661
3071
  return {
2662
- valid: false,
2663
- message: "Card number must contain only digits"
3072
+ valid,
3073
+ cardNumber: input.cardNumber,
3074
+ message: valid ? "Valid credit card number" : "Invalid credit card number (failed Luhn check)"
2664
3075
  };
2665
- }
2666
- let sum = 0;
2667
- let isEven = false;
2668
- for (let i = cleaned.length - 1; i >= 0; i--) {
2669
- let digit = parseInt(cleaned[i], 10);
2670
- if (isEven) {
2671
- digit *= 2;
2672
- if (digit > 9) {
2673
- digit -= 9;
3076
+ }).build();
3077
+ }
3078
+ function createIpValidatorTool() {
3079
+ return toolBuilder().name("ip-validator").description("Validate if a string is a valid IPv4 or IPv6 address.").category(ToolCategory.UTILITY).tags(["validation", "ip", "validate", "network"]).schema(IpValidatorSchema).implement(async (input) => {
3080
+ const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
3081
+ const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
3082
+ let valid = false;
3083
+ let detectedVersion;
3084
+ if (input.version === "v4" || input.version === "any") {
3085
+ if (ipv4Regex.test(input.ip)) {
3086
+ const parts = input.ip.split(".");
3087
+ valid = parts.every((part) => {
3088
+ const num = parseInt(part, 10);
3089
+ return num >= 0 && num <= 255;
3090
+ });
3091
+ if (valid) detectedVersion = "IPv4";
2674
3092
  }
2675
3093
  }
2676
- sum += digit;
2677
- isEven = !isEven;
2678
- }
2679
- const valid = sum % 10 === 0;
2680
- return {
2681
- valid,
2682
- cardNumber: input.cardNumber,
2683
- message: valid ? "Valid credit card number" : "Invalid credit card number (failed Luhn check)"
2684
- };
2685
- }).build();
2686
- var ipValidator = toolBuilder().name("ip-validator").description("Validate if a string is a valid IPv4 or IPv6 address.").category(ToolCategory.UTILITY).tags(["validation", "ip", "validate", "network"]).schema(z.object({
2687
- ip: z.string().describe("IP address to validate"),
2688
- version: z.enum(["v4", "v6", "any"]).default("any").describe("IP version to validate against")
2689
- })).implement(async (input) => {
2690
- const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
2691
- const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
2692
- let valid = false;
2693
- let detectedVersion;
2694
- if (input.version === "v4" || input.version === "any") {
2695
- if (ipv4Regex.test(input.ip)) {
2696
- const parts = input.ip.split(".");
2697
- valid = parts.every((part) => {
2698
- const num = parseInt(part, 10);
2699
- return num >= 0 && num <= 255;
2700
- });
2701
- if (valid) detectedVersion = "IPv4";
3094
+ if (!valid && (input.version === "v6" || input.version === "any")) {
3095
+ if (ipv6Regex.test(input.ip)) {
3096
+ valid = true;
3097
+ detectedVersion = "IPv6";
3098
+ }
2702
3099
  }
2703
- }
2704
- if (!valid && (input.version === "v6" || input.version === "any")) {
2705
- if (ipv6Regex.test(input.ip)) {
2706
- valid = true;
2707
- detectedVersion = "IPv6";
3100
+ return {
3101
+ valid,
3102
+ ip: input.ip,
3103
+ version: detectedVersion,
3104
+ message: valid ? `Valid ${detectedVersion} address` : "Invalid IP address format"
3105
+ };
3106
+ }).build();
3107
+ }
3108
+ function createUuidValidatorTool() {
3109
+ return toolBuilder().name("uuid-validator").description("Validate if a string is a valid UUID (v1, v3, v4, or v5).").category(ToolCategory.UTILITY).tags(["validation", "uuid", "validate", "guid"]).schema(UuidValidatorSchema).implement(async (input) => {
3110
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
3111
+ const valid = uuidRegex.test(input.uuid);
3112
+ let version;
3113
+ if (valid) {
3114
+ version = parseInt(input.uuid[14], 10);
2708
3115
  }
2709
- }
2710
- return {
2711
- valid,
2712
- ip: input.ip,
2713
- version: detectedVersion,
2714
- message: valid ? `Valid ${detectedVersion} address` : "Invalid IP address format"
2715
- };
2716
- }).build();
2717
- var uuidValidator = toolBuilder().name("uuid-validator").description("Validate if a string is a valid UUID (v1, v3, v4, or v5).").category(ToolCategory.UTILITY).tags(["validation", "uuid", "validate", "guid"]).schema(z.object({
2718
- uuid: z.string().describe("UUID to validate")
2719
- })).implement(async (input) => {
2720
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2721
- const valid = uuidRegex.test(input.uuid);
2722
- let version;
2723
- if (valid) {
2724
- version = parseInt(input.uuid[14], 10);
2725
- }
2726
- return {
2727
- valid,
2728
- uuid: input.uuid,
2729
- version,
2730
- message: valid ? `Valid UUID v${version}` : "Invalid UUID format"
2731
- };
2732
- }).build();
3116
+ return {
3117
+ valid,
3118
+ uuid: input.uuid,
3119
+ version,
3120
+ message: valid ? `Valid UUID v${version}` : "Invalid UUID format"
3121
+ };
3122
+ }).build();
3123
+ }
3124
+
3125
+ // src/utility/validation/index.ts
3126
+ var emailValidator = createEmailValidatorTool();
3127
+ var urlValidatorSimple = createUrlValidatorSimpleTool();
3128
+ var phoneValidator = createPhoneValidatorTool();
3129
+ var creditCardValidator = createCreditCardValidatorTool();
3130
+ var ipValidator = createIpValidatorTool();
3131
+ var uuidValidator = createUuidValidatorTool();
3132
+ var validationTools = [
3133
+ emailValidator,
3134
+ urlValidatorSimple,
3135
+ phoneValidator,
3136
+ creditCardValidator,
3137
+ ipValidator,
3138
+ uuidValidator
3139
+ ];
3140
+ function createValidationTools(config = {}) {
3141
+ return [
3142
+ createEmailValidatorTool(),
3143
+ createUrlValidatorSimpleTool(),
3144
+ createPhoneValidatorTool(),
3145
+ createCreditCardValidatorTool(),
3146
+ createIpValidatorTool(),
3147
+ createUuidValidatorTool()
3148
+ ];
3149
+ }
2733
3150
  var AskHumanInputSchema = z.object({
2734
3151
  /**
2735
3152
  * The question to ask the human
@@ -2821,6 +3238,6 @@ function createAskHumanTool() {
2821
3238
  }
2822
3239
  var askHumanTool = createAskHumanTool();
2823
3240
 
2824
- export { AskHumanInputSchema, DuckDuckGoProvider, SerperProvider, archiveConfluencePage, arrayFilter, arrayGroupBy, arrayMap, arraySort, askHumanTool, calculator, confluenceTools, createAskHumanTool, createConfluencePage, createConfluenceTools, createDuckDuckGoProvider, createSerperProvider, createSlackTools, creditCardValidator, csvGenerator, csvParser, csvToJson, currentDateTime, dateArithmetic, dateComparison, dateDifference, dateFormatter, directoryCreate, directoryDelete, directoryList, emailValidator, extractImages, extractLinks, fileAppend, fileDelete, fileExists, fileReader, fileSearch, fileWriter, getConfluencePage, getSlackChannels, getSlackMessages, getSpacePages, htmlParser, httpClient, httpGet, httpPost, ipValidator, jsonMerge, jsonParser, jsonQuery, jsonStringify, jsonToCsv, jsonToXml, jsonValidator, listConfluenceSpaces, mathFunctions, notifySlack, objectOmit, objectPick, pathBasename, pathDirname, pathExtension, pathJoin, pathNormalize, pathParse, pathRelative, pathResolve, phoneValidator, randomNumber, searchConfluence, searchResultSchema, sendSlackMessage, slackTools, statistics, stringCaseConverter, stringJoin, stringLength, stringReplace, stringSplit, stringSubstring, stringTrim, updateConfluencePage, urlBuilder, urlQueryParser, urlValidator, urlValidatorSimple, uuidValidator, webScraper, webSearch, webSearchOutputSchema, webSearchSchema, xmlGenerator, xmlParser, xmlToJson };
3241
+ export { AskHumanInputSchema, CalculatorSchema, CreditCardValidatorSchema, CurrentDateTimeSchema, DateArithmeticSchema, DateComparisonSchema, DateDifferenceSchema, DateFormatterSchema, DuckDuckGoProvider, EmailValidatorSchema, HttpMethod, IpValidatorSchema, MathFunctionsSchema, PhoneValidatorSchema, RandomNumberSchema, SerperProvider, StatisticsSchema, StringCaseConverterSchema, StringJoinSchema, StringLengthSchema, StringReplaceSchema, StringSplitSchema, StringSubstringSchema, StringTrimSchema, UrlValidatorSimpleSchema, UuidValidatorSchema, archiveConfluencePage, arrayFilter, arrayFilterSchema, arrayGroupBy, arrayGroupBySchema, arrayMap, arrayMapSchema, arraySort, arraySortSchema, askHumanTool, calculator, confluenceTools, createArrayFilterTool, createArrayGroupByTool, createArrayMapTool, createArraySortTool, createAskHumanTool, createCalculatorTool, createConfluencePage, createConfluenceTools, createCreditCardValidatorTool, createCsvGeneratorTool, createCsvParserTool, createCsvToJsonTool, createCsvTools, createCurrentDateTimeTool, createDateArithmeticTool, createDateComparisonTool, createDateDifferenceTool, createDateFormatterTool, createDateTimeTools, createDirectoryCreateTool, createDirectoryDeleteTool, createDirectoryListTool, createDirectoryOperationTools, createDuckDuckGoProvider, createEmailValidatorTool, createExtractImagesTool, createExtractLinksTool, createFileAppendTool, createFileDeleteTool, createFileExistsTool, createFileOperationTools, createFileReaderTool, createFileSearchTool, createFileWriterTool, createHtmlParserTool, createHtmlParserTools, createHttpTools, createIpValidatorTool, createJsonMergeTool, createJsonParserTool, createJsonQueryTool, createJsonStringifyTool, createJsonToCsvTool, createJsonToXmlTool, createJsonTools, createJsonValidatorTool, createMathFunctionsTool, createMathOperationTools, createObjectOmitTool, createObjectPickTool, createPathBasenameTool, createPathDirnameTool, createPathExtensionTool, createPathJoinTool, createPathNormalizeTool, createPathParseTool, createPathRelativeTool, createPathResolveTool, createPathUtilityTools, createPhoneValidatorTool, createRandomNumberTool, createScraperTools, createSerperProvider, createSlackTools, createStatisticsTool, createStringCaseConverterTool, createStringJoinTool, createStringLengthTool, createStringReplaceTool, createStringSplitTool, createStringSubstringTool, createStringTrimTool, createStringUtilityTools, createTransformerTools, createUrlBuilderTool, createUrlQueryParserTool, createUrlValidatorSimpleTool, createUrlValidatorTool, createUrlValidatorTools, createUuidValidatorTool, createValidationTools, createWebScraperTool, createXmlGeneratorTool, createXmlParserTool, createXmlToJsonTool, createXmlTools, creditCardValidator, csvGenerator, csvGeneratorSchema, csvParser, csvParserSchema, csvToJson, csvToJsonSchema, csvTools, currentDateTime, dateArithmetic, dateComparison, dateDifference, dateFormatter, dateTimeTools, directoryCreate, directoryCreateSchema, directoryDelete, directoryDeleteSchema, directoryList, directoryListSchema, directoryOperationTools, emailValidator, extractImages, extractImagesSchema, extractLinks, extractLinksSchema, fileAppend, fileAppendSchema, fileDelete, fileDeleteSchema, fileExists, fileExistsSchema, fileOperationTools, fileReader, fileReaderSchema, fileSearch, fileSearchSchema, fileWriter, fileWriterSchema, getConfluencePage, getSlackChannels, getSlackMessages, getSpacePages, htmlParser, htmlParserSchema, htmlParserTools, httpClient, httpGet, httpGetSchema, httpPost, httpPostSchema, httpRequestSchema, httpTools, ipValidator, jsonMerge, jsonMergeSchema, jsonParser, jsonParserSchema, jsonQuery, jsonQuerySchema, jsonStringify, jsonStringifySchema, jsonToCsv, jsonToCsvSchema, jsonToXml, jsonToXmlSchema, jsonTools, jsonValidator, jsonValidatorSchema, listConfluenceSpaces, mathFunctions, mathOperationTools, notifySlack, objectOmit, objectOmitSchema, objectPick, objectPickSchema, pathBasename, pathBasenameSchema, pathDirname, pathDirnameSchema, pathExtension, pathExtensionSchema, pathJoin, pathJoinSchema, pathNormalize, pathNormalizeSchema, pathParse, pathParseSchema, pathRelative, pathRelativeSchema, pathResolve, pathResolveSchema, pathUtilityTools, phoneValidator, randomNumber, scraperTools, searchConfluence, searchResultSchema, sendSlackMessage, slackTools, statistics, stringCaseConverter, stringJoin, stringLength, stringReplace, stringSplit, stringSubstring, stringTrim, stringUtilityTools, transformerTools, updateConfluencePage, urlBuilder, urlBuilderSchema, urlQueryParser, urlQueryParserSchema, urlValidator, urlValidatorSchema, urlValidatorSimple, urlValidatorTools, uuidValidator, validationTools, webScraper, webScraperSchema, webSearch, webSearchOutputSchema, webSearchSchema, xmlGenerator, xmlGeneratorSchema, xmlParser, xmlParserSchema, xmlToJson, xmlToJsonSchema, xmlTools };
2825
3242
  //# sourceMappingURL=index.js.map
2826
3243
  //# sourceMappingURL=index.js.map