@chances-ai/tools 3.1.1 → 3.2.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/builtins/_shared.d.ts +15 -0
- package/dist/builtins/_shared.d.ts.map +1 -0
- package/dist/builtins/_shared.js +52 -0
- package/dist/builtins/_shared.js.map +1 -0
- package/dist/builtins/bash.d.ts +3 -0
- package/dist/builtins/bash.d.ts.map +1 -0
- package/dist/builtins/bash.js +25 -0
- package/dist/builtins/bash.js.map +1 -0
- package/dist/builtins/diff.d.ts +3 -0
- package/dist/builtins/diff.d.ts.map +1 -0
- package/dist/builtins/diff.js +83 -0
- package/dist/builtins/diff.js.map +1 -0
- package/dist/builtins/edit.d.ts +3 -0
- package/dist/builtins/edit.d.ts.map +1 -0
- package/dist/builtins/edit.js +37 -0
- package/dist/builtins/edit.js.map +1 -0
- package/dist/builtins/glob.d.ts +3 -0
- package/dist/builtins/glob.d.ts.map +1 -0
- package/dist/builtins/glob.js +37 -0
- package/dist/builtins/glob.js.map +1 -0
- package/dist/builtins/grep.d.ts +3 -0
- package/dist/builtins/grep.d.ts.map +1 -0
- package/dist/builtins/grep.js +80 -0
- package/dist/builtins/grep.js.map +1 -0
- package/dist/builtins/read.d.ts +3 -0
- package/dist/builtins/read.d.ts.map +1 -0
- package/dist/builtins/read.js +18 -0
- package/dist/builtins/read.js.map +1 -0
- package/dist/builtins/web-fetch.d.ts +4 -0
- package/dist/builtins/web-fetch.d.ts.map +1 -0
- package/dist/builtins/web-fetch.js +335 -0
- package/dist/builtins/web-fetch.js.map +1 -0
- package/dist/builtins/write.d.ts +3 -0
- package/dist/builtins/write.d.ts.map +1 -0
- package/dist/builtins/write.js +44 -0
- package/dist/builtins/write.js.map +1 -0
- package/dist/builtins.d.ts +6 -0
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +24 -353
- package/dist/builtins.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { AppError, ErrorCode } from "@chances-ai/runtime";
|
|
2
|
+
import { optBool, optNum, str } from "./_shared.js";
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
+
const DEFAULT_MAX_BYTES = 250 * 1024;
|
|
5
|
+
/** Absolute ceiling on caller-supplied `maxBytes`. A misbehaving model could
|
|
6
|
+
* otherwise ask for a multi-GB body and force memory growth. 4 MiB is
|
|
7
|
+
* generous for any realistic doc page while still bounded. */
|
|
8
|
+
const MAX_BYTES_CEILING = 4 * 1024 * 1024;
|
|
9
|
+
const MAX_REDIRECTS = 10;
|
|
10
|
+
const URL_MAX_LENGTH = 2048;
|
|
11
|
+
/**
|
|
12
|
+
* Refuses RFC1918, loopback, link-local, CGNAT, and common internal hostnames.
|
|
13
|
+
* The goal is SSRF defense: a model that asks for `http://169.254.169.254/...`
|
|
14
|
+
* (cloud metadata) or `http://10.0.0.5/admin` (an internal box) must be denied
|
|
15
|
+
* before the gate even prompts. Operators who legitimately want to fetch a
|
|
16
|
+
* local dev server can edit the config — the explicit override is the trust
|
|
17
|
+
* signal, not a silent fallback.
|
|
18
|
+
*/
|
|
19
|
+
function isPrivateIPv4(a, b) {
|
|
20
|
+
if (a === 0)
|
|
21
|
+
return true; // 0.0.0.0/8
|
|
22
|
+
if (a === 10)
|
|
23
|
+
return true; // 10.0.0.0/8
|
|
24
|
+
if (a === 127)
|
|
25
|
+
return true; // loopback
|
|
26
|
+
if (a === 169 && b === 254)
|
|
27
|
+
return true; // link-local
|
|
28
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
29
|
+
return true; // 172.16.0.0/12
|
|
30
|
+
if (a === 192 && b === 168)
|
|
31
|
+
return true; // 192.168.0.0/16
|
|
32
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
33
|
+
return true; // CGNAT 100.64.0.0/10
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* If `inner` is an IPv4-mapped IPv6 address (`::ffff:a.b.c.d` or its hex
|
|
38
|
+
* canonicalization like `::ffff:7f00:1`), return the embedded IPv4 octets.
|
|
39
|
+
* URL parsers (Bun's included) silently canonicalize the dotted form into
|
|
40
|
+
* hex, so a check that only sees `127.0.0.1` literals misses an attacker
|
|
41
|
+
* who writes `[::ffff:127.0.0.1]` — it lands as `[::ffff:7f00:1]` and
|
|
42
|
+
* defeats the IPv4 branch entirely.
|
|
43
|
+
*/
|
|
44
|
+
function parseMappedIPv4(inner) {
|
|
45
|
+
// Bun normalizes `::ffff:127.0.0.1` to `::ffff:7f00:1` and elides leading zeros.
|
|
46
|
+
// Reject early if the address isn't a mapped form.
|
|
47
|
+
const mapped = inner.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
|
|
48
|
+
if (mapped) {
|
|
49
|
+
const hi = parseInt(mapped[1], 16);
|
|
50
|
+
const lo = parseInt(mapped[2], 16);
|
|
51
|
+
return [(hi >> 8) & 0xff, hi & 0xff, (lo >> 8) & 0xff, lo & 0xff];
|
|
52
|
+
}
|
|
53
|
+
// Dotted-quad form preserved (e.g. some parsers leave `::ffff:127.0.0.1`).
|
|
54
|
+
const dotted = inner.match(/^::ffff:(\d+)\.(\d+)\.(\d+)\.(\d+)$/i);
|
|
55
|
+
if (dotted) {
|
|
56
|
+
return [Number(dotted[1]), Number(dotted[2]), Number(dotted[3]), Number(dotted[4])];
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
function isPrivateHost(hostname) {
|
|
61
|
+
// Normalize once: lowercase + strip *all* trailing dots. `localhost.` is
|
|
62
|
+
// the same host as `localhost` in DNS; `localhost..` is malformed but a
|
|
63
|
+
// resolver may still accept it, so a single-dot strip would leave a
|
|
64
|
+
// bypass. Trailing dots are never load-bearing for the public suffix.
|
|
65
|
+
const host = hostname.toLowerCase().replace(/\.+$/, "");
|
|
66
|
+
const ipv4 = host.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
|
|
67
|
+
if (ipv4)
|
|
68
|
+
return isPrivateIPv4(Number(ipv4[1]), Number(ipv4[2]));
|
|
69
|
+
if (host.startsWith("[") && host.endsWith("]")) {
|
|
70
|
+
const inner = host.slice(1, -1);
|
|
71
|
+
if (inner === "::1" || inner === "::")
|
|
72
|
+
return true;
|
|
73
|
+
const mapped = parseMappedIPv4(inner);
|
|
74
|
+
if (mapped)
|
|
75
|
+
return isPrivateIPv4(mapped[0], mapped[1]);
|
|
76
|
+
// Unique local addresses fc00::/7 (covers fc** and fd**).
|
|
77
|
+
if (inner.startsWith("fc") || inner.startsWith("fd"))
|
|
78
|
+
return true;
|
|
79
|
+
// Link-local fe80::/10 — top 10 bits of the first hextet are 1111111010,
|
|
80
|
+
// so the first hextet falls in the range fe80–febf inclusive. `fe80:`
|
|
81
|
+
// alone misses `fea0::1`, `febf::1`, etc.
|
|
82
|
+
const firstHextet = parseInt(inner.split(":")[0], 16);
|
|
83
|
+
if (!Number.isNaN(firstHextet) && (firstHextet & 0xffc0) === 0xfe80)
|
|
84
|
+
return true;
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (host === "localhost")
|
|
88
|
+
return true;
|
|
89
|
+
if (host.endsWith(".localhost"))
|
|
90
|
+
return true;
|
|
91
|
+
if (host.endsWith(".local"))
|
|
92
|
+
return true;
|
|
93
|
+
if (host.endsWith(".internal"))
|
|
94
|
+
return true;
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
function validateUrl(raw) {
|
|
98
|
+
if (raw.length > URL_MAX_LENGTH) {
|
|
99
|
+
throw new AppError(ErrorCode.Tool, `URL too long (>${URL_MAX_LENGTH} chars)`);
|
|
100
|
+
}
|
|
101
|
+
let u;
|
|
102
|
+
try {
|
|
103
|
+
u = new URL(raw);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
throw new AppError(ErrorCode.Tool, `Invalid URL: ${raw}`);
|
|
107
|
+
}
|
|
108
|
+
if (u.protocol !== "http:" && u.protocol !== "https:") {
|
|
109
|
+
throw new AppError(ErrorCode.Tool, `Unsupported URL scheme: ${u.protocol}`);
|
|
110
|
+
}
|
|
111
|
+
if (u.username || u.password) {
|
|
112
|
+
throw new AppError(ErrorCode.Tool, "URL must not contain credentials");
|
|
113
|
+
}
|
|
114
|
+
if (isPrivateHost(u.hostname)) {
|
|
115
|
+
throw new AppError(ErrorCode.Tool, `Refusing to fetch private/local address: ${u.hostname}`);
|
|
116
|
+
}
|
|
117
|
+
return u;
|
|
118
|
+
}
|
|
119
|
+
/** Same registrable host, or one is the `www.` variant of the other. */
|
|
120
|
+
function isSameHostOrWwwVariant(a, b) {
|
|
121
|
+
if (a.host === b.host)
|
|
122
|
+
return true;
|
|
123
|
+
const stripWww = (h) => (h.startsWith("www.") ? h.slice(4) : h);
|
|
124
|
+
return stripWww(a.host) === stripWww(b.host);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Minimal HTML → readable text. Deliberately string-based (no DOM, no turndown
|
|
128
|
+
* dep) for v1: we trade markdown fidelity for a 60-LoC implementation with
|
|
129
|
+
* zero new dependencies. Most use cases (docs, README mirrors, news pages)
|
|
130
|
+
* survive this cleanly; rich pages still produce *readable* text even if the
|
|
131
|
+
* markdown is rough. `raw: true` bypasses this entirely for callers that want
|
|
132
|
+
* the original HTML. A turndown / readability upgrade is a v2+ candidate.
|
|
133
|
+
*/
|
|
134
|
+
function decodeEntities(s) {
|
|
135
|
+
return s
|
|
136
|
+
.replace(/ /g, " ")
|
|
137
|
+
.replace(/&/g, "&")
|
|
138
|
+
.replace(/</g, "<")
|
|
139
|
+
.replace(/>/g, ">")
|
|
140
|
+
.replace(/"/g, '"')
|
|
141
|
+
.replace(/'/g, "'")
|
|
142
|
+
.replace(/'/g, "'");
|
|
143
|
+
}
|
|
144
|
+
export function htmlToText(html) {
|
|
145
|
+
// Capture title before we touch tags — a title like `<title>A <b>B</b></title>`
|
|
146
|
+
// would otherwise either keep `<b>` (bad heading) or get duplicated as body
|
|
147
|
+
// text after we strip and replace block tags.
|
|
148
|
+
const titleMatch = html.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
|
|
149
|
+
const title = titleMatch?.[1] ? decodeEntities(titleMatch[1].replace(/<[^>]+>/g, "")).trim() : "";
|
|
150
|
+
let s = html
|
|
151
|
+
.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "")
|
|
152
|
+
.replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "")
|
|
153
|
+
// Best-effort: an unclosed <script> or <style> would otherwise leak its
|
|
154
|
+
// body into output. Drop everything from an unclosed opener to end.
|
|
155
|
+
.replace(/<script\b[^>]*>[\s\S]*$/gi, "")
|
|
156
|
+
.replace(/<style\b[^>]*>[\s\S]*$/gi, "")
|
|
157
|
+
.replace(/<!--[\s\S]*?-->/g, "")
|
|
158
|
+
// Strip the captured title block so it isn't duplicated in body output.
|
|
159
|
+
.replace(/<title[^>]*>[\s\S]*?<\/title>/gi, "")
|
|
160
|
+
.replace(/<\/(p|div|section|article|li|tr|h[1-6])[^>]*>/gi, "\n\n")
|
|
161
|
+
.replace(/<(p|div|section|article|li|tr|h[1-6])[^>]*>/gi, "\n")
|
|
162
|
+
.replace(/<br\s*\/?>/gi, "\n")
|
|
163
|
+
.replace(/<hr\s*\/?>/gi, "\n---\n")
|
|
164
|
+
.replace(/<[^>]+>/g, "");
|
|
165
|
+
s = decodeEntities(s)
|
|
166
|
+
.replace(/[ \t]+/g, " ")
|
|
167
|
+
.replace(/\n[ \t]+/g, "\n")
|
|
168
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
169
|
+
.trim();
|
|
170
|
+
if (title)
|
|
171
|
+
return `# ${title}\n\n${s}`;
|
|
172
|
+
return s;
|
|
173
|
+
}
|
|
174
|
+
async function readBodyCapped(res, maxBytes) {
|
|
175
|
+
const reader = res.body?.getReader();
|
|
176
|
+
if (!reader)
|
|
177
|
+
return { body: "", truncated: false };
|
|
178
|
+
const chunks = [];
|
|
179
|
+
let received = 0;
|
|
180
|
+
let truncated = false;
|
|
181
|
+
for (;;) {
|
|
182
|
+
const { value, done } = await reader.read();
|
|
183
|
+
if (done)
|
|
184
|
+
break;
|
|
185
|
+
if (received + value.byteLength > maxBytes) {
|
|
186
|
+
const room = maxBytes - received;
|
|
187
|
+
if (room > 0)
|
|
188
|
+
chunks.push(value.subarray(0, room));
|
|
189
|
+
truncated = true;
|
|
190
|
+
try {
|
|
191
|
+
await reader.cancel();
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
/* best-effort */
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
chunks.push(value);
|
|
199
|
+
received += value.byteLength;
|
|
200
|
+
}
|
|
201
|
+
// Decode as UTF-8; lossy for non-UTF responses but the LLM will see "?" runs
|
|
202
|
+
// rather than crash. We mark Content-Type in the header so the model knows.
|
|
203
|
+
const total = chunks.reduce((acc, c) => acc + c.byteLength, 0);
|
|
204
|
+
const merged = new Uint8Array(total);
|
|
205
|
+
let offset = 0;
|
|
206
|
+
for (const c of chunks) {
|
|
207
|
+
merged.set(c, offset);
|
|
208
|
+
offset += c.byteLength;
|
|
209
|
+
}
|
|
210
|
+
return { body: new TextDecoder("utf-8", { fatal: false }).decode(merged), truncated };
|
|
211
|
+
}
|
|
212
|
+
async function followRedirects(initial, signal, maxBytes) {
|
|
213
|
+
let url = initial;
|
|
214
|
+
let redirectsLeft = MAX_REDIRECTS;
|
|
215
|
+
for (;;) {
|
|
216
|
+
const res = await fetch(url.toString(), { redirect: "manual", signal });
|
|
217
|
+
const status = res.status;
|
|
218
|
+
if (status >= 300 && status < 400) {
|
|
219
|
+
const loc = res.headers.get("location");
|
|
220
|
+
if (loc) {
|
|
221
|
+
if (redirectsLeft-- === 0) {
|
|
222
|
+
throw new AppError(ErrorCode.Tool, `Too many redirects (>${MAX_REDIRECTS})`);
|
|
223
|
+
}
|
|
224
|
+
const target = new URL(loc, url);
|
|
225
|
+
// Re-validate: a redirect to file://, localhost, or a private IP must
|
|
226
|
+
// be refused regardless of how friendly the source URL looked.
|
|
227
|
+
validateUrl(target.toString());
|
|
228
|
+
if (!isSameHostOrWwwVariant(url, target)) {
|
|
229
|
+
try {
|
|
230
|
+
await res.body?.cancel();
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
/* best-effort */
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
finalUrl: url.toString(),
|
|
237
|
+
status,
|
|
238
|
+
contentType: "text/plain",
|
|
239
|
+
body: `Cross-host redirect to ${target.toString()} — re-invoke web_fetch with the new URL if you trust it.`,
|
|
240
|
+
truncated: false,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
await res.body?.cancel();
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
/* best-effort */
|
|
248
|
+
}
|
|
249
|
+
url = target;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
254
|
+
const { body, truncated } = await readBodyCapped(res, maxBytes);
|
|
255
|
+
return { finalUrl: url.toString(), status, contentType, body, truncated };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
export const webFetchTool = {
|
|
259
|
+
name: "web_fetch",
|
|
260
|
+
description: "Fetch a URL and return its content as text the model can read. http(s) only; literal private IPs (RFC1918, loopback, link-local, CGNAT, IPv4-mapped IPv6) and credentials in the URL are rejected. Note: lexical filtering only — a public hostname that DNS-resolves to a private address is NOT blocked at the validator (a v2+ item); the per-call `network-read` prompt is the user-side defense. text/html is reduced to readable text; JSON / markdown / plain text pass through. Use raw:true to get the unprocessed body. Cross-host redirects are not followed automatically — a one-line note is returned instead so the model can re-invoke with the new URL.",
|
|
261
|
+
category: "network-read",
|
|
262
|
+
parameters: {
|
|
263
|
+
type: "object",
|
|
264
|
+
properties: {
|
|
265
|
+
url: { type: "string", description: "Absolute http(s) URL to fetch." },
|
|
266
|
+
raw: { type: "boolean", description: "Skip HTML→text reduction; return the body as received." },
|
|
267
|
+
maxBytes: {
|
|
268
|
+
type: "number",
|
|
269
|
+
description: `Cap on body bytes (default ${DEFAULT_MAX_BYTES}). Responses are truncated to fit.`,
|
|
270
|
+
},
|
|
271
|
+
timeoutMs: {
|
|
272
|
+
type: "number",
|
|
273
|
+
description: `Per-request timeout in ms (default ${DEFAULT_TIMEOUT_MS}).`,
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
required: ["url"],
|
|
277
|
+
},
|
|
278
|
+
summarize: (args) => `web_fetch ${str(args, "url")}`,
|
|
279
|
+
async execute(args, ctx) {
|
|
280
|
+
const raw = optBool(args, "raw") ?? false;
|
|
281
|
+
const requestedMaxBytes = optNum(args, "maxBytes") ?? DEFAULT_MAX_BYTES;
|
|
282
|
+
// Clamp model-controlled cap into [1, MAX_BYTES_CEILING]. Non-positive /
|
|
283
|
+
// non-finite values fall through to the default — silently accepting "0"
|
|
284
|
+
// would always return an empty body which is unhelpful, and accepting a
|
|
285
|
+
// huge value would let a model force memory growth.
|
|
286
|
+
const maxBytes = Number.isFinite(requestedMaxBytes) && requestedMaxBytes >= 1
|
|
287
|
+
? Math.min(Math.floor(requestedMaxBytes), MAX_BYTES_CEILING)
|
|
288
|
+
: DEFAULT_MAX_BYTES;
|
|
289
|
+
const timeoutMs = optNum(args, "timeoutMs") ?? DEFAULT_TIMEOUT_MS;
|
|
290
|
+
let initial;
|
|
291
|
+
try {
|
|
292
|
+
initial = validateUrl(str(args, "url"));
|
|
293
|
+
}
|
|
294
|
+
catch (e) {
|
|
295
|
+
return { ok: false, output: e.message };
|
|
296
|
+
}
|
|
297
|
+
// Compose request timeout + caller cancel into one signal.
|
|
298
|
+
const ac = new AbortController();
|
|
299
|
+
const timer = setTimeout(() => ac.abort(new Error(`Timeout after ${timeoutMs} ms`)), timeoutMs);
|
|
300
|
+
let onAbort;
|
|
301
|
+
if (ctx.signal.aborted) {
|
|
302
|
+
ac.abort(ctx.signal.reason ?? new Error("Cancelled"));
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
onAbort = () => ac.abort(ctx.signal.reason ?? new Error("Cancelled"));
|
|
306
|
+
ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
307
|
+
}
|
|
308
|
+
try {
|
|
309
|
+
const r = await followRedirects(initial, ac.signal, maxBytes);
|
|
310
|
+
const isHtml = /^\s*text\/html\b/i.test(r.contentType);
|
|
311
|
+
const body = !raw && isHtml ? htmlToText(r.body) : r.body;
|
|
312
|
+
const header = [
|
|
313
|
+
`URL: ${initial.toString()}`,
|
|
314
|
+
`Final-URL: ${r.finalUrl}`,
|
|
315
|
+
`Status: ${r.status}`,
|
|
316
|
+
`Content-Type: ${r.contentType}`,
|
|
317
|
+
`Truncated: ${r.truncated}`,
|
|
318
|
+
].join("\n");
|
|
319
|
+
// ok:true even for HTTP 4xx/5xx — the model can read the status line in
|
|
320
|
+
// the header and the error body below. ok:false is reserved for network
|
|
321
|
+
// / validation / timeout failures where there's nothing meaningful to return.
|
|
322
|
+
return { ok: true, output: `${header}\n\n${body}` };
|
|
323
|
+
}
|
|
324
|
+
catch (e) {
|
|
325
|
+
const err = e;
|
|
326
|
+
return { ok: false, output: `web_fetch failed: ${err.message}` };
|
|
327
|
+
}
|
|
328
|
+
finally {
|
|
329
|
+
clearTimeout(timer);
|
|
330
|
+
if (onAbort)
|
|
331
|
+
ctx.signal.removeEventListener("abort", onAbort);
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
//# sourceMappingURL=web-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-fetch.js","sourceRoot":"","sources":["../../src/builtins/web-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/builtins/write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,aAAa,CAAC;AAGpD,eAAO,MAAM,SAAS,EAAE,IAoCvB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { linesDiff } from "../diff.js";
|
|
4
|
+
import { PREVIEW_BYTE_CAP, safePath, str } from "./_shared.js";
|
|
5
|
+
export const writeTool = {
|
|
6
|
+
name: "write",
|
|
7
|
+
description: "Create or overwrite a file in the workspace.",
|
|
8
|
+
category: "file-write",
|
|
9
|
+
parameters: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: { path: { type: "string" }, content: { type: "string" } },
|
|
12
|
+
required: ["path", "content"],
|
|
13
|
+
},
|
|
14
|
+
summarize: (args, ctx) => {
|
|
15
|
+
const path = str(args, "path");
|
|
16
|
+
const content = str(args, "content");
|
|
17
|
+
let abs = null;
|
|
18
|
+
try {
|
|
19
|
+
abs = safePath(ctx, path);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return `write ${path} (${content.length} bytes)`;
|
|
23
|
+
}
|
|
24
|
+
if (!existsSync(abs)) {
|
|
25
|
+
const lineCount = content === "" ? 0 : content.split("\n").length;
|
|
26
|
+
return `create ${path} (${content.length} bytes, ${lineCount} lines)`;
|
|
27
|
+
}
|
|
28
|
+
const priorSize = statSync(abs).size;
|
|
29
|
+
if (priorSize > PREVIEW_BYTE_CAP || content.length > PREVIEW_BYTE_CAP) {
|
|
30
|
+
return `overwrite ${path} (${priorSize} → ${content.length} bytes; diff preview skipped)`;
|
|
31
|
+
}
|
|
32
|
+
const before = readFileSync(abs, "utf8");
|
|
33
|
+
if (before === content)
|
|
34
|
+
return `overwrite ${path} (no changes)`;
|
|
35
|
+
return `overwrite ${path}\n${linesDiff(before, content)}`;
|
|
36
|
+
},
|
|
37
|
+
async execute(args, ctx) {
|
|
38
|
+
const path = safePath(ctx, str(args, "path"));
|
|
39
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
40
|
+
writeFileSync(path, str(args, "content"));
|
|
41
|
+
return { ok: true, output: `Wrote ${str(args, "path")}` };
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/builtins/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAE/D,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,8CAA8C;IAC3D,QAAQ,EAAE,YAAY;IACtB,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACrE,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;KAC9B;IACD,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACrC,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,IAAI,CAAC;YACH,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,IAAI,KAAK,OAAO,CAAC,MAAM,SAAS,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAClE,OAAO,UAAU,IAAI,KAAK,OAAO,CAAC,MAAM,WAAW,SAAS,SAAS,CAAC;QACxE,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACrC,IAAI,SAAS,GAAG,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;YACtE,OAAO,aAAa,IAAI,KAAK,SAAS,MAAM,OAAO,CAAC,MAAM,+BAA+B,CAAC;QAC5F,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,aAAa,IAAI,eAAe,CAAC;QAChE,OAAO,aAAa,IAAI,KAAK,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC5D,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9C,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;IAC5D,CAAC;CACF,CAAC"}
|
package/dist/builtins.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { Tool } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registry of first-party tools the engine ships with. New tools live in their
|
|
4
|
+
* own module under `./builtins/<name>.ts`; this file is a pure barrel so the
|
|
5
|
+
* registration surface stays one-line-per-tool and reviewers can see the full
|
|
6
|
+
* tool inventory at a glance.
|
|
7
|
+
*/
|
|
2
8
|
export declare const builtinTools: Tool[];
|
|
3
9
|
//# sourceMappingURL=builtins.d.ts.map
|
package/dist/builtins.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAUvC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,IAAI,EAS9B,CAAC"}
|