@humanlayer/agentlayer-justbash 0.0.7
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.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +630 -0
- package/dist/index.js.map +22 -0
- package/dist/prompts/index.d.ts +29 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +123 -0
- package/dist/prompts/index.js.map +10 -0
- package/dist/tools/apply-patch.d.ts +9 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/bash.d.ts +8 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/code-search.d.ts +12 -0
- package/dist/tools/code-search.d.ts.map +1 -0
- package/dist/tools/edit.d.ts +12 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/glob.d.ts +6 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/grep.d.ts +8 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +510 -0
- package/dist/tools/index.js.map +21 -0
- package/dist/tools/list.d.ts +7 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/read.d.ts +7 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/skill.d.ts +10 -0
- package/dist/tools/skill.d.ts.map +1 -0
- package/dist/tools/web-fetch.d.ts +7 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-search.d.ts +16 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/write.d.ts +6 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/package.json +59 -0
- package/src/index.ts +2 -0
- package/src/prompts/index.ts +161 -0
- package/src/tools/apply-patch.ts +121 -0
- package/src/tools/apply-patch.txt +35 -0
- package/src/tools/bash.ts +20 -0
- package/src/tools/bash.txt +114 -0
- package/src/tools/code-search.ts +119 -0
- package/src/tools/edit.ts +58 -0
- package/src/tools/edit.txt +10 -0
- package/src/tools/glob.ts +33 -0
- package/src/tools/glob.txt +6 -0
- package/src/tools/grep.ts +53 -0
- package/src/tools/grep.txt +8 -0
- package/src/tools/index.ts +12 -0
- package/src/tools/list.ts +41 -0
- package/src/tools/list.txt +5 -0
- package/src/tools/read.ts +16 -0
- package/src/tools/read.txt +14 -0
- package/src/tools/skill.ts +49 -0
- package/src/tools/web-fetch.ts +97 -0
- package/src/tools/web-fetch.txt +10 -0
- package/src/tools/web-search.ts +59 -0
- package/src/tools/write.ts +26 -0
- package/src/tools/write.txt +8 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
// src/tools/apply-patch.ts
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { ApplyPatchTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
4
|
+
import { APPLY_PATCH_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
5
|
+
import { applyUpdateChunks, parsePatch, validateHunks } from "@humanlayer/agentlayer-core/utils";
|
|
6
|
+
function createApplyPatchTool(bash, opts = {}) {
|
|
7
|
+
const { cwd } = opts;
|
|
8
|
+
const _resolvePath = (filePath) => {
|
|
9
|
+
if (!cwd || isAbsolute(filePath)) {
|
|
10
|
+
return filePath;
|
|
11
|
+
}
|
|
12
|
+
return resolve(cwd, filePath);
|
|
13
|
+
};
|
|
14
|
+
return ApplyPatchTool.define(async (input) => {
|
|
15
|
+
const { patch_text } = input;
|
|
16
|
+
if (!patch_text || !patch_text.trim()) {
|
|
17
|
+
throw new Error("patch_text is required");
|
|
18
|
+
}
|
|
19
|
+
let ops;
|
|
20
|
+
try {
|
|
21
|
+
ops = parsePatch(patch_text);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
throw new Error(`apply_patch verification failed: ${err}`);
|
|
24
|
+
}
|
|
25
|
+
if (ops.length === 0) {
|
|
26
|
+
throw new Error("patch rejected: empty patch");
|
|
27
|
+
}
|
|
28
|
+
const hasHunks = ops.some((op) => op.type === "add" || op.chunks.length > 0 || op.type === "delete");
|
|
29
|
+
if (!hasHunks) {
|
|
30
|
+
throw new Error("apply_patch verification failed: no hunks found");
|
|
31
|
+
}
|
|
32
|
+
const readFile = async (filePath) => {
|
|
33
|
+
const result = await bash.exec(`cat "${filePath}"`);
|
|
34
|
+
if (result.exitCode !== 0) {
|
|
35
|
+
throw new Error(`File not found: ${filePath}`);
|
|
36
|
+
}
|
|
37
|
+
return result.stdout;
|
|
38
|
+
};
|
|
39
|
+
await validateHunks(ops, readFile);
|
|
40
|
+
const results = [];
|
|
41
|
+
for (const op of ops) {
|
|
42
|
+
if (op.type === "add") {
|
|
43
|
+
const filePath = op.filePath;
|
|
44
|
+
const mkdirResult = await bash.exec(`mkdir -p "$(dirname "${filePath}")"`);
|
|
45
|
+
if (mkdirResult.exitCode !== 0) {
|
|
46
|
+
throw new Error(`Failed to create parent directory for ${filePath}: ${mkdirResult.stderr}`);
|
|
47
|
+
}
|
|
48
|
+
const DELIM = "PATCHEOF_8f3a2b1c";
|
|
49
|
+
const content = op.addContent ?? "";
|
|
50
|
+
const writeResult = await bash.exec(`cat > "${filePath}" <<'${DELIM}'
|
|
51
|
+
${content}
|
|
52
|
+
${DELIM}`);
|
|
53
|
+
if (writeResult.exitCode !== 0) {
|
|
54
|
+
throw new Error(`Failed to write file ${filePath}: ${writeResult.stderr}`);
|
|
55
|
+
}
|
|
56
|
+
results.push(`Added ${filePath}`);
|
|
57
|
+
} else if (op.type === "update") {
|
|
58
|
+
const content = await readFile(op.filePath);
|
|
59
|
+
const updated = applyUpdateChunks(content, op.chunks);
|
|
60
|
+
const DELIM = "PATCHEOF_8f3a2b1c";
|
|
61
|
+
const writeResult = await bash.exec(`cat > "${op.filePath}" <<'${DELIM}'
|
|
62
|
+
${updated}
|
|
63
|
+
${DELIM}`);
|
|
64
|
+
if (writeResult.exitCode !== 0) {
|
|
65
|
+
throw new Error(`Failed to write file ${op.filePath}: ${writeResult.stderr}`);
|
|
66
|
+
}
|
|
67
|
+
results.push(`Updated ${op.filePath}`);
|
|
68
|
+
} else if (op.type === "move") {
|
|
69
|
+
const content = await readFile(op.filePath);
|
|
70
|
+
const updated = applyUpdateChunks(content, op.chunks);
|
|
71
|
+
const targetPath = op.targetPath;
|
|
72
|
+
const mkdirResult = await bash.exec(`mkdir -p "$(dirname "${targetPath}")"`);
|
|
73
|
+
if (mkdirResult.exitCode !== 0) {
|
|
74
|
+
throw new Error(`Failed to create parent directory for ${targetPath}: ${mkdirResult.stderr}`);
|
|
75
|
+
}
|
|
76
|
+
const DELIM = "PATCHEOF_8f3a2b1c";
|
|
77
|
+
const writeResult = await bash.exec(`cat > "${targetPath}" <<'${DELIM}'
|
|
78
|
+
${updated}
|
|
79
|
+
${DELIM}`);
|
|
80
|
+
if (writeResult.exitCode !== 0) {
|
|
81
|
+
throw new Error(`Failed to write file ${targetPath}: ${writeResult.stderr}`);
|
|
82
|
+
}
|
|
83
|
+
const rmResult = await bash.exec(`rm "${op.filePath}"`);
|
|
84
|
+
if (rmResult.exitCode !== 0) {
|
|
85
|
+
throw new Error(`Failed to remove original file ${op.filePath}: ${rmResult.stderr}`);
|
|
86
|
+
}
|
|
87
|
+
results.push(`Moved ${op.filePath} → ${targetPath}`);
|
|
88
|
+
} else if (op.type === "delete") {
|
|
89
|
+
const rmResult = await bash.exec(`rm "${op.filePath}"`);
|
|
90
|
+
if (rmResult.exitCode !== 0) {
|
|
91
|
+
throw new Error(`Failed to delete file ${op.filePath}: ${rmResult.stderr}`);
|
|
92
|
+
}
|
|
93
|
+
results.push(`Deleted ${op.filePath}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results.join(`
|
|
97
|
+
`);
|
|
98
|
+
}, { description: APPLY_PATCH_DESCRIPTION });
|
|
99
|
+
}
|
|
100
|
+
// src/tools/bash.ts
|
|
101
|
+
import { BashTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
102
|
+
import { BASH_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
103
|
+
import { truncateOutput } from "@humanlayer/agentlayer-core/utils";
|
|
104
|
+
function createJustBashTool(bash) {
|
|
105
|
+
return BashTool.define(async (input) => {
|
|
106
|
+
const result = await bash.exec(input.command, {
|
|
107
|
+
...input.workdir ? { cwd: input.workdir } : {}
|
|
108
|
+
});
|
|
109
|
+
let output = result.stdout;
|
|
110
|
+
if (result.stderr) {
|
|
111
|
+
output += `
|
|
112
|
+
STDERR: ${result.stderr}`;
|
|
113
|
+
}
|
|
114
|
+
return truncateOutput(`Exit code: ${result.exitCode}
|
|
115
|
+
${output}`);
|
|
116
|
+
}, { description: BASH_DESCRIPTION });
|
|
117
|
+
}
|
|
118
|
+
// src/tools/code-search.ts
|
|
119
|
+
import { CodeSearchTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
120
|
+
import { CODE_SEARCH_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
121
|
+
var DEFAULT_TIMEOUT_SEC = 30;
|
|
122
|
+
var CONTEXT7_BASE_URL = "https://context7.com";
|
|
123
|
+
async function fetchExaViaBash(bash, input, apiKey, timeoutSec) {
|
|
124
|
+
try {
|
|
125
|
+
const query = `${input.query} -- for ${input.packageName} in ${input.language}`;
|
|
126
|
+
const payload = JSON.stringify({ query, tokensNum: 5000 });
|
|
127
|
+
const escapedPayload = payload.replace(/'/g, "'\\''");
|
|
128
|
+
const result = await bash.exec(`curl -s --max-time ${timeoutSec} ` + `-H "Content-Type: application/json" ` + `-H "x-api-key: ${apiKey}" ` + `-d '${escapedPayload}' ` + `https://api.exa.ai/context`);
|
|
129
|
+
if (result.exitCode !== 0)
|
|
130
|
+
return null;
|
|
131
|
+
const data = JSON.parse(result.stdout);
|
|
132
|
+
return data.response ?? null;
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function fetchContext7ViaBash(bash, input, apiKey, timeoutSec) {
|
|
138
|
+
try {
|
|
139
|
+
const searchQuery = encodeURIComponent(input.query);
|
|
140
|
+
const libName = encodeURIComponent(input.packageName);
|
|
141
|
+
const searchResult = await bash.exec(`curl -s --max-time ${timeoutSec} ` + `-H "Authorization: Bearer ${apiKey}" ` + `"${CONTEXT7_BASE_URL}/api/v2/libs/search?query=${searchQuery}&libraryName=${libName}"`);
|
|
142
|
+
if (searchResult.exitCode !== 0)
|
|
143
|
+
return null;
|
|
144
|
+
const searchData = JSON.parse(searchResult.stdout);
|
|
145
|
+
const libraries = searchData.results ?? [];
|
|
146
|
+
if (libraries.length === 0)
|
|
147
|
+
return null;
|
|
148
|
+
const best = libraries.reduce((a, b) => (b.trustScore ?? 0) > (a.trustScore ?? 0) ? b : a);
|
|
149
|
+
const contextQuery = encodeURIComponent(input.query);
|
|
150
|
+
const libId = encodeURIComponent(best.id);
|
|
151
|
+
const contextResult = await bash.exec(`curl -s --max-time ${timeoutSec} ` + `-H "Authorization: Bearer ${apiKey}" ` + `"${CONTEXT7_BASE_URL}/api/v2/context?query=${contextQuery}&libraryId=${libId}"`);
|
|
152
|
+
if (contextResult.exitCode !== 0)
|
|
153
|
+
return null;
|
|
154
|
+
return contextResult.stdout;
|
|
155
|
+
} catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function createCodeSearchTool(bash, opts) {
|
|
160
|
+
if (!opts.exaApiKey && !opts.context7ApiKey) {
|
|
161
|
+
throw new Error("At least one API key (exaApiKey or context7ApiKey) is required");
|
|
162
|
+
}
|
|
163
|
+
const timeoutSec = opts.timeoutSec ?? DEFAULT_TIMEOUT_SEC;
|
|
164
|
+
return CodeSearchTool.define(async (input) => {
|
|
165
|
+
const [exaResult, c7Result] = await Promise.all([
|
|
166
|
+
opts.exaApiKey ? fetchExaViaBash(bash, input, opts.exaApiKey, timeoutSec) : Promise.resolve(null),
|
|
167
|
+
opts.context7ApiKey ? fetchContext7ViaBash(bash, input, opts.context7ApiKey, timeoutSec) : Promise.resolve(null)
|
|
168
|
+
]);
|
|
169
|
+
const parts = [];
|
|
170
|
+
if (c7Result) {
|
|
171
|
+
parts.push(`## Context7 Documentation
|
|
172
|
+
|
|
173
|
+
${c7Result}`);
|
|
174
|
+
}
|
|
175
|
+
if (exaResult) {
|
|
176
|
+
parts.push(`## Exa Search Results
|
|
177
|
+
|
|
178
|
+
${exaResult}`);
|
|
179
|
+
}
|
|
180
|
+
if (parts.length === 0) {
|
|
181
|
+
return `No documentation found for "${input.packageName}" with query: ${input.query}`;
|
|
182
|
+
}
|
|
183
|
+
return parts.join(`
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
`);
|
|
188
|
+
}, { description: CODE_SEARCH_DESCRIPTION });
|
|
189
|
+
}
|
|
190
|
+
// src/tools/edit.ts
|
|
191
|
+
import { EditTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
192
|
+
import { EDIT_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
193
|
+
function createEditTool(bash) {
|
|
194
|
+
return EditTool.define(async (input) => {
|
|
195
|
+
const catResult = await bash.exec(`cat "${input.file_path}"`);
|
|
196
|
+
if (catResult.exitCode !== 0) {
|
|
197
|
+
throw new Error(`File ${input.file_path} not found`);
|
|
198
|
+
}
|
|
199
|
+
const content = catResult.stdout;
|
|
200
|
+
if (!content.includes(input.old_string)) {
|
|
201
|
+
return { content, matchCount: 0 };
|
|
202
|
+
}
|
|
203
|
+
let updated;
|
|
204
|
+
let matchCount;
|
|
205
|
+
if (input.replace_all) {
|
|
206
|
+
let count = 0;
|
|
207
|
+
let pos = 0;
|
|
208
|
+
while (true) {
|
|
209
|
+
const idx = content.indexOf(input.old_string, pos);
|
|
210
|
+
if (idx === -1)
|
|
211
|
+
break;
|
|
212
|
+
count++;
|
|
213
|
+
pos = idx + input.old_string.length;
|
|
214
|
+
}
|
|
215
|
+
updated = content.split(input.old_string).join(input.new_string);
|
|
216
|
+
matchCount = count;
|
|
217
|
+
} else {
|
|
218
|
+
const firstIdx = content.indexOf(input.old_string);
|
|
219
|
+
const lastIdx = content.lastIndexOf(input.old_string);
|
|
220
|
+
if (firstIdx !== lastIdx) {
|
|
221
|
+
throw new Error("Found multiple matches for old_string. Provide more surrounding context to make the match unique.");
|
|
222
|
+
}
|
|
223
|
+
updated = content.replace(input.old_string, input.new_string);
|
|
224
|
+
matchCount = 1;
|
|
225
|
+
}
|
|
226
|
+
const DELIM = "EDITEOF_8f3a2b1c";
|
|
227
|
+
const writeResult = await bash.exec(`cat > "${input.file_path}" <<'${DELIM}'
|
|
228
|
+
${updated}
|
|
229
|
+
${DELIM}`);
|
|
230
|
+
if (writeResult.exitCode !== 0) {
|
|
231
|
+
throw new Error(`Failed to write file ${input.file_path}: ${writeResult.stderr}`);
|
|
232
|
+
}
|
|
233
|
+
return { content: updated, matchCount };
|
|
234
|
+
}, { description: EDIT_DESCRIPTION });
|
|
235
|
+
}
|
|
236
|
+
// src/tools/glob.ts
|
|
237
|
+
import { GlobTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
238
|
+
import { GLOB_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
239
|
+
function createGlobTool(bash) {
|
|
240
|
+
return GlobTool.define(async (input) => {
|
|
241
|
+
const searchPath = input.path ?? ".";
|
|
242
|
+
const result = await bash.exec(`rg --files -g "${input.pattern}" "${searchPath}" 2>/dev/null`);
|
|
243
|
+
if (result.exitCode !== 0 && result.exitCode !== 1) {
|
|
244
|
+
const findResult = await bash.exec(`find "${searchPath}" -type f -name "${input.pattern}" 2>/dev/null | head -100`);
|
|
245
|
+
if (findResult.exitCode !== 0) {
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
return findResult.stdout.split(`
|
|
249
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
250
|
+
}
|
|
251
|
+
return result.stdout.split(`
|
|
252
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
253
|
+
}, { description: GLOB_DESCRIPTION });
|
|
254
|
+
}
|
|
255
|
+
// src/tools/grep.ts
|
|
256
|
+
import { GrepTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
257
|
+
import { GREP_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
258
|
+
var MAX_MATCHES = 100;
|
|
259
|
+
function createGrepTool(bash) {
|
|
260
|
+
return GrepTool.define(async (input) => {
|
|
261
|
+
const searchPath = input.path ?? ".";
|
|
262
|
+
let cmd = `rg -nH --hidden --no-messages --regexp "${input.pattern}"`;
|
|
263
|
+
if (input.include) {
|
|
264
|
+
cmd += ` --glob "${input.include}"`;
|
|
265
|
+
}
|
|
266
|
+
cmd += ` "${searchPath}"`;
|
|
267
|
+
const result = await bash.exec(cmd);
|
|
268
|
+
if (result.exitCode === 1) {
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
if (result.exitCode !== 0) {
|
|
272
|
+
throw new Error(`grep failed with exit code ${result.exitCode}: ${result.stderr}`);
|
|
273
|
+
}
|
|
274
|
+
const matches = [];
|
|
275
|
+
for (const line of result.stdout.split(`
|
|
276
|
+
`)) {
|
|
277
|
+
if (!line)
|
|
278
|
+
continue;
|
|
279
|
+
const colonIdx = line.indexOf(":");
|
|
280
|
+
if (colonIdx === -1)
|
|
281
|
+
continue;
|
|
282
|
+
const afterFile = line.indexOf(":", colonIdx + 1);
|
|
283
|
+
if (afterFile === -1)
|
|
284
|
+
continue;
|
|
285
|
+
const file = line.slice(0, colonIdx);
|
|
286
|
+
const lineNum = Number.parseInt(line.slice(colonIdx + 1, afterFile), 10);
|
|
287
|
+
const content = line.slice(afterFile + 1);
|
|
288
|
+
if (!Number.isNaN(lineNum)) {
|
|
289
|
+
matches.push({ file, line: lineNum, content });
|
|
290
|
+
}
|
|
291
|
+
if (matches.length >= MAX_MATCHES)
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
return matches;
|
|
295
|
+
}, { description: GREP_DESCRIPTION });
|
|
296
|
+
}
|
|
297
|
+
// src/tools/list.ts
|
|
298
|
+
import { ListTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
299
|
+
import { LIST_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
300
|
+
function createListTool(bash) {
|
|
301
|
+
return ListTool.define(async (input) => {
|
|
302
|
+
const dirPath = input.path ?? ".";
|
|
303
|
+
const result = await bash.exec(`ls -1F "${dirPath}" 2>/dev/null`);
|
|
304
|
+
if (result.exitCode !== 0) {
|
|
305
|
+
throw new Error(`Failed to list directory ${dirPath}: ${result.stderr}`);
|
|
306
|
+
}
|
|
307
|
+
const ignorePatterns = new Set(["node_modules", ".git", "dist", "build", ...input.ignore ?? []]);
|
|
308
|
+
const entries = [];
|
|
309
|
+
for (const raw of result.stdout.split(`
|
|
310
|
+
`)) {
|
|
311
|
+
const line = raw.trim();
|
|
312
|
+
if (!line)
|
|
313
|
+
continue;
|
|
314
|
+
if (line.endsWith("/")) {
|
|
315
|
+
const name = line.slice(0, -1);
|
|
316
|
+
if (ignorePatterns.has(name))
|
|
317
|
+
continue;
|
|
318
|
+
entries.push({ name, type: "directory" });
|
|
319
|
+
} else {
|
|
320
|
+
const name = line.replace(/[*@|=>]$/, "");
|
|
321
|
+
if (ignorePatterns.has(name))
|
|
322
|
+
continue;
|
|
323
|
+
entries.push({ name, type: "file" });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return entries;
|
|
327
|
+
}, { description: LIST_DESCRIPTION });
|
|
328
|
+
}
|
|
329
|
+
// src/tools/read.ts
|
|
330
|
+
import { ReadTool } from "@humanlayer/agentlayer-core/interfaces";
|
|
331
|
+
import { READ_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
332
|
+
function createJustBashReadTool(bash) {
|
|
333
|
+
return ReadTool.define(async (input) => {
|
|
334
|
+
const result = await bash.exec(`cat "${input.file_path}"`);
|
|
335
|
+
if (result.exitCode !== 0) {
|
|
336
|
+
throw new Error(`File not found: ${input.file_path}`);
|
|
337
|
+
}
|
|
338
|
+
return result.stdout;
|
|
339
|
+
}, { description: READ_DESCRIPTION });
|
|
340
|
+
}
|
|
341
|
+
// src/tools/skill.ts
|
|
342
|
+
import { createSkillTool } from "@humanlayer/agentlayer-core";
|
|
343
|
+
function parseFrontmatterDescription(content) {
|
|
344
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
345
|
+
if (!match)
|
|
346
|
+
return null;
|
|
347
|
+
const fmMatch = match[1]?.match(/description:\s*(.+)/);
|
|
348
|
+
return fmMatch?.[1]?.trim() ?? null;
|
|
349
|
+
}
|
|
350
|
+
function parseFirstHeading(content) {
|
|
351
|
+
const match = content.match(/^#\s+(.+)/m);
|
|
352
|
+
return match?.[1]?.trim() ?? null;
|
|
353
|
+
}
|
|
354
|
+
async function createSkillToolFromVFS(bash, opts) {
|
|
355
|
+
const directories = Array.isArray(opts.dirs) ? opts.dirs : [opts.dirs];
|
|
356
|
+
const resolved = [];
|
|
357
|
+
for (const dir of directories) {
|
|
358
|
+
let lsResult;
|
|
359
|
+
try {
|
|
360
|
+
lsResult = await bash.exec(`ls "${dir}"/*.md 2>/dev/null`);
|
|
361
|
+
} catch {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (lsResult.exitCode !== 0)
|
|
365
|
+
continue;
|
|
366
|
+
const files = lsResult.stdout.trim().split(`
|
|
367
|
+
`).filter(Boolean);
|
|
368
|
+
for (const filePath of files) {
|
|
369
|
+
const catResult = await bash.exec(`cat "${filePath}"`);
|
|
370
|
+
if (catResult.exitCode !== 0)
|
|
371
|
+
continue;
|
|
372
|
+
const content = catResult.stdout;
|
|
373
|
+
const name = filePath.split("/").pop()?.replace(".md", "") ?? filePath;
|
|
374
|
+
const description = parseFrontmatterDescription(content) ?? parseFirstHeading(content) ?? name;
|
|
375
|
+
resolved.push({ name, description, content });
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const mergedMap = new Map(resolved.map((s) => [s.name, s]));
|
|
379
|
+
for (const skill of opts.skills ?? []) {
|
|
380
|
+
mergedMap.set(skill.name, skill);
|
|
381
|
+
}
|
|
382
|
+
return createSkillTool({ skills: [...mergedMap.values()] });
|
|
383
|
+
}
|
|
384
|
+
// src/tools/web-fetch.ts
|
|
385
|
+
import { WebFetchTool } from "@humanlayer/agentlayer-core";
|
|
386
|
+
import { WEB_FETCH_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
387
|
+
import TurndownService from "turndown";
|
|
388
|
+
var MAX_RESPONSE_SIZE = 5 * 1024 * 1024;
|
|
389
|
+
var MAX_TIMEOUT_MS = 120000;
|
|
390
|
+
function stripHtmlTags(html) {
|
|
391
|
+
return html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, "").replace(/<[^>]+>/g, "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, " ").replace(/\n{3,}/g, `
|
|
392
|
+
|
|
393
|
+
`).trim();
|
|
394
|
+
}
|
|
395
|
+
function createWebFetchTool(bash) {
|
|
396
|
+
const turndown = new TurndownService({
|
|
397
|
+
headingStyle: "atx",
|
|
398
|
+
codeBlockStyle: "fenced"
|
|
399
|
+
});
|
|
400
|
+
turndown.remove(["script", "style", "meta", "link", "noscript", "iframe"]);
|
|
401
|
+
return WebFetchTool.define(async (input) => {
|
|
402
|
+
if (!input.url.startsWith("http://") && !input.url.startsWith("https://")) {
|
|
403
|
+
throw new Error("URL must start with http:// or https://");
|
|
404
|
+
}
|
|
405
|
+
const timeoutSec = Math.min(input.timeout, MAX_TIMEOUT_MS) / 1000;
|
|
406
|
+
const maxSizeBytes = MAX_RESPONSE_SIZE;
|
|
407
|
+
const result = await bash.exec(`curl -sL --max-filesize ${maxSizeBytes} --max-time ${timeoutSec} ` + `-A "Mozilla/5.0 (compatible; agent/1.0)" ` + `-w '\\n%{http_code}' "${input.url}"`);
|
|
408
|
+
if (result.exitCode !== 0) {
|
|
409
|
+
if (result.exitCode === 28) {
|
|
410
|
+
throw new Error(`Request timed out after ${input.timeout}ms`);
|
|
411
|
+
}
|
|
412
|
+
if (result.exitCode === 63) {
|
|
413
|
+
throw new Error("Response too large (exceeds 5MB limit)");
|
|
414
|
+
}
|
|
415
|
+
throw new Error(`curl failed (exit ${result.exitCode}): ${result.stderr}`);
|
|
416
|
+
}
|
|
417
|
+
const lines = result.stdout.split(`
|
|
418
|
+
`);
|
|
419
|
+
const statusLine = lines[lines.length - 1]?.trim() ?? "";
|
|
420
|
+
const statusCode = Number.parseInt(statusLine, 10);
|
|
421
|
+
const body = lines.slice(0, -1).join(`
|
|
422
|
+
`);
|
|
423
|
+
if (!Number.isNaN(statusCode) && statusCode >= 400) {
|
|
424
|
+
throw new Error(`Request failed with status code: ${statusCode}`);
|
|
425
|
+
}
|
|
426
|
+
if (input.format === "html") {
|
|
427
|
+
return body;
|
|
428
|
+
}
|
|
429
|
+
const isHtml = body.trimStart().startsWith("<!") || body.trimStart().toLowerCase().startsWith("<html");
|
|
430
|
+
if (input.format === "text") {
|
|
431
|
+
if (isHtml) {
|
|
432
|
+
return stripHtmlTags(body);
|
|
433
|
+
}
|
|
434
|
+
return body;
|
|
435
|
+
}
|
|
436
|
+
if (isHtml) {
|
|
437
|
+
return turndown.turndown(body);
|
|
438
|
+
}
|
|
439
|
+
return body;
|
|
440
|
+
}, { description: WEB_FETCH_DESCRIPTION });
|
|
441
|
+
}
|
|
442
|
+
// src/tools/web-search.ts
|
|
443
|
+
import { WebSearchTool } from "@humanlayer/agentlayer-core";
|
|
444
|
+
import { WEB_SEARCH_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
445
|
+
var DEFAULT_TIMEOUT_SEC2 = 25;
|
|
446
|
+
function createWebSearchTool(bash, opts) {
|
|
447
|
+
const timeoutSec = opts.timeoutSec ?? DEFAULT_TIMEOUT_SEC2;
|
|
448
|
+
return WebSearchTool.define(async (input) => {
|
|
449
|
+
const payload = JSON.stringify({
|
|
450
|
+
query: input.query,
|
|
451
|
+
numResults: input.numResults,
|
|
452
|
+
contents: { text: { maxCharacters: 500 } }
|
|
453
|
+
});
|
|
454
|
+
const escapedPayload = payload.replace(/'/g, "'\\''");
|
|
455
|
+
const result = await bash.exec(`curl -s --max-time ${timeoutSec} ` + `-H "Content-Type: application/json" ` + `-H "x-api-key: ${opts.exaApiKey}" ` + `-d '${escapedPayload}' ` + `https://api.exa.ai/search`);
|
|
456
|
+
if (result.exitCode !== 0) {
|
|
457
|
+
if (result.exitCode === 28) {
|
|
458
|
+
throw new Error("Search request timed out");
|
|
459
|
+
}
|
|
460
|
+
throw new Error(`curl failed (exit ${result.exitCode}): ${result.stderr}`);
|
|
461
|
+
}
|
|
462
|
+
let data;
|
|
463
|
+
try {
|
|
464
|
+
data = JSON.parse(result.stdout);
|
|
465
|
+
} catch {
|
|
466
|
+
throw new Error(`Failed to parse search response: ${result.stdout.slice(0, 200)}`);
|
|
467
|
+
}
|
|
468
|
+
const results = (data.results ?? []).map((r) => ({
|
|
469
|
+
title: r.title ?? "",
|
|
470
|
+
url: r.url ?? "",
|
|
471
|
+
snippet: r.text ?? r.snippet ?? ""
|
|
472
|
+
}));
|
|
473
|
+
return { results };
|
|
474
|
+
}, { description: WEB_SEARCH_DESCRIPTION });
|
|
475
|
+
}
|
|
476
|
+
// src/tools/write.ts
|
|
477
|
+
import { WriteTool } from "@humanlayer/agentlayer-core";
|
|
478
|
+
import { WRITE_DESCRIPTION } from "@humanlayer/agentlayer-core/prompts";
|
|
479
|
+
function createWriteTool(bash) {
|
|
480
|
+
return WriteTool.define(async (input) => {
|
|
481
|
+
const dirResult = await bash.exec(`mkdir -p "$(dirname "${input.file_path}")"`);
|
|
482
|
+
if (dirResult.exitCode !== 0) {
|
|
483
|
+
throw new Error(`Failed to create parent directory for ${input.file_path}: ${dirResult.stderr}`);
|
|
484
|
+
}
|
|
485
|
+
const DELIM = "WRITEOF_8f3a2b1c";
|
|
486
|
+
const writeResult = await bash.exec(`cat > "${input.file_path}" <<'${DELIM}'
|
|
487
|
+
${input.content}
|
|
488
|
+
${DELIM}`);
|
|
489
|
+
if (writeResult.exitCode !== 0) {
|
|
490
|
+
throw new Error(`Failed to write file ${input.file_path}: ${writeResult.stderr}`);
|
|
491
|
+
}
|
|
492
|
+
return `Successfully wrote to ${input.file_path}`;
|
|
493
|
+
}, { description: WRITE_DESCRIPTION });
|
|
494
|
+
}
|
|
495
|
+
export {
|
|
496
|
+
createWriteTool,
|
|
497
|
+
createWebSearchTool,
|
|
498
|
+
createWebFetchTool,
|
|
499
|
+
createSkillToolFromVFS,
|
|
500
|
+
createListTool,
|
|
501
|
+
createJustBashTool,
|
|
502
|
+
createJustBashReadTool,
|
|
503
|
+
createGrepTool,
|
|
504
|
+
createGlobTool,
|
|
505
|
+
createEditTool,
|
|
506
|
+
createCodeSearchTool,
|
|
507
|
+
createApplyPatchTool
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
//# debugId=1524F9AF4D010FAD64756E2164756E21
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/tools/apply-patch.ts", "../src/tools/bash.ts", "../src/tools/code-search.ts", "../src/tools/edit.ts", "../src/tools/glob.ts", "../src/tools/grep.ts", "../src/tools/list.ts", "../src/tools/read.ts", "../src/tools/skill.ts", "../src/tools/web-fetch.ts", "../src/tools/web-search.ts", "../src/tools/write.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { isAbsolute, resolve } from 'node:path'\nimport { ApplyPatchTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { APPLY_PATCH_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport { applyUpdateChunks, type PatchOperation, parsePatch, validateHunks } from '@humanlayer/agentlayer-core/utils'\nimport type { Bash } from 'just-bash'\n\nexport interface ApplyPatchOptions {\n\t/** Working directory for resolving relative paths. If not provided, paths are resolved by bash's cwd. */\n\tcwd?: string\n}\n\nexport function createApplyPatchTool(bash: Bash, opts: ApplyPatchOptions = {}) {\n\tconst { cwd } = opts\n\n\t/**\n\t * Resolve a file path to absolute if cwd is provided and path is relative.\n\t * Note: bash.exec already uses bash's cwd, but this ensures consistency\n\t * when passing paths to commands.\n\t */\n\tconst _resolvePath = (filePath: string): string => {\n\t\tif (!cwd || isAbsolute(filePath)) {\n\t\t\treturn filePath\n\t\t}\n\t\treturn resolve(cwd, filePath)\n\t}\n\treturn ApplyPatchTool.define(\n\t\tasync (input) => {\n\t\t\tconst { patch_text } = input\n\n\t\t\tif (!patch_text || !patch_text.trim()) {\n\t\t\t\tthrow new Error('patch_text is required')\n\t\t\t}\n\n\t\t\tlet ops: PatchOperation[]\n\t\t\ttry {\n\t\t\t\tops = parsePatch(patch_text)\n\t\t\t} catch (err) {\n\t\t\t\tthrow new Error(`apply_patch verification failed: ${err}`)\n\t\t\t}\n\n\t\t\tif (ops.length === 0) {\n\t\t\t\tthrow new Error('patch rejected: empty patch')\n\t\t\t}\n\n\t\t\tconst hasHunks = ops.some((op) => op.type === 'add' || op.chunks.length > 0 || op.type === 'delete')\n\t\t\tif (!hasHunks) {\n\t\t\t\tthrow new Error('apply_patch verification failed: no hunks found')\n\t\t\t}\n\n\t\t\t// Read helper via bash\n\t\t\tconst readFile = async (filePath: string): Promise<string> => {\n\t\t\t\tconst result = await bash.exec(`cat \"${filePath}\"`)\n\t\t\t\tif (result.exitCode !== 0) {\n\t\t\t\t\tthrow new Error(`File not found: ${filePath}`)\n\t\t\t\t}\n\t\t\t\treturn result.stdout\n\t\t\t}\n\n\t\t\t// Validation phase — reads only, no writes\n\t\t\tawait validateHunks(ops, readFile)\n\n\t\t\t// Apply phase\n\t\t\tconst results: string[] = []\n\n\t\t\tfor (const op of ops) {\n\t\t\t\tif (op.type === 'add') {\n\t\t\t\t\tconst filePath = op.filePath\n\t\t\t\t\t// Ensure parent directory exists\n\t\t\t\t\tconst mkdirResult = await bash.exec(`mkdir -p \"$(dirname \"${filePath}\")\"`)\n\t\t\t\t\tif (mkdirResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to create parent directory for ${filePath}: ${mkdirResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\t// Write content using a heredoc\n\t\t\t\t\tconst DELIM = 'PATCHEOF_8f3a2b1c'\n\t\t\t\t\tconst content = op.addContent ?? ''\n\t\t\t\t\tconst writeResult = await bash.exec(`cat > \"${filePath}\" <<'${DELIM}'\\n${content}\\n${DELIM}`)\n\t\t\t\t\tif (writeResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to write file ${filePath}: ${writeResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\tresults.push(`Added ${filePath}`)\n\t\t\t\t} else if (op.type === 'update') {\n\t\t\t\t\tconst content = await readFile(op.filePath)\n\t\t\t\t\tconst updated = applyUpdateChunks(content, op.chunks)\n\t\t\t\t\tconst DELIM = 'PATCHEOF_8f3a2b1c'\n\t\t\t\t\tconst writeResult = await bash.exec(`cat > \"${op.filePath}\" <<'${DELIM}'\\n${updated}\\n${DELIM}`)\n\t\t\t\t\tif (writeResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to write file ${op.filePath}: ${writeResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\tresults.push(`Updated ${op.filePath}`)\n\t\t\t\t} else if (op.type === 'move') {\n\t\t\t\t\tconst content = await readFile(op.filePath)\n\t\t\t\t\tconst updated = applyUpdateChunks(content, op.chunks)\n\t\t\t\t\tconst targetPath = op.targetPath!\n\t\t\t\t\tconst mkdirResult = await bash.exec(`mkdir -p \"$(dirname \"${targetPath}\")\"`)\n\t\t\t\t\tif (mkdirResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to create parent directory for ${targetPath}: ${mkdirResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\tconst DELIM = 'PATCHEOF_8f3a2b1c'\n\t\t\t\t\tconst writeResult = await bash.exec(`cat > \"${targetPath}\" <<'${DELIM}'\\n${updated}\\n${DELIM}`)\n\t\t\t\t\tif (writeResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to write file ${targetPath}: ${writeResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\tconst rmResult = await bash.exec(`rm \"${op.filePath}\"`)\n\t\t\t\t\tif (rmResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to remove original file ${op.filePath}: ${rmResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\tresults.push(`Moved ${op.filePath} → ${targetPath}`)\n\t\t\t\t} else if (op.type === 'delete') {\n\t\t\t\t\tconst rmResult = await bash.exec(`rm \"${op.filePath}\"`)\n\t\t\t\t\tif (rmResult.exitCode !== 0) {\n\t\t\t\t\t\tthrow new Error(`Failed to delete file ${op.filePath}: ${rmResult.stderr}`)\n\t\t\t\t\t}\n\t\t\t\t\tresults.push(`Deleted ${op.filePath}`)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn results.join('\\n')\n\t\t},\n\t\t{ description: APPLY_PATCH_DESCRIPTION },\n\t)\n}\n",
|
|
6
|
+
"import { BashTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { BASH_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport { truncateOutput } from '@humanlayer/agentlayer-core/utils'\nimport type { Bash } from 'just-bash'\n\nexport function createJustBashTool(bash: Bash) {\n\treturn BashTool.define(\n\t\tasync (input) => {\n\t\t\tconst result = await bash.exec(input.command, {\n\t\t\t\t...(input.workdir ? { cwd: input.workdir } : {}),\n\t\t\t})\n\t\t\tlet output = result.stdout\n\t\t\tif (result.stderr) {\n\t\t\t\toutput += `\\nSTDERR: ${result.stderr}`\n\t\t\t}\n\t\t\treturn truncateOutput(`Exit code: ${result.exitCode}\\n${output}`)\n\t\t},\n\t\t{ description: BASH_DESCRIPTION },\n\t)\n}\n",
|
|
7
|
+
"import type { CodeSearchInput } from '@humanlayer/agentlayer-core/interfaces'\nimport { CodeSearchTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { CODE_SEARCH_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nconst DEFAULT_TIMEOUT_SEC = 30\nconst CONTEXT7_BASE_URL = 'https://context7.com'\n\nexport interface JustBashCodeSearchOptions {\n\texaApiKey?: string\n\tcontext7ApiKey?: string\n\ttimeoutSec?: number\n}\n\nasync function fetchExaViaBash(\n\tbash: Bash,\n\tinput: CodeSearchInput,\n\tapiKey: string,\n\ttimeoutSec: number,\n): Promise<string | null> {\n\ttry {\n\t\tconst query = `${input.query} -- for ${input.packageName} in ${input.language}`\n\t\tconst payload = JSON.stringify({ query, tokensNum: 5000 })\n\t\tconst escapedPayload = payload.replace(/'/g, \"'\\\\''\")\n\n\t\tconst result = await bash.exec(\n\t\t\t`curl -s --max-time ${timeoutSec} ` +\n\t\t\t\t`-H \"Content-Type: application/json\" ` +\n\t\t\t\t`-H \"x-api-key: ${apiKey}\" ` +\n\t\t\t\t`-d '${escapedPayload}' ` +\n\t\t\t\t`https://api.exa.ai/context`,\n\t\t)\n\n\t\tif (result.exitCode !== 0) return null\n\n\t\tconst data = JSON.parse(result.stdout) as { response?: string }\n\t\treturn data.response ?? null\n\t} catch {\n\t\treturn null\n\t}\n}\n\nasync function fetchContext7ViaBash(\n\tbash: Bash,\n\tinput: CodeSearchInput,\n\tapiKey: string,\n\ttimeoutSec: number,\n): Promise<string | null> {\n\ttry {\n\t\t// Step 1: search for the library\n\t\tconst searchQuery = encodeURIComponent(input.query)\n\t\tconst libName = encodeURIComponent(input.packageName)\n\n\t\tconst searchResult = await bash.exec(\n\t\t\t`curl -s --max-time ${timeoutSec} ` +\n\t\t\t\t`-H \"Authorization: Bearer ${apiKey}\" ` +\n\t\t\t\t`\"${CONTEXT7_BASE_URL}/api/v2/libs/search?query=${searchQuery}&libraryName=${libName}\"`,\n\t\t)\n\n\t\tif (searchResult.exitCode !== 0) return null\n\n\t\tconst searchData = JSON.parse(searchResult.stdout) as {\n\t\t\tresults?: Array<{ id: string; title: string; trustScore?: number }>\n\t\t}\n\t\tconst libraries = searchData.results ?? []\n\t\tif (libraries.length === 0) return null\n\n\t\tconst best = libraries.reduce((a, b) => ((b.trustScore ?? 0) > (a.trustScore ?? 0) ? b : a))\n\n\t\t// Step 2: fetch context for the selected library\n\t\tconst contextQuery = encodeURIComponent(input.query)\n\t\tconst libId = encodeURIComponent(best.id)\n\n\t\tconst contextResult = await bash.exec(\n\t\t\t`curl -s --max-time ${timeoutSec} ` +\n\t\t\t\t`-H \"Authorization: Bearer ${apiKey}\" ` +\n\t\t\t\t`\"${CONTEXT7_BASE_URL}/api/v2/context?query=${contextQuery}&libraryId=${libId}\"`,\n\t\t)\n\n\t\tif (contextResult.exitCode !== 0) return null\n\t\treturn contextResult.stdout\n\t} catch {\n\t\treturn null\n\t}\n}\n\nexport function createCodeSearchTool(bash: Bash, opts: JustBashCodeSearchOptions) {\n\tif (!opts.exaApiKey && !opts.context7ApiKey) {\n\t\tthrow new Error('At least one API key (exaApiKey or context7ApiKey) is required')\n\t}\n\n\tconst timeoutSec = opts.timeoutSec ?? DEFAULT_TIMEOUT_SEC\n\n\treturn CodeSearchTool.define(\n\t\tasync (input: CodeSearchInput): Promise<string> => {\n\t\t\tconst [exaResult, c7Result] = await Promise.all([\n\t\t\t\topts.exaApiKey ? fetchExaViaBash(bash, input, opts.exaApiKey, timeoutSec) : Promise.resolve(null),\n\t\t\t\topts.context7ApiKey\n\t\t\t\t\t? fetchContext7ViaBash(bash, input, opts.context7ApiKey, timeoutSec)\n\t\t\t\t\t: Promise.resolve(null),\n\t\t\t])\n\n\t\t\tconst parts: string[] = []\n\t\t\tif (c7Result) {\n\t\t\t\tparts.push(`## Context7 Documentation\\n\\n${c7Result}`)\n\t\t\t}\n\t\t\tif (exaResult) {\n\t\t\t\tparts.push(`## Exa Search Results\\n\\n${exaResult}`)\n\t\t\t}\n\n\t\t\tif (parts.length === 0) {\n\t\t\t\treturn `No documentation found for \"${input.packageName}\" with query: ${input.query}`\n\t\t\t}\n\n\t\t\treturn parts.join('\\n\\n---\\n\\n')\n\t\t},\n\t\t{ description: CODE_SEARCH_DESCRIPTION },\n\t)\n}\n",
|
|
8
|
+
"import { EditTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { EDIT_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nexport function createEditTool(bash: Bash) {\n\treturn EditTool.define(\n\t\tasync (input) => {\n\t\t\t// Read the file content\n\t\t\tconst catResult = await bash.exec(`cat \"${input.file_path}\"`)\n\t\t\tif (catResult.exitCode !== 0) {\n\t\t\t\tthrow new Error(`File ${input.file_path} not found`)\n\t\t\t}\n\n\t\t\tconst content = catResult.stdout\n\n\t\t\tif (!content.includes(input.old_string)) {\n\t\t\t\treturn { content, matchCount: 0 }\n\t\t\t}\n\n\t\t\tlet updated: string\n\t\t\tlet matchCount: number\n\n\t\t\tif (input.replace_all) {\n\t\t\t\tlet count = 0\n\t\t\t\tlet pos = 0\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst idx = content.indexOf(input.old_string, pos)\n\t\t\t\t\tif (idx === -1) break\n\t\t\t\t\tcount++\n\t\t\t\t\tpos = idx + input.old_string.length\n\t\t\t\t}\n\t\t\t\tupdated = content.split(input.old_string).join(input.new_string)\n\t\t\t\tmatchCount = count\n\t\t\t} else {\n\t\t\t\t// Single replacement — check for multiple matches\n\t\t\t\tconst firstIdx = content.indexOf(input.old_string)\n\t\t\t\tconst lastIdx = content.lastIndexOf(input.old_string)\n\t\t\t\tif (firstIdx !== lastIdx) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Found multiple matches for old_string. Provide more surrounding context to make the match unique.',\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tupdated = content.replace(input.old_string, input.new_string)\n\t\t\t\tmatchCount = 1\n\t\t\t}\n\n\t\t\t// Write the updated content back using a heredoc\n\t\t\tconst DELIM = 'EDITEOF_8f3a2b1c'\n\t\t\tconst writeResult = await bash.exec(`cat > \"${input.file_path}\" <<'${DELIM}'\\n${updated}\\n${DELIM}`)\n\t\t\tif (writeResult.exitCode !== 0) {\n\t\t\t\tthrow new Error(`Failed to write file ${input.file_path}: ${writeResult.stderr}`)\n\t\t\t}\n\n\t\t\treturn { content: updated, matchCount }\n\t\t},\n\t\t{ description: EDIT_DESCRIPTION },\n\t)\n}\n",
|
|
9
|
+
"import { GlobTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { GLOB_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nexport function createGlobTool(bash: Bash) {\n\treturn GlobTool.define(\n\t\tasync (input) => {\n\t\t\tconst searchPath = input.path ?? '.'\n\t\t\t// Use rg --files with glob filter — rg is typically available in just-bash environments\n\t\t\tconst result = await bash.exec(`rg --files -g \"${input.pattern}\" \"${searchPath}\" 2>/dev/null`)\n\n\t\t\tif (result.exitCode !== 0 && result.exitCode !== 1) {\n\t\t\t\t// Non-zero / non-empty exit may mean rg not available — fall back to find\n\t\t\t\tconst findResult = await bash.exec(\n\t\t\t\t\t`find \"${searchPath}\" -type f -name \"${input.pattern}\" 2>/dev/null | head -100`,\n\t\t\t\t)\n\t\t\t\tif (findResult.exitCode !== 0) {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\treturn findResult.stdout\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((l) => l.trim())\n\t\t\t\t\t.filter(Boolean)\n\t\t\t}\n\n\t\t\treturn result.stdout\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter(Boolean)\n\t\t},\n\t\t{ description: GLOB_DESCRIPTION },\n\t)\n}\n",
|
|
10
|
+
"import type { GrepMatch } from '@humanlayer/agentlayer-core/interfaces'\nimport { GrepTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { GREP_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nconst MAX_MATCHES = 100\n\nexport function createGrepTool(bash: Bash) {\n\treturn GrepTool.define(\n\t\tasync (input) => {\n\t\t\tconst searchPath = input.path ?? '.'\n\t\t\tlet cmd = `rg -nH --hidden --no-messages --regexp \"${input.pattern}\"`\n\t\t\tif (input.include) {\n\t\t\t\tcmd += ` --glob \"${input.include}\"`\n\t\t\t}\n\t\t\tcmd += ` \"${searchPath}\"`\n\n\t\t\tconst result = await bash.exec(cmd)\n\n\t\t\t// Exit code 1 = no matches\n\t\t\tif (result.exitCode === 1) {\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\tthrow new Error(`grep failed with exit code ${result.exitCode}: ${result.stderr}`)\n\t\t\t}\n\n\t\t\t// Parse `file:line:content` output lines\n\t\t\tconst matches: GrepMatch[] = []\n\t\t\tfor (const line of result.stdout.split('\\n')) {\n\t\t\t\tif (!line) continue\n\t\t\t\tconst colonIdx = line.indexOf(':')\n\t\t\t\tif (colonIdx === -1) continue\n\t\t\t\tconst afterFile = line.indexOf(':', colonIdx + 1)\n\t\t\t\tif (afterFile === -1) continue\n\n\t\t\t\tconst file = line.slice(0, colonIdx)\n\t\t\t\tconst lineNum = Number.parseInt(line.slice(colonIdx + 1, afterFile), 10)\n\t\t\t\tconst content = line.slice(afterFile + 1)\n\n\t\t\t\tif (!Number.isNaN(lineNum)) {\n\t\t\t\t\tmatches.push({ file, line: lineNum, content })\n\t\t\t\t}\n\n\t\t\t\tif (matches.length >= MAX_MATCHES) break\n\t\t\t}\n\n\t\t\treturn matches\n\t\t},\n\t\t{ description: GREP_DESCRIPTION },\n\t)\n}\n",
|
|
11
|
+
"import type { ListEntry } from '@humanlayer/agentlayer-core/interfaces'\nimport { ListTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { LIST_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\nexport function createListTool(bash: Bash) {\n\treturn ListTool.define(\n\t\tasync (input) => {\n\t\t\tconst dirPath = input.path ?? '.'\n\n\t\t\t// Use ls -1F: appends '/' to directories, nothing to files\n\t\t\tconst result = await bash.exec(`ls -1F \"${dirPath}\" 2>/dev/null`)\n\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\tthrow new Error(`Failed to list directory ${dirPath}: ${result.stderr}`)\n\t\t\t}\n\n\t\t\tconst ignorePatterns = new Set<string>(['node_modules', '.git', 'dist', 'build', ...(input.ignore ?? [])])\n\n\t\t\tconst entries: ListEntry[] = []\n\t\t\tfor (const raw of result.stdout.split('\\n')) {\n\t\t\t\tconst line = raw.trim()\n\t\t\t\tif (!line) continue\n\n\t\t\t\tif (line.endsWith('/')) {\n\t\t\t\t\t// Directory\n\t\t\t\t\tconst name = line.slice(0, -1)\n\t\t\t\t\tif (ignorePatterns.has(name)) continue\n\t\t\t\t\tentries.push({ name, type: 'directory' })\n\t\t\t\t} else {\n\t\t\t\t\t// File (strip any trailing decorator: *, @, |, =, >)\n\t\t\t\t\tconst name = line.replace(/[*@|=>]$/, '')\n\t\t\t\t\tif (ignorePatterns.has(name)) continue\n\t\t\t\t\tentries.push({ name, type: 'file' })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn entries\n\t\t},\n\t\t{ description: LIST_DESCRIPTION },\n\t)\n}\n",
|
|
12
|
+
"import { ReadTool } from '@humanlayer/agentlayer-core/interfaces'\nimport { READ_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nexport function createJustBashReadTool(bash: Bash) {\n\treturn ReadTool.define(\n\t\tasync (input) => {\n\t\t\tconst result = await bash.exec(`cat \"${input.file_path}\"`)\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\tthrow new Error(`File not found: ${input.file_path}`)\n\t\t\t}\n\t\t\treturn result.stdout\n\t\t},\n\t\t{ description: READ_DESCRIPTION },\n\t)\n}\n",
|
|
13
|
+
"import { createSkillTool } from '@humanlayer/agentlayer-core'\nimport type { Skill } from '@humanlayer/agentlayer-core/interfaces'\nimport type { Bash } from 'just-bash'\n\nfunction parseFrontmatterDescription(content: string): string | null {\n\tconst match = content.match(/^---\\n([\\s\\S]*?)\\n---/)\n\tif (!match) return null\n\tconst fmMatch = match[1]?.match(/description:\\s*(.+)/)\n\treturn fmMatch?.[1]?.trim() ?? null\n}\n\nfunction parseFirstHeading(content: string): string | null {\n\tconst match = content.match(/^#\\s+(.+)/m)\n\treturn match?.[1]?.trim() ?? null\n}\n\nexport async function createSkillToolFromVFS(bash: Bash, opts: { dirs: string | string[]; skills?: Skill[] }) {\n\tconst directories = Array.isArray(opts.dirs) ? opts.dirs : [opts.dirs]\n\tconst resolved: Skill[] = []\n\n\tfor (const dir of directories) {\n\t\tlet lsResult: { stdout: string; exitCode: number }\n\t\ttry {\n\t\t\tlsResult = await bash.exec(`ls \"${dir}\"/*.md 2>/dev/null`)\n\t\t} catch {\n\t\t\tcontinue\n\t\t}\n\t\tif (lsResult.exitCode !== 0) continue\n\n\t\tconst files = lsResult.stdout.trim().split('\\n').filter(Boolean)\n\t\tfor (const filePath of files) {\n\t\t\tconst catResult = await bash.exec(`cat \"${filePath}\"`)\n\t\t\tif (catResult.exitCode !== 0) continue\n\n\t\t\tconst content = catResult.stdout\n\t\t\tconst name = filePath.split('/').pop()?.replace('.md', '') ?? filePath\n\t\t\tconst description = parseFrontmatterDescription(content) ?? parseFirstHeading(content) ?? name\n\n\t\t\tresolved.push({ name, description, content })\n\t\t}\n\t}\n\n\tconst mergedMap = new Map(resolved.map((s) => [s.name, s]))\n\tfor (const skill of opts.skills ?? []) {\n\t\tmergedMap.set(skill.name, skill)\n\t}\n\n\treturn createSkillTool({ skills: [...mergedMap.values()] })\n}\n",
|
|
14
|
+
"import { WebFetchTool } from '@humanlayer/agentlayer-core'\nimport { WEB_FETCH_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\nimport TurndownService from 'turndown'\n\nconst MAX_RESPONSE_SIZE = 5 * 1024 * 1024 // 5MB in bytes\nconst MAX_TIMEOUT_MS = 120_000\n\n/**\n * Strip HTML tags from a string to produce plain text.\n */\nfunction stripHtmlTags(html: string): string {\n\treturn html\n\t\t.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n\t\t.replace(/<style\\b[^<]*(?:(?!<\\/style>)<[^<]*)*<\\/style>/gi, '')\n\t\t.replace(/<[^>]+>/g, '')\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/"/g, '\"')\n\t\t.replace(/'/g, \"'\")\n\t\t.replace(/ /g, ' ')\n\t\t.replace(/\\n{3,}/g, '\\n\\n')\n\t\t.trim()\n}\n\nexport function createWebFetchTool(bash: Bash) {\n\tconst turndown = new TurndownService({\n\t\theadingStyle: 'atx',\n\t\tcodeBlockStyle: 'fenced',\n\t})\n\tturndown.remove(['script', 'style', 'meta', 'link', 'noscript', 'iframe'])\n\n\treturn WebFetchTool.define(\n\t\tasync (input) => {\n\t\t\tif (!input.url.startsWith('http://') && !input.url.startsWith('https://')) {\n\t\t\t\tthrow new Error('URL must start with http:// or https://')\n\t\t\t}\n\n\t\t\tconst timeoutSec = Math.min(input.timeout, MAX_TIMEOUT_MS) / 1000\n\t\t\tconst maxSizeBytes = MAX_RESPONSE_SIZE\n\n\t\t\t// curl flags:\n\t\t\t// -s: silent, -L: follow redirects\n\t\t\t// --max-filesize: reject oversized responses\n\t\t\t// --max-time: timeout\n\t\t\t// -A: User-Agent\n\t\t\t// -w '\\n%{http_code}': append status code on last line\n\t\t\tconst result = await bash.exec(\n\t\t\t\t`curl -sL --max-filesize ${maxSizeBytes} --max-time ${timeoutSec} ` +\n\t\t\t\t\t`-A \"Mozilla/5.0 (compatible; agent/1.0)\" ` +\n\t\t\t\t\t`-w '\\\\n%{http_code}' \"${input.url}\"`,\n\t\t\t)\n\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\t// curl exit code 28 = timeout, 63 = file too large\n\t\t\t\tif (result.exitCode === 28) {\n\t\t\t\t\tthrow new Error(`Request timed out after ${input.timeout}ms`)\n\t\t\t\t}\n\t\t\t\tif (result.exitCode === 63) {\n\t\t\t\t\tthrow new Error('Response too large (exceeds 5MB limit)')\n\t\t\t\t}\n\t\t\t\tthrow new Error(`curl failed (exit ${result.exitCode}): ${result.stderr}`)\n\t\t\t}\n\n\t\t\t// Split off the status code appended by -w\n\t\t\tconst lines = result.stdout.split('\\n')\n\t\t\tconst statusLine = lines[lines.length - 1]?.trim() ?? ''\n\t\t\tconst statusCode = Number.parseInt(statusLine, 10)\n\t\t\tconst body = lines.slice(0, -1).join('\\n')\n\n\t\t\tif (!Number.isNaN(statusCode) && statusCode >= 400) {\n\t\t\t\tthrow new Error(`Request failed with status code: ${statusCode}`)\n\t\t\t}\n\n\t\t\tif (input.format === 'html') {\n\t\t\t\treturn body\n\t\t\t}\n\n\t\t\tconst isHtml = body.trimStart().startsWith('<!') || body.trimStart().toLowerCase().startsWith('<html')\n\n\t\t\tif (input.format === 'text') {\n\t\t\t\tif (isHtml) {\n\t\t\t\t\treturn stripHtmlTags(body)\n\t\t\t\t}\n\t\t\t\treturn body\n\t\t\t}\n\n\t\t\t// format === 'markdown' (default)\n\t\t\tif (isHtml) {\n\t\t\t\treturn turndown.turndown(body)\n\t\t\t}\n\t\t\treturn body\n\t\t},\n\t\t{ description: WEB_FETCH_DESCRIPTION },\n\t)\n}\n",
|
|
15
|
+
"import type { WebSearchInput, WebSearchResult } from '@humanlayer/agentlayer-core'\nimport { WebSearchTool } from '@humanlayer/agentlayer-core'\nimport { WEB_SEARCH_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nconst DEFAULT_TIMEOUT_SEC = 25\n\nexport interface JustBashWebSearchOptions {\n\texaApiKey: string\n\ttimeoutSec?: number\n}\n\nexport function createWebSearchTool(bash: Bash, opts: JustBashWebSearchOptions) {\n\tconst timeoutSec = opts.timeoutSec ?? DEFAULT_TIMEOUT_SEC\n\n\treturn WebSearchTool.define(\n\t\tasync (input: WebSearchInput): Promise<WebSearchResult> => {\n\t\t\tconst payload = JSON.stringify({\n\t\t\t\tquery: input.query,\n\t\t\t\tnumResults: input.numResults,\n\t\t\t\tcontents: { text: { maxCharacters: 500 } },\n\t\t\t})\n\n\t\t\t// Escape single quotes in payload for shell safety\n\t\t\tconst escapedPayload = payload.replace(/'/g, \"'\\\\''\")\n\n\t\t\tconst result = await bash.exec(\n\t\t\t\t`curl -s --max-time ${timeoutSec} ` +\n\t\t\t\t\t`-H \"Content-Type: application/json\" ` +\n\t\t\t\t\t`-H \"x-api-key: ${opts.exaApiKey}\" ` +\n\t\t\t\t\t`-d '${escapedPayload}' ` +\n\t\t\t\t\t`https://api.exa.ai/search`,\n\t\t\t)\n\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\tif (result.exitCode === 28) {\n\t\t\t\t\tthrow new Error('Search request timed out')\n\t\t\t\t}\n\t\t\t\tthrow new Error(`curl failed (exit ${result.exitCode}): ${result.stderr}`)\n\t\t\t}\n\n\t\t\tlet data: { results?: Array<{ title?: string; url?: string; text?: string; snippet?: string }> }\n\t\t\ttry {\n\t\t\t\tdata = JSON.parse(result.stdout)\n\t\t\t} catch {\n\t\t\t\tthrow new Error(`Failed to parse search response: ${result.stdout.slice(0, 200)}`)\n\t\t\t}\n\n\t\t\tconst results = (data.results ?? []).map((r) => ({\n\t\t\t\ttitle: r.title ?? '',\n\t\t\t\turl: r.url ?? '',\n\t\t\t\tsnippet: r.text ?? r.snippet ?? '',\n\t\t\t}))\n\n\t\t\treturn { results }\n\t\t},\n\t\t{ description: WEB_SEARCH_DESCRIPTION },\n\t)\n}\n",
|
|
16
|
+
"import { WriteTool } from '@humanlayer/agentlayer-core'\nimport { WRITE_DESCRIPTION } from '@humanlayer/agentlayer-core/prompts'\nimport type { Bash } from 'just-bash'\n\nexport function createWriteTool(bash: Bash) {\n\treturn WriteTool.define(\n\t\tasync (input) => {\n\t\t\t// Ensure parent directory exists\n\t\t\tconst dirResult = await bash.exec(`mkdir -p \"$(dirname \"${input.file_path}\")\"`)\n\t\t\tif (dirResult.exitCode !== 0) {\n\t\t\t\tthrow new Error(`Failed to create parent directory for ${input.file_path}: ${dirResult.stderr}`)\n\t\t\t}\n\n\t\t\t// Write content using a heredoc to handle special characters safely\n\t\t\t// We use a unique delimiter to avoid conflicts with content\n\t\t\tconst DELIM = 'WRITEOF_8f3a2b1c'\n\t\t\tconst writeResult = await bash.exec(`cat > \"${input.file_path}\" <<'${DELIM}'\\n${input.content}\\n${DELIM}`)\n\t\t\tif (writeResult.exitCode !== 0) {\n\t\t\t\tthrow new Error(`Failed to write file ${input.file_path}: ${writeResult.stderr}`)\n\t\t\t}\n\n\t\t\treturn `Successfully wrote to ${input.file_path}`\n\t\t},\n\t\t{ description: WRITE_DESCRIPTION },\n\t)\n}\n"
|
|
17
|
+
],
|
|
18
|
+
"mappings": ";AAAA;AACA;AACA;AACA;AAQO,SAAS,oBAAoB,CAAC,MAAY,OAA0B,CAAC,GAAG;AAAA,EAC9E,QAAQ,QAAQ;AAAA,EAOhB,MAAM,eAAe,CAAC,aAA6B;AAAA,IAClD,IAAI,CAAC,OAAO,WAAW,QAAQ,GAAG;AAAA,MACjC,OAAO;AAAA,IACR;AAAA,IACA,OAAO,QAAQ,KAAK,QAAQ;AAAA;AAAA,EAE7B,OAAO,eAAe,OACrB,OAAO,UAAU;AAAA,IAChB,QAAQ,eAAe;AAAA,IAEvB,IAAI,CAAC,cAAc,CAAC,WAAW,KAAK,GAAG;AAAA,MACtC,MAAM,IAAI,MAAM,wBAAwB;AAAA,IACzC;AAAA,IAEA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,MAAM,WAAW,UAAU;AAAA,MAC1B,OAAO,KAAK;AAAA,MACb,MAAM,IAAI,MAAM,oCAAoC,KAAK;AAAA;AAAA,IAG1D,IAAI,IAAI,WAAW,GAAG;AAAA,MACrB,MAAM,IAAI,MAAM,6BAA6B;AAAA,IAC9C;AAAA,IAEA,MAAM,WAAW,IAAI,KAAK,CAAC,OAAO,GAAG,SAAS,SAAS,GAAG,OAAO,SAAS,KAAK,GAAG,SAAS,QAAQ;AAAA,IACnG,IAAI,CAAC,UAAU;AAAA,MACd,MAAM,IAAI,MAAM,iDAAiD;AAAA,IAClE;AAAA,IAGA,MAAM,WAAW,OAAO,aAAsC;AAAA,MAC7D,MAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,WAAW;AAAA,MAClD,IAAI,OAAO,aAAa,GAAG;AAAA,QAC1B,MAAM,IAAI,MAAM,mBAAmB,UAAU;AAAA,MAC9C;AAAA,MACA,OAAO,OAAO;AAAA;AAAA,IAIf,MAAM,cAAc,KAAK,QAAQ;AAAA,IAGjC,MAAM,UAAoB,CAAC;AAAA,IAE3B,WAAW,MAAM,KAAK;AAAA,MACrB,IAAI,GAAG,SAAS,OAAO;AAAA,QACtB,MAAM,WAAW,GAAG;AAAA,QAEpB,MAAM,cAAc,MAAM,KAAK,KAAK,wBAAwB,aAAa;AAAA,QACzE,IAAI,YAAY,aAAa,GAAG;AAAA,UAC/B,MAAM,IAAI,MAAM,yCAAyC,aAAa,YAAY,QAAQ;AAAA,QAC3F;AAAA,QAEA,MAAM,QAAQ;AAAA,QACd,MAAM,UAAU,GAAG,cAAc;AAAA,QACjC,MAAM,cAAc,MAAM,KAAK,KAAK,UAAU,gBAAgB;AAAA,EAAW;AAAA,EAAY,OAAO;AAAA,QAC5F,IAAI,YAAY,aAAa,GAAG;AAAA,UAC/B,MAAM,IAAI,MAAM,wBAAwB,aAAa,YAAY,QAAQ;AAAA,QAC1E;AAAA,QACA,QAAQ,KAAK,SAAS,UAAU;AAAA,MACjC,EAAO,SAAI,GAAG,SAAS,UAAU;AAAA,QAChC,MAAM,UAAU,MAAM,SAAS,GAAG,QAAQ;AAAA,QAC1C,MAAM,UAAU,kBAAkB,SAAS,GAAG,MAAM;AAAA,QACpD,MAAM,QAAQ;AAAA,QACd,MAAM,cAAc,MAAM,KAAK,KAAK,UAAU,GAAG,gBAAgB;AAAA,EAAW;AAAA,EAAY,OAAO;AAAA,QAC/F,IAAI,YAAY,aAAa,GAAG;AAAA,UAC/B,MAAM,IAAI,MAAM,wBAAwB,GAAG,aAAa,YAAY,QAAQ;AAAA,QAC7E;AAAA,QACA,QAAQ,KAAK,WAAW,GAAG,UAAU;AAAA,MACtC,EAAO,SAAI,GAAG,SAAS,QAAQ;AAAA,QAC9B,MAAM,UAAU,MAAM,SAAS,GAAG,QAAQ;AAAA,QAC1C,MAAM,UAAU,kBAAkB,SAAS,GAAG,MAAM;AAAA,QACpD,MAAM,aAAa,GAAG;AAAA,QACtB,MAAM,cAAc,MAAM,KAAK,KAAK,wBAAwB,eAAe;AAAA,QAC3E,IAAI,YAAY,aAAa,GAAG;AAAA,UAC/B,MAAM,IAAI,MAAM,yCAAyC,eAAe,YAAY,QAAQ;AAAA,QAC7F;AAAA,QACA,MAAM,QAAQ;AAAA,QACd,MAAM,cAAc,MAAM,KAAK,KAAK,UAAU,kBAAkB;AAAA,EAAW;AAAA,EAAY,OAAO;AAAA,QAC9F,IAAI,YAAY,aAAa,GAAG;AAAA,UAC/B,MAAM,IAAI,MAAM,wBAAwB,eAAe,YAAY,QAAQ;AAAA,QAC5E;AAAA,QACA,MAAM,WAAW,MAAM,KAAK,KAAK,OAAO,GAAG,WAAW;AAAA,QACtD,IAAI,SAAS,aAAa,GAAG;AAAA,UAC5B,MAAM,IAAI,MAAM,kCAAkC,GAAG,aAAa,SAAS,QAAQ;AAAA,QACpF;AAAA,QACA,QAAQ,KAAK,SAAS,GAAG,cAAa,YAAY;AAAA,MACnD,EAAO,SAAI,GAAG,SAAS,UAAU;AAAA,QAChC,MAAM,WAAW,MAAM,KAAK,KAAK,OAAO,GAAG,WAAW;AAAA,QACtD,IAAI,SAAS,aAAa,GAAG;AAAA,UAC5B,MAAM,IAAI,MAAM,yBAAyB,GAAG,aAAa,SAAS,QAAQ;AAAA,QAC3E;AAAA,QACA,QAAQ,KAAK,WAAW,GAAG,UAAU;AAAA,MACtC;AAAA,IACD;AAAA,IAEA,OAAO,QAAQ,KAAK;AAAA,CAAI;AAAA,KAEzB,EAAE,aAAa,wBAAwB,CACxC;AAAA;;ACvHD;AACA;AACA;AAGO,SAAS,kBAAkB,CAAC,MAAY;AAAA,EAC9C,OAAO,SAAS,OACf,OAAO,UAAU;AAAA,IAChB,MAAM,SAAS,MAAM,KAAK,KAAK,MAAM,SAAS;AAAA,SACzC,MAAM,UAAU,EAAE,KAAK,MAAM,QAAQ,IAAI,CAAC;AAAA,IAC/C,CAAC;AAAA,IACD,IAAI,SAAS,OAAO;AAAA,IACpB,IAAI,OAAO,QAAQ;AAAA,MAClB,UAAU;AAAA,UAAa,OAAO;AAAA,IAC/B;AAAA,IACA,OAAO,eAAe,cAAc,OAAO;AAAA,EAAa,QAAQ;AAAA,KAEjE,EAAE,aAAa,iBAAiB,CACjC;AAAA;;ACjBD;AACA;AAGA,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAQ1B,eAAe,eAAe,CAC7B,MACA,OACA,QACA,YACyB;AAAA,EACzB,IAAI;AAAA,IACH,MAAM,QAAQ,GAAG,MAAM,gBAAgB,MAAM,kBAAkB,MAAM;AAAA,IACrE,MAAM,UAAU,KAAK,UAAU,EAAE,OAAO,WAAW,KAAK,CAAC;AAAA,IACzD,MAAM,iBAAiB,QAAQ,QAAQ,MAAM,OAAO;AAAA,IAEpD,MAAM,SAAS,MAAM,KAAK,KACzB,sBAAsB,gBACrB,yCACA,kBAAkB,aAClB,OAAO,qBACP,4BACF;AAAA,IAEA,IAAI,OAAO,aAAa;AAAA,MAAG,OAAO;AAAA,IAElC,MAAM,OAAO,KAAK,MAAM,OAAO,MAAM;AAAA,IACrC,OAAO,KAAK,YAAY;AAAA,IACvB,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;AAIT,eAAe,oBAAoB,CAClC,MACA,OACA,QACA,YACyB;AAAA,EACzB,IAAI;AAAA,IAEH,MAAM,cAAc,mBAAmB,MAAM,KAAK;AAAA,IAClD,MAAM,UAAU,mBAAmB,MAAM,WAAW;AAAA,IAEpD,MAAM,eAAe,MAAM,KAAK,KAC/B,sBAAsB,gBACrB,6BAA6B,aAC7B,IAAI,8CAA8C,2BAA2B,UAC/E;AAAA,IAEA,IAAI,aAAa,aAAa;AAAA,MAAG,OAAO;AAAA,IAExC,MAAM,aAAa,KAAK,MAAM,aAAa,MAAM;AAAA,IAGjD,MAAM,YAAY,WAAW,WAAW,CAAC;AAAA,IACzC,IAAI,UAAU,WAAW;AAAA,MAAG,OAAO;AAAA,IAEnC,MAAM,OAAO,UAAU,OAAO,CAAC,GAAG,OAAQ,EAAE,cAAc,MAAM,EAAE,cAAc,KAAK,IAAI,CAAE;AAAA,IAG3F,MAAM,eAAe,mBAAmB,MAAM,KAAK;AAAA,IACnD,MAAM,QAAQ,mBAAmB,KAAK,EAAE;AAAA,IAExC,MAAM,gBAAgB,MAAM,KAAK,KAChC,sBAAsB,gBACrB,6BAA6B,aAC7B,IAAI,0CAA0C,0BAA0B,QAC1E;AAAA,IAEA,IAAI,cAAc,aAAa;AAAA,MAAG,OAAO;AAAA,IACzC,OAAO,cAAc;AAAA,IACpB,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;AAIF,SAAS,oBAAoB,CAAC,MAAY,MAAiC;AAAA,EACjF,IAAI,CAAC,KAAK,aAAa,CAAC,KAAK,gBAAgB;AAAA,IAC5C,MAAM,IAAI,MAAM,gEAAgE;AAAA,EACjF;AAAA,EAEA,MAAM,aAAa,KAAK,cAAc;AAAA,EAEtC,OAAO,eAAe,OACrB,OAAO,UAA4C;AAAA,IAClD,OAAO,WAAW,YAAY,MAAM,QAAQ,IAAI;AAAA,MAC/C,KAAK,YAAY,gBAAgB,MAAM,OAAO,KAAK,WAAW,UAAU,IAAI,QAAQ,QAAQ,IAAI;AAAA,MAChG,KAAK,iBACF,qBAAqB,MAAM,OAAO,KAAK,gBAAgB,UAAU,IACjE,QAAQ,QAAQ,IAAI;AAAA,IACxB,CAAC;AAAA,IAED,MAAM,QAAkB,CAAC;AAAA,IACzB,IAAI,UAAU;AAAA,MACb,MAAM,KAAK;AAAA;AAAA,EAAgC,UAAU;AAAA,IACtD;AAAA,IACA,IAAI,WAAW;AAAA,MACd,MAAM,KAAK;AAAA;AAAA,EAA4B,WAAW;AAAA,IACnD;AAAA,IAEA,IAAI,MAAM,WAAW,GAAG;AAAA,MACvB,OAAO,+BAA+B,MAAM,4BAA4B,MAAM;AAAA,IAC/E;AAAA,IAEA,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,CAAa;AAAA,KAEhC,EAAE,aAAa,wBAAwB,CACxC;AAAA;;ACrHD;AACA;AAGO,SAAS,cAAc,CAAC,MAAY;AAAA,EAC1C,OAAO,SAAS,OACf,OAAO,UAAU;AAAA,IAEhB,MAAM,YAAY,MAAM,KAAK,KAAK,QAAQ,MAAM,YAAY;AAAA,IAC5D,IAAI,UAAU,aAAa,GAAG;AAAA,MAC7B,MAAM,IAAI,MAAM,QAAQ,MAAM,qBAAqB;AAAA,IACpD;AAAA,IAEA,MAAM,UAAU,UAAU;AAAA,IAE1B,IAAI,CAAC,QAAQ,SAAS,MAAM,UAAU,GAAG;AAAA,MACxC,OAAO,EAAE,SAAS,YAAY,EAAE;AAAA,IACjC;AAAA,IAEA,IAAI;AAAA,IACJ,IAAI;AAAA,IAEJ,IAAI,MAAM,aAAa;AAAA,MACtB,IAAI,QAAQ;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,QACZ,MAAM,MAAM,QAAQ,QAAQ,MAAM,YAAY,GAAG;AAAA,QACjD,IAAI,QAAQ;AAAA,UAAI;AAAA,QAChB;AAAA,QACA,MAAM,MAAM,MAAM,WAAW;AAAA,MAC9B;AAAA,MACA,UAAU,QAAQ,MAAM,MAAM,UAAU,EAAE,KAAK,MAAM,UAAU;AAAA,MAC/D,aAAa;AAAA,IACd,EAAO;AAAA,MAEN,MAAM,WAAW,QAAQ,QAAQ,MAAM,UAAU;AAAA,MACjD,MAAM,UAAU,QAAQ,YAAY,MAAM,UAAU;AAAA,MACpD,IAAI,aAAa,SAAS;AAAA,QACzB,MAAM,IAAI,MACT,mGACD;AAAA,MACD;AAAA,MACA,UAAU,QAAQ,QAAQ,MAAM,YAAY,MAAM,UAAU;AAAA,MAC5D,aAAa;AAAA;AAAA,IAId,MAAM,QAAQ;AAAA,IACd,MAAM,cAAc,MAAM,KAAK,KAAK,UAAU,MAAM,iBAAiB;AAAA,EAAW;AAAA,EAAY,OAAO;AAAA,IACnG,IAAI,YAAY,aAAa,GAAG;AAAA,MAC/B,MAAM,IAAI,MAAM,wBAAwB,MAAM,cAAc,YAAY,QAAQ;AAAA,IACjF;AAAA,IAEA,OAAO,EAAE,SAAS,SAAS,WAAW;AAAA,KAEvC,EAAE,aAAa,iBAAiB,CACjC;AAAA;;ACxDD;AACA;AAGO,SAAS,cAAc,CAAC,MAAY;AAAA,EAC1C,OAAO,SAAS,OACf,OAAO,UAAU;AAAA,IAChB,MAAM,aAAa,MAAM,QAAQ;AAAA,IAEjC,MAAM,SAAS,MAAM,KAAK,KAAK,kBAAkB,MAAM,aAAa,yBAAyB;AAAA,IAE7F,IAAI,OAAO,aAAa,KAAK,OAAO,aAAa,GAAG;AAAA,MAEnD,MAAM,aAAa,MAAM,KAAK,KAC7B,SAAS,8BAA8B,MAAM,kCAC9C;AAAA,MACA,IAAI,WAAW,aAAa,GAAG;AAAA,QAC9B,OAAO,CAAC;AAAA,MACT;AAAA,MACA,OAAO,WAAW,OAChB,MAAM;AAAA,CAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AAAA,IACjB;AAAA,IAEA,OAAO,OAAO,OACZ,MAAM;AAAA,CAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AAAA,KAEjB,EAAE,aAAa,iBAAiB,CACjC;AAAA;;AC9BD;AACA;AAGA,IAAM,cAAc;AAEb,SAAS,cAAc,CAAC,MAAY;AAAA,EAC1C,OAAO,SAAS,OACf,OAAO,UAAU;AAAA,IAChB,MAAM,aAAa,MAAM,QAAQ;AAAA,IACjC,IAAI,MAAM,2CAA2C,MAAM;AAAA,IAC3D,IAAI,MAAM,SAAS;AAAA,MAClB,OAAO,YAAY,MAAM;AAAA,IAC1B;AAAA,IACA,OAAO,KAAK;AAAA,IAEZ,MAAM,SAAS,MAAM,KAAK,KAAK,GAAG;AAAA,IAGlC,IAAI,OAAO,aAAa,GAAG;AAAA,MAC1B,OAAO,CAAC;AAAA,IACT;AAAA,IAEA,IAAI,OAAO,aAAa,GAAG;AAAA,MAC1B,MAAM,IAAI,MAAM,8BAA8B,OAAO,aAAa,OAAO,QAAQ;AAAA,IAClF;AAAA,IAGA,MAAM,UAAuB,CAAC;AAAA,IAC9B,WAAW,QAAQ,OAAO,OAAO,MAAM;AAAA,CAAI,GAAG;AAAA,MAC7C,IAAI,CAAC;AAAA,QAAM;AAAA,MACX,MAAM,WAAW,KAAK,QAAQ,GAAG;AAAA,MACjC,IAAI,aAAa;AAAA,QAAI;AAAA,MACrB,MAAM,YAAY,KAAK,QAAQ,KAAK,WAAW,CAAC;AAAA,MAChD,IAAI,cAAc;AAAA,QAAI;AAAA,MAEtB,MAAM,OAAO,KAAK,MAAM,GAAG,QAAQ;AAAA,MACnC,MAAM,UAAU,OAAO,SAAS,KAAK,MAAM,WAAW,GAAG,SAAS,GAAG,EAAE;AAAA,MACvE,MAAM,UAAU,KAAK,MAAM,YAAY,CAAC;AAAA,MAExC,IAAI,CAAC,OAAO,MAAM,OAAO,GAAG;AAAA,QAC3B,QAAQ,KAAK,EAAE,MAAM,MAAM,SAAS,QAAQ,CAAC;AAAA,MAC9C;AAAA,MAEA,IAAI,QAAQ,UAAU;AAAA,QAAa;AAAA,IACpC;AAAA,IAEA,OAAO;AAAA,KAER,EAAE,aAAa,iBAAiB,CACjC;AAAA;;AClDD;AACA;AAEO,SAAS,cAAc,CAAC,MAAY;AAAA,EAC1C,OAAO,SAAS,OACf,OAAO,UAAU;AAAA,IAChB,MAAM,UAAU,MAAM,QAAQ;AAAA,IAG9B,MAAM,SAAS,MAAM,KAAK,KAAK,WAAW,sBAAsB;AAAA,IAEhE,IAAI,OAAO,aAAa,GAAG;AAAA,MAC1B,MAAM,IAAI,MAAM,4BAA4B,YAAY,OAAO,QAAQ;AAAA,IACxE;AAAA,IAEA,MAAM,iBAAiB,IAAI,IAAY,CAAC,gBAAgB,QAAQ,QAAQ,SAAS,GAAI,MAAM,UAAU,CAAC,CAAE,CAAC;AAAA,IAEzG,MAAM,UAAuB,CAAC;AAAA,IAC9B,WAAW,OAAO,OAAO,OAAO,MAAM;AAAA,CAAI,GAAG;AAAA,MAC5C,MAAM,OAAO,IAAI,KAAK;AAAA,MACtB,IAAI,CAAC;AAAA,QAAM;AAAA,MAEX,IAAI,KAAK,SAAS,GAAG,GAAG;AAAA,QAEvB,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE;AAAA,QAC7B,IAAI,eAAe,IAAI,IAAI;AAAA,UAAG;AAAA,QAC9B,QAAQ,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC;AAAA,MACzC,EAAO;AAAA,QAEN,MAAM,OAAO,KAAK,QAAQ,YAAY,EAAE;AAAA,QACxC,IAAI,eAAe,IAAI,IAAI;AAAA,UAAG;AAAA,QAC9B,QAAQ,KAAK,EAAE,MAAM,MAAM,OAAO,CAAC;AAAA;AAAA,IAErC;AAAA,IAEA,OAAO;AAAA,KAER,EAAE,aAAa,iBAAiB,CACjC;AAAA;;ACvCD;AACA;AAGO,SAAS,sBAAsB,CAAC,MAAY;AAAA,EAClD,OAAO,SAAS,OACf,OAAO,UAAU;AAAA,IAChB,MAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,MAAM,YAAY;AAAA,IACzD,IAAI,OAAO,aAAa,GAAG;AAAA,MAC1B,MAAM,IAAI,MAAM,mBAAmB,MAAM,WAAW;AAAA,IACrD;AAAA,IACA,OAAO,OAAO;AAAA,KAEf,EAAE,aAAa,iBAAiB,CACjC;AAAA;;ACdD;AAIA,SAAS,2BAA2B,CAAC,SAAgC;AAAA,EACpE,MAAM,QAAQ,QAAQ,MAAM,uBAAuB;AAAA,EACnD,IAAI,CAAC;AAAA,IAAO,OAAO;AAAA,EACnB,MAAM,UAAU,MAAM,IAAI,MAAM,qBAAqB;AAAA,EACrD,OAAO,UAAU,IAAI,KAAK,KAAK;AAAA;AAGhC,SAAS,iBAAiB,CAAC,SAAgC;AAAA,EAC1D,MAAM,QAAQ,QAAQ,MAAM,YAAY;AAAA,EACxC,OAAO,QAAQ,IAAI,KAAK,KAAK;AAAA;AAG9B,eAAsB,sBAAsB,CAAC,MAAY,MAAqD;AAAA,EAC7G,MAAM,cAAc,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC,KAAK,IAAI;AAAA,EACrE,MAAM,WAAoB,CAAC;AAAA,EAE3B,WAAW,OAAO,aAAa;AAAA,IAC9B,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,WAAW,MAAM,KAAK,KAAK,OAAO,uBAAuB;AAAA,MACxD,MAAM;AAAA,MACP;AAAA;AAAA,IAED,IAAI,SAAS,aAAa;AAAA,MAAG;AAAA,IAE7B,MAAM,QAAQ,SAAS,OAAO,KAAK,EAAE,MAAM;AAAA,CAAI,EAAE,OAAO,OAAO;AAAA,IAC/D,WAAW,YAAY,OAAO;AAAA,MAC7B,MAAM,YAAY,MAAM,KAAK,KAAK,QAAQ,WAAW;AAAA,MACrD,IAAI,UAAU,aAAa;AAAA,QAAG;AAAA,MAE9B,MAAM,UAAU,UAAU;AAAA,MAC1B,MAAM,OAAO,SAAS,MAAM,GAAG,EAAE,IAAI,GAAG,QAAQ,OAAO,EAAE,KAAK;AAAA,MAC9D,MAAM,cAAc,4BAA4B,OAAO,KAAK,kBAAkB,OAAO,KAAK;AAAA,MAE1F,SAAS,KAAK,EAAE,MAAM,aAAa,QAAQ,CAAC;AAAA,IAC7C;AAAA,EACD;AAAA,EAEA,MAAM,YAAY,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAAA,EAC1D,WAAW,SAAS,KAAK,UAAU,CAAC,GAAG;AAAA,IACtC,UAAU,IAAI,MAAM,MAAM,KAAK;AAAA,EAChC;AAAA,EAEA,OAAO,gBAAgB,EAAE,QAAQ,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE,CAAC;AAAA;;AC/C3D;AACA;AAEA;AAEA,IAAM,oBAAoB,IAAI,OAAO;AACrC,IAAM,iBAAiB;AAKvB,SAAS,aAAa,CAAC,MAAsB;AAAA,EAC5C,OAAO,KACL,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,oDAAoD,EAAE,EAC9D,QAAQ,YAAY,EAAE,EACtB,QAAQ,UAAU,GAAG,EACrB,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,GAAG,EACpB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG,EACrB,QAAQ,WAAW,GAAG,EACtB,QAAQ,WAAW;AAAA;AAAA,CAAM,EACzB,KAAK;AAAA;AAGD,SAAS,kBAAkB,CAAC,MAAY;AAAA,EAC9C,MAAM,WAAW,IAAI,gBAAgB;AAAA,IACpC,cAAc;AAAA,IACd,gBAAgB;AAAA,EACjB,CAAC;AAAA,EACD,SAAS,OAAO,CAAC,UAAU,SAAS,QAAQ,QAAQ,YAAY,QAAQ,CAAC;AAAA,EAEzE,OAAO,aAAa,OACnB,OAAO,UAAU;AAAA,IAChB,IAAI,CAAC,MAAM,IAAI,WAAW,SAAS,KAAK,CAAC,MAAM,IAAI,WAAW,UAAU,GAAG;AAAA,MAC1E,MAAM,IAAI,MAAM,yCAAyC;AAAA,IAC1D;AAAA,IAEA,MAAM,aAAa,KAAK,IAAI,MAAM,SAAS,cAAc,IAAI;AAAA,IAC7D,MAAM,eAAe;AAAA,IAQrB,MAAM,SAAS,MAAM,KAAK,KACzB,2BAA2B,2BAA2B,gBACrD,8CACA,yBAAyB,MAAM,MACjC;AAAA,IAEA,IAAI,OAAO,aAAa,GAAG;AAAA,MAE1B,IAAI,OAAO,aAAa,IAAI;AAAA,QAC3B,MAAM,IAAI,MAAM,2BAA2B,MAAM,WAAW;AAAA,MAC7D;AAAA,MACA,IAAI,OAAO,aAAa,IAAI;AAAA,QAC3B,MAAM,IAAI,MAAM,wCAAwC;AAAA,MACzD;AAAA,MACA,MAAM,IAAI,MAAM,qBAAqB,OAAO,cAAc,OAAO,QAAQ;AAAA,IAC1E;AAAA,IAGA,MAAM,QAAQ,OAAO,OAAO,MAAM;AAAA,CAAI;AAAA,IACtC,MAAM,aAAa,MAAM,MAAM,SAAS,IAAI,KAAK,KAAK;AAAA,IACtD,MAAM,aAAa,OAAO,SAAS,YAAY,EAAE;AAAA,IACjD,MAAM,OAAO,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK;AAAA,CAAI;AAAA,IAEzC,IAAI,CAAC,OAAO,MAAM,UAAU,KAAK,cAAc,KAAK;AAAA,MACnD,MAAM,IAAI,MAAM,oCAAoC,YAAY;AAAA,IACjE;AAAA,IAEA,IAAI,MAAM,WAAW,QAAQ;AAAA,MAC5B,OAAO;AAAA,IACR;AAAA,IAEA,MAAM,SAAS,KAAK,UAAU,EAAE,WAAW,IAAI,KAAK,KAAK,UAAU,EAAE,YAAY,EAAE,WAAW,OAAO;AAAA,IAErG,IAAI,MAAM,WAAW,QAAQ;AAAA,MAC5B,IAAI,QAAQ;AAAA,QACX,OAAO,cAAc,IAAI;AAAA,MAC1B;AAAA,MACA,OAAO;AAAA,IACR;AAAA,IAGA,IAAI,QAAQ;AAAA,MACX,OAAO,SAAS,SAAS,IAAI;AAAA,IAC9B;AAAA,IACA,OAAO;AAAA,KAER,EAAE,aAAa,sBAAsB,CACtC;AAAA;;AC9FD;AACA;AAGA,IAAM,uBAAsB;AAOrB,SAAS,mBAAmB,CAAC,MAAY,MAAgC;AAAA,EAC/E,MAAM,aAAa,KAAK,cAAc;AAAA,EAEtC,OAAO,cAAc,OACpB,OAAO,UAAoD;AAAA,IAC1D,MAAM,UAAU,KAAK,UAAU;AAAA,MAC9B,OAAO,MAAM;AAAA,MACb,YAAY,MAAM;AAAA,MAClB,UAAU,EAAE,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,IAC1C,CAAC;AAAA,IAGD,MAAM,iBAAiB,QAAQ,QAAQ,MAAM,OAAO;AAAA,IAEpD,MAAM,SAAS,MAAM,KAAK,KACzB,sBAAsB,gBACrB,yCACA,kBAAkB,KAAK,gBACvB,OAAO,qBACP,2BACF;AAAA,IAEA,IAAI,OAAO,aAAa,GAAG;AAAA,MAC1B,IAAI,OAAO,aAAa,IAAI;AAAA,QAC3B,MAAM,IAAI,MAAM,0BAA0B;AAAA,MAC3C;AAAA,MACA,MAAM,IAAI,MAAM,qBAAqB,OAAO,cAAc,OAAO,QAAQ;AAAA,IAC1E;AAAA,IAEA,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,OAAO,KAAK,MAAM,OAAO,MAAM;AAAA,MAC9B,MAAM;AAAA,MACP,MAAM,IAAI,MAAM,oCAAoC,OAAO,OAAO,MAAM,GAAG,GAAG,GAAG;AAAA;AAAA,IAGlF,MAAM,WAAW,KAAK,WAAW,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,MAChD,OAAO,EAAE,SAAS;AAAA,MAClB,KAAK,EAAE,OAAO;AAAA,MACd,SAAS,EAAE,QAAQ,EAAE,WAAW;AAAA,IACjC,EAAE;AAAA,IAEF,OAAO,EAAE,QAAQ;AAAA,KAElB,EAAE,aAAa,uBAAuB,CACvC;AAAA;;ACzDD;AACA;AAGO,SAAS,eAAe,CAAC,MAAY;AAAA,EAC3C,OAAO,UAAU,OAChB,OAAO,UAAU;AAAA,IAEhB,MAAM,YAAY,MAAM,KAAK,KAAK,wBAAwB,MAAM,cAAc;AAAA,IAC9E,IAAI,UAAU,aAAa,GAAG;AAAA,MAC7B,MAAM,IAAI,MAAM,yCAAyC,MAAM,cAAc,UAAU,QAAQ;AAAA,IAChG;AAAA,IAIA,MAAM,QAAQ;AAAA,IACd,MAAM,cAAc,MAAM,KAAK,KAAK,UAAU,MAAM,iBAAiB;AAAA,EAAW,MAAM;AAAA,EAAY,OAAO;AAAA,IACzG,IAAI,YAAY,aAAa,GAAG;AAAA,MAC/B,MAAM,IAAI,MAAM,wBAAwB,MAAM,cAAc,YAAY,QAAQ;AAAA,IACjF;AAAA,IAEA,OAAO,yBAAyB,MAAM;AAAA,KAEvC,EAAE,aAAa,kBAAkB,CAClC;AAAA;",
|
|
19
|
+
"debugId": "1524F9AF4D010FAD64756E2164756E21",
|
|
20
|
+
"names": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ListEntry } from '@humanlayer/agentlayer-core/interfaces';
|
|
2
|
+
import type { Bash } from 'just-bash';
|
|
3
|
+
export declare function createListTool(bash: Bash): import("@humanlayer/agentlayer-core").Tool<{
|
|
4
|
+
path?: string | undefined;
|
|
5
|
+
ignore?: string[] | undefined;
|
|
6
|
+
}, ListEntry[]>;
|
|
7
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAGvE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACrC,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI;;;gBAoCxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI;;;;WAWhD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Skill } from '@humanlayer/agentlayer-core/interfaces';
|
|
2
|
+
import type { Bash } from 'just-bash';
|
|
3
|
+
export declare function createSkillToolFromVFS(bash: Bash, opts: {
|
|
4
|
+
dirs: string | string[];
|
|
5
|
+
skills?: Skill[];
|
|
6
|
+
}): Promise<import("@humanlayer/agentlayer-core").Tool<{
|
|
7
|
+
name: string;
|
|
8
|
+
args?: string | undefined;
|
|
9
|
+
}, string>>;
|
|
10
|
+
//# sourceMappingURL=skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/tools/skill.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAA;AACnE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAcrC,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;CAAE;;;YAgC3G"}
|