@vymalo/opencode-devtools 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/catalog.d.ts +18 -0
  4. package/dist/catalog.js +44 -0
  5. package/dist/catalog.js.map +1 -0
  6. package/dist/groups/codec.d.ts +2 -0
  7. package/dist/groups/codec.js +141 -0
  8. package/dist/groups/codec.js.map +1 -0
  9. package/dist/groups/convert.d.ts +2 -0
  10. package/dist/groups/convert.js +99 -0
  11. package/dist/groups/convert.js.map +1 -0
  12. package/dist/groups/crypto.d.ts +2 -0
  13. package/dist/groups/crypto.js +205 -0
  14. package/dist/groups/crypto.js.map +1 -0
  15. package/dist/groups/datetime.d.ts +2 -0
  16. package/dist/groups/datetime.js +229 -0
  17. package/dist/groups/datetime.js.map +1 -0
  18. package/dist/groups/http.d.ts +10 -0
  19. package/dist/groups/http.js +269 -0
  20. package/dist/groups/http.js.map +1 -0
  21. package/dist/groups/math.d.ts +2 -0
  22. package/dist/groups/math.js +139 -0
  23. package/dist/groups/math.js.map +1 -0
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +6 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib.d.ts +7 -0
  28. package/dist/lib.js +7 -0
  29. package/dist/lib.js.map +1 -0
  30. package/dist/logging.d.ts +16 -0
  31. package/dist/logging.js +72 -0
  32. package/dist/logging.js.map +1 -0
  33. package/dist/opencode.d.ts +14 -0
  34. package/dist/opencode.js +91 -0
  35. package/dist/opencode.js.map +1 -0
  36. package/dist/schema.d.ts +63 -0
  37. package/dist/schema.js +54 -0
  38. package/dist/schema.js.map +1 -0
  39. package/dist/tool-spec.d.ts +44 -0
  40. package/dist/tool-spec.js +27 -0
  41. package/dist/tool-spec.js.map +1 -0
  42. package/dist/tools.d.ts +18 -0
  43. package/dist/tools.js +91 -0
  44. package/dist/tools.js.map +1 -0
  45. package/dist/types.d.ts +38 -0
  46. package/dist/types.js +2 -0
  47. package/dist/types.js.map +1 -0
  48. package/package.json +81 -0
