nodebench-mcp 1.4.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NODEBENCH_AGENTS.md +154 -2
- package/README.md +214 -215
- package/dist/__tests__/comparativeBench.test.d.ts +1 -0
- package/dist/__tests__/comparativeBench.test.js +722 -0
- package/dist/__tests__/comparativeBench.test.js.map +1 -0
- package/dist/__tests__/evalHarness.test.js +24 -2
- package/dist/__tests__/evalHarness.test.js.map +1 -1
- package/dist/__tests__/gaiaCapabilityEval.test.d.ts +14 -0
- package/dist/__tests__/gaiaCapabilityEval.test.js +420 -0
- package/dist/__tests__/gaiaCapabilityEval.test.js.map +1 -0
- package/dist/__tests__/gaiaCapabilityFilesEval.test.d.ts +15 -0
- package/dist/__tests__/gaiaCapabilityFilesEval.test.js +303 -0
- package/dist/__tests__/gaiaCapabilityFilesEval.test.js.map +1 -0
- package/dist/__tests__/openDatasetParallelEvalGaia.test.d.ts +7 -0
- package/dist/__tests__/openDatasetParallelEvalGaia.test.js +279 -0
- package/dist/__tests__/openDatasetParallelEvalGaia.test.js.map +1 -0
- package/dist/__tests__/openDatasetPerfComparison.test.d.ts +10 -0
- package/dist/__tests__/openDatasetPerfComparison.test.js +318 -0
- package/dist/__tests__/openDatasetPerfComparison.test.js.map +1 -0
- package/dist/__tests__/tools.test.js +155 -7
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/__tests__/toolsetGatingEval.test.d.ts +1 -0
- package/dist/__tests__/toolsetGatingEval.test.js +1031 -0
- package/dist/__tests__/toolsetGatingEval.test.js.map +1 -0
- package/dist/db.js +56 -0
- package/dist/db.js.map +1 -1
- package/dist/index.js +462 -28
- package/dist/index.js.map +1 -1
- package/dist/tools/localFileTools.d.ts +15 -0
- package/dist/tools/localFileTools.js +386 -0
- package/dist/tools/localFileTools.js.map +1 -0
- package/dist/tools/metaTools.js +170 -3
- package/dist/tools/metaTools.js.map +1 -1
- package/dist/tools/parallelAgentTools.d.ts +18 -0
- package/dist/tools/parallelAgentTools.js +1272 -0
- package/dist/tools/parallelAgentTools.js.map +1 -0
- package/dist/tools/selfEvalTools.js +240 -10
- package/dist/tools/selfEvalTools.js.map +1 -1
- package/dist/tools/webTools.js +171 -37
- package/dist/tools/webTools.js.map +1 -1
- package/package.json +26 -8
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local file parsing tools (deterministic).
|
|
3
|
+
*
|
|
4
|
+
* These tools intentionally avoid network access and operate only on local files.
|
|
5
|
+
* Primary use cases:
|
|
6
|
+
* - GAIA file-backed tasks (PDF / XLSX / CSV attachments)
|
|
7
|
+
* - Internal agent workflows that need structured parsing without "LLM OCR"
|
|
8
|
+
*
|
|
9
|
+
* Optional deps (installed by default when available):
|
|
10
|
+
* - xlsx: XLSX parsing
|
|
11
|
+
* - papaparse: CSV parsing
|
|
12
|
+
* - pdf-parse: PDF text extraction (page-aware)
|
|
13
|
+
*/
|
|
14
|
+
import { readFile } from "node:fs/promises";
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import os from "node:os";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
function expandTilde(p) {
|
|
19
|
+
if (!p)
|
|
20
|
+
return p;
|
|
21
|
+
if (p === "~")
|
|
22
|
+
return os.homedir();
|
|
23
|
+
if (p.startsWith("~/") || p.startsWith("~\\"))
|
|
24
|
+
return path.join(os.homedir(), p.slice(2));
|
|
25
|
+
return p;
|
|
26
|
+
}
|
|
27
|
+
function resolveLocalPath(inputPath) {
|
|
28
|
+
const expanded = expandTilde(String(inputPath ?? "").trim());
|
|
29
|
+
if (!expanded)
|
|
30
|
+
throw new Error("path is required");
|
|
31
|
+
return path.isAbsolute(expanded) ? expanded : path.resolve(process.cwd(), expanded);
|
|
32
|
+
}
|
|
33
|
+
function clampInt(value, fallback, min, max) {
|
|
34
|
+
const n = typeof value === "number" ? value : Number.parseInt(String(value ?? ""), 10);
|
|
35
|
+
if (!Number.isFinite(n))
|
|
36
|
+
return fallback;
|
|
37
|
+
return Math.max(min, Math.min(max, n));
|
|
38
|
+
}
|
|
39
|
+
function truncateCell(value, maxChars) {
|
|
40
|
+
if (value === null || value === undefined)
|
|
41
|
+
return null;
|
|
42
|
+
if (typeof value === "number")
|
|
43
|
+
return value;
|
|
44
|
+
if (typeof value === "boolean")
|
|
45
|
+
return value;
|
|
46
|
+
if (value instanceof Date)
|
|
47
|
+
return value.toISOString();
|
|
48
|
+
const s = String(value);
|
|
49
|
+
if (s.length <= maxChars)
|
|
50
|
+
return s;
|
|
51
|
+
return s.slice(0, maxChars) + "...";
|
|
52
|
+
}
|
|
53
|
+
async function getXlsx() {
|
|
54
|
+
try {
|
|
55
|
+
const mod = await import("xlsx");
|
|
56
|
+
return mod.default ?? mod;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
throw new Error("Missing optional dependency: xlsx. Install it (or run npm install in packages/mcp-local) to use XLSX parsing.");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function getPapaParse() {
|
|
63
|
+
try {
|
|
64
|
+
const mod = await import("papaparse");
|
|
65
|
+
return mod.default ?? mod;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function getPdfParseModule() {
|
|
72
|
+
try {
|
|
73
|
+
return await import("pdf-parse");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new Error("Missing optional dependency: pdf-parse. Install it (or run npm install in packages/mcp-local) to use PDF parsing.");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export const localFileTools = [
|
|
80
|
+
{
|
|
81
|
+
name: "read_csv_file",
|
|
82
|
+
description: "Read a local CSV file and return a bounded table preview (headers + rows). Deterministic, no network.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
path: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "Path to a local .csv file (absolute or relative to current working directory).",
|
|
89
|
+
},
|
|
90
|
+
hasHeader: {
|
|
91
|
+
type: "boolean",
|
|
92
|
+
description: "If true, treats the first row as headers.",
|
|
93
|
+
default: true,
|
|
94
|
+
},
|
|
95
|
+
delimiter: {
|
|
96
|
+
type: "string",
|
|
97
|
+
description: "Optional delimiter override, e.g. ',' or '\\t'. If omitted, parser default is used.",
|
|
98
|
+
},
|
|
99
|
+
encoding: {
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "File encoding (default: utf8).",
|
|
102
|
+
default: "utf8",
|
|
103
|
+
},
|
|
104
|
+
maxRows: {
|
|
105
|
+
type: "number",
|
|
106
|
+
description: "Maximum number of data rows to return (excluding header).",
|
|
107
|
+
default: 200,
|
|
108
|
+
},
|
|
109
|
+
maxCols: {
|
|
110
|
+
type: "number",
|
|
111
|
+
description: "Maximum number of columns to return.",
|
|
112
|
+
default: 50,
|
|
113
|
+
},
|
|
114
|
+
maxCellChars: {
|
|
115
|
+
type: "number",
|
|
116
|
+
description: "Maximum characters to return per cell (long cells are truncated).",
|
|
117
|
+
default: 2000,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
required: ["path"],
|
|
121
|
+
},
|
|
122
|
+
handler: async (args) => {
|
|
123
|
+
const filePath = resolveLocalPath(args?.path);
|
|
124
|
+
if (!existsSync(filePath))
|
|
125
|
+
throw new Error(`File not found: ${filePath}`);
|
|
126
|
+
const encoding = String(args?.encoding ?? "utf8");
|
|
127
|
+
const text = await readFile(filePath, { encoding });
|
|
128
|
+
const hasHeader = args?.hasHeader !== false;
|
|
129
|
+
const maxRows = clampInt(args?.maxRows, 200, 1, 5000);
|
|
130
|
+
const maxCols = clampInt(args?.maxCols, 50, 1, 500);
|
|
131
|
+
const maxCellChars = clampInt(args?.maxCellChars, 2000, 20, 20000);
|
|
132
|
+
const delimiter = typeof args?.delimiter === "string" ? args.delimiter : undefined;
|
|
133
|
+
const papa = await getPapaParse();
|
|
134
|
+
let rows = [];
|
|
135
|
+
let parseErrors = [];
|
|
136
|
+
if (papa?.parse) {
|
|
137
|
+
const result = papa.parse(text, {
|
|
138
|
+
...(delimiter ? { delimiter } : {}),
|
|
139
|
+
skipEmptyLines: true,
|
|
140
|
+
dynamicTyping: false,
|
|
141
|
+
});
|
|
142
|
+
rows = Array.isArray(result?.data) ? result.data : [];
|
|
143
|
+
parseErrors = Array.isArray(result?.errors) ? result.errors : [];
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// Minimal fallback parser: split by newlines and commas (no quote handling).
|
|
147
|
+
const lines = String(text).split(/\r?\n/).filter((l) => l.trim().length > 0);
|
|
148
|
+
rows = lines.map((l) => l.split(delimiter ?? ","));
|
|
149
|
+
}
|
|
150
|
+
// Normalize to array-of-arrays and bound.
|
|
151
|
+
const normalized = rows
|
|
152
|
+
.filter((r) => Array.isArray(r))
|
|
153
|
+
.map((r) => r.slice(0, maxCols).map((c) => truncateCell(c, maxCellChars)));
|
|
154
|
+
const headerRow = hasHeader ? normalized[0] : undefined;
|
|
155
|
+
const dataRows = hasHeader ? normalized.slice(1) : normalized;
|
|
156
|
+
const limitedRows = dataRows.slice(0, maxRows);
|
|
157
|
+
const colCount = Math.max(headerRow ? headerRow.length : 0, ...limitedRows.map((r) => r.length));
|
|
158
|
+
const truncated = dataRows.length > limitedRows.length ||
|
|
159
|
+
normalized.some((r) => r.length > maxCols) ||
|
|
160
|
+
colCount > maxCols;
|
|
161
|
+
const headers = headerRow
|
|
162
|
+
? headerRow.map((h) => String(h ?? "").trim())
|
|
163
|
+
: Array.from({ length: colCount }, (_, i) => `col_${i + 1}`);
|
|
164
|
+
return {
|
|
165
|
+
path: filePath,
|
|
166
|
+
encoding,
|
|
167
|
+
hasHeader,
|
|
168
|
+
delimiter: delimiter ?? null,
|
|
169
|
+
parseErrors: parseErrors.length > 0 ? parseErrors.slice(0, 5) : [],
|
|
170
|
+
rowCount: dataRows.length,
|
|
171
|
+
returnedRows: limitedRows.length,
|
|
172
|
+
colCount,
|
|
173
|
+
truncated,
|
|
174
|
+
headers: headers.slice(0, maxCols),
|
|
175
|
+
rows: limitedRows.map((r) => r.slice(0, maxCols)),
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: "read_xlsx_file",
|
|
181
|
+
description: "Read a local XLSX workbook and return a bounded sheet preview (headers + rows). Deterministic, no network.",
|
|
182
|
+
inputSchema: {
|
|
183
|
+
type: "object",
|
|
184
|
+
properties: {
|
|
185
|
+
path: {
|
|
186
|
+
type: "string",
|
|
187
|
+
description: "Path to a local .xlsx file (absolute or relative to current working directory).",
|
|
188
|
+
},
|
|
189
|
+
sheetName: {
|
|
190
|
+
type: "string",
|
|
191
|
+
description: "Sheet to read. If omitted, the first sheet is used.",
|
|
192
|
+
},
|
|
193
|
+
headerRow: {
|
|
194
|
+
type: "number",
|
|
195
|
+
description: "1-based header row index. Use 0 for no header row.",
|
|
196
|
+
default: 1,
|
|
197
|
+
},
|
|
198
|
+
rangeA1: {
|
|
199
|
+
type: "string",
|
|
200
|
+
description: "Optional A1 range (e.g. A1:D50) to limit parsing to a specific region.",
|
|
201
|
+
},
|
|
202
|
+
maxRows: {
|
|
203
|
+
type: "number",
|
|
204
|
+
description: "Maximum number of data rows to return (excluding header).",
|
|
205
|
+
default: 200,
|
|
206
|
+
},
|
|
207
|
+
maxCols: {
|
|
208
|
+
type: "number",
|
|
209
|
+
description: "Maximum number of columns to return.",
|
|
210
|
+
default: 50,
|
|
211
|
+
},
|
|
212
|
+
maxCellChars: {
|
|
213
|
+
type: "number",
|
|
214
|
+
description: "Maximum characters to return per cell (long cells are truncated).",
|
|
215
|
+
default: 2000,
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
required: ["path"],
|
|
219
|
+
},
|
|
220
|
+
handler: async (args) => {
|
|
221
|
+
const filePath = resolveLocalPath(args?.path);
|
|
222
|
+
if (!existsSync(filePath))
|
|
223
|
+
throw new Error(`File not found: ${filePath}`);
|
|
224
|
+
const XLSX = await getXlsx();
|
|
225
|
+
const wb = XLSX.readFile(filePath, {
|
|
226
|
+
cellDates: true,
|
|
227
|
+
dense: true,
|
|
228
|
+
});
|
|
229
|
+
const sheets = Array.isArray(wb?.SheetNames) ? wb.SheetNames : [];
|
|
230
|
+
if (sheets.length === 0)
|
|
231
|
+
throw new Error(`No sheets found in workbook: ${filePath}`);
|
|
232
|
+
const requestedSheet = typeof args?.sheetName === "string" ? args.sheetName.trim() : "";
|
|
233
|
+
const sheetName = requestedSheet || sheets[0];
|
|
234
|
+
const sheet = wb.Sheets?.[sheetName];
|
|
235
|
+
if (!sheet) {
|
|
236
|
+
throw new Error(`Sheet not found: "${sheetName}". Available sheets: ${sheets.join(", ")}`);
|
|
237
|
+
}
|
|
238
|
+
const headerRow = clampInt(args?.headerRow, 1, 0, 1000);
|
|
239
|
+
const maxRows = clampInt(args?.maxRows, 200, 1, 5000);
|
|
240
|
+
const maxCols = clampInt(args?.maxCols, 50, 1, 500);
|
|
241
|
+
const maxCellChars = clampInt(args?.maxCellChars, 2000, 20, 20000);
|
|
242
|
+
const rangeA1 = typeof args?.rangeA1 === "string" ? args.rangeA1.trim() : "";
|
|
243
|
+
const table = XLSX.utils.sheet_to_json(sheet, {
|
|
244
|
+
header: 1,
|
|
245
|
+
blankrows: false,
|
|
246
|
+
defval: "",
|
|
247
|
+
...(rangeA1 ? { range: rangeA1 } : {}),
|
|
248
|
+
});
|
|
249
|
+
const normalized = table
|
|
250
|
+
.filter((r) => Array.isArray(r))
|
|
251
|
+
.map((r) => r.slice(0, maxCols).map((c) => truncateCell(c, maxCellChars)));
|
|
252
|
+
const headerIdx = headerRow > 0 ? headerRow - 1 : -1;
|
|
253
|
+
const header = headerIdx >= 0 ? normalized[headerIdx] : undefined;
|
|
254
|
+
const dataRows = headerIdx >= 0 ? normalized.slice(headerIdx + 1) : normalized;
|
|
255
|
+
const limitedRows = dataRows.slice(0, maxRows);
|
|
256
|
+
const colCount = Math.max(header ? header.length : 0, ...limitedRows.map((r) => r.length));
|
|
257
|
+
const truncated = dataRows.length > limitedRows.length ||
|
|
258
|
+
normalized.some((r) => r.length > maxCols) ||
|
|
259
|
+
colCount > maxCols;
|
|
260
|
+
const headers = header
|
|
261
|
+
? header.map((h) => String(h ?? "").trim())
|
|
262
|
+
: Array.from({ length: colCount }, (_, i) => `col_${i + 1}`);
|
|
263
|
+
return {
|
|
264
|
+
path: filePath,
|
|
265
|
+
sheets,
|
|
266
|
+
sheetName,
|
|
267
|
+
headerRow,
|
|
268
|
+
rangeA1: rangeA1 || null,
|
|
269
|
+
rowCount: dataRows.length,
|
|
270
|
+
returnedRows: limitedRows.length,
|
|
271
|
+
colCount,
|
|
272
|
+
truncated,
|
|
273
|
+
headers: headers.slice(0, maxCols),
|
|
274
|
+
rows: limitedRows.map((r) => r.slice(0, maxCols)),
|
|
275
|
+
};
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: "read_pdf_text",
|
|
280
|
+
description: "Extract text from a local PDF file for selected pages. Returns bounded text with page markers. Deterministic, no network.",
|
|
281
|
+
inputSchema: {
|
|
282
|
+
type: "object",
|
|
283
|
+
properties: {
|
|
284
|
+
path: {
|
|
285
|
+
type: "string",
|
|
286
|
+
description: "Path to a local .pdf file (absolute or relative to current working directory).",
|
|
287
|
+
},
|
|
288
|
+
pageStart: {
|
|
289
|
+
type: "number",
|
|
290
|
+
description: "1-based start page (inclusive). Defaults to 1.",
|
|
291
|
+
default: 1,
|
|
292
|
+
},
|
|
293
|
+
pageEnd: {
|
|
294
|
+
type: "number",
|
|
295
|
+
description: "1-based end page (inclusive). Defaults to 3.",
|
|
296
|
+
default: 3,
|
|
297
|
+
},
|
|
298
|
+
pageNumbers: {
|
|
299
|
+
type: "array",
|
|
300
|
+
description: "Optional explicit list of 1-based pages to extract (overrides pageStart/pageEnd).",
|
|
301
|
+
items: { type: "number" },
|
|
302
|
+
},
|
|
303
|
+
maxChars: {
|
|
304
|
+
type: "number",
|
|
305
|
+
description: "Maximum characters to return across all extracted pages (text is truncated).",
|
|
306
|
+
default: 12000,
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
required: ["path"],
|
|
310
|
+
},
|
|
311
|
+
handler: async (args) => {
|
|
312
|
+
const filePath = resolveLocalPath(args?.path);
|
|
313
|
+
if (!existsSync(filePath))
|
|
314
|
+
throw new Error(`File not found: ${filePath}`);
|
|
315
|
+
const maxChars = clampInt(args?.maxChars, 12000, 1000, 200000);
|
|
316
|
+
const pageNumbersRaw = Array.isArray(args?.pageNumbers) ? args.pageNumbers : null;
|
|
317
|
+
const explicitPages = pageNumbersRaw
|
|
318
|
+
? pageNumbersRaw
|
|
319
|
+
.map((n) => clampInt(n, 0, 0, 100000))
|
|
320
|
+
.filter((n) => n > 0)
|
|
321
|
+
: null;
|
|
322
|
+
const pageStart = clampInt(args?.pageStart, 1, 1, 100000);
|
|
323
|
+
const pageEnd = clampInt(args?.pageEnd, 3, 1, 100000);
|
|
324
|
+
const mod = await getPdfParseModule();
|
|
325
|
+
const PDFParse = mod?.PDFParse;
|
|
326
|
+
if (typeof PDFParse !== "function") {
|
|
327
|
+
throw new Error("pdf-parse module missing PDFParse export (unsupported version)");
|
|
328
|
+
}
|
|
329
|
+
const buffer = await readFile(filePath);
|
|
330
|
+
const parser = new PDFParse({ data: buffer });
|
|
331
|
+
let numPages = 0;
|
|
332
|
+
let text = "";
|
|
333
|
+
let extractedPages = [];
|
|
334
|
+
try {
|
|
335
|
+
const parseParams = {
|
|
336
|
+
// Prefer consistent structure; we add our own page markers below.
|
|
337
|
+
lineEnforce: true,
|
|
338
|
+
pageJoiner: "",
|
|
339
|
+
parseHyperlinks: false,
|
|
340
|
+
};
|
|
341
|
+
if (explicitPages && explicitPages.length > 0) {
|
|
342
|
+
parseParams.partial = explicitPages;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
const start = Math.min(pageStart, pageEnd);
|
|
346
|
+
const end = Math.max(pageStart, pageEnd);
|
|
347
|
+
parseParams.first = start;
|
|
348
|
+
parseParams.last = end;
|
|
349
|
+
}
|
|
350
|
+
const result = await parser.getText(parseParams);
|
|
351
|
+
numPages = Number(result?.total ?? 0);
|
|
352
|
+
const pages = Array.isArray(result?.pages) ? result.pages : [];
|
|
353
|
+
extractedPages = pages
|
|
354
|
+
.map((p) => Number(p?.num ?? 0))
|
|
355
|
+
.filter((n) => Number.isFinite(n) && n > 0);
|
|
356
|
+
text = pages
|
|
357
|
+
.map((p) => `\n\n[PAGE ${Number(p?.num ?? 0)}]\n${String(p?.text ?? "").trim()}\n`)
|
|
358
|
+
.join("")
|
|
359
|
+
.trim();
|
|
360
|
+
}
|
|
361
|
+
finally {
|
|
362
|
+
try {
|
|
363
|
+
await parser.destroy();
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// ignore
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
let truncated = false;
|
|
370
|
+
if (text.length > maxChars) {
|
|
371
|
+
text = text.slice(0, maxChars);
|
|
372
|
+
truncated = true;
|
|
373
|
+
}
|
|
374
|
+
const pagesIncluded = extractedPages;
|
|
375
|
+
return {
|
|
376
|
+
path: filePath,
|
|
377
|
+
numPages,
|
|
378
|
+
pagesIncluded,
|
|
379
|
+
maxChars,
|
|
380
|
+
truncated,
|
|
381
|
+
text,
|
|
382
|
+
};
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
];
|
|
386
|
+
//# sourceMappingURL=localFileTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localFileTools.js","sourceRoot":"","sources":["../../src/tools/localFileTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB;IACzC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc,EAAE,QAAgB,EAAE,GAAW,EAAE,GAAW;IAC1E,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACvF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAE,QAAgB;IACpD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,OAAO;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QACjC,OAAQ,GAAW,CAAC,OAAO,IAAI,GAAG,CAAC;IACrC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QACtC,OAAQ,GAAW,CAAC,OAAO,IAAI,GAAG,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB;IAC9B,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,uGAAuG;QACzG,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gFAAgF;iBAC9F;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,2CAA2C;oBACxD,OAAO,EAAE,IAAI;iBACd;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,qFAAqF;iBACnG;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gCAAgC;oBAC7C,OAAO,EAAE,MAAM;iBAChB;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,2DAA2D;oBACxE,OAAO,EAAE,GAAG;iBACb;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sCAAsC;oBACnD,OAAO,EAAE,EAAE;iBACZ;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mEAAmE;oBAChF,OAAO,EAAE,IAAI;iBACd;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YAE1E,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,IAAI,MAAM,CAA0B,CAAC;YAC3E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpD,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,KAAK,KAAK,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnE,MAAM,SAAS,GAAG,OAAO,IAAI,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YAEnF,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAC;YAElC,IAAI,IAAI,GAAgB,EAAE,CAAC;YAC3B,IAAI,WAAW,GAAU,EAAE,CAAC;YAE5B,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;oBAC9B,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnC,cAAc,EAAE,IAAI;oBACpB,aAAa,EAAE,KAAK;iBACrB,CAAC,CAAC;gBACH,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,IAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvE,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,6EAA6E;gBAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC7E,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC;YACrD,CAAC;YAED,0CAA0C;YAC1C,MAAM,UAAU,GAAG,IAAI;iBACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;iBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAe,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;YAE5F,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAE,UAAU,CAAC,CAAC,CAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;YAC/E,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YAE9D,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAE/C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAChC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CACpC,CAAC;YACF,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;gBACpC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC;gBAC1C,QAAQ,GAAG,OAAO,CAAC;YAErB,MAAM,OAAO,GAAG,SAAS;gBACvB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC9C,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAE/D,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ;gBACR,SAAS;gBACT,SAAS,EAAE,SAAS,IAAI,IAAI;gBAC5B,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;gBAClE,QAAQ,EAAE,QAAQ,CAAC,MAAM;gBACzB,YAAY,EAAE,WAAW,CAAC,MAAM;gBAChC,QAAQ;gBACR,SAAS;gBACT,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;gBAClC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;aAClD,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,4GAA4G;QAC9G,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iFAAiF;iBAC/F;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,qDAAqD;iBACnE;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oDAAoD;oBACjE,OAAO,EAAE,CAAC;iBACX;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,wEAAwE;iBACtF;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,2DAA2D;oBACxE,OAAO,EAAE,GAAG;iBACb;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sCAAsC;oBACnD,OAAO,EAAE,EAAE;iBACZ;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mEAAmE;oBAChF,OAAO,EAAE,IAAI;iBACd;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YAE1E,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;YAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;gBACjC,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YAEH,MAAM,MAAM,GAAa,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAC;YAErF,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,MAAM,SAAS,GAAG,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;YACrC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CACb,qBAAqB,SAAS,wBAAwB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1E,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAE7E,MAAM,KAAK,GAAgB,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE;gBACzD,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,EAAE;gBACV,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvC,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,KAAK;iBACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;iBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAe,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;YAE5F,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAE,UAAU,CAAC,SAAS,CAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;YAEzF,MAAM,QAAQ,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YAC/E,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAE/C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3F,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;gBACpC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC;gBAC1C,QAAQ,GAAG,OAAO,CAAC;YAErB,MAAM,OAAO,GAAG,MAAM;gBACpB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC3C,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAE/D,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,MAAM;gBACN,SAAS;gBACT,SAAS;gBACT,OAAO,EAAE,OAAO,IAAI,IAAI;gBACxB,QAAQ,EAAE,QAAQ,CAAC,MAAM;gBACzB,YAAY,EAAE,WAAW,CAAC,MAAM;gBAChC,QAAQ;gBACR,SAAS;gBACT,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;gBAClC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;aAClD,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,2HAA2H;QAC7H,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gFAAgF;iBAC9F;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gDAAgD;oBAC7D,OAAO,EAAE,CAAC;iBACX;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,8CAA8C;oBAC3D,OAAO,EAAE,CAAC;iBACX;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,mFAAmF;oBAChG,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC1B;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,8EAA8E;oBAC3F,OAAO,EAAE,KAAK;iBACf;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YAE1E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAE/D,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,WAAyB,CAAC,CAAC,CAAC,IAAI,CAAC;YACjG,MAAM,aAAa,GAAG,cAAc;gBAClC,CAAC,CAAC,cAAc;qBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;qBACrC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;gBACzB,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAEtD,MAAM,GAAG,GAAG,MAAM,iBAAiB,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAI,GAAW,EAAE,QAAQ,CAAC;YACxC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAE9C,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,IAAI,cAAc,GAAa,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,WAAW,GAAQ;oBACvB,kEAAkE;oBAClE,WAAW,EAAE,IAAI;oBACjB,UAAU,EAAE,EAAE;oBACd,eAAe,EAAE,KAAK;iBACvB,CAAC;gBAEF,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9C,WAAW,CAAC,OAAO,GAAG,aAAa,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;oBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;oBACzC,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;oBAC1B,WAAW,CAAC,IAAI,GAAG,GAAG,CAAC;gBACzB,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBACjD,QAAQ,GAAG,MAAM,CAAE,MAAc,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;gBAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAE,MAAc,EAAE,KAAK,CAAC,CAAC,CAAC,CAAE,MAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjF,cAAc,GAAG,KAAK;qBACnB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;qBACpC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACtD,IAAI,GAAG,KAAK;qBACT,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,aAAa,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC;qBACvF,IAAI,CAAC,EAAE,CAAC;qBACR,IAAI,EAAE,CAAC;YACZ,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;gBACzB,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YAED,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBAC/B,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,MAAM,aAAa,GAAG,cAAc,CAAC;YAErC,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ;gBACR,aAAa;gBACb,QAAQ;gBACR,SAAS;gBACT,IAAI;aACL,CAAC;QACJ,CAAC;KACF;CACF,CAAC"}
|
package/dist/tools/metaTools.js
CHANGED
|
@@ -723,9 +723,120 @@ const METHODOLOGY_CONTENT = {
|
|
|
723
723
|
},
|
|
724
724
|
composesWith: "Use alongside agent_bootstrap for complete autonomous infrastructure setup. Feeds into triple_verify for validation.",
|
|
725
725
|
},
|
|
726
|
+
parallel_agent_teams: {
|
|
727
|
+
title: "Parallel Agent Teams — Multi-Agent Coordination",
|
|
728
|
+
description: 'Based on Anthropic\'s "Building a C Compiler with Parallel Claudes" (Feb 2026). Patterns for running multiple AI agents in parallel on a shared codebase: task locking to prevent duplicate work, role specialization, context window budget management, oracle-based testing, and progress tracking for fresh agent sessions. Reference: https://www.anthropic.com/engineering/building-c-compiler',
|
|
729
|
+
steps: [
|
|
730
|
+
{
|
|
731
|
+
step: 1,
|
|
732
|
+
name: "Orient — Check Parallel Status",
|
|
733
|
+
description: "Every new agent session starts by checking what other agents are doing. Avoid duplicate work. Review blocked tasks that need fresh eyes.",
|
|
734
|
+
tools: ["get_parallel_status", "list_agent_tasks"],
|
|
735
|
+
action: "Call get_parallel_status to see active tasks, roles, failed oracle tests, and context budgets. Then call list_agent_tasks to see what's claimed.",
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
step: 2,
|
|
739
|
+
name: "Assign Role — Specialize",
|
|
740
|
+
description: "Assign yourself a role. Specialization enables parallelism: implementer, dedup_reviewer, performance_optimizer, documentation_maintainer, code_quality_critic, test_writer, security_auditor.",
|
|
741
|
+
tools: ["assign_agent_role", "get_agent_role"],
|
|
742
|
+
action: 'Call assign_agent_role({ role: "implementer", focusArea: "auth module" }). Each parallel agent should have a different role or focus area.',
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
step: 3,
|
|
746
|
+
name: "Claim Task — Lock Before Working",
|
|
747
|
+
description: "Claim a task lock before starting work. This prevents two agents from solving the same problem. If another agent already claimed the task, pick a different one.",
|
|
748
|
+
tools: ["claim_agent_task"],
|
|
749
|
+
action: 'Call claim_agent_task({ taskKey: "fix_auth_middleware", description: "Fix JWT validation" }). If conflict, pick another task.',
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
step: 4,
|
|
753
|
+
name: "Work — Monitor Context Budget",
|
|
754
|
+
description: "Work on the task. Track context window usage to prevent pollution. Pre-compute summaries instead of dumping raw output. Log errors with ERROR prefix on same line for easy grep.",
|
|
755
|
+
tools: ["log_context_budget"],
|
|
756
|
+
action: "After reading large files or receiving large test output, call log_context_budget to track usage. Heed warnings about approaching limits.",
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
step: 5,
|
|
760
|
+
name: "Validate — Oracle Comparison",
|
|
761
|
+
description: "Compare your output against a known-good reference (oracle). The oracle pattern enables parallel debugging: each failing comparison can be assigned to a different agent.",
|
|
762
|
+
tools: ["run_oracle_comparison"],
|
|
763
|
+
action: 'Call run_oracle_comparison({ testLabel: "api_output", actualOutput: "...", expectedOutput: "...", oracleSource: "production_v2" }). Fix differences before committing.',
|
|
764
|
+
},
|
|
765
|
+
{
|
|
766
|
+
step: 6,
|
|
767
|
+
name: "Release — Handoff to Next Agent",
|
|
768
|
+
description: "Release the task lock with a progress note. If blocked, mark as blocked so another agent can pick it up with context about what was tried.",
|
|
769
|
+
tools: ["release_agent_task"],
|
|
770
|
+
action: 'Call release_agent_task({ taskKey: "fix_auth_middleware", status: "completed", progressNote: "Fixed JWT validation, added tests" }).',
|
|
771
|
+
},
|
|
772
|
+
],
|
|
773
|
+
keyPatterns: {
|
|
774
|
+
task_locking: "File-based locks in Anthropic's implementation; SQLite-based locks in NodeBench. Prevents duplicate work when agents run in parallel.",
|
|
775
|
+
role_specialization: "Different agents for different concerns: one implements features, one deduplicates code, one optimizes performance, one maintains docs, one reviews code quality.",
|
|
776
|
+
context_pollution_prevention: "Test harnesses should NOT print thousands of useless bytes. Pre-compute summaries, use --fast sampling for large suites, log details to files.",
|
|
777
|
+
time_blindness_mitigation: "Agents can't tell time. Print incremental progress infrequently. Include --fast option for 1-10% random sample of tests.",
|
|
778
|
+
oracle_testing: "Use a known-good reference as an oracle. Compare outputs to identify which specific components are broken. Enables parallel debugging.",
|
|
779
|
+
progress_files: "Maintain running docs of status, failed approaches, and remaining tasks. Fresh agent sessions read these to orient themselves.",
|
|
780
|
+
bootstrap_external_repos: "When connected to another project that lacks parallel agent capabilities, use bootstrap_parallel_agents to auto-detect gaps and scaffold infrastructure. The tool scans 7 categories (task coordination, roles, oracle, context budget, progress files, AGENTS.md parallel section, git worktrees) and generates ready-to-use files. Follow the AI Flywheel closed loop: detect → scaffold → verify → fix → document.",
|
|
781
|
+
},
|
|
782
|
+
claudeCodeNativePath: {
|
|
783
|
+
title: "Claude Code Native Parallel Subagents",
|
|
784
|
+
description: "If you are using Claude Code (Anthropic's CLI), you already have parallel subagent support via the Task tool. NodeBench MCP adds coordination, tracking, and impact measurement on top of Claude Code's native parallelism.",
|
|
785
|
+
howItWorks: [
|
|
786
|
+
"1. The main Claude Code session is the COORDINATOR — it breaks work into independent tasks",
|
|
787
|
+
"2. Each Task tool call spawns a SUBAGENT — a separate Claude instance with its own context",
|
|
788
|
+
"3. Each subagent has access to the same NodeBench MCP tools (shared SQLite database)",
|
|
789
|
+
"4. Subagents use claim_agent_task/release_agent_task to coordinate without conflicts",
|
|
790
|
+
"5. The coordinator uses get_parallel_status to monitor progress across all subagents",
|
|
791
|
+
],
|
|
792
|
+
exampleWorkflow: [
|
|
793
|
+
"COORDINATOR: Break work into 3 independent tasks",
|
|
794
|
+
"COORDINATOR: For each task, spawn a Task tool subagent with prompt:",
|
|
795
|
+
' "You have access to NodeBench MCP. First call claim_agent_task({ taskKey: \'fix_auth\' }), then do the work, then call release_agent_task with a progress note."',
|
|
796
|
+
"COORDINATOR: Call get_parallel_status to see all subagent progress",
|
|
797
|
+
"COORDINATOR: When all subagents complete, aggregate results and run quality gate",
|
|
798
|
+
],
|
|
799
|
+
impact: "Prevents duplicate work across subagents, captures per-task learnings, enables oracle-based validation, tracks context budget per subagent",
|
|
800
|
+
},
|
|
801
|
+
whenToUseParallelTools: {
|
|
802
|
+
description: "Parallel agent tools are NOT always needed. Use them ONLY when the situation calls for coordination.",
|
|
803
|
+
useWhen: [
|
|
804
|
+
"You are running 2+ agent sessions (Claude Code subagents, worktrees, or separate terminals)",
|
|
805
|
+
"You need to prevent two agents from working on the same thing",
|
|
806
|
+
"You want oracle-based testing to split failures into independent work items",
|
|
807
|
+
"You are bootstrapping parallel agent infrastructure for an external project",
|
|
808
|
+
],
|
|
809
|
+
doNotUseWhen: [
|
|
810
|
+
"You are a single agent working sequentially — standard verification/eval tools are sufficient",
|
|
811
|
+
"The task is simple enough for one agent to handle end-to-end",
|
|
812
|
+
"You are not in a multi-agent or multi-session context",
|
|
813
|
+
],
|
|
814
|
+
},
|
|
815
|
+
impactPerStep: {
|
|
816
|
+
orient: "IMPACT: Prevents wasted time re-doing work another agent already started or completed",
|
|
817
|
+
assign_role: "IMPACT: Specialization enables parallelism — agents don't step on each other's toes",
|
|
818
|
+
claim_task: "IMPACT: Zero duplicate work — each task is owned by exactly one agent",
|
|
819
|
+
monitor_budget: "IMPACT: Prevents context window exhaustion that forces expensive session restarts",
|
|
820
|
+
oracle_validate: "IMPACT: Catches regressions by comparing against known-good reference — each failure is an independent debuggable work item",
|
|
821
|
+
release_handoff: "IMPACT: Progress notes ensure the next agent (or next session) doesn't restart from scratch",
|
|
822
|
+
},
|
|
823
|
+
bootstrapForExternalRepos: {
|
|
824
|
+
description: "When nodebench-mcp detects that a target project repo does not have parallel agent infrastructure, it can automatically bootstrap it using the AI Flywheel closed loop.",
|
|
825
|
+
steps: [
|
|
826
|
+
"1. DETECT: Call bootstrap_parallel_agents({ projectRoot: '/path/to/their/repo', dryRun: true }) — scans 7 categories and returns gap report",
|
|
827
|
+
"2. SCAFFOLD: Call bootstrap_parallel_agents({ projectRoot: '...', dryRun: false, techStack: 'TypeScript/React' }) — creates .parallel-agents/ dir, progress.md, roles.json, lock dirs, oracle dirs",
|
|
828
|
+
"3. AGENTS.MD: Call generate_parallel_agents_md({ techStack: '...', projectName: '...', maxAgents: 4 }) — generates portable AGENTS.md section, paste into their repo",
|
|
829
|
+
"4. VERIFY: Run the 6-step flywheel plan returned by bootstrap_parallel_agents — static analysis, happy path, conflict test, oracle test, gap re-scan, document",
|
|
830
|
+
"5. FIX: If any flywheel step fails, fix and re-verify from step 1",
|
|
831
|
+
"6. DOCUMENT: Call record_learning with patterns discovered during bootstrap",
|
|
832
|
+
],
|
|
833
|
+
},
|
|
834
|
+
authoritativeSource: "https://www.anthropic.com/engineering/building-c-compiler",
|
|
835
|
+
composesWith: "Works with verification cycles (each agent runs its own), eval runs (aggregate across agents), and learnings (shared knowledge base). Task claims compose with the mandatory flywheel. bootstrap_parallel_agents works on ANY project directory — not just nodebench.",
|
|
836
|
+
},
|
|
726
837
|
self_reinforced_learning: {
|
|
727
838
|
title: "Self-Reinforced Learning Loop",
|
|
728
|
-
description: "Continuous self-improvement cycle for agents using the MCP.
|
|
839
|
+
description: "Continuous self-improvement cycle for agents using the MCP. Tool calls are now auto-instrumented — every call is automatically logged with timing and status. The loop: Use tools → Auto-log → Analyze trajectories → Find gaps → Clean stale data → Synthesize recon → Recommend improvements → Apply → Re-analyze. Over time, the system gets smarter about the project's specific development patterns.",
|
|
729
840
|
steps: [
|
|
730
841
|
{
|
|
731
842
|
step: 1,
|
|
@@ -757,6 +868,13 @@ const METHODOLOGY_CONTENT = {
|
|
|
757
868
|
},
|
|
758
869
|
{
|
|
759
870
|
step: 5,
|
|
871
|
+
name: "Clean & Synthesize",
|
|
872
|
+
description: "Clean up stale runs and synthesize recon findings into learnings. Orphaned eval runs and stale gaps skew health scores. Recon findings are ephemeral — convert them into searchable learnings.",
|
|
873
|
+
tools: ["cleanup_stale_runs", "synthesize_recon_to_learnings"],
|
|
874
|
+
action: "Call cleanup_stale_runs(dryRun=true) to preview, then dryRun=false to clean. Call synthesize_recon_to_learnings(dryRun=true) to preview conversions, then dryRun=false.",
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
step: 6,
|
|
760
878
|
name: "Apply & Re-Analyze",
|
|
761
879
|
description: "Implement the top recommendations, then re-run the analysis to verify improvement. This closes the loop and makes the system progressively smarter.",
|
|
762
880
|
tools: ["record_learning", "get_self_eval_report"],
|
|
@@ -789,7 +907,8 @@ const METHODOLOGY_CONTENT = {
|
|
|
789
907
|
agents_md_maintenance: "AGENTS.md Maintenance — keep documentation synchronized with implementations",
|
|
790
908
|
agent_bootstrap: "Agent Bootstrap — self-discover infrastructure, triple verification with authoritative sources, self-implement missing components",
|
|
791
909
|
autonomous_maintenance: "Autonomous Maintenance — risk-tiered execution, re-update before create, self-maintenance cycles, OpenClaw scaffolding, Ralph Wiggum loops",
|
|
792
|
-
|
|
910
|
+
parallel_agent_teams: "Parallel Agent Teams — task locking, role specialization, context budget management, oracle testing. Based on Anthropic's 'Building a C Compiler with Parallel Claudes' (Feb 2026)",
|
|
911
|
+
self_reinforced_learning: "Self-Reinforced Learning — auto-instrumented trajectory analysis, self-evaluation reports, improvement recommendations, stale run cleanup, recon synthesis, closed-loop optimization",
|
|
793
912
|
},
|
|
794
913
|
},
|
|
795
914
|
{
|
|
@@ -851,6 +970,7 @@ export function createMetaTools(allTools) {
|
|
|
851
970
|
"documentation",
|
|
852
971
|
"bootstrap",
|
|
853
972
|
"self_eval",
|
|
973
|
+
"parallel_agents",
|
|
854
974
|
"meta",
|
|
855
975
|
],
|
|
856
976
|
description: "Filter by tool category (optional)",
|
|
@@ -945,6 +1065,20 @@ export function createMetaTools(allTools) {
|
|
|
945
1065
|
"get_trajectory_analysis",
|
|
946
1066
|
"get_self_eval_report",
|
|
947
1067
|
"get_improvement_recommendations",
|
|
1068
|
+
"cleanup_stale_runs",
|
|
1069
|
+
"synthesize_recon_to_learnings",
|
|
1070
|
+
],
|
|
1071
|
+
parallel_agents: [
|
|
1072
|
+
"claim_agent_task",
|
|
1073
|
+
"release_agent_task",
|
|
1074
|
+
"list_agent_tasks",
|
|
1075
|
+
"assign_agent_role",
|
|
1076
|
+
"get_agent_role",
|
|
1077
|
+
"log_context_budget",
|
|
1078
|
+
"run_oracle_comparison",
|
|
1079
|
+
"get_parallel_status",
|
|
1080
|
+
"bootstrap_parallel_agents",
|
|
1081
|
+
"generate_parallel_agents_md",
|
|
948
1082
|
],
|
|
949
1083
|
meta: ["findTools", "getMethodology"],
|
|
950
1084
|
};
|
|
@@ -957,6 +1091,36 @@ export function createMetaTools(allTools) {
|
|
|
957
1091
|
const text = `${t.name} ${t.description}`.toLowerCase();
|
|
958
1092
|
return query.split(/\s+/).some((word) => text.includes(word));
|
|
959
1093
|
});
|
|
1094
|
+
// Contextual recommendations: surface parallel tools only when relevant
|
|
1095
|
+
const parallelKeywords = ["parallel", "agent", "team", "multi-agent", "subagent", "concurrent", "worktree", "oracle", "lock", "coordinate", "role"];
|
|
1096
|
+
const queryHintsParallel = parallelKeywords.some((kw) => query.includes(kw));
|
|
1097
|
+
const parallelToolNames = new Set(categoryMap.parallel_agents);
|
|
1098
|
+
// Add contextual hint about parallel tools
|
|
1099
|
+
const contextHints = [];
|
|
1100
|
+
if (!queryHintsParallel && !category) {
|
|
1101
|
+
// Don't surface parallel tools unless the query is about parallel/agent work
|
|
1102
|
+
const filtered = matches.filter((t) => !parallelToolNames.has(t.name));
|
|
1103
|
+
if (filtered.length < matches.length) {
|
|
1104
|
+
contextHints.push("Parallel agent tools are available but not shown (query didn't indicate multi-agent work). " +
|
|
1105
|
+
"Use findTools({ category: 'parallel_agents' }) or include 'parallel'/'agent'/'team' in your query to discover them.");
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
query,
|
|
1109
|
+
count: filtered.length,
|
|
1110
|
+
tools: filtered.map((t) => ({
|
|
1111
|
+
name: t.name,
|
|
1112
|
+
description: t.description,
|
|
1113
|
+
})),
|
|
1114
|
+
contextHints,
|
|
1115
|
+
tip: "Use category filter or specific keywords to narrow results. Call getMethodology('overview') for all available methodologies.",
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
// When parallel tools ARE relevant, add Claude Code guidance
|
|
1119
|
+
if (queryHintsParallel || category === "parallel_agents") {
|
|
1120
|
+
contextHints.push("Claude Code users: Use the Task tool to spawn parallel subagents, each with access to NodeBench MCP. " +
|
|
1121
|
+
"Each subagent calls claim_agent_task to lock work, assign_agent_role for specialization, and release_agent_task when done. " +
|
|
1122
|
+
"Call getMethodology('parallel_agent_teams') for the full workflow.");
|
|
1123
|
+
}
|
|
960
1124
|
return {
|
|
961
1125
|
query,
|
|
962
1126
|
count: matches.length,
|
|
@@ -964,12 +1128,14 @@ export function createMetaTools(allTools) {
|
|
|
964
1128
|
name: t.name,
|
|
965
1129
|
description: t.description,
|
|
966
1130
|
})),
|
|
1131
|
+
contextHints,
|
|
1132
|
+
tip: "Use category filter or specific keywords to narrow results. Call getMethodology('overview') for all available methodologies.",
|
|
967
1133
|
};
|
|
968
1134
|
},
|
|
969
1135
|
},
|
|
970
1136
|
{
|
|
971
1137
|
name: "getMethodology",
|
|
972
|
-
description: 'Get step-by-step guidance for a development methodology. Topics: verification, eval, flywheel, mandatory_flywheel, reconnaissance, quality_gates, ui_ux_qa, agentic_vision, closed_loop, learnings, project_ideation, tech_stack_2026, telemetry_setup, agents_md_maintenance, agent_bootstrap, autonomous_maintenance, self_reinforced_learning, overview. Call with topic "overview" to see all available methodologies.',
|
|
1138
|
+
description: 'Get step-by-step guidance for a development methodology. Topics: verification, eval, flywheel, mandatory_flywheel, reconnaissance, quality_gates, ui_ux_qa, agentic_vision, closed_loop, learnings, project_ideation, tech_stack_2026, telemetry_setup, agents_md_maintenance, agent_bootstrap, autonomous_maintenance, parallel_agent_teams, self_reinforced_learning, overview. Call with topic "overview" to see all available methodologies.',
|
|
973
1139
|
inputSchema: {
|
|
974
1140
|
type: "object",
|
|
975
1141
|
properties: {
|
|
@@ -992,6 +1158,7 @@ export function createMetaTools(allTools) {
|
|
|
992
1158
|
"agents_md_maintenance",
|
|
993
1159
|
"agent_bootstrap",
|
|
994
1160
|
"autonomous_maintenance",
|
|
1161
|
+
"parallel_agent_teams",
|
|
995
1162
|
"self_reinforced_learning",
|
|
996
1163
|
"overview",
|
|
997
1164
|
],
|