@agentick/sandbox 0.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/README.md +251 -0
- package/dist/component.d.ts +43 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +41 -0
- package/dist/component.js.map +1 -0
- package/dist/context.d.ts +26 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +32 -0
- package/dist/context.js.map +1 -0
- package/dist/edit.d.ts +62 -0
- package/dist/edit.d.ts.map +1 -0
- package/dist/edit.js +270 -0
- package/dist/edit.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/testing.d.ts +29 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +49 -0
- package/dist/testing.js.map +1 -0
- package/dist/tools.d.ts +37 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +93 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +156 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +65 -0
- package/src/index.ts +40 -0
package/dist/edit.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surgical Code Editing
|
|
3
|
+
*
|
|
4
|
+
* LLM-driven code editing with layered matching that recovers from
|
|
5
|
+
* trailing whitespace, indentation mismatch, and CRLF/LF differences.
|
|
6
|
+
*
|
|
7
|
+
* Pure transform (`applyEdits`) + file wrapper (`editFile`) with atomic writes.
|
|
8
|
+
*/
|
|
9
|
+
import { readFile, writeFile, rename, unlink } from "node:fs/promises";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
11
|
+
import { randomBytes } from "node:crypto";
|
|
12
|
+
export class EditError extends Error {
|
|
13
|
+
editIndex;
|
|
14
|
+
detail;
|
|
15
|
+
constructor(message, editIndex, detail) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.editIndex = editIndex;
|
|
18
|
+
this.detail = detail;
|
|
19
|
+
this.name = "EditError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Precompute byte offset of each line start. */
|
|
23
|
+
function lineStarts(source) {
|
|
24
|
+
const starts = [0];
|
|
25
|
+
for (let i = 0; i < source.length; i++) {
|
|
26
|
+
if (source[i] === "\n")
|
|
27
|
+
starts.push(i + 1);
|
|
28
|
+
}
|
|
29
|
+
return starts;
|
|
30
|
+
}
|
|
31
|
+
/** 1-based line number at byte offset. */
|
|
32
|
+
function lineAtOffset(starts, offset) {
|
|
33
|
+
let lo = 0, hi = starts.length - 1;
|
|
34
|
+
while (lo < hi) {
|
|
35
|
+
const mid = (lo + hi + 1) >> 1;
|
|
36
|
+
if (starts[mid] <= offset)
|
|
37
|
+
lo = mid;
|
|
38
|
+
else
|
|
39
|
+
hi = mid - 1;
|
|
40
|
+
}
|
|
41
|
+
return lo + 1; // 1-based
|
|
42
|
+
}
|
|
43
|
+
/** Byte range covering lines [startLine, endLine] (0-indexed, inclusive). */
|
|
44
|
+
function lineRange(source, starts, sourceLines, startLine, endLine) {
|
|
45
|
+
const start = starts[startLine];
|
|
46
|
+
// End = start of endLine + its length (excludes trailing \n)
|
|
47
|
+
const end = starts[endLine] + sourceLines[endLine].length;
|
|
48
|
+
return { start, end };
|
|
49
|
+
}
|
|
50
|
+
function countNewlines(s) {
|
|
51
|
+
let n = 0;
|
|
52
|
+
for (let i = 0; i < s.length; i++) {
|
|
53
|
+
if (s[i] === "\n")
|
|
54
|
+
n++;
|
|
55
|
+
}
|
|
56
|
+
return n;
|
|
57
|
+
}
|
|
58
|
+
/** Minimum leading whitespace of non-empty lines. */
|
|
59
|
+
function minIndent(lines) {
|
|
60
|
+
let min = Infinity;
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
if (line.trim() === "")
|
|
63
|
+
continue;
|
|
64
|
+
const indent = line.length - line.trimStart().length;
|
|
65
|
+
if (indent < min)
|
|
66
|
+
min = indent;
|
|
67
|
+
}
|
|
68
|
+
return min === Infinity ? 0 : min;
|
|
69
|
+
}
|
|
70
|
+
/** Find all non-overlapping occurrences. */
|
|
71
|
+
function findAll(source, needle) {
|
|
72
|
+
if (needle.length === 0)
|
|
73
|
+
return [];
|
|
74
|
+
const positions = [];
|
|
75
|
+
let pos = 0;
|
|
76
|
+
while ((pos = source.indexOf(needle, pos)) !== -1) {
|
|
77
|
+
positions.push(pos);
|
|
78
|
+
pos += needle.length;
|
|
79
|
+
}
|
|
80
|
+
return positions;
|
|
81
|
+
}
|
|
82
|
+
/** Slide `needle` lines over `haystack` lines, comparing with `cmp`. */
|
|
83
|
+
function slideMatch(haystackLines, needleLines, cmp) {
|
|
84
|
+
const windowSize = needleLines.length;
|
|
85
|
+
for (let i = 0; i <= haystackLines.length - windowSize; i++) {
|
|
86
|
+
let match = true;
|
|
87
|
+
for (let j = 0; j < windowSize; j++) {
|
|
88
|
+
if (!cmp(haystackLines[i + j], needleLines[j])) {
|
|
89
|
+
match = false;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (match)
|
|
94
|
+
return i; // 0-indexed line
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Adjust `replacement` indentation to match the delta between
|
|
100
|
+
* the `old` string and the actual matched source block.
|
|
101
|
+
*/
|
|
102
|
+
function adjustIndent(oldStr, matchedStr, newStr) {
|
|
103
|
+
const oldLines = oldStr.split("\n");
|
|
104
|
+
const matchedLines = matchedStr.split("\n");
|
|
105
|
+
const delta = minIndent(matchedLines) - minIndent(oldLines);
|
|
106
|
+
if (delta === 0)
|
|
107
|
+
return newStr;
|
|
108
|
+
const pad = " ".repeat(Math.abs(delta));
|
|
109
|
+
return newStr
|
|
110
|
+
.split("\n")
|
|
111
|
+
.map((line) => {
|
|
112
|
+
if (line.trim() === "")
|
|
113
|
+
return line;
|
|
114
|
+
if (delta > 0)
|
|
115
|
+
return pad + line;
|
|
116
|
+
return line.startsWith(pad) ? line.slice(pad.length) : line.trimStart();
|
|
117
|
+
})
|
|
118
|
+
.join("\n");
|
|
119
|
+
}
|
|
120
|
+
// ── Core: Pure Transform ─────────────────────────────────────────────────────
|
|
121
|
+
/**
|
|
122
|
+
* Apply edits to a source string. Pure function, no I/O.
|
|
123
|
+
*
|
|
124
|
+
* Matching strategy per edit (in order):
|
|
125
|
+
* 1. Exact byte match
|
|
126
|
+
* 2. Line-normalized (trailing whitespace stripped)
|
|
127
|
+
* 3. Indent-adjusted (leading whitespace baseline stripped, new indentation adjusted)
|
|
128
|
+
*
|
|
129
|
+
* Multi-edit: all matches resolved against original source,
|
|
130
|
+
* validated for overlap, applied bottom-to-top.
|
|
131
|
+
*
|
|
132
|
+
* @throws EditError on match failure or overlapping edits
|
|
133
|
+
*/
|
|
134
|
+
export function applyEdits(source, edits) {
|
|
135
|
+
if (edits.length === 0)
|
|
136
|
+
return { content: source, applied: 0, changes: [] };
|
|
137
|
+
// Normalize CRLF once. Code files should use LF.
|
|
138
|
+
source = source.replace(/\r\n/g, "\n");
|
|
139
|
+
const starts = lineStarts(source);
|
|
140
|
+
const sourceLines = source.split("\n");
|
|
141
|
+
const replacements = [];
|
|
142
|
+
for (let i = 0; i < edits.length; i++) {
|
|
143
|
+
const edit = edits[i];
|
|
144
|
+
if (edit.old.length === 0) {
|
|
145
|
+
throw new EditError(`Edit ${i}: old string cannot be empty.`, i);
|
|
146
|
+
}
|
|
147
|
+
const old = edit.old.replace(/\r\n/g, "\n");
|
|
148
|
+
const neu = edit.new.replace(/\r\n/g, "\n");
|
|
149
|
+
// ── Strategy 1: Exact match ──────────────────────────────────────────
|
|
150
|
+
const positions = findAll(source, old);
|
|
151
|
+
if (positions.length > 0) {
|
|
152
|
+
if (edit.all) {
|
|
153
|
+
for (const pos of positions) {
|
|
154
|
+
replacements.push({ start: pos, end: pos + old.length, content: neu, editIndex: i });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (positions.length === 1) {
|
|
158
|
+
replacements.push({
|
|
159
|
+
start: positions[0],
|
|
160
|
+
end: positions[0] + old.length,
|
|
161
|
+
content: neu,
|
|
162
|
+
editIndex: i,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const lines = positions.map((p) => lineAtOffset(starts, p));
|
|
167
|
+
throw new EditError(`Edit ${i}: ${positions.length} matches found (lines ${lines.join(", ")}). ` +
|
|
168
|
+
`Include more surrounding context to disambiguate, or use all: true.`, i);
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
// all: true edits only use exact match — skip fallbacks
|
|
173
|
+
if (edit.all) {
|
|
174
|
+
// Zero matches with all: true is a no-op, not an error
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const oldLines = old.split("\n");
|
|
178
|
+
// ── Strategy 2: Line-normalized (strip trailing WS) ──────────────────
|
|
179
|
+
const normSourceLines = sourceLines.map((l) => l.trimEnd());
|
|
180
|
+
const normOldLines = oldLines.map((l) => l.trimEnd());
|
|
181
|
+
const normHit = slideMatch(normSourceLines, normOldLines, (a, b) => a === b);
|
|
182
|
+
if (normHit !== null) {
|
|
183
|
+
const { start, end } = lineRange(source, starts, sourceLines, normHit, normHit + oldLines.length - 1);
|
|
184
|
+
replacements.push({ start, end, content: neu, editIndex: i });
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
// ── Strategy 3: Indent-adjusted (strip indent baseline, compare shapes)
|
|
188
|
+
const indentHit = (() => {
|
|
189
|
+
const baseIndent = minIndent(oldLines);
|
|
190
|
+
const strippedNeedle = oldLines.map((l) => (l.trim() === "" ? "" : l.slice(baseIndent)));
|
|
191
|
+
for (let si = 0; si <= sourceLines.length - oldLines.length; si++) {
|
|
192
|
+
const window = sourceLines.slice(si, si + oldLines.length);
|
|
193
|
+
const windowIndent = minIndent(window);
|
|
194
|
+
const strippedWindow = window.map((l) => (l.trim() === "" ? "" : l.slice(windowIndent)));
|
|
195
|
+
if (strippedNeedle.every((line, j) => line === strippedWindow[j])) {
|
|
196
|
+
return si;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
})();
|
|
201
|
+
if (indentHit !== null) {
|
|
202
|
+
const { start, end } = lineRange(source, starts, sourceLines, indentHit, indentHit + oldLines.length - 1);
|
|
203
|
+
const matched = source.slice(start, end);
|
|
204
|
+
const adjusted = adjustIndent(old, matched, neu);
|
|
205
|
+
replacements.push({ start, end, content: adjusted, editIndex: i });
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// ── No match — diagnostic error ──────────────────────────────────────
|
|
209
|
+
const firstLine = oldLines[0].trim();
|
|
210
|
+
let closestLine = -1;
|
|
211
|
+
for (let j = 0; j < sourceLines.length; j++) {
|
|
212
|
+
if (sourceLines[j].includes(firstLine)) {
|
|
213
|
+
closestLine = j + 1;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
throw new EditError(`Edit ${i}: no match found` +
|
|
218
|
+
(closestLine > 0 ? ` (first line appears near line ${closestLine})` : "") +
|
|
219
|
+
`. First line: "${firstLine.slice(0, 80)}"`, i, closestLine > 0 ? { closest: sourceLines[closestLine - 1], line: closestLine } : undefined);
|
|
220
|
+
}
|
|
221
|
+
// ── Validate no overlaps ───────────────────────────────────────────────
|
|
222
|
+
const sorted = [...replacements].sort((a, b) => a.start - b.start);
|
|
223
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
224
|
+
if (sorted[i].start < sorted[i - 1].end) {
|
|
225
|
+
throw new EditError(`Edits ${sorted[i - 1].editIndex} and ${sorted[i].editIndex} overlap at offset ${sorted[i].start}.`, sorted[i].editIndex);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// ── Apply bottom-to-top ────────────────────────────────────────────────
|
|
229
|
+
sorted.sort((a, b) => b.start - a.start);
|
|
230
|
+
let result = source;
|
|
231
|
+
const changes = [];
|
|
232
|
+
for (const rep of sorted) {
|
|
233
|
+
const before = result.slice(rep.start, rep.end);
|
|
234
|
+
result = result.slice(0, rep.start) + rep.content + result.slice(rep.end);
|
|
235
|
+
changes.push({
|
|
236
|
+
line: lineAtOffset(starts, rep.start),
|
|
237
|
+
removed: countNewlines(before) + 1,
|
|
238
|
+
added: countNewlines(rep.content) + 1,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
changes.reverse(); // document order
|
|
242
|
+
return { content: result, applied: replacements.length, changes };
|
|
243
|
+
}
|
|
244
|
+
// ── File Wrapper ─────────────────────────────────────────────────────────────
|
|
245
|
+
/**
|
|
246
|
+
* Edit a file on disk. Reads, applies edits, writes atomically (temp + rename).
|
|
247
|
+
*/
|
|
248
|
+
export async function editFile(path, edits) {
|
|
249
|
+
const source = await readFile(path, "utf-8");
|
|
250
|
+
const result = applyEdits(source, edits);
|
|
251
|
+
if (result.applied === 0)
|
|
252
|
+
return result;
|
|
253
|
+
// Atomic write: temp in same dir (same filesystem), then rename
|
|
254
|
+
const tmp = join(dirname(path), `.edit-${randomBytes(6).toString("hex")}.tmp`);
|
|
255
|
+
try {
|
|
256
|
+
await writeFile(tmp, result.content, "utf-8");
|
|
257
|
+
await rename(tmp, path);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
try {
|
|
261
|
+
await unlink(tmp);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Ignore cleanup errors
|
|
265
|
+
}
|
|
266
|
+
throw err;
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=edit.js.map
|
package/dist/edit.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../src/edit.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agentick/sandbox - Sandbox primitive layer
|
|
3
|
+
*
|
|
4
|
+
* Types, context, component, and pre-built tools for sandboxed execution.
|
|
5
|
+
*/
|
|
6
|
+
export type { Sandbox as SandboxHandle, SandboxProvider, SandboxCreateOptions, SandboxConfig, SandboxSnapshot, ExecOptions, ExecResult, OutputChunk, Mount, Permissions, ResourceLimits, NetworkRule, ProxiedRequest, } from "./types";
|
|
7
|
+
export { applyEdits, editFile, EditError } from "./edit";
|
|
8
|
+
export type { Edit, EditResult, EditChange } from "./edit";
|
|
9
|
+
export { SandboxContext, useSandbox } from "./context";
|
|
10
|
+
export { Sandbox } from "./component";
|
|
11
|
+
export type { SandboxProps } from "./component";
|
|
12
|
+
export { Shell, ReadFile, WriteFile, EditFile } from "./tools";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,OAAO,IAAI,aAAa,EACxB,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,KAAK,EACL,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agentick/sandbox - Sandbox primitive layer
|
|
3
|
+
*
|
|
4
|
+
* Types, context, component, and pre-built tools for sandboxed execution.
|
|
5
|
+
*/
|
|
6
|
+
// ── Edit Types & Utilities ───────────────────────────────────────────────────
|
|
7
|
+
export { applyEdits, editFile, EditError } from "./edit";
|
|
8
|
+
// ── Context & Hook ───────────────────────────────────────────────────────────
|
|
9
|
+
export { SandboxContext, useSandbox } from "./context";
|
|
10
|
+
// ── Component ────────────────────────────────────────────────────────────────
|
|
11
|
+
export { Sandbox } from "./component";
|
|
12
|
+
// ── Tools ────────────────────────────────────────────────────────────────────
|
|
13
|
+
export { Shell, ReadFile, WriteFile, EditFile } from "./tools";
|
|
14
|
+
// ── Testing ──────────────────────────────────────────────────────────────────
|
|
15
|
+
// Import from "@agentick/sandbox/testing" — not re-exported here to avoid
|
|
16
|
+
// pulling vitest into production bundles.
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGzD,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvD,gFAAgF;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,gFAAgF;AAChF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,gFAAgF;AAChF,0EAA0E;AAC1E,0CAA0C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox Testing Utilities
|
|
3
|
+
*
|
|
4
|
+
* Mock implementations for testing sandbox consumers and provider adapters.
|
|
5
|
+
*/
|
|
6
|
+
import type { Sandbox, SandboxProvider } from "./types";
|
|
7
|
+
/**
|
|
8
|
+
* Create a mock Sandbox with vi.fn() stubs and sensible defaults.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const sandbox = createMockSandbox({
|
|
13
|
+
* exec: vi.fn().mockResolvedValue({ stdout: "hello", stderr: "", exitCode: 0 }),
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function createMockSandbox(overrides?: Partial<Sandbox>): Sandbox;
|
|
18
|
+
/**
|
|
19
|
+
* Create a mock SandboxProvider whose create() returns a mock sandbox.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const provider = createMockProvider();
|
|
24
|
+
* const sandbox = await provider.create({});
|
|
25
|
+
* expect(sandbox.id).toBe("mock-sandbox-1");
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function createMockProvider(overrides?: Partial<SandboxProvider>): SandboxProvider;
|
|
29
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAc,MAAM,SAAS,CAAC;AAGpE;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAcvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAQxF"}
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox Testing Utilities
|
|
3
|
+
*
|
|
4
|
+
* Mock implementations for testing sandbox consumers and provider adapters.
|
|
5
|
+
*/
|
|
6
|
+
import { vi } from "vitest";
|
|
7
|
+
/**
|
|
8
|
+
* Create a mock Sandbox with vi.fn() stubs and sensible defaults.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const sandbox = createMockSandbox({
|
|
13
|
+
* exec: vi.fn().mockResolvedValue({ stdout: "hello", stderr: "", exitCode: 0 }),
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function createMockSandbox(overrides) {
|
|
18
|
+
const defaultExecResult = { stdout: "", stderr: "", exitCode: 0 };
|
|
19
|
+
const defaultEditResult = { content: "", applied: 0, changes: [] };
|
|
20
|
+
return {
|
|
21
|
+
id: "mock-sandbox-1",
|
|
22
|
+
workspacePath: "/tmp/mock-sandbox",
|
|
23
|
+
exec: vi.fn().mockResolvedValue(defaultExecResult),
|
|
24
|
+
readFile: vi.fn().mockResolvedValue(""),
|
|
25
|
+
writeFile: vi.fn().mockResolvedValue(undefined),
|
|
26
|
+
editFile: vi.fn().mockResolvedValue(defaultEditResult),
|
|
27
|
+
destroy: vi.fn().mockResolvedValue(undefined),
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a mock SandboxProvider whose create() returns a mock sandbox.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const provider = createMockProvider();
|
|
37
|
+
* const sandbox = await provider.create({});
|
|
38
|
+
* expect(sandbox.id).toBe("mock-sandbox-1");
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function createMockProvider(overrides) {
|
|
42
|
+
const mockSandbox = createMockSandbox();
|
|
43
|
+
return {
|
|
44
|
+
name: "mock",
|
|
45
|
+
create: vi.fn().mockResolvedValue(mockSandbox),
|
|
46
|
+
...overrides,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAI5B;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAA4B;IAC5D,MAAM,iBAAiB,GAAe,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAC9E,MAAM,iBAAiB,GAAe,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAE/E,OAAO;QACL,EAAE,EAAE,gBAAgB;QACpB,aAAa,EAAE,mBAAmB;QAClC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;QAClD,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAC/C,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;QACtD,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAC7C,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAoC;IACrE,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;IAExC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC;QAC9C,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-built Sandbox Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools that access the sandbox from the component tree via useSandbox().
|
|
5
|
+
* Tree-scoped — multiple sandboxes just work, each tool accesses its nearest provider.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Execute a shell command in the sandbox.
|
|
9
|
+
*/
|
|
10
|
+
export declare const Shell: import("@agentick/core/tool").RunnableToolClass<{
|
|
11
|
+
command: string;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* Read a file from the sandbox filesystem.
|
|
15
|
+
*/
|
|
16
|
+
export declare const ReadFile: import("@agentick/core/tool").RunnableToolClass<{
|
|
17
|
+
path: string;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Write a file to the sandbox filesystem.
|
|
21
|
+
*/
|
|
22
|
+
export declare const WriteFile: import("@agentick/core/tool").RunnableToolClass<{
|
|
23
|
+
path: string;
|
|
24
|
+
content: string;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Apply surgical edits to a file in the sandbox.
|
|
28
|
+
*/
|
|
29
|
+
export declare const EditFile: import("@agentick/core/tool").RunnableToolClass<{
|
|
30
|
+
path: string;
|
|
31
|
+
edits: {
|
|
32
|
+
old: string;
|
|
33
|
+
new: string;
|
|
34
|
+
all?: boolean | undefined;
|
|
35
|
+
}[];
|
|
36
|
+
}>;
|
|
37
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,eAAO,MAAM,KAAK;;EAehB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ;;EAWnB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,SAAS;;;EAYpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;EA6BnB,CAAC"}
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-built Sandbox Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools that access the sandbox from the component tree via useSandbox().
|
|
5
|
+
* Tree-scoped — multiple sandboxes just work, each tool accesses its nearest provider.
|
|
6
|
+
*/
|
|
7
|
+
import { createTool } from "@agentick/core";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { useSandbox } from "./context";
|
|
10
|
+
/**
|
|
11
|
+
* Execute a shell command in the sandbox.
|
|
12
|
+
*/
|
|
13
|
+
export const Shell = createTool({
|
|
14
|
+
name: "shell",
|
|
15
|
+
description: "Execute a shell command in the sandbox environment.",
|
|
16
|
+
input: z.object({
|
|
17
|
+
command: z.string().describe("The shell command to execute."),
|
|
18
|
+
}),
|
|
19
|
+
use: () => ({ sandbox: useSandbox() }),
|
|
20
|
+
handler: async ({ command }, deps) => {
|
|
21
|
+
const result = await deps.sandbox.exec(command);
|
|
22
|
+
const parts = [];
|
|
23
|
+
if (result.stdout)
|
|
24
|
+
parts.push(result.stdout);
|
|
25
|
+
if (result.stderr)
|
|
26
|
+
parts.push(`[stderr]\n${result.stderr}`);
|
|
27
|
+
if (result.exitCode !== 0)
|
|
28
|
+
parts.push(`[exit code: ${result.exitCode}]`);
|
|
29
|
+
return [{ type: "text", text: parts.join("\n") || "(no output)" }];
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Read a file from the sandbox filesystem.
|
|
34
|
+
*/
|
|
35
|
+
export const ReadFile = createTool({
|
|
36
|
+
name: "read_file",
|
|
37
|
+
description: "Read the contents of a file in the sandbox.",
|
|
38
|
+
input: z.object({
|
|
39
|
+
path: z.string().describe("Path to the file to read."),
|
|
40
|
+
}),
|
|
41
|
+
use: () => ({ sandbox: useSandbox() }),
|
|
42
|
+
handler: async ({ path }, deps) => {
|
|
43
|
+
const content = await deps.sandbox.readFile(path);
|
|
44
|
+
return [{ type: "text", text: content }];
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Write a file to the sandbox filesystem.
|
|
49
|
+
*/
|
|
50
|
+
export const WriteFile = createTool({
|
|
51
|
+
name: "write_file",
|
|
52
|
+
description: "Write content to a file in the sandbox. Creates the file if it doesn't exist.",
|
|
53
|
+
input: z.object({
|
|
54
|
+
path: z.string().describe("Path to the file to write."),
|
|
55
|
+
content: z.string().describe("Content to write to the file."),
|
|
56
|
+
}),
|
|
57
|
+
use: () => ({ sandbox: useSandbox() }),
|
|
58
|
+
handler: async ({ path, content }, deps) => {
|
|
59
|
+
await deps.sandbox.writeFile(path, content);
|
|
60
|
+
return [{ type: "text", text: `Wrote ${content.length} bytes to ${path}` }];
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Apply surgical edits to a file in the sandbox.
|
|
65
|
+
*/
|
|
66
|
+
export const EditFile = createTool({
|
|
67
|
+
name: "edit_file",
|
|
68
|
+
description: "Apply surgical edits to a file. Each edit specifies an old string to find and a new string to replace it with.",
|
|
69
|
+
input: z.object({
|
|
70
|
+
path: z.string().describe("Path to the file to edit."),
|
|
71
|
+
edits: z
|
|
72
|
+
.array(z.object({
|
|
73
|
+
old: z.string().describe("Exact string to find in the file."),
|
|
74
|
+
new: z.string().describe("Replacement string. Empty string deletes the match."),
|
|
75
|
+
all: z
|
|
76
|
+
.boolean()
|
|
77
|
+
.optional()
|
|
78
|
+
.describe("Replace all occurrences. Default: false (requires unique match)."),
|
|
79
|
+
}))
|
|
80
|
+
.describe("Array of edits to apply."),
|
|
81
|
+
}),
|
|
82
|
+
use: () => ({ sandbox: useSandbox() }),
|
|
83
|
+
handler: async ({ path, edits }, deps) => {
|
|
84
|
+
const result = await deps.sandbox.editFile(path, edits);
|
|
85
|
+
return [
|
|
86
|
+
{
|
|
87
|
+
type: "text",
|
|
88
|
+
text: `Applied ${result.applied} edit(s) to ${path}. Changes: ${result.changes.map((c) => `line ${c.line}: -${c.removed}/+${c.added}`).join(", ")}`,
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|