@@ -0,0 +1,229 @@
1
+ import { CronExpressionParser } from "cron-parser";
2
+ import cronstrue from "cronstrue";
3
+ import { DateTime, Duration } from "luxon";
4
+ import { json, optString, reqString } from "../tool-spec.js";
5
+ const DEFAULT_DIFF_UNITS = ["years", "months", "days", "hours", "minutes", "seconds"];
6
+ /** Parse an instant from ISO, RFC 2822, SQL, epoch-millis, or an explicit format. */
7
+ function parseInstant(input, zone, format) {
8
+ const opts = zone ? { zone } : {};
9
+ if (format) {
10
+ return DateTime.fromFormat(input, format, opts);
11
+ }
12
+ const trimmed = input.trim();
13
+ if (/^-?\d{10,}$/.test(trimmed)) {
14
+ return DateTime.fromMillis(Number(trimmed), opts);
15
+ }
16
+ const iso = DateTime.fromISO(trimmed, opts);
17
+ if (iso.isValid) {
18
+ return iso;
19
+ }
20
+ const rfc = DateTime.fromRFC2822(trimmed, opts);
21
+ if (rfc.isValid) {
22
+ return rfc;
23
+ }
24
+ const sql = DateTime.fromSQL(trimmed, opts);
25
+ if (sql.isValid) {
26
+ return sql;
27
+ }
28
+ return iso; // invalid; caller reports the reason
29
+ }
30
+ function ensureValid(dt, label) {
31
+ if (!dt.isValid) {
32
+ throw new Error(`${label} is not a valid date/time (${dt.invalidReason ?? "unknown"})`);
33
+ }
34
+ return dt;
35
+ }
36
+ function describe(dt) {
37
+ return {
38
+ iso: dt.toISO(),
39
+ epochMs: dt.toMillis(),
40
+ epochSeconds: Math.floor(dt.toMillis() / 1000),
41
+ zone: dt.zoneName,
42
+ weekday: dt.weekdayLong,
43
+ components: {
44
+ year: dt.year,
45
+ month: dt.month,
46
+ day: dt.day,
47
+ hour: dt.hour,
48
+ minute: dt.minute,
49
+ second: dt.second
50
+ }
51
+ };
52
+ }
53
+ export const DATETIME_TOOLS = [
54
+ {
55
+ name: "datetime_now",
56
+ group: "datetime",
57
+ description: "Get the current date and time, optionally in a specific IANA timezone.",
58
+ input: {
59
+ zone: {
60
+ type: "string",
61
+ optional: true,
62
+ description: 'IANA timezone, e.g. "Europe/Paris" (default system zone).'
63
+ }
64
+ },
65
+ handler: (args, ctx) => {
66
+ const zone = optString(args, "zone");
67
+ let dt = DateTime.fromJSDate(ctx.now());
68
+ if (zone) {
69
+ dt = dt.setZone(zone);
70
+ ensureValid(dt, `zone "${zone}"`);
71
+ }
72
+ return json(describe(dt), `${dt.toISO()} (${dt.zoneName})`);
73
+ }
74
+ },
75
+ {
76
+ name: "datetime_parse",
77
+ group: "datetime",
78
+ description: "Parse a date/time string (ISO 8601, RFC 2822, SQL, epoch-millis, or a custom format) into a normalized ISO timestamp plus its components.",
79
+ input: {
80
+ input: { type: "string", description: "The date/time string to parse." },
81
+ format: {
82
+ type: "string",
83
+ optional: true,
84
+ description: 'Optional Luxon parse format, e.g. "dd/MM/yyyy HH:mm".'
85
+ },
86
+ zone: {
87
+ type: "string",
88
+ optional: true,
89
+ description: "IANA timezone to interpret the input in."
90
+ }
91
+ },
92
+ handler: (args) => {
93
+ const input = reqString(args, "input");
94
+ const dt = ensureValid(parseInstant(input, optString(args, "zone"), optString(args, "format")), "input");
95
+ return json(describe(dt), `${dt.toISO()} (${dt.zoneName})`);
96
+ }
97
+ },
98
+ {
99
+ name: "datetime_format",
100
+ group: "datetime",
101
+ description: "Reformat a date/time into a chosen representation: a Luxon format string, or a preset (iso, rfc2822, http, sql, relative).",
102
+ input: {
103
+ input: { type: "string", description: "The date/time to format (ISO, epoch-millis, …)." },
104
+ format: {
105
+ type: "string",
106
+ description: "Luxon format token string, or one of: iso, rfc2822, http, sql, relative."
107
+ },
108
+ zone: { type: "string", optional: true, description: "IANA timezone for the output." }
109
+ },
110
+ handler: (args, ctx) => {
111
+ const input = reqString(args, "input");
112
+ const format = reqString(args, "format");
113
+ let dt = ensureValid(parseInstant(input, undefined, undefined), "input");
114
+ const zone = optString(args, "zone");
115
+ if (zone) {
116
+ dt = dt.setZone(zone);
117
+ ensureValid(dt, `zone "${zone}"`);
118
+ }
119
+ let out;
120
+ switch (format) {
121
+ case "iso":
122
+ out = dt.toISO();
123
+ break;
124
+ case "rfc2822":
125
+ out = dt.toRFC2822();
126
+ break;
127
+ case "http":
128
+ out = dt.toHTTP();
129
+ break;
130
+ case "sql":
131
+ out = dt.toSQL();
132
+ break;
133
+ case "relative":
134
+ out = dt.toRelative({ base: DateTime.fromJSDate(ctx.now()) });
135
+ break;
136
+ default:
137
+ out = dt.toFormat(format);
138
+ }
139
+ return json({ input, format, result: out }, out ?? "");
140
+ }
141
+ },
142
+ {
143
+ name: "datetime_diff",
144
+ group: "datetime",
145
+ description: "Compute the duration between two date/times, broken down into the requested units (default years→seconds).",
146
+ input: {
147
+ from: { type: "string", description: "Start date/time." },
148
+ to: { type: "string", description: "End date/time." },
149
+ units: {
150
+ type: "array",
151
+ optional: true,
152
+ items: { type: "string" },
153
+ description: 'Units to break the duration into, e.g. ["days","hours"].'
154
+ }
155
+ },
156
+ handler: (args) => {
157
+ const from = ensureValid(parseInstant(reqString(args, "from"), undefined, undefined), "from");
158
+ const to = ensureValid(parseInstant(reqString(args, "to"), undefined, undefined), "to");
159
+ const units = Array.isArray(args.units)
160
+ ? args.units.filter((u) => typeof u === "string")
161
+ : DEFAULT_DIFF_UNITS;
162
+ const diff = to.diff(from, units);
163
+ const obj = diff.toObject();
164
+ return json({ from: from.toISO(), to: to.toISO(), milliseconds: diff.toMillis(), duration: obj }, `${Duration.fromObject(obj).toHuman()} (${diff.toMillis()} ms)`);
165
+ }
166
+ },
167
+ {
168
+ name: "datetime_convert_tz",
169
+ group: "datetime",
170
+ description: "Convert a date/time from one IANA timezone to another (the instant is preserved).",
171
+ input: {
172
+ input: { type: "string", description: "The date/time to convert." },
173
+ toZone: { type: "string", description: 'Target IANA timezone, e.g. "Asia/Tokyo".' },
174
+ fromZone: {
175
+ type: "string",
176
+ optional: true,
177
+ description: "Source timezone if `input` has no offset (default system zone)."
178
+ }
179
+ },
180
+ handler: (args) => {
181
+ const input = reqString(args, "input");
182
+ const toZone = reqString(args, "toZone");
183
+ const fromZone = optString(args, "fromZone");
184
+ const src = ensureValid(parseInstant(input, fromZone, undefined), "input");
185
+ const dst = src.setZone(toZone);
186
+ ensureValid(dst, `toZone "${toZone}"`);
187
+ return json({
188
+ from: { iso: src.toISO(), zone: src.zoneName },
189
+ to: { iso: dst.toISO(), zone: dst.zoneName }
190
+ }, `${src.toISO()} (${src.zoneName}) → ${dst.toISO()} (${dst.zoneName})`);
191
+ }
192
+ },
193
+ {
194
+ name: "datetime_cron",
195
+ group: "datetime",
196
+ description: "Explain a cron expression in plain English and list its next N run times (in an optional IANA timezone).",
197
+ input: {
198
+ expression: { type: "string", description: 'Cron expression, e.g. "0 9 * * 1-5".' },
199
+ count: {
200
+ type: "number",
201
+ optional: true,
202
+ description: "How many upcoming runs to list (default 5)."
203
+ },
204
+ zone: { type: "string", optional: true, description: "IANA timezone to compute runs in." }
205
+ },
206
+ handler: (args, ctx) => {
207
+ const expression = reqString(args, "expression");
208
+ const count = typeof args.count === "number" ? Math.min(50, Math.max(1, Math.floor(args.count))) : 5;
209
+ const zone = optString(args, "zone");
210
+ let englishDescription;
211
+ try {
212
+ englishDescription = cronstrue.toString(expression, { throwExceptionOnParseError: true });
213
+ }
214
+ catch (err) {
215
+ throw new Error(`invalid cron expression: ${err instanceof Error ? err.message : String(err)}`);
216
+ }
217
+ const interval = CronExpressionParser.parse(expression, {
218
+ currentDate: ctx.now(),
219
+ ...(zone ? { tz: zone } : {})
220
+ });
221
+ const next = [];
222
+ for (let i = 0; i < count; i++) {
223
+ next.push(interval.next().toDate().toISOString());
224
+ }
225
+ return json({ expression, description: englishDescription, next }, `${englishDescription}\nNext ${count}:\n${next.join("\n")}`);
226
+ }
227
+ }
228
+ ];
229
+ //# sourceMappingURL=datetime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datetime.js","sourceRoot":"","sources":["../../src/groups/datetime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type ToolSpec } from "../tool-spec.js";
2
+ /**
3
+ * Reject loopback / private / link-local destinations. IPv6-prefix and IPv4
4
+ * range checks only run on actual IP *literals* — a DNS name like `fdroid.org`
5
+ * (which starts with `fd`) is NOT an IPv6 ULA and must not be blocked. This is
6
+ * still a literal-host guard: it does not resolve DNS, so a public name that
7
+ * resolves to a private IP (DNS rebinding) is not caught — see docs/devtools.md.
8
+ */
9
+ export declare function isBlockedHost(hostname: string): boolean;
10
+ export declare const HTTP_TOOLS: readonly ToolSpec[];
@@ -0,0 +1,269 @@
1
+ import { json, reqString } from "../tool-spec.js";
2
+ const METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
3
+ const MAX_REDIRECTS = 5;
4
+ const MAX_RESPONSE_BYTES = 10_000_000; // 10 MB — cap buffered response bodies.
5
+ function isPrivateIpv4(host) {
6
+ const m = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
7
+ if (!m) {
8
+ return false;
9
+ }
10
+ const a = Number(m[1]);
11
+ const b = Number(m[2]);
12
+ if (a === 10 || a === 127 || a === 0) {
13
+ return true;
14
+ }
15
+ if (a === 169 && b === 254) {
16
+ return true; // link-local incl. cloud metadata 169.254.169.254
17
+ }
18
+ if (a === 172 && b >= 16 && b <= 31) {
19
+ return true;
20
+ }
21
+ if (a === 192 && b === 168) {
22
+ return true;
23
+ }
24
+ if (a === 100 && b >= 64 && b <= 127) {
25
+ return true; // CGNAT
26
+ }
27
+ return false;
28
+ }
29
+ /**
30
+ * Extract a dotted IPv4 from an IPv4-mapped IPv6 literal — both the dotted
31
+ * (`::ffff:127.0.0.1`) and the hex (`::ffff:7f00:1`, what `new URL()` normalizes
32
+ * to) forms. Returns null if not a mapped address.
33
+ */
34
+ function mappedIpv4(h) {
35
+ const dotted = h.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
36
+ if (dotted) {
37
+ return dotted[1];
38
+ }
39
+ const hex = h.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
40
+ if (hex) {
41
+ const hi = Number.parseInt(hex[1], 16);
42
+ const lo = Number.parseInt(hex[2], 16);
43
+ return `${(hi >> 8) & 0xff}.${hi & 0xff}.${(lo >> 8) & 0xff}.${lo & 0xff}`;
44
+ }
45
+ return null;
46
+ }
47
+ /**
48
+ * Reject loopback / private / link-local destinations. IPv6-prefix and IPv4
49
+ * range checks only run on actual IP *literals* — a DNS name like `fdroid.org`
50
+ * (which starts with `fd`) is NOT an IPv6 ULA and must not be blocked. This is
51
+ * still a literal-host guard: it does not resolve DNS, so a public name that
52
+ * resolves to a private IP (DNS rebinding) is not caught — see docs/devtools.md.
53
+ */
54
+ export function isBlockedHost(hostname) {
55
+ const h = hostname.toLowerCase().replace(/^\[|\]$/g, "");
56
+ const isIpv6 = h.includes(":");
57
+ const isIpv4 = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(h);
58
+ if (!isIpv6 && !isIpv4) {
59
+ // Plain DNS name — only the localhost family is private.
60
+ return h === "localhost" || h.endsWith(".localhost");
61
+ }
62
+ if (isIpv4) {
63
+ return isPrivateIpv4(h);
64
+ }
65
+ // IPv6 literal.
66
+ if (h === "::1" || h === "::") {
67
+ return true;
68
+ }
69
+ const mapped = mappedIpv4(h);
70
+ if (mapped) {
71
+ return isPrivateIpv4(mapped);
72
+ }
73
+ if (h.startsWith("fc") || h.startsWith("fd")) {
74
+ return true; // unique-local fc00::/7
75
+ }
76
+ if (/^fe[89ab]/.test(h)) {
77
+ return true; // link-local fe80::/10
78
+ }
79
+ return h.startsWith("ff"); // multicast ff00::/8
80
+ }
81
+ function assertAllowed(rawUrl, ctx) {
82
+ let url;
83
+ try {
84
+ url = new URL(rawUrl);
85
+ }
86
+ catch {
87
+ throw new Error(`invalid URL: ${rawUrl}`);
88
+ }
89
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
90
+ throw new Error(`unsupported protocol "${url.protocol}" (only http/https)`);
91
+ }
92
+ if (!ctx.options.http.allowPrivateNetwork && isBlockedHost(url.hostname)) {
93
+ throw new Error(`refusing to reach private/loopback host "${url.hostname}" (set http.allowPrivateNetwork to allow)`);
94
+ }
95
+ return url;
96
+ }
97
+ function asHeaders(value) {
98
+ if (value === undefined || value === null) {
99
+ return {};
100
+ }
101
+ if (typeof value !== "object") {
102
+ throw new Error('"headers" must be an object of string values');
103
+ }
104
+ const out = {};
105
+ for (const [k, v] of Object.entries(value)) {
106
+ out[k] = typeof v === "string" ? v : String(v);
107
+ }
108
+ return out;
109
+ }
110
+ /**
111
+ * Fetch with **manual** redirect handling so every hop is re-validated by the
112
+ * SSRF guard — the default follow-redirects behaviour would let a public URL
113
+ * 30x to `http://127.0.0.1/…` and bypass `allowPrivateNetwork: false`.
114
+ */
115
+ async function fetchGuarded(start, init, ctx) {
116
+ let url = start;
117
+ let method = init.method;
118
+ let body = init.body;
119
+ for (let hop = 0;; hop++) {
120
+ const res = await ctx.fetchImpl(url, {
121
+ method,
122
+ headers: init.headers,
123
+ body,
124
+ redirect: "manual",
125
+ signal: AbortSignal.timeout(ctx.options.http.timeoutMs)
126
+ });
127
+ const location = res.status >= 300 && res.status < 400 ? res.headers.get("location") : null;
128
+ if (!location) {
129
+ return res;
130
+ }
131
+ if (hop >= MAX_REDIRECTS) {
132
+ throw new Error(`too many redirects (> ${MAX_REDIRECTS})`);
133
+ }
134
+ const next = new URL(location, url);
135
+ assertAllowed(next.href, ctx); // re-check the redirect target
136
+ // 303 (and 301/302 from a non-idempotent method) → GET with no body.
137
+ if (res.status === 303 ||
138
+ ((res.status === 301 || res.status === 302) && method !== "GET" && method !== "HEAD")) {
139
+ method = "GET";
140
+ body = undefined;
141
+ }
142
+ url = next;
143
+ await res.body?.cancel().catch(() => { });
144
+ }
145
+ }
146
+ /** Read a response body, capped at MAX_RESPONSE_BYTES, parsing JSON when applicable. */
147
+ async function readBody(res) {
148
+ let text = "";
149
+ let truncated = false;
150
+ const reader = res.body?.getReader();
151
+ if (reader) {
152
+ const chunks = [];
153
+ let received = 0;
154
+ while (true) {
155
+ const { done, value } = await reader.read();
156
+ if (done) {
157
+ break;
158
+ }
159
+ received += value.byteLength;
160
+ if (received > MAX_RESPONSE_BYTES) {
161
+ const keep = value.byteLength - (received - MAX_RESPONSE_BYTES);
162
+ chunks.push(value.subarray(0, Math.max(0, keep)));
163
+ truncated = true;
164
+ await reader.cancel();
165
+ break;
166
+ }
167
+ chunks.push(value);
168
+ }
169
+ text = Buffer.concat(chunks.map((c) => Buffer.from(c))).toString("utf8");
170
+ }
171
+ else {
172
+ text = await res.text();
173
+ }
174
+ const contentType = res.headers.get("content-type") ?? "";
175
+ let body = text;
176
+ if (contentType.includes("application/json") && text.length > 0 && !truncated) {
177
+ try {
178
+ body = JSON.parse(text);
179
+ }
180
+ catch {
181
+ /* keep as text */
182
+ }
183
+ }
184
+ return { body, bodyText: text, truncated };
185
+ }
186
+ export const HTTP_TOOLS = [
187
+ {
188
+ name: "http_request",
189
+ group: "http",
190
+ description: "Make an HTTP request (GET/POST/PUT/PATCH/DELETE/…) and return the status, response headers, and parsed body. JSON responses are parsed automatically. Redirects are followed but re-checked against the SSRF guard; response bodies are capped at 10 MB.",
191
+ input: {
192
+ url: { type: "string", description: "Absolute http(s) URL." },
193
+ method: {
194
+ type: "string",
195
+ optional: true,
196
+ enum: METHODS,
197
+ description: "HTTP method (default GET)."
198
+ },
199
+ headers: {
200
+ type: "record",
201
+ optional: true,
202
+ valueType: "string",
203
+ description: "Request headers (e.g. Authorization, Content-Type)."
204
+ },
205
+ body: {
206
+ type: "string",
207
+ optional: true,
208
+ description: "Request body (string; set Content-Type yourself)."
209
+ }
210
+ },
211
+ handler: async (args, ctx) => {
212
+ const url = assertAllowed(reqString(args, "url"), ctx);
213
+ const method = typeof args.method === "string" ? args.method.toUpperCase() : "GET";
214
+ const headers = asHeaders(args.headers);
215
+ const rawBody = typeof args.body === "string" ? args.body : undefined;
216
+ const body = method === "GET" || method === "HEAD" ? undefined : rawBody;
217
+ const res = await fetchGuarded(url, { method, headers, body }, ctx);
218
+ const responseHeaders = Object.fromEntries(res.headers.entries());
219
+ const { body: parsed, bodyText, truncated } = await readBody(res);
220
+ return json({
221
+ status: res.status,
222
+ statusText: res.statusText,
223
+ ok: res.ok,
224
+ headers: responseHeaders,
225
+ body: parsed,
226
+ truncated
227
+ }, `${method} ${url.href} → ${res.status} ${res.statusText}${truncated ? " (body truncated at 10 MB)" : ""}\n\n${bodyText.slice(0, 4000)}`);
228
+ }
229
+ },
230
+ {
231
+ name: "http_graphql",
232
+ group: "http",
233
+ description: "Execute a GraphQL query or mutation against an endpoint and return the structured data and errors.",
234
+ input: {
235
+ url: { type: "string", description: "GraphQL endpoint URL." },
236
+ query: { type: "string", description: "The GraphQL query or mutation document." },
237
+ variables: {
238
+ type: "record",
239
+ optional: true,
240
+ valueType: "any",
241
+ description: "Query variables."
242
+ },
243
+ headers: {
244
+ type: "record",
245
+ optional: true,
246
+ valueType: "string",
247
+ description: "Extra request headers (e.g. Authorization)."
248
+ }
249
+ },
250
+ handler: async (args, ctx) => {
251
+ const url = assertAllowed(reqString(args, "url"), ctx);
252
+ const query = reqString(args, "query");
253
+ const variables = typeof args.variables === "object" && args.variables !== null ? args.variables : {};
254
+ const res = await fetchGuarded(url, {
255
+ method: "POST",
256
+ headers: {
257
+ "content-type": "application/json",
258
+ accept: "application/json",
259
+ ...asHeaders(args.headers)
260
+ },
261
+ body: JSON.stringify({ query, variables })
262
+ }, ctx);
263
+ const { body, bodyText } = await readBody(res);
264
+ const payload = (typeof body === "object" && body !== null ? body : {});
265
+ return json({ status: res.status, data: payload.data, errors: payload.errors }, `${url.href} → ${res.status}\n\n${bodyText.slice(0, 4000)}`);
266
+ }
267
+ }
268
+ ];
269
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/groups/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type ToolSpec } from "../tool-spec.js";
2
+ export declare const MATH_TOOLS: readonly ToolSpec[];