nodebench-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +237 -0
  2. package/dist/__tests__/tools.test.d.ts +1 -0
  3. package/dist/__tests__/tools.test.js +402 -0
  4. package/dist/__tests__/tools.test.js.map +1 -0
  5. package/dist/db.d.ts +4 -0
  6. package/dist/db.js +198 -0
  7. package/dist/db.js.map +1 -0
  8. package/dist/index.d.ts +19 -0
  9. package/dist/index.js +237 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/tools/documentTools.d.ts +5 -0
  12. package/dist/tools/documentTools.js +524 -0
  13. package/dist/tools/documentTools.js.map +1 -0
  14. package/dist/tools/documentationTools.d.ts +12 -0
  15. package/dist/tools/documentationTools.js +647 -0
  16. package/dist/tools/documentationTools.js.map +1 -0
  17. package/dist/tools/evalTools.d.ts +6 -0
  18. package/dist/tools/evalTools.js +335 -0
  19. package/dist/tools/evalTools.js.map +1 -0
  20. package/dist/tools/financialTools.d.ts +10 -0
  21. package/dist/tools/financialTools.js +403 -0
  22. package/dist/tools/financialTools.js.map +1 -0
  23. package/dist/tools/flywheelTools.d.ts +6 -0
  24. package/dist/tools/flywheelTools.js +366 -0
  25. package/dist/tools/flywheelTools.js.map +1 -0
  26. package/dist/tools/githubTools.d.ts +12 -0
  27. package/dist/tools/githubTools.js +432 -0
  28. package/dist/tools/githubTools.js.map +1 -0
  29. package/dist/tools/learningTools.d.ts +6 -0
  30. package/dist/tools/learningTools.js +199 -0
  31. package/dist/tools/learningTools.js.map +1 -0
  32. package/dist/tools/memoryTools.d.ts +5 -0
  33. package/dist/tools/memoryTools.js +137 -0
  34. package/dist/tools/memoryTools.js.map +1 -0
  35. package/dist/tools/metaTools.d.ts +7 -0
  36. package/dist/tools/metaTools.js +837 -0
  37. package/dist/tools/metaTools.js.map +1 -0
  38. package/dist/tools/planningTools.d.ts +5 -0
  39. package/dist/tools/planningTools.js +147 -0
  40. package/dist/tools/planningTools.js.map +1 -0
  41. package/dist/tools/qualityGateTools.d.ts +6 -0
  42. package/dist/tools/qualityGateTools.js +347 -0
  43. package/dist/tools/qualityGateTools.js.map +1 -0
  44. package/dist/tools/reconTools.d.ts +8 -0
  45. package/dist/tools/reconTools.js +729 -0
  46. package/dist/tools/reconTools.js.map +1 -0
  47. package/dist/tools/searchTools.d.ts +5 -0
  48. package/dist/tools/searchTools.js +145 -0
  49. package/dist/tools/searchTools.js.map +1 -0
  50. package/dist/tools/uiCaptureTools.d.ts +8 -0
  51. package/dist/tools/uiCaptureTools.js +339 -0
  52. package/dist/tools/uiCaptureTools.js.map +1 -0
  53. package/dist/tools/verificationTools.d.ts +6 -0
  54. package/dist/tools/verificationTools.js +472 -0
  55. package/dist/tools/verificationTools.js.map +1 -0
  56. package/dist/tools/visionTools.d.ts +12 -0
  57. package/dist/tools/visionTools.js +553 -0
  58. package/dist/tools/visionTools.js.map +1 -0
  59. package/dist/tools/webTools.d.ts +12 -0
  60. package/dist/tools/webTools.js +443 -0
  61. package/dist/tools/webTools.js.map +1 -0
  62. package/dist/types.d.ts +16 -0
  63. package/dist/types.js +2 -0
  64. package/dist/types.js.map +1 -0
  65. package/package.json +66 -0
