nodebench-mcp 2.17.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/NODEBENCH_AGENTS.md +2 -2
  3. package/README.md +516 -82
  4. package/dist/__tests__/analytics.test.d.ts +11 -0
  5. package/dist/__tests__/analytics.test.js +546 -0
  6. package/dist/__tests__/analytics.test.js.map +1 -0
  7. package/dist/__tests__/dynamicLoading.test.d.ts +1 -0
  8. package/dist/__tests__/dynamicLoading.test.js +278 -0
  9. package/dist/__tests__/dynamicLoading.test.js.map +1 -0
  10. package/dist/__tests__/evalHarness.test.js +1 -1
  11. package/dist/__tests__/evalHarness.test.js.map +1 -1
  12. package/dist/__tests__/helpers/answerMatch.js +22 -22
  13. package/dist/__tests__/presetRealWorldBench.test.js +9 -0
  14. package/dist/__tests__/presetRealWorldBench.test.js.map +1 -1
  15. package/dist/__tests__/tools.test.js +1 -1
  16. package/dist/__tests__/toolsetGatingEval.test.js +9 -1
  17. package/dist/__tests__/toolsetGatingEval.test.js.map +1 -1
  18. package/dist/analytics/index.d.ts +10 -0
  19. package/dist/analytics/index.js +11 -0
  20. package/dist/analytics/index.js.map +1 -0
  21. package/dist/analytics/projectDetector.d.ts +19 -0
  22. package/dist/analytics/projectDetector.js +259 -0
  23. package/dist/analytics/projectDetector.js.map +1 -0
  24. package/dist/analytics/schema.d.ts +57 -0
  25. package/dist/analytics/schema.js +157 -0
  26. package/dist/analytics/schema.js.map +1 -0
  27. package/dist/analytics/smartPreset.d.ts +63 -0
  28. package/dist/analytics/smartPreset.js +300 -0
  29. package/dist/analytics/smartPreset.js.map +1 -0
  30. package/dist/analytics/toolTracker.d.ts +59 -0
  31. package/dist/analytics/toolTracker.js +163 -0
  32. package/dist/analytics/toolTracker.js.map +1 -0
  33. package/dist/analytics/usageStats.d.ts +64 -0
  34. package/dist/analytics/usageStats.js +252 -0
  35. package/dist/analytics/usageStats.js.map +1 -0
  36. package/dist/db.js +359 -321
  37. package/dist/db.js.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.js +652 -89
  40. package/dist/index.js.map +1 -1
  41. package/dist/tools/architectTools.js +13 -13
  42. package/dist/tools/critterTools.js +14 -14
  43. package/dist/tools/parallelAgentTools.js +176 -176
  44. package/dist/tools/patternTools.js +11 -11
  45. package/dist/tools/progressiveDiscoveryTools.d.ts +5 -1
  46. package/dist/tools/progressiveDiscoveryTools.js +111 -19
  47. package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
  48. package/dist/tools/researchWritingTools.js +42 -42
  49. package/dist/tools/rssTools.js +396 -396
  50. package/dist/tools/toolRegistry.d.ts +17 -0
  51. package/dist/tools/toolRegistry.js +65 -17
  52. package/dist/tools/toolRegistry.js.map +1 -1
  53. package/dist/tools/voiceBridgeTools.js +498 -498
  54. package/dist/toolsetRegistry.d.ts +10 -0
  55. package/dist/toolsetRegistry.js +84 -0
  56. package/dist/toolsetRegistry.js.map +1 -0
  57. package/package.json +4 -4
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Project Type Detection
3
+ *
4
+ * Analyzes the current working directory to determine project type,
5
+ * language, framework, and characteristics.
6
+ */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ const FRAMEWORK_PATTERNS = {
10
+ 'react': {
11
+ files: ['package.json', 'src/App.jsx', 'src/App.tsx', 'public/index.html'],
12
+ type: 'web_frontend'
13
+ },
14
+ 'nextjs': {
15
+ files: ['next.config.js', 'pages/_app.js', 'app/layout.tsx'],
16
+ type: 'fullstack'
17
+ },
18
+ 'vue': {
19
+ files: ['vue.config.js', 'src/App.vue', 'public/index.html'],
20
+ type: 'web_frontend'
21
+ },
22
+ 'angular': {
23
+ files: ['angular.json', 'src/main.ts', 'src/app/app.component.ts'],
24
+ type: 'web_frontend'
25
+ },
26
+ 'svelte': {
27
+ files: ['svelte.config.js', 'src/App.svelte'],
28
+ type: 'web_frontend'
29
+ },
30
+ 'express': {
31
+ files: ['package.json', 'server.js', 'app.js'],
32
+ type: 'web_backend'
33
+ },
34
+ 'fastapi': {
35
+ files: ['main.py', 'requirements.txt', 'app.py'],
36
+ type: 'web_backend'
37
+ },
38
+ 'django': {
39
+ files: ['manage.py', 'settings.py', 'wsgi.py'],
40
+ type: 'web_backend'
41
+ },
42
+ 'flask': {
43
+ files: ['app.py', 'requirements.txt', 'wsgi.py'],
44
+ type: 'web_backend'
45
+ },
46
+ 'spring': {
47
+ files: ['pom.xml', 'build.gradle', 'src/main/java'],
48
+ type: 'web_backend'
49
+ },
50
+ 'rails': {
51
+ files: ['Gemfile', 'config/application.rb', 'app/controllers'],
52
+ type: 'web_backend'
53
+ },
54
+ 'electron': {
55
+ files: ['package.json', 'main.js', 'electron-builder.yml'],
56
+ type: 'desktop'
57
+ },
58
+ 'tauri': {
59
+ files: ['src-tauri/Cargo.toml', 'tauri.conf.json'],
60
+ type: 'desktop'
61
+ },
62
+ 'react_native': {
63
+ files: ['package.json', 'App.tsx', 'ios/Podfile', 'android/build.gradle'],
64
+ type: 'mobile'
65
+ },
66
+ 'flutter': {
67
+ files: ['pubspec.yaml', 'lib/main.dart'],
68
+ type: 'mobile'
69
+ },
70
+ 'swiftui': {
71
+ files: ['Package.swift', 'ContentView.swift'],
72
+ type: 'mobile'
73
+ },
74
+ 'python_library': {
75
+ files: ['setup.py', 'pyproject.toml', 'src/__init__.py'],
76
+ type: 'library'
77
+ },
78
+ 'npm_library': {
79
+ files: ['package.json', 'src/index.ts', 'tsconfig.json'],
80
+ type: 'library'
81
+ },
82
+ 'rust_library': {
83
+ files: ['Cargo.toml', 'src/lib.rs'],
84
+ type: 'library'
85
+ },
86
+ 'jupyter': {
87
+ files: ['*.ipynb', 'requirements.txt', 'environment.yml'],
88
+ type: 'data_science'
89
+ },
90
+ 'terraform': {
91
+ files: ['*.tf', 'terraform.tfstate', 'main.tf'],
92
+ type: 'devops'
93
+ },
94
+ 'kubernetes': {
95
+ files: ['*.yaml', 'k8s/', 'deployment.yaml'],
96
+ type: 'devops'
97
+ },
98
+ 'docker': {
99
+ files: ['Dockerfile', 'docker-compose.yml'],
100
+ type: 'devops'
101
+ },
102
+ };
103
+ const LANGUAGE_PATTERNS = {
104
+ 'typescript': ['*.ts', '*.tsx', 'tsconfig.json'],
105
+ 'javascript': ['*.js', '*.jsx', 'package.json'],
106
+ 'python': ['*.py', 'requirements.txt', 'pyproject.toml', 'setup.py'],
107
+ 'java': ['*.java', 'pom.xml', 'build.gradle'],
108
+ 'kotlin': ['*.kt', 'build.gradle.kts'],
109
+ 'go': ['*.go', 'go.mod'],
110
+ 'rust': ['*.rs', 'Cargo.toml'],
111
+ 'csharp': ['*.cs', '*.csproj'],
112
+ 'cpp': ['*.cpp', '*.h', 'CMakeLists.txt', 'Makefile'],
113
+ 'ruby': ['*.rb', 'Gemfile'],
114
+ 'php': ['*.php', 'composer.json'],
115
+ 'swift': ['*.swift', 'Package.swift'],
116
+ 'shell': ['*.sh', 'Makefile'],
117
+ };
118
+ const CI_PATTERNS = [
119
+ '.github/workflows/*.yml',
120
+ '.github/workflows/*.yaml',
121
+ '.gitlab-ci.yml',
122
+ 'Jenkinsfile',
123
+ '.travis.yml',
124
+ 'circleci/config.yml',
125
+ 'azure-pipelines.yml',
126
+ 'bitbucket-pipelines.yml',
127
+ ];
128
+ const DOC_PATTERNS = [
129
+ 'README.md',
130
+ 'docs/',
131
+ 'doc/',
132
+ '*.md',
133
+ 'CONTRIBUTING.md',
134
+ 'CHANGELOG.md',
135
+ ];
136
+ const TEST_PATTERNS = [
137
+ '**/*.test.ts',
138
+ '**/*.test.js',
139
+ '**/*.spec.ts',
140
+ '**/*.spec.js',
141
+ '**/*_test.py',
142
+ '**/test_*.py',
143
+ '**/__tests__/**',
144
+ 'tests/',
145
+ 'test/',
146
+ ];
147
+ function fileExists(dir, pattern) {
148
+ const fullPath = path.join(dir, pattern);
149
+ if (pattern.includes('*')) {
150
+ const parts = pattern.split('/');
151
+ const baseDir = parts.slice(0, -1).join('/');
152
+ const glob = parts[parts.length - 1];
153
+ const searchDir = baseDir ? path.join(dir, baseDir) : dir;
154
+ if (!fs.existsSync(searchDir))
155
+ return false;
156
+ try {
157
+ const files = fs.readdirSync(searchDir);
158
+ const regex = new RegExp('^' + glob.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$');
159
+ return files.some(f => regex.test(f));
160
+ }
161
+ catch {
162
+ return false;
163
+ }
164
+ }
165
+ return fs.existsSync(fullPath);
166
+ }
167
+ function anyFileExists(dir, patterns) {
168
+ return patterns.some(p => fileExists(dir, p));
169
+ }
170
+ function countFiles(dir, maxDepth = 3) {
171
+ let count = 0;
172
+ function walk(currentDir, depth) {
173
+ if (depth > maxDepth)
174
+ return;
175
+ try {
176
+ const entries = fs.readdirSync(currentDir, { withFileTypes: true });
177
+ for (const entry of entries) {
178
+ if (entry.isDirectory()) {
179
+ // Skip node_modules, .git, etc.
180
+ if (!['node_modules', '.git', '.next', 'dist', 'build', 'target'].includes(entry.name)) {
181
+ walk(path.join(currentDir, entry.name), depth + 1);
182
+ }
183
+ }
184
+ else {
185
+ count++;
186
+ }
187
+ }
188
+ }
189
+ catch {
190
+ // Ignore permission errors
191
+ }
192
+ }
193
+ walk(dir, 0);
194
+ return count;
195
+ }
196
+ function detectLanguage(dir) {
197
+ for (const [lang, patterns] of Object.entries(LANGUAGE_PATTERNS)) {
198
+ if (anyFileExists(dir, patterns)) {
199
+ return lang;
200
+ }
201
+ }
202
+ return 'unknown';
203
+ }
204
+ function detectFramework(dir) {
205
+ for (const [framework, config] of Object.entries(FRAMEWORK_PATTERNS)) {
206
+ if (anyFileExists(dir, config.files)) {
207
+ return { framework, type: config.type };
208
+ }
209
+ }
210
+ return { framework: undefined, type: 'unknown' };
211
+ }
212
+ export function detectProject(projectPath = process.cwd()) {
213
+ const { framework, type: detectedType } = detectFramework(projectPath);
214
+ const language = detectLanguage(projectPath);
215
+ // Determine project type based on framework or language
216
+ let projectType = detectedType;
217
+ if (projectType === 'unknown') {
218
+ // Fallback: infer from language
219
+ if (['typescript', 'javascript'].includes(language)) {
220
+ projectType = 'web_frontend';
221
+ }
222
+ else if (['python', 'java', 'go'].includes(language)) {
223
+ projectType = 'web_backend';
224
+ }
225
+ else if (['rust', 'csharp', 'cpp'].includes(language)) {
226
+ projectType = 'library';
227
+ }
228
+ }
229
+ const hasTests = anyFileExists(projectPath, TEST_PATTERNS);
230
+ const hasCI = anyFileExists(projectPath, CI_PATTERNS);
231
+ const hasDocs = anyFileExists(projectPath, DOC_PATTERNS);
232
+ const fileCount = countFiles(projectPath);
233
+ return {
234
+ projectPath,
235
+ projectType,
236
+ language,
237
+ framework,
238
+ hasTests,
239
+ hasCI,
240
+ hasDocs,
241
+ fileCount,
242
+ };
243
+ }
244
+ export function getProjectTypeDescription(type) {
245
+ const descriptions = {
246
+ web_frontend: 'Web frontend application (React, Vue, Angular, etc.)',
247
+ web_backend: 'Web backend API or service',
248
+ fullstack: 'Full-stack web application (Next.js, etc.)',
249
+ mobile: 'Mobile application (React Native, Flutter, etc.)',
250
+ desktop: 'Desktop application (Electron, Tauri, etc.)',
251
+ cli: 'Command-line interface tool',
252
+ library: 'Reusable library or package',
253
+ data_science: 'Data science or ML project (Jupyter, etc.)',
254
+ devops: 'DevOps or infrastructure project (Terraform, Docker, etc.)',
255
+ unknown: 'Unknown project type',
256
+ };
257
+ return descriptions[type];
258
+ }
259
+ //# sourceMappingURL=projectDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectDetector.js","sourceRoot":"","sources":["../../src/analytics/projectDetector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAyBxB,MAAM,kBAAkB,GAA2D;IACjF,OAAO,EAAE;QACP,KAAK,EAAE,CAAC,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,CAAC;QAC1E,IAAI,EAAE,cAAc;KACrB;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,CAAC;QAC5D,IAAI,EAAE,WAAW;KAClB;IACD,KAAK,EAAE;QACL,KAAK,EAAE,CAAC,eAAe,EAAE,aAAa,EAAE,mBAAmB,CAAC;QAC5D,IAAI,EAAE,cAAc;KACrB;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,cAAc,EAAE,aAAa,EAAE,0BAA0B,CAAC;QAClE,IAAI,EAAE,cAAc;KACrB;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;QAC7C,IAAI,EAAE,cAAc;KACrB;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,cAAc,EAAE,WAAW,EAAE,QAAQ,CAAC;QAC9C,IAAI,EAAE,aAAa;KACpB;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,CAAC;QAChD,IAAI,EAAE,aAAa;KACpB;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,SAAS,CAAC;QAC9C,IAAI,EAAE,aAAa;KACpB;IACD,OAAO,EAAE;QACP,KAAK,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC;QAChD,IAAI,EAAE,aAAa;KACpB;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,eAAe,CAAC;QACnD,IAAI,EAAE,aAAa;KACpB;IACD,OAAO,EAAE;QACP,KAAK,EAAE,CAAC,SAAS,EAAE,uBAAuB,EAAE,iBAAiB,CAAC;QAC9D,IAAI,EAAE,aAAa;KACpB;IACD,UAAU,EAAE;QACV,KAAK,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,sBAAsB,CAAC;QAC1D,IAAI,EAAE,SAAS;KAChB;IACD,OAAO,EAAE;QACP,KAAK,EAAE,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;QAClD,IAAI,EAAE,SAAS;KAChB;IACD,cAAc,EAAE;QACd,KAAK,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,sBAAsB,CAAC;QACzE,IAAI,EAAE,QAAQ;KACf;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;QACxC,IAAI,EAAE,QAAQ;KACf;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,eAAe,EAAE,mBAAmB,CAAC;QAC7C,IAAI,EAAE,QAAQ;KACf;IACD,gBAAgB,EAAE;QAChB,KAAK,EAAE,CAAC,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,CAAC;QACxD,IAAI,EAAE,SAAS;KAChB;IACD,aAAa,EAAE;QACb,KAAK,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,eAAe,CAAC;QACxD,IAAI,EAAE,SAAS;KAChB;IACD,cAAc,EAAE;QACd,KAAK,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;QACnC,IAAI,EAAE,SAAS;KAChB;IACD,SAAS,EAAE;QACT,KAAK,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,iBAAiB,CAAC;QACzD,IAAI,EAAE,cAAc;KACrB;IACD,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,CAAC;QAC/C,IAAI,EAAE,QAAQ;KACf;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,CAAC;QAC5C,IAAI,EAAE,QAAQ;KACf;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,CAAC,YAAY,EAAE,oBAAoB,CAAC;QAC3C,IAAI,EAAE,QAAQ;KACf;CACF,CAAC;AAEF,MAAM,iBAAiB,GAA6B;IAClD,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC;IAChD,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC;IAC/C,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,UAAU,CAAC;IACpE,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC;IAC7C,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACtC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;IACxB,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;IAC9B,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,UAAU,CAAC;IACrD,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,KAAK,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IACjC,OAAO,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC;IACrC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;CAC9B,CAAC;AAEF,MAAM,WAAW,GAAG;IAClB,yBAAyB;IACzB,0BAA0B;IAC1B,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,qBAAqB;IACrB,qBAAqB;IACrB,yBAAyB;CAC1B,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,WAAW;IACX,OAAO;IACP,MAAM;IACN,MAAM;IACN,iBAAiB;IACjB,cAAc;CACf,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,QAAQ;IACR,OAAO;CACR,CAAC;AAEF,SAAS,UAAU,CAAC,GAAW,EAAE,OAAe;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAE1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;YACtG,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,QAAkB;IACpD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,WAAmB,CAAC;IACnD,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,SAAS,IAAI,CAAC,UAAkB,EAAE,KAAa;QAC7C,IAAI,KAAK,GAAG,QAAQ;YAAE,OAAO;QAE7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACpE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,gCAAgC;oBAChC,IAAI,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,KAAK,EAAE,CAAC;gBACV,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACb,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACjE,IAAI,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACrE,IAAI,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,cAAsB,OAAO,CAAC,GAAG,EAAE;IAC/D,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAE7C,wDAAwD;IACxD,IAAI,WAAW,GAAgB,YAAY,CAAC;IAE5C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,gCAAgC;QAChC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,WAAW,GAAG,cAAc,CAAC;QAC/B,CAAC;aAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,WAAW,GAAG,aAAa,CAAC;QAC9B,CAAC;aAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,WAAW,GAAG,SAAS,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAE1C,OAAO;QACL,WAAW;QACX,WAAW;QACX,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,KAAK;QACL,OAAO;QACP,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,IAAiB;IACzD,MAAM,YAAY,GAAgC;QAChD,YAAY,EAAE,sDAAsD;QACpE,WAAW,EAAE,4BAA4B;QACzC,SAAS,EAAE,4CAA4C;QACvD,MAAM,EAAE,kDAAkD;QAC1D,OAAO,EAAE,6CAA6C;QACtD,GAAG,EAAE,6BAA6B;QAClC,OAAO,EAAE,6BAA6B;QACtC,YAAY,EAAE,4CAA4C;QAC1D,MAAM,EAAE,4DAA4D;QACpE,OAAO,EAAE,sBAAsB;KAChC,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Usage Analytics Schema for NodeBench MCP
3
+ *
4
+ * Tracks tool usage, project context, and generates smart preset recommendations.
5
+ * All data stored locally in SQLite at ~/.nodebench/analytics.db
6
+ */
7
+ import Database from 'better-sqlite3';
8
+ export interface ToolUsageRecord {
9
+ id?: number;
10
+ toolName: string;
11
+ toolset: string;
12
+ timestamp: number;
13
+ duration: number;
14
+ success: boolean;
15
+ errorMessage?: string;
16
+ projectPath: string;
17
+ preset: string;
18
+ args?: string;
19
+ }
20
+ export interface ProjectContextRecord {
21
+ id?: number;
22
+ projectPath: string;
23
+ projectType: string;
24
+ detectedAt: number;
25
+ lastSeen: number;
26
+ language: string;
27
+ framework?: string;
28
+ hasTests: boolean;
29
+ hasCI: boolean;
30
+ hasDocs: boolean;
31
+ fileCount: number;
32
+ }
33
+ export interface PresetHistoryRecord {
34
+ id?: number;
35
+ projectPath: string;
36
+ preset: string;
37
+ toolsetCount: number;
38
+ selectedAt: number;
39
+ selectionReason: 'manual' | 'smart' | 'default';
40
+ }
41
+ export interface UsageStatsCacheRecord {
42
+ id?: number;
43
+ projectPath: string;
44
+ cacheKey: string;
45
+ stats: string;
46
+ computedAt: number;
47
+ ttl: number;
48
+ }
49
+ export declare function initAnalyticsDb(): Database.Database;
50
+ export declare function getAnalyticsDb(): Database.Database;
51
+ export declare function closeAnalyticsDb(db: Database.Database): void;
52
+ export declare function recordToolUsage(db: Database.Database, record: Omit<ToolUsageRecord, 'id'>): void;
53
+ export declare function updateProjectContext(db: Database.Database, context: Omit<ProjectContextRecord, 'id'>): void;
54
+ export declare function recordPresetSelection(db: Database.Database, record: Omit<PresetHistoryRecord, 'id'>): void;
55
+ export declare function getCachedStats(db: Database.Database, projectPath: string, cacheKey: string): string | null;
56
+ export declare function setCachedStats(db: Database.Database, record: Omit<UsageStatsCacheRecord, 'id'>): void;
57
+ export declare function clearOldRecords(db: Database.Database, daysToKeep?: number): void;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Usage Analytics Schema for NodeBench MCP
3
+ *
4
+ * Tracks tool usage, project context, and generates smart preset recommendations.
5
+ * All data stored locally in SQLite at ~/.nodebench/analytics.db
6
+ */
7
+ import Database from 'better-sqlite3';
8
+ import path from 'path';
9
+ import os from 'os';
10
+ import fs from 'fs';
11
+ const DB_DIR = path.join(os.homedir(), '.nodebench');
12
+ const DB_PATH = path.join(DB_DIR, 'analytics.db');
13
+ let _analyticsDb = null;
14
+ export function initAnalyticsDb() {
15
+ fs.mkdirSync(DB_DIR, { recursive: true });
16
+ const db = new Database(DB_PATH);
17
+ // Enable WAL mode for better concurrency
18
+ db.pragma('journal_mode = WAL');
19
+ // Create tables
20
+ db.exec(`
21
+ CREATE TABLE IF NOT EXISTS tool_usage (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ tool_name TEXT NOT NULL,
24
+ toolset TEXT NOT NULL,
25
+ timestamp INTEGER NOT NULL,
26
+ duration INTEGER NOT NULL,
27
+ success BOOLEAN NOT NULL,
28
+ error_message TEXT,
29
+ project_path TEXT NOT NULL,
30
+ preset TEXT NOT NULL,
31
+ args TEXT
32
+ );
33
+
34
+ CREATE INDEX IF NOT EXISTS idx_tool_usage_tool ON tool_usage(tool_name);
35
+ CREATE INDEX IF NOT EXISTS idx_tool_usage_toolset ON tool_usage(toolset);
36
+ CREATE INDEX IF NOT EXISTS idx_tool_usage_project ON tool_usage(project_path);
37
+ CREATE INDEX IF NOT EXISTS idx_tool_usage_timestamp ON tool_usage(timestamp);
38
+
39
+ CREATE TABLE IF NOT EXISTS project_context (
40
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
41
+ project_path TEXT UNIQUE NOT NULL,
42
+ project_type TEXT NOT NULL,
43
+ detected_at INTEGER NOT NULL,
44
+ last_seen INTEGER NOT NULL,
45
+ language TEXT NOT NULL,
46
+ framework TEXT,
47
+ has_tests BOOLEAN NOT NULL,
48
+ has_ci BOOLEAN NOT NULL,
49
+ has_docs BOOLEAN NOT NULL,
50
+ file_count INTEGER NOT NULL
51
+ );
52
+
53
+ CREATE INDEX IF NOT EXISTS idx_project_context_type ON project_context(project_type);
54
+ CREATE INDEX IF NOT EXISTS idx_project_context_last_seen ON project_context(last_seen);
55
+
56
+ CREATE TABLE IF NOT EXISTS preset_history (
57
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
58
+ project_path TEXT NOT NULL,
59
+ preset TEXT NOT NULL,
60
+ toolset_count INTEGER NOT NULL,
61
+ selected_at INTEGER NOT NULL,
62
+ selection_reason TEXT NOT NULL
63
+ );
64
+
65
+ CREATE INDEX IF NOT EXISTS idx_preset_history_project ON preset_history(project_path);
66
+ CREATE INDEX IF NOT EXISTS idx_preset_history_timestamp ON preset_history(selected_at);
67
+
68
+ CREATE TABLE IF NOT EXISTS usage_stats_cache (
69
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
70
+ project_path TEXT NOT NULL,
71
+ cache_key TEXT NOT NULL,
72
+ stats TEXT NOT NULL,
73
+ computed_at INTEGER NOT NULL,
74
+ ttl INTEGER NOT NULL,
75
+ UNIQUE(project_path, cache_key)
76
+ );
77
+
78
+ CREATE INDEX IF NOT EXISTS idx_usage_stats_cache_key ON usage_stats_cache(project_path, cache_key);
79
+ `);
80
+ return db;
81
+ }
82
+ export function getAnalyticsDb() {
83
+ if (_analyticsDb)
84
+ return _analyticsDb;
85
+ _analyticsDb = initAnalyticsDb();
86
+ return _analyticsDb;
87
+ }
88
+ export function closeAnalyticsDb(db) {
89
+ db.close();
90
+ if (_analyticsDb === db)
91
+ _analyticsDb = null;
92
+ }
93
+ // Helper functions for common queries
94
+ export function recordToolUsage(db, record) {
95
+ const stmt = db.prepare(`
96
+ INSERT INTO tool_usage (
97
+ tool_name, toolset, timestamp, duration, success,
98
+ error_message, project_path, preset, args
99
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
100
+ `);
101
+ stmt.run(record.toolName, record.toolset, record.timestamp, record.duration, record.success ? 1 : 0, record.errorMessage || null, record.projectPath, record.preset, record.args || null);
102
+ }
103
+ export function updateProjectContext(db, context) {
104
+ const stmt = db.prepare(`
105
+ INSERT INTO project_context (
106
+ project_path, project_type, detected_at, last_seen,
107
+ language, framework, has_tests, has_ci, has_docs, file_count
108
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
109
+ ON CONFLICT(project_path) DO UPDATE SET
110
+ project_type = excluded.project_type,
111
+ last_seen = excluded.last_seen,
112
+ language = excluded.language,
113
+ framework = excluded.framework,
114
+ has_tests = excluded.has_tests,
115
+ has_ci = excluded.has_ci,
116
+ has_docs = excluded.has_docs,
117
+ file_count = excluded.file_count
118
+ `);
119
+ stmt.run(context.projectPath, context.projectType, context.detectedAt, context.lastSeen, context.language, context.framework || null, context.hasTests ? 1 : 0, context.hasCI ? 1 : 0, context.hasDocs ? 1 : 0, context.fileCount);
120
+ }
121
+ export function recordPresetSelection(db, record) {
122
+ const stmt = db.prepare(`
123
+ INSERT INTO preset_history (
124
+ project_path, preset, toolset_count, selected_at, selection_reason
125
+ ) VALUES (?, ?, ?, ?, ?)
126
+ `);
127
+ stmt.run(record.projectPath, record.preset, record.toolsetCount, record.selectedAt, record.selectionReason);
128
+ }
129
+ export function getCachedStats(db, projectPath, cacheKey) {
130
+ const stmt = db.prepare(`
131
+ SELECT stats FROM usage_stats_cache
132
+ WHERE project_path = ? AND cache_key = ?
133
+ AND computed_at + (ttl * 1000) > ?
134
+ `);
135
+ const now = Date.now();
136
+ const result = stmt.get(projectPath, cacheKey, now);
137
+ return result?.stats || null;
138
+ }
139
+ export function setCachedStats(db, record) {
140
+ const stmt = db.prepare(`
141
+ INSERT INTO usage_stats_cache (
142
+ project_path, cache_key, stats, computed_at, ttl
143
+ ) VALUES (?, ?, ?, ?, ?)
144
+ ON CONFLICT(project_path, cache_key) DO UPDATE SET
145
+ stats = excluded.stats,
146
+ computed_at = excluded.computed_at,
147
+ ttl = excluded.ttl
148
+ `);
149
+ stmt.run(record.projectPath, record.cacheKey, record.stats, record.computedAt, record.ttl);
150
+ }
151
+ export function clearOldRecords(db, daysToKeep = 90) {
152
+ const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);
153
+ db.prepare('DELETE FROM tool_usage WHERE timestamp < ?').run(cutoff);
154
+ db.prepare('DELETE FROM usage_stats_cache WHERE computed_at < ?').run(cutoff);
155
+ // Don't delete project_context or preset_history - they're useful for history
156
+ }
157
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/analytics/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACrD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAElD,IAAI,YAAY,GAA6B,IAAI,CAAC;AA+ClD,MAAM,UAAU,eAAe;IAC7B,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,yCAAyC;IACzC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAEhC,gBAAgB;IAChB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DP,CAAC,CAAC;IAEH,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,YAAY,GAAG,eAAe,EAAE,CAAC;IACjC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAqB;IACpD,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,IAAI,YAAY,KAAK,EAAE;QAAE,YAAY,GAAG,IAAI,CAAC;AAC/C,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,eAAe,CAC7B,EAAqB,EACrB,MAAmC;IAEnC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;GAKvB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CACN,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACtB,MAAM,CAAC,YAAY,IAAI,IAAI,EAC3B,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,IAAI,IAAI,IAAI,CACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,OAAyC;IAEzC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;;GAcvB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CACN,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,SAAS,IAAI,IAAI,EACzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACxB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACvB,OAAO,CAAC,SAAS,CAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,MAAuC;IAEvC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;GAIvB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CACN,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,eAAe,CACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,WAAmB,EACnB,QAAgB;IAEhB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;GAIvB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAkC,CAAC;IAErF,OAAO,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,MAAyC;IAEzC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;GAQvB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CACN,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,GAAG,CACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAqB,EAAE,aAAqB,EAAE;IAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE/D,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrE,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE9E,8EAA8E;AAChF,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Smart Preset Generator — Weighted Multi-Signal Scoring Model
3
+ *
4
+ * Recommends preset (default vs full) using 5 weighted signals derived from
5
+ * actual project context and historical usage data:
6
+ *
7
+ * 1. Project Type Affinity — static: how many specialized toolsets fit this project type
8
+ * 2. Usage Breadth — empirical: how many distinct toolsets were actually used
9
+ * 3. Specialized Usage Depth — empirical: calls to non-default toolsets (weighted by recency)
10
+ * 4. Failure Penalty — empirical: frequently failing tools penalize confidence
11
+ * 5. History Weight — meta: more history = higher confidence in the recommendation
12
+ *
13
+ * The final score is a weighted sum normalized to [0, 1].
14
+ * score > 0.55 → recommend full
15
+ * score <= 0.55 → recommend default
16
+ * confidence = f(history_weight, failure_penalty)
17
+ */
18
+ import Database from 'better-sqlite3';
19
+ import { type ProjectContext } from './projectDetector.js';
20
+ import type { McpTool } from '../types.js';
21
+ export interface PresetRecommendation {
22
+ preset: 'default' | 'full';
23
+ reason: string;
24
+ confidence: number;
25
+ score: number;
26
+ suggestedToolsets: string[];
27
+ optionalToolsets: string[];
28
+ projectContext: ProjectContext;
29
+ usageInsights: UsageInsights;
30
+ signals: SignalBreakdown;
31
+ }
32
+ export interface UsageInsights {
33
+ mostUsedToolsets: string[];
34
+ unusedToolsets: string[];
35
+ frequentlyFailingTools: Array<{
36
+ name: string;
37
+ failures: number;
38
+ lastError: string | null;
39
+ }>;
40
+ totalCallsLast30d: number;
41
+ uniqueToolsetsUsed: number;
42
+ }
43
+ export interface SignalBreakdown {
44
+ projectTypeAffinity: number;
45
+ usageBreadth: number;
46
+ specializedDepth: number;
47
+ failurePenalty: number;
48
+ historyWeight: number;
49
+ }
50
+ export interface PresetConfig {
51
+ name: 'default' | 'full';
52
+ toolsets: string[];
53
+ toolCount: number;
54
+ }
55
+ export declare function generateSmartPreset(db: Database.Database, toolsetMap: Record<string, McpTool[]>, projectPath?: string): PresetRecommendation;
56
+ export declare function getPresetConfig(preset: 'default' | 'full', toolsetMap: Record<string, McpTool[]>): PresetConfig;
57
+ export declare function listPresets(toolsetMap: Record<string, McpTool[]>): Array<{
58
+ name: string;
59
+ toolsets: string[];
60
+ toolCount: number;
61
+ description: string;
62
+ }>;
63
+ export declare function formatPresetRecommendation(recommendation: PresetRecommendation, toolsetMap: Record<string, McpTool[]>): string;