@@ -0,0 +1,432 @@
1
+ /**
2
+ * GitHub tools — Repository search and analysis.
3
+ * Enables agents to discover and analyze GitHub repositories for learning patterns,
4
+ * finding prior art, and understanding tech stacks.
5
+ *
6
+ * - search_github: Search repositories by topic, language, stars
7
+ * - analyze_repo: Analyze a repo's structure, tech stack, and patterns
8
+ *
9
+ * Uses GitHub REST API. GITHUB_TOKEN optional but recommended for higher rate limits.
10
+ */
11
+ // ─── GitHub API helpers ───────────────────────────────────────────────────────
12
+ function getHeaders() {
13
+ const headers = {
14
+ Accept: "application/vnd.github+json",
15
+ "User-Agent": "NodeBench-MCP/1.0",
16
+ };
17
+ const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
18
+ if (token) {
19
+ headers.Authorization = `Bearer ${token}`;
20
+ }
21
+ return headers;
22
+ }
23
+ async function githubFetch(endpoint) {
24
+ const url = endpoint.startsWith("http")
25
+ ? endpoint
26
+ : `https://api.github.com${endpoint}`;
27
+ const response = await fetch(url, { headers: getHeaders() });
28
+ if (!response.ok) {
29
+ const error = await response.text();
30
+ throw new Error(`GitHub API error ${response.status}: ${error}`);
31
+ }
32
+ return response.json();
33
+ }
34
+ // ─── Repo URL parsing ─────────────────────────────────────────────────────────
35
+ function parseRepoUrl(url) {
36
+ // Handle: https://github.com/owner/repo, github.com/owner/repo, owner/repo
37
+ const patterns = [
38
+ /github\.com\/([^/]+)\/([^/]+)/,
39
+ /^([^/]+)\/([^/]+)$/,
40
+ ];
41
+ for (const pattern of patterns) {
42
+ const match = url.match(pattern);
43
+ if (match) {
44
+ return {
45
+ owner: match[1],
46
+ repo: match[2].replace(/\.git$/, ""),
47
+ };
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ function detectDependencies(files) {
53
+ const deps = {
54
+ dependencies: [],
55
+ devDependencies: [],
56
+ frameworks: [],
57
+ };
58
+ // Check package.json
59
+ const packageJson = files.get("package.json");
60
+ if (packageJson) {
61
+ try {
62
+ const pkg = JSON.parse(packageJson);
63
+ deps.dependencies = Object.keys(pkg.dependencies ?? {});
64
+ deps.devDependencies = Object.keys(pkg.devDependencies ?? {});
65
+ // Detect frameworks
66
+ const allDeps = [...deps.dependencies, ...deps.devDependencies];
67
+ if (allDeps.includes("next"))
68
+ deps.frameworks.push("Next.js");
69
+ if (allDeps.includes("react"))
70
+ deps.frameworks.push("React");
71
+ if (allDeps.includes("vue"))
72
+ deps.frameworks.push("Vue");
73
+ if (allDeps.includes("svelte"))
74
+ deps.frameworks.push("Svelte");
75
+ if (allDeps.includes("express"))
76
+ deps.frameworks.push("Express");
77
+ if (allDeps.includes("fastify"))
78
+ deps.frameworks.push("Fastify");
79
+ if (allDeps.includes("hono"))
80
+ deps.frameworks.push("Hono");
81
+ if (allDeps.includes("convex"))
82
+ deps.frameworks.push("Convex");
83
+ if (allDeps.includes("prisma") || allDeps.includes("@prisma/client"))
84
+ deps.frameworks.push("Prisma");
85
+ if (allDeps.includes("drizzle-orm"))
86
+ deps.frameworks.push("Drizzle");
87
+ if (allDeps.includes("@tanstack/react-query"))
88
+ deps.frameworks.push("TanStack Query");
89
+ if (allDeps.includes("tailwindcss"))
90
+ deps.frameworks.push("Tailwind CSS");
91
+ if (allDeps.includes("@modelcontextprotocol/sdk"))
92
+ deps.frameworks.push("MCP SDK");
93
+ }
94
+ catch {
95
+ // Invalid JSON
96
+ }
97
+ }
98
+ // Check requirements.txt
99
+ const requirements = files.get("requirements.txt");
100
+ if (requirements) {
101
+ const pythonDeps = requirements
102
+ .split("\n")
103
+ .map((line) => line.split("==")[0].split(">=")[0].trim())
104
+ .filter(Boolean);
105
+ deps.dependencies.push(...pythonDeps);
106
+ if (pythonDeps.includes("fastapi"))
107
+ deps.frameworks.push("FastAPI");
108
+ if (pythonDeps.includes("django"))
109
+ deps.frameworks.push("Django");
110
+ if (pythonDeps.includes("flask"))
111
+ deps.frameworks.push("Flask");
112
+ if (pythonDeps.includes("langchain"))
113
+ deps.frameworks.push("LangChain");
114
+ if (pythonDeps.includes("openai"))
115
+ deps.frameworks.push("OpenAI Python");
116
+ }
117
+ // Check Cargo.toml
118
+ const cargoToml = files.get("Cargo.toml");
119
+ if (cargoToml) {
120
+ const depMatch = cargoToml.match(/\[dependencies\]([\s\S]*?)(\[|$)/);
121
+ if (depMatch) {
122
+ const rustDeps = depMatch[1]
123
+ .split("\n")
124
+ .map((line) => line.split("=")[0].trim())
125
+ .filter(Boolean);
126
+ deps.dependencies.push(...rustDeps);
127
+ if (rustDeps.includes("axum"))
128
+ deps.frameworks.push("Axum");
129
+ if (rustDeps.includes("actix-web"))
130
+ deps.frameworks.push("Actix");
131
+ if (rustDeps.includes("tokio"))
132
+ deps.frameworks.push("Tokio");
133
+ }
134
+ }
135
+ return deps;
136
+ }
137
+ function detectPatterns(tree) {
138
+ const patterns = {
139
+ hasTests: false,
140
+ hasCi: false,
141
+ hasReadme: false,
142
+ hasDocs: false,
143
+ hasTypes: false,
144
+ hasDocker: false,
145
+ hasLicense: false,
146
+ testFramework: null,
147
+ ciPlatform: null,
148
+ };
149
+ for (const path of tree) {
150
+ const lower = path.toLowerCase();
151
+ // Tests
152
+ if (lower.includes("test") ||
153
+ lower.includes("__tests__") ||
154
+ lower.includes("spec")) {
155
+ patterns.hasTests = true;
156
+ if (lower.includes("vitest"))
157
+ patterns.testFramework = "Vitest";
158
+ else if (lower.includes("jest"))
159
+ patterns.testFramework = "Jest";
160
+ else if (lower.includes("pytest"))
161
+ patterns.testFramework = "pytest";
162
+ else if (lower.includes("mocha"))
163
+ patterns.testFramework = "Mocha";
164
+ }
165
+ // CI/CD
166
+ if (lower.includes(".github/workflows")) {
167
+ patterns.hasCi = true;
168
+ patterns.ciPlatform = "GitHub Actions";
169
+ }
170
+ else if (lower.includes(".circleci")) {
171
+ patterns.hasCi = true;
172
+ patterns.ciPlatform = "CircleCI";
173
+ }
174
+ else if (lower.includes("gitlab-ci")) {
175
+ patterns.hasCi = true;
176
+ patterns.ciPlatform = "GitLab CI";
177
+ }
178
+ // Docs
179
+ if (lower === "readme.md" || lower === "readme")
180
+ patterns.hasReadme = true;
181
+ if (lower.includes("docs/") || lower.includes("documentation/"))
182
+ patterns.hasDocs = true;
183
+ if (lower === "license" || lower === "license.md")
184
+ patterns.hasLicense = true;
185
+ // Types
186
+ if (lower.endsWith(".d.ts") || lower === "tsconfig.json")
187
+ patterns.hasTypes = true;
188
+ // Docker
189
+ if (lower.includes("dockerfile") || lower.includes("docker-compose"))
190
+ patterns.hasDocker = true;
191
+ }
192
+ return patterns;
193
+ }
194
+ // ─── Tools ────────────────────────────────────────────────────────────────────
195
+ export const githubTools = [
196
+ {
197
+ name: "search_github",
198
+ description: "Search GitHub repositories by query, topic, language, and star count. Useful for discovering libraries, frameworks, prior art, and learning from existing implementations. Returns repo metadata including stars, forks, description, and topics. GITHUB_TOKEN optional but recommended for higher rate limits.",
199
+ inputSchema: {
200
+ type: "object",
201
+ properties: {
202
+ query: {
203
+ type: "string",
204
+ description: "Search query (e.g., 'mcp server', 'ai agents', 'typescript sdk')",
205
+ },
206
+ language: {
207
+ type: "string",
208
+ description: "Filter by programming language (e.g., 'typescript', 'python', 'rust')",
209
+ },
210
+ topic: {
211
+ type: "string",
212
+ description: "Filter by GitHub topic (e.g., 'mcp', 'ai-agents', 'llm')",
213
+ },
214
+ minStars: {
215
+ type: "number",
216
+ description: "Minimum star count (default: 10)",
217
+ },
218
+ sort: {
219
+ type: "string",
220
+ enum: ["stars", "updated", "relevance"],
221
+ description: "Sort order: 'stars' (most popular), 'updated' (recently active), 'relevance' (best match). Default: 'stars'.",
222
+ },
223
+ maxResults: {
224
+ type: "number",
225
+ description: "Maximum results to return (default: 10, max: 30)",
226
+ },
227
+ },
228
+ required: ["query"],
229
+ },
230
+ handler: async (args) => {
231
+ const query = args.query;
232
+ const language = args.language;
233
+ const topic = args.topic;
234
+ const minStars = args.minStars ?? 10;
235
+ const sort = args.sort ?? "stars";
236
+ const maxResults = Math.min(args.maxResults ?? 10, 30);
237
+ // Build GitHub search query
238
+ const queryParts = [query];
239
+ if (language)
240
+ queryParts.push(`language:${language}`);
241
+ if (topic)
242
+ queryParts.push(`topic:${topic}`);
243
+ if (minStars > 0)
244
+ queryParts.push(`stars:>=${minStars}`);
245
+ const searchQuery = encodeURIComponent(queryParts.join(" "));
246
+ const sortParam = sort === "relevance" ? "" : `&sort=${sort}`;
247
+ try {
248
+ const data = await githubFetch(`/search/repositories?q=${searchQuery}${sortParam}&per_page=${maxResults}`);
249
+ const repos = (data.items ?? []).map((item) => ({
250
+ name: item.name,
251
+ fullName: item.full_name,
252
+ description: item.description ?? "",
253
+ url: item.html_url,
254
+ stars: item.stargazers_count,
255
+ forks: item.forks_count,
256
+ language: item.language,
257
+ topics: item.topics ?? [],
258
+ updatedAt: item.updated_at,
259
+ license: item.license?.spdx_id ?? null,
260
+ isArchived: item.archived,
261
+ openIssues: item.open_issues_count,
262
+ }));
263
+ return {
264
+ query,
265
+ filters: { language, topic, minStars, sort },
266
+ repos,
267
+ totalCount: data.total_count,
268
+ resultCount: repos.length,
269
+ hasGitHubToken: !!(process.env.GITHUB_TOKEN || process.env.GH_TOKEN),
270
+ };
271
+ }
272
+ catch (err) {
273
+ return {
274
+ error: true,
275
+ query,
276
+ message: `GitHub search failed: ${err.message}`,
277
+ suggestion: "Check network connectivity. Set GITHUB_TOKEN for higher rate limits (60/hour without, 5000/hour with).",
278
+ };
279
+ }
280
+ },
281
+ },
282
+ {
283
+ name: "analyze_repo",
284
+ description: "Analyze a GitHub repository's structure, tech stack, dependencies, and development patterns. Fetches repo metadata, file tree, and key configuration files (package.json, requirements.txt, etc.) to understand the project. No cloning required — uses GitHub API. Useful for learning from implementations, evaluating libraries, and understanding architectures.",
285
+ inputSchema: {
286
+ type: "object",
287
+ properties: {
288
+ repoUrl: {
289
+ type: "string",
290
+ description: "GitHub repository URL or owner/repo (e.g., 'https://github.com/anthropics/claude-code', 'anthropics/claude-code')",
291
+ },
292
+ depth: {
293
+ type: "string",
294
+ enum: ["shallow", "standard", "deep"],
295
+ description: "Analysis depth: 'shallow' (metadata only), 'standard' (+ file tree + key files), 'deep' (+ more files). Default: 'standard'.",
296
+ },
297
+ },
298
+ required: ["repoUrl"],
299
+ },
300
+ handler: async (args) => {
301
+ const repoUrl = args.repoUrl;
302
+ const depth = args.depth ?? "standard";
303
+ const parsed = parseRepoUrl(repoUrl);
304
+ if (!parsed) {
305
+ return {
306
+ error: true,
307
+ repoUrl,
308
+ message: "Invalid repository URL format",
309
+ suggestion: "Use format: 'owner/repo' or 'https://github.com/owner/repo'",
310
+ };
311
+ }
312
+ const { owner, repo } = parsed;
313
+ try {
314
+ // Fetch repo metadata
315
+ const repoData = await githubFetch(`/repos/${owner}/${repo}`);
316
+ const result = {
317
+ repo: {
318
+ name: repoData.name,
319
+ fullName: repoData.full_name,
320
+ description: repoData.description,
321
+ url: repoData.html_url,
322
+ stars: repoData.stargazers_count,
323
+ forks: repoData.forks_count,
324
+ language: repoData.language,
325
+ topics: repoData.topics ?? [],
326
+ createdAt: repoData.created_at,
327
+ updatedAt: repoData.updated_at,
328
+ pushedAt: repoData.pushed_at,
329
+ defaultBranch: repoData.default_branch,
330
+ license: repoData.license?.spdx_id ?? null,
331
+ isArchived: repoData.archived,
332
+ openIssues: repoData.open_issues_count,
333
+ },
334
+ depth,
335
+ analyzedAt: new Date().toISOString(),
336
+ };
337
+ if (depth === "shallow") {
338
+ return result;
339
+ }
340
+ // Fetch file tree
341
+ const defaultBranch = repoData.default_branch ?? "main";
342
+ const treeData = await githubFetch(`/repos/${owner}/${repo}/git/trees/${defaultBranch}?recursive=1`);
343
+ const tree = (treeData.tree ?? [])
344
+ .filter((item) => item.type === "blob")
345
+ .map((item) => item.path);
346
+ // Analyze structure
347
+ const directories = new Set();
348
+ for (const path of tree) {
349
+ const parts = path.split("/");
350
+ for (let i = 1; i < parts.length; i++) {
351
+ directories.add(parts.slice(0, i).join("/"));
352
+ }
353
+ }
354
+ const keyFiles = tree.filter((path) => {
355
+ const name = path.toLowerCase();
356
+ return (name === "readme.md" ||
357
+ name === "package.json" ||
358
+ name === "tsconfig.json" ||
359
+ name === "requirements.txt" ||
360
+ name === "cargo.toml" ||
361
+ name === "go.mod" ||
362
+ name === "dockerfile" ||
363
+ name.includes("docker-compose") ||
364
+ name === ".env.example" ||
365
+ name === "agents.md");
366
+ });
367
+ result.structure = {
368
+ directories: Array.from(directories).slice(0, 50),
369
+ keyFiles,
370
+ fileCount: tree.length,
371
+ truncated: treeData.truncated ?? false,
372
+ };
373
+ // Detect patterns
374
+ result.patterns = detectPatterns(tree);
375
+ // Fetch key files for dependency analysis
376
+ const filesToFetch = ["package.json", "requirements.txt", "Cargo.toml"];
377
+ const fetchedFiles = new Map();
378
+ for (const filename of filesToFetch) {
379
+ if (tree.includes(filename)) {
380
+ try {
381
+ const fileData = await githubFetch(`/repos/${owner}/${repo}/contents/${filename}`);
382
+ if (fileData.content) {
383
+ const content = Buffer.from(fileData.content, "base64").toString("utf-8");
384
+ fetchedFiles.set(filename, content);
385
+ }
386
+ }
387
+ catch {
388
+ // File not accessible
389
+ }
390
+ }
391
+ }
392
+ // Detect tech stack
393
+ const deps = detectDependencies(fetchedFiles);
394
+ result.techStack = {
395
+ primaryLanguage: repoData.language,
396
+ languages: {}, // Would need languages API call
397
+ dependencies: deps.dependencies.slice(0, 30),
398
+ devDependencies: deps.devDependencies.slice(0, 20),
399
+ frameworksDetected: deps.frameworks,
400
+ };
401
+ // Generate recommendation
402
+ const recommendations = [];
403
+ if (!result.patterns.hasReadme)
404
+ recommendations.push("Add a README.md");
405
+ if (!result.patterns.hasTests)
406
+ recommendations.push("Add tests");
407
+ if (!result.patterns.hasCi)
408
+ recommendations.push("Set up CI/CD");
409
+ if (!result.patterns.hasTypes && repoData.language === "TypeScript")
410
+ recommendations.push("Ensure TypeScript types are exported");
411
+ if (!result.patterns.hasLicense)
412
+ recommendations.push("Add a license");
413
+ result.recommendation =
414
+ recommendations.length > 0
415
+ ? `Suggestions: ${recommendations.join(", ")}`
416
+ : "Repository follows good practices (README, tests, CI, license detected).";
417
+ return result;
418
+ }
419
+ catch (err) {
420
+ return {
421
+ error: true,
422
+ repoUrl,
423
+ owner,
424
+ repo,
425
+ message: `Repository analysis failed: ${err.message}`,
426
+ suggestion: "Check that the repository exists and is public. Set GITHUB_TOKEN for private repos or higher rate limits.",
427
+ };
428
+ }
429
+ },
430
+ },
431
+ ];
432
+ //# sourceMappingURL=githubTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubTools.js","sourceRoot":"","sources":["../../src/tools/githubTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,iFAAiF;AAEjF,SAAS,UAAU;IACjB,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,6BAA6B;QACrC,YAAY,EAAE,mBAAmB;KAClC,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC/D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAgB;IACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;QACrC,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,yBAAyB,QAAQ,EAAE,CAAC;IAExC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAE7D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,iFAAiF;AAEjF,SAAS,YAAY,CAAC,GAAW;IAC/B,2EAA2E;IAC3E,MAAM,QAAQ,GAAG;QACf,+BAA+B;QAC/B,oBAAoB;KACrB,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO;gBACL,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;gBACf,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;aACrC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAUD,SAAS,kBAAkB,CAAC,KAA0B;IACpD,MAAM,IAAI,GAAiB;QACzB,YAAY,EAAE,EAAE;QAChB,eAAe,EAAE,EAAE;QACnB,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,qBAAqB;IACrB,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9C,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;YAE9D,oBAAoB;YACpB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;YAChE,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9D,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7D,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzD,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/D,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACjE,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACjE,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/D,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrG,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACrE,IAAI,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACtF,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1E,IAAI,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrF,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,YAAY;aAC5B,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACxD,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;QAEtC,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChE,IAAI,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxE,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3E,CAAC;IAED,mBAAmB;IACnB,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1C,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACrE,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;iBACzB,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACxC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YAEpC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC5D,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClE,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD,SAAS,cAAc,CAAC,IAAc;IACpC,MAAM,QAAQ,GAAa;QACzB,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;QACf,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;KACjB,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAEjC,QAAQ;QACR,IACE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YACtB,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC3B,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EACtB,CAAC;YACD,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;YACzB,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC;iBAC3D,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,QAAQ,CAAC,aAAa,GAAG,MAAM,CAAC;iBAC5D,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC;iBAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,QAAQ,CAAC,aAAa,GAAG,OAAO,CAAC;QACrE,CAAC;QAED,QAAQ;QACR,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACxC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;YACtB,QAAQ,CAAC,UAAU,GAAG,gBAAgB,CAAC;QACzC,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;YACtB,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;YACtB,QAAQ,CAAC,UAAU,GAAG,WAAW,CAAC;QACpC,CAAC;QAED,OAAO;QACP,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,QAAQ;YAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;QAC3E,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QACzF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,YAAY;YAAE,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;QAE9E,QAAQ;QACR,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,eAAe;YAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;QAEnF,SAAS;QACT,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;IAClG,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,WAAW,GAAc;IACpC;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,iTAAiT;QACnT,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kEAAkE;iBAChF;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uEAAuE;iBACrF;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0DAA0D;iBACxE;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kCAAkC;iBAChD;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;oBACvC,WAAW,EAAE,8GAA8G;iBAC5H;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kDAAkD;iBAChE;aACF;YACD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAe,CAAC;YACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAA8B,CAAC;YACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAA2B,CAAC;YAC/C,MAAM,QAAQ,GAAI,IAAI,CAAC,QAAmB,IAAI,EAAE,CAAC;YACjD,MAAM,IAAI,GAAI,IAAI,CAAC,IAAe,IAAI,OAAO,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAE,IAAI,CAAC,UAAqB,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAEnE,4BAA4B;YAC5B,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,QAAQ;gBAAE,UAAU,CAAC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC;YACtD,IAAI,KAAK;gBAAE,UAAU,CAAC,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;YAC7C,IAAI,QAAQ,GAAG,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;YAEzD,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;YAE9D,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,WAAW,CAC5B,0BAA0B,WAAW,GAAG,SAAS,aAAa,UAAU,EAAE,CAC3E,CAAC;gBAEF,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CAAC;oBACnD,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,QAAQ,EAAE,IAAI,CAAC,SAAS;oBACxB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;oBACnC,GAAG,EAAE,IAAI,CAAC,QAAQ;oBAClB,KAAK,EAAE,IAAI,CAAC,gBAAgB;oBAC5B,KAAK,EAAE,IAAI,CAAC,WAAW;oBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;oBACzB,SAAS,EAAE,IAAI,CAAC,UAAU;oBAC1B,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI;oBACtC,UAAU,EAAE,IAAI,CAAC,QAAQ;oBACzB,UAAU,EAAE,IAAI,CAAC,iBAAiB;iBACnC,CAAC,CAAC,CAAC;gBAEJ,OAAO;oBACL,KAAK;oBACL,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC5C,KAAK;oBACL,UAAU,EAAE,IAAI,CAAC,WAAW;oBAC5B,WAAW,EAAE,KAAK,CAAC,MAAM;oBACzB,cAAc,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;iBACrE,CAAC;YACJ,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,KAAK,EAAE,IAAI;oBACX,KAAK;oBACL,OAAO,EAAE,yBAAyB,GAAG,CAAC,OAAO,EAAE;oBAC/C,UAAU,EACR,wGAAwG;iBAC3G,CAAC;YACJ,CAAC;QACH,CAAC;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,sWAAsW;QACxW,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mHAAmH;iBACjI;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC;oBACrC,WAAW,EACT,8HAA8H;iBACjI;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;YACvC,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAI,UAAU,CAAC;YAEnD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,KAAK,EAAE,IAAI;oBACX,OAAO;oBACP,OAAO,EAAE,+BAA+B;oBACxC,UAAU,EAAE,6DAA6D;iBAC1E,CAAC;YACJ,CAAC;YAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;YAE/B,IAAI,CAAC;gBACH,sBAAsB;gBACtB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,UAAU,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;gBAE9D,MAAM,MAAM,GAAQ;oBAClB,IAAI,EAAE;wBACJ,IAAI,EAAE,QAAQ,CAAC,IAAI;wBACnB,QAAQ,EAAE,QAAQ,CAAC,SAAS;wBAC5B,WAAW,EAAE,QAAQ,CAAC,WAAW;wBACjC,GAAG,EAAE,QAAQ,CAAC,QAAQ;wBACtB,KAAK,EAAE,QAAQ,CAAC,gBAAgB;wBAChC,KAAK,EAAE,QAAQ,CAAC,WAAW;wBAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;wBAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE;wBAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU;wBAC9B,SAAS,EAAE,QAAQ,CAAC,UAAU;wBAC9B,QAAQ,EAAE,QAAQ,CAAC,SAAS;wBAC5B,aAAa,EAAE,QAAQ,CAAC,cAAc;wBACtC,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI;wBAC1C,UAAU,EAAE,QAAQ,CAAC,QAAQ;wBAC7B,UAAU,EAAE,QAAQ,CAAC,iBAAiB;qBACvC;oBACD,KAAK;oBACL,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACrC,CAAC;gBAEF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAED,kBAAkB;gBAClB,MAAM,aAAa,GAAG,QAAQ,CAAC,cAAc,IAAI,MAAM,CAAC;gBACxD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,UAAU,KAAK,IAAI,IAAI,cAAc,aAAa,cAAc,CACjE,CAAC;gBAEF,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;qBAC/B,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;qBAC3C,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEjC,oBAAoB;gBACpB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;gBACtC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;oBACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC/C,CAAC;gBACH,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;oBAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;oBAChC,OAAO,CACL,IAAI,KAAK,WAAW;wBACpB,IAAI,KAAK,cAAc;wBACvB,IAAI,KAAK,eAAe;wBACxB,IAAI,KAAK,kBAAkB;wBAC3B,IAAI,KAAK,YAAY;wBACrB,IAAI,KAAK,QAAQ;wBACjB,IAAI,KAAK,YAAY;wBACrB,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;wBAC/B,IAAI,KAAK,cAAc;wBACvB,IAAI,KAAK,WAAW,CACrB,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,MAAM,CAAC,SAAS,GAAG;oBACjB,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBACjD,QAAQ;oBACR,SAAS,EAAE,IAAI,CAAC,MAAM;oBACtB,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,KAAK;iBACvC,CAAC;gBAEF,kBAAkB;gBAClB,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;gBAEvC,0CAA0C;gBAC1C,MAAM,YAAY,GAAG,CAAC,cAAc,EAAE,kBAAkB,EAAE,YAAY,CAAC,CAAC;gBACxE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;gBAE/C,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;oBACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC5B,IAAI,CAAC;4BACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,UAAU,KAAK,IAAI,IAAI,aAAa,QAAQ,EAAE,CAC/C,CAAC;4BACF,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gCACrB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gCAC1E,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;4BACtC,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,sBAAsB;wBACxB,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,oBAAoB;gBACpB,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;gBAC9C,MAAM,CAAC,SAAS,GAAG;oBACjB,eAAe,EAAE,QAAQ,CAAC,QAAQ;oBAClC,SAAS,EAAE,EAAE,EAAE,gCAAgC;oBAC/C,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBAC5C,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBAClD,kBAAkB,EAAE,IAAI,CAAC,UAAU;iBACpC,CAAC;gBAEF,0BAA0B;gBAC1B,MAAM,eAAe,GAAa,EAAE,CAAC;gBACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS;oBAAE,eAAe,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBACxE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ;oBAAE,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK;oBAAE,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,YAAY;oBACjE,eAAe,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;gBAC/D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU;oBAAE,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAEvE,MAAM,CAAC,cAAc;oBACnB,eAAe,CAAC,MAAM,GAAG,CAAC;wBACxB,CAAC,CAAC,gBAAgB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBAC9C,CAAC,CAAC,0EAA0E,CAAC;gBAEjF,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,KAAK,EAAE,IAAI;oBACX,OAAO;oBACP,KAAK;oBACL,IAAI;oBACJ,OAAO,EAAE,+BAA+B,GAAG,CAAC,OAAO,EAAE;oBACrD,UAAU,EACR,2GAA2G;iBAC9G,CAAC;YACJ,CAAC;QACH,CAAC;KACF;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Learning tools — persistent edge case / gotcha / pattern store backed by SQLite FTS5.
3
+ * Reframed from generic "agent memory" to development learnings that prevent repeating mistakes.
4
+ */
5
+ import type { McpTool } from "../types.js";
6
+ export declare const learningTools: McpTool[];
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Learning tools — persistent edge case / gotcha / pattern store backed by SQLite FTS5.
3
+ * Reframed from generic "agent memory" to development learnings that prevent repeating mistakes.
4
+ */
5
+ import { getDb } from "../db.js";
6
+ export const learningTools = [
7
+ {
8
+ name: "record_learning",
9
+ description: "Store an edge case, gotcha, pattern, or regression discovered during verification. Learnings are searchable via full-text search and prevent repeating the same mistakes. Always record learnings at the end of a verification cycle.",
10
+ inputSchema: {
11
+ type: "object",
12
+ properties: {
13
+ key: {
14
+ type: "string",
15
+ description: "Short identifier (e.g. 'convex-use-node-export-restriction', 'stooq-crypto-suffix')",
16
+ },
17
+ content: {
18
+ type: "string",
19
+ description: "The learning: what happened, why, and how to avoid it",
20
+ },
21
+ category: {
22
+ type: "string",
23
+ enum: ["edge_case", "gotcha", "pattern", "regression", "convention"],
24
+ description: "Type of learning",
25
+ },
26
+ tags: {
27
+ type: "array",
28
+ items: { type: "string" },
29
+ description: "Searchable tags",
30
+ },
31
+ sourceCycle: {
32
+ type: "string",
33
+ description: "Verification cycle ID that produced this learning (optional)",
34
+ },
35
+ },
36
+ required: ["key", "content", "category"],
37
+ },
38
+ handler: async (args) => {
39
+ const { key, content, category, tags, sourceCycle } = args;
40
+ if (!key || !content)
41
+ throw new Error("Key and content are required");
42
+ const db = getDb();
43
+ const now = new Date().toISOString();
44
+ const tagsJson = tags ? JSON.stringify(tags) : null;
45
+ db.prepare(`
46
+ INSERT INTO learnings (key, content, category, tags, source_cycle, created_at, updated_at)
47
+ VALUES (?, ?, ?, ?, ?, ?, ?)
48
+ ON CONFLICT(key) DO UPDATE SET
49
+ content = excluded.content,
50
+ category = excluded.category,
51
+ tags = excluded.tags,
52
+ source_cycle = excluded.source_cycle,
53
+ updated_at = excluded.updated_at
54
+ `).run(key, content, category, tagsJson, sourceCycle ?? null, now, now);
55
+ const row = db
56
+ .prepare("SELECT id FROM learnings WHERE key = ?")
57
+ .get(key);
58
+ return {
59
+ success: true,
60
+ learningId: row?.id,
61
+ key,
62
+ category,
63
+ message: `Learning recorded. It will surface in future searches.`,
64
+ };
65
+ },
66
+ },
67
+ {
68
+ name: "search_learnings",
69
+ description: "Search past learnings before making changes. This prevents repeating known mistakes. Always search learnings at the start of a verification cycle or before implementing a fix.",
70
+ inputSchema: {
71
+ type: "object",
72
+ properties: {
73
+ query: {
74
+ type: "string",
75
+ description: "What you are about to work on (e.g. 'convex http routing', 'crypto price API')",
76
+ },
77
+ category: {
78
+ type: "string",
79
+ enum: ["edge_case", "gotcha", "pattern", "regression", "convention"],
80
+ description: "Filter by category (optional)",
81
+ },
82
+ limit: {
83
+ type: "number",
84
+ description: "Max results (default 10)",
85
+ },
86
+ },
87
+ required: ["query"],
88
+ },
89
+ handler: async (args) => {
90
+ const db = getDb();
91
+ const limit = args.limit ?? 10;
92
+ const query = args.query;
93
+ let results;
94
+ if (args.category) {
95
+ results = db
96
+ .prepare(`
97
+ SELECT l.id, l.key, l.content, l.category, l.tags, l.source_cycle, l.created_at,
98
+ rank
99
+ FROM learnings_fts
100
+ JOIN learnings l ON l.id = learnings_fts.rowid
101
+ WHERE learnings_fts MATCH ?
102
+ AND l.category = ?
103
+ ORDER BY rank
104
+ LIMIT ?
105
+ `)
106
+ .all(query, args.category, limit);
107
+ }
108
+ else {
109
+ results = db
110
+ .prepare(`
111
+ SELECT l.id, l.key, l.content, l.category, l.tags, l.source_cycle, l.created_at,
112
+ rank
113
+ FROM learnings_fts
114
+ JOIN learnings l ON l.id = learnings_fts.rowid
115
+ WHERE learnings_fts MATCH ?
116
+ ORDER BY rank
117
+ LIMIT ?
118
+ `)
119
+ .all(query, limit);
120
+ }
121
+ return {
122
+ query,
123
+ count: results.length,
124
+ learnings: results.map((r) => ({
125
+ key: r.key,
126
+ content: r.content,
127
+ category: r.category,
128
+ tags: r.tags ? JSON.parse(r.tags) : [],
129
+ sourceCycle: r.source_cycle,
130
+ createdAt: r.created_at,
131
+ })),
132
+ };
133
+ },
134
+ },
135
+ {
136
+ name: "list_learnings",
137
+ description: "List all stored learnings, optionally filtered by category. Use this to review the knowledge base.",
138
+ inputSchema: {
139
+ type: "object",
140
+ properties: {
141
+ category: {
142
+ type: "string",
143
+ enum: ["edge_case", "gotcha", "pattern", "regression", "convention"],
144
+ description: "Filter by category (optional)",
145
+ },
146
+ limit: {
147
+ type: "number",
148
+ description: "Max results (default 50)",
149
+ },
150
+ },
151
+ },
152
+ handler: async (args) => {
153
+ const db = getDb();
154
+ const limit = args.limit ?? 50;
155
+ const rows = args.category
156
+ ? db
157
+ .prepare("SELECT * FROM learnings WHERE category = ? ORDER BY created_at DESC LIMIT ?")
158
+ .all(args.category, limit)
159
+ : db
160
+ .prepare("SELECT * FROM learnings ORDER BY created_at DESC LIMIT ?")
161
+ .all(limit);
162
+ return {
163
+ count: rows.length,
164
+ learnings: rows.map((r) => ({
165
+ key: r.key,
166
+ content: r.content,
167
+ category: r.category,
168
+ tags: r.tags ? JSON.parse(r.tags) : [],
169
+ sourceCycle: r.source_cycle,
170
+ createdAt: r.created_at,
171
+ })),
172
+ };
173
+ },
174
+ },
175
+ {
176
+ name: "delete_learning",
177
+ description: "Delete a learning by key. Use when a learning is outdated or incorrect.",
178
+ inputSchema: {
179
+ type: "object",
180
+ properties: {
181
+ key: { type: "string", description: "Key of the learning to delete" },
182
+ },
183
+ required: ["key"],
184
+ },
185
+ handler: async (args) => {
186
+ const db = getDb();
187
+ const result = db
188
+ .prepare("DELETE FROM learnings WHERE key = ?")
189
+ .run(args.key);
190
+ if (result.changes === 0)
191
+ throw new Error(`No learning found for key: ${args.key}`);
192
+ return {
193
+ success: true,
194
+ message: `Deleted learning '${args.key}'`,
195
+ };
196
+ },
197
+ },
198
+ ];
199
+ //# sourceMappingURL=learningTools.js